Commit graph Warrior_EA/research/test_exits.py
Author SHA1 Message Date
AnimateDread
bd076ddbad research: test the shipped classic patterns for entry edge - and the lookahead that faked one
Transcribes all 26 classic vote models (MA 4, RSI 4, MACD 6, Ichimoku 12) from
Signals/*.mqh into vectorised Python, with their shipped constructor weights, then tests
them as entry triggers on 178k-bar FX histories.

Pre-registered by construction: the rules were written long before this test and nothing
about them is fitted here, so there is no in-sample/out-of-sample split to draw and the
whole history is usable. Break-even == chance by the gambler's-ruin identity, so "beats a
coin" and "makes money" are one question. Sequential non-overlapping trades only; a
sign-flip null over the whole pattern family gives the family-wise bar.

The result that matters is a negative one, and it took two lookahead fixes to see:

  - _price_extremum reproduced the standard library's CENTRED MinValue(pos-2,5) window,
    which reads up to 2 bars newer than the extremum it describes.
  - turning_points marked a turn AT bar i, which is only knowable once bar i+1 closes.

Together those two bars of leakage WERE the entire apparent edge. MACD_p4 on EURUSD 1:2
read +5.05pp at +4.05 sigma before, -0.02pp at -0.02 sigma after; USDJPY 1:2 went +5.24pp
-> +0.02pp. RSI_p2's large NEGATIVE went the same way (-10.33pp -> -1.34pp), which is the
tell: a leak inflates whatever sign it lands on.

With both closed, across 4 instruments x 3 geometries: no pattern, no vote threshold, no
quorum and no event+confirmation rule separates from chance. One cell in ~180 tests stars
(SP500 2:6 vote>=30) and it is non-monotone in the threshold either side of the hit.

test_exits.py answers the trade-management half with the control that makes it mean
something: hold entries fixed, vary only the exit, and run every rule again on RANDOM
entries at the same bars. Breakeven-at-1R, chandelier trails, partials and time stops all
move E[R] - and move it by the same amount on random entries. No rule beats its own
control (max +0.99 sigma over 32 comparisons). Management reshapes the win-rate/payoff
split; it does not manufacture expectancy from a directionless entry.

Residual E[R] across every cell is -0.01 to -0.08 R, which is approximately the spread.

Incidental, both worth fixing in the EA:
  - CSignalMA pattern 1 is unsatisfiable at the shipped EMA default. For an EMA,
    MA[i]-MA[i-1] and c[i]-MA[i] are both positive multiples of (c[i]-MA[i-1]), so
    "close below the MA while the MA rises" cannot occur. Dead code (weight 10).
  - Ichimoku pattern 11 (Sanyaku, weight 100, the method's top signal) fires on 27% of
    bars because it is a conjunction of three standing STATES with no event term, so it
    dominates the averaged vote while carrying no trigger information.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 16:58:57 -04:00