QuantJourney Backtester

QuantJourney Backtester

Share product feedback

✓

Thank you.

Your note is now in the QuantJourney inbox.

docs/engine/execution-assumptions.mdx

Execution Assumptions

Daily-bar execution boundaries, fill priority, gap-through behavior and explicit model limits.

This page describes the order-mode model boundary. It should be read before trusting stops, limits, brackets, OCO or trailing-stop results on daily bars.

Sourcebacktester/execution/fill_engine.py
LayerExecution semantics
ModeOrder mode
InputOHLCV bars, order state, fill priority, slippage and commission
Outputdocumented assumptions for interpreting fills
Primary APIFillEngine.process_bar(...)
Main caveatDaily bars reveal touched prices, not the intraday path between them.

Daily-Bar Execution Boundary

Daily OHLC bars contain open, high, low and close. They do not contain the intraday sequence.

text
bar.open  = 100
bar.high  = 112
bar.low   = 94
bar.close = 105

take_profit = 110
stop_loss   = 95

This bar proves that both levels were touched. It does not prove whether price hit 110 before 95, or 95 before 110. A daily-bar backtest must therefore apply a documented same-bar convention.

Same-Bar Convention

The fill engine processes active orders by priority:

text
STOP -> STOP_LIMIT -> STOP_TRAIL -> STOP_TRAIL_LIMIT -> LIMIT -> MARKET -> BRACKET -> OCO

For a long position with separate protective stop and take-profit, this makes same-bar ambiguity conservative: stop-like orders are evaluated before limit exits. This is acceptable for EOD research when the assumption is explicit. It is not tick-accurate execution.

Gap-Through Rules

A stop price is a trigger level, not a guaranteed fill price.

OrderTriggerOpen-aware theoretical fill
Sell stopbar.low <= stop_pricemin(stop_price, bar.open)
Buy stopbar.high >= stop_pricemax(stop_price, bar.open)
Buy limitbar.low <= limit_pricemin(limit_price, bar.open)
Sell limitbar.high >= limit_pricemax(limit_price, bar.open)

Slippage and commission are applied after the theoretical price is selected.

Stop-Limit Boundary

A stop-limit has two phases:

  1. The stop activates when the stop level is crossed.
  2. The activated limit order only fills at-or-better than its limit.

If price gaps through the limit, the order can remain pending instead of filling. That is different from a plain stop-loss.

Partial Fill Boundary

Volume participation can create partial fills. This models a maximum share of bar volume, not queue priority, hidden liquidity or exchange matching behavior.

Explicit Non-Goals

  • Tick-level event reconstruction from daily bars.
  • Exchange queue priority.
  • Broker rejects and venue routing.
  • Low-latency live execution.
  • Guaranteed fill ordering when OHLC does not contain the path.

Audit Checklist

  • What bar frequency was used?
  • Did any candle touch both TP and SL?
  • Which fill priority applies to same-bar ambiguity?
  • Did a stop gap through the trigger level?
  • Did a stop-limit activate but remain unfilled?
  • Were partial fills enabled by max_volume_participation?
  • Are slippage and commission documented in the report packet?