diff --git a/fieldtests/cycle-328-axis-namespace/TRANSCRIPT.md b/fieldtests/cycle-328-axis-namespace/TRANSCRIPT.md new file mode 100644 index 0000000..5dd02d6 --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/TRANSCRIPT.md @@ -0,0 +1,109 @@ +# Fieldtest transcript — cycle #328 (axis-namespace reconciliation) + +Per-cycle field test of the one-raw-namespace axis surface: the raw +`.` form as the only user-facing sweep-axis name across every +surface (discovery, intake on all three verbs, run manifests, campaign +documents), with the wrapped `..` form retired behind +translation refusals. + +Binary: `target/release/aura`, built from HEAD `4474814` via +`cargo build --release -p aura-cli` (Finished in 5.45s — HEAD builds clean). +Scratch project `aura new ax_lab` in `/tmp/axwork/ax_lab`; real data from the +built-in archive (US500). Public interface only (README, authoring-guide, +glossary, design ledger, `aura … --help`) — no crate source read. + +Base blueprint `cycle328_crossover`: an SMA-crossover → bias signal with a +deliberate mix — `fast.length` **open**, `slow.length` **bound** (default=6), +`bias.scale` **bound** (default=0.5) — so both discovery line shapes and the +bound-override contract are exercised. Content id +`f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240`. + +--- + +## Example 1 — discovery-surface identity (`--params` vs `--list-axes`) + +``` +$ aura graph introspect --params cycle328_crossover.bp.json +fast.length:I64 +slow.length:I64 default=6 +bias.scale:F64 default=0.5 +$ aura sweep cycle328_crossover.bp.json --list-axes +fast.length:I64 +slow.length:I64 default=6 +bias.scale:F64 default=0.5 +$ diff params.txt listaxes.txt # → IDENTICAL (no diff) +``` + +Byte-identical, raw `.` form, bound params carrying `default=`. +`--params` discovers bound params too. (Finding W1.) + +## Example 2 — document-first loop (paste verbatim, incl. bound-override) + +Axes pasted verbatim from `--params` into a hand-written campaign document +(`cycle328_2_campaign.json`), including two bound-override axes (`slow.length`, +`bias.scale` — bound defaults re-opened by name, #246 coincidence contract): + +``` +$ aura campaign validate cycle328_2_campaign.json # inside project, refs registered +campaign document valid (intrinsic): 1 strategy(ies), 3 axes (4 points), 1 instrument(s), 1 window(s), 1 regime(s) (default) — 1 cell(s) +campaign document valid (referential): all references resolve, axes are in the param space +campaign document valid (executable): pipeline shape and static guards pass +$ aura campaign run cycle328_2_campaign.json # exit 0 +aura: campaign run 0 recorded: 1 cells +# manifest.params (raw): fast.length, slow.length, bias.scale (+ stop knobs) +``` + +All three tiers pass; the bound-override axes validate; the run manifest records +raw names. (Finding W2.) + +## Example 3 — translation seams (wrapped form on every intake) + +``` +$ aura sweep cycle328_crossover.bp.json --axis graph.fast.length=2,4 ... (exit 2) +$ aura sweep cycle328_crossover.bp.json --real US500 --axis graph.fast.length=... (exit 2) +$ aura walkforward cycle328_crossover.bp.json --real US500 --axis graph.fast.length=... (exit 2) +aura: axis "graph.fast.length": axis names are raw node.param paths — use "fast.length" (the wrapped --list-axes form was retired, #328) + +$ aura campaign validate cycle328_3d_wrapped_campaign.json (exit 1) +aura: campaign references do not resolve: + strategy f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240: axis "graph.fast.length" is not in the param space; axis names are raw node.param paths — did you mean "fast.length"? +``` + +All three verbs refuse identically, naming the raw candidate; campaign validate +appends a did-you-mean. Note the campaign-validate strategy identifier is the +FULL 64-hex content id, where the authoring guide's transcript shows a 4-hex +`strategy 9f3a:` placeholder (Finding SG1). Edge probes: + +``` +$ aura sweep ... --axis fastt.length=2,4 # typo +aura: axis fastt.length: names no param of this blueprint (open or bound) — see `aura sweep --list-axes` +$ aura sweep ... --axis graph.fast.bogus=1 # wrapped, tail not a param +aura: axis graph.fast.bogus: names no param of this blueprint (open or bound) — see `aura sweep --list-axes` +$ aura sweep ... --axis project.graph.fast.length=2 # two leading segments (> one) +aura: axis project.graph.fast.length: names no param of this blueprint (open or bound) — see `aura sweep --list-axes` +``` + +Typos and >1-segment wrappings fall to a clean generic error — consistent with +the documented "one leading segment strips to a hit" contract. (Finding W3.) + +## Example 4 — manifest raw names + reproduce + +``` +$ aura sweep cycle328_crossover.bp.json --axis fast.length=2,4 --axis slow.length=8,16 --name cycle328-sweep-bo +# each member manifest: +# params: [["fast.length",..],["slow.length",..],["stop_length",..],["stop_k",..]] (raw) +# defaults: [["bias.scale",{"F64":0.5}]] (raw) +$ aura reproduce cycle328-sweep-bo-0 (exit 0) +cycle328-sweep-bo-0 member fast.length=2, slow.length=8, stop_length=3, stop_k=2 reproduced: bit-identical +... reproduced 4/4 members bit-identically +``` + +Positive real/walkforward routes also record raw (params AND defaults) and run +clean (exit 0): `cycle328_6a_sweep_real.*`, `cycle328_6b_walkforward.*`. No +wrapped name appears on any surface. (Finding W4.) + +--- + +Not exercised: the "old wrapped-name manifests remain reproducible" backward- +compat claim (no pre-#328 on-disk family is reachable through the public +interface to a source-blind consumer). diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_1_listaxes.err b/fieldtests/cycle-328-axis-namespace/cycle328_1_listaxes.err new file mode 100644 index 0000000..e69de29 diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_1_listaxes.txt b/fieldtests/cycle-328-axis-namespace/cycle328_1_listaxes.txt new file mode 100644 index 0000000..e472fd3 --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_1_listaxes.txt @@ -0,0 +1,3 @@ +fast.length:I64 +slow.length:I64 default=6 +bias.scale:F64 default=0.5 diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_1_params.err b/fieldtests/cycle-328-axis-namespace/cycle328_1_params.err new file mode 100644 index 0000000..e69de29 diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_1_params.txt b/fieldtests/cycle-328-axis-namespace/cycle328_1_params.txt new file mode 100644 index 0000000..e472fd3 --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_1_params.txt @@ -0,0 +1,3 @@ +fast.length:I64 +slow.length:I64 default=6 +bias.scale:F64 default=0.5 diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_2_campaign.json b/fieldtests/cycle-328-axis-namespace/cycle328_2_campaign.json new file mode 100644 index 0000000..d339f97 --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_2_campaign.json @@ -0,0 +1,22 @@ +{ + "format_version": 1, + "kind": "campaign", + "name": "cycle328-doc-first-boundoverride", + "seed": 7, + "data": { + "instruments": ["US500"], + "windows": [ { "from_ms": 1725148800000, "to_ms": 1725580800000 } ] + }, + "strategies": [ + { + "ref": { "content_id": "f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240" }, + "axes": { + "fast.length": { "kind": "I64", "values": [2, 4] }, + "slow.length": { "kind": "I64", "values": [8, 16] }, + "bias.scale": { "kind": "F64", "values": [0.5] } + } + } + ], + "process": { "ref": { "content_id": "f14023a1fef5640311163690f1140532412ea5e1d1cbb93e293e63fcf0bf2bf9" } }, + "presentation": { "persist_taps": [], "emit": ["family_table"] } +} diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_2_proc.json b/fieldtests/cycle-328-axis-namespace/cycle328_2_proc.json new file mode 100644 index 0000000..5ed7fa1 --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_2_proc.json @@ -0,0 +1 @@ +{"format_version":1,"kind":"process","name":"ax-sweep-select","description":"Sweep the grid and select the argmax-SQN cell.","pipeline":[{"block":"std::sweep","metric":"sqn","select":"argmax"}]} diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_2_run.err b/fieldtests/cycle-328-axis-namespace/cycle328_2_run.err new file mode 100644 index 0000000..7230024 --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_2_run.err @@ -0,0 +1 @@ +aura: campaign run 0 recorded: 1 cells diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_2_run.json b/fieldtests/cycle-328-axis-namespace/cycle328_2_run.json new file mode 100644 index 0000000..b162880 --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_2_run.json @@ -0,0 +1,5 @@ +{"family_id":"844fe329-0-US500-w0-r0-s0-0","report":{"manifest":{"commit":"4474814fa79e227cd2d93e34a6982b49f31ba846","params":[["fast.length",{"I64":2}],["slow.length",{"I64":8}],["bias.scale",{"F64":0.5}],["stop_length",{"I64":3}],["stop_k",{"F64":2.0}]],"defaults":[],"window":[1725148800000000000,1725580800000000000],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=1)","instrument":"US500","topology_hash":"f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240","project":{"commit":"6bb76063046d41062b68fbde79950b9d06fbd41d"}},"metrics":{"total_pips":46.422499999968466,"max_drawdown":125.89999999998915,"bias_sign_flips":861,"r":{"expectancy_r":0.052960279961470944,"n_trades":846,"win_rate":0.31796690307328607,"avg_win_r":1.8016249253621428,"avg_loss_r":-0.7622750573223781,"profit_factor":1.1018669053593053,"max_r_drawdown":29.11884107504975,"n_open_at_end":1,"sqn":0.8388429079176243,"sqn_normalized":0.2884001324999155,"net_expectancy_r":0.052960279961470944,"conviction_terciles_r":[-0.05618014716431794,0.13546662237309962,0.07959436467563116]}}}} +{"family_id":"844fe329-0-US500-w0-r0-s0-0","report":{"manifest":{"commit":"4474814fa79e227cd2d93e34a6982b49f31ba846","params":[["fast.length",{"I64":2}],["slow.length",{"I64":16}],["bias.scale",{"F64":0.5}],["stop_length",{"I64":3}],["stop_k",{"F64":2.0}]],"defaults":[],"window":[1725148800000000000,1725580800000000000],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=1)","instrument":"US500","topology_hash":"f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240","project":{"commit":"6bb76063046d41062b68fbde79950b9d06fbd41d"}},"metrics":{"total_pips":23.387499999972977,"max_drawdown":113.9349999999979,"bias_sign_flips":521,"r":{"expectancy_r":0.09527242267306019,"n_trades":529,"win_rate":0.3005671077504726,"avg_win_r":2.0866957092558716,"avg_loss_r":-0.7605013680476617,"profit_factor":1.179110545808399,"max_r_drawdown":26.058017560225167,"n_open_at_end":1,"sqn":1.126033935020108,"sqn_normalized":0.4895799717478731,"net_expectancy_r":0.09527242267306019,"conviction_terciles_r":[-0.07002826150651001,0.25569891492505703,0.10011907679313316]}}}} +{"family_id":"844fe329-0-US500-w0-r0-s0-0","report":{"manifest":{"commit":"4474814fa79e227cd2d93e34a6982b49f31ba846","params":[["fast.length",{"I64":4}],["slow.length",{"I64":8}],["bias.scale",{"F64":0.5}],["stop_length",{"I64":3}],["stop_k",{"F64":2.0}]],"defaults":[],"window":[1725148800000000000,1725580800000000000],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=1)","instrument":"US500","topology_hash":"f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240","project":{"commit":"6bb76063046d41062b68fbde79950b9d06fbd41d"}},"metrics":{"total_pips":80.28249999994746,"max_drawdown":87.96499999997366,"bias_sign_flips":780,"r":{"expectancy_r":0.13213069018419635,"n_trades":821,"win_rate":0.3617539585870889,"avg_win_r":1.848016846738723,"avg_loss_r":-0.8404231046568231,"profit_factor":1.2463301607589143,"max_r_drawdown":28.220480388404972,"n_open_at_end":1,"sqn":1.8795915057542347,"sqn_normalized":0.655981958519425,"net_expectancy_r":0.13213069018419635,"conviction_terciles_r":[0.11958074358694365,0.22575289096933593,0.05101263327150186]}}}} +{"family_id":"844fe329-0-US500-w0-r0-s0-0","report":{"manifest":{"commit":"4474814fa79e227cd2d93e34a6982b49f31ba846","params":[["fast.length",{"I64":4}],["slow.length",{"I64":16}],["bias.scale",{"F64":0.5}],["stop_length",{"I64":3}],["stop_k",{"F64":2.0}]],"defaults":[],"window":[1725148800000000000,1725580800000000000],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=1)","instrument":"US500","topology_hash":"f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240","project":{"commit":"6bb76063046d41062b68fbde79950b9d06fbd41d"}},"metrics":{"total_pips":19.558750000014825,"max_drawdown":85.75000000000286,"bias_sign_flips":399,"r":{"expectancy_r":0.11821373408670934,"n_trades":479,"win_rate":0.31315240083507306,"avg_win_r":2.3901102129922043,"avg_loss_r":-0.9176053292440638,"profit_factor":1.1875649234489034,"max_r_drawdown":28.108663585145585,"n_open_at_end":1,"sqn":1.0959164423645071,"sqn_normalized":0.5007370035157714,"net_expectancy_r":0.11821373408670934,"conviction_terciles_r":[0.2576229784937875,0.13377757213522506,-0.035888040591340105]}}}} +{"campaign_run":{"campaign":"844fe3290562346f37c756a74f3d76bab9a3c7257341ec8dafec0025ac2f68db","process":"f14023a1fef5640311163690f1140532412ea5e1d1cbb93e293e63fcf0bf2bf9","run":0,"seed":7,"cells":[{"strategy":"f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240","instrument":"US500","window_ms":[1725148800000,1725580800000],"stages":[{"block":"std::sweep","family_id":"844fe329-0-US500-w0-r0-s0-0","selection":{"winner_ordinal":2,"params":[["bias.scale",{"F64":0.5}],["fast.length",{"I64":4}],["slow.length",{"I64":8}]],"selection":{"selection_metric":"sqn","n_trials":4,"raw_winner_metric":1.8795915057542347,"mode":"Argmax"}}}],"coverage":{"effective_from_ms":1725235200000,"effective_to_ms":1725580800000}}]}} diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_2_validate.txt b/fieldtests/cycle-328-axis-namespace/cycle328_2_validate.txt new file mode 100644 index 0000000..c3e950f --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_2_validate.txt @@ -0,0 +1,3 @@ +campaign document valid (intrinsic): 1 strategy(ies), 3 axes (4 points), 1 instrument(s), 1 window(s), 1 regime(s) (default) — 1 cell(s) +campaign document valid (referential): all references resolve, axes are in the param space +campaign document valid (executable): pipeline shape and static guards pass diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_3a_sweep_synth.out b/fieldtests/cycle-328-axis-namespace/cycle328_3a_sweep_synth.out new file mode 100644 index 0000000..060280a --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_3a_sweep_synth.out @@ -0,0 +1 @@ +aura: axis "graph.fast.length": axis names are raw node.param paths — use "fast.length" (the wrapped --list-axes form was retired, #328) diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_3b_sweep_real.out b/fieldtests/cycle-328-axis-namespace/cycle328_3b_sweep_real.out new file mode 100644 index 0000000..060280a --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_3b_sweep_real.out @@ -0,0 +1 @@ +aura: axis "graph.fast.length": axis names are raw node.param paths — use "fast.length" (the wrapped --list-axes form was retired, #328) diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_3c_walkforward.out b/fieldtests/cycle-328-axis-namespace/cycle328_3c_walkforward.out new file mode 100644 index 0000000..060280a --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_3c_walkforward.out @@ -0,0 +1 @@ +aura: axis "graph.fast.length": axis names are raw node.param paths — use "fast.length" (the wrapped --list-axes form was retired, #328) diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_3d_validate.out b/fieldtests/cycle-328-axis-namespace/cycle328_3d_validate.out new file mode 100644 index 0000000..72da25f --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_3d_validate.out @@ -0,0 +1,4 @@ +campaign document valid (intrinsic): 1 strategy(ies), 1 axes (2 points), 1 instrument(s), 1 window(s), 1 regime(s) (default) — 1 cell(s) +aura: campaign references do not resolve: + strategy f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240: axis "graph.fast.length" is not in the param space; axis names are raw node.param paths — did you mean "fast.length"? + strategy f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240: open param "fast.length" is bound by no campaign axis diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_3d_wrapped_campaign.json b/fieldtests/cycle-328-axis-namespace/cycle328_3d_wrapped_campaign.json new file mode 100644 index 0000000..a26be5c --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_3d_wrapped_campaign.json @@ -0,0 +1,20 @@ +{ + "format_version": 1, + "kind": "campaign", + "name": "cycle328-wrapped-axis-in-doc", + "seed": 7, + "data": { + "instruments": ["US500"], + "windows": [ { "from_ms": 1725148800000, "to_ms": 1725580800000 } ] + }, + "strategies": [ + { + "ref": { "content_id": "f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240" }, + "axes": { + "graph.fast.length": { "kind": "I64", "values": [2, 4] } + } + } + ], + "process": { "ref": { "content_id": "f14023a1fef5640311163690f1140532412ea5e1d1cbb93e293e63fcf0bf2bf9" } }, + "presentation": { "persist_taps": [], "emit": ["family_table"] } +} diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_4_families.txt b/fieldtests/cycle-328-axis-namespace/cycle328_4_families.txt new file mode 100644 index 0000000..91b623e --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_4_families.txt @@ -0,0 +1,2 @@ +{"family_id":"844fe329-0-US500-w0-r0-s0-0","kind":"Sweep","members":4} +{"family_id":"cycle328-sweep-bo-0","kind":"Sweep","members":4} diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_4_members.txt b/fieldtests/cycle-328-axis-namespace/cycle328_4_members.txt new file mode 100644 index 0000000..3811ee2 --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_4_members.txt @@ -0,0 +1,4 @@ +{"manifest":{"commit":"4474814fa79e227cd2d93e34a6982b49f31ba846","params":[["fast.length",{"I64":2}],["slow.length",{"I64":8}],["stop_length",{"I64":3}],["stop_k",{"F64":2.0}]],"defaults":[["bias.scale",{"F64":0.5}]],"window":[1,18],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=0.0001)","topology_hash":"f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240","project":{"commit":"6bb76063046d41062b68fbde79950b9d06fbd41d"}},"metrics":{"total_pips":-0.23484999999997555,"max_drawdown":0.38129999999997777,"bias_sign_flips":2,"r":{"expectancy_r":0.05853072923940165,"n_trades":3,"win_rate":0.3333333333333333,"avg_win_r":1.127161364109783,"avg_loss_r":-0.47578458819578906,"profit_factor":1.18452908319715,"max_r_drawdown":0.2739524763392649,"n_open_at_end":1,"sqn":0.1070277396717771,"sqn_normalized":0.1070277396717771,"net_expectancy_r":0.05853072923940165,"conviction_terciles_r":[-0.2739524763392649,1.127161364109783,-0.6776167000523132]}}} +{"manifest":{"commit":"4474814fa79e227cd2d93e34a6982b49f31ba846","params":[["fast.length",{"I64":2}],["slow.length",{"I64":16}],["stop_length",{"I64":3}],["stop_k",{"F64":2.0}]],"defaults":[["bias.scale",{"F64":0.5}]],"window":[1,18],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=0.0001)","topology_hash":"f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240","project":{"commit":"6bb76063046d41062b68fbde79950b9d06fbd41d"}},"metrics":{"total_pips":0.037062500000010136,"max_drawdown":0.04543749999999568,"bias_sign_flips":0,"r":{"expectancy_r":0.1570020451313814,"n_trades":1,"win_rate":1.0,"avg_win_r":0.1570020451313814,"avg_loss_r":0.0,"profit_factor":0.0,"max_r_drawdown":0.0,"n_open_at_end":1,"sqn":0.0,"sqn_normalized":0.0,"net_expectancy_r":0.1570020451313814,"conviction_terciles_r":[0.0,0.0,0.0]}}} +{"manifest":{"commit":"4474814fa79e227cd2d93e34a6982b49f31ba846","params":[["fast.length",{"I64":4}],["slow.length",{"I64":8}],["stop_length",{"I64":3}],["stop_k",{"F64":2.0}]],"defaults":[["bias.scale",{"F64":0.5}]],"window":[1,18],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=0.0001)","topology_hash":"f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240","project":{"commit":"6bb76063046d41062b68fbde79950b9d06fbd41d"}},"metrics":{"total_pips":-0.5274999999999815,"max_drawdown":0.5609499999999865,"bias_sign_flips":2,"r":{"expectancy_r":-0.6426407768510923,"n_trades":3,"win_rate":0.3333333333333333,"avg_win_r":0.5474739899790243,"avg_loss_r":-1.2376981602661505,"profit_factor":0.22116619687844463,"max_r_drawdown":1.245647494511426,"n_open_at_end":1,"sqn":-1.0799322573025962,"sqn_normalized":-1.0799322573025962,"net_expectancy_r":-0.6426407768510923,"conviction_terciles_r":[-1.2456474945114262,0.5474739899790243,-1.229748826020875]}}} +{"manifest":{"commit":"4474814fa79e227cd2d93e34a6982b49f31ba846","params":[["fast.length",{"I64":4}],["slow.length",{"I64":16}],["stop_length",{"I64":3}],["stop_k",{"F64":2.0}]],"defaults":[["bias.scale",{"F64":0.5}]],"window":[1,18],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=0.0001)","topology_hash":"f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240","project":{"commit":"6bb76063046d41062b68fbde79950b9d06fbd41d"}},"metrics":{"total_pips":0.0076125000000051846,"max_drawdown":0.02868749999999659,"bias_sign_flips":0,"r":{"expectancy_r":0.1570020451313814,"n_trades":1,"win_rate":1.0,"avg_win_r":0.1570020451313814,"avg_loss_r":0.0,"profit_factor":0.0,"max_r_drawdown":0.0,"n_open_at_end":1,"sqn":0.0,"sqn_normalized":0.0,"net_expectancy_r":0.1570020451313814,"conviction_terciles_r":[0.0,0.0,0.0]}}} diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_4_reproduce.out b/fieldtests/cycle-328-axis-namespace/cycle328_4_reproduce.out new file mode 100644 index 0000000..ad96a1d --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_4_reproduce.out @@ -0,0 +1,5 @@ +cycle328-sweep-bo-0 member fast.length=2, slow.length=8, stop_length=3, stop_k=2 reproduced: bit-identical +cycle328-sweep-bo-0 member fast.length=2, slow.length=16, stop_length=3, stop_k=2 reproduced: bit-identical +cycle328-sweep-bo-0 member fast.length=4, slow.length=8, stop_length=3, stop_k=2 reproduced: bit-identical +cycle328-sweep-bo-0 member fast.length=4, slow.length=16, stop_length=3, stop_k=2 reproduced: bit-identical +reproduced 4/4 members bit-identically diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_4_sweep.err b/fieldtests/cycle-328-axis-namespace/cycle328_4_sweep.err new file mode 100644 index 0000000..e69de29 diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_4_sweep.out b/fieldtests/cycle-328-axis-namespace/cycle328_4_sweep.out new file mode 100644 index 0000000..976721f --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_4_sweep.out @@ -0,0 +1,4 @@ +{"family_id":"cycle328-sweep-bo-0","report":{"manifest":{"commit":"4474814fa79e227cd2d93e34a6982b49f31ba846","params":[["fast.length",{"I64":2}],["slow.length",{"I64":8}],["stop_length",{"I64":3}],["stop_k",{"F64":2.0}]],"defaults":[["bias.scale",{"F64":0.5}]],"window":[1,18],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=0.0001)","topology_hash":"f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240","project":{"commit":"6bb76063046d41062b68fbde79950b9d06fbd41d"}},"metrics":{"total_pips":-0.23484999999997555,"max_drawdown":0.38129999999997777,"bias_sign_flips":2,"r":{"expectancy_r":0.05853072923940165,"n_trades":3,"win_rate":0.3333333333333333,"avg_win_r":1.127161364109783,"avg_loss_r":-0.47578458819578906,"profit_factor":1.18452908319715,"max_r_drawdown":0.2739524763392649,"n_open_at_end":1,"sqn":0.1070277396717771,"sqn_normalized":0.1070277396717771,"net_expectancy_r":0.05853072923940165,"conviction_terciles_r":[-0.2739524763392649,1.127161364109783,-0.6776167000523132]}}}} +{"family_id":"cycle328-sweep-bo-0","report":{"manifest":{"commit":"4474814fa79e227cd2d93e34a6982b49f31ba846","params":[["fast.length",{"I64":2}],["slow.length",{"I64":16}],["stop_length",{"I64":3}],["stop_k",{"F64":2.0}]],"defaults":[["bias.scale",{"F64":0.5}]],"window":[1,18],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=0.0001)","topology_hash":"f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240","project":{"commit":"6bb76063046d41062b68fbde79950b9d06fbd41d"}},"metrics":{"total_pips":0.037062500000010136,"max_drawdown":0.04543749999999568,"bias_sign_flips":0,"r":{"expectancy_r":0.1570020451313814,"n_trades":1,"win_rate":1.0,"avg_win_r":0.1570020451313814,"avg_loss_r":0.0,"profit_factor":0.0,"max_r_drawdown":0.0,"n_open_at_end":1,"sqn":0.0,"sqn_normalized":0.0,"net_expectancy_r":0.1570020451313814,"conviction_terciles_r":[0.0,0.0,0.0]}}}} +{"family_id":"cycle328-sweep-bo-0","report":{"manifest":{"commit":"4474814fa79e227cd2d93e34a6982b49f31ba846","params":[["fast.length",{"I64":4}],["slow.length",{"I64":8}],["stop_length",{"I64":3}],["stop_k",{"F64":2.0}]],"defaults":[["bias.scale",{"F64":0.5}]],"window":[1,18],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=0.0001)","topology_hash":"f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240","project":{"commit":"6bb76063046d41062b68fbde79950b9d06fbd41d"}},"metrics":{"total_pips":-0.5274999999999815,"max_drawdown":0.5609499999999865,"bias_sign_flips":2,"r":{"expectancy_r":-0.6426407768510923,"n_trades":3,"win_rate":0.3333333333333333,"avg_win_r":0.5474739899790243,"avg_loss_r":-1.2376981602661505,"profit_factor":0.22116619687844463,"max_r_drawdown":1.245647494511426,"n_open_at_end":1,"sqn":-1.0799322573025962,"sqn_normalized":-1.0799322573025962,"net_expectancy_r":-0.6426407768510923,"conviction_terciles_r":[-1.2456474945114262,0.5474739899790243,-1.229748826020875]}}}} +{"family_id":"cycle328-sweep-bo-0","report":{"manifest":{"commit":"4474814fa79e227cd2d93e34a6982b49f31ba846","params":[["fast.length",{"I64":4}],["slow.length",{"I64":16}],["stop_length",{"I64":3}],["stop_k",{"F64":2.0}]],"defaults":[["bias.scale",{"F64":0.5}]],"window":[1,18],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=0.0001)","topology_hash":"f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240","project":{"commit":"6bb76063046d41062b68fbde79950b9d06fbd41d"}},"metrics":{"total_pips":0.0076125000000051846,"max_drawdown":0.02868749999999659,"bias_sign_flips":0,"r":{"expectancy_r":0.1570020451313814,"n_trades":1,"win_rate":1.0,"avg_win_r":0.1570020451313814,"avg_loss_r":0.0,"profit_factor":0.0,"max_r_drawdown":0.0,"n_open_at_end":1,"sqn":0.0,"sqn_normalized":0.0,"net_expectancy_r":0.1570020451313814,"conviction_terciles_r":[0.0,0.0,0.0]}}}} diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_5a_typo.out b/fieldtests/cycle-328-axis-namespace/cycle328_5a_typo.out new file mode 100644 index 0000000..8db750e --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_5a_typo.out @@ -0,0 +1 @@ +aura: axis fastt.length: names no param of this blueprint (open or bound) — see `aura sweep --list-axes` diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_5b_wrapped_nohit.out b/fieldtests/cycle-328-axis-namespace/cycle328_5b_wrapped_nohit.out new file mode 100644 index 0000000..7c20461 --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_5b_wrapped_nohit.out @@ -0,0 +1 @@ +aura: axis graph.fast.bogus: names no param of this blueprint (open or bound) — see `aura sweep --list-axes` diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_5c_deep_wrapped.out b/fieldtests/cycle-328-axis-namespace/cycle328_5c_deep_wrapped.out new file mode 100644 index 0000000..66d7bb6 --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_5c_deep_wrapped.out @@ -0,0 +1 @@ +aura: axis project.graph.fast.length: names no param of this blueprint (open or bound) — see `aura sweep --list-axes` diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_6a_sweep_real.err b/fieldtests/cycle-328-axis-namespace/cycle328_6a_sweep_real.err new file mode 100644 index 0000000..e69de29 diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_6a_sweep_real.out b/fieldtests/cycle-328-axis-namespace/cycle328_6a_sweep_real.out new file mode 100644 index 0000000..6146929 --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_6a_sweep_real.out @@ -0,0 +1,2 @@ +{"family_id":"1102542f-0-US500-w0-r0-s0-0","report":{"manifest":{"commit":"4474814fa79e227cd2d93e34a6982b49f31ba846","params":[["fast.length",{"I64":2}],["slow.length",{"I64":8}],["stop_length",{"I64":3}],["stop_k",{"F64":2.0}]],"defaults":[["bias.scale",{"F64":0.5}]],"window":[1725235200000000000,1725580800000000000],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=1)","instrument":"US500","topology_hash":"f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240","project":{"commit":"6bb76063046d41062b68fbde79950b9d06fbd41d"}},"metrics":{"total_pips":46.422499999968466,"max_drawdown":125.89999999998915,"bias_sign_flips":861,"r":{"expectancy_r":0.052960279961470944,"n_trades":846,"win_rate":0.31796690307328607,"avg_win_r":1.8016249253621428,"avg_loss_r":-0.7622750573223781,"profit_factor":1.1018669053593053,"max_r_drawdown":29.11884107504975,"n_open_at_end":1,"sqn":0.8388429079176243,"sqn_normalized":0.2884001324999155,"net_expectancy_r":0.052960279961470944,"conviction_terciles_r":[-0.05618014716431794,0.13546662237309962,0.07959436467563116]}}}} +{"family_id":"1102542f-0-US500-w0-r0-s0-0","report":{"manifest":{"commit":"4474814fa79e227cd2d93e34a6982b49f31ba846","params":[["fast.length",{"I64":4}],["slow.length",{"I64":8}],["stop_length",{"I64":3}],["stop_k",{"F64":2.0}]],"defaults":[["bias.scale",{"F64":0.5}]],"window":[1725235200000000000,1725580800000000000],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=1)","instrument":"US500","topology_hash":"f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240","project":{"commit":"6bb76063046d41062b68fbde79950b9d06fbd41d"}},"metrics":{"total_pips":80.28249999994746,"max_drawdown":87.96499999997366,"bias_sign_flips":780,"r":{"expectancy_r":0.13213069018419635,"n_trades":821,"win_rate":0.3617539585870889,"avg_win_r":1.848016846738723,"avg_loss_r":-0.8404231046568231,"profit_factor":1.2463301607589143,"max_r_drawdown":28.220480388404972,"n_open_at_end":1,"sqn":1.8795915057542347,"sqn_normalized":0.655981958519425,"net_expectancy_r":0.13213069018419635,"conviction_terciles_r":[0.11958074358694365,0.22575289096933593,0.05101263327150186]}}}} diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_6b_walkforward.err b/fieldtests/cycle-328-axis-namespace/cycle328_6b_walkforward.err new file mode 100644 index 0000000..e69de29 diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_6b_walkforward.out b/fieldtests/cycle-328-axis-namespace/cycle328_6b_walkforward.out new file mode 100644 index 0000000..b864313 --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_6b_walkforward.out @@ -0,0 +1,2 @@ +{"family_id":"3fbe4493-0-US500-w0-r0-s1-0","report":{"manifest":{"commit":"4474814fa79e227cd2d93e34a6982b49f31ba846","params":[["fast.length",{"I64":4}],["slow.length",{"I64":8}],["stop_length",{"I64":3}],["stop_k",{"F64":2.0}]],"defaults":[["bias.scale",{"F64":0.5}]],"window":[1730986785000000000,1732903979999000000],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=1)","selection":{"selection_metric":"sqn_normalized","n_trials":2,"raw_winner_metric":-0.047813708639866226,"mode":"Argmax","deflated_score":-0.2491637240312123,"overfit_probability":0.9090909090909091,"n_resamples":1000,"block_len":5,"seed":0},"instrument":"US500","topology_hash":"f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240","project":{"commit":"6bb76063046d41062b68fbde79950b9d06fbd41d"}},"metrics":{"total_pips":86.88750000012675,"max_drawdown":212.54749999991324,"bias_sign_flips":3244,"r":{"expectancy_r":0.030790024810340468,"n_trades":3446,"win_rate":0.3444573418456181,"avg_win_r":1.6171611559204189,"avg_loss_r":-0.8027746200004905,"profit_factor":1.0585080262251694,"max_r_drawdown":132.69624561269114,"n_open_at_end":1,"sqn":0.9012552216989966,"sqn_normalized":0.15352890674784425,"net_expectancy_r":0.030790024810340468,"conviction_terciles_r":[0.03406326248492066,0.038379965173779666,0.019929695543143295]}}}} +{"walkforward":{"oos_r":{"avg_loss_r":-0.8027746200004905,"avg_win_r":1.6171611559204189,"conviction_terciles_r":[0.0,0.0,0.0],"expectancy_r":0.030790024810340468,"max_r_drawdown":132.69624561269114,"n_open_at_end":0,"n_trades":3446,"net_expectancy_r":0.030790024810340468,"profit_factor":1.0585080262251694,"sqn":0.9012552216989966,"sqn_normalized":0.15352890674784425,"win_rate":0.3444573418456181},"param_stability":[{"mean":4.0,"p25":4.0,"p5":4.0,"p50":4.0,"p75":4.0,"p95":4.0},{"mean":8.0,"p25":8.0,"p5":8.0,"p50":8.0,"p75":8.0,"p95":8.0},{"mean":3.0,"p25":3.0,"p5":3.0,"p50":3.0,"p75":3.0,"p95":3.0},{"mean":2.0,"p25":2.0,"p5":2.0,"p50":2.0,"p75":2.0,"p95":2.0}],"stitched_total_pips":86.88750000012675,"windows":1}} diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_crossover.bp.json b/fieldtests/cycle-328-axis-namespace/cycle328_crossover.bp.json new file mode 100644 index 0000000..8ab92d8 --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_crossover.bp.json @@ -0,0 +1 @@ +{"format_version":1,"blueprint":{"name":"graph","doc":"SMA crossover bias: fast minus slow moving average, scaled to a bounded directional bias","nodes":[{"primitive":{"type":"SMA","name":"fast"}},{"primitive":{"type":"SMA","name":"slow","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":6}}]}},{"primitive":{"type":"Sub","name":"sub"}},{"primitive":{"type":"Bias","name":"bias","bound":[{"pos":0,"name":"scale","kind":"F64","value":{"F64":0.5}}]}}],"edges":[{"from":0,"to":2,"slot":0,"from_field":0},{"from":1,"to":2,"slot":1,"from_field":0},{"from":2,"to":3,"slot":0,"from_field":0}],"input_roles":[{"name":"price","targets":[{"node":0,"slot":0},{"node":1,"slot":0}],"source":"F64"}],"output":[{"node":3,"field":0,"name":"bias"}]}} \ No newline at end of file diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_crossover.build.err b/fieldtests/cycle-328-axis-namespace/cycle328_crossover.build.err new file mode 100644 index 0000000..e69de29 diff --git a/fieldtests/cycle-328-axis-namespace/cycle328_crossover.ops.json b/fieldtests/cycle-328-axis-namespace/cycle328_crossover.ops.json new file mode 100644 index 0000000..192e081 --- /dev/null +++ b/fieldtests/cycle-328-axis-namespace/cycle328_crossover.ops.json @@ -0,0 +1,13 @@ +[ + {"op":"doc","text":"SMA crossover bias: fast minus slow moving average, scaled to a bounded directional bias"}, + {"op":"source","role":"price","kind":"F64"}, + {"op":"add","type":"SMA","name":"fast"}, + {"op":"add","type":"SMA","name":"slow","bind":{"length":{"I64":6}}}, + {"op":"add","type":"Sub","name":"sub"}, + {"op":"add","type":"Bias","name":"bias","bind":{"scale":{"F64":0.5}}}, + {"op":"feed","role":"price","into":["fast.series","slow.series"]}, + {"op":"connect","from":"fast.value","to":"sub.lhs"}, + {"op":"connect","from":"slow.value","to":"sub.rhs"}, + {"op":"connect","from":"sub.value","to":"bias.signal"}, + {"op":"expose","from":"bias.bias","as":"bias"} +]