The research platform
Every strategy family runs through one shared, contract-enforced pipeline from raw bar data to a result tree with full provenance. (The signal logic itself stays private — what's shown here is the machinery around it.)
Stage A → B → C pipeline
- Stage A generates entries and attaches signal families, each registered with exactly which bar it is permitted to read.
- Stage B screens signals solo and in combination, ranking on out-of-sample performance with decorrelated top-N selection.
- Stage C runs a numba-JIT sweep over a six-figure count of candidate configurations.
- A mandatory family rollup reports the family median, not the sweep's max-statistic — the anti-cherry-picking rule.
- One command (
python -m tools.estimate) runs the whole chain with a single exit contract threaded through every stage.
Risk & exit modelling
- Volatility-adaptive stops and laddered targets.
- Exits resolve on a finer data stream than entries — measured in-code: a stop that fits inside a single entry bar grants the coarse backtest artificial "free-bar immunity" worth more than some strategies' entire edge.
- Path-dependent exit rules must qualify before they may trigger — unqualified variants exist only as controls (see guardrails below).
- Finalists face a 5-check validation battery: structural drill, neighbour stability, ~18 rolling OOS cuts refit per cut, and one untouched holdout reserved before selection.
Guardrails that stop backtests from lying
The defining feature of the platform is not the strategies — it is the machinery that makes a good-looking result hard to fake. Most commits in the log record a refutation, written into the run ledger, with the rule that produced it added to the repo's working contract.
The no-lookahead contract — enforced at runtime, not just written down
A per-entry-style table defines which bars a feature may read. It is backed by a runtime validator that NaN-patches every entry's anchor bar, re-runs the signal attachment, and asserts the outputs are unchanged — a signal that notices the NaN is reading its own entry bar. The validator is mandatory for new signal families and CI includes tests proving the validator itself catches planted lookahead.
| Entry style | Bar i state at fill | Features may read |
|---|---|---|
Level/touch entry (fill intrabar on bar i) | still forming | bars ≤ i−1 only |
Close entry (fill at C[i]) | complete | bars ≤ i |
Next-bar-open entry (fill at O[entry_bar]) | not started | bars ≤ entry_bar−1 |
Random controls as a mandatory noise floor
- Stage A seeds 20 information-free random signals that pass through the identical screen, decorrelation and full sweep.
- Results split three ways — pure-real / mixed / all-control — because a mixed combination inherits its real member's edge and would flatter the controls.
- Verdicts (
REAL BEATS NOISE/PARTIAL/NOISE-SATURATED) come with a Mann-Whitney p-value. - Exit-rule variants with a known optimistic bias are demoted to control-prefixed variants that are scored every run but structurally cannot be ranked, promoted or frozen — the type system of the pipeline enforces it.
Provenance & immutability
- Caches carry a fingerprint of their inputs — changed inputs produce a new file, so cache invalidation "should not exist at all". Deleting a cache or result tree is a merge-blocking test failure.
- The evaluation window is a first-class run parameter carried in the cache filename; clipping happens at load on every stream that decides which entries exist.
- Result trees chain run tags folder-to-folder, and every runner appends a one-line objective to a per-strategy
RUNS.mdledger. - The live tree and research tree are physically separated: research bars are a pinned vintage, live bars advance nightly.
Three-way control partition (excerpt)
def fset_class(fset: str) -> str:
"""``pure-real`` | ``mixed`` | ``all-control`` by fset MEMBERSHIP."""
mem = [m for m in str(fset).split("+") if m]
if not mem:
return "pure-real"
n_ctrl = sum(CTRL_MARK in m for m in mem)
if n_ctrl == 0:
return "pure-real"
return "all-control" if n_ctrl == len(mem) else "mixed"
A combination containing one real signal and one random control is neither evidence for the strategy nor a clean control — so it is quarantined into its own class. Getting this split wrong once forced a published internal claim to be retracted; the fix became a permanent, tested rule.
Promotion to live — parity before orders
A finalist is frozen as a production JSON artifact, specified in a model document, and re-implemented as a C++ study. Nothing is trusted until proven equal.
Parity ladder
- Gate zero: bar-stream parity. Features are never diffed until the bar streams are proven identical — a single one-bar disagreement was measured materially re-ordering downstream features.
- ~19 numeric feature kernels — from volatility and session context to proprietary order-flow families — each proven bit-identical against its Python reference.
- Float64 numeric contract with a diagnostic fingerprint: a ~1e-7 relative residual is the float32 signature — the rule is "find the narrow type, never widen the tolerance."
- Full-stack trade comparison under composite-key matching; the promoted portfolio passed at 100.00% with 0.000000 R total difference.
Live order layer
- A single submission choke point is the only buy/sell call site in the study; every accept and refuse goes to an append-only order-event journal.
- The concurrent-position bound is owned in code against filled quantity — not delegated to a chart setting that measures working orders.
- Server-side bracket children at absolute prices, so stop and target never drift on parent fill.
- Expanding feature state survives restarts via a CRC-checked snapshot with atomic publish (tmp → verify → rotate backups → replace) and a seam check that fails closed.
- A nightly watchdog parses the trade service log and classifies every event as benign noise, an explained ignore, or a true reject — alerting before the next open.
The stale-level guard — a live post-mortem turned into a pure function
inline Verdict Judge(int mode, bool replaying, int dir, double level,
double market, int sweptAt)
{
Verdict v;
v.swept = (sweptAt >= 0);
v.marketable = StopAlreadyMarketable(dir, level, market);
if (mode == kGuardOff) return v; // not even evaluated
if (!v.swept && !v.marketable) return v; // healthy arming
v.cause = v.swept ? "already-swept" : "already-marketable";
if (GuardArmedHere(mode, replaying)) v.refuse = true;
else v.shadow = true; // measured, not acted on
return v;
}
After a DLL hot-reload or platform restart, the rebuilt order state no longer knows which pending entries recent history has already invalidated — an order that should never fire can fill instantly at market. Diagnosed from three live tickets filled in the same second, the fix is two pure predicates with an explicit off / live-edge-only / always mode, so a replay can measure the guard in shadow while only the live edge refuses. Because the decision cores are ACSIL-free pure functions, a standalone console probe links the very same code — no Sierra Chart running, no mocks — and feeds it the literal bytes a reloaded live layer would see.
Developer infrastructure
Hot-reload rig for a closed GUI host
- MSBuild events release/re-allow the DLL over Sierra Chart's UDP control port and write a reload trigger file.
- A resident dev-loader study watches the trigger and recalculates or inserts studies on the right chart.
- ACSIL exposes no user-defined chart name, so charts are targeted through a chartbook-scoped tag map — and tagged rig charts reject untagged inserts so no other workflow can touch them.
Evidence-first verification
- Sierra's message log is memory-only and unreadable from outside, so every claim is proven from files: structured debug logs, probe studies, export comparators.
- A Python replay driver requests bounded chart replays and reconciles them fill-by-fill against the order journal.
- Development runs under a multi-agent AI workflow with independent, refute-by-default review — described in its own case study.