/******************************************************************************* * Copyright (c) 2013 Luigi Sgro. 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: * Luigi Sgro - initial API and implementation ******************************************************************************/ package com.quantcomponents.ui.algo; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.Date; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.part.ViewPart; import com.quantcomponents.algo.IPositionPoint; import com.quantcomponents.core.model.IContract; import com.quantcomponents.core.model.ISeries; import com.quantcomponents.core.model.ISeriesListener; import com.quantcomponents.core.model.ISeriesPoint; import com.quantcomponents.core.model.beans.ContractBase; public class PositionView extends ViewPart implements ISelectionListener { private class ExecutionInfo implements ISeriesListener<Date, Double> { TradingAgentExecutionWrapper executionWrapper; ISeries<Date, Double, ISeriesPoint<Date, Double>> executionOutput; Map<IContract, IPositionPoint> positionMap = new ConcurrentHashMap<IContract, IPositionPoint>(); public ExecutionInfo(TradingAgentExecutionWrapper executionWrapper) { this.executionWrapper = executionWrapper; this.executionOutput = executionWrapper.getManager().getExecutionOutput(executionWrapper.getHandle()); for (ISeriesPoint<Date, Double> point : executionOutput) { if (point instanceof IPositionPoint) { onItemAdded((IPositionPoint) point); } } this.executionOutput.addSeriesListener(this); } public void dispose() { executionOutput.removeSeriesListener(this); } @Override public void onItemUpdated(ISeriesPoint<Date, Double> existingItem, ISeriesPoint<Date, Double> updatedItem) { if (updatedItem instanceof IPositionPoint) { IPositionPoint positionPoint = (IPositionPoint) updatedItem; positionMap.put(positionPoint.getContract(), positionPoint); executionUpdated(this); } } @Override public void onItemAdded(ISeriesPoint<Date, Double> newItem) { onItemUpdated(null, newItem); } } public static final String VIEW_ID = "com.quantcomponents.ui.algo.positions"; private static final int SORT_ASCENDING = 1; private final Map<TradingAgentExecutionWrapper, ExecutionInfo> executionMap = new ConcurrentHashMap<TradingAgentExecutionWrapper, ExecutionInfo>(); private final NumberFormat priceFormat = new DecimalFormat("0.000"); private final NumberFormat positionFormat = new DecimalFormat("0.##"); private volatile Composite parent; private volatile ExecutionInfo currentExecutionInfo; private volatile TableViewer positionListViewer; @Override public void createPartControl(Composite parent) { this.parent = parent; positionListViewer = new TableViewer(parent, SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); TableViewerColumn viewColContract = new TableViewerColumn(positionListViewer, SWT.NONE); viewColContract.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { IPositionPoint p = (IPositionPoint)element; return ContractBase.shortStringRepr(p.getContract()); }}); TableColumn columnContract = viewColContract.getColumn(); columnContract.setText("Contract"); columnContract.setWidth(120); columnContract.setResizable(true); TableViewerColumn viewColPosition = new TableViewerColumn(positionListViewer, SWT.RIGHT); viewColPosition.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { IPositionPoint p = (IPositionPoint)element; return positionFormat.format(p.getPosition().getSignedAmount()); }}); TableColumn columnPosition = viewColPosition.getColumn(); columnPosition.setText("Position"); columnPosition.setWidth(80); columnPosition.setResizable(true); TableViewerColumn viewColMktPrice = new TableViewerColumn(positionListViewer, SWT.RIGHT); viewColMktPrice.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { IPositionPoint p = (IPositionPoint)element; return priceFormat.format(p.getPosition().getMarketPrice()); }}); TableColumn columnMktPrice = viewColMktPrice.getColumn(); columnMktPrice.setText("Mkt Price"); columnMktPrice.setWidth(100); columnMktPrice.setResizable(true); TableViewerColumn viewColMktValue = new TableViewerColumn(positionListViewer, SWT.RIGHT); viewColMktValue.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { IPositionPoint p = (IPositionPoint)element; return priceFormat.format(p.getPosition().getMarketValue()); }}); TableColumn columnMktValue = viewColMktValue.getColumn(); columnMktValue.setText("Mkt Value"); columnMktValue.setWidth(100); columnMktValue.setResizable(true); TableViewerColumn viewColAvgPrice = new TableViewerColumn(positionListViewer, SWT.RIGHT); viewColAvgPrice.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { IPositionPoint p = (IPositionPoint)element; return priceFormat.format(p.getPosition().getAveragePrice()); }}); TableColumn columnAvgPrice = viewColAvgPrice.getColumn(); columnAvgPrice.setText("Avg Price"); columnAvgPrice.setWidth(100); columnAvgPrice.setResizable(true); TableViewerColumn viewColUnrPnl = new TableViewerColumn(positionListViewer, SWT.RIGHT); viewColUnrPnl.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { IPositionPoint p = (IPositionPoint)element; return priceFormat.format(p.getPosition().getUnrealizedPnl()); }}); TableColumn columnUnrPnl = viewColUnrPnl.getColumn(); columnUnrPnl.setText("Unr P&&L"); columnUnrPnl.setWidth(100); columnUnrPnl.setResizable(true); TableViewerColumn viewColRealPnl = new TableViewerColumn(positionListViewer, SWT.RIGHT); viewColRealPnl.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { IPositionPoint p = (IPositionPoint)element; return priceFormat.format(p.getPosition().getRealizedPnl()); }}); TableColumn columnRealPnl = viewColRealPnl.getColumn(); columnRealPnl.setText("Real P&&L"); columnRealPnl.setWidth(100); columnRealPnl.setResizable(true); Table table = positionListViewer.getTable(); table.setHeaderVisible(true); table.setLinesVisible(true); table.setSortColumn(columnContract); table.setSortDirection(SORT_ASCENDING); positionListViewer.setContentProvider(new ArrayContentProvider()); getSite().getPage().addSelectionListener(this); selectionChanged(null, getSite().getPage().getSelection()); } @Override public void setFocus() { } @Override public void selectionChanged(IWorkbenchPart part, ISelection selection) { if (selection instanceof IStructuredSelection) { IStructuredSelection structured = (IStructuredSelection) selection; Object object = structured.getFirstElement(); if (object instanceof TradingAgentExecutionWrapper) { TradingAgentExecutionWrapper executionWrapper = (TradingAgentExecutionWrapper) object; if (currentExecutionInfo == null || currentExecutionInfo.executionWrapper != executionWrapper) { ExecutionInfo executionInfo = executionMap.get(executionWrapper); if (executionInfo == null) { executionInfo = new ExecutionInfo(executionWrapper); executionMap.put(executionWrapper, executionInfo); } currentExecutionInfo = executionInfo; executionUpdated(currentExecutionInfo); } } } } @Override public void dispose() { for (ExecutionInfo executionInfo : executionMap.values()) { executionInfo.dispose(); } } private void executionUpdated(final ExecutionInfo executionInfo) { if (executionInfo == currentExecutionInfo) { PositionView.this.parent.getDisplay().asyncExec(new Runnable() { @Override public void run() { positionListViewer.setInput(executionInfo.positionMap.values()); }}); } } }