/*
* Copyright (c) 2004-2011 Marco Maccaferri and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marco Maccaferri - initial API and implementation
*/
package org.eclipsetrader.directa.internal.core;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExecutableExtension;
import org.eclipse.core.runtime.IExecutableExtensionFactory;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.swt.widgets.Display;
import org.eclipsetrader.core.feed.IFeedIdentifier;
import org.eclipsetrader.core.feed.IFeedProperties;
import org.eclipsetrader.core.instruments.ISecurity;
import org.eclipsetrader.core.repositories.IRepositoryService;
import org.eclipsetrader.core.trading.BrokerException;
import org.eclipsetrader.core.trading.IAccount;
import org.eclipsetrader.core.trading.IBroker;
import org.eclipsetrader.core.trading.IOrder;
import org.eclipsetrader.core.trading.IOrderChangeListener;
import org.eclipsetrader.core.trading.IOrderMonitor;
import org.eclipsetrader.core.trading.IOrderRoute;
import org.eclipsetrader.core.trading.IOrderSide;
import org.eclipsetrader.core.trading.IOrderStatus;
import org.eclipsetrader.core.trading.IOrderType;
import org.eclipsetrader.core.trading.IOrderValidity;
import org.eclipsetrader.core.trading.Order;
import org.eclipsetrader.core.trading.OrderChangeEvent;
import org.eclipsetrader.core.trading.OrderDelta;
import org.eclipsetrader.directa.internal.Activator;
import org.eclipsetrader.directa.internal.ui.StatusLineContributionItem;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public class BrokerConnector implements IBroker, IExecutableExtension, IExecutableExtensionFactory, Runnable {
public static final IOrderRoute Immediate = new OrderRoute("1", "immed"); //$NON-NLS-1$ //$NON-NLS-2$
public static final IOrderRoute MTA = new OrderRoute("2", "MTA"); //$NON-NLS-1$ //$NON-NLS-2$
public static final IOrderRoute CloseMTA = new OrderRoute("4", "clos-MTA"); //$NON-NLS-1$ //$NON-NLS-2$
public static final IOrderRoute AfterHours = new OrderRoute("5", "AfterHours"); //$NON-NLS-1$ //$NON-NLS-2$
public static final IOrderRoute Open = new OrderRoute("7", "open//"); //$NON-NLS-1$ //$NON-NLS-2$
public static final IOrderValidity Valid30Days = new OrderValidity("30days", Messages.BrokerConnector_30Days); //$NON-NLS-1$
private static BrokerConnector instance;
private String id;
private String name;
private String server = "213.92.13.4"; //$NON-NLS-1$
private int port = 1080;
Set<OrderMonitor> orders = new HashSet<OrderMonitor>();
private ListenerList listeners = new ListenerList(ListenerList.IDENTITY);
private NumberFormat amountParser = NumberFormat.getInstance(Locale.ITALY);
private NumberFormat amountFormatter = NumberFormat.getInstance();
private SocketChannel socketChannel;
private Thread thread;
private Log logger = LogFactory.getLog(getClass());
public BrokerConnector() {
amountFormatter.setMinimumFractionDigits(2);
amountFormatter.setMaximumFractionDigits(2);
amountFormatter.setGroupingUsed(true);
}
public static BrokerConnector getInstance() {
if (instance == null) {
instance = new BrokerConnector();
}
return instance;
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
*/
@Override
public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
id = config.getAttribute("id"); //$NON-NLS-1$
name = config.getAttribute("name"); //$NON-NLS-1$
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IExecutableExtensionFactory#create()
*/
@Override
public Object create() throws CoreException {
if (instance == null) {
instance = this;
}
return instance;
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.trading.IBroker#getId()
*/
@Override
public String getId() {
return id;
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.trading.IBroker#getName()
*/
@Override
public String getName() {
return name;
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.trading.IBroker#connect()
*/
@Override
public void connect() {
if ("".equals(WebConnector.getInstance().getUser())) { //$NON-NLS-1$
WebConnector.getInstance().login();
}
if (thread == null || !thread.isAlive()) {
thread = new Thread(this, getName() + " - Orders Monitor"); //$NON-NLS-1$
logger.info("Starting " + thread.getName()); //$NON-NLS-1$
thread.start();
}
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.trading.IBroker#disconnect()
*/
@Override
public void disconnect() {
if (thread != null) {
try {
if (socketChannel != null) {
socketChannel.close();
}
} catch (IOException e) {
// Do nothing
}
try {
thread.interrupt();
thread.join(30 * 1000);
} catch (InterruptedException e) {
// Do nothing
}
logger.info("Stopped " + thread.getName()); //$NON-NLS-1$
thread = null;
}
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.trading.IBroker#canTrade(org.eclipsetrader.core.instruments.ISecurity)
*/
@Override
public boolean canTrade(ISecurity security) {
IFeedIdentifier identifier = security.getIdentifier();
if (identifier == null) {
return false;
}
IFeedProperties properties = (IFeedProperties) identifier.getAdapter(IFeedProperties.class);
if (properties != null) {
for (int p = 0; p < WebConnector.PROPERTIES.length; p++) {
if (properties.getProperty(WebConnector.PROPERTIES[p]) != null) {
return true;
}
}
}
return false;
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.trading.IBroker#getSymbolFromSecurity(org.eclipsetrader.core.instruments.ISecurity)
*/
@Override
public String getSymbolFromSecurity(ISecurity security) {
IFeedIdentifier identifier = security.getIdentifier();
if (identifier == null) {
return null;
}
IFeedProperties properties = (IFeedProperties) identifier.getAdapter(IFeedProperties.class);
if (properties != null) {
for (int p = 0; p < WebConnector.PROPERTIES.length; p++) {
if (properties.getProperty(WebConnector.PROPERTIES[p]) != null) {
return properties.getProperty(WebConnector.PROPERTIES[p]);
}
}
}
return null;
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.trading.IBroker#getSecurityFromSymbol(java.lang.String)
*/
@Override
public ISecurity getSecurityFromSymbol(String symbol) {
ISecurity security = null;
if (Activator.getDefault() != null) {
BundleContext context = Activator.getDefault().getBundle().getBundleContext();
ServiceReference serviceReference = context.getServiceReference(IRepositoryService.class.getName());
if (serviceReference != null) {
IRepositoryService service = (IRepositoryService) context.getService(serviceReference);
ISecurity[] securities = service.getSecurities();
for (int i = 0; i < securities.length; i++) {
String feedSymbol = getSymbolFromSecurity(securities[i]);
if (feedSymbol != null && feedSymbol.equals(symbol)) {
security = securities[i];
break;
}
}
context.ungetService(serviceReference);
}
}
return security;
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.trading.IBroker#prepareOrder(org.eclipsetrader.core.trading.IOrder)
*/
@Override
public IOrderMonitor prepareOrder(IOrder order) throws BrokerException {
if (order.getType() != IOrderType.Limit && order.getType() != IOrderType.Market) {
throw new BrokerException(Messages.BrokerConnector_InvalidOrderType);
}
if (order.getSide() != IOrderSide.Buy && order.getSide() != IOrderSide.Sell) {
throw new BrokerException(Messages.BrokerConnector_InvalidOrderSide);
}
if (order.getValidity() != IOrderValidity.Day && order.getValidity() != Valid30Days) {
throw new BrokerException(Messages.BrokerConnector_InvalidOrderValidity);
}
return new OrderMonitor(WebConnector.getInstance(), this, order);
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.trading.IBroker#getAllowedSides()
*/
@Override
public IOrderSide[] getAllowedSides() {
return new IOrderSide[] {
IOrderSide.Buy, IOrderSide.Sell,
};
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.trading.IBroker#getAllowedTypes()
*/
@Override
public IOrderType[] getAllowedTypes() {
return new IOrderType[] {
IOrderType.Limit, IOrderType.Market,
};
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.trading.IBroker#getAllowedValidity()
*/
@Override
public IOrderValidity[] getAllowedValidity() {
return new IOrderValidity[] {
IOrderValidity.Day, Valid30Days,
};
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.trading.IBroker#getAllowedRoutes()
*/
@Override
public IOrderRoute[] getAllowedRoutes() {
return new IOrderRoute[] {
BrokerConnector.Immediate,
BrokerConnector.MTA,
BrokerConnector.CloseMTA,
BrokerConnector.Open,
BrokerConnector.AfterHours,
};
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.trading.IBroker#getOrders()
*/
@Override
public IOrderMonitor[] getOrders() {
synchronized (orders) {
return orders.toArray(new IOrderMonitor[orders.size()]);
}
}
private static final String LOGIN = "21"; //$NON-NLS-1$
private static final String UNKNOWN55 = "55"; //$NON-NLS-1$
private static final String UNKNOWN70 = "70"; //$NON-NLS-1$
private static final String HEARTBEAT = "40"; //$NON-NLS-1$
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
Selector socketSelector;
ByteBuffer dst = ByteBuffer.wrap(new byte[2048]);
List<Position> positions = new ArrayList<Position>();
try {
// Create a non-blocking socket channel
socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.socket().setReceiveBufferSize(32768);
socketChannel.socket().setSoLinger(true, 1);
socketChannel.socket().setSoTimeout(0x15f90);
socketChannel.socket().setReuseAddress(true);
// Kick off connection establishment
socketChannel.connect(new InetSocketAddress(server, port));
// Create a new selector
socketSelector = SelectorProvider.provider().openSelector();
// Register the server socket channel, indicating an interest in
// accepting new connections
socketChannel.register(socketSelector, SelectionKey.OP_READ | SelectionKey.OP_CONNECT);
} catch (Exception e) {
Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, "Error connecting to orders monitor", e); //$NON-NLS-1$
Activator.log(status);
return;
}
for (;;) {
try {
if (socketSelector.select(30 * 1000) == 0) {
logger.trace(">" + HEARTBEAT); //$NON-NLS-1$
socketChannel.write(ByteBuffer.wrap(new String(HEARTBEAT + "\r\n").getBytes())); //$NON-NLS-1$
}
} catch (Exception e) {
break;
}
// Iterate over the set of keys for which events are available
Iterator<SelectionKey> selectedKeys = socketSelector.selectedKeys().iterator();
while (selectedKeys.hasNext()) {
SelectionKey key = selectedKeys.next();
selectedKeys.remove();
if (!key.isValid()) {
continue;
}
try {
// Check what event is available and deal with it
if (key.isConnectable()) {
// Finish the connection. If the connection operation failed
// this will raise an IOException.
try {
socketChannel.finishConnect();
} catch (IOException e) {
// Cancel the channel's registration with our selector
key.cancel();
return;
}
// Register an interest in writing on this channel
key.interestOps(SelectionKey.OP_WRITE);
}
if (key.isWritable()) {
logger.trace(">" + LOGIN + WebConnector.getInstance().getUser()); //$NON-NLS-1$
socketChannel.write(ByteBuffer.wrap(new String(LOGIN + WebConnector.getInstance().getUser() + "\r\n").getBytes())); //$NON-NLS-1$
// Register an interest in reading on this channel
key.interestOps(SelectionKey.OP_READ);
}
if (key.isReadable()) {
dst.clear();
int readed = socketChannel.read(dst);
if (readed > 0) {
String[] s = new String(dst.array(), 0, readed).split("\r\n"); //$NON-NLS-1$
for (int i = 0; i < s.length; i++) {
logger.trace("<" + s[i]); //$NON-NLS-1$
if (s[i].endsWith(";" + WebConnector.getInstance().getUser() + ";")) { //$NON-NLS-1$ //$NON-NLS-2$
logger.trace(">" + UNKNOWN70); //$NON-NLS-1$
socketChannel.write(ByteBuffer.wrap(new String(UNKNOWN70 + "\r\n").getBytes())); //$NON-NLS-1$
logger.trace(">" + UNKNOWN55); //$NON-NLS-1$
socketChannel.write(ByteBuffer.wrap(new String(UNKNOWN55 + "\r\n").getBytes())); //$NON-NLS-1$
}
if (s[i].indexOf(";6;5;") != -1 || s[i].indexOf(";8;0;") != -1) { //$NON-NLS-1$ //$NON-NLS-2$
try {
OrderMonitor monitor = parseOrderLine(s[i]);
OrderDelta[] delta;
synchronized (orders) {
if (!orders.contains(monitor)) {
orders.add(monitor);
delta = new OrderDelta[] {
new OrderDelta(OrderDelta.KIND_ADDED, monitor)
};
}
else {
delta = new OrderDelta[] {
new OrderDelta(OrderDelta.KIND_UPDATED, monitor)
};
}
}
fireUpdateNotifications(delta);
if (monitor.getFilledQuantity() != null && monitor.getAveragePrice() != null) {
Account account = WebConnector.getInstance().getAccount();
account.updatePosition(monitor);
}
} catch (ParseException e) {
Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, "Error parsing line: " + s[i], e); //$NON-NLS-1$
Activator.log(status);
}
}
if (s[i].indexOf(";6;0;") != -1) { //$NON-NLS-1$
updateStatusLine(s[i]);
}
if (s[i].indexOf(";7;0;") != -1) { //$NON-NLS-1$
try {
positions.add(new Position(s[i]));
} catch (Exception e) {
Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, "Error parsing line: " + s[i], e); //$NON-NLS-1$
Activator.log(status);
}
}
if (s[i].indexOf(";7;9;") != -1) { //$NON-NLS-1$
Account account = WebConnector.getInstance().getAccount();
account.setPositions(positions.toArray(new Position[positions.size()]));
positions.clear();
}
}
}
}
} catch (Exception e) {
Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, "Connection error", e); //$NON-NLS-1$
Activator.log(status);
}
}
}
}
private static final int IDX_ID = 3;
private static final int IDX_STATUS = 4;
private static final int IDX_SYMBOL = 5;
private static final int IDX_PF_QUANTITY = 9;
private static final int IDX_AVERAGE_PRICE = 10;
private static final int IDX_QUANTITY = 15;
private static final int IDX_PRICE = 16;
private static final int IDX_SIDE = 18;
private static final int IDX_DATE = 19;
private static final int IDX_TIME = 20;
private static final int IDX_FILLED_QUANTITY = 25;
private SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd HHmmss"); //$NON-NLS-1$
private NumberFormat numberFormatter = NumberFormat.getInstance(Locale.US);
protected OrderMonitor parseOrderLine(String line) throws ParseException {
String[] item = line.split(";"); //$NON-NLS-1$
OrderMonitor tracker = null;
synchronized (orders) {
for (OrderMonitor m : orders) {
if (item[IDX_ID].equals(m.getId())) {
tracker = m;
break;
}
}
if (tracker == null) {
for (OrderMonitor m : orders) {
if (m.getId() == null && getSymbolFromSecurity(m.getOrder().getSecurity()).equals(item[IDX_SYMBOL])) {
tracker = m;
tracker.setId(item[IDX_ID]);
break;
}
}
}
}
if (tracker == null) {
Long quantity = !item[IDX_QUANTITY].equals("") ? Long.parseLong(item[IDX_QUANTITY]) : null; //$NON-NLS-1$
if (quantity == null && item.length > IDX_FILLED_QUANTITY && !item[IDX_FILLED_QUANTITY].equals("")) { //$NON-NLS-1$
try {
quantity = numberFormatter.parse(item[IDX_FILLED_QUANTITY]).longValue();
} catch (Exception e) {
}
}
Order order = new Order(null, !item[IDX_PRICE].equals("") ? IOrderType.Limit : IOrderType.Market, item[IDX_SIDE].equalsIgnoreCase("V") ? IOrderSide.Sell : IOrderSide.Buy, getSecurityFromSymbol(item[IDX_SYMBOL]), quantity, !item[IDX_PRICE].equals("") ? numberFormatter.parse(item[IDX_PRICE]).doubleValue() : null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
tracker = new OrderMonitor(WebConnector.getInstance(), BrokerConnector.getInstance(), order);
tracker.setId(item[IDX_ID]);
}
IOrder order = tracker.getOrder();
try {
Method classMethod = order.getClass().getMethod("setDate", Date.class); //$NON-NLS-1$
if (classMethod != null) {
if (item[IDX_TIME].length() < 6) {
item[IDX_TIME] = "0" + item[IDX_TIME]; //$NON-NLS-1$
}
classMethod.invoke(order, dateFormatter.parse(item[IDX_DATE] + " " + item[IDX_TIME])); //$NON-NLS-1$
}
} catch (Exception e) {
}
if (item[IDX_STATUS].equals("e") || item[IDX_STATUS].equals("e ")) { //$NON-NLS-1$ //$NON-NLS-2$
if (!item[IDX_AVERAGE_PRICE].equals("")) { //$NON-NLS-1$
try {
tracker.setAveragePrice(numberFormatter.parse(item[IDX_AVERAGE_PRICE]).doubleValue());
} catch (Exception e) {
}
}
else {
tracker.setAveragePrice(numberFormatter.parse(item[IDX_PRICE]).doubleValue());
}
if (!item[IDX_FILLED_QUANTITY].equals("")) { //$NON-NLS-1$
try {
tracker.setFilledQuantity(numberFormatter.parse(item[IDX_FILLED_QUANTITY]).longValue());
} catch (Exception e) {
}
}
}
IOrderStatus status = tracker.getStatus();
if (item[IDX_STATUS].equals("e") || item[IDX_STATUS].equals("e ")) { //$NON-NLS-1$ //$NON-NLS-2$
status = IOrderStatus.Filled;
}
else if (item[IDX_STATUS].equals("n") || item[IDX_STATUS].equals("n ") || item[IDX_STATUS].equals("j")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
status = IOrderStatus.PendingNew;
}
else if (item[IDX_STATUS].equals("zA") || item[IDX_STATUS].equals("z ")) { //$NON-NLS-1$ //$NON-NLS-2$
status = IOrderStatus.Canceled;
}
else if (item[IDX_STATUS].equals("na")) { //$NON-NLS-1$
status = IOrderStatus.PendingCancel;
}
else {
status = IOrderStatus.PendingNew;
}
if (status != IOrderStatus.Canceled) {
if (tracker.getFilledQuantity() != null && !tracker.getFilledQuantity().equals(order.getQuantity())) {
status = IOrderStatus.Partial;
}
}
if ((status == IOrderStatus.Filled || status == IOrderStatus.Canceled || status == IOrderStatus.Rejected) && tracker.getStatus() != status) {
tracker.setStatus(status);
if (logger.isInfoEnabled()) {
StringBuilder sb = new StringBuilder();
if (status == IOrderStatus.Filled) {
sb.append("Order Filled:");
}
else if (status == IOrderStatus.Canceled) {
sb.append("Order Canceled:");
}
else if (status == IOrderStatus.Rejected) {
sb.append("Order Rejected:");
}
if (tracker.getId() != null) {
sb.append(" id=" + tracker.getId() + ",");
}
sb.append(" instrument=" + tracker.getOrder().getSecurity().getName());
sb.append(", type=" + tracker.getOrder().getType());
sb.append(", side=" + tracker.getOrder().getSide());
sb.append(", qty=" + tracker.getOrder().getQuantity());
if (tracker.getOrder().getPrice() != null) {
sb.append(", price=" + tracker.getOrder().getPrice());
}
if (tracker.getOrder().getReference() != null) {
sb.append(", reference=" + tracker.getOrder().getReference());
}
logger.info(sb.toString());
}
tracker.fireOrderCompletedEvent();
}
else {
tracker.setStatus(status);
}
return tracker;
}
protected Position parsePositionLine(String line) {
String[] item = line.split(";"); //$NON-NLS-1$
ISecurity security = getSecurityFromSymbol(item[IDX_SYMBOL]);
Long quantity = Long.parseLong(item[IDX_PF_QUANTITY]);
Double price = Double.parseDouble(item[IDX_AVERAGE_PRICE]);
return new Position(security, quantity, price);
}
protected void updateStatusLine(String line) {
BundleContext context = Activator.getDefault().getBundle().getBundleContext();
ServiceReference serviceReference = context.getServiceReference(IStatusLineManager.class.getName());
if (serviceReference != null) {
IStatusLineManager statusLine = (IStatusLineManager) context.getService(serviceReference);
final StatusLineContributionItem contributionItem = (StatusLineContributionItem) statusLine.find(Activator.PLUGIN_ID);
try {
String[] item = line.split("\\;"); //$NON-NLS-1$
final double liquidity = amountParser.parse(item[3]).doubleValue();
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
contributionItem.setText(Messages.BrokerConnector_Liquidity + amountFormatter.format(liquidity));
}
});
} catch (Exception e) {
Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, "Error parsing line: " + line, e); //$NON-NLS-1$
Activator.log(status);
}
context.ungetService(serviceReference);
}
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.trading.IBroker#addOrderChangeListener(org.eclipsetrader.core.trading.IOrderChangeListener)
*/
@Override
public void addOrderChangeListener(IOrderChangeListener listener) {
listeners.add(listener);
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.trading.IBroker#removeOrderChangeListener(org.eclipsetrader.core.trading.IOrderChangeListener)
*/
@Override
public void removeOrderChangeListener(IOrderChangeListener listener) {
listeners.remove(listener);
}
protected void fireUpdateNotifications(OrderDelta[] deltas) {
if (deltas.length != 0) {
OrderChangeEvent event = new OrderChangeEvent(this, deltas);
Object[] l = listeners.getListeners();
for (int i = 0; i < l.length; i++) {
try {
((IOrderChangeListener) l[i]).orderChanged(event);
} catch (Throwable e) {
Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, "Error running listener", e); //$NON-NLS-1$
Activator.log(status);
}
}
}
}
public void addWithNotification(OrderMonitor orderMonitor) {
synchronized (orders) {
if (!orders.contains(orderMonitor)) {
orders.add(orderMonitor);
}
}
fireUpdateNotifications(new OrderDelta[] {
new OrderDelta(OrderDelta.KIND_ADDED, orderMonitor),
});
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.trading.IBroker#getAccounts()
*/
@Override
public IAccount[] getAccounts() {
return new IAccount[] {
WebConnector.getInstance().getAccount(),
};
}
}