-
Notifications
You must be signed in to change notification settings - Fork 1k
Introduce trigger model config for OTO contingencies #2623
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@cjdsellers |
Hi @hope2see Thanks for the report. It seems the docs are misaligned with the code. Potentially the docs were lifted from a FIX description of that contingency type, however this might not be how contingent orders are actually executed in all cases. This requires some research to find venue specs, but I think it's desirable for child orders to be triggered on a partial fill of the parent. For instance, if you filled half of the entry quantity, you'd want the equivalent quantity working in the market as SL and TP, rather than awaiting a complete fill of the parent (which isn't guaranteed). What are your thoughts? (I'm leaning towards a docs update here.) |
Right, venue specs need to be researched. BTW, this issue is not just limited to bracket order, but related to general OTO contingency. If a partially filled order is allowed to trigger child orders, the quantities of them should be automatically adjusted, whenever the parent order is filled. However, this is not addressed in the current implementation. |
In binance, only an fully filled filled order triggers child orders.
|
Indeed, all of the below relates to the OTO contingency.
That is almost the current implementation, quantities are automatically adjusted for Also to be considered is behavior for the order emulator: For the order manager (looks like quantities are modified here on partial fills): Note the order manager is used for live trading also. So if we'd like to align with other venues such as Binance, this is going to require another venue configuration option |
Understood, seems like an interesting default which results in uncovered exposure in partially filled entry scenarios. |
@cjdsellers If you are okay with the policy of not allowing partial fill triggering, then I will open a PR. |
Hi @hope2see A patch would be most welcome to introduce the possibility of being able to align the behavior more accurately with Binance. That said, I don't think Binance should be the canonical standard to which we align behavior. Here is an except from some research I did earlier: Full trigger modelMany traditional stock brokers (TD Ameritrade, Schwab, Fidelity, E*TRADE) favor the full execution trigger model for OTO orders. This means the contingent orders are held off-market until the primary order completely fills. This approach simplifies the logic (you either have the position or you don’t) but leaves a potential gap in coverage during partial fills. Partial trigger modelOn the other hand, brokers/platforms oriented towards active trading and high-volume markets (Interactive Brokers, Kraken, futures platforms, etc.) use the partial trigger model. This method actively adjusts or sends child orders as each fill comes in, ensuring no portion of a filled order is left without its OCO protection. Crypto exchanges vary: some like Kraken follow the partial model, while others like Binance and Coinbase use the full-fill model on their spot exchanges. SolutionSo I think we need to introduce a venue configuration option to retrain the partial trigger model behavior by default (so we don't introduce a breaking change). This will then allow us to more accurately simulate a venue such as Binance, which will meet your use case. Introducing configuration is often a trade-off between increasing complexity and increasing value on some axis. In this case, I think it's worth it - and will be very useful when we introduce "venue templates", which will give you say a Binance Futures venue out-of-box as closely as the platform can simulate. What are your thoughts? References |
What a quick and great research! That said, if we decide to adopt the partial trigger model as a default, we’ll also need to implement (or fix) the logic for auto-adjusting the quantities of child orders. At the moment, that functionality doesn’t work. |
Just to add one more thing, as of now, the current implementation can be easily fixed to work correctly under the full trigger model. |
Hi @hope2see Current state
For the venue managed contingency case, I think the functionality works for Otherwise, on a trigger the order is just processed as if it was just submitted (I think this is the correct behavior for partial trigger model). If you believe it doesn't, then a test asserting this would be helpful (then I can fix the behavior). For the strategy managed contingency case, the quantity is updated here: Moving forward
How about we add a venue configuration option Then, you could add the behavior for the full trigger model which works when this is set to false. Then after the above, if any of the default behavior does not have test cases - I'll add those as a follow-up. What do you think? |
Actually, when fill_order() is invoked due to a partial fill, this part of the code is not executed because the position is None at that moment—it returns before reaching this section. |
Yes, it would be great! :) |
Hi @hope2see, I've updated the orders concept guide to more accurately describe the behavior we're targeting. I didn't add anything about the config yet as it's still TBD. |
Oh, It is very comprehensive!! 👍🏻 |
Hi @hope2see I've converted this ticket to an enhancement request to add a trigger model config. |
Uh oh!
There was an error while loading. Please reload this page.
Bug Report
According to OTO doc, a parent order only trigger child orders only when fully filled. However, it actually triggers in partially filled status, resulting in some derivative problems.
Confirmation
Before opening a bug report, please confirm:
nautilus_trader
.Expected Behavior
A parent order should not trigger OTO child orders before it is fully filled.
Actual Behavior
It triggers OTO child orders when it is filled, regardless of whether it is fully or partially filled.
Steps to Reproduce the Problem
It can be checked using the pytest below.
The current implementation fails these tests.
Code Snippets or Logs
I tested these by adding to test_exchange_contingences.py.
Specifications
nautilus_trader
version: branch (commit 4b29b43)The text was updated successfully, but these errors were encountered: