It is not the case. Moreover you should not read synchronously such quantities of ticks, because you risk both to run out java heap space and overload the strategy thread with tasks. Consider doing it asynchronously by using the
IHistory.readTicks method:
package jforex.requests;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.ArrayBlockingQueue;
import com.dukascopy.api.*;
public class ReadTicksMultiInstrQueue implements IStrategy {
private IHistory history;
private IConsole console;
private IContext context;
@SuppressWarnings("serial")
private final SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss") { { setTimeZone(TimeZone.getTimeZone("GMT")); } };
@Configurable("from dd-MM-yyyy HH:mm:ss")
public String fromStr = "24-06-2012 21:00:00";
@Configurable("to dd-MM-yyyy HH:mm:ss")
public String toStr = "25-06-2012 12:00:00";
@Configurable("tick queue size")
private int queueSize = 5000;
private final Set<Instrument> instruments = new HashSet<Instrument>(Arrays.asList(new Instrument[] {
Instrument.CHFJPY,
Instrument.EURJPY,
Instrument.EURUSD,
Instrument.USDJPY
}));
private Map<Instrument, Queue<ITick>> insrtTickLists = new HashMap<Instrument, Queue<ITick>>();
private Map<Instrument, Boolean> insrtDataLoaded = new HashMap<Instrument, Boolean>();
@Override
public void onStart(IContext context) throws JFException {
history = context.getHistory();
console = context.getConsole();
this.context = context;
subscribeInstruments();
long from =0, to=0;
try {
from = sdf.parse(fromStr).getTime();
to = sdf.parse(toStr).getTime();
} catch (ParseException e) {
console.getErr().println(e + " on date parsing. The straetgy will stop.");
context.stop();
}
for(final Instrument instrument : instruments){
insrtDataLoaded.put(instrument, false);
final Queue<ITick> ticks = new ArrayBlockingQueue<ITick>(queueSize);
history.readTicks(instrument, from, to,
new LoadingDataListener(){
@Override
public void newTick(Instrument instrument, long time, double ask, double bid, double askVol, double bidVol) {
ticks.offer(new MockTick(time, ask, bid,askVol, bidVol));
}
@Override
public void newBar(Instrument instrument, Period period, OfferSide side, long time, double open, double close, double low,
double high, double vol) {
// no bars expected
}},
new LoadingProgressListener () {
@Override
public void dataLoaded(long start, long end, long currentPosition, String information) {
print("dataLoaded: instrument=%s, start=%s, end=%s, currentPosition=%s, information=%s",
instrument, sdf.format(start), sdf.format(end), sdf.format(currentPosition), information);
}
@Override
public void loadingFinished(boolean allDataLoaded, long start, long end, long currentPosition) {
print("loadingFinished: instrument=%s, allDataLoaded=%s, start=%s, end=%s, currentPosition=%s",
instrument, allDataLoaded, sdf.format(start), sdf.format(end), sdf.format(currentPosition));
insrtDataLoaded.put(instrument, true);
}
@Override
public boolean stopJob() {
// TODO Auto-generated method stub
return false;
}});
insrtTickLists.put(instrument, ticks);
}
}
private void subscribeInstruments(){
context.setSubscribedInstruments(instruments);
// wait max 1 second for the instruments to get subscribed
int i = 10;
while (!context.getSubscribedInstruments().containsAll(instruments)) {
try {
console.getOut().println("Instruments not subscribed yet " + i);
Thread.sleep(100);
} catch (InterruptedException e) {
console.getOut().println(e.getMessage());
}
i--;
}
}
private void print (String format, Object...args){
console.getOut().println(String.format(format, args));
}
@Override
public void onTick(Instrument instrument, ITick tick) throws JFException {
//perform logging attempt only on EUR/USD tick
if(instrument != Instrument.EURUSD){
return;
}
//log some info
boolean allLoadingFinished = true;
for(Map.Entry<Instrument, Queue<ITick>> entry : insrtTickLists.entrySet()){
Instrument instr = entry.getKey();
Queue<ITick> ticks = entry.getValue();
Boolean loaded = insrtDataLoaded.get(instr);
if(loaded.booleanValue()){
if(ticks.size() > 0){
print("%s loaded %s ticks, \n\t first tick=%s, \n\t last tick=%s",instr, ticks.size(), ticks.toArray()[0], ticks.toArray()[ticks.size() - 1]);
} else {
print("%s loading finished, but no ticks loaded",instr);
}
} else {
allLoadingFinished = false;
print("%s loading not finished, currently loaded %s ticks",instr, ticks.size());
}
}
if(allLoadingFinished){
print("All ticks loaded, stopping the strategy.");
context.stop();
}
}
@Override
public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {}
@Override
public void onMessage(IMessage message) throws JFException {}
@Override
public void onAccount(IAccount account) throws JFException {}
@Override
public void onStop() throws JFException {}
public class MockTick implements ITick {
long time;
double ask;
double bid;
double askVolume;
double bidVolume;
@SuppressWarnings("serial")
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS") {
{
setTimeZone(TimeZone.getTimeZone("GMT"));
}
};
private DecimalFormat df = new DecimalFormat("0.00000");
public MockTick (long time, double ask, double bid, double askVolume, double bidVolume){
this.ask = ask;
this.bid = bid;
this.askVolume = askVolume;
this.bidVolume = bidVolume;
this.time = time;
}
@Override
public long getTime() {
return time;
}
@Override
public double getAsk() {
return ask;
}
@Override
public double getBid() {
return bid;
}
@Override
public double getAskVolume() {
return askVolume;
}
@Override
public double getBidVolume() {
return bidVolume;
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append(time).append("[").append(sdf.format(time)).append("] Ask: ")
.append(df.format(ask)).append(" Bid: ").append(df.format(bid)).append(" AskVol: ").append(df.format(askVolume)).append(" BidVol: ")
.append(df.format(bidVolume));
return str.toString();
}
@Override
public double[] getAsks() {
return new double[]{getAsk()};
}
@Override
public double[] getBids() {
return new double[]{getBid()};
}
@Override
public double[] getAskVolumes() {
return new double[]{getAskVolume()};
}
@Override
public double[] getBidVolumes() {
return new double[]{getBidVolume()};
}
@Override
public double getTotalAskVolume() {
return 0.0;}
@Override
public double getTotalBidVolume() {
return 0.0;}
}
}