package com.activequant.utils.recorder;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.log4j.Logger;
import com.activequant.component.ComponentBase;
import com.activequant.domainmodel.OHLCV;
import com.activequant.domainmodel.TimeFrame;
import com.activequant.domainmodel.exceptions.TransportException;
import com.activequant.interfaces.archive.IArchiveFactory;
import com.activequant.interfaces.archive.IArchiveWriter;
import com.activequant.interfaces.transport.ITransportFactory;
import com.activequant.interfaces.utils.IEventListener;
import com.activequant.messages.AQMessages;
import com.activequant.messages.AQMessages.BaseMessage;
import com.activequant.messages.AQMessages.BaseMessage.CommandType;
import com.activequant.messages.Marshaller;
/**
* A market data snapshot recorder.
*
* @author GhostRider
*
*/
public class CandleRecorder extends ComponentBase {
private IArchiveFactory archiveFactory;
private ITransportFactory transFac;
private Logger log = Logger.getLogger(CandleRecorder.class);
final Timer t = new Timer(true);
final long collectionPhase = 5000l;
private TimeFrame tf;
private final ConcurrentLinkedQueue<OHLCV> collectionList = new ConcurrentLinkedQueue<OHLCV>();
private final Marshaller marshaller = new Marshaller();
private final IArchiveWriter writer;
class InternalTimerTask extends TimerTask {
@Override
public void run() {
Object o = collectionList.poll();
int counter = 0;
while (o != null) {
counter++;
store((OHLCV) o);
o = collectionList.poll();
}
log.info("Collected " + counter + " events. ");
if (counter > 0) {
try {
writer.commit();
} catch (IOException e) {
e.printStackTrace();
}
}
t.schedule(new InternalTimerTask(),
(collectionPhase - System.currentTimeMillis()
% collectionPhase));
}
public void store(OHLCV o) {
if (o == null)
return;
if(o.getOpen().equals(Double.NaN) || o.getHigh().equals(Double.NaN) ||
o.getLow().equals(Double.NaN)
|| o.getClose().equals(Double.NaN))
return;
writer.write(o.getMdiId(), o.getTimeStamp(), "OPEN", o.getOpen());
writer.write(o.getMdiId(), o.getTimeStamp(), "HIGH", o.getHigh());
writer.write(o.getMdiId(), o.getTimeStamp(), "LOW", o.getLow());
writer.write(o.getMdiId(), o.getTimeStamp(), "CLOSE", o.getClose());
if(o.getVolume()!=null)writer.write(o.getMdiId(), o.getTimeStamp(), "VOLUME",o.getVolume());
}
}
public CandleRecorder(IArchiveFactory archFac, ITransportFactory transFac,
TimeFrame tf, String mdiFile) throws Exception {
super("CandleRecorder " + tf, transFac);
this.tf = tf;
this.archiveFactory = archFac;
this.transFac = transFac;
writer = archiveFactory.getWriter(tf);
subscribe(mdiFile);
t.schedule(
new InternalTimerTask(),
(collectionPhase - System.currentTimeMillis() % collectionPhase));
}
private void subscribe(String mdiFile) throws IOException,
TransportException {
List<String> instruments = new ArrayList<String>();
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(mdiFile)));
String l = br.readLine();
while (l != null) {
if (!l.startsWith("#") && !l.isEmpty()) {
String symbol = l;
int depth = 1;
if (l.indexOf(";") != -1) {
String[] s = l.split(";");
symbol = s[0];
depth = Integer.parseInt(s[1]);
}
instruments.add(symbol);
}
l = br.readLine();
}
for (String s : instruments) {
OHLCV temp = new OHLCV();
temp.setResolutionInSeconds(tf.getMinutes() * 60);
temp.setMdiId(s);
transFac.getReceiver(temp.getId()).getRawEvent()
.addEventListener(new IEventListener<byte[]>() {
@Override
public void eventFired(byte[] event) {
BaseMessage bm;
try {
bm = marshaller.demarshall(event);
if (log.isDebugEnabled())
log.debug("Event type: " + bm.getType());
if (bm.getType().equals(CommandType.OHLC)) {
OHLCV o = marshaller.demarshall((AQMessages.OHLC) bm
.getExtension(AQMessages.OHLC.cmd));
o.setResolutionInSeconds(tf.getMinutes() * 60);
collectionList.add(o);
}
} catch (Exception e) {
e.printStackTrace();
log.warn("Exception: ", e);
}
}
});
}
}
@Override
public String getDescription() {
return "Candle recorder for timeframe " + tf;
}
}