derivado de animatedread/Warrior_EA
Five modes went, all of them staking real risk on the model's confidence: Intelligent entry (ENTRY_INTELLIGENT), stop (SL_INTELLIGENT), target (TP_INTELLIGENT), trailing (CTrailingIntelligent) and lot size (CMoneyIntelligent's quarter-Kelly). With them, the Confidence_Source input and the CONFIDENCE_SOURCE enum, whose only job was choosing which number those five read. The reason is calibration, not correctness: the confidence magnitude is known to be miscalibrated against the label prior, so every one of these modes multiplied money by a quantity whose units were never established. The DB arm had a second, independent defect - since the tester DB guard (SignalDatabaseActive) it reads 0 in tester and optimizer but non-zero live, so any backtest of CONF_DB/CONF_BLENDED could not reproduce live trading. And what the DB produces is a filter-RANKING win rate, not a per-trade win probability. Both confidence numbers are still recorded per trade (aiConfidence / dbConfidence) and still bucketed against outcome in TradeJournalReport. Recording is what keeps the question answerable; acting on it was the part with no evidence behind it. ConfidenceBridge.mqh now carries an explicit telemetry-only rule at the top. ENUM ORDINALS PINNED. Removing a member vacated a value in four enums at once and MT5 does not validate an enum input replayed from a saved .set or a stored optimization pass. TRAILING_STRATEGY and MONEY_MANAGEMENT_STRATEGY now carry explicit values so the survivors keep the numbers they were saved as, and ValidateBarrierInputs is widened into ValidateTradeManagementInputs covering SL_Mode, TP_Mode, Entry_Multiplier, TrailingStrategy and MM_STRATEGY. Without that gate a chart saved with the Intelligent stop would feed SL_Mode = -1 into a multiplier now used verbatim, placing the stop on the wrong side of entry. RETRAIN-NEUTRAL: neither SL_Mode nor TP_Mode appears in BuildModelFingerprint() or ComputeDbConfigFingerprint() since the swing-pivot target replaced the barrier labels. No .nnw, .cfg or .db re-keys. Also drops the now-dead g_TradeRewardRiskRatio bridge, the CMoneyRiskBase::AdjustRiskAmount hook and the unsigned AIConfidence(). Compile-verified in _claude_stage: 0 errors, 0 warnings. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
76 linhas
5 KiB
MQL5
76 linhas
5 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Warrior_EA |
|
|
//| AnimateDread |
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
//--- TELEMETRY ONLY SINCE 2026-08-25 - NOTHING HERE MAY STEER A TRADE.
|
|
//---
|
|
//--- These globals used to be a control path: OpenParams() refreshed them, and the five "Intelligent"
|
|
//--- trade-management modes (entry / SL / TP / trailing / lot size) read them back to size real risk.
|
|
//--- All five are gone, and the reason is worth keeping next to the numbers themselves: the model's
|
|
//--- confidence is KNOWN TO BE MISCALIBRATED (it over-calls by roughly an order of magnitude against
|
|
//--- the label prior), so every one of those modes was scaling money by a quantity whose units were
|
|
//--- never established. Uncalibrated is not the same as uninformative - it may well rank trades
|
|
//--- correctly even while its absolute level is meaningless - which is exactly why the numbers are
|
|
//--- still RECORDED here and journalled per trade (aiConfidence / dbConfidence in
|
|
//--- Database\TradeJournalManager.mqh, bucketed against realised outcome in TradeJournalReport.mqh).
|
|
//--- That report is the evidence a future confidence-scaled mode would have to produce first.
|
|
//---
|
|
//--- THE RULE: a write to any global in this file must be observable only in the journal, the panel,
|
|
//--- or a log line. If a new reader would change an order's price, size, stop or lifetime, it does
|
|
//--- not belong here - it belongs behind a measurement.
|
|
double g_AISignedConfidence = 0.0; // -1..1, sign = direction, magnitude = AI confidence; 0 if no AI filter
|
|
double g_DBConfidence = 0.0; // 0..1, historical time-based win rate of the active pattern set
|
|
// Live per-tick signed AI confidence (-1..1, sign = predicted direction, magnitude = confidence),
|
|
// refreshed every tick/timer from the active AI signal's SignedAIConfidence() in
|
|
// CExpertSignalAIBase::ScheduleTrainingIfNeeded(). Kept because it is the only read available while a
|
|
// position is already OPEN (an open position generates no further OpenParams() calls), which is the
|
|
// interesting half of any future confidence-vs-outcome study - does conviction decay before the loss?
|
|
double g_LiveAISignedConfidence = 0.0;
|
|
//--- THE LIVE AI VOTE BOARD, and it exists to keep one signal out of another signal's business.
|
|
//---
|
|
//--- g_LiveAISignedConfidence above is written once per tick and read by the intelligent trailing stop.
|
|
//--- With ONE AI signal that is exactly right. With several (an ensemble) every member wrote it
|
|
//--- unconditionally, last writer won, and an LSTM entry's stop was moved by whichever member's OnTick
|
|
//--- happened to run last (user-identified 2026-08-17).
|
|
//---
|
|
//--- The obvious patch - have a member average its siblings - trades a scheduling bug for a coupling bug,
|
|
//--- and this EA is deliberately built the other way: every signal runs in its own instance, minds its own
|
|
//--- state, and VOTES to the orchestrator, which is the only thing allowed to combine opinions. So the
|
|
//--- board below is a publish/aggregate pair with that split enforced by shape:
|
|
//--- - a member writes ONLY its own slot (PublishAIVote), never reads another's;
|
|
//--- - the orchestrator (CExpertSignalCustom::LiveSignedConfidence) calls AggregateAIVotes() to combine.
|
|
//--- Same contract as every other global here: one-way, same-tick, no back-pointer into the wizard chain.
|
|
//---
|
|
//--- The mean, matching the live open decision (a weighted-average vote, not unanimity) and the ensemble
|
|
//--- gate's combined-vote score. A member that abstains publishes 0 and dilutes, exactly as it does there;
|
|
//--- a member still training publishes 0, so a half-trained ensemble reads WEAKER rather than louder,
|
|
//--- which is the safe direction for something that can close a position.
|
|
#define AI_VOTE_BOARD_MAX 8
|
|
double g_AIVoteBoard[AI_VOTE_BOARD_MAX];
|
|
bool g_AIVoteBoardUsed[AI_VOTE_BOARD_MAX];
|
|
void PublishAIVote(int slot, double signedConfidence)
|
|
{
|
|
if(slot < 0 || slot >= AI_VOTE_BOARD_MAX)
|
|
return;
|
|
g_AIVoteBoard[slot] = signedConfidence;
|
|
g_AIVoteBoardUsed[slot] = true;
|
|
}
|
|
double AggregateAIVotes(void)
|
|
{
|
|
double sum = 0.0;
|
|
int n = 0;
|
|
for(int i = 0; i < AI_VOTE_BOARD_MAX; i++)
|
|
if(g_AIVoteBoardUsed[i])
|
|
{
|
|
sum += g_AIVoteBoard[i];
|
|
n++;
|
|
}
|
|
return (n > 0) ? sum / n : 0.0;
|
|
}
|
|
//--- CombinedConfidence(source) lived here and collapsed the two numbers above into one 0..1
|
|
//--- magnitude per the Confidence_Source input. Removed 2026-08-25 with that input and with every
|
|
//--- mode that consumed its result. The journal records the two numbers SEPARATELY and always did,
|
|
//--- so nothing is lost: a blend can be computed from the recorded columns whenever there is a
|
|
//--- reason to believe in one, which is the correct order for that operation.
|
|
//+------------------------------------------------------------------+
|