On Wed, Jul 20, 2011 at 10:21 PM, rv <[email protected]> wrote:
> None. There is no reference to jbt being disconnected before the
> following line :
>
>
Ok, good, this validates my theory. Here is what I think is happening.
Imagine the scenario when JBT submits an order, the TWS sends it to the
exchange, and the connection between TWS and IB is lost (which happens
occasionally). Next, the order is executed by the exchange, the
confirmation is sent to IB, and IB sends it back to TWS. Since TWS is at
this point disconnected from IB, the order confirmation never reaches TWS.
After the connection is restored, JBT would wait indefinitely for the
confirmation of execution. Another scenario is this: JBT submits an order,
connection between TWS and IB is lost immediately after, so the order never
reaches the IB. To work around these two situations, JBT has logic in place
which makes an explicit request for executions, and attempts to find the
order confirmation in the response. This logic kicks in after errorCode 1101
or errorCode 1102 are received, indicating that the connection was restored.
You can see this code in Trader.java. All of this works well, except that
sometimes, neither error code 1101 nor 1102 are sent after the reconnection.
As a result, JBT would never invoke the explicit check for executions. So,
as a fix to this problem, JBT also uses code 2104 as an indication that the
connection was restored, and uses this as a trigger for the check for
executions. See line 140 in Trader.java.
As it turns out, that code 2104 does not necessarily indicate that the
connection with TWS was lost, but instead that the data farm is "OK".
So, in your case, as indicated in your report, here is what happened:
21:22:05.001 everything is cool and connected, JBT places order 217
21:22:05.193 JBT gets the error 2104: Market data farm connection is
OK:aufarm
21:22:05.193 Because of error 2104, JBT thinks that there was a period of
disconnection, so it requests executions for order 217
21:22:05.232 Only 231 milliseconds have passed since order 217 was
submitted, so that order didn't get executed yet. However, JBT thinks that
since there is no record of order 217, it must have been because it never
reached IB because there was a disconnection.
21:22:06.001 JBT discards order 217 and places order 218
21:22:06.287 Order 218 is filled. Order 217 is also eventually filled, but
JBT had previously discarded it. The end result is that both order have been
executed, while JBT thinks only one got through.
So, that's the cause of the problem. As can be seen, Trader.java contains
some hacks to address bugs in IB API. However, this code was put long time
ago, and since them, the API was upgraded several times. So, it's quite
possible that these IB API bugs were fixed. If that's the case, then the fix
to your "double fill" problem is simply to replace line:
boolean isConnectivityRestored = (errorCode == 1101 || errorCode
== 1102 || errorCode == 2104);
with line
boolean isConnectivityRestored = (errorCode == 1101 || errorCode
== 1102);
No other code changes are necessary. However, if the IB API bug is still
there (failing to send 1101 or 1102 on reconnect), then we should look for
another solution. A fairly obvious alternative solution is to delay the
explicit request for executions after the reconnection by a couple of
seconds, if there is a pending order which was submitted recently (in the
previous couple of seconds, that is). That seems rather hacky, though. If
anyone can think of a better way to handle this, I am open to suggestions.
--
You received this message because you are subscribed to the Google Groups
"JBookTrader" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/jbooktrader?hl=en.