/*
* 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.ui.internal.views;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.events.IHyperlinkListener;
import org.eclipse.ui.forms.widgets.ImageHyperlink;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.part.ViewPart;
import org.eclipsetrader.core.feed.IBook;
import org.eclipsetrader.core.feed.IBookEntry;
import org.eclipsetrader.core.feed.IFeedConnector;
import org.eclipsetrader.core.feed.IFeedConnector2;
import org.eclipsetrader.core.feed.IFeedIdentifier;
import org.eclipsetrader.core.feed.IFeedService;
import org.eclipsetrader.core.feed.IFeedSubscription2;
import org.eclipsetrader.core.feed.ILastClose;
import org.eclipsetrader.core.feed.ISubscriptionListener;
import org.eclipsetrader.core.feed.ITodayOHL;
import org.eclipsetrader.core.feed.ITrade;
import org.eclipsetrader.core.feed.QuoteDelta;
import org.eclipsetrader.core.feed.QuoteEvent;
import org.eclipsetrader.core.instruments.ISecurity;
import org.eclipsetrader.core.internal.CoreActivator;
import org.eclipsetrader.core.markets.IMarket;
import org.eclipsetrader.core.markets.IMarketService;
import org.eclipsetrader.core.trading.IBroker;
import org.eclipsetrader.core.trading.ITradingService;
import org.eclipsetrader.ui.SelectionProvider;
import org.eclipsetrader.ui.UIConstants;
import org.eclipsetrader.ui.internal.UIActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public class Level2View extends ViewPart {
public static final String VIEW_ID = "org.eclipsetrader.ui.views.level2";
private static final String VIEW_TITLE_TOOLTIP = "Level II - {0}";
private IMarketService marketService;
private IFeedService feedService;
private Text symbol;
private Label activeConnector;
private Composite summaryGroup;
private Label time;
private Label volume;
private Label last;
private Label high;
private Label change;
private Label low;
private PressureBar pressureBar;
private Table table;
private DateFormat timeFormatter = DateFormat.getTimeInstance(SimpleDateFormat.MEDIUM);
private NumberFormat numberFormatter = NumberFormat.getInstance();
private NumberFormat priceFormatter = NumberFormat.getInstance();
private NumberFormat percentageFormatter = NumberFormat.getInstance();
private IMemento memento;
private IFeedConnector2 connector;
private IFeedSubscription2 subscription;
private ITrade lastTrade;
private ILastClose lastClose;
private IBook lastBook;
private IBook nextBook;
private Action showMarketMakerAction;
private Action hideSummaryAction;
private ISubscriptionListener subscriptionListener = new ISubscriptionListener() {
@Override
public void quoteUpdate(QuoteEvent event) {
onQuoteUpdate(event);
}
};
private SelectionAdapter connectionSelectionListener = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (e.widget.getData() instanceof IFeedConnector2) {
IFeedConnector2 newConnector = (IFeedConnector2) e.widget.getData();
onChangeConnector(newConnector);
}
}
};
private Runnable bookUpdateRunnable = new Runnable() {
@Override
public void run() {
if (table == null || table.isDisposed()) {
return;
}
if (lastBook != nextBook) {
onBookUpdate(lastBook = nextBook);
}
Display.getDefault().timerExec(100, bookUpdateRunnable);
}
};
public Level2View() {
numberFormatter.setGroupingUsed(true);
numberFormatter.setMinimumIntegerDigits(1);
numberFormatter.setMinimumFractionDigits(0);
numberFormatter.setMaximumFractionDigits(0);
priceFormatter.setGroupingUsed(true);
priceFormatter.setMinimumIntegerDigits(1);
priceFormatter.setMinimumFractionDigits(2);
priceFormatter.setMaximumFractionDigits(4);
percentageFormatter.setGroupingUsed(true);
percentageFormatter.setMinimumIntegerDigits(1);
percentageFormatter.setMinimumFractionDigits(2);
percentageFormatter.setMaximumFractionDigits(2);
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento)
*/
@Override
public void init(IViewSite site, IMemento memento) throws PartInitException {
super.init(site, memento);
this.memento = memento;
BundleContext context = CoreActivator.getDefault().getBundle().getBundleContext();
ServiceReference<IMarketService> marketServiceReference = context.getServiceReference(IMarketService.class);
marketService = context.getService(marketServiceReference);
ServiceReference<IFeedService> feedServiceReference = context.getServiceReference(IFeedService.class);
feedService = context.getService(feedServiceReference);
showMarketMakerAction = new Action("Show Market Maker", IAction.AS_CHECK_BOX) {
@Override
public void run() {
updateViewer();
if (lastBook != null) {
onBookUpdate(lastBook);
}
}
};
hideSummaryAction = new Action("Hide Summary", IAction.AS_CHECK_BOX) {
@Override
public void run() {
summaryGroup.setVisible(!isChecked());
((GridData) summaryGroup.getLayoutData()).exclude = isChecked();
summaryGroup.getParent().layout();
}
};
if (memento != null) {
hideSummaryAction.setChecked("true".equals(memento.getString("hide-summary")));
}
IActionBars actionBars = site.getActionBars();
IMenuManager menuManager = actionBars.getMenuManager();
menuManager.add(showMarketMakerAction);
menuManager.add(new Separator());
menuManager.add(hideSummaryAction);
actionBars.updateActionBars();
site.setSelectionProvider(new SelectionProvider());
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
@Override
public void createPartControl(Composite parent) {
Composite content = new Composite(parent, SWT.NONE);
GridLayout gridLayout = new GridLayout(1, false);
gridLayout.marginWidth = gridLayout.marginHeight = 0;
gridLayout.verticalSpacing = 0;
content.setLayout(gridLayout);
GC gc = new GC(content);
gc.setFont(JFaceResources.getDialogFont());
FontMetrics fontMetrics = gc.getFontMetrics();
gc.dispose();
Composite group = new Composite(content, SWT.NONE);
group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
group.setLayout(new GridLayout(4, false));
Label label = new Label(group, SWT.NONE);
label.setText("Symbol");
symbol = new Text(group, SWT.BORDER);
symbol.setLayoutData(new GridData(Dialog.convertWidthInCharsToPixels(fontMetrics, 15), SWT.DEFAULT));
symbol.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
onSetSymbol();
}
});
symbol.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetDefaultSelected(SelectionEvent e) {
onSetSymbol();
}
});
final ImageHyperlink connectorButton = new ImageHyperlink(group, SWT.NONE);
connectorButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
connectorButton.setImage(UIActivator.getDefault().getImageRegistry().get(UIConstants.TOOLBAR_ARROW_RIGHT));
connectorButton.setToolTipText("Select Data Source");
connectorButton.addHyperlinkListener(new IHyperlinkListener() {
private Menu dropDownMenu;
@Override
public void linkActivated(HyperlinkEvent e) {
if (dropDownMenu != null) {
dropDownMenu.dispose();
}
dropDownMenu = new Menu(connectorButton);
List<IFeedConnector> c = Arrays.asList(feedService.getConnectors());
Collections.sort(c, new Comparator<IFeedConnector>() {
@Override
public int compare(IFeedConnector o1, IFeedConnector o2) {
return o1.getName().compareTo(o2.getName());
}
});
for (IFeedConnector connector : c) {
if (connector instanceof IFeedConnector2) {
MenuItem menuItem = new MenuItem(dropDownMenu, SWT.CHECK);
menuItem.setText(connector.getName());
menuItem.setData(connector);
menuItem.setSelection(Level2View.this.connector == connector);
menuItem.addSelectionListener(connectionSelectionListener);
}
}
dropDownMenu.setVisible(true);
}
@Override
public void linkEntered(HyperlinkEvent e) {
}
@Override
public void linkExited(HyperlinkEvent e) {
}
});
activeConnector = new Label(group, SWT.NONE);
activeConnector.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
summaryGroup = createSummary(content);
if (hideSummaryAction != null) {
summaryGroup.setVisible(!hideSummaryAction.isChecked());
((GridData) summaryGroup.getLayoutData()).exclude = hideSummaryAction.isChecked();
}
pressureBar = new PressureBar(content, SWT.NONE);
GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
gridData.heightHint = 16;
pressureBar.getControl().setLayoutData(gridData);
createBookViewer(content);
if (memento != null) {
String s = memento.getString("symbol");
if (s != null) {
symbol.setText(s);
ISecurity security = getSecurityFromSymbol(s);
if (security != null) {
getSite().getSelectionProvider().setSelection(new StructuredSelection(security));
setPartName(security.getName());
setTitleToolTip(NLS.bind(VIEW_TITLE_TOOLTIP, new Object[] {
security.getName()
}));
}
}
String id = memento.getString("connector");
if (id != null) {
IFeedConnector connector = feedService.getConnector(id);
if (connector == null) {
connector = CoreActivator.getDefault().getDefaultConnector();
}
if (connector instanceof IFeedConnector2) {
this.connector = (IFeedConnector2) connector;
activeConnector.setText(this.connector.getName());
}
}
if (s != null && connector != null) {
subscription = this.connector.subscribeLevel2(s);
subscription.addSubscriptionListener(subscriptionListener);
lastClose = subscription.getLastClose();
lastTrade = subscription.getTrade();
update(subscription.getTodayOHL());
update();
}
}
Display.getDefault().timerExec(100, bookUpdateRunnable);
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.ViewPart#saveState(org.eclipse.ui.IMemento)
*/
@Override
public void saveState(IMemento memento) {
memento.putString("symbol", symbol.getText());
if (connector != null) {
memento.putString("connector", connector.getId());
}
if (hideSummaryAction.isChecked()) {
memento.putString("hide-summary", "true");
}
super.saveState(memento);
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#setFocus()
*/
@Override
public void setFocus() {
symbol.setFocus();
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#dispose()
*/
@Override
public void dispose() {
if (subscription != null) {
subscription.removeSubscriptionListener(subscriptionListener);
subscription.dispose();
}
BundleContext context = CoreActivator.getDefault().getBundle().getBundleContext();
ServiceReference<IMarketService> marketServiceReference = context.getServiceReference(IMarketService.class);
context.ungetService(marketServiceReference);
ServiceReference<IFeedService> feedServiceReference = context.getServiceReference(IFeedService.class);
context.ungetService(feedServiceReference);
super.dispose();
}
protected void createBookViewer(Composite parent) {
Composite content = new Composite(parent, SWT.NONE);
content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
TableColumnLayout tableLayout = new TableColumnLayout();
content.setLayout(tableLayout);
table = new Table(content, SWT.MULTI | SWT.FULL_SELECTION | SWT.NO_FOCUS | SWT.V_SCROLL);
table.setHeaderVisible(true);
table.setLinesVisible(false);
table.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
table.deselectAll();
}
});
ICommandService commandService = (ICommandService) getSite().getService(ICommandService.class);
IHandlerService handlerService = (IHandlerService) getSite().getService(IHandlerService.class);
new Level2QuickTradeDecorator(table, commandService, handlerService);
updateViewer();
}
protected void updateViewer() {
TableColumnLayout tableLayout = (TableColumnLayout) table.getParent().getLayout();
int columnIndex = 0;
TableColumn tableColumn;
if (showMarketMakerAction.isChecked()) {
tableColumn = columnIndex < table.getColumnCount() ? table.getColumn(columnIndex) : new TableColumn(table, SWT.CENTER);
tableColumn.setText("MM");
tableLayout.setColumnData(tableColumn, new ColumnWeightData(5));
columnIndex++;
}
tableColumn = columnIndex < table.getColumnCount() ? table.getColumn(columnIndex) : new TableColumn(table, SWT.CENTER);
tableColumn.setText("#");
tableLayout.setColumnData(tableColumn, new ColumnWeightData(showMarketMakerAction.isChecked() ? 5 : 6));
columnIndex++;
tableColumn = columnIndex < table.getColumnCount() ? table.getColumn(columnIndex) : new TableColumn(table, SWT.CENTER);
tableColumn.setText("Q.ty");
tableLayout.setColumnData(tableColumn, new ColumnWeightData(showMarketMakerAction.isChecked() ? 22 : 24));
columnIndex++;
tableColumn = columnIndex < table.getColumnCount() ? table.getColumn(columnIndex) : new TableColumn(table, SWT.CENTER);
tableColumn.setText("Bid");
tableLayout.setColumnData(tableColumn, new ColumnWeightData(showMarketMakerAction.isChecked() ? 18 : 20));
columnIndex++;
tableColumn = columnIndex < table.getColumnCount() ? table.getColumn(columnIndex) : new TableColumn(table, SWT.CENTER);
tableColumn.setText("Ask");
tableLayout.setColumnData(tableColumn, new ColumnWeightData(showMarketMakerAction.isChecked() ? 18 : 20));
columnIndex++;
tableColumn = columnIndex < table.getColumnCount() ? table.getColumn(columnIndex) : new TableColumn(table, SWT.CENTER);
tableColumn.setText("Q.ty");
tableLayout.setColumnData(tableColumn, new ColumnWeightData(showMarketMakerAction.isChecked() ? 21 : 24));
columnIndex++;
tableColumn = columnIndex < table.getColumnCount() ? table.getColumn(columnIndex) : new TableColumn(table, SWT.CENTER);
tableColumn.setText("#");
tableLayout.setColumnData(tableColumn, new ColumnWeightData(showMarketMakerAction.isChecked() ? 5 : 6));
columnIndex++;
if (showMarketMakerAction.isChecked()) {
tableColumn = columnIndex < table.getColumnCount() ? table.getColumn(columnIndex) : new TableColumn(table, SWT.CENTER);
tableColumn.setText("MM");
tableLayout.setColumnData(tableColumn, new ColumnWeightData(5));
columnIndex++;
}
while (table.getColumnCount() > columnIndex) {
table.getColumn(table.getColumnCount() - 1).dispose();
}
table.getParent().layout();
}
protected Composite createSummary(Composite parent) {
Composite content = new Composite(parent, SWT.NONE);
content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
GridLayout gridLayout = new GridLayout(4, false);
gridLayout.horizontalSpacing = gridLayout.horizontalSpacing * 2;
content.setLayout(gridLayout);
Label label = new Label(content, SWT.SEPARATOR | SWT.HORIZONTAL);
label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 4, 1));
label = new Label(content, SWT.NONE);
label.setText("Time");
time = new Label(content, SWT.RIGHT);
time.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
label = new Label(content, SWT.NONE);
label.setText("Volume");
volume = new Label(content, SWT.RIGHT);
volume.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
label = new Label(content, SWT.NONE);
label.setText("Last Price");
last = new Label(content, SWT.RIGHT);
last.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
label = new Label(content, SWT.NONE);
label.setText("High");
high = new Label(content, SWT.RIGHT);
high.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
label = new Label(content, SWT.NONE);
label.setText("Change");
change = new Label(content, SWT.RIGHT);
change.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
label = new Label(content, SWT.NONE);
label.setText("Low");
low = new Label(content, SWT.RIGHT);
low.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
return content;
}
protected void updateBid(TableItem tableItem, IBookEntry entry) {
int columnIndex = 0;
if (entry != null) {
if (showMarketMakerAction.isChecked()) {
String s = entry.getMarketMaker() != null ? entry.getMarketMaker() : "";
if (!s.equals(tableItem.getText(columnIndex))) {
tableItem.setText(columnIndex, s);
}
columnIndex++;
}
String s = numberFormatter.format(entry.getProposals());
if (!s.equals(tableItem.getText(columnIndex))) {
tableItem.setText(columnIndex, s);
}
columnIndex++;
s = numberFormatter.format(entry.getQuantity());
if (!s.equals(tableItem.getText(columnIndex))) {
tableItem.setText(columnIndex, s);
}
columnIndex++;
s = priceFormatter.format(entry.getPrice());
if (!s.equals(tableItem.getText(columnIndex))) {
tableItem.setText(columnIndex, s);
}
columnIndex++;
}
else {
if (showMarketMakerAction.isChecked()) {
tableItem.setText(columnIndex, "");
tableItem.setBackground(columnIndex++, null);
}
tableItem.setText(columnIndex, "");
tableItem.setBackground(columnIndex++, null);
tableItem.setText(columnIndex, "");
tableItem.setBackground(columnIndex++, null);
tableItem.setText(columnIndex, "");
tableItem.setBackground(columnIndex++, null);
}
tableItem.setData("bid", entry);
}
protected void updateAsk(TableItem tableItem, IBookEntry entry) {
int columnIndex = tableItem.getParent().getColumnCount() - 1;
if (entry != null) {
if (showMarketMakerAction.isChecked()) {
String s = entry.getMarketMaker() != null ? entry.getMarketMaker() : "";
if (!s.equals(tableItem.getText(columnIndex))) {
tableItem.setText(columnIndex, s);
}
columnIndex--;
}
String s = numberFormatter.format(entry.getProposals());
if (!s.equals(tableItem.getText(columnIndex))) {
tableItem.setText(columnIndex, s);
}
columnIndex--;
s = numberFormatter.format(entry.getQuantity());
if (!s.equals(tableItem.getText(columnIndex))) {
tableItem.setText(columnIndex, s);
}
columnIndex--;
s = priceFormatter.format(entry.getPrice());
if (!s.equals(tableItem.getText(columnIndex))) {
tableItem.setText(columnIndex, s);
}
columnIndex--;
}
else {
if (showMarketMakerAction.isChecked()) {
tableItem.setText(columnIndex, "");
tableItem.setBackground(columnIndex--, null);
}
tableItem.setText(columnIndex, "");
tableItem.setBackground(columnIndex--, null);
tableItem.setText(columnIndex, "");
tableItem.setBackground(columnIndex--, null);
tableItem.setText(columnIndex, "");
tableItem.setBackground(columnIndex--, null);
}
tableItem.setData("ask", entry);
}
protected void onBookUpdate(IBook book) {
IBookEntry[] bidEntries = book.getBidProposals();
IBookEntry[] askEntries = book.getAskProposals();
int rows = Math.max(bidEntries.length, askEntries.length);
table.setRedraw(false);
boolean doLayout = rows != table.getItemCount();
try {
for (int rowIndex = 0; rowIndex < rows; rowIndex++) {
TableItem tableItem = rowIndex < table.getItemCount() ? table.getItem(rowIndex) : new TableItem(table, SWT.NONE);
updateBid(tableItem, rowIndex < bidEntries.length ? bidEntries[rowIndex] : null);
updateAsk(tableItem, rowIndex < askEntries.length ? askEntries[rowIndex] : null);
}
while (table.getItemCount() > rows) {
table.getItem(table.getItemCount() - 1).dispose();
}
} finally {
table.setRedraw(true);
}
if (doLayout) {
table.layout();
table.getParent().layout();
table.layout();
table.getParent().layout();
}
long[] leftWeights = new long[Math.min(bidEntries.length, 5)];
for (int i = 0; i < leftWeights.length; i++) {
leftWeights[i] = bidEntries[i] != null && bidEntries[i].getQuantity() != null ? bidEntries[i].getQuantity() : 0;
}
long[] rightWeights = new long[Math.min(askEntries.length, 5)];
for (int i = 0; i < rightWeights.length; i++) {
rightWeights[i] = askEntries[i] != null && askEntries[i].getQuantity() != null ? askEntries[i].getQuantity() : 0;
}
pressureBar.setWeights(leftWeights, rightWeights);
}
protected void onSetSymbol() {
if (subscription != null && subscription.getSymbol().equals(symbol.getText())) {
return;
}
if (connector != null) {
if (subscription != null) {
subscription.removeSubscriptionListener(subscriptionListener);
subscription.dispose();
}
subscription = connector.subscribeLevel2(symbol.getText());
subscription.addSubscriptionListener(subscriptionListener);
lastClose = subscription.getLastClose();
lastTrade = subscription.getTrade();
update(subscription.getTodayOHL());
update();
IBook book = subscription.getBook();
if (book != null) {
onBookUpdate(book);
}
ISecurity security = getSecurityFromSymbol(symbol.getText());
if (security != null) {
getSite().getSelectionProvider().setSelection(new StructuredSelection(security));
setPartName(security.getName());
setTitleToolTip(NLS.bind(VIEW_TITLE_TOOLTIP, new Object[] {
security.getName()
}));
}
}
}
protected void onChangeConnector(IFeedConnector2 newConnector) {
if (newConnector != connector) {
if (connector != null && subscription != null) {
subscription.removeSubscriptionListener(subscriptionListener);
subscription.dispose();
subscription = null;
}
connector = newConnector;
activeConnector.setText(connector != null ? connector.getName() : "");
if (connector != null && !symbol.getText().equals("")) {
subscription = connector.subscribeLevel2(symbol.getText());
subscription.addSubscriptionListener(subscriptionListener);
lastClose = subscription.getLastClose();
lastTrade = subscription.getTrade();
update(subscription.getTodayOHL());
update();
IBook book = subscription.getBook();
if (book != null) {
onBookUpdate(book);
}
}
}
}
public void setSecurity(ISecurity security) {
IFeedConnector connector = null;
IMarket[] market = marketService.getMarkets();
for (int i = 0; i < market.length; i++) {
if (market[i].hasMember(security)) {
connector = market[i].getLiveFeedConnector();
break;
}
}
if (connector == null) {
connector = CoreActivator.getDefault().getDefaultConnector();
}
if (connector instanceof IFeedConnector2) {
this.connector = (IFeedConnector2) connector;
}
if (this.connector != null) {
activeConnector.setText(this.connector.getName());
if (subscription != null) {
subscription.removeSubscriptionListener(subscriptionListener);
subscription.dispose();
}
IFeedIdentifier feedIdentifier = (IFeedIdentifier) security.getAdapter(IFeedIdentifier.class);
if (feedIdentifier != null) {
subscription = this.connector.subscribeLevel2(feedIdentifier);
subscription.addSubscriptionListener(subscriptionListener);
symbol.setText(subscription.getSymbol());
lastClose = subscription.getLastClose();
lastTrade = subscription.getTrade();
update(subscription.getTodayOHL());
update();
IBook book = subscription.getBook();
if (book != null) {
onBookUpdate(book);
}
}
}
getSite().getSelectionProvider().setSelection(new StructuredSelection(security));
}
protected void onQuoteUpdate(final QuoteEvent event) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
if (table.isDisposed()) {
return;
}
QuoteDelta[] delta = event.getDelta();
for (int i = 0; i < delta.length; i++) {
if (delta[i].getNewValue() instanceof IBook) {
nextBook = (IBook) delta[i].getNewValue();
}
if (delta[i].getNewValue() instanceof ITrade) {
lastTrade = (ITrade) delta[i].getNewValue();
update();
}
if (delta[i].getNewValue() instanceof ITodayOHL) {
ITodayOHL todayOHL = (ITodayOHL) delta[i].getNewValue();
update(todayOHL);
}
if (delta[i].getNewValue() instanceof ILastClose) {
lastClose = (ILastClose) delta[i].getNewValue();
update();
}
}
}
});
}
protected void update() {
time.setText(lastTrade != null && lastTrade.getTime() != null ? timeFormatter.format(lastTrade.getTime()) : "");
last.setText(lastTrade != null && lastTrade.getPrice() != null ? priceFormatter.format(lastTrade.getPrice()) : "");
volume.setText(lastTrade != null && lastTrade.getVolume() != null ? numberFormatter.format(lastTrade.getVolume()) : "");
if (lastTrade != null && lastClose != null && lastClose.getPrice() != null && lastTrade.getPrice() != null) {
double changePercent = (lastTrade.getPrice() - lastClose.getPrice()) / lastClose.getPrice() * 100.0;
change.setText(NLS.bind("{0}{1}%", new Object[] {
changePercent < 0 ? "-" : changePercent > 0 ? "+" : "",
percentageFormatter.format(Math.abs(changePercent)),
}));
}
else {
change.setText("");
}
}
protected void update(ITodayOHL todayOHL) {
high.setText(todayOHL != null && todayOHL.getHigh() != null ? priceFormatter.format(todayOHL.getHigh()) : "");
low.setText(todayOHL != null && todayOHL.getLow() != null ? priceFormatter.format(todayOHL.getLow()) : "");
}
protected ISecurity getSecurityFromSymbol(String symbol) {
ISecurity security = null;
BundleContext context = UIActivator.getDefault().getBundle().getBundleContext();
ServiceReference serviceReference = context.getServiceReference(ITradingService.class.getName());
if (serviceReference != null) {
ITradingService service = (ITradingService) context.getService(serviceReference);
IBroker[] broker = service.getBrokers();
for (int i = 0; i < broker.length; i++) {
security = broker[i].getSecurityFromSymbol(symbol);
if (security != null) {
break;
}
}
context.ungetService(serviceReference);
}
return security;
}
}