I ran into a problem which seems to be a bug (or undocumented feature) in the API.
Please consider the following code snippet which runs in a separate thread to close an already submitted order.
console.getOut().println(mainCurrencyPair + ":ABOUT TO CLOSE POSITION: " + dateFormat.format(new Date(exitSignal.getTimeStamp())) + " expected profit: " + profit);
console.getOut().println(mainCurrencyPair + ":State just before closing: " + order.getState());
start = new Date();
// Close Order
Future<Object> exitFuture = context.executeTask(
new Callable<Object>() {
public Object call() {
// Wait for correct state before closing
int i = 0; int sleep = 1;
IOrder.State state = order.getState();
while(state == IOrder.State.CREATED){
// Sleep
order.waitForUpdate(sleep); // Thread.sleep(sleep);
i++;
// Increase sleep every 10 iterations
if(i%10 == 0) sleep*=2;
state = order.getState();
}
// Correct state reached, close order
state = order.getState();
if(state == IOrder.State.FILLED || state == IOrder.State.OPENED){
try {
console.getOut().println(mainCurrencyPair + ":Closing order after " + i + " iterations. state:" + state);
order.close();
} catch (JFException e) {
e.printStackTrace(console.getOut());
}
}else{
console.getOut().println(mainCurrencyPair + ":Order was already in closed/cancelled state. state:" + state);
}
return null;
}
});
// Wait till call() finishes
exitFuture.get();
stop = new Date();
console.getOut().println(mainCurrencyPair + ":Time to submit order.close() in milliseconds: " + (stop.getTime() - start.getTime()));
// Wait till order really reaches the closed or cancelled status
while(order.getState() != IOrder.State.CANCELED && order.getState() != IOrder.State.CLOSED){
console.getOut().println(mainCurrencyPair + ":Wait for order to reach close/cancelled status: current state: " + order.getState());
Thread.sleep(500);
}
While testing this code I noticed that sometimes the close() method is completely ignored when called on OPENED orders. I'm 100% sure the IOrder.close() method gets called and no errors occur since the output looks like this:
position id: 8187945
GBP/AUD:ABOUT TO PLACE ORDER!!!! BUY price: 1.7396 timeStamp: 2010-05-20 14:15:05:843
GBP/AUD:Time to get reference to Order in milliseconds: 1
GBP/AUD:ABOUT TO CLOSE POSITION: 2010-05-20 14:15:06:551 expected profit: 3.9999999999995595
GBP/AUD:State just before closing: OPENED
GBP/AUD:Closing order after 0 iterations. state:OPENED
GBP/AUD:Time to submit order.close() in milliseconds: 0
GBP/AUD:Wait for order to reach close/cancelled status: current state: OPENED
GBP/AUD:Wait for order to reach close/cancelled status: current state: FILLED
GBP/AUD:Wait for order to reach close/cancelled status: current state: FILLED
GBP/AUD:Wait for order to reach close/cancelled status: current state: FILLED
..... endless loop....
position id: 8193307
GBP/CHF:ABOUT TO PLACE ORDER!!!! SELL price: 1.6535 timeStamp: 2010-05-20 17:27:32:058
GBP/CHF:Time to get reference to Order in milliseconds: 1
GBP/CHF:ABOUT TO CLOSE POSITION: 2010-05-20 17:27:32:423 expected profit: -0.9999999999998899
GBP/CHF:State just before closing: OPENED
GBP/CHF:Closing order after 0 iterations. state:OPENED
GBP/CHF:Time to submit order.close() in milliseconds: 1
GBP/CHF:Wait for order to reach close/cancelled status: current state: OPENED
GBP/CHF:Wait for order to reach close/cancelled status: current state: FILLED
GBP/CHF:Wait for order to reach close/cancelled status: current state: FILLED
GBP/CHF:Wait for order to reach close/cancelled status: current state: FILLED
..... endless loop....
position id: 8236846
GBP/AUD:ABOUT TO PLACE ORDER!!!! SELL price: 1.74625 timeStamp: 2010-05-21 13:47:43:912
GBP/AUD:Time to get reference to Order in milliseconds: 0
GBP/AUD:ABOUT TO CLOSE POSITION: 2010-05-21 13:47:43:928 expected profit: -0.9999999999998899
GBP/AUD:State just before closing: CREATED
GBP/AUD:Closing order after 10 iterations. state:OPENED
close() called
GBP/AUD:Time to submit order.close() in milliseconds: 59
GBP/AUD:Wait for order to reach close/cancelled status: current state: OPENED
GBP/AUD:Wait for order to reach close/cancelled status: current state: FILLED
GBP/AUD:Wait for order to reach close/cancelled status: current state: FILLED
GBP/AUD:Wait for order to reach close/cancelled status: current state: FILLED
..... endless loop....
(I added a line 'console.getOut().println("close() called");' for the previous output directly after the order.close() to make sure the code actually reaches this line)
I would love to hear what I am doing wrong or how I can work around this bug/feature.
Thanks in advance,
Jan Snelders