Please pardon my asking, but are you sure?
(that
live bars are
always assembled server-side?)
This may not seem so important but for my implementation it would be very useful to know if live bars are assembled client-side.
Here is one of the reasons I doubt that bars are assembled server side:
In
viewtopic.php?f=5&t=4840&hilit=OnBar+CalledSupport wrote:
Function onBar() is called when a first tick of the next candle has arrived. If there isn't new ticks, then the onBar() is called after 1 second when the last tick came for the last candle.
If the bars are being sent from the server, then why is there a timeout based on tick arrivals? Suppose the bar from the server is lost on the way, and the one second timeout elapses, so onBar is called; what bar is passed into onBar then?
I have noticed that, when I slow down my connection, there is a tendency for onTick arrivals to lag behind onBar arrivals, but never the reverse. I.e. They can arrive too late for the IBar object, but the IBar object never arrives too late for the surrounding ticks. To provide you with some concrete data, I ran the following strategy, which provides information when a tick or bar arrives at the strategy out of logical sequence:
package jforex;
import java.util.*;
import java.io.*;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
import com.dukascopy.api.*;
public class TestEventSequence implements IStrategy {
private IEngine engine;
private IConsole console;
private IHistory history;
private IContext context;
private IIndicators indicators;
private IUserInterface userInterface;
private PrintStream out;
private SimpleDateFormat sdf;
private long lastTickTime;
private long lastBarGenTime;
private double lastTickBid = Double.NaN;
private double lastBarCloseBid = Double.NaN;
public void onStart(IContext context) throws JFException {
this.engine = context.getEngine();
this.console = context.getConsole();
this.history = context.getHistory();
this.context = context;
this.indicators = context.getIndicators();
this.userInterface = context.getUserInterface();
out = console.getOut();
out.println("starting");
sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss.SSS") {{setTimeZone(TimeZone.getTimeZone("GMT"));}};
}
public void onAccount(IAccount account) throws JFException {
}
public void onMessage(IMessage message) throws JFException {
}
public void onStop() throws JFException {
out.println("stopping");
}
public void onTick(Instrument instrument, ITick tick) throws JFException {
if(instrument != Instrument.EURUSD)
return;
long time = tick.getTime();
if(time < lastBarGenTime){
out.println("onTick(" + sdf.format(time) + ") called after onBar(" + sdf.format(lastBarGenTime) + ")");
out.println("...tick bid == " + tick.getBid() + " and last bar close == " + lastBarCloseBid + " and last tick bid == " + lastTickBid);
}
lastTickBid = tick.getBid();
lastTickTime = time;
}
public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
if(instrument != Instrument.EURUSD || period != Period.TEN_SECS)
return;
long time = bidBar.getTime() + period.getInterval();
if(time < lastTickTime){
out.println("onBar(" + sdf.format(time) + ") called after onTick(" + sdf.format(lastTickTime) + ")");
out.println("...close bid == " + bidBar.getClose() + " and last tick bid == " + lastTickBid);
}
lastBarCloseBid = bidBar.getClose();
lastBarGenTime = time;
}
}
Under normal circumstances, it prints nothing as expected. However, when I slowed down my internet connection, it printed this output (note that it is reversed, and I have added coloring for clarity):
10:41:10 stopping
10:41:04 ...tick bid ==
1.44072 and last bar close ==
1.44071 and last tick bid == 1.4407
10:41:04 onTick(2011.06.29 10:40:56.767) called after onBar(2011.06.29 10:
41:00.000)
10:41:04 ...tick bid == 1.4407 and last bar close == 1.44071 and last tick bid ==
1.4407110:41:04 onTick(2011.06.29 10:40:56.216) called after onBar(2011.06.29 10:
41:00.000)
10:40:51 ...tick bid ==
1.44081 and last bar close ==
1.4408 and last tick bid == 1.4408
10:40:51 onTick(2011.06.29 10:40:48.186) called after onBar(2011.06.29 10:
40:50.000)
10:40:51 ...tick bid == 1.4408 and last bar close == 1.4408 and last tick bid ==
1.440810:40:51 onTick(2011.06.29 10:40:47.265) called after onBar(2011.06.29 10:
40:50.000)
10:39:31 ...tick bid ==
1.44016 and last bar close ==
1.4402 and last tick bid == 1.44017
10:39:31 onTick(2011.06.29 10:39:29.998) called after onBar(2011.06.29 10:
39:30.000)
10:39:31 ...tick bid == 1.44017 and last bar close == 1.4402 and last tick bid == 1.44017
10:39:31 onTick(2011.06.29 10:39:29.456) called after onBar(2011.06.29 10:
39:30.000)
10:39:31 ...tick bid == 1.44017 and last bar close == 1.4402 and last tick bid == 1.44019
10:39:31 onTick(2011.06.29 10:39:28.896) called after onBar(2011.06.29 10:
39:30.000)
10:39:31 ...tick bid == 1.44019 and last bar close == 1.4402 and last tick bid ==
1.440210:39:31 onTick(2011.06.29 10:39:28.565) called after onBar(2011.06.29 10:
39:30.000)
10:38:03 ...tick bid ==
1.44006 and last bar close ==
1.44005 and last tick bid == 1.44005
10:38:03 onTick(2011.06.29 10:37:59.011) called after onBar(2011.06.29 10:
38:00.000)
10:38:03 ...tick bid == 1.44005 and last bar close == 1.44005 and last tick bid ==
1.4400510:38:03 onTick(2011.06.29 10:37:58.351) called after onBar(2011.06.29 10:
38:00.000)
10:37:30 starting
You can see from the log that if the ticks are delayed, we get a bar with close price based on the last tick received by the client at the time the bar is generated. If the bars are assembled server-side, then why is the close price wrong?