Engine Settings & Assumptions

Code: c408696 Merge csbf/p2-t1-zwindow-hours (Trillian approved: REV-20260613-final-ada4c2)  |  versions: backtest v3.1.0, centre v2.0.0, config v2.0.0, gates v1.2.0, assumptions v1.1.1  |  Audit: docs/ASSUMPTIONS_AUDIT.md (2026-06-05)

Behavioral assumptions (audited)

IDAreaStatusAssumptionWhat we foundRight wayLook-ahead
1.1 Signal Verified Centre/sigma window = previous L bars, EXCLUDING current bar Pre-fix engine included current bar → centre pulled toward price → fewer fills closes[-(L+1):-1]; z = (current − mean(prev L)) / std(prev L) clean
1.2 Signal Verified Population std (ddof=0) Pre-fix engine used ddof=1; ~0.8% sigma difference at L=60 ddof=0, matching verified script n/a
1.3 Signal Verified Sigma valid range [0.005, 0.50]; outside → no new entries, exits still run Pre-fix engine traded near-zero/extreme sigma bars Floor/cap per script; invalid bars still manage open positions clean
1.4 Signal Fixed Contract roll: CAUSAL close on last old-month bar, reset window + cooldown v2.1 retro-closed at bar i−1 when roll detected at i (escalator: non-causal, impossible same-bar entry/exit, contaminated duration stats) v2.2: roll calendar is deterministic ex ante (CME specs) → entries blocked on last old-month bar, positions closed AT that bar's close/time. No retroactive timestamps clean — next-bar delivery_month is calendar knowledge, not data
1.5 Signal Open Signal source: ALL butterfly_* tables are the OUTRIGHT synthetic (cl1−2·cl2+cl3); butterfly_m15 = resampled butterfly_m1 (verified exact, C064 — corrects C051/audit r2) No calendar-synthetic table exists. A/B vs quote-built calendar (C064): synth gross-tier P&L is substantially OWN-NOISE harvesting — quote-cal signal at same mechanics ≈ $0. Hour exclusion does not reconcile the series Engine output = SIGNAL-RANKING only. Absolute P&L requires V1 fills validated against BF book sides (OFS_EXEC_ACCT_V1). M15 stays the only run-approved TF (script-era alignment); M1 grain noise = K394 n/a (provenance)
1.6 Signal Fixed Flystd gate: prior-bar window + expanding percentile, BOTH per contract segment Precompute AND threshold crossed contract rolls (Trillian caught threshold side). Escalator: expanding percentile is regime/start-date dependent even when causal — each segment has a ~20-obs warmup where the gate never blocks v2.2: values and threshold computed within current delivery-month segment only. Absolute/frozen thresholds = V1 research option clean
2.1 Execution Fixed Fill model = trade_through only (price crosses resting level → 100% fill at level) fill.model volume_proxy/probability were config-accepted but NEVER read — silent no-op Engine rejects unimplemented fill models at run start (this change) clean — orders derive from prior-bar info, fill on subsequent prices
2.2 Execution Limitation Fills/exits detected on bar CLOSE only (no high/low) Escalator: bias is AMBIGUOUS, not conservative — misses intrabar target touches (longer holds, more horizon exits) but also delays entry timestamps and misses touch-and-revert winners. Risk/MAE/duration stats from close-only runs are not execution-grade BBO/tick fill detection with tick-rounded levels (V1). Treat current runs as signal-ranking tier clean
2.3 Execution Verified Exit at entry-time centre (fix_at_entry=True default); retreat = centre ± entry_dist×(retreat−1) Pre-fix: floating default + centre×retreat formula (wrong direction for negative fly prices) Fixed mean default (better semi-agg at Z≥2.0); float = sweepable option with shallower DD clean — gap-through fills at target = at-or-better for resting limit
2.4 Execution Open Spread cost = $0 — passive maker both directions (C029) Engine ≈ script's GROSS tier (optimistic). Realistic = semi-agg: passive entry, taker exit (~$5–10/trade, C031). Escalator adds: forced exits (horizon/roll/EOD) MUST pay taker costs; centre±z·sigma levels are off-tick — tick rounding alone can move P&L 0.5–1 tick/side; touches ≠ fills without queue model V1 execution model: tick rounding, strict trade-through vs touch, queue/probability fills, taker cost on forced exits. Until then engine net is an upper bound n/a
2.5 Execution Verified Commission = per_side × legs × 2 from ofs_products ($15.36 RT for CL, C011) Matches verified script; config override available As implemented n/a
2.6 Execution Fixed MAE/MFE marked at sample closes, INCLUDING the entry-triggering close Escalator found a real bug: the close that triggers a fill is already adverse (close crossed our level) but extremes ran BEFORE fills — entry-bar adverse excursion was invisible to MAE v2.2: position marked against trigger price immediately at fill. Intrabar MAE still understated (close-only) — treat as LOWER BOUND (C037) clean
3.1 Gates Unresolved Hour handling: engine loads 24h; hour gate default OFF Script traded US 13–19 UTC only (data/liquidity scoping). C046 (signal layer): quiet hours strongest. Different layers — not a contradiction, but engine↔script comparisons MUST use allow_hours=[13..19] Gate supports deny_hours AND allow_hours (this change). Tradeable-hours research = open clean
3.2 Gates Verified DTE gate from cme_contract_specs; entry records DTE at current bar Index checked — no off-by-one As implemented clean
3.3 Gates Fixed crude_d5 and news gates FAIL CLOSED until their data is wired Worker never passes their inputs → they silently allowed everything when switched on (mislabeled runs) v2.2: enabling either gate refuses the run with an explicit error until data feeds exist n/a
4.1 Positions Verified One position per side per z-level; pyramid default OFF (C035: catastrophic tail mechanism) De-dup via |entry_z − level_z| < 0.1 As implemented clean
4.4 Positions Limitation Cooldown set on exit bar; entries already blocked that bar; decrement starts same bar Effective block ≈ cooldown_duration−1 full bars + exit bar (escalator: off-by-one class). Consistent across runs, documented rather than changed As implemented, documented. Revisit if live parity needs exact bar counts clean
4.5 Positions Fixed End-of-data force close = EOD_FORCE (censored), NOT horizon Was labeled HORIZON — contaminated horizon-exit stats (escalator §6) v2.2: ExitReason.EOD_FORCE; exclude from horizon stats n/a
4.2 Positions Verified Horizon H counted in SAMPLES — wall-clock meaning varies by TF L/H must be wall-clock normalized by researcher (15h natural timescale, handoff Part 2) As implemented; normalization is a research-process rule clean
5.1 Process Fixed Services run the audited engine code (main) 2026-06-05: working tree was on pre-fix branch feat/data-sync — ALL OFS runs ≤ 2026-06-05 (incl. OFS-0001..0019) used the unfixed engine and are invalid Merged to main (fbc1cb7); settings page shows live code version + git head n/a

Default config (every engine parameter)

Showing CODE defaults — no saved overrides. Values are JSON: true/false, numbers, null, [13,14], "p90".

centre
centre.mode Centre calculation mode
centre.L Lookback window in samples
centre.fix_at_entry Lock exit target at entry vs float with mean
centre.sample_mode Sample trigger: wall clock or N trades
centre.sample_tf Sample timeframe
centre.dual_mean_on Enable dual-mean (L_fast + L_slow)
centre.L_fast Fast lookback (dual mean)
centre.L_slow Slow lookback (dual mean)
centre.dual_agree_gate Only enter when both means agree on gap direction (C042)
centre.sigma_floor Min sigma for valid signal
centre.sigma_cap Max sigma for valid signal
data
data.allow_unverified_source Explicit override for artifact-risk runs (e.g. V-A self-fills on csmid recreate the C066 artifact). Pre-v1 DB-table semantics retired 2026-06-07.
data.series Signal series source (v1 epoch, /data/commodity/signal): csmid_flat = CS quote-mid (default), synth_flat = outright-trade synth (builder pending). DB price tables removed 2026-06-07
exec
exec.variant Fill model: va=trade-through bar fills (optimistic bound), vb=alpha-queue against prints+BBO (research default; needs event tape)
exec.alpha V-B queue assumption: fill at-level when printed vol at level since join >= alpha x top-of-book size at join. 0.25=front-third, 1.0=back-of-queue. Sweep {0.25,0.5,1.0}
exec.markouts_on Record touch events + post-event reference moves at 1m/5m/30m (spec §5). V-B only
entry
entry.z_long Z-score threshold to enter long
entry.z_short Z-score threshold to enter short
entry.min_win Min distance from mean to enter (price units, 0=off). 0.03 = 3 cents
exit
exit.retreat Exit at centre × retreat (>1 = overshoot past mean)
exit.H Max hold in samples before forced exit
exit.stop_loss Stop loss in $ (None = no stop). C022: stops are net-negative
risk
risk.cooldown_mode Post-trade cooldown mode
risk.cooldown_duration Cooldown duration in samples
risk.dte_offset UNWIRED legacy field (kept for config compat) — use flat_dte
risk.flat_dte Force-flat all positions when DTE <= this (None=off). Fixes 6-9 entries bleeding into the 0-5 roll zone via H (C083 corrected)
pyramid
pyramid.on Enable pyramiding
pyramid.base_lots Base position size in lots
pyramid.levels Z-score thresholds for each add level
pyramid.size_pct Size as % of base at each level
pyramid.max_levels Maximum pyramid levels
gates
gates.flystd.on Enable flystd gate
gates.flystd.threshold Percentile threshold string (p75, p90, p95)
gates.flystd.window Rolling window for flystd computation
gates.crude_d5.on Enable crude_d5 gate
gates.crude_d5.threshold Abs 5-day ROC threshold
gates.dte.on Enable DTE gate
gates.dte.min_dte Minimum DTE to allow entry
gates.hour.on Enable hour-deny gate
gates.hour.deny_hours UTC hours blocked for entry
gates.hour.allow_hours If set, ONLY these UTC hours allow entry and deny_hours is IGNORED (script parity: [13,14,15,16,17,18,19])
gates.news.on Enable news blackout gate
gates.news.events Event types to gate on
gates.news.blackout_before_min Minutes before event to block
gates.news.blackout_after_min Minutes after event to block
gates.news.hard_exit_before Force-close positions before blackout window
fill
fill.model Fill model mode
fill.fill_at_level_prob Fill probability for probability model
fill.min_volume_at_level Min adjacent-price volume for volume_proxy model
fill.m1_resolution Use M1 bars for fill detection between samples. Requires correct M1 data source.
cost
cost.commission_per_side_override Override product commission (None = use product default)
contracts
contracts.combos Contract combos: front, +1, +2
lattice
lattice.on Enable unified lattice mode
lattice.distance_bands Exit rules by fill distance from centre

Products & costs (from ofs_products — commission = per_side × legs × 2)
ProductTickPoint valueComm/sideLegsCommission RT
CL_BF0.01$1000.0$1.924 $15.36
GC_BF0.1$100.0$1.924 $15.36
HG_BF0.001$25000.0$1.924 $15.36
NG_BF0.001$10000.0$1.924 $15.36