指定
XAUUSD DumpRisk + FVG Dashboard (MT5/MQL5) — Programmer Specification (v1)
1) Objective
Build a standalone dashboard module for XAUUSD (preferably an Expert Advisor, an indicator is also acceptable) that evaluates dump (sharp drop) risk and displays the result directly on the chart (on-screen display).
The module MUST NOT open, modify, or close trades.
The module ONLY calculates and displays:
-
DumpRisk % (0–100)
-
Mode: NORMAL / SAFE / NO_TRADE
-
Top reasons (2–3) explaining why risk is high (based on the largest contributing categories)
-
Lock (if a hard trigger forces NO_TRADE for a defined period)
2) Critical Quality Requirements (MUST)
-
100% compatible with MT5 / MQL5
-
0 errors, 0 warnings in MetaEditor
-
Robust CopyRates() / CopyBuffer() usage:
-
Always check return values
-
Fail gracefully (no crashes)
-
If data is missing, show “N/A” for affected parts and keep the module running
-
-
CPU optimized:
-
When ComputeOnlyOnNewM5Bar = true , compute only on a new M5 bar
-
FVG (H1/H4) recalculation only when needed (new H1/H4 bar + caching)
-
No unnecessary work in OnTick()
-
-
Clean, readable, clearly commented code:
-
Functions separated by responsibility (cache, features, scoring, UI)
-
Explicit score mapping and clamping/normalization logic
-
-
All thresholds, weights, values, and settings MUST be input parameters (tunable directly in MT5, not hardcoded)
3) “Dump-Only” Philosophy (Key Behavior)
This dashboard is designed for BUY-only / grid / averaging systems on XAUUSD.
It must not punish normal sideways markets or mild BUY trends.
-
Chop / consolidation should remain NORMAL (very low risk).
-
Mild BUY trend should remain NORMAL.
-
Risk should rise meaningfully only when clear bearish dump preparation appears:
-
Bearish impulse on M1
-
Break of structure down (BOS) on M5
-
Nearby bearish FVG below price (H1/H4)
-
Volatility chaos
-
Toxic spread conditions
-
Session acts only as a minor amplifier, never as the primary trigger.
-
4) INPUTS (Everything Adjustable in MT5)
4.1 Global Thresholds and Modes
4.2 Category Weights (Contributions to 0–100)
All must be inputs and the system must remain correct if changed:
input int W_Volatility = 25; input int W_Micro = 25; input int W_Divergence = 20; input int W_Spread = 15; input int W_Session = 10; input int W_Structure = 10; input int W_FVG_ContribMax = 20; // Max FVG contribution to final score
Developer requirement: implement clamping and normalization so the final score always remains 0–100 even if weights are modified.
5) Modules / Architecture
A) DataCache
-
Safe CopyRates() for: M1, M5, H1, H4
-
Track lastBarTime for M5/H1/H4 (and M1 for spread buffer updates)
-
If ComputeOnlyOnNewM5Bar = true , compute only on a new M5 bar
B) FeatureEngine
Compute category sub-scores:
-
Volatility (0..W_Volatility)
-
Microstructure (0..W_Micro)
-
Divergence / Exhaustion (0..W_Divergence)
-
Spread proxy (0..W_Spread)
-
Session risk (0..W_Session)
-
Structure / BOS (0..W_Structure)
C) FVGEngine (H1 + H4)
-
Detect bearish FVG zones using a 3-candle model
-
Zone becomes inactive when filled ≥ FVG_FillPct
-
Identify nearest bearish FVG below price + stack count
-
Compute FVG_RiskScore in range 0..25
-
Apply contribution cap:
-
FVG_Contrib = min(W_FVG_ContribMax, FVG_RiskScore)
-
D) DumpRiskEngine
-
Compute final DumpRiskScore (0..100) as sum of category contributions (normalized)
-
Determine Mode: NORMAL / SAFE / NO_TRADE
-
Apply hard triggers + lock handling
E) Dashboard (Display)
-
Use OBJ_LABEL (preferred), top-left corner
-
Show DumpRisk %, Mode, lock status (if active), and top reasons (2–3)
6) Exact Calculations + Score Mapping (v1)
IMPORTANT: all thresholds and boundary values below must be input parameters.
6.1 Volatility (0..W_Volatility)
Inputs
Logic
-
Compute ATR_M5 and ATR_H1
-
baseline = ATR_H1 / 12
-
ratio = ATR_M5 / baseline
-
Map ratio to base score (Score1..Score5)
-
Compute spike count: in last TRSpikes_Lookback M5 bars, count bars where TR > TRSpikes_Factor * ATR_M5
-
Add bonus based on spike count thresholds (max +TRSpikes_B3)
-
Clamp final volatility score to 0..W_Volatility (scale if needed)
6.2 Microstructure (0..W_Micro)
Micro = Wicks + FailedBO + BearImpulse
Each component has its own maximum (all inputs).
Inputs
input int WickBars = 12; input int Wick_Max = 12; input int FailedBO_Lookback = 20; input int FailedBO_Max = 6; input int BearImpulse_LookbackM1= 6; input double BearImpulse_ATRMult = 1.2; input int BearImpulse_Max = 7;
6.2.1 WickScore (0..Wick_Max) — dump-only (penalize only bearish distribution)
Threshold inputs (recommended defaults)
Logic
-
Compute average upper wick fraction over last WickBars M5 bars:
-
upperWickFraction = (high - max(open,close)) / (high - low + eps)
-
-
Compute bad fraction = % of bars where:
-
bodyRatio < Wick_BodyRatioBad AND upperWickFraction > Wick_UpperRatioBad
-
-
WickScore = AvgUpperScore + BadFracScore , clamp to 0..Wick_Max
6.2.2 FailedBreakoutScore (0..FailedBO_Max) — chop should not inflate risk
Inputs
input int FBO_Th1 = 3; input int FBO_Th2 = 5; input int FBO_Score0 = 0; input int FBO_Score1 = 2; input int FBO_Score2 = 5; input int FBO_Score3 = 6; input int FBO_LocalWindow = 5;
Definition (example)
-
A “failed breakout up” occurs when price makes a local high above prior highs but closes back below the breakout area within FBO_LocalWindow bars.
Map counts to points and clamp to 0..FailedBO_Max .
6.2.3 BearImpulseScore (0..BearImpulse_Max) — primary dump signal
Inputs
Logic
-
On M1, detect bearish impulse candle(s) within last BearImpulse_LookbackM1 bars:
-
close is near low: (close - low) / (high - low + eps) <= Impulse_ClosePosMax
-
body = (open - close) must be >= Impulse_BodyFactor * ATR_M1 * BearImpulse_ATRMult
-
-
Strength tiers:
-
if body >= Impulse_Str1 * ATR_M1 * BearImpulse_ATRMult → score Impulse_Score1
-
if body >= Impulse_Str2 * ATR_M1 * BearImpulse_ATRMult → score Impulse_Score2 (max)
-
-
Clamp to 0..BearImpulse_Max
6.3 Divergence / Exhaustion (0..W_Divergence) — only strong exhaustion
Inputs
input int RSI_Period = 14; input int EMA_SlopeBars = 10; input int Div_RSI_Max = 6; input int Div_RSIdiv_Max = 8; input int Div_EMAslope_Max = 6; // Dump-only RSI state thresholds input double RSI_T1 = 60; input double RSI_T2 = 65; input double RSI_T3 = 70; input int RSI_S0 = 0; input int RSI_S1 = 3; input int RSI_S2 = 6; // RSI divergence input int Div_SwingLookback = 60; input int Div_Score = 8; // EMA slope in points input double EMA_Slope_PosHi = 15; input double EMA_Slope_PosLo = 5; input double EMA_Slope_Neg = -5; input int EMA_Slope_S0 = 0; input int EMA_Slope_S1 = 2; input int EMA_Slope_S2 = 6;
Logic
-
RSI state:
-
RSI < RSI_T1 → RSI_S0
-
RSI >= RSI_T2 → RSI_S1
-
RSI >= RSI_T3 → RSI_S2
-
-
RSI divergence:
-
Detect bearish divergence over Div_SwingLookback and add Div_Score when confirmed
-
-
EMA slope:
-
Compute EMA slope over EMA_SlopeBars (points delta)
-
Positive slope → 0
-
Slight negative → +2
-
Strong negative → +6
Clamp each component to its max and sum, then clamp to 0..W_Divergence .
-
6.4 Spread Proxy (0..W_Spread) — only toxic conditions
Inputs
Implementation
-
Maintain a circular buffer of spread values updated only on a new M1 bar
-
Compute z = (SpreadNow - mean) / (std + eps)
-
Map z to points and clamp to 0..W_Spread
6.5 Session Risk (0..W_Session) — minor amplifier only
Inputs
input int Session_London_Start = 8; input int Session_London_End = 10; input int Session_NY_Start = 14; input int Session_NY_End = 16; input int Session_Rollover_Start = 23; input int Session_Rollover_End = 1; // must handle midnight crossover input int Session_Add_LondonNY = 2; input int Session_Add_Rollover = 3;
Clamp to 0..W_Session .
6.6 Structure (0..W_Structure) — BOS down is key
Inputs
Logic
-
Compute structureLow from bars 2..(lookback+1) on M5
-
If close(shift=1) < structureLow - BOS_BufferPoints*_Point → BOS down = true
-
Score = Struct_ScoreBOS else Struct_ScoreNoBOS, clamp to 0..W_Structure
7) FVG ENGINE (H1 + H4) — Exact and Adjustable
Inputs
input bool UseFVG = true; input ENUM_TIMEFRAMES FVG_TF1 = PERIOD_H1; input ENUM_TIMEFRAMES FVG_TF2 = PERIOD_H4; input int FVG_LookbackH1 = 400; input int FVG_LookbackH4 = 250; input double FVG_FillPct = 80.0; input double FVG_StackATRWindow= 1.5; input double FVG_DistATR_T1 = 0.75; input double FVG_DistATR_T2 = 1.50; input double FVG_DistATR_T3 = 2.50; input double FVG_SizeATR_T1 = 0.40; input double FVG_SizeATR_T2 = 0.80; // Scoring input int FVG_S_Dist1 = 12; input int FVG_S_Dist2 = 7; input int FVG_S_Dist3 = 3; input int FVG_S_Size1 = 1; input int FVG_S_Size2 = 3; input int FVG_S_Size3 = 5; input int FVG_S_Stack0 = 0; input int FVG_S_Stack1 = 1; input int FVG_S_Stack2 = 3; input int FVG_S_Stack3 = 4; input int FVG_S_InsideZone= 4; // Combining input double FVG_CombineH1Weight = 0.65; input double FVG_CombineH4Weight = 0.35;
Output
-
FVG_RiskScore in range 0..25
-
FVG_Contrib = min(W_FVG_ContribMax, FVG_RiskScore)
Performance requirement: FVG scanning must be cached and recalculated only on a new H1/H4 bar.
8) Hard Triggers + NO_TRADE Lock (Adjustable)
Inputs
Logic
-
If lock is active → always NO_TRADE
-
Trigger A:
-
If FVG >= HardA_FVG_Min AND BOS == true
-
→ NO_TRADE + lock for HardA_LockMinutes
-
-
Trigger B:
-
If FVG >= HardB_FVG_Min AND BearImpulse == true
-
→ NO_TRADE + lock for round(NoTradeLockMinutes * HardB_LockFactor)
-
9) Dashboard Output + Reasons (OBJ_LABEL)
Use OBJ_LABEL , top-left corner.
Required lines
-
DumpRisk: XX% | Mode: NORMAL/SAFE/NO_TRADE
-
Drop: 30pts | Safe:35 | NoTrade:60
-
Vol:x Micro:x Div:x Spr:x Sess:x Str:x FVG:x
-
Reasons: ... (top 2–3 category reason texts)
-
Lock: XX min (only if active)
Top reasons selection rule
-
Choose the highest contributing categories (after weighting/capping).
-
Provide human-readable reason strings, e.g.:
-
BearImpulse(M1): strong
-
BOS(M5): DOWN
-
FVG(H4): bearish below (near)
-
SpreadZ: 2.3
-
Volatility: spike/chaos
-
10) Performance Rules (Must Be Followed)
-
OnTick() :
-
If ComputeOnlyOnNewM5Bar=true :
-
Only detect new M5 bar
-
Compute only on new M5 bar
-
-
-
CopyRates() windows:
-
M5: only required bars (e.g., ~80 for divergence/structure)
-
M1: only what is needed for impulse and spread update on new M1 bar
-
-
FVG:
-
Do not scan 400/250 bars every tick
-
Scan only when needed + cache results
-
11) Delivery
-
Provide one .mq5 file (EA or indicator)
-
Must compile with 0 warnings / 0 errors
-
Provide short usage notes:
-
How to attach it to XAUUSD M5
-
Explain the meaning of NORMAL / SAFE / NO_TRADE
-
12) Acceptance Tests (Scenario-Based)
General Acceptance (Always True)
-
No trading operations
-
The module must never call trade functions that place/modify/close orders or positions.
-
-
Stable operation
-
No freezes, no crashes, no excessive journal spam.
-
-
Correct update cadence
-
With ComputeOnlyOnNewM5Bar=true , DumpRisk and all category scores must not change within the same M5 bar (except lock countdown display).
-
-
FVG caching
-
FVG scan must run only on new H1/H4 bars (or when explicitly required by cache invalidation), not on every tick.
-
A) CHOP / CONSOLIDATION (Sideways Market)
Setup
-
Price moves in a tight range, frequent small reversals
-
No strong bearish impulse candles on M1
-
No BOS down on M5
-
Spread normal (SpreadZ typically < 1.0)
-
FVG zones, if present, are far or not relevant (distance above T3)
Expected
-
Mode = NORMAL
-
DumpRisk typically ≤ 15% (target range: 5–15%)
-
Category expectations:
-
Volatility low (0–4 points typical)
-
Micro low (0–2 typical; wicks may be present but should not dominate)
-
Divergence low (0–3 typical)
-
Spread near 0
-
Structure 0 (no BOS)
-
FVG low (0–3 typical, or 0 if far)
-
-
Reasons:
-
If any reasons appear, they must be mild (e.g. “Wicks: moderate”), and only when contributions are meaningful.
-
Fail conditions
-
Mode becomes SAFE/NO_TRADE without BearImpulse or BOS down.
-
DumpRisk consistently > 25 in a sideways market with normal spread.
B) MILD BUY TREND (Gradual Uptrend / Normal Pullbacks)
Setup
-
M5 trend mildly up, pullbacks are shallow
-
EMA slope is positive or near-flat
-
RSI is below 65 most of the time
-
No BOS down
-
No strong bearish impulses on M1 (occasional red candles allowed)
-
Spread normal
Expected
-
Mode = NORMAL
-
DumpRisk typically ≤ 20% (target range: 5–20%)
-
Category expectations:
-
Divergence should not inflate risk unless RSI is very high AND divergence confirmed
-
Structure must remain 0 (no BOS)
-
Micro remains low unless a real impulse occurs
-
-
Reasons:
-
Should not show “dump-style” reasons in normal uptrend conditions
-
Fail conditions
-
SAFE mode triggered solely because RSI > 60 or because normal pullbacks occur.
-
NO_TRADE triggered without hard trigger conditions.
C) DUMP / PRE-DUMP CONDITIONS (Sharp Bearish Move)
Setup
One of the following must be present (ideally multiple):
-
BearImpulse(M1) detected (strong body, close near low)
-
BOS down (M5) confirmed
-
Nearby bearish FVG below price (distance within T1/T2)
-
Volatility ratio high (≥ L3/L4) and/or multiple TR spikes
-
SpreadZ elevated (≥ 1.6 or more)
Expected (Soft)
-
If score ≥ ScoreSafe (default 35) → Mode = SAFE
-
If score ≥ ScoreNoTrade (default 60) → Mode = NO_TRADE
-
DumpRisk should jump meaningfully (e.g., from <20 to >60) when conditions align.
Expected (Hard Triggers + Lock)
-
Trigger A:
-
If FVG >= HardA_FVG_Min AND BOS==true
-
→ Mode immediately becomes NO_TRADE
-
Lock activates for HardA_LockMinutes
-
-
Trigger B:
-
If FVG >= HardB_FVG_Min AND BearImpulse==true
-
→ Mode immediately becomes NO_TRADE
-
Lock activates for round(NoTradeLockMinutes * HardB_LockFactor)
-
Lock behavior
-
While lock is active:
-
Mode must remain NO_TRADE regardless of score changes
-
UI must show Lock: XX min counting down
-
-
When lock expires:
-
Mode returns to score-based evaluation (NORMAL/SAFE/NO_TRADE)
-
Reasons
-
Reasons must reflect the main contributors, typically:
-
BearImpulse(M1): strong
-
BOS(M5): DOWN
-
FVG(H4): bearish below (near)
-
Volatility: chaos spike
-
SpreadZ: high
-
Fail conditions
-
A true dump scenario (impulse + BOS + near FVG) does not elevate Mode to SAFE/NO_TRADE.
-
Lock does not hold NO_TRADE until expiry.
-
Reasons do not correspond to the highest contributing categories.
D) DATA ISSUES / MISSING HISTORY (Robustness)
Setup
-
Insufficient bars on H4/H1 or temporary CopyRates() failure
Expected
-
Module remains running
-
Affected values show “N/A” or score=0 with a clear reason in code
-
No crash, no endless loops, no tick-level spam
-
Mode should still be computed from available categories, but must not produce false NO_TRADE purely due to missing data