/*
* 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.core.ats;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipsetrader.core.charts.DataSeries;
import org.eclipsetrader.core.feed.IBar;
import org.eclipsetrader.core.feed.IPricingListener;
import org.eclipsetrader.core.feed.ITrade;
import org.eclipsetrader.core.feed.PricingDelta;
import org.eclipsetrader.core.feed.PricingEvent;
import org.eclipsetrader.core.instruments.ISecurity;
import org.eclipsetrader.core.trading.IPosition;
import org.eclipsetrader.core.trading.ITransaction;
public class Report {
private final IStrategy strategy;
private final ITradingSystemContext context;
private final List<EquityData> equityData = new ArrayList<EquityData>();
private final Map<ISecurity, List<IBar>> barsData = new HashMap<ISecurity, List<IBar>>();
private class EquityData implements IAdaptable {
final Date date;
final Double amount;
public EquityData(Date date, Double amount) {
this.date = date;
this.amount = amount;
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
*/
@Override
@SuppressWarnings({
"unchecked", "rawtypes"
})
public Object getAdapter(Class adapter) {
if (adapter.isAssignableFrom(Date.class)) {
return date;
}
if (adapter.isAssignableFrom(Double.class)) {
return amount;
}
if (adapter.isAssignableFrom(getClass())) {
return this;
}
return null;
}
}
private final IPricingListener pricingListener = new IPricingListener() {
@Override
public void pricingUpdate(PricingEvent event) {
List<IBar> bars = barsData.get(event.getSecurity());
if (bars == null) {
bars = new ArrayList<IBar>();
barsData.put(event.getSecurity(), bars);
}
for (PricingDelta delta : event.getDelta()) {
if (!(delta.getNewValue() instanceof IBar)) {
continue;
}
bars.add((IBar) delta.getNewValue());
double amount = calculateCurrentEquity();
if (amount == 0.0) {
continue;
}
if (equityData.size() != 0) {
EquityData lastData = equityData.get(equityData.size() - 1);
if (lastData.amount == amount) {
continue;
}
}
equityData.add(new EquityData(((IBar) delta.getNewValue()).getDate(), amount));
}
}
};
public Report(IStrategy strategy, ITradingSystemContext context) {
this.strategy = strategy;
this.context = context;
context.getPricingEnvironment().addPricingListener(pricingListener);
}
public void dispose() {
context.getPricingEnvironment().removePricingListener(pricingListener);
equityData.clear();
}
public IStrategy getStrategy() {
return strategy;
}
public DataSeries getEquityData() {
DataSeries result = new DataSeries("Performance", equityData.toArray(new IAdaptable[equityData.size()]));
result.setHighest(result.getHighest());
result.setLowest(result.getLowest());
return result;
}
double calculateCurrentEquity() {
double result = context.getAccount().getBalance().getAmount();
for (IPosition position : context.getAccount().getPositions()) {
ITrade trade = context.getPricingEnvironment().getTrade(position.getSecurity());
result += position.getQuantity() * trade.getPrice();
}
return result;
}
public List<ITransaction> getTradesData() {
return Arrays.asList(context.getAccount().getTransactions());
}
public Map<ISecurity, List<IBar>> getBarsData() {
return barsData;
}
}