package com.activequant.backtesting;
import java.util.Map;
import com.activequant.archive.MultiValueTimeSeriesIterator;
import com.activequant.domainmodel.OHLCV;
import com.activequant.domainmodel.TimeFrame;
import com.activequant.domainmodel.TimeStamp;
import com.activequant.domainmodel.Tuple;
import com.activequant.domainmodel.streaming.StreamEventIterator;
import com.activequant.domainmodel.streaming.TimeStreamEvent;
import com.activequant.interfaces.archive.IArchiveReader;
/**
*
* @author GhostRider
*
*/
public class ArchiveStreamToOHLCIterator extends StreamEventIterator<TimeStreamEvent> {
private String mdiId, tdiId;
private Double open, high, low, close, volume;
private int resInSeconds;
private long offset;
private String OPEN="OPEN", HIGH = "HIGH", LOW="LOW", CLOSE = "CLOSE", VOL="VOLUME";
private MultiValueTimeSeriesIterator streamIterator;
public ArchiveStreamToOHLCIterator(String mdiId, TimeFrame timeFrame, TimeStamp startTime, TimeStamp endTime, IArchiveReader archiveReader) throws Exception {
this.mdiId = mdiId;
this.tdiId = mdiId;
resInSeconds = timeFrame.getMinutes()*60;
offset = resInSeconds * 1000l * 1000l * 1000l;
this.streamIterator = archiveReader.getMultiValueStream(mdiId, startTime, endTime);
}
@Override
public boolean hasNext() {
return streamIterator.hasNext();
}
@Override
public OHLCV next() {
Tuple<TimeStamp, Map<String, Double>> valueMap = streamIterator.next();
if(valueMap.getB().containsKey(OPEN))open = valueMap.getB().get(OPEN);
if(valueMap.getB().containsKey(HIGH))high = valueMap.getB().get(HIGH);
if(valueMap.getB().containsKey(LOW))low = valueMap.getB().get(LOW);
if(valueMap.getB().containsKey(CLOSE))close = valueMap.getB().get(CLOSE);
if(valueMap.getB().containsKey(VOL))volume = valueMap.getB().get(VOL);
OHLCV o = new OHLCV();
o.setMdiId(mdiId);
o.setOpen(open);
o.setHigh(high);
o.setLow(low);
o.setClose(close);
o.setVolume(volume);
o.setResolutionInSeconds(resInSeconds);
// shift it, so that it looks as if it emitted at the end of a candle for replaying only
// NOTE: In live streaming mode and for charting, it is proper to stamp a candle with the beginning timestamp!!
o.setTimeStamp(new TimeStamp(valueMap.getA().getNanoseconds() + offset));
return o;
}
public long getOffset() {
return offset;
}
public void setOffset(long offset) {
this.offset = offset;
}
}