Skip to main content

Horizon Advanced Orders

Horizon provides synthetic advanced order types managed entirely by the engine. Stop-losses, take-profits, bracket orders, and OCO links are not sent to the exchange. They live in-engine and fire through the normal risk pipeline when triggered.
Contingent orders (stop-loss, take-profit) are evaluated every tick via engine.check_contingent_triggers(). When using hz.run(), this is called automatically. If you manage the loop yourself, you must call it explicitly.

Core Concepts

Contingent Orders

Synthetic orders that wait for a trigger condition before submitting to the exchange. They go through the full risk pipeline when fired.

OCO (One-Cancels-Other)

Two contingent orders linked together. When one triggers, the other is automatically canceled.

Bracket Orders

An entry order paired with a stop-loss and take-profit, automatically linked as OCO.

Order Amendment

Modify price or size of a live order. Paper exchange amends in-place; live exchanges do cancel + resubmit.

Types

TriggerType

ContingentOrder

Each contingent order exposes the following fields:

Trigger Logic

Understanding when contingent orders fire is critical.
Stop-losses protect against adverse price movement.

Engine Methods

add_stop_loss

Returns the contingent order ID. The order is held in-engine until the trigger condition is met.

add_take_profit

Returns the contingent order ID. If both trigger_price and trigger_pnl are set, the order fires when either condition is met.

submit_bracket

Submits the entry order immediately and creates linked stop-loss and take-profit contingent orders. Returns (entry_id, sl_id, tp_id). The SL and TP are automatically linked as OCO.

check_contingent_triggers

Evaluates all pending contingent orders for the given market. Returns the number of orders that triggered. Called automatically each tick in hz.run().

cancel_contingent

Cancels a pending contingent order. Returns True if the order was found and canceled, False if it was already triggered or not found.

pending_contingent_orders

Returns all pending (not yet triggered) contingent orders.

amend_order

Amends an existing order’s price and/or size. Behavior differs by exchange:
Amends the order in-place and returns the same order ID. The order’s amendment_count is incremented.
On live exchanges, there is a brief window between cancel and resubmit where you have no order in the book. If you need atomic amendment, use the exchange’s native amend API directly.

Examples

Standalone Stop-Loss

1

Set up the engine and enter a position

2

Add a stop-loss to protect the position

3

Check triggers on each tick

Bracket Order

A bracket order is the most common advanced order pattern: enter a position with automatic downside protection and profit target.

Automatic OCO via Bracket

Use submit_bracket() to automatically link stop-loss and take-profit as OCO. When one triggers, the other is auto-canceled.

Inspecting Pending Orders

Amending Orders


Using Advanced Orders in hz.run()

When using hz.run(), contingent triggers are checked automatically. You can set up contingent orders inside your pipeline functions.
Contingent orders survive for the lifetime of the engine. If you want to reset them (e.g., after a position is fully closed), cancel them explicitly with engine.cancel_contingent().