Package com.quantcomponents.ui.algo

Source Code of com.quantcomponents.ui.algo.TradingStatsView$TradeSeriesContentProvider

/*******************************************************************************
* 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.lang.reflect.InvocationTargetException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.part.ViewPart;

import com.quantcomponents.algo.ITradeStatsPoint;
import com.quantcomponents.algo.TradeStatsProcessor;
import com.quantcomponents.core.model.IMutableSeries;
import com.quantcomponents.core.model.ISeries;
import com.quantcomponents.core.model.ISeriesListener;
import com.quantcomponents.core.model.ISeriesPoint;
import com.quantcomponents.core.series.LinkedListSeries;
import com.quantcomponents.core.series.SimplePoint;
import com.quantcomponents.core.utils.LangUtils;

public class TradingStatsView extends ViewPart implements ISelectionListener, ISeriesListener<Date, Double> {
 
  private static class ExecutionInfo {
    public ExecutionInfo(TradeStatsProcessor processor, IMutableSeries<Date, Double, ISeriesPoint<Date, Double>> outputSeries) {
      this.processor = processor;
      this.outputSeries = outputSeries;
    }
    TradeStatsProcessor processor;
    IMutableSeries<Date, Double, ISeriesPoint<Date, Double>> outputSeries;
  }
 
  private class TradeSeriesContentProvider implements IStructuredContentProvider, ISeriesListener<Date, Double> {
    ISeries<Date, Double, ISeriesPoint<Date, Double>> data;
    final Deque<ITradeStatsPoint> trades = new LinkedList<ITradeStatsPoint>();

    @Override
    public void dispose() {
      if (data != null) {
        data.removeSeriesListener(this);
      }
    }

    @SuppressWarnings("unchecked")
    @Override
    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
      if (data != null) {
        data.removeSeriesListener(this);
      }
      if (newInput != null) {
        data = (ISeries<Date, Double, ISeriesPoint<Date,Double>>) newInput;
        fillTradeSeries();
        data.addSeriesListener(this);
      }
    }

    @Override
    public void onItemUpdated(ISeriesPoint<Date, Double> existingItem, ISeriesPoint<Date, Double> updatedItem) {
      if (updatedItem instanceof ITradeStatsPoint) {
        synchronized (this) {
          trades.removeLast();
          trades.addLast((ITradeStatsPoint) updatedItem);
        }
      }
    }

    @Override
    public void onItemAdded(ISeriesPoint<Date, Double> newItem) {
      if (newItem instanceof ITradeStatsPoint) {
        synchronized (this) {
          trades.addLast((ITradeStatsPoint) newItem);
        }
      }
    }

    @Override
    public synchronized Object[] getElements(Object inputElement) {
      return trades.toArray(new Object[trades.size()]);
    }
   
    private synchronized void fillTradeSeries() {
      trades.clear();
      for (ISeriesPoint<Date, Double> point : data) {
        if (point instanceof ITradeStatsPoint) {
          trades.add((ITradeStatsPoint) point);
        }
      }
    }
  }
 
  public static final String VIEW_ID = "com.quantcomponents.ui.algo.tradingStats";
  private static final int SORT_ASCENDING = 1;
  private final Map<TradingAgentExecutionWrapper, ExecutionInfo> executionMap = new HashMap<TradingAgentExecutionWrapper, ExecutionInfo>();
  private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
  private final DecimalFormat df = new DecimalFormat("0.00");
 
  private volatile Composite parent;
  private volatile TabFolder rootTabs;
  private volatile TabItem tabList;
  private volatile TabItem tabStats;
 
  private volatile TableViewer tradesTableViewer;
 
  private volatile Text bestTradeTimeDisplay;
  private volatile Text bestTradePnlDisplay;
  private volatile Text worstTradeTimeDisplay;
  private volatile Text worstTradePnlDisplay;
  private volatile Text maxDrawdownEndTimeDisplay;
  private volatile Text maxDrawdownValueDisplay;
  private volatile Text maxRunupEndTimeDisplay;
  private volatile Text maxRunupValueDisplay;
  private volatile Text lowestEquityTimeDisplay;
  private volatile Text lowestEquityValueDisplay;
  private volatile Text highestEquityTimeDisplay;
  private volatile Text highestEquityValueDisplay;
  private volatile ExecutionInfo currentExecutionInfo;

  @Override
  public void createPartControl(Composite parent) {
    this.parent = parent;
   
    rootTabs = new TabFolder(parent, SWT.NULL);
   
    tabList = new TabItem(rootTabs, SWT.NULL);
    tabList.setText("List");
   
    tabStats = new TabItem(rootTabs, SWT.NULL);
    tabStats.setText("Statistics");
   
    Composite tradesContainer = new Composite(rootTabs, SWT.NULL);
    tabList.setControl(tradesContainer);
   
    // ----------------------- TRADE TABLE ----------------------- //
    Composite listContainer = new Composite(rootTabs, SWT.NULL);
    tabList.setControl(listContainer);
    listContainer.setLayout(new FillLayout());
   
    tradesTableViewer = new TableViewer(listContainer, SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
   
    TableViewerColumn viewColDateTime = new TableViewerColumn(tradesTableViewer, SWT.NONE);
    viewColDateTime.setLabelProvider(new ColumnLabelProvider() {
      @Override
      public String getText(Object element) {
        ITradeStatsPoint t = (ITradeStatsPoint) element;
        return sdf.format(t.getIndex());
      }
    });
    TableColumn columnDateTime = viewColDateTime.getColumn();
    columnDateTime.setText("Time");
    columnDateTime.setWidth(140);
    columnDateTime.setResizable(true);
   
    TableViewerColumn viewColSide = new TableViewerColumn(tradesTableViewer, SWT.NONE);
    viewColSide.setLabelProvider(new ColumnLabelProvider() {
      @Override
      public String getText(Object element) {
        ITradeStatsPoint t = (ITradeStatsPoint) element;
        return t.getTrade().getOrder() != null ? t.getTrade().getOrder().getSide().name() : "";
      }
    });
    TableColumn columnSide = viewColSide.getColumn();
    columnSide.setText("Side");
    columnSide.setWidth(40);
    columnSide.setResizable(true);
   
    TableViewerColumn viewColSize = new TableViewerColumn(tradesTableViewer, SWT.NONE);
    viewColSize.setLabelProvider(new ColumnLabelProvider() {
      @Override
      public String getText(Object element) {
        ITradeStatsPoint t = (ITradeStatsPoint) element;
        return t.getTrade().getOrder() != null ? Integer.toString(t.getTrade().getOrder().getAmount()) : "";
      }
    });
    TableColumn columnSize = viewColSize.getColumn();
    columnSize.setText("Size");
    columnSize.setWidth(40);
    columnSize.setResizable(true);
   
    TableViewerColumn viewColExPrice = new TableViewerColumn(tradesTableViewer, SWT.RIGHT);
    viewColExPrice.setLabelProvider(new ColumnLabelProvider() {
      @Override
      public String getText(Object element) {
        ITradeStatsPoint t = (ITradeStatsPoint) element;
        return df.format(t.getTrade().getExecutionPrice());
      }
    });
    TableColumn columnExPrice = viewColExPrice.getColumn();
    columnExPrice.setText("Ex.Price");
    columnExPrice.setWidth(80);
    columnExPrice.setResizable(true);
   
    TableViewerColumn viewColAvgPrice = new TableViewerColumn(tradesTableViewer, SWT.RIGHT);
    viewColAvgPrice.setLabelProvider(new ColumnLabelProvider() {
      @Override
      public String getText(Object element) {
        ITradeStatsPoint t = (ITradeStatsPoint) element;
        return df.format(t.getTrade().getAveragePrice());
      }
    });
    TableColumn columnAvgPrice = viewColAvgPrice.getColumn();
    columnAvgPrice.setText("Avg.Price");
    columnAvgPrice.setWidth(80);
    columnAvgPrice.setResizable(true);
   
    TableViewerColumn viewColTradePnl = new TableViewerColumn(tradesTableViewer, SWT.RIGHT);
    viewColTradePnl.setLabelProvider(new ColumnLabelProvider() {
      @Override
      public String getText(Object element) {
        ITradeStatsPoint t = (ITradeStatsPoint) element;
        return df.format(t.getTradePnl());
      }
    });
    TableColumn columnTradePnl = viewColTradePnl.getColumn();
    columnTradePnl.setText("Trade P&&L");
    columnTradePnl.setWidth(80);
    columnTradePnl.setResizable(true);
   
    TableViewerColumn viewColMaxFavExc = new TableViewerColumn(tradesTableViewer, SWT.RIGHT);
    viewColMaxFavExc.setLabelProvider(new ColumnLabelProvider() {
      @Override
      public String getText(Object element) {
        ITradeStatsPoint t = (ITradeStatsPoint) element;
        return df.format(t.getMaxFavorableExcursion());
      }
    });
    TableColumn columnMaxFavExc = viewColMaxFavExc.getColumn();
    columnMaxFavExc.setText("Fav.Chg.");
    columnMaxFavExc.setWidth(80);
    columnMaxFavExc.setResizable(true);
   
    TableViewerColumn viewColMaxAdvExc = new TableViewerColumn(tradesTableViewer, SWT.RIGHT);
    viewColMaxAdvExc.setLabelProvider(new ColumnLabelProvider() {
      @Override
      public String getText(Object element) {
        ITradeStatsPoint t = (ITradeStatsPoint) element;
        return df.format(t.getMaxAdverseExcursion());
      }
    });
    TableColumn columnMaxAdvExc = viewColMaxAdvExc.getColumn();
    columnMaxAdvExc.setText("Adv.Chg.");
    columnMaxAdvExc.setWidth(80);
    columnMaxAdvExc.setResizable(true);
   
    Table table = tradesTableViewer.getTable();
    table.setHeaderVisible(true);
    table.setLinesVisible(true);
    table.setSortColumn(columnDateTime);
    table.setSortDirection(SORT_ASCENDING);
   
    tradesTableViewer.setContentProvider(new TradeSeriesContentProvider());

    // ----------------------- TRADE STATS ----------------------- //
    Composite statsContainer = new Composite(rootTabs, SWT.NULL);
    tabStats.setControl(statsContainer);
   
    statsContainer.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
    GridLayout rootLayout = new GridLayout();
    rootLayout.verticalSpacing = 10;
    rootLayout.numColumns = 3;
    statsContainer.setLayout(rootLayout);
   
    Label bestTradeLabel = new Label(statsContainer, SWT.NULL);
    bestTradeLabel.setText("Best trade");
    bestTradeTimeDisplay = new Text(statsContainer, SWT.READ_ONLY | SWT.BORDER);
    GridData bestTradeTimeDisplayGridData = new GridData();
    bestTradeTimeDisplayGridData.widthHint = 250;
    bestTradeTimeDisplay.setLayoutData(bestTradeTimeDisplayGridData);
    bestTradePnlDisplay = new Text(statsContainer, SWT.READ_ONLY | SWT.BORDER | SWT.RIGHT);
    GridData bestTradePnlDisplayGridData = new GridData();
    bestTradePnlDisplayGridData.widthHint = 100;
    bestTradePnlDisplay.setLayoutData(bestTradePnlDisplayGridData);
   
    Label worstTradeLabel = new Label(statsContainer, SWT.NULL);
    worstTradeLabel.setText("Worst trade");
    worstTradeTimeDisplay = new Text(statsContainer, SWT.READ_ONLY | SWT.BORDER);
    GridData worstTradeTimeDisplayGridData = new GridData();
    worstTradeTimeDisplayGridData.widthHint = 250;
    worstTradeTimeDisplay.setLayoutData(worstTradeTimeDisplayGridData);
    worstTradeTimeDisplay.setSize(400, 10);
    worstTradePnlDisplay = new Text(statsContainer, SWT.READ_ONLY | SWT.BORDER | SWT.RIGHT);
    GridData worstTradePnlDisplayGridData = new GridData();
    worstTradePnlDisplayGridData.widthHint = 100;
    worstTradePnlDisplay.setLayoutData(worstTradePnlDisplayGridData);

    Label maxDrawdownLabel = new Label(statsContainer, SWT.NULL);
    maxDrawdownLabel.setText("Max drawdown");
    maxDrawdownEndTimeDisplay = new Text(statsContainer, SWT.READ_ONLY | SWT.BORDER);
    GridData maxDrawdownEndTimeDisplayGridData = new GridData();
    maxDrawdownEndTimeDisplayGridData.widthHint = 250;
    maxDrawdownEndTimeDisplay.setLayoutData(maxDrawdownEndTimeDisplayGridData);
    maxDrawdownEndTimeDisplay.setSize(400, 10);
    maxDrawdownValueDisplay = new Text(statsContainer, SWT.READ_ONLY | SWT.BORDER | SWT.RIGHT);
    GridData maxDrawdownValueDisplayGridData = new GridData();
    maxDrawdownValueDisplayGridData.widthHint = 100;
    maxDrawdownValueDisplay.setLayoutData(maxDrawdownValueDisplayGridData);
   
    Label maxRunupLabel = new Label(statsContainer, SWT.NULL);
    maxRunupLabel.setText("Max runup");
    maxRunupEndTimeDisplay = new Text(statsContainer, SWT.READ_ONLY | SWT.BORDER);
    GridData maxRunupEndTimeDisplayGridData = new GridData();
    maxRunupEndTimeDisplayGridData.widthHint = 250;
    maxRunupEndTimeDisplay.setLayoutData(maxRunupEndTimeDisplayGridData);
    maxRunupEndTimeDisplay.setSize(400, 10);
    maxRunupValueDisplay = new Text(statsContainer, SWT.READ_ONLY | SWT.BORDER | SWT.RIGHT);
    GridData maxRunupValueDisplayGridData = new GridData();
    maxRunupValueDisplayGridData.widthHint = 100;
    maxRunupValueDisplay.setLayoutData(maxRunupValueDisplayGridData);
 
    Label lowestEquityPointLabel = new Label(statsContainer, SWT.NULL);
    lowestEquityPointLabel.setText("Lowest equity");
    lowestEquityTimeDisplay = new Text(statsContainer, SWT.READ_ONLY | SWT.BORDER);
    GridData lowestEquityTimeDisplayGridData = new GridData();
    lowestEquityTimeDisplayGridData.widthHint = 250;
    lowestEquityTimeDisplay.setLayoutData(lowestEquityTimeDisplayGridData);
    lowestEquityValueDisplay = new Text(statsContainer, SWT.READ_ONLY | SWT.BORDER | SWT.RIGHT);
    GridData lowestEquityValueDisplayGridData = new GridData();
    lowestEquityValueDisplayGridData.widthHint = 100;
    lowestEquityValueDisplay.setLayoutData(lowestEquityValueDisplayGridData);
   
    Label highestEquityPointLabel = new Label(statsContainer, SWT.NULL);
    highestEquityPointLabel.setText("Highest equity");
    highestEquityTimeDisplay = new Text(statsContainer, SWT.READ_ONLY | SWT.BORDER);
    GridData highestEquityTimeDisplayGridData = new GridData();
    highestEquityTimeDisplayGridData.widthHint = 250;
    highestEquityTimeDisplay.setLayoutData(highestEquityTimeDisplayGridData);
    highestEquityValueDisplay = new Text(statsContainer, SWT.READ_ONLY | SWT.BORDER | SWT.RIGHT);
    GridData highestEquityValueDisplayGridData = new GridData();
    highestEquityValueDisplayGridData.widthHint = 100;
    highestEquityValueDisplay.setLayoutData(highestEquityValueDisplayGridData);

    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) {
        final TradingAgentExecutionWrapper executionHandle = (TradingAgentExecutionWrapper) object;
        try {
          getViewSite().getWorkbenchWindow().run(true, false, new IRunnableWithProgress() {
            @Override
            public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
              try {
              ExecutionInfo executionInfo = executionMap.get(executionHandle);
              if (executionInfo == null) {
                TradeStatsProcessor processor = new TradeStatsProcessor();
                String processorOutputSeriesID = "output-" + processor.toString();
                ISeries<Date, Double, ISeriesPoint<Date, Double>> executionOutputSeries = executionHandle.getManager().getExecutionOutput(executionHandle.getHandle());
                executionInfo = new ExecutionInfo(processor, new LinkedListSeries<Date, Double, ISeriesPoint<Date, Double>>(processorOutputSeriesID, false));
                executionInfo.processor.wire(Collections.singletonMap(TradeStatsProcessor.INPUT_SERIES_NAME, executionOutputSeries) ,executionInfo.outputSeries);
                executionMap.put(executionHandle, executionInfo);
              }
              if (currentExecutionInfo != null) {
                currentExecutionInfo.outputSeries.removeSeriesListener(TradingStatsView.this);
              }
              currentExecutionInfo = executionInfo;
              currentExecutionInfo.outputSeries.addSeriesListener(TradingStatsView.this);
              TradingStatsView.this.parent.getDisplay().asyncExec(new Runnable() {
                @Override
                public void run() {
                  tradesTableViewer.setInput(currentExecutionInfo.outputSeries);
                }});
              updateStats();
              } catch (Exception e1) {
                e1.printStackTrace();
              }
            }});
        } catch (Exception e) {
          MessageDialog.openError(parent.getShell(), "Trading stats update failed", "Error while changing selection: " + LangUtils.exceptionMessage(e));
        }
      }
    }
  }
 
  @Override
  public void dispose() {
    for (ExecutionInfo executionInfo : executionMap.values()) {
      executionInfo.processor.unwire();
    }
  }
 
  private void updateStats() {
    final TradeStatsProcessor tradeStatsProcessor = currentExecutionInfo == null ? null : currentExecutionInfo.processor;
    if (tradeStatsProcessor != null) {
      parent.getDisplay().asyncExec(new Runnable() {
        @Override
        public void run() {
          ITradeStatsPoint bestTrade = tradeStatsProcessor.getBestTrade();
          if (bestTrade != null) {
            bestTradeTimeDisplay.setText(sdf.format(bestTrade.getIndex()));
            bestTradePnlDisplay.setText(df.format(bestTrade.getTradePnl()));
          } else {
            bestTradeTimeDisplay.setText("");
            bestTradePnlDisplay.setText("");
          }
          ITradeStatsPoint worstTrade = tradeStatsProcessor.getWorstTrade();
          if (worstTrade != null) {
            worstTradeTimeDisplay.setText(sdf.format(worstTrade.getIndex()));
            worstTradePnlDisplay.setText(df.format(worstTrade.getTradePnl()));
          } else {
            worstTradeTimeDisplay.setText("");
            worstTradePnlDisplay.setText("");
          }
          SimplePoint maxDDEnd = tradeStatsProcessor.getEndOfMaxDrawdown();
          if (maxDDEnd != null) {
            maxDrawdownEndTimeDisplay.setText(sdf.format(maxDDEnd.getIndex()));
            maxDrawdownValueDisplay.setText(df.format(maxDDEnd.getValue() - tradeStatsProcessor.getStartOfMaxDrawdown().getValue()));
          } else {
            maxDrawdownEndTimeDisplay.setText("");
            maxDrawdownValueDisplay.setText("");
          }
          SimplePoint maxRUEnd = tradeStatsProcessor.getEndOfMaxRunup();
          if (maxRUEnd != null) {
            maxRunupEndTimeDisplay.setText(sdf.format(maxRUEnd.getIndex()));
            maxRunupValueDisplay.setText(df.format(maxRUEnd.getValue() - tradeStatsProcessor.getStartOfMaxRunup().getValue()));
          } else {
            maxRunupEndTimeDisplay.setText("");
            maxRunupValueDisplay.setText("");
          }
          SimplePoint lowestEP = tradeStatsProcessor.getLowestEquityPoint();
          if (lowestEP != null) {
            lowestEquityTimeDisplay.setText(sdf.format(lowestEP.getIndex()));
            lowestEquityValueDisplay.setText(df.format(lowestEP.getValue()));
          } else {
            lowestEquityTimeDisplay.setText("");
            lowestEquityValueDisplay.setText("");
          }
          SimplePoint highestEP = tradeStatsProcessor.getHighestEquityPoint();
          if (highestEP != null) {
            highestEquityTimeDisplay.setText(sdf.format(highestEP.getIndex()));
            highestEquityValueDisplay.setText(df.format(highestEP.getValue()));
          } else {
            highestEquityTimeDisplay.setText("");
            highestEquityValueDisplay.setText("");
          }
          tradesTableViewer.refresh();
        }});
    }
  }
 
  @Override
  public void onItemUpdated(ISeriesPoint<Date, Double> existingItem, ISeriesPoint<Date, Double> updatedItem) {
    updateStats();
  }

  @Override
  public void onItemAdded(ISeriesPoint<Date, Double> newItem) {
    updateStats();
  }
}
TOP

Related Classes of com.quantcomponents.ui.algo.TradingStatsView$TradeSeriesContentProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.