Skip to content
This repository has been archived by the owner on Mar 14, 2024. It is now read-only.

Cancellation of inactive orders #363

Open
dmoklaf opened this issue Apr 30, 2021 · 4 comments
Open

Cancellation of inactive orders #363

dmoklaf opened this issue Apr 30, 2021 · 4 comments

Comments

@dmoklaf
Copy link

dmoklaf commented Apr 30, 2021

The code managing the cancellation of inactive orders (

or status == OrderStatus.Inactive):
)
declares them immediately as Cancelled, as opposed to PendingCancel. There is one common case where this seems premature: unavailable shares to short. In these case, IB declares the order as inactive, but it is still looking for these shares and could at any moment execute the order should new borrowable shares become available (I practice short-selling quite a lot and this is often unpredictable).
To handle these cases properly inactive orders shall be removed from this condition, i.e. declared as PendingCancel until the server confirms the effective cancellation.

Note: I have only a cursory understanding of how the library and the IB API interact so I may be completely wrong. For example I don't know if the server does send a cancellation confirmation for inactive orders.

@erdewit
Copy link
Owner

erdewit commented May 3, 2021

When canceling an Inactive order, IBKR sometimes does not send a status update back. This leaves the order hanging in the PendingCancel state forever. To prevent that, Inactive orders are set to Cancelled right away when canceled. You are right that there's still a time window (in the order of 100 ms) where it could be filled.

@erdewit erdewit closed this as completed May 3, 2021
@dmoklaf
Copy link
Author

dmoklaf commented May 3, 2021

I have had cases like that, with high-volume high-frequency low-quantity orders.

One solution could be to launch an asynchronous task which sleeps 3 seconds, checks the state and if it is not cancelled switches it to cancelled and emits the appropriate events. That would definitely kill my cases which were very tight in terms of timing, as you mentionned.

That would require a careful review of the lib code to be sure that we do not create race conditions with the rest of the code that depends on this status. However as the library is cleanly modularized and fully async( same thread which simplifies race condition analysis - we only look for await statements) this analysis seems doable:

I just had a look into the wrapper code, it does not use a single await or has any async method. Consequently this asynchronous task would never interfere with ongoing wrapper method execution (it would be executed either before or after any wrapper method, but never in parallel). But maybe I am missing a bigger risk outside of the wrapper class.

@erdewit
Copy link
Owner

erdewit commented May 4, 2021

One solution could be to launch an asynchronous task which sleeps 3 seconds, checks the state and if it is not cancelled switches it to cancelled and emits the appropriate events

I think that's a good idea.

@erdewit erdewit reopened this May 4, 2021
@goodboy
Copy link

goodboy commented Aug 9, 2022

I actually just ran into this as well particularly when firing lots of orders and then quickly cancelling right away in a batch.

I might put up a patch for this and test in our production stuff 🏄🏼

goodboy added a commit to pikers/piker that referenced this issue Aug 17, 2022
We were overwriting the existing loaded orders list in the per client
loop (lul) so move the def above all that.

Comment out the "try-to-cancel-inactive-orders-via-task-after-timeout"
stuff pertaining to erdewit/ib_insync#363 for
now since we don't have a mechanism in place to cancel the re-cancel
task once the order is cancelled - plus who knows if this is even the
best way to do it..
goodboy added a commit to pikers/piker that referenced this issue Aug 18, 2022
We were overwriting the existing loaded orders list in the per client
loop (lul) so move the def above all that.

Comment out the "try-to-cancel-inactive-orders-via-task-after-timeout"
stuff pertaining to erdewit/ib_insync#363 for
now since we don't have a mechanism in place to cancel the re-cancel
task once the order is cancelled - plus who knows if this is even the
best way to do it..
goodboy added a commit to pikers/piker that referenced this issue Aug 18, 2022
We were overwriting the existing loaded orders list in the per client
loop (lul) so move the def above all that.

Comment out the "try-to-cancel-inactive-orders-via-task-after-timeout"
stuff pertaining to erdewit/ib_insync#363 for
now since we don't have a mechanism in place to cancel the re-cancel
task once the order is cancelled - plus who knows if this is even the
best way to do it..
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants