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}