Public beta: Banger supports paper trading only. Live execution is disabled, and historical backtesting currently supports only in-memory/synthetic tick sources.
N°04 / Build

Risk envelope

A RiskEnvelope is a declarative spec of the limits your strategy must operate inside. The paper runtime enforces it before recording a simulated fill. Strategies declare the envelope as a class attribute; the runtime reads it once at deploy time and gates every ctx.place() against it.

Available limits

from decimal import Decimal
from banger.risk import RiskEnvelope

class MyStrategy(Strategy):
    risk = RiskEnvelope(
        max_position_usd=Decimal("200"),
        max_daily_loss_usd=Decimal("500"),
        max_open_positions=5,
        max_concentration_pct=0.25,
        max_orders_per_minute=10,
    )
    ...
FieldTypeEffect
max_position_usdDecimalCumulative cost-basis cap for one venue/market/side position.
max_daily_loss_usdDecimalBlocks new orders when mark-to-market loss since the current UTC day baseline reaches the limit.
max_open_positionsintCap on simultaneous open positions across all venues.
max_concentration_pctfloat (0–1)Max cost-basis share of the paper account for one position.
max_orders_per_minuteintSliding 60-second limit on successful order attempts.

All fields are optional. Unset = no limit. Set what you need.

What happens on a violation

When ctx.place() would breach an envelope limit:

  • The order is not placed.
  • RiskViolation is raised.
  • The runtime logs a strategy.risk_violation event with the reason.
  • The next event handler invocation continues normally.

Strategies can also gate proactively with ctx.can_open_position() — true if the envelope currently permits a new position.

Why declarative?

Two reasons. First, it’s auditable: the envelope is a single block of declarative config that anyone reading the file can see. No buried if statements scattered through your strategy code. Second, the same declaration can be snapshotted with a deployment. Live execution is not released; its future control-plane risk engine must independently re-enforce every limit outside user code.

What the envelope doesn’t do

  • It doesn’t hedge. If you want a market-neutral exposure, place the hedge leg yourself.
  • It doesn’t close existing positions when a limit gets tighter — only blocks new ones.
  • It doesn’t enforce the same limits across strategies. Account-wide aggregation is on the roadmap (per-strategy is what v0 ships).

See also