Argiris wrote:
It seems that API invokes IClient.ISystemListener.onDisconnect() approx 60 s after the outage actually started.
In general it is not the case - it depends on the disconnection reason.
Argiris wrote:
1. Can a trader program check whether the broker connection is actually up or down – prior to 'official' connection status change event (IClient.ISystemListener.onDisconnect())? What would you suggest (e.g. IEngine.getOrders() can't work without a live connection)?
As an alternative to handling
IClient.onDisconnect you can check if some action executes in time. You can also consider calling
IHistory.getLastTick. Consider the following strategy which checks if particular tasks get executed on time:
package jforex.test;
import com.dukascopy.api.*;
public class HistoryThreadTest4 implements IStrategy {
private IConsole console;
private IHistory history;
private IEngine engine;
@Configurable("patience (in seconds)")
public int patience = 3;
@Override
public void onStart(IContext context) throws JFException {
this.console = context.getConsole();
this.history = context.getHistory();
this.engine = context.getEngine();
print("test success (execute immediately)");
boolean onTime1= launchTask(new IFunction() {
@Override
public void execute() throws InterruptedException {
try {
console.getOut().println(" last tick: " + history.getLastTick(Instrument.EURUSD)
+ " active order count: " + engine.getOrders().size());
} catch (JFException e) {
console.getErr().println("-1 " + e);
}
}
}, patience);
print("test fail (execute for patience + 2 secs)");
boolean onTime2 = launchTask(new IFunction() {
@Override
public void execute() throws InterruptedException {
for (int i = 0; i < patience + 3; i++) {
Thread.sleep(1000);
try {
console.getOut().println(i + " last tick: " + history.getLastTick(Instrument.EURUSD)
+ " active order count: " + engine.getOrders().size());
} catch (JFException e) {
console.getErr().println("-1 " + e);
}
}
}
}, patience);
print("Task 1 on time: "+onTime1 +". Task 2 on time: " + onTime2);
context.stop();
}
private interface IFunction {
public void execute() throws InterruptedException;
}
/**
* Launches a task in a separate thread with expiry time
*
* @param function
* task
* @param expiryTime
* expiry time in seconds
* @return true if task succeeded to execute before the expiration time
*/
private boolean launchTask(final IFunction function, int expiryTime) {
long startTime = System.currentTimeMillis();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
function.execute();
} catch (InterruptedException e) {
console.getErr().println(Thread.currentThread().getName() + " got interrupted!");
}
}
});
t.start();
// loop until MessageLoop thread exits
while (t.isAlive()) {
// Wait maximum of 1 second for function thread to finish.
try {
t.join(1000);
} catch (InterruptedException e) {
console.getErr().println(e);
}
if (((System.currentTimeMillis() - startTime) > expiryTime * 1000) && t.isAlive()) {
print(Thread.currentThread().getName() + " expired!");
t.interrupt();
// wait indefinitely for the thread to get interrupted
try {
t.join();
} catch (InterruptedException e) {
console.getErr().println(e);
}
return false;
}
}
return true;
}
@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 {
}
private void print(Object o) {
console.getOut().println(o);
}
}
Attachment:
HistoryThreadTest4.java [3.36 KiB]
Downloaded 269 times
Argiris wrote:
2. What happens if a trader program calls IClient.reconnect() before API invoking onDisconnect(), when connection is still up officially?
This will create no negative effect - if the connection is there then it will take no action, if not - will try to reconnect.