2026-09-11 06:16:08 -04:00 | | | //+------------------------------------------------------------------+
|
| | | //| WarriorEnums.mqh |
|
| | | //| AnimateDread |
|
| | | //| |
|
| | | //| EVERY INPUT THIS EA TAKES IS AN ENUM, and each enum's VALUE IS |
|
| | | //| ITS PAYLOAD. SL_ATR_x2 is literally 2, RISK_PCT_3 is literally 3, |
|
| | | //| so a consumer writes `m_atr * SL_Mode` with no lookup table and |
|
| | | //| no switch that can fall out of step with the list. The MT5 |
|
| | | //| optimizer steps over members, so a sweep can only ever produce a |
|
| | | //| legal configuration - which is the real reason for the dropdowns. |
|
| | | //| |
|
| | | //| ORDINALS ARE PINNED AND NEVER REUSED. MT5 stores an input's VALUE |
|
| | | //| in the .set file and in each chart's .chr, and does not validate |
|
| | | //| it against the current enum. Renumbering a member therefore |
|
| | | //| silently re-points every saved configuration at a different |
|
| | | //| setting. Gaps in the sequence are deliberate headstones for |
|
| | | //| members that were removed; leave them. |
|
| | | //+------------------------------------------------------------------+
|
| | | #ifndef WARRIOR_SIMPLE_ENUMS_MQH
|
| | | #define WARRIOR_SIMPLE_ENUMS_MQH
|
| | |
|
| | | //--- Which way this chart is allowed to trade. LONG_ONLY exists because an index is not symmetric;
|
| | | //--- it is a legitimate setting, not a crutch. Value 1 was the default a stale tester preset once
|
| | | //--- supplied to every run, turning a two-sided EA long-only for days, so read the init echo.
|
| | | enum WARRIOR_DIRECTION
|
| | | {
|
| | | DIR_BOTH = 0, // Both directions
|
| | | DIR_LONG = 1, // Long only
|
| | | DIR_SHORT = 2, // Short only
|
| | | };
|
| | |
|
| | | //--- Position sizing. 1 is deliberately vacant: it was INTELLIGENT, which staked real money on an
|
| | | //--- uncalibrated confidence number (and in an earlier form increased size after a losing streak).
|
| | | //--- It is not coming back, and the hole stops a saved "1" from selecting something else.
|
| | | enum WARRIOR_MONEY_MODE
|
| | | {
|
| | | MONEY_FIXED_RISK = 0, // Risk a fixed % of balance
|
| | | MONEY_FIXED_LOT = 2, // Fixed lot size
|
| | | };
|
| | |
|
| | | //--- Risk per trade, as a whole percent of balance. The value IS the percent.
|
| | | enum WARRIOR_RISK_PCT
|
| | | {
|
| | | RISK_1 = 1, // 1%
|
| | | RISK_2 = 2, // 2%
|
| | | RISK_3 = 3, // 3%
|
| | | RISK_5 = 5, // 5%
|
| | | };
|
| | |
|
| | | //--- The stop, in ATR from entry. The value IS the multiple.
|
| | | enum WARRIOR_SL_MODE
|
| | | {
|
| | | SL_ATR_x1 = 1, // ATR x 1
|
| | | SL_ATR_x2 = 2, // ATR x 2
|
| | | SL_ATR_x3 = 3, // ATR x 3
|
| | | SL_ATR_x4 = 4, // ATR x 4
|
| | | };
|
| | |
|
| | | //--- The target, in ATR from entry. 0 = none, run it on the trail alone.
|
| | | enum WARRIOR_TP_MODE
|
| | | {
|
| | | TP_NONE = 0, // No target (trail only)
|
| | | TP_ATR_x1 = 1, // ATR x 1
|
| | | TP_ATR_x2 = 2, // ATR x 2
|
| | | TP_ATR_x3 = 3, // ATR x 3
|
| | | TP_ATR_x4 = 4, // ATR x 4
|
| | | TP_ATR_x6 = 6, // ATR x 6
|
| | | TP_ATR_x8 = 8, // ATR x 8
|
| | | TP_ATR_x10 = 10, // ATR x 10
|
| | | };
|
| | |
|
| | | //--- The trailing stop, in ATR behind price. The value IS the multiple; 0 disables it.
|
| | | enum WARRIOR_TRAIL_MODE
|
| | | {
|
| | | TRAIL_NONE = 0, // No trailing stop
|
| | | TRAIL_ATR_x1 = 1, // Trail at ATR x 1
|
| | | TRAIL_ATR_x2 = 2, // Trail at ATR x 2
|
| | | TRAIL_ATR_x3 = 3, // Trail at ATR x 3
|
| | | };
|
| | |
|
| | | //--- THE VOTE THRESHOLD, as a percent of the ensemble's weight.
|
| | | //---
|
| | | //--- ⚠ WHAT THIS MEANS DEPENDS ON THE ROSTER, and that is the single easiest way to misread this EA.
|
| | | //--- CExpertSignal::Direction() divides the weighted sum by the NUMBER OF FILTERS THAT ANSWERED, so
|
| | | //--- one unopposed voter at full weight scores 100/N. With 19 filters registered that is 5.3%, and a
|
| | | //--- threshold of 15% therefore demands three agreeing voters, not one. Change the roster and every
|
| | | //--- rung on this list means something different. The EA prints the resolved ladder at init for
|
| | | //--- exactly this reason - read that, not this comment.
|
| | | //---
|
| | | //--- The sub-5% rungs exist because a large roster pushes the whole useful range down there.
|
| | | enum WARRIOR_THRESHOLD
|
| | | {
|
| | | THR_1 = 1, // 1%
|
| | | THR_2 = 2, // 2%
|
| | | THR_3 = 3, // 3%
|
| | | THR_4 = 4, // 4%
|
| | | THR_5 = 5, // 5%
|
| | | THR_10 = 10, // 10%
|
| | | THR_15 = 15, // 15%
|
| | | THR_20 = 20, // 20%
|
| | | THR_25 = 25, // 25%
|
| | | THR_30 = 30, // 30%
|
| | | THR_40 = 40, // 40%
|
| | | THR_50 = 50, // 50%
|
| | | };
|
| | |
|
2026-09-13 14:32:40 -04:00 | | | //--- THE PROBABILITY CUT for anything that outputs a calibrated probability - the neural module.
|
| | | //--- Stored as integer percent, read as value/100.0.
|
| | | //---
|
| | | //--- 50 IS "NO CUT" AND IS THE RIGHT DEFAULT until a trained model's calibration has been measured
|
| | | //--- on the instrument it will trade. A threshold chosen before a calibration curve exists is a
|
| | | //--- guess wearing a setting's clothes, and it will look like a decision in the .set file forever.
|
| | | //---
|
| | | //--- ⚠ FOR THE FRACTAL NET, EXPECT THE USEFUL CUT TO BE LOW, and to act as a floor rather than a
|
| | | //--- trigger: measured mean R by predicted-probability quintile was -0.230 / -0.089 / -0.026 /
|
| | | //--- +0.002 / +0.017 across 20 series. Nearly all of the separation is in refusing the bottom, not
|
| | | //--- in selecting the top - so raising this hunting for a "high conviction" band is chasing a part
|
| | | //--- of the curve that was measured flat.
|
| | | enum WARRIOR_CONFIDENCE
|
| | | {
|
| | | CONF_50 = 50, // 0.50 - no cut
|
| | | CONF_55 = 55, // 0.55
|
| | | CONF_60 = 60, // 0.60
|
| | | CONF_65 = 65, // 0.65
|
| | | CONF_70 = 70, // 0.70
|
| | | CONF_75 = 75, // 0.75
|
| | | CONF_80 = 80, // 0.80
|
| | | CONF_90 = 90, // 0.90
|
| | | };
|
| | | //--- A MODULE'S WEIGHT IN THE VOTE, as a percent. The value IS the percent, so WEIGHT_100 is 1.0.
|
| | | //---
|
| | | //--- These are SWEPT BY THE OPTIMISER, alongside the threshold and the ATR multiples, and that is
|
| | | //--- the deliberate division of labour with the database: the journal sets the 49 PATTERN weights
|
| | | //--- from measured expectancy (far too many to optimise), the optimiser sets the 12 MODULE weights
|
| | | //--- (few enough to be tractable, and coarse enough that a genetic pass can explore them).
|
| | | //---
|
| | | //--- WEIGHT_0 IS THE USEFUL ONE. A module at zero is switched off without being deleted, so the
|
| | | //--- optimiser can discover that an indicator contributes nothing - which is the question this EA
|
| | | //--- has never been able to ask, because every module has always voted at weight 1.0 by default.
|
| | | enum WARRIOR_WEIGHT
|
| | | {
|
| | | WEIGHT_0 = 0, // 0.0 - silent
|
| | | WEIGHT_25 = 25, // 0.25
|
| | | WEIGHT_50 = 50, // 0.50
|
| | | WEIGHT_75 = 75, // 0.75
|
| | | WEIGHT_100 = 100, // 1.00 - the default
|
| | | WEIGHT_150 = 150, // 1.50
|
| | | WEIGHT_200 = 200, // 2.00
|
| | | };
|
| | | //--- MOVE THE STOP TO ENTRY once the trade is this many TENTHS of R in front. The value IS the
|
| | | //--- tenths, so BE_AT_0R5 is 5 and the consumer divides by 10.
|
| | | //---
|
| | | //--- ⚠ THIS IS NOT A TRAILING STOP AND MUST NOT BE CONFUSED WITH ONE. Measured 2026-09-11: every
|
| | | //--- ATR-trail setting made results WORSE (+150.67 -> +90.56 at 1 ATR, worse as it widened),
|
| | | //--- because a trail keeps moving and exits the winner on its first pullback. Breakeven moves
|
| | | //--- ONCE and then stands still, so it scratches the loser without capping the winner. On 5,491
|
| | | //--- traded-side firings the counterfactual was mean R -0.132 -> +0.216 at +0.5R.
|
| | | enum WARRIOR_BREAKEVEN
|
| | | {
|
| | | BE_OFF = 0, // Never move the stop to entry
|
| | | BE_AT_0R5 = 5, // +0.5 R
|
| | | BE_AT_0R7 = 7, // +0.7 R
|
| | | BE_AT_1R0 = 10, // +1.0 R
|
| | | BE_AT_1R5 = 15, // +1.5 R
|
| | | };
|
| | | //--- MANAGEMENT MODEL CUT. At +0.5R the model is asked "does this continue?"; below this
|
| | | //--- probability the trade is closed at the crossing instead of being left to the stop. The value
|
| | | //--- IS the percent. MGMT_OFF disables both the model and its training walk.
|
| | | //---
|
| | | //--- ⚠ 46% of crossings continue and 54% retrace, so a cut of 50 acts on almost every trade while
|
| | | //--- a cut of 30 acts only where the model is confident. Which is right depends on the model's
|
| | | //--- calibration, which is why this is an input and not a constant - and why the net prints its
|
| | | //--- held-out AUC: a cut applied to a coin-flip model is just a random early exit.
|
| | | enum WARRIOR_MGMT_CUT
|
| | | {
|
| | | MGMT_OFF = 0, // No management model
|
| | | MGMT_CUT30 = 30, // exit when P(continue) < 0.30
|
| | | MGMT_CUT40 = 40, // < 0.40
|
| | | MGMT_CUT50 = 50, // < 0.50
|
| | | MGMT_CUT60 = 60, // < 0.60
|
| | | };
|
| | | //--- FADE THE CROWD. When at least this many filters vote the SAME way, take the OTHER side; when
|
| | | //--- fewer do, stand aside entirely. The value IS the voter count.
|
| | | //---
|
| | | //--- WHY THIS EXISTS. Measured on 32,409 traded bar-sides (4 majors, H4, 2015-2026) the ensemble's
|
| | | //--- conviction is monotonically ANTI-predictive: agree=12 -0.27R, agree=13 -0.61R, in both halves,
|
| | | //--- on every symbol. Priced exactly from the journal as a symmetric-1R fade (wins iff the traded
|
| | | //--- side touched -1R before +1R, read from mfeR, ties scored AGAINST the fade): agree>=12 gives
|
| | | //--- +0.294R in-sample and +0.323R out of sample, every symbol, every t >= 3.5. The mechanism is
|
| | | //--- plain: these are lagging indicators, the vote fires after the move, and when ALL of them agree
|
| | | //--- the move is mature. Unanimity is exhaustion.
|
| | | //--- USE WITH StopMode == TargetMode (1R/1R). The measurement was symmetric; an asymmetric fade is
|
| | | //--- a different trade that has not been priced.
|
| | | enum WARRIOR_FADE
|
| | | {
|
| | | FADE_OFF = 0, // Normal voting
|
| | | FADE_AGREE_11 = 11, // Fade when >= 11 filters agree (+0.15R measured)
|
| | | FADE_AGREE_12 = 12, // Fade when >= 12 agree (+0.29R measured)
|
| | | FADE_AGREE_13 = 13, // Fade only unanimity (+0.6R measured, rare)
|
| | | };
|
| | | //--- THE DIP-BUY'S TWO MEASURED FORMS (Signals\SignalDipBuy.mqh has the numbers): the daily RSI(2)
|
| | | //--- Connors form, and the z-score form that the seven-style scan found to be the deepest and the
|
| | | //--- only one with H4 cadence (~15 trades a month on SP500).
|
| | | enum WARRIOR_DIP_ENTRY
|
| | | {
|
| | | DIP_RSI2 = 0, // RSI(2) at or below RsiEntry (the daily Connors form)
|
| | | DIP_ZSCORE = 1, // close below the 20-bar mean by DipZ standard deviations
|
| | | };
|
2026-09-11 06:16:08 -04:00 | | | #endif // WARRIOR_SIMPLE_ENUMS_MQH
|