Full Code
How It Works
The bracket order workflow has three phases:-
Entry submission:
submit_bracket()sends a regular limit order to the paper exchange and creates two contingent orders (stop-loss and take-profit) linked as an OCO pair. -
Trigger monitoring: On each tick (or when you call
check_contingent_triggers()), the engine checks all pending contingent orders for the given market. If the current price crosses a trigger level, the contingent order is converted into a real order and submitted. - OCO cancellation: When one side of an OCO pair triggers, the partner is automatically canceled. This prevents conflicting exit orders from both firing.
Standalone Stop-Loss
Add a stop-loss to an existing position without a take-profit:Standalone Take-Profit
Take-profit orders can trigger on price or PnL:When
trigger_pnl is set, the take-profit fires if either the price condition or the PnL condition is met. The PnL is computed from the engine’s position tracker as unrealized PnL for that market.Manual OCO Linking
You can manually link any two contingent orders as OCO. This is useful when you want custom trigger logic beyond simple bracket orders:Amending Contingent Orders
To move a stop-loss or take-profit, cancel the old one and create a new one:Integration with hz.run()
When usinghz.run(), contingent triggers are checked automatically each cycle. You set up brackets inside your pipeline and the engine handles the rest:
engine.check_contingent_triggers(market_id, current_price) each cycle after ticking the paper exchange.