package com.activequant.backtesting;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.activequant.domainmodel.TimeStamp;
import com.activequant.domainmodel.trade.event.OrderAcceptedEvent;
import com.activequant.domainmodel.trade.event.OrderCancelledEvent;
import com.activequant.domainmodel.trade.event.OrderEvent;
import com.activequant.domainmodel.trade.event.OrderFillEvent;
import com.activequant.domainmodel.trade.order.OrderSide;
import com.activequant.interfaces.utils.IEventListener;
import com.activequant.timeseries.TSContainer2;
import com.activequant.timeseries.TSContainerMethods;
import com.activequant.timeseries.TypedColumn;
/**
*
* @author GhostRider
*
*/
public class OrderEventListener implements IEventListener<OrderEvent> {
private final List<OrderFillEvent> fillEvents = new ArrayList<OrderFillEvent>();
private final TSContainer2 changeOverTime = new TSContainer2("CHANGEOVERTIME", new ArrayList<String>(),
new ArrayList<TypedColumn>());
private final TSContainer2 positionOverTime = new TSContainer2("POSITIONSOVERTIME", new ArrayList<String>(),
new ArrayList<TypedColumn>());
private final TSContainer2 executionOverTime = new TSContainer2("POSITIONVALUATION", new ArrayList<String>(),
new ArrayList<TypedColumn>());
private final Map<String, Double> currentPos = new HashMap<String, Double>();
private final Map<String, TimeStamp> refTimeStamp = new HashMap<String, TimeStamp>();
private final Map<String, Double> currentChange = new HashMap<String, Double>();
private final Map<String, Integer> placed = new HashMap<String, Integer>();
private final Map<String, Integer> fills = new HashMap<String, Integer>();
private final Map<String, Integer> cancellations = new HashMap<String, Integer>();
private final Map<String, Integer> updates = new HashMap<String, Integer>();
private IFeeCalculator feeCalculator = null;
public OrderEventListener(){
}
@Override
public void eventFired(OrderEvent event) {
if (event instanceof OrderFillEvent) {
OrderFillEvent ofe = (OrderFillEvent) event;
if(ofe.getFillAmount()!=0.0)fillEvents.add(ofe);
trackFill(ofe.getOptionalInstId(), ofe.getTimeStamp(), ofe.getFillAmount()
* (ofe.getSide().equals(OrderSide.BUY) ? 1.0 : -1.0), ofe.getFillPrice());
countFill(ofe.getOptionalInstId());
} else if (event instanceof OrderCancelledEvent) {
countCancellation(((OrderCancelledEvent) event).getOptionalInstId());
} else if (event instanceof OrderAcceptedEvent) {
countAccepted(((OrderAcceptedEvent) event).getOptionalInstId());
}
if(feeCalculator != null)
feeCalculator.track(event);
}
private void trackFill(String tdiId, TimeStamp ts, double change, double price) {
Double val = currentPos.get(tdiId);
if (val == null)
val = 0.0;
val = val + change;
currentPos.put(tdiId, val);
positionOverTime.setValue(tdiId, ts, val);
executionOverTime.setValue(tdiId, ts, price);
TimeStamp ref = refTimeStamp.get(tdiId);
Double cc = 0.0;
if (ref != null) {
if(ref.getNanoseconds() != ts.getNanoseconds()){
refTimeStamp.put(tdiId, ts);
}
else
cc = currentChange.get(tdiId);
}
else
refTimeStamp.put(tdiId, ts);
cc+=change;
currentChange.put(tdiId, cc);
if(cc!=0.0)changeOverTime.setValue(tdiId, ts, cc);
}
private void countAccepted(String id) {
// count it.
Integer val = placed.get(id);
if (val == null)
val = 0;
val += 1;
placed.put(id, val);
}
private void countFill(String id) {
// count it.
Integer val = fills.get(id);
if (val == null)
val = 0;
val += 1;
fills.put(id, val);
}
private void countCancellation(String id) {
// count it.
Integer val = cancellations.get(id);
if (val == null)
val = 0;
val += 1;
cancellations.put(id, val);
}
private void countUpdate(String id) {
// count it.
Integer val = updates.get(id);
if (val == null)
val = 0;
val += 1;
updates.put(id, val);
}
public List<OrderFillEvent> getFillEvents() {
return fillEvents;
}
public TSContainer2 getPositionOverTime() {
// overwrite all nulls with former value.
TSContainerMethods tcm = new TSContainerMethods();
return tcm.overwriteNull(positionOverTime);
}
public TSContainer2 getExecutionOverTime() {
// overwrite all nulls with former value.
TSContainerMethods tcm = new TSContainerMethods();
return tcm.overwriteNull(executionOverTime, 0.0);
}
public TSContainer2 getChangeOverTime() {
// overwrite all nulls with former value.
TSContainerMethods tcm = new TSContainerMethods();
return tcm.overwriteNull(changeOverTime, 0.0);
}
public Map<String, Integer> getFills() {
return fills;
}
public Map<String, Integer> getCancellations() {
return cancellations;
}
public Map<String, Integer> getUpdates() {
return updates;
}
public Map<String, Integer> getPlaced() {
return placed;
}
public IFeeCalculator getFeeCalculator() {
return feeCalculator;
}
public void setFeeCalculator(IFeeCalculator feeCalculator) {
this.feeCalculator = feeCalculator;
}
}