Skip to main content
Every order passes through an 8-point risk pipeline in Rust before reaching the exchange. The pipeline is designed to prevent catastrophic losses and enforce trading limits.

Risk Pipeline

The checks run in order. If any check fails, the order is rejected immediately:
When the drawdown check triggers, it automatically activates the kill switch and cancels all open orders across all exchanges. This is a hard stop that requires manual intervention.

Configuration

Risk Builder

The Risk class provides a clean builder API:
hz.Risk() does not support max_position_per_event. For event-level position limits, use RiskConfig directly (see below).

Equity Risk Preset

For equity strategies, use Risk.equity() which sets appropriate defaults:
Risk.equity() sets price_min=0.01 and price_max=100000 (vs 0.01-0.99 for prediction markets).
Use default hz.Risk() for prediction markets (price: 0.01-0.99). Use Risk.equity() for equities/options (price: 0.01-100,000). For crypto, customize price_min/price_max to match the asset’s range.

RiskConfig (Direct)

For full control, use the Rust RiskConfig directly:

Kill Switch

The kill switch is a global emergency stop:
The kill switch is automatically activated when:
  • Daily drawdown exceeds max_drawdown_pct
  • You can also trigger it manually or from a pipeline function
In the TUI dashboard, press k to toggle the kill switch.

Drawdown Tracking

The strategy loop automatically tracks drawdown:
  1. On startup, the daily baseline is set to the current total P&L
  2. Each cycle, update_daily_pnl() is called with the latest total P&L
  3. If P&L drops below baseline * (1 - max_drawdown_pct / 100), the kill switch triggers

Rate Limiting

The rate limiter uses a token bucket algorithm:
  • Sustained rate: refill rate in orders per second
  • Burst capacity: maximum tokens available for bursts
This allows short bursts of rapid order submission while enforcing a sustainable average rate.

Dedup Window

The dedup check prevents submitting identical orders within a configurable time window. Two orders are considered duplicates if they have the same:
  • Market ID
  • Side (Yes/No/Long)
  • Order side (Buy/Sell)
  • Size
  • Price
Default window: 1000ms.

Event Risk Limits

When trading multi-outcome events, you can set max_position_per_event to cap total exposure across all outcomes in an event:
This check only applies to markets registered in an event via engine.register_event() (or via hz.run(events=...)). Markets not in any event are unaffected. When max_position_per_event is None (the default), event-level risk checks are skipped entirely.

Netting and Risk

When netting pairs are configured, the notional limit check accounts for hedged positions. For each netting pair (market_a, market_b), the hedged portion is subtracted from the total portfolio notional:
This allows larger positions when they’re hedged across exchanges.