From cdd4503164ca40b6132ac5affd84008fbf9b0e57 Mon Sep 17 00:00:00 2001 From: claude Date: Mon, 13 Jul 2026 16:23:51 +0200 Subject: [PATCH] =?UTF-8?q?research:=20Arc=201=20=E2=80=94=20trend=20regim?= =?UTF-8?q?e=20vs=20H1=20breakout,=20campaign=20path,=20results=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two std-vocabulary blueprints (bo_h1 donchian-style H1 breakout; bo_h1_trend adds a post-latch EMA 12/48 regime gate). First real use of the campaign path: process + campaign documents registered and run as executable intent (screen 490d14df.., curves da886931.. with persisted taps). Finding: the gate reshapes the R-distribution per instrument (GER40 flips sign, EURUSD deteriorates); no deployable edge (best P(E[R]<=0)=0.08, generalization floor negative, sign agreement 0/4, all gross of costs). site/: build.py bakes a fully static index.html from the runs/ registry (aura.css embedded verbatim, inline SVG, zero external requests); adversarially verified — all baked figures re-derived from the registry. --- blueprints/bo_h1.json | 1 + blueprints/bo_h1_trend.json | 1 + docs/arc-1-breakout-trend.md | 63 ++ research/campaign-arc1-curves.json | 24 + research/campaign-arc1.json | 30 + research/process-curves.json | 9 + research/process-screen.json | 12 + site/assets/aura.css | 146 +++++ site/build.py | 914 +++++++++++++++++++++++++++++ site/index.html | 214 +++++++ 10 files changed, 1414 insertions(+) create mode 100644 blueprints/bo_h1.json create mode 100644 blueprints/bo_h1_trend.json create mode 100644 docs/arc-1-breakout-trend.md create mode 100644 research/campaign-arc1-curves.json create mode 100644 research/campaign-arc1.json create mode 100644 research/process-curves.json create mode 100644 research/process-screen.json create mode 100644 site/assets/aura.css create mode 100644 site/build.py create mode 100644 site/index.html diff --git a/blueprints/bo_h1.json b/blueprints/bo_h1.json new file mode 100644 index 0000000..b3eb8db --- /dev/null +++ b/blueprints/bo_h1.json @@ -0,0 +1 @@ +{"format_version":1,"blueprint":{"name":"bo_h1","nodes":[{"primitive":{"type":"Resample","name":"h1","bound":[{"pos":0,"name":"period_minutes","kind":"I64","value":{"I64":60}}]}},{"primitive":{"type":"Delay","name":"prev_high","bound":[{"pos":0,"name":"lag","kind":"I64","value":{"I64":1}}]}},{"primitive":{"type":"Delay","name":"prev_low","bound":[{"pos":0,"name":"lag","kind":"I64","value":{"I64":1}}]}},{"primitive":{"type":"RollingMax","name":"channel_hi","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":24}}]}},{"primitive":{"type":"RollingMin","name":"channel_lo","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":24}}]}},{"primitive":{"type":"Gt"}},{"primitive":{"type":"Gt"}},{"primitive":{"type":"Latch"}},{"primitive":{"type":"Latch"}},{"primitive":{"type":"Sub"}}],"edges":[{"from":0,"to":1,"slot":0,"from_field":1},{"from":0,"to":2,"slot":0,"from_field":2},{"from":0,"to":5,"slot":0,"from_field":3},{"from":0,"to":6,"slot":1,"from_field":3},{"from":1,"to":3,"slot":0,"from_field":0},{"from":2,"to":4,"slot":0,"from_field":0},{"from":3,"to":5,"slot":1,"from_field":0},{"from":4,"to":6,"slot":0,"from_field":0},{"from":5,"to":7,"slot":0,"from_field":0},{"from":6,"to":7,"slot":1,"from_field":0},{"from":6,"to":8,"slot":0,"from_field":0},{"from":5,"to":8,"slot":1,"from_field":0},{"from":7,"to":9,"slot":0,"from_field":0},{"from":8,"to":9,"slot":1,"from_field":0}],"input_roles":[{"name":"open","targets":[{"node":0,"slot":0}],"source":"F64"},{"name":"high","targets":[{"node":0,"slot":1}],"source":"F64"},{"name":"low","targets":[{"node":0,"slot":2}],"source":"F64"},{"name":"close","targets":[{"node":0,"slot":3}],"source":"F64"}],"output":[{"node":9,"field":0,"name":"bias"}]}} diff --git a/blueprints/bo_h1_trend.json b/blueprints/bo_h1_trend.json new file mode 100644 index 0000000..a776cdd --- /dev/null +++ b/blueprints/bo_h1_trend.json @@ -0,0 +1 @@ +{"format_version":1,"blueprint":{"name":"bo_h1_trend","nodes":[{"primitive":{"type":"Resample","name":"h1","bound":[{"pos":0,"name":"period_minutes","kind":"I64","value":{"I64":60}}]}},{"primitive":{"type":"Delay","name":"prev_high","bound":[{"pos":0,"name":"lag","kind":"I64","value":{"I64":1}}]}},{"primitive":{"type":"Delay","name":"prev_low","bound":[{"pos":0,"name":"lag","kind":"I64","value":{"I64":1}}]}},{"primitive":{"type":"RollingMax","name":"channel_hi","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":24}}]}},{"primitive":{"type":"RollingMin","name":"channel_lo","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":24}}]}},{"primitive":{"type":"Gt"}},{"primitive":{"type":"Gt"}},{"primitive":{"type":"Latch"}},{"primitive":{"type":"Latch"}},{"primitive":{"type":"EMA","name":"ema_fast","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":12}}]}},{"primitive":{"type":"EMA","name":"ema_slow","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":48}}]}},{"primitive":{"type":"Gt"}},{"primitive":{"type":"Gt"}},{"primitive":{"type":"Latch"}},{"primitive":{"type":"Latch"}},{"primitive":{"type":"Mul"}},{"primitive":{"type":"Mul"}},{"primitive":{"type":"Sub"}}],"edges":[{"from":0,"to":1,"slot":0,"from_field":1},{"from":0,"to":2,"slot":0,"from_field":2},{"from":0,"to":5,"slot":0,"from_field":3},{"from":0,"to":6,"slot":1,"from_field":3},{"from":0,"to":9,"slot":0,"from_field":3},{"from":0,"to":10,"slot":0,"from_field":3},{"from":1,"to":3,"slot":0,"from_field":0},{"from":2,"to":4,"slot":0,"from_field":0},{"from":3,"to":5,"slot":1,"from_field":0},{"from":4,"to":6,"slot":0,"from_field":0},{"from":5,"to":7,"slot":0,"from_field":0},{"from":6,"to":7,"slot":1,"from_field":0},{"from":6,"to":8,"slot":0,"from_field":0},{"from":5,"to":8,"slot":1,"from_field":0},{"from":9,"to":11,"slot":0,"from_field":0},{"from":10,"to":11,"slot":1,"from_field":0},{"from":10,"to":12,"slot":0,"from_field":0},{"from":9,"to":12,"slot":1,"from_field":0},{"from":11,"to":13,"slot":0,"from_field":0},{"from":12,"to":13,"slot":1,"from_field":0},{"from":12,"to":14,"slot":0,"from_field":0},{"from":11,"to":14,"slot":1,"from_field":0},{"from":7,"to":15,"slot":0,"from_field":0},{"from":13,"to":15,"slot":1,"from_field":0},{"from":8,"to":16,"slot":0,"from_field":0},{"from":14,"to":16,"slot":1,"from_field":0},{"from":15,"to":17,"slot":0,"from_field":0},{"from":16,"to":17,"slot":1,"from_field":0}],"input_roles":[{"name":"open","targets":[{"node":0,"slot":0}],"source":"F64"},{"name":"high","targets":[{"node":0,"slot":1}],"source":"F64"},{"name":"low","targets":[{"node":0,"slot":2}],"source":"F64"},{"name":"close","targets":[{"node":0,"slot":3}],"source":"F64"}],"output":[{"node":17,"field":0,"name":"bias"}]}} diff --git a/docs/arc-1-breakout-trend.md b/docs/arc-1-breakout-trend.md new file mode 100644 index 0000000..056c1bd --- /dev/null +++ b/docs/arc-1-breakout-trend.md @@ -0,0 +1,63 @@ +# Arc 1 — does a trend regime reshape the H1 breakout's R-distribution? + +**Date:** 2026-07-13 +**Engine:** aura @ `1ebb94c` (release build) +**Results page:** `site/index.html` (build: `python3 site/build.py`) + +## Hypothesis + +Following the orthogonal confirm/refute research model: a lone signal is not +expected to be profitable; the question is whether a *conditioner* B reshapes +the R-distribution of a base signal A. Here A = an H1 donchian-style breakout +(`blueprints/bo_h1.json`), B = an EMA(12)/EMA(48) trend regime that gates the +held breakout state post-latch (`blueprints/bo_h1_trend.json`) — a held +breakout is cut the moment the regime flips against it. + +## Method (campaign path, first real use) + +Everything ran as registered research documents — no ad-hoc verb flags: + +- `research/process-screen.json` — sweep (deflated argmax on sqn_normalized) + → 90/30-day rolling walk-forward refit → 1000-resample block-5 R-bootstrap + pooled over WF OOS trades → cross-instrument generalize (expectancy_r). +- `research/campaign-arc1.json` (id `490d14df…`) — both variants × 4 + instruments (GER40, US500, EURUSD, XAUUSD) × window 2018-01-01..2026-06-30, + channel axes {24,48,96}², risk Vol{3, 2.0}, seed 0. 8 cells, 76 s wall. +- `research/campaign-arc1-curves.json` (id `da886931…`) — both variants at + default params, taps persisted (equity, exposure, r_equity) for the page. + +No cost block: all R figures are **gross** (net == gross). + +## Findings + +1. **The gate reshapes the R-distribution, instrument-dependently** (pooled + WF-OOS bootstrap, mean E[R] and P(E[R] ≤ 0)): + - GER40 **flips sign**: −0.151 (P≤0 = 0.90) → +0.139 (P≤0 = 0.18) + - US500 improves: +0.193 (0.10) → +0.205 (0.08) + - EURUSD deteriorates sharply: −0.150 (0.88) → −0.204 (0.99) + - XAUUSD roughly flat: +0.170 (0.14) → +0.124 (0.15) + This is the conditional effect the research model looks for: B is not a + uniform improvement, it is a per-instrument reshaping. +2. **No deployable edge.** Best cell P(E[R] ≤ 0) ≈ 0.08 (US500 gated) — not + significant against 8 comparisons; generalization worst-case is deeply + negative for both variants with sign agreement 0/4; and all of it is + gross of costs. +3. **Selection instability.** The full-window IS argmax picks asymmetric + channels (e.g. hi=96/lo=24) that wander across WF windows — the deflation + and param-stability records show the screen overfitting the grid, which + the WF/MC stages correctly deflate. + +## Verdict + +Honest null on deployability; positive on the machinery and on the research +question's shape: the conditional framing (B reshapes A) is measurable with +the recorded artifacts alone (MC quantile bands per cell). Arc 2 candidates: +a costed rerun (constant + vol-slippage cost blocks) to see what survives +gross-to-net, an orthogonal conditioner (time-of-day / volatility tercile), +or the same pair on coarser bars (H4). + +## Engine friction + +None. The campaign path (process/campaign documents, three-tier validate, +`aura campaign run` as executor, persist_taps traces) carried the whole arc +on its first real use. diff --git a/research/campaign-arc1-curves.json b/research/campaign-arc1-curves.json new file mode 100644 index 0000000..852c420 --- /dev/null +++ b/research/campaign-arc1-curves.json @@ -0,0 +1,24 @@ +{ + "format_version": 1, + "kind": "campaign", + "name": "arc1-curves", + "description": "Trace companion to arc1-breakout-trend: both variants at their default parameters (channel 24/24, EMA 12/48) over the full window, persisting equity/exposure/r_equity curves for the results page. Default params isolate the gate's effect on the curve shape.", + "seed": 0, + "data": { + "instruments": ["GER40", "US500", "EURUSD", "XAUUSD"], + "windows": [ { "from_ms": 1514764800000, "to_ms": 1782863999999 } ] + }, + "risk": [ { "vol": { "length": 3, "k": 2.0 } } ], + "strategies": [ + { + "ref": { "content_id": "82515a31bfe58ae087b4bd09eb4adb032cc2cabddd71a2761c543066bd237d3d" }, + "axes": { "channel_hi.length": { "kind": "I64", "values": [24] } } + }, + { + "ref": { "content_id": "82d61d13bf21984068d6fd3ae9de9766fe99edb5163ea50ffb3485bfae9f56bc" }, + "axes": { "channel_hi.length": { "kind": "I64", "values": [24] } } + } + ], + "process": { "ref": { "content_id": "476752f5af365c85be3e5bd6265e5503040fc691ac548c0bd42e67714110e05f" } }, + "presentation": { "persist_taps": ["equity", "exposure", "r_equity"], "emit": [] } +} diff --git a/research/campaign-arc1.json b/research/campaign-arc1.json new file mode 100644 index 0000000..8175669 --- /dev/null +++ b/research/campaign-arc1.json @@ -0,0 +1,30 @@ +{ + "format_version": 1, + "kind": "campaign", + "name": "arc1-breakout-trend", + "description": "Arc 1 experiment intent: does an EMA trend regime reshape the H1 breakout's R-distribution? Both variants run over the identical data/window/risk/seed matrix; the comparison is per-cell.", + "seed": 0, + "data": { + "instruments": ["GER40", "US500", "EURUSD", "XAUUSD"], + "windows": [ { "from_ms": 1514764800000, "to_ms": 1782863999999 } ] + }, + "risk": [ { "vol": { "length": 3, "k": 2.0 } } ], + "strategies": [ + { + "ref": { "content_id": "82515a31bfe58ae087b4bd09eb4adb032cc2cabddd71a2761c543066bd237d3d" }, + "axes": { + "channel_hi.length": { "kind": "I64", "values": [24, 48, 96] }, + "channel_lo.length": { "kind": "I64", "values": [24, 48, 96] } + } + }, + { + "ref": { "content_id": "82d61d13bf21984068d6fd3ae9de9766fe99edb5163ea50ffb3485bfae9f56bc" }, + "axes": { + "channel_hi.length": { "kind": "I64", "values": [24, 48, 96] }, + "channel_lo.length": { "kind": "I64", "values": [24, 48, 96] } + } + } + ], + "process": { "ref": { "content_id": "41863fcae9300b334056c6f2a899e8c2672ecb29387d294e9a6e58f159ef51b4" } }, + "presentation": { "persist_taps": [], "emit": ["selection_report"] } +} diff --git a/research/process-curves.json b/research/process-curves.json new file mode 100644 index 0000000..c328ad4 --- /dev/null +++ b/research/process-curves.json @@ -0,0 +1,9 @@ +{ + "format_version": 1, + "kind": "process", + "name": "curves-sweep", + "description": "Trace producer: a terminal selection-free sweep whose members persist their tap curves (equity, exposure, r_equity) for the results page.", + "pipeline": [ + { "block": "std::sweep" } + ] +} diff --git a/research/process-screen.json b/research/process-screen.json new file mode 100644 index 0000000..a61fdf3 --- /dev/null +++ b/research/process-screen.json @@ -0,0 +1,12 @@ +{ + "format_version": 1, + "kind": "process", + "name": "screen-wf-mc-generalize", + "description": "Arc 1 methodology: full-window screen (deflated argmax on sqn_normalized), 90/30-day rolling walk-forward refit, pooled-OOS R-bootstrap, cross-instrument generalization floor.", + "pipeline": [ + { "block": "std::sweep", "metric": "sqn_normalized", "select": "argmax", "deflate": true }, + { "block": "std::walk_forward", "in_sample_ms": 7776000000, "out_of_sample_ms": 2592000000, "step_ms": 2592000000, "mode": "rolling", "metric": "sqn_normalized", "select": "argmax" }, + { "block": "std::monte_carlo", "resamples": 1000, "block_len": 5 }, + { "block": "std::generalize", "metric": "expectancy_r" } + ] +} diff --git a/site/assets/aura.css b/site/assets/aura.css new file mode 100644 index 0000000..6d17d33 --- /dev/null +++ b/site/assets/aura.css @@ -0,0 +1,146 @@ +/* aura.css — the single source of aura's frontend style: palette tokens + + * shared components. Embedded verbatim into every runtime page (render.rs + * SHELL_HEAD) and inlined into ad-hoc demo/report pages. New components + * extend this file; never fork the palette. Design record: issue #209. */ + +/* --------------------------------------------------------------------------- + * :root tokens + * Catppuccin-Mocha-derived palette; the page background (--bg) is + * deliberately darker than the Mocha base. --border3 (#585b70, Mocha + * surface2) completes the border ladder used by the shell tooltip. + * ------------------------------------------------------------------------- */ +:root { + --bg: #16161a; --bg2: #1e1e2e; --bg3: #24243a; + --border: #313244; --border2: #45475a; --border3: #585b70; + --fg: #cdd6f4; --dim: #7f849c; --dim2: #6c7086; + --accent: #f5e0dc; --blue: #89b4fa; --green: #a6e3a1; + --red: #f38ba8; --orange: #fab387; --yellow: #f9e2af; + --mauve: #cba6f7; --teal: #94e2d5; + --mono: ui-monospace, 'JetBrains Mono', 'Cascadia Code', Menlo, monospace; + --sans: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; +} + +/* --------------------------------------------------------------------------- + * shell + * Rules for the runtime viewer pages (graph / chart). Values are identical + * to the pre-token literals; only colors with a token were migrated to + * var(...). The font stays the literal `ui-monospace, monospace` (the + * --mono token carries a longer fallback chain and would change the + * computed value). + * ------------------------------------------------------------------------- */ +html, body { margin: 0; height: 100%; background: var(--bg); color: var(--fg); + font-family: ui-monospace, monospace; } +header { padding: 8px 14px; border-bottom: 1px solid var(--border); font-size: 13px; + display: flex; gap: 16px; align-items: baseline; flex-wrap: nowrap; + white-space: nowrap; overflow: hidden; } +header b { color: var(--accent); } .sub { color: var(--dim2); } +#crumb a { color: var(--blue); cursor: pointer; text-decoration: none; } +#crumb a:hover { text-decoration: underline; } +#crumb .sep { color: var(--dim2); } +#status { color: var(--dim2); margin-left: auto; } +#stage { width: 100%; height: calc(100% - 44px); } +#stage svg { width: 100%; height: 100%; cursor: default; } +#stage svg text { cursor: inherit; user-select: none; -webkit-user-select: none; } +#stage svg a { cursor: inherit; } +#err { padding: 14px; color: var(--red); white-space: pre-wrap; } +#tip { position: fixed; display: none; pointer-events: none; z-index: 10; + background: var(--bg2); border: 1px solid var(--border3); border-radius: 6px; padding: 6px 9px; + font-family: ui-monospace, monospace; font-size: 12px; color: var(--fg); + max-width: 420px; box-shadow: 0 6px 18px rgba(0,0,0,.55); line-height: 1.5; } +#tip b { color: var(--accent); } #tip code { color: var(--blue); } #tip .dim { color: var(--dim); } + +/* --------------------------------------------------------------------------- + * components (opt-in, class-scoped) + * Shared component library for ad-hoc document pages (demos, reports). + * Every rule is scoped to a class, so the runtime viewer pages — which use + * none of these classes — render pixel-identically with this block present. + * Element-level typography is scoped under .aura-doc: only pages that opt + * in via get the sans document register. + * ------------------------------------------------------------------------- */ + +/* document register — opt-in via body.aura-doc */ +body.aura-doc { font-family: var(--sans); line-height: 1.6; } +.aura-doc, .aura-doc * { box-sizing: border-box; } +.aura-doc a { color: var(--blue); text-decoration: none; } +.aura-doc a:hover { text-decoration: underline; } +.aura-doc code { font-family: var(--mono); font-size: 0.92em; background: var(--bg2); + border: 1px solid var(--border); border-radius: 4px; padding: 1px 5px; } + +/* centered content column */ +.wrap { max-width: 1100px; margin: 0 auto; padding: 0 24px; } + +/* status pill */ +.badge { display: inline-block; font-family: var(--mono); font-size: 12.5px; + padding: 3px 10px; border-radius: 20px; border: 1px solid; margin-right: 8px; } +.badge.green { color: var(--green); border-color: var(--green); background: rgba(166,227,161,.08); } +.badge.dim { color: var(--dim); border-color: var(--border2); } + +/* headline-number tiles */ +.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: 12px; margin-top: 28px; } +.stat { background: var(--bg2); border: 1px solid var(--border); border-radius: 10px; + padding: 14px 16px; } +.stat .n { font-family: var(--mono); font-size: 24px; color: var(--accent); } +.stat .l { color: var(--dim); font-size: 12.5px; margin-top: 2px; } + +/* card grid */ +.cards { display: grid; gap: 16px; margin: 20px 0; } +.cards.c3 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); } +.cards.c2 { grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); } +.card { background: var(--bg2); border: 1px solid var(--border); border-radius: 10px; + padding: 18px 20px; } +.card h3 { margin: 0 0 4px; font-size: 16px; } +.card h3 .tag { font-family: var(--mono); font-size: 11px; color: var(--dim); + font-weight: 400; margin-left: 6px; } +.card .cid { font-family: var(--mono); font-size: 11.5px; color: var(--teal); + word-break: break-all; margin: 4px 0 10px; } +.card .cid b { color: var(--accent); } +.card p { color: var(--dim); font-size: 14px; margin: 6px 0; } +.card pre { background: #131320; border: 1px solid var(--border); border-radius: 8px; + padding: 12px; overflow-x: auto; font-family: var(--mono); font-size: 12px; + line-height: 1.5; margin: 10px 0 0; } + +/* terminal transcript */ +.term { background: #131320; border: 1px solid var(--border); border-radius: 10px; + overflow: hidden; margin: 16px 0; } +.term .bar { display: flex; gap: 8px; align-items: center; padding: 7px 12px; + background: var(--bg2); border-bottom: 1px solid var(--border); + font-family: var(--mono); font-size: 12px; color: var(--dim); } +.term .bar .dots { display: inline-flex; gap: 5px; margin-right: 4px; } +.term .bar .dots i { width: 9px; height: 9px; border-radius: 50%; background: var(--border2); } +.term pre { margin: 0; padding: 14px 16px; overflow-x: auto; font-family: var(--mono); + font-size: 13px; line-height: 1.55; } +.term pre .p { color: var(--green); } +.term pre .cmd { color: var(--fg); font-weight: 600; } +.term pre .out { color: #b6bdd8; } +.term pre .err { color: var(--red); } +.term pre .hi { color: var(--yellow); } +.term pre .ok { color: var(--green); } +.term pre .dim { color: var(--dim2); } + +/* attention block */ +.callout { border-left: 3px solid var(--yellow); background: rgba(249,226,175,.06); + border-radius: 0 8px 8px 0; padding: 12px 18px; margin: 20px 0; color: var(--fg); + font-size: 14.5px; } +.callout.green { border-color: var(--green); background: rgba(166,227,161,.06); } +.callout b { color: var(--yellow); } +.callout.green b { color: var(--green); } + +/* results table */ +table.res { border-collapse: collapse; width: 100%; margin: 16px 0; font-size: 14px; } +table.res th, table.res td { border: 1px solid var(--border); padding: 8px 12px; text-align: left; } +table.res th { background: var(--bg2); color: var(--dim); font-weight: 600; font-size: 12.5px; } +table.res td { font-family: var(--mono); font-size: 13px; } +table.res td.neg { color: var(--red); } +table.res td.pos { color: var(--green); } +table.res td:first-child { color: var(--dim); font-family: var(--sans); font-size: 13.5px; } + +/* pipeline stages */ +.pipe { display: flex; flex-wrap: wrap; gap: 10px; align-items: stretch; margin: 24px 0; } +.pipe .stage { flex: 1 1 170px; background: var(--bg2); border: 1px solid var(--border2); + border-radius: 10px; padding: 12px 14px; position: relative; } +.pipe .stage.ann { border-style: dashed; } +.pipe .stage b { font-family: var(--mono); font-size: 14px; color: var(--accent); display: block; } +.pipe .stage i { font-style: normal; font-size: 11px; color: var(--mauve); font-family: var(--mono); } +.pipe .stage p { margin: 6px 0 0; font-size: 12.5px; color: var(--dim); line-height: 1.45; } +.pipe .arr { align-self: center; color: var(--dim2); font-family: var(--mono); font-size: 18px; } diff --git a/site/build.py b/site/build.py new file mode 100644 index 0000000..db2bcc3 --- /dev/null +++ b/site/build.py @@ -0,0 +1,914 @@ +#!/usr/bin/env python3 +"""Bake site/index.html — the static results page for aura-quadriga Arc 1. + +Reads the runs/ registry (campaign_runs.jsonl, families.jsonl, persisted +r_equity traces) and emits a fully self-contained HTML page: no external +requests, all charts are build-time inline SVG. + +Style contract (aura engine rule, issue #209): the page's first ") + add("") + add('
') + + # ---- 1 · hero ---------------------------------------------------------- + # NB: a
, not
— aura.css styles the bare header element for + # the runtime viewer shell (flex row, overflow hidden), which would + # swallow the stats grid and callout. + ger_a, ger_b = mc_by[("GER40", "A")], mc_by[("GER40", "B")] + add('
') + add("

aura-quadriga — Arc 1

") + add('

Does an EMA trend regime reshape an H1 breakout’s ' + "R-distribution?

") + add('
') + add(f'engine {engine_commit}') + add(f'project {esc(project_commit)}') + add('2018-01 → 2026-06 · m1') + add('GER40 · US500 · EURUSD · XAUUSD') + add('gross R — no cost model') + add(f'seed {main["seed"]}') + add("
") + add('
') + add(f'
{len(main["cells"])}
' + '
cells — 2 strategies × 4 instruments
') + add(f'
{n_windows}
' + '
walk-forward rolls per cell (90 d IS / 30 d OOS)
') + add(f'
{fc(pooled_trades["A"])} / {fc(pooled_trades["B"])}
' + '
pooled OOS trades — bo_h1 / bo_h1_trend
') + add(f'
{fp(best_p)}
' + f'
best-cell P(E[R]≤0) — {best_p_label}
') + add(f'
{sign_agree["A"]} / {n_instr}
' + '
cross-instrument sign agreement, either variant
') + worst_key = min(worst_case, key=worst_case.get) + add(f'
{fr(worst_case[worst_key], 2)}
' + f'
worst generalization floor (E[R], ' + f'{var_by_key[worst_key]["name"]})
') + add("
") + add('
The gate reshapes the R-distribution — per instrument, ' + "not uniformly. On the pooled walk-forward OOS bootstrap, GER40 flips sign: mean " + f'E[R] {fr(ger_a["e_r"]["mean"], 3)} (P(E[R]≤0) = {fp(ger_a["prob_le_zero"])}) ' + f'without the gate, {fr(ger_b["e_r"]["mean"], 3)} ({fp(ger_b["prob_le_zero"])}) with it. ' + "US500 improves, EURUSD deteriorates sharply, XAUUSD stays roughly flat. That " + "per-instrument conditionality — B reshapes A, instrument-dependently — is the finding " + "of this arc. No variant survives as a deployable edge: the best cell still shows " + f"P(E[R]≤0) = {fp(best_p)} across eight unadjusted comparisons, the " + "cross-instrument worst case is deeply negative for both variants " + f'({fr(worst_case["A"], 2)} plain, {fr(worst_case["B"], 2)} gated), sign agreement is ' + f'{sign_agree["A"]}/{n_instr} — and every figure on this page is gross of costs.
') + add("
") + + # ---- 2 · the experiment -------------------------------------------------- + add(section_h(2, "The experiment", + "Two blueprint variants over an identical data / window / risk / seed matrix; " + "the comparison is per cell. Risk regime Vol{length: 3, k: 2.0} — " + "the protective stop defines 1 R. No cost block: net == gross " + "everywhere.")) + add('
') + add('

bo_h1 variant A — base signal

') + add(f'
{VARIANTS[0]["cid"]}
') + add("

H1-resampled donchian-style breakout: RollingMax/Min(24) over Delay(1) high/low, " + "close vs channel (Gt), an SR-latch pair holds the breakout state; " + "bias = latch_long − latch_short ∈ {−1, 0, +1}.

") + add("
h1.period_minutes = 60      prev_high/low.lag = 1\n"
+        "channel_hi.length = 24      channel_lo.length = 24\n"
+        "risk = Vol { length: 3, k: 2.0 }   (shared)
") + add('

bo_h1_trend variant B — gated

') + add(f'
{VARIANTS[1]["cid"]}
') + add("

The same breakout, gated post-latch by an EMA(12) vs EMA(48) trend-regime latch " + "(Mul per side): a held breakout is suppressed the moment the regime flips against " + "it. Same channel params, same risk, same seed.

") + add("
ema_fast.length = 12        ema_slow.length = 48\n"
+        "channel_hi.length = 24      channel_lo.length = 24\n"
+        "risk = Vol { length: 3, k: 2.0 }   (shared)
") + add("
") + add('
') + add(f'
std::sweep {grid_cells} trials' + "

3×3 channel grid (hi/lo ∈ {24, 48, 96}), argmax on sqn_normalized, " + "deflated (1 000 resamples, block 5).

") + add('') + add(f'
std::walk_forward {n_windows} rolls' + "

Rolling 90-day IS refit over the same axes, 30-day OOS, 30-day step; " + "argmax on sqn_normalized per roll.

") + add('') + add(f'
std::monte_carlo {fc(mc_rows[0]["n_resamples"])} × ' + f'block {mc_rows[0]["block_len"]}' + "

Block bootstrap of the R-series pooled over all walk-forward OOS trades: " + "E[R] quantiles and P(E[R]≤0) per cell.

") + add('') + add('
std::generalize expectancy_r' + "

Cross-instrument floor: apply each instrument’s winner to the other three; " + "worst case and sign agreement.

") + add("
") + add(f'

Screen campaign {main["campaign"][:8]}… runs the full ' + f'pipeline; curves campaign {curves["campaign"][:8]}… re-runs both variants ' + "at default params (channel 24/24, EMA 12/48), selection-free, persisting equity / exposure / " + "r_equity taps for sections 4 and 6.

") + + # ---- 3 · R-distribution --------------------------------------------------- + add(section_h(3, "R-distribution — pooled-OOS bootstrap", + f'{fc(mc_rows[0]["n_resamples"])}-resample block-{mc_rows[0]["block_len"]} ' + "bootstrap of per-trade R, pooled over each cell’s " + f"{n_windows} walk-forward OOS windows (screen campaign). Whisker p5–p95, " + "box p25–p75, tick median, dot mean. The dashed line is E[R] = 0 — " + "mass to its right is what an edge would look like. Gross R.")) + add(legend_html()) + add(f'
{interval_plot(mc_rows)}
') + add('

GER40 is the reshaping case: the gate moves essentially the whole ' + "interval across zero. EURUSD moves the other way — the gate makes it decisively worse. " + "A conditioner, not an improvement.

") + + # ---- 4 · per-instrument tables --------------------------------------------- + add(section_h(4, "Per-instrument metrics — default params, full window", + "Single members from the curves campaign (channel 24/24, EMA 12/48, no " + "selection), full 2018–2026 window, gross R. This isolates the " + "gate’s effect from the screen’s parameter selection. The shape is " + "classic vol-stop breakout: ~10 % hit rate, average win an order of " + "magnitude larger than average loss.")) + add('
') + for inst in INSTRUMENTS: + a, b = cur[(inst, "A")], cur[(inst, "B")] + add(f'

{inst} default params · gross

') + add('') + + def row(label, va, vb, fmt, signed=False): + def td(v, txt): + cls = "" + if signed: + cls = ' class="pos"' if v > 0 else (' class="neg"' if v < 0 else "") + return f"{txt}" + add(f"{td(va, fmt(va))}{td(vb, fmt(vb))}") + + row("expectancy_r", a["expectancy_r"], b["expectancy_r"], lambda v: fr(v), signed=True) + row("win_rate", a["win_rate"], b["win_rate"], lambda v: f"{fnum(v * 100)} %") + row("profit_factor", a["profit_factor"], b["profit_factor"], lambda v: fnum(v, 3)) + row("sqn_normalized", a["sqn_normalized"], b["sqn_normalized"], lambda v: fr(v), signed=True) + row("max_r_drawdown", a["max_r_drawdown"], b["max_r_drawdown"], + lambda v: f"{fnum(v)} R") + row("n_trades", a["n_trades"], b["n_trades"], lambda v: fc(v)) + row("bias_sign_flips", a["bias_sign_flips"], b["bias_sign_flips"], lambda v: fc(v)) + add("
bo_h1bo_h1_trend
{label}
") + add(tercile_svg(inst, {"A": a["conviction_terciles_r"], "B": b["conviction_terciles_r"]}, + terc_max)) + add('

conviction terciles — mean R per trade by tercile; within each ' + "group: left bar bo_h1, right bar bo_h1_trend; green/red by sign

") + add("
") + add("
") + + # ---- 5 · walk-forward ------------------------------------------------------- + max_distinct = max(wf_distinct.values()) + add(section_h(5, "Walk-forward — stitched OOS R", + f"Cumulative out-of-sample R across the {n_windows} rolled windows " + "(per-window expectancy × trades, refit each roll). The IS " + "winner is unstable: in every one of the eight cells the per-roll argmax " + f"visits all {max_distinct} cells of the 3×3 channel grid at least once " + "over the 100 rolls — the full-window screen winner is not a stable optimum, " + "which is exactly what the deflated sweep scores already hinted at.")) + add(legend_html()) + add('
') + for inst in INSTRUMENTS: + add(f'

{inst} OOS, refit per roll

') + add(wf_svg(inst, wf_series[inst])) + add('' + "") + for var in VARIANTS: + s = wf_stats[(inst, var["key"])] + cls = "pos" if s["total"] > 0 else "neg" + add(f'' + f'' + f'') + add("
windowspositivestitched R
{var["name"]}{s["windows"]}{fnum(s["pos_pct"], 0)} %{fr(s["total"], 1)}
") + add("
") + + # ---- 6 · full-period R-curves ----------------------------------------------- + add(section_h(6, "Full-period R-curves — default params", + "Cumulative realized + unrealized R from the persisted r_equity " + "taps (curves campaign, default params — gate-effect isolation, no selection), " + f"~2.6 M m1 points per member decimated to ≤{fc(ENVELOPE_BUCKETS)} " + "min–max envelope buckets: the band is the per-bucket min–max range " + "(drawdown spikes survive the decimation), the line its midpoint. Gross R.")) + add(legend_html()) + add('
') + for inst in INSTRUMENTS: + add(f'

{inst} r_equity · full window

') + add(envelope_svg(inst, envelopes[inst], finals[inst])) + add("
") + add("
") + + # ---- 7 · artifacts & reproduce ------------------------------------------------ + add(section_h(7, "Artifacts & reproduce", + "Everything on this page is derived from the runs/ registry; every artifact " + "is content-addressed. Same documents, same seed → same numbers.")) + add('
' + "aura-quadriga — reproduce
")
+    add(f'$ aura campaign run research/campaign-arc1.json'
+        f'        # screen → {main["campaign"][:8]}…\n')
+    add(f'$ aura campaign run research/campaign-arc1-curves.json'
+        f' # curves → {curves["campaign"][:8]}…\n')
+    add('$ aura runs families'
+        '                                    # registry index\n')
+    add(f'$ aura reproduce '
+        f'{stage(cell_of(main, VARIANTS[0]["cid"], "GER40"), "std::walk_forward")["family_id"]}'
+        '   # any family, bit-identical\n')
+    add(f'$ aura chart {curves["trace_name"]} '
+        '--tap r_equity              # interactive trace viewer')
+    add("
") + add('
') + add('

Blueprints

' + f'
bo_h1
{VARIANTS[0]["cid"]}
' + f'
bo_h1_trend
{VARIANTS[1]["cid"]}
') + add('

Processes

' + f'
screen-wf-mc-generalize
{main["process"]}
' + f'
curves-sweep
{curves["process"]}
') + add('

Campaigns

' + f'
arc1-breakout-trend
{main["campaign"]}
' + f'
arc1-curves
{curves["campaign"]}
') + add("
") + add(f'

generated by site/build.py from the runs/ registry · ' + f'engine {engine_commit} · project {esc(project_commit)} · {PAGE_DATE}

') + + add("
") # .wrap + add("") + add("") + + OUT_PATH.write_text("".join(h)) + print(f"wrote {OUT_PATH} ({OUT_PATH.stat().st_size:,} bytes)") + + +def section_h(n, title, sub): + return (f'
0{n}

{title}

' + f'

{sub}

') + + +# -------------------------------------------------------------------------- +# page-specific CSS — tokens only (var(--x)) + the pinned series palette +# -------------------------------------------------------------------------- + +PAGE_CSS = """ +/* page-specific rules — consume aura.css tokens only; series colors are the + * established palette slots #89b4fa (A) and #cba6f7 (B). */ +.wrap { padding-top: 44px; padding-bottom: 28px; } +.hero h1 { margin: 0 0 4px; font-size: 30px; letter-spacing: -0.5px; } +.subtitle { margin: 0 0 18px; color: var(--dim); font-size: 16.5px; } +.badges { margin: 14px 0 4px; line-height: 2.2; } +.badge.warn { color: var(--yellow); border-color: var(--yellow); + background: rgba(249,226,175,.08); } +.sec { margin-top: 54px; } +.sec .kick { font-family: var(--mono); font-size: 11.5px; color: var(--dim2); + letter-spacing: 2px; } +.sec h2 { margin: 2px 0 8px; font-size: 21px; } +.sec .sub { margin: 0; color: var(--dim); font-size: 14px; max-width: 74ch; } +.fnote { color: var(--dim); font-size: 13px; max-width: 74ch; } +.fnote.foot { margin-top: 40px; border-top: 1px solid var(--border); + padding-top: 14px; font-family: var(--mono); font-size: 12px; max-width: none; } +.mini { color: var(--dim2); font-size: 11.5px; font-family: var(--mono); + margin: 4px 0 0; } +.chartbox { margin: 14px 0; } +.legend { display: flex; gap: 22px; margin: 16px 0 4px; font-family: var(--mono); + font-size: 12.5px; color: var(--fg); } +.legend .lk { color: var(--dim); } +.legend .sw { display: inline-block; width: 10px; height: 10px; border-radius: 3px; + margin-right: 7px; vertical-align: -1px; } +.legend .swA { background: #89b4fa; } +.legend .swB { background: #cba6f7; } +/* chart internals */ +.chart { display: block; } +.chart text { font-family: var(--mono); } +.chart .tick { fill: var(--dim); font-size: 10.5px; } +.chart .grid { stroke: var(--border); stroke-width: 1; } +.chart .zero { stroke: var(--dim2); stroke-width: 1; } +.chart .zero-d { stroke: var(--dim2); stroke-width: 1; stroke-dasharray: 4 4; } +.chart .base { stroke: var(--border2); stroke-width: 1; } +.chart .inst { fill: var(--accent); font-size: 13px; } +.chart .vlab { fill: var(--dim); font-size: 11px; } +.chart .ro { font-size: 11.5px; } +.chart .ro-p { fill: var(--fg); } +.chart .ro-n { fill: var(--dim); } +.chart .endlab { fill: var(--fg); font-size: 11px; } +.chart .med { stroke: var(--accent); stroke-width: 2; } +.chart .sA { stroke: #89b4fa; } .chart .sB { stroke: #cba6f7; } +.chart .fA { fill: #89b4fa; } .chart .fB { fill: #cba6f7; } +.chart .wh { stroke-width: 1.5; fill: none; } +.chart .box { fill: var(--bg3); stroke-width: 1; } +.chart .mean { stroke: var(--bg); stroke-width: 2; } +.chart .ln { fill: none; stroke-width: 2; stroke-linejoin: round; + stroke-linecap: round; } +.chart .mid { fill: none; stroke-width: 1.6; stroke-linejoin: round; } +.chart .band { stroke: none; fill-opacity: 0.16; } +.chart .pb { fill: var(--green); } .chart .nb { fill: var(--red); } +.chart [data-tip] { cursor: default; } +.card .chart { margin-top: 6px; } +@media (max-width: 640px) { .legend { flex-wrap: wrap; gap: 10px; } } +""" + +# hover tooltips — reuses aura.css's #tip shell styles; enhancement only, +# every value is also present as text or in a table. +TIP_JS = ("(function(){var t=document.getElementById('tip');" + "document.addEventListener('pointerover',function(e){" + "var m=e.target.closest&&e.target.closest('[data-tip]');" + "if(!m){t.style.display='none';return;}" + "t.textContent=m.getAttribute('data-tip');t.style.display='block';});" + "document.addEventListener('pointermove',function(e){" + "if(t.style.display!=='block')return;" + "var x=Math.min(e.clientX+14,innerWidth-t.offsetWidth-8)," + "y=Math.min(e.clientY+18,innerHeight-t.offsetHeight-8);" + "t.style.left=x+'px';t.style.top=y+'px';});})();") + + +if __name__ == "__main__": + build() diff --git a/site/index.html b/site/index.html new file mode 100644 index 0000000..5da32ae --- /dev/null +++ b/site/index.html @@ -0,0 +1,214 @@ +aura-quadriga — Arc 1

aura-quadriga — Arc 1

Does an EMA trend regime reshape an H1 breakout’s R-distribution?

engine 1ebb94cproject 221c4082018-01 → 2026-06 · m1GER40 · US500 · EURUSD · XAUUSDgross R — no cost modelseed 0
8
cells — 2 strategies × 4 instruments
100
walk-forward rolls per cell (90 d IS / 30 d OOS)
17 640 / 20 163
pooled OOS trades — bo_h1 / bo_h1_trend
0.080
best-cell P(E[R]≤0) — US500, bo_h1_trend
0 / 4
cross-instrument sign agreement, either variant
−1.06
worst generalization floor (E[R], bo_h1_trend)
The gate reshapes the R-distribution — per instrument, not uniformly. On the pooled walk-forward OOS bootstrap, GER40 flips sign: mean E[R] −0.151 (P(E[R]≤0) = 0.895) without the gate, +0.139 (0.177) with it. US500 improves, EURUSD deteriorates sharply, XAUUSD stays roughly flat. That per-instrument conditionality — B reshapes A, instrument-dependently — is the finding of this arc. No variant survives as a deployable edge: the best cell still shows P(E[R]≤0) = 0.080 across eight unadjusted comparisons, the cross-instrument worst case is deeply negative for both variants (−0.75 plain, −1.06 gated), sign agreement is 0/4 — and every figure on this page is gross of costs.
02

The experiment

Two blueprint variants over an identical data / window / risk / seed matrix; the comparison is per cell. Risk regime Vol{length: 3, k: 2.0} — the protective stop defines 1 R. No cost block: net == gross everywhere.

bo_h1 variant A — base signal

82515a31bfe58ae087b4bd09eb4adb032cc2cabddd71a2761c543066bd237d3d

H1-resampled donchian-style breakout: RollingMax/Min(24) over Delay(1) high/low, close vs channel (Gt), an SR-latch pair holds the breakout state; bias = latch_long − latch_short ∈ {−1, 0, +1}.

h1.period_minutes = 60      prev_high/low.lag = 1
+channel_hi.length = 24      channel_lo.length = 24
+risk = Vol { length: 3, k: 2.0 }   (shared)

bo_h1_trend variant B — gated

82d61d13bf21984068d6fd3ae9de9766fe99edb5163ea50ffb3485bfae9f56bc

The same breakout, gated post-latch by an EMA(12) vs EMA(48) trend-regime latch (Mul per side): a held breakout is suppressed the moment the regime flips against it. Same channel params, same risk, same seed.

ema_fast.length = 12        ema_slow.length = 48
+channel_hi.length = 24      channel_lo.length = 24
+risk = Vol { length: 3, k: 2.0 }   (shared)
std::sweep 9 trials

3×3 channel grid (hi/lo ∈ {24, 48, 96}), argmax on sqn_normalized, deflated (1 000 resamples, block 5).

std::walk_forward 100 rolls

Rolling 90-day IS refit over the same axes, 30-day OOS, 30-day step; argmax on sqn_normalized per roll.

std::monte_carlo 1 000 × block 5

Block bootstrap of the R-series pooled over all walk-forward OOS trades: E[R] quantiles and P(E[R]≤0) per cell.

std::generalize expectancy_r

Cross-instrument floor: apply each instrument’s winner to the other three; worst case and sign agreement.

Screen campaign 490d14df… runs the full pipeline; curves campaign da886931… re-runs both variants at default params (channel 24/24, EMA 12/48), selection-free, persisting equity / exposure / r_equity taps for sections 4 and 6.

03

R-distribution — pooled-OOS bootstrap

1 000-resample block-5 bootstrap of per-trade R, pooled over each cell’s 100 walk-forward OOS windows (screen campaign). Whisker p5–p95, box p25–p75, tick median, dot mean. The dashed line is E[R] = 0 — mass to its right is what an edge would look like. Gross R.

bo_h1 (A — breakout)bo_h1_trend (B — gated)
−0.20+0.2+0.4pooled walk-forward OOS E[R] per trade (gross)GER40bo_h1P(≤0) 0.895 · n 4 576bo_h1_trendP(≤0) 0.177 · n 4 893US500bo_h1P(≤0) 0.104 · n 4 362bo_h1_trendP(≤0) 0.080 · n 4 947EURUSDbo_h1P(≤0) 0.884 · n 4 700bo_h1_trendP(≤0) 0.988 · n 5 442XAUUSDbo_h1P(≤0) 0.142 · n 4 002bo_h1_trendP(≤0) 0.150 · n 4 881

GER40 is the reshaping case: the gate moves essentially the whole interval across zero. EURUSD moves the other way — the gate makes it decisively worse. A conditioner, not an improvement.

04

Per-instrument metrics — default params, full window

Single members from the curves campaign (channel 24/24, EMA 12/48, no selection), full 2018–2026 window, gross R. This isolates the gate’s effect from the screen’s parameter selection. The shape is classic vol-stop breakout: ~10 % hit rate, average win an order of magnitude larger than average loss.

GER40 default params · gross

bo_h1bo_h1_trend
expectancy_r+0.0716+0.0563
win_rate9.9 %11.6 %
profit_factor1.0581.046
sqn_normalized+0.0761+0.0606
max_r_drawdown751.5 R756.4 R
n_trades6 4356 664
bias_sign_flips8611 882
T1T2T3

conviction terciles — mean R per trade by tercile; within each group: left bar bo_h1, right bar bo_h1_trend; green/red by sign

US500 default params · gross

bo_h1bo_h1_trend
expectancy_r+0.0450+0.1572
win_rate9.6 %11.3 %
profit_factor1.0361.128
sqn_normalized+0.0494+0.1448
max_r_drawdown804.8 R440.8 R
n_trades7 2937 157
bias_sign_flips9772 001
T1T2T3

conviction terciles — mean R per trade by tercile; within each group: left bar bo_h1, right bar bo_h1_trend; green/red by sign

EURUSD default params · gross

bo_h1bo_h1_trend
expectancy_r−0.0866−0.0771
win_rate10.3 %11.5 %
profit_factor0.9310.937
sqn_normalized−0.1100−0.0969
max_r_drawdown1005.4 R1313.6 R
n_trades6 7887 398
bias_sign_flips9142 055
T1T2T3

conviction terciles — mean R per trade by tercile; within each group: left bar bo_h1, right bar bo_h1_trend; green/red by sign

XAUUSD default params · gross

bo_h1bo_h1_trend
expectancy_r+0.1406+0.0299
win_rate10.1 %12.2 %
profit_factor1.1141.024
sqn_normalized+0.1435+0.0361
max_r_drawdown451.9 R586.4 R
n_trades6 2016 825
bias_sign_flips8692 029
T1T2T3

conviction terciles — mean R per trade by tercile; within each group: left bar bo_h1, right bar bo_h1_trend; green/red by sign

05

Walk-forward — stitched OOS R

Cumulative out-of-sample R across the 100 rolled windows (per-window expectancy × trades, refit each roll). The IS winner is unstable: in every one of the eight cells the per-roll argmax visits all 9 cells of the 3×3 channel grid at least once over the 100 rolls — the full-window screen winner is not a stable optimum, which is exactly what the deflated sweep scores already hinted at.

bo_h1 (A — breakout)bo_h1_trend (B — gated)

GER40 OOS, refit per roll

−5000+5002019202120232025A −678 RB +628 R
windowspositivestitched R
bo_h110040 %−678.0
bo_h1_trend10049 %+627.9

US500 OOS, refit per roll

0+500+10002019202120232025A +825 RB +1064 R
windowspositivestitched R
bo_h110042 %+825.1
bo_h1_trend10048 %+1063.6

EURUSD OOS, refit per roll

−1000−50002019202120232025A −696 RB −1112 R
windowspositivestitched R
bo_h110047 %−696.1
bo_h1_trend10036 %−1111.7

XAUUSD OOS, refit per roll

0+250+5002019202120232025A +668 RB +583 R
windowspositivestitched R
bo_h110050 %+668.0
bo_h1_trend10048 %+583.0
06

Full-period R-curves — default params

Cumulative realized + unrealized R from the persisted r_equity taps (curves campaign, default params — gate-effect isolation, no selection), ~2.6 M m1 points per member decimated to ≤1 100 min–max envelope buckets: the band is the per-bucket min–max range (drawdown spikes survive the decimation), the line its midpoint. Gross R.

bo_h1 (A — breakout)bo_h1_trend (B — gated)

GER40 r_equity · full window

0+5002019202120232025A +460.6 RB +375.1 R

US500 r_equity · full window

0+500+1000+15002019202120232025A +328.5 RB +1125.3 R

EURUSD r_equity · full window

−5000+5002019202120232025A −588.0 RB −570.6 R

XAUUSD r_equity · full window

0+500+10002019202120232025A +871.8 RB +203.7 R
07

Artifacts & reproduce

Everything on this page is derived from the runs/ registry; every artifact is content-addressed. Same documents, same seed → same numbers.

aura-quadriga — reproduce
$ aura campaign run research/campaign-arc1.json        # screen → 490d14df…
+$ aura campaign run research/campaign-arc1-curves.json # curves → da886931…
+$ aura runs families                                    # registry index
+$ aura reproduce 490d14df-0-GER40-w0-r0-s1-0   # any family, bit-identical
+$ aura chart da886931-0 --tap r_equity              # interactive trace viewer

Blueprints

bo_h1
82515a31bfe58ae087b4bd09eb4adb032cc2cabddd71a2761c543066bd237d3d
bo_h1_trend
82d61d13bf21984068d6fd3ae9de9766fe99edb5163ea50ffb3485bfae9f56bc

Processes

screen-wf-mc-generalize
41863fcae9300b334056c6f2a899e8c2672ecb29387d294e9a6e58f159ef51b4
curves-sweep
476752f5af365c85be3e5bd6265e5503040fc691ac548c0bd42e67714110e05f

Campaigns

arc1-breakout-trend
490d14df576a7ef2ad099bbfdd21b9840f4cd9436e499f7e541316dc646e47eb
arc1-curves
da886931b0688d57a17e64a016cc004af792038454513dc7b8826763d778c685

generated by site/build.py from the runs/ registry · engine 1ebb94c · project 221c408 · 2026-07-13

\ No newline at end of file