See comments in the source code:
package jforex.charts;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import com.dukascopy.api.*;
import com.dukascopy.api.drawings.IChannelChartObject;
/**
* The strategy on its start plots a channel chart object on the chart.
* If the chart time frame does not match the one from parameters, the
* channel gets removed from the chart. As soon as the time frame is correct,
* the channel gets plotted
*
*/
@RequiresFullAccess
public class ChannelTimeFrames implements IStrategy {
private IHistory history;
private IChart chart;
private IConsole console;
private ScheduledExecutorService executor;
@Configurable("")
public Instrument instrument = Instrument.EURUSD;
@Configurable(value="Execution interval in milliseconds", description="decrease the interval for quicker execution")
public long execIntervalMillis = 1000;
@Configurable("Channel period")
public Period channelShowPeriod = Period.FIVE_MINS;
@Override
public void onStart(final IContext context) throws JFException {
history = context.getHistory();
console = context.getConsole();
chart = context.getChart(instrument);
if (chart == null){
console.getErr().println("No chart opened for "+ instrument + " can't plot the chart object!");
context.stop();
}
//get from history bars by shift 0 and 5 by chart time frame
Period period = chart.getSelectedPeriod();
OfferSide side = chart.getSelectedOfferSide();
IBar bar0 = history.getBar(instrument, period, side, 0);
IBar bar5 = history.getBar(instrument, period, side, 5);
//create and plot the chart object
IChannelChartObject channel = chart.getChartObjectFactory().createChannel("channelLine",
bar5.getTime(), bar5.getClose(),
bar0.getTime(), bar0.getClose(),
bar0.getTime(), bar5.getOpen()
);
chart.addToMainChart(channel);
//schedule the executor which checks chart time frame
final ChannelTask hlineTask = new ChannelTask(channel, channelShowPeriod);
executor = Executors.newSingleThreadScheduledExecutor();
Runnable periodicTask = new Runnable() {
public void run() {
context.executeTask(hlineTask);
}
};
executor.scheduleAtFixedRate(periodicTask, 0, execIntervalMillis, TimeUnit.MILLISECONDS);
}
private class ChannelTask implements Callable<Object>{
private final Period channelPeriod;
private final IChannelChartObject channel;
public ChannelTask(IChannelChartObject channel, Period channelPeriod) {
this.channel = channel;
this.channelPeriod = channelPeriod;
}
public Object call() throws Exception {
//wrong chart period and the channel is on the chart
if(chart.getSelectedPeriod() != channelPeriod && chart.getAll().contains(channel)){
chart.remove(channel);
console.getOut().println("Chart period is not " + channelPeriod + " - remove channel!");
//correct chart period and the channel is NOT on the chart
} else if (chart.getSelectedPeriod() == channelPeriod && !chart.getAll().contains(channel)) {
chart.addToMainChart(channel);
console.getOut().println("Chart period is " + channelPeriod + " - plot channel!");
}
return null;
}
}
@Override
public void onStop() throws JFException {
//Essential to call shutdown, otherwise the executor service will keep on running
executor.shutdown();
}
@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 {}
}