Skip to content

fix(ta): exact-order window summation for short SMAs + corpus warmup-origin reconfigs (309 excellent) - #156

Merged
luisleo526 merged 2 commits into
mainfrom
fix/sma-exact-order-ship
Aug 13, 2026
Merged

fix(ta): exact-order window summation for short SMAs + corpus warmup-origin reconfigs (309 excellent)#156
luisleo526 merged 2 commits into
mainfrom
fix/sma-exact-order-ship

Conversation

@luisleo526

Copy link
Copy Markdown
Collaborator

Gate

pr-gate PASS — engine corpus zero regressions, scraped entering excellent+strong >= leaving.

Verdict: /Users/haoliangwen/code/pineforge-lab/pr-gate-verdict.json

🤖 Generated with Claude Code

luisleo526 and others added 2 commits August 14, 2026 05:15
Pine defines ta.sma(src, length) as the mean of the last `length` values,
which makes it a pure function of its window. The incremental running sum
(`running_sum += src - popped`) broke that: the emitted value became a
function of every value ever accumulated, and the periodic exact re-summation
at (bar_count & 255) == 0 only re-PHASED that drift rather than removing it.

The failure is observable at the signal layer through the stochRSI shape
k = ta.sma(stoch, 3); d = ta.sma(k, 3). On a saturating source the three
k-windows feeding d are rotations of one multiset, so the s_{t-2} term
cancels identically and

    9 * (k_t - d_t) = 2*s_t + s_{t-1} - 2*s_{t-3} - s_{t-4}

is EXACTLY ZERO whenever s_t == s_{t-3} and s_{t-1} == s_{t-4}. stochRSI hits
that constantly because stoch saturates at exactly 100.0 / 0.0 (x/x -> 1.0,
*100 exact in IEEE-754) every time rsi is its own 14-window extremum.
ta.crossover / ta.crossunder are strict inequalities, so no correct
implementation at any precision may fire at such a bar. Running-sum drift
broke those ties at +-1 ULP and manufactured crossings the mathematics
forbids, with a sign set by the resync phase rather than by the data.

Windows of length <= 16 now re-sum the buffer every bar: exact-order
deterministic, history-independent, and bounded at 16 additions per bar.
Longer windows keep the amortised incremental path, where the chained-tie
geometry does not arise. recompute() follows the same rule so a recomputed
bar and a freshly computed one with an identical window agree bit-for-bit.

Corpus (312 strategies): 3 tapes move, 0 regress.
  composite-kkb-margin-100-pct-01  unmatched 1  -> 0
  ta-stochastic-rsi-cross-01       matched 1292 -> 1305 (96.6% -> 97.6%)
  ta-triple-sma-stack-latch-01     metrics unchanged (100% both)
Tier distribution unchanged: excellent=307 strong=4 anomaly=1.

tests/test_ta_sma_exact_order.cpp pins the invariant (red before, green
after): equal windows -> bitwise equal output, and chained SMA(3) rotation
ties stay exactly tied so no cross can fire.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…run (309 excellent / 2 strong / 1 anomaly)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@luisleo526
luisleo526 merged commit cc6cf46 into main Aug 13, 2026
7 checks passed
@luisleo526
luisleo526 deleted the fix/sma-exact-order-ship branch August 13, 2026 21:46
luisleo526 added a commit that referenced this pull request Aug 13, 2026
…reconfigs + exact-order SMA) (#157)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant