package com.activequant.trading.systems.sma;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import javax.script.ScriptException;
import com.activequant.domainmodel.ETransportType;
import com.activequant.domainmodel.MarketDataInstrument;
import com.activequant.domainmodel.TimeStamp;
import com.activequant.domainmodel.TradeableInstrument;
import com.activequant.domainmodel.exceptions.IncompleteOrderInstructions;
import com.activequant.domainmodel.exceptions.UnsupportedOrderType;
import com.activequant.domainmodel.streaming.MarketDataSnapshot;
import com.activequant.domainmodel.streaming.StreamEvent;
import com.activequant.domainmodel.trade.order.MarketOrder;
import com.activequant.domainmodel.trade.order.OrderSide;
import com.activequant.interfaces.trading.IOrderTracker;
import com.activequant.trading.AbstractTSBase;
import com.activequant.trading.datamodel.InstrumentTable;
import com.activequant.utils.RenjinCore;
/**
* Simple Moving Average class that processes a stream event.
*
* @author GhostRider
*
*/
public class SimpleMovingAverage extends AbstractTSBase {
private List<Double> midpoints = new ArrayList<Double>();
private RenjinCore R = new RenjinCore();
private double currentPos = 0;
private DecimalFormat dcf = new DecimalFormat("#.00");
private MarketDataInstrument mdi;
private TradeableInstrument tdi;
protected boolean isRunning = false;
@Override
public void start() throws Exception {
//
mdi = new MarketDataInstrument("CSV", "SOY");
tdi = new TradeableInstrument("CSV", "SOY");
// add to local memory environment.
addInstrument(mdi, tdi);
getInstrumentTable().setValueAt(0.01, getInstrumentTable().getRowIndexOf(mdi.getId()), InstrumentTable.Columns.TICKSIZE.colIdx());
getInstrumentTable().setValueAt(12.50, getInstrumentTable().getRowIndexOf(mdi.getId()), InstrumentTable.Columns.TICKVALUE.colIdx());
getInstrumentTable().signalUpdate();
isRunning = true;
}
@Override
public void stop() throws Exception {
isRunning = false;
}
public boolean isRunning(){
return isRunning;
}
/**
* Called if there is a new market stream data event.
*
*/
@Override
public void process(StreamEvent se) {
super.process(se);
TimeStamp ts = se.getTimeStamp();
if(se.getEventType().equals(ETransportType.MARKET_DATA) && se instanceof MarketDataSnapshot){
Double mid = ((MarketDataSnapshot)se).getBidPrices()[0] + ((MarketDataSnapshot)se).getAskPrices()[0];
mid /= 2.0;
midpoints.add(mid);
// restricting total length of our stored data ...
if(midpoints.size()>100)
midpoints.remove(0);
// size calculation
if(midpoints.size()==100){
// calculate some stuff.
try {
R.put("x", midpoints.toArray(new Double[]{}));
R.execute("summedValue = sum(x)");
Double sma = R.getDoubleVector("summedValue").getElementAsObject(0)/midpoints.size();
double tgtPos = Math.signum(mid - sma.doubleValue());
System.out.println(ts.getDate()+ " \tClose: " + dcf.format(mid) + " \tMean: " + dcf.format(sma) + "\tPos: " + dcf.format(tgtPos));
// creating orders ...
if(tgtPos != currentPos){
//
double posDifference = Math.abs(currentPos - tgtPos);
currentPos = tgtPos;
//
MarketOrder mo = new MarketOrder();
mo.setTradInstId(tdi.getId());
mo.setQuantity(posDifference);
mo.setOrderSide(tgtPos>0?OrderSide.BUY:OrderSide.SELL);
IOrderTracker ot = this.env.getExchange().prepareOrder(mo);
ot.submit();
}
} catch (ScriptException e) {
e.printStackTrace();
} catch (UnsupportedOrderType e) {
e.printStackTrace();
} catch (IncompleteOrderInstructions e) {
e.printStackTrace();
}
}
}
}
}