Skip to content

Latest commit

 

History

History
133 lines (102 loc) · 5.77 KB

execution_contracts.md

File metadata and controls

133 lines (102 loc) · 5.77 KB

QuantBT Execution Contracts

Execution contract is the promise between a strategy signal and the backtest engine. It says when the signal is known, when an order may be submitted, which price can fill, and which accounting rules are certified.

This matters because a single pos_weight column can mean very different things:

  • target exposure at the current close;
  • signal observed at close and filled next open;
  • entry plus stop-loss/take-profit/trailing behavior inside the next bar;
  • explicit fills already generated by an external alpha;
  • multi-order package lifecycle such as DCA/grid/basket/arbitrage.

QuantBT now makes those contracts explicit. Old endpoints remain compatible, but execution-sensitive alphas should use the narrowest contract that matches their domain.

Contract Map

Contract Endpoint Signal phase Fill phase Intrabar semantics Certification target
close_target_v2 signal_notional, pct_equity, native vectorized bar close bar close target accounting none Level 2 for close-target signals
next_open_v1 reserved / event routes bar close next bar open entry/exit only future specialized route
intrabar_bracket_v1 intrabar_bracket, intrabar_bracket_reference bar close next bar open, then high/low path SL/TP/trailing/reversal Level 2 now, Level 3+ with parity bundle
fill_replay_v1 fill_replay explicit fills supplied explicit fill tape alpha-owned Level 1 accounting replay
event_lifecycle_v2_next_bar_close native-event compatibility routes command/event driven market at effective-bar close; legacy OHLC triggers order-owned, legacy frozen reproducibility contract
event_lifecycle_v3_next_open event_driven, explicit lifecycle, reactive strategy prior close observation or explicit tape actual effective-bar open plus versioned gap rules order-owned, ambiguity flagged Level 2 with Python/Rust parity
nautilus nautilus_validation, order/package validation event driven Nautilus simulation external engine Level 4 route when configured

Close Target

Use close-target routes when the strategy already produced a target exposure series and does not claim stop-loss, take-profit, trailing-stop, or custom intrabar exit prices.

The model is intentionally simple:

signal[t] -> target exposure at close[t]
PnL[t+1]  -> position[t] * (close[t+1] - close[t])

This is correct for research signals that do not depend on the inside of the bar. It is not a certified route for alphas that generate exit_price, exit_type, slpercent, tppercent, or high/low-based exits. If such columns are present on a close-target run, QuantBT records an uncertified status in metadata instead of silently claiming intrabar correctness.

Intrabar Bracket

Use intrabar_bracket_v1 when a strategy emits compact entry intent and the engine must own:

  • next-open entry;
  • gap-aware stop-loss;
  • limit-style take-profit;
  • same-bar SL/TP conflict policy;
  • trailing-stop update timing;
  • technical exits;
  • reversals as two fee-paying legs;
  • optional final close;
  • simple single-symbol liquidation checks.

The canonical timing is:

strategy observes bar t close
entry/reversal/technical exit may fill at open[t + 1]
stop/take-profit may fill within bar t + 1 using high/low
trailing stop updates after bar t + 1 close

The Python reference oracle is readable and should be used when debugging a new alpha migration. The Numba kernel is the production research path once parity is verified.

Fill Replay

Use fill_replay_v1 when an alpha already emitted exact fills. QuantBT then replays the fill tape for accounting only:

bar_index, sequence, side, qty, price

This certifies PnL/fee/funding/margin accounting from the supplied fills. It does not certify how those fills were generated. The right label is Level 1 unless paired with a separate causal fill-generation proof.

Event Lifecycle

Use native event or Nautilus routes when the strategy has explicit order lifecycle requirements:

  • market/limit/stop orders;
  • order activation/cancel/replace;
  • bracket/OCO packages;
  • basket all-or-none packages;
  • arbitrage multi-leg execution;
  • DCA/grid state machines.

These routes are broader but slower than the narrow intrabar kernel. They are the right place for order/package semantics that cannot be reduced to a compact single-symbol bracket tape.

V2 is retained under its honest next-bar-close name for historical replay. V3 is the causal close-to-next-open contract and requires real open prices. The two IDs never alias to each other. Exact clock, gap, stop-limit ambiguity, bar-zero, final-bar, and typed lifecycle semantics are maintained in the native-event contract registry.

Certification Levels

Level Label Meaning
0 Legacy / unspecified Backtest ran, but execution-sensitive claims are not certified
1 Accounting replay Explicit fills were replayed correctly; fill generation remains alpha-owned
2 Engine causal QuantBT owns causal execution semantics with oracle/kernel parity
3 Cross-backend Native route matches another QuantBT route on known scenarios
4 External validation Nautilus/lower-timeframe/external bundle is available

Production-style claims should be at least Level 2. Execution-sensitive stakeholder reports should prefer Level 3 or Level 4 when feasible.

Rule Of Thumb

  • Pure signal target: use close target.
  • Entry at next bar and SL/TP/trailing inside the bar: use intrabar bracket.
  • Old alpha emits fills: use fill replay first, then migrate to causal engine.
  • Multi-leg package or grid state: use event lifecycle or Nautilus validation.
  • If unsure, scan the alpha and treat the result as a migration hint, not proof.