History ticks
There are two main ways how one can retrieve tick data:
- by shift,
- by time interval.
This can be done both synchronously and asynchronously. See History bars article for synchronous vs asynchronous loading considerations.
Last tick
Assume that we need to get the last tick time, which is also perceived as the current time when back-testing. We obtain the ITick object by a call of getLastTick mehod and call on it getTime to get its time:
long currentTime = history.getLastTick(instrument).getTime();
To get the best ask price on the market of the last tick, use getAsk method :
double bestAskPrice = history.getLastTick(instrument).getAsk();
Note: Use tick.getAsks() to get top 10 best last tick ask prices.
Tick by shift
The getTick method returns an ITick by shift. Shift of value 0 refers to the last tick - thus it contains the current market price, 1 - previous tick, 2 - second to last tick. Consider retrieving last tick and previous tick:
ITick tick0 = history.getTick(Instrument.EURUSD, 0);
ITick tick1 = history.getTick(Instrument.EURUSD, 1);
console.getOut().println(String.format("last tick: %s; previous tick: %s", tick0, tick1));
Note: The getTick method is available starting with JForex-API 2.6.49.
Ticks by time interval
The getTicks method returns a list of ITicks over the given time interval. Both from and to times are inclusive, i.e. if tick time matches one of those values, it gets returned in the resulting list.
Consider retrieving ticks for 10 second interval that ends with the last tick time:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS") {{setTimeZone(TimeZone.getTimeZone("GMT"));}};
ITick lastTick = history.getLastTick(Instrument.EURUSD);
List<ITick> ticks = history.getTicks(Instrument.EURUSD, lastTick.getTime() - 10 * 1000, lastTick.getTime());
int last = ticks.size() - 1;
console.getOut().println(String.format(
"Tick count=%s; Latest bid price=%.5f, time=%s; Oldest bid price=%.5f, time=%s",
ticks.size(), ticks.get(last).getBid(), sdf.format(ticks.get(last).getTime()), ticks.get(0).getBid(), sdf.format(ticks.get(last).getTime())));
Follow the price dynamic
Consider a strategy which for each active order determines how many times since its fill a certain price level had been breached or fallen under:
package jforex.data;
import java.util.List;
import com.dukascopy.api.*;
import com.dukascopy.api.util.*;
public class PriceBreachAccordingToOrder implements IStrategy {
@Configurable("")
public Instrument instrument = Instrument.EURUSD;
private IHistory history;
private IConsole console;
private IEngine engine;
enum Location {
ABOVE,
BELOW
}
private Location priceLocation;
private double priceLevel;
@Override
public void onStart(IContext context) throws JFException {
history = context.getHistory();
console = context.getConsole();
engine = context.getEngine();
context.setSubscribedInstruments(java.util.Collections.singleton(Instrument.EURUSD), true);
ITick lastTick = history.getLastTick(instrument);
for(IOrder order : engine.getOrders(instrument)){
int breachCount = 0;
int fallCount = 0;
//choose as price level the order open price + 5pips
priceLevel = order.getOpenPrice() + instrument.getPipValue() * 5;
List<ITick> ticks = history.getTicks(instrument, order.getFillTime(), lastTick.getTime());
if(ticks == null || ticks.size() == 0){
console.getErr().println("There are no ticks between order fill time and the last tick");
continue;
}
priceLocation = ticks.get(0).getBid() >= priceLevel
? Location.ABOVE //the oldest tick price is above the target price
: Location.BELOW;
ticks.remove(0); //not to iterate over the already considered tick
for(ITick tick : ticks){
if(priceLocation == Location.ABOVE && tick.getBid() < priceLevel){
priceLocation = Location.BELOW;
fallCount++;
} else if(priceLocation == Location.BELOW && tick.getBid() > priceLevel){
priceLocation = Location.ABOVE;
breachCount++;
}
}
console.getOut().println(String.format(
"For order %s since its fill at %s the price level of %.5f was breached %s and fallen under %s times.",
order.getLabel(), DateUtils.format(order.getFillTime()), priceLevel, breachCount, fallCount
));
}
}
@Override
public void onTick(Instrument instrument, ITick tick) throws JFException {}
@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 {}
}
PriceBreachAccordingToOrder.java