code wiki / (root) / nx_fin_paper.nx

nx_fin_paper.nx source

↩ module page · 38 lines · 2134 B

1// nx_fin_paper.nx -- R5: PAPER / forward simulation = the OVERFIT CHECK before any capital. Splits the bar 2// history into in-sample (train) vs OUT-OF-SAMPLE (test), replays the strategy signals through the R2 engine on 3// the OOS slice ONLY, and asks the honest question: does the edge SURVIVE on data it never saw? An edge that 4// only works in-sample is overfit -- this is the gate before R6 live. Composes R1 (MD_FIELDS) + R2 (bt_run). 5// license_tier: ORIGINAL 6import "nx_syscalls.nx" 7import "nx_fin_marketdata.nx" 8import "nx_fin_backtest.nx" 9const K_MAGIC_10000: i64 = 10000 10 11// split index for an in-sample fraction (bps). bars[0..idx) = in-sample, bars[idx..n) = out-of-sample. 12func pp_split(nbars: i64, is_frac_bps: i64) -> i64 { return nbars * is_frac_bps / K_MAGIC_10000 } 13 14// run the R2 backtester on the OUT-OF-SAMPLE slice [split_idx..nbars) only. Fills out[] with OOS metrics; 15// returns n_trades. Copies the slice into scratch so bt_run (which starts at index 0) sees only OOS data. 16func pp_oos_run(bars: *i64, nbars: i64, signals: *i64, split_idx: i64, start_equity: i64, 17 slippage_bps: i64, commission_cents: i64, adv_cents: i64, participation_bps: i64, out: *i64) -> i64 { 18 let m: i64 = nbars - split_idx 19 if m <= 0 { return 0 } 20 let obars: *i64 = sys_mmap(8 * MD_FIELDS * m) as *i64 21 let osig: *i64 = sys_mmap(8 * m) as *i64 22 var i: i64 = 0 23 while i < m { 24 var j: i64 = 0 25 while j < MD_FIELDS { obars[i*MD_FIELDS+j] = bars[(split_idx+i)*MD_FIELDS+j]; j = j + 1 } 26 osig[i] = signals[split_idx + i] 27 i = i + 1 28 } 29 return bt_run(obars, m, osig, start_equity, slippage_bps, commission_cents, adv_cents, participation_bps, out) 30} 31 32// did the edge SURVIVE out-of-sample? 1 iff OOS expectancy is still positive AND retains at least 33// min_retain_bps of the in-sample expectancy (guards against a decayed / overfit edge). 34func pp_edge_survives(is_expectancy: i64, oos_expectancy: i64, min_retain_bps: i64) -> i64 { 35 if oos_expectancy <= 0 { return 0 } 36 if oos_expectancy < is_expectancy * min_retain_bps / K_MAGIC_10000 { return 0 } 37 return 1 38}