The Engine is the core orchestrator. While hz.run() manages it for you, you can use it directly for advanced use cases, testing, or custom integration.
Construction
Paper exchange (default)
api_key is optional if you’ve set HORIZON_API_KEY as an environment variable. See Authentication.
Polymarket
Kalshi
With persistence
Full signature
Maker/taker fees
Split fees by liquidity role. Makers add liquidity (limit orders resting in the book), takers remove it (market orders or aggressive limit orders that cross the spread).
Each Fill includes an is_maker field indicating whether the order was a maker or taker. See Fill type.
Multi-Exchange
add_exchange
Add a secondary exchange to the engine.
Full signature matches the constructor parameters for each exchange type.
Each exchange type can only be registered once. Calling add_exchange("polymarket", ...) when Polymarket is already registered raises ValueError.
exchange_names
exchange_count
exchange_name
Get the primary exchange name (backward compatible):
set_netting_pair
Register a netting pair for cross-exchange risk reduction:
netting_pairs
Order Submission
All order methods support optional exchange parameter for routing:
submit_order
Submit an order through the risk pipeline. Returns the exchange-assigned order ID.
submit_quotes
Submit bid+ask quote pairs. Returns a list of order IDs (2 per quote: bid + ask).
submit_market_order
Order Amendment
amend_order
Amend an existing order’s price and/or size.
- Paper exchange: Returns the same order ID (amendment is applied in-place).
- Live exchanges (Polymarket, Kalshi): Performs a cancel+resubmit under the hood, returning a new order ID.
- At least one of
new_price or new_size must be provided.
- Raises
ValueError if the order is not found.
Each successful amendment increments the order’s amendment_count field. See Order type for details.
Contingent Orders (Stop-Loss / Take-Profit)
Contingent orders are triggered automatically when market conditions are met. They enable stop-loss and take-profit strategies, and can be linked together as OCO (one-cancels-other) pairs via bracket orders.
add_stop_loss
Registers a stop-loss contingent order. When the market price drops to or below the trigger_price, a market order is submitted automatically.
add_take_profit
Registers a take-profit contingent order. When the market price rises to or above the trigger_price (or the position PnL reaches trigger_pnl if set), a market order is submitted automatically.
submit_bracket
Submit an entry order with linked stop-loss and take-profit as an OCO (one-cancels-other) group.
When either the stop-loss or take-profit triggers, its OCO partner is automatically canceled.
check_contingent_triggers
Check all pending contingent orders for a market against the current price and trigger any that match.
hz.run() calls check_contingent_triggers automatically on every tick. You only need to call this manually when using the engine directly.
cancel_contingent
Cancel a specific contingent order by its ID.
If the contingent order is part of an OCO pair, only the specified order is canceled (the partner remains active).
pending_contingent_orders
List all pending (not yet triggered) contingent orders.
See ContingentOrder type for field details.
Smart Order Routing
submit_order_smart
Route an order to the exchange with the best available price based on current feed data.
- Buy orders are routed to the exchange with the lowest ask price.
- Sell orders are routed to the exchange with the highest bid price.
- If no feed data is available or prices are equal, the order is sent to
fallback_exchange (or the primary exchange if None).
Smart routing requires active feeds for each exchange. Start feeds before using submit_order_smart.
Cancel
cancel
Cancel a single order by ID. Looks up the exchange automatically:
cancel_all
Cancel all orders across all exchanges:
cancel_market
Cancel all orders for a specific market across all exchanges:
Fills & Positions
tick
Tick the paper exchange with a price and process fills:
poll_fills
Poll fills from all live exchanges:
process_fill
Manually inject a fill:
update_mark_price
Update mark price for unrealized P&L calculation:
sync_positions
Fetch positions from an exchange and reconcile:
Queries
Each Order returned includes an amendment_count field (number of times the order has been amended). See Order type for details.
Runtime Parameters
Runtime parameters are injected into ctx.params every cycle when using hz.run() with hot_reload() in the pipeline.
Risk Controls
Feed Management
Persistence
Multi-Outcome Event Management
Register and query multi-outcome events. See Multi-Outcome Events for the full guide.
register_event
Register an event with its outcome market IDs:
event_exposure
Total exposure across all outcome markets in an event:
event_positions
All positions in markets belonging to an event:
event_parity_check
Check whether outcome prices sum to ~1.0 using current feed data:
market_event_id
Reverse lookup - which event does a market belong to?
registered_events
All registered events and their market IDs:
Arbitrage Execution
execute_arbitrage
Submit a cross-exchange arbitrage trade with atomic rollback. Both legs go through the risk pipeline with Fill-Or-Kill semantics.
- Both legs use
TimeInForce.FOK (Fill Or Kill)
- If the sell leg fails after the buy succeeds, the buy order is automatically canceled
- Returns
(buy_order_id, sell_order_id) on success
- Raises an exception if risk rejects either leg
See Arbitrage Executor for the full guide including arb_scanner() and arb_sweep().
Maintenance
Shutdown Behavior
When the Engine is dropped (Python garbage collection or explicit del):
- Position snapshot is saved to the database
- Strategy run is ended in the database
- All orders are canceled across all exchanges
- All feeds are stopped