superhimzbot/boting

1785 lines
54 KiB
Text
Raw Permalink Normal View History

2026-01-17 18:47:53 +00:00
//+------------------------------------------------------------------+
//| AI_MLEngine_PatternDetector.mqh|
//| Machine Learning & Pattern Recognition |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Candlestick Pattern Detector |
//+------------------------------------------------------------------+
class CPatternDetector
{
private:
string m_symbol;
ENUM_TIMEFRAMES m_timeframe;
MqlRates m_rates[];
public:
CPatternDetector(string symbol, ENUM_TIMEFRAMES tf)
{
m_symbol = symbol;
m_timeframe = tf;
ArraySetAsSeries(m_rates, true);
}
bool UpdateData()
{
return CopyRates(m_symbol, m_timeframe, 0, 10, m_rates) > 0;
}
// Bullish Engulfing
bool IsBullishEngulfing()
{
if(ArraySize(m_rates) < 2) return false;
bool prevBearish = m_rates[1].close < m_rates[1].open;
bool currBullish = m_rates[0].close > m_rates[0].open;
bool engulfs = m_rates[0].close > m_rates[1].open &&
m_rates[0].open < m_rates[1].close;
return prevBearish && currBullish && engulfs;
}
// Bearish Engulfing
bool IsBearishEngulfing()
{
if(ArraySize(m_rates) < 2) return false;
bool prevBullish = m_rates[1].close > m_rates[1].open;
bool currBearish = m_rates[0].close < m_rates[0].open;
bool engulfs = m_rates[0].close < m_rates[1].open &&
m_rates[0].open > m_rates[1].close;
return prevBullish && currBearish && engulfs;
}
// Pin Bar (Hammer/Shooting Star)
int DetectPinBar()
{
if(ArraySize(m_rates) < 1) return 0;
double body = MathAbs(m_rates[0].close - m_rates[0].open);
double upperWick = m_rates[0].high - MathMax(m_rates[0].close, m_rates[0].open);
double lowerWick = MathMin(m_rates[0].close, m_rates[0].open) - m_rates[0].low;
double totalRange = m_rates[0].high - m_rates[0].low;
if(totalRange == 0) return 0;
// Bullish Pin (Hammer)
if(lowerWick > body * 2 && lowerWick > totalRange * 0.6 && upperWick < body)
return 1;
// Bearish Pin (Shooting Star)
if(upperWick > body * 2 && upperWick > totalRange * 0.6 && lowerWick < body)
return -1;
return 0;
}
// Doji
bool IsDoji()
{
if(ArraySize(m_rates) < 1) return false;
double body = MathAbs(m_rates[0].close - m_rates[0].open);
double totalRange = m_rates[0].high - m_rates[0].low;
return (body < totalRange * 0.1);
}
// Morning/Evening Star (3-candle pattern)
int DetectStar()
{
if(ArraySize(m_rates) < 3) return 0;
double body1 = MathAbs(m_rates[2].close - m_rates[2].open);
double body2 = MathAbs(m_rates[1].close - m_rates[1].open);
double body3 = MathAbs(m_rates[0].close - m_rates[0].open);
// Morning Star (Bullish)
if(m_rates[2].close < m_rates[2].open && // Bearish candle
body2 < body1 * 0.3 && // Small middle candle
m_rates[0].close > m_rates[0].open && // Bullish candle
m_rates[0].close > m_rates[2].open) // Closes above first candle open
return 1;
// Evening Star (Bearish)
if(m_rates[2].close > m_rates[2].open && // Bullish candle
body2 < body1 * 0.3 && // Small middle candle
m_rates[0].close < m_rates[0].open && // Bearish candle
m_rates[0].close < m_rates[2].open) // Closes below first candle open
return -1;
return 0;
}
// Get pattern score (combined)
double GetPatternScore()
{
UpdateData();
double score = 0;
if(IsBullishEngulfing()) score += 30;
if(IsBearishEngulfing()) score -= 30;
int pinBar = DetectPinBar();
score += pinBar * 25;
int star = DetectStar();
score += star * 35;
if(IsDoji()) score += 0; // Neutral - indecision
return score;
}
};
//+------------------------------------------------------------------+
//| Support & Resistance Level Detector |
//+------------------------------------------------------------------+
class CLevelDetector
{
private:
string m_symbol;
ENUM_TIMEFRAMES m_timeframe;
double m_supportLevels[];
double m_resistanceLevels[];
int m_lookbackBars;
public:
CLevelDetector(string symbol, ENUM_TIMEFRAMES tf, int lookback = 100)
{
m_symbol = symbol;
m_timeframe = tf;
m_lookbackBars = lookback;
}
void DetectLevels()
{
ArrayResize(m_supportLevels, 0);
ArrayResize(m_resistanceLevels, 0);
MqlRates rates[];
ArraySetAsSeries(rates, true);
if(CopyRates(m_symbol, m_timeframe, 0, m_lookbackBars, rates) <= 0)
return;
// Detect swing highs and lows
for(int i = 3; i < m_lookbackBars - 3; i++)
{
// Swing High (Resistance)
if(rates[i].high > rates[i-1].high && rates[i].high > rates[i-2].high &&
rates[i].high > rates[i+1].high && rates[i].high > rates[i+2].high)
{
AddResistance(rates[i].high);
}
// Swing Low (Support)
if(rates[i].low < rates[i-1].low && rates[i].low < rates[i-2].low &&
rates[i].low < rates[i+1].low && rates[i].low < rates[i+2].low)
{
AddSupport(rates[i].low);
}
}
// Cluster nearby levels
ClusterLevels();
}
void AddSupport(double level)
{
int size = ArraySize(m_supportLevels);
ArrayResize(m_supportLevels, size + 1);
m_supportLevels[size] = level;
}
void AddResistance(double level)
{
int size = ArraySize(m_resistanceLevels);
ArrayResize(m_resistanceLevels, size + 1);
m_resistanceLevels[size] = level;
}
void ClusterLevels()
{
double threshold = SymbolInfoDouble(m_symbol, SYMBOL_POINT) * 50;
// Cluster support levels
for(int i = 0; i < ArraySize(m_supportLevels); i++)
{
for(int j = i + 1; j < ArraySize(m_supportLevels); j++)
{
if(MathAbs(m_supportLevels[i] - m_supportLevels[j]) < threshold)
{
m_supportLevels[i] = (m_supportLevels[i] + m_supportLevels[j]) / 2;
ArrayRemove(m_supportLevels, j, 1);
j--;
}
}
}
// Cluster resistance levels
for(int i = 0; i < ArraySize(m_resistanceLevels); i++)
{
for(int j = i + 1; j < ArraySize(m_resistanceLevels); j++)
{
if(MathAbs(m_resistanceLevels[i] - m_resistanceLevels[j]) < threshold)
{
m_resistanceLevels[i] = (m_resistanceLevels[i] + m_resistanceLevels[j]) / 2;
ArrayRemove(m_resistanceLevels, j, 1);
j--;
}
}
}
}
double GetNearestSupport(double price)
{
double nearest = 0;
double minDist = DBL_MAX;
for(int i = 0; i < ArraySize(m_supportLevels); i++)
{
if(m_supportLevels[i] < price)
{
double dist = price - m_supportLevels[i];
if(dist < minDist)
{
minDist = dist;
nearest = m_supportLevels[i];
}
}
}
return nearest;
}
double GetNearestResistance(double price)
{
double nearest = 0;
double minDist = DBL_MAX;
for(int i = 0; i < ArraySize(m_resistanceLevels); i++)
{
if(m_resistanceLevels[i] > price)
{
double dist = m_resistanceLevels[i] - price;
if(dist < minDist)
{
minDist = dist;
nearest = m_resistanceLevels[i];
}
}
}
return nearest;
}
bool IsNearSupport(double price, double threshold = 0.0005)
{
double support = GetNearestSupport(price);
if(support == 0) return false;
return (MathAbs(price - support) / price < threshold);
}
bool IsNearResistance(double price, double threshold = 0.0005)
{
double resistance = GetNearestResistance(price);
if(resistance == 0) return false;
return (MathAbs(price - resistance) / price < threshold);
}
};
//+------------------------------------------------------------------+
//| Simple Neural Network for Decision Making |
//+------------------------------------------------------------------+
class CNeuralNetwork
{
private:
// Simple 3-layer network: Input -> Hidden -> Output
int m_inputSize;
int m_hiddenSize;
int m_outputSize;
double m_weightsIH[][]; // Input to Hidden
double m_weightsHO[][]; // Hidden to Output
double m_biasH[];
double m_biasO[];
public:
CNeuralNetwork(int inputSize, int hiddenSize, int outputSize)
{
m_inputSize = inputSize;
m_hiddenSize = hiddenSize;
m_outputSize = outputSize;
InitializeWeights();
}
void InitializeWeights()
{
// Initialize with small random values
ArrayResize(m_weightsIH, m_inputSize);
for(int i = 0; i < m_inputSize; i++)
{
ArrayResize(m_weightsIH[i], m_hiddenSize);
for(int j = 0; j < m_hiddenSize; j++)
m_weightsIH[i][j] = (MathRand() / 32767.0 - 0.5) * 0.5;
}
ArrayResize(m_weightsHO, m_hiddenSize);
for(int i = 0; i < m_hiddenSize; i++)
{
ArrayResize(m_weightsHO[i], m_outputSize);
for(int j = 0; j < m_outputSize; j++)
m_weightsHO[i][j] = (MathRand() / 32767.0 - 0.5) * 0.5;
}
ArrayResize(m_biasH, m_hiddenSize);
ArrayResize(m_biasO, m_outputSize);
ArrayInitialize(m_biasH, 0);
ArrayInitialize(m_biasO, 0);
}
double Sigmoid(double x)
{
return 1.0 / (1.0 + MathExp(-x));
}
double ReLU(double x)
{
return MathMax(0, x);
}
void Forward(double &inputs[], double &outputs[])
{
ArrayResize(outputs, m_outputSize);
// Hidden layer
double hidden[];
ArrayResize(hidden, m_hiddenSize);
for(int j = 0; j < m_hiddenSize; j++)
{
double sum = m_biasH[j];
for(int i = 0; i < m_inputSize; i++)
sum += inputs[i] * m_weightsIH[i][j];
hidden[j] = ReLU(sum);
}
// Output layer
for(int k = 0; k < m_outputSize; k++)
{
double sum = m_biasO[k];
for(int j = 0; j < m_hiddenSize; j++)
sum += hidden[j] * m_weightsHO[j][k];
outputs[k] = Sigmoid(sum);
}
}
// Simplified training (would need proper backpropagation in production)
void Train(double &inputs[], double &targets[], double learningRate = 0.01)
{
// This is a placeholder - implement full backpropagation for production
// For now, just forward pass
double outputs[];
Forward(inputs, outputs);
}
};
//+------------------------------------------------------------------+
//| AI Decision Engine - Combines All Intelligence |
//+------------------------------------------------------------------+
class CAIDecisionEngine
{
private:
CPatternDetector *m_patternH1;
CPatternDetector *m_patternH4;
CLevelDetector *m_levelH4;
CNeuralNetwork *m_neuralNet;
string m_symbol;
public:
CAIDecisionEngine(string symbol)
{
m_symbol = symbol;
m_patternH1 = new CPatternDetector(symbol, PERIOD_H1);
m_patternH4 = new CPatternDetector(symbol, PERIOD_H4);
m_levelH4 = new CLevelDetector(symbol, PERIOD_H4, 200);
// Neural network: 10 inputs -> 20 hidden -> 3 outputs (Buy/Neutral/Sell)
m_neuralNet = new CNeuralNetwork(10, 20, 3);
}
~CAIDecisionEngine()
{
delete m_patternH1;
delete m_patternH4;
delete m_levelH4;
delete m_neuralNet;
}
double MakeDecision(MarketContext &ctx)
{
// Update levels
m_levelH4.DetectLevels();
// Get pattern scores
double patternScoreH1 = m_patternH1.GetPatternScore();
double patternScoreH4 = m_patternH4.GetPatternScore();
// Check proximity to levels
ctx.nearSupport = m_levelH4.IsNearSupport(ctx.currentPrice);
ctx.nearResistance = m_levelH4.IsNearResistance(ctx.currentPrice);
// Prepare neural network inputs (normalized 0-1)
double inputs[10];
inputs[0] = (ctx.trendStrengthH1 + 100) / 200.0; // -100 to 100 -> 0 to 1
inputs[1] = (ctx.trendStrengthH4 + 100) / 200.0;
inputs[2] = (ctx.trendStrengthD1 + 100) / 200.0;
inputs[3] = ctx.volatilityRatio / 3.0; // Normalize assuming max 3x
inputs[4] = (patternScoreH1 + 100) / 200.0;
inputs[5] = (patternScoreH4 + 100) / 200.0;
inputs[6] = ctx.nearSupport ? 1.0 : 0.0;
inputs[7] = ctx.nearResistance ? 1.0 : 0.0;
inputs[8] = ctx.isNewsTime ? 1.0 : 0.0;
inputs[9] = (ctx.usdStrength + 100) / 200.0;
// Get neural network decision
double outputs[];
m_neuralNet.Forward(inputs, outputs);
// outputs[0] = Buy probability
// outputs[1] = Neutral probability
// outputs[2] = Sell probability
// Return decision score: -1 (Strong Sell) to +1 (Strong Buy)
double decision = outputs[0] - outputs[2];
return decision;
}
};
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| UltraFast_AI_XAUUSD_System.mq5 |
//| High-Frequency AI Trading Framework |
//| Sub-Second Multi-Factor Analysis |
//+------------------------------------------------------------------+
#property copyright "Ultra-Fast AI Gold Trading System"
#property version "2.00"
#property strict
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
//+------------------------------------------------------------------+
//| INPUT PARAMETERS - Fine-tune for HFT performance |
//+------------------------------------------------------------------+
input group "=== CORE SETTINGS ==="
input double RiskPercentPerTrade = 1.0; // Risk % per trade
input double MaxDailyLoss = 3.0; // Max daily loss %
input int MagicNumber = 123456; // EA Magic Number
input string TradeComment = "AI_HFT_Gold"; // Trade comment
input group "=== HIGH-FREQUENCY SETTINGS ==="
input bool EnableSubSecondAnalysis = true; // Enable tick-by-tick analysis
input int MinTicksBeforeTrade = 3; // Min ticks for signal confirmation
input int MaxSlippagePips = 5; // Max allowed slippage
input bool UseMarketExecution = true; // Use instant execution (faster)
input int MaxSpreadPips = 30; // Max spread to trade
input group "=== MULTI-FACTOR SCORING ==="
input double TrendWeight = 30.0; // Trend strength weight %
input double VolatilityWeight = 20.0; // Volatility regime weight %
input double IndicatorWeight = 25.0; // Indicator confluence weight %
input double PatternWeight = 25.0; // Pattern recognition weight %
input double MinConfluenceScore = 65.0; // Min score to trade (0-100)
input group "=== EXECUTION DISCIPLINE ==="
input bool InstantStopLoss = true; // Place SL immediately
input double StopLossATRMultiplier = 1.5; // SL = ATR * multiplier
input double TakeProfitATRMultiplier = 3.0; // TP = ATR * multiplier
input bool UseTrailingStop = true; // Enable trailing stop
input double TrailingStopATRMultiplier = 1.0;// Trailing stop distance
input group "=== ADVANCED FILTERS ==="
input bool FilterHighSpread = true; // Block trades on high spread
input bool FilterNewsEvents = true; // Block trades during news
input int NewsBufferMinutes = 15; // Minutes before/after news
input bool FilterSessionTimes = true; // Trade only in specific sessions
input bool AllowLondonSession = true; // Trade during London
input bool AllowNYSession = true; // Trade during NY
input bool AllowAsianSession = false; // Trade during Asian
//+------------------------------------------------------------------+
//| ENUMERATIONS |
//+------------------------------------------------------------------+
enum ENUM_MARKET_REGIME
{
REGIME_STRONG_UPTREND,
REGIME_WEAK_UPTREND,
REGIME_STRONG_DOWNTREND,
REGIME_WEAK_DOWNTREND,
REGIME_RANGING,
REGIME_BREAKOUT_UP,
REGIME_BREAKOUT_DOWN,
REGIME_HIGH_VOLATILITY,
REGIME_UNKNOWN
};
enum ENUM_SIGNAL_STRENGTH
{
SIGNAL_VERY_STRONG_BUY = 100,
SIGNAL_STRONG_BUY = 75,
SIGNAL_WEAK_BUY = 50,
SIGNAL_NEUTRAL = 0,
SIGNAL_WEAK_SELL = -50,
SIGNAL_STRONG_SELL = -75,
SIGNAL_VERY_STRONG_SELL = -100
};
//+------------------------------------------------------------------+
//| Ultra-Fast Market Context - Optimized for Speed |
//+------------------------------------------------------------------+
struct UltraFastContext
{
// Timing (microsecond precision)
datetime lastTickTime;
ulong lastTickMicroseconds;
int tickCounter;
// Price action (immediate)
double bid, ask, spread;
double lastClose, currentClose;
double priceChangeRate; // Price velocity
// Market structure
ENUM_MARKET_REGIME regime;
double trendScore; // -100 to +100
double volatilityScore; // 0 to 100
// Multi-factor scores
double indicatorScore; // 0 to 100
double patternScore; // -100 to +100
double confluenceScore; // Final weighted score
// Execution context
bool canTrade;
bool isHighSpread;
bool isNewsTime;
bool isValidSession;
// Risk metrics
double atrValue;
double dynamicSL;
double dynamicTP;
void Reset()
{
tickCounter = 0;
regime = REGIME_UNKNOWN;
trendScore = 0;
volatilityScore = 0;
indicatorScore = 0;
patternScore = 0;
confluenceScore = 0;
canTrade = false;
}
};
//+------------------------------------------------------------------+
//| Ultra-Fast Indicator Engine - Pre-calculated & Cached |
//+------------------------------------------------------------------+
class CUltraFastIndicators
{
private:
// Cached handles (initialized once)
int h_ema_fast, h_ema_medium, h_ema_slow;
int h_rsi, h_macd, h_atr, h_adx;
int h_bb, h_stoch;
// Cached buffers (updated only on bar change)
double cache_ema_fast[3], cache_ema_medium[3], cache_ema_slow[3];
double cache_rsi[3], cache_macd_main[3], cache_macd_signal[3];
double cache_atr[3], cache_adx[3];
double cache_bb_upper[3], cache_bb_lower[3], cache_bb_middle[3];
double cache_stoch_main[3], cache_stoch_signal[3];
// Real-time tick data (updated every tick)
double tick_price;
double tick_ema_fast; // Exponential smoothing on ticks
datetime lastBarTime;
string m_symbol;
ENUM_TIMEFRAMES m_tf;
// Exponential smoothing factor for tick-level EMA
double alpha_fast;
public:
CUltraFastIndicators(string symbol, ENUM_TIMEFRAMES tf = PERIOD_M1)
{
m_symbol = symbol;
m_tf = tf;
lastBarTime = 0;
tick_ema_fast = 0;
alpha_fast = 2.0 / (10.0 + 1.0); // 10-period EMA smoothing
InitializeIndicators();
}
~CUltraFastIndicators()
{
ReleaseIndicators();
}
bool InitializeIndicators()
{
// Initialize all indicators
h_ema_fast = iMA(m_symbol, m_tf, 9, 0, MODE_EMA, PRICE_CLOSE);
h_ema_medium = iMA(m_symbol, m_tf, 21, 0, MODE_EMA, PRICE_CLOSE);
h_ema_slow = iMA(m_symbol, m_tf, 50, 0, MODE_EMA, PRICE_CLOSE);
h_rsi = iRSI(m_symbol, m_tf, 14, PRICE_CLOSE);
h_macd = iMACD(m_symbol, m_tf, 12, 26, 9, PRICE_CLOSE);
h_atr = iATR(m_symbol, m_tf, 14);
h_adx = iADX(m_symbol, m_tf, 14);
h_bb = iBands(m_symbol, m_tf, 20, 0, 2.0, PRICE_CLOSE);
h_stoch = iStochastic(m_symbol, m_tf, 5, 3, 3, MODE_SMA, STO_LOWHIGH);
if(h_ema_fast == INVALID_HANDLE || h_rsi == INVALID_HANDLE)
{
Print("ERROR: Indicator initialization failed!");
return false;
}
// Pre-fill cache
Sleep(100); // Allow indicators to calculate
UpdateCache(true);
return true;
}
void ReleaseIndicators()
{
IndicatorRelease(h_ema_fast);
IndicatorRelease(h_ema_medium);
IndicatorRelease(h_ema_slow);
IndicatorRelease(h_rsi);
IndicatorRelease(h_macd);
IndicatorRelease(h_atr);
IndicatorRelease(h_adx);
IndicatorRelease(h_bb);
IndicatorRelease(h_stoch);
}
// Update cache only on new bar (efficient)
bool UpdateCache(bool force = false)
{
datetime currentBarTime = iTime(m_symbol, m_tf, 0);
if(!force && currentBarTime == lastBarTime)
return false; // No new bar, use cached values
lastBarTime = currentBarTime;
// Copy all buffers at once (optimized)
if(CopyBuffer(h_ema_fast, 0, 0, 3, cache_ema_fast) <= 0) return false;
if(CopyBuffer(h_ema_medium, 0, 0, 3, cache_ema_medium) <= 0) return false;
if(CopyBuffer(h_ema_slow, 0, 0, 3, cache_ema_slow) <= 0) return false;
if(CopyBuffer(h_rsi, 0, 0, 3, cache_rsi) <= 0) return false;
if(CopyBuffer(h_macd, 0, 0, 3, cache_macd_main) <= 0) return false;
if(CopyBuffer(h_macd, 1, 0, 3, cache_macd_signal) <= 0) return false;
if(CopyBuffer(h_atr, 0, 0, 3, cache_atr) <= 0) return false;
if(CopyBuffer(h_adx, 0, 0, 3, cache_adx) <= 0) return false;
if(CopyBuffer(h_bb, 1, 0, 3, cache_bb_upper) <= 0) return false;
if(CopyBuffer(h_bb, 2, 0, 3, cache_bb_lower) <= 0) return false;
if(CopyBuffer(h_bb, 0, 0, 3, cache_bb_middle) <= 0) return false;
if(CopyBuffer(h_stoch, 0, 0, 3, cache_stoch_main) <= 0) return false;
if(CopyBuffer(h_stoch, 1, 0, 3, cache_stoch_signal) <= 0) return false;
return true;
}
// Ultra-fast tick update (sub-millisecond)
void UpdateTick(double price)
{
tick_price = price;
// Real-time EMA calculation on ticks
if(tick_ema_fast == 0)
tick_ema_fast = price;
else
tick_ema_fast = alpha_fast * price + (1 - alpha_fast) * tick_ema_fast;
}
// Instant access to cached values (microsecond speed)
double GetEMAFast(int shift = 0) { return cache_ema_fast[shift]; }
double GetEMAMedium(int shift = 0) { return cache_ema_medium[shift]; }
double GetEMASlow(int shift = 0) { return cache_ema_slow[shift]; }
double GetRSI(int shift = 0) { return cache_rsi[shift]; }
double GetMACD(int shift = 0) { return cache_macd_main[shift]; }
double GetMACDSignal(int shift = 0) { return cache_macd_signal[shift]; }
double GetATR(int shift = 0) { return cache_atr[shift]; }
double GetADX(int shift = 0) { return cache_adx[shift]; }
double GetBBUpper(int shift = 0) { return cache_bb_upper[shift]; }
double GetBBLower(int shift = 0) { return cache_bb_lower[shift]; }
double GetBBMiddle(int shift = 0) { return cache_bb_middle[shift]; }
double GetStochMain(int shift = 0) { return cache_stoch_main[shift]; }
double GetStochSignal(int shift = 0) { return cache_stoch_signal[shift]; }
// Tick-level indicators
double GetTickEMA() { return tick_ema_fast; }
double GetTickPrice() { return tick_price; }
};
//+------------------------------------------------------------------+
//| Ultra-Fast Multi-Factor Analyzer |
//+------------------------------------------------------------------+
class CMultiFactorAnalyzer
{
private:
CUltraFastIndicators *indicators;
string m_symbol;
public:
CMultiFactorAnalyzer(string symbol)
{
m_symbol = symbol;
indicators = new CUltraFastIndicators(symbol, PERIOD_M1);
}
~CMultiFactorAnalyzer()
{
delete indicators;
}
// FACTOR 1: Trend Strength Analysis (-100 to +100)
double AnalyzeTrendStrength()
{
double score = 0;
double price = SymbolInfoDouble(m_symbol, SYMBOL_BID);
// EMA alignment (50 points max)
double ema_fast = indicators.GetEMAFast();
double ema_medium = indicators.GetEMAMedium();
double ema_slow = indicators.GetEMASlow();
if(ema_fast > ema_medium && ema_medium > ema_slow)
score += 50; // Perfect bullish alignment
else if(ema_fast < ema_medium && ema_medium < ema_slow)
score -= 50; // Perfect bearish alignment
else
score += 0; // Mixed signals
// Price position relative to EMAs (30 points max)
if(price > ema_fast && price > ema_medium && price > ema_slow)
score += 30;
else if(price < ema_fast && price < ema_medium && price < ema_slow)
score -= 30;
// ADX strength confirmation (20 points max)
double adx = indicators.GetADX();
if(adx > 25)
score *= 1.2; // Boost score in strong trend
else if(adx < 15)
score *= 0.5; // Reduce score in weak trend
return NormalizeDouble(MathMax(-100, MathMin(100, score)), 2);
}
// FACTOR 2: Volatility Regime Detection (0 to 100)
double AnalyzeVolatility()
{
double atr = indicators.GetATR();
double atr_prev = indicators.GetATR(1);
double atr_change = (atr - atr_prev) / atr_prev * 100;
// Calculate volatility percentile
double score = 50; // Base score
// ATR expansion/contraction
if(atr_change > 10)
score += 30; // Volatility expanding
else if(atr_change < -10)
score -= 20; // Volatility contracting
// Bollinger Band width
double bb_upper = indicators.GetBBUpper();
double bb_lower = indicators.GetBBLower();
double bb_width = (bb_upper - bb_lower) / indicators.GetBBMiddle() * 100;
if(bb_width > 2.0)
score += 20;
else if(bb_width < 1.0)
score -= 20;
return NormalizeDouble(MathMax(0, MathMin(100, score)), 2);
}
// FACTOR 3: Indicator Confluence Scoring (0 to 100)
double AnalyzeIndicatorConfluence()
{
double score = 0;
int bullish_signals = 0;
int bearish_signals = 0;
// RSI analysis
double rsi = indicators.GetRSI();
if(rsi > 50 && rsi < 70)
bullish_signals++;
else if(rsi < 50 && rsi > 30)
bearish_signals++;
// MACD analysis
double macd = indicators.GetMACD();
double macd_signal = indicators.GetMACDSignal();
if(macd > macd_signal && macd > 0)
bullish_signals++;
else if(macd < macd_signal && macd < 0)
bearish_signals++;
// Stochastic analysis
double stoch_main = indicators.GetStochMain();
double stoch_signal = indicators.GetStochSignal();
if(stoch_main > stoch_signal && stoch_main < 80)
bullish_signals++;
else if(stoch_main < stoch_signal && stoch_main > 20)
bearish_signals++;
// Bollinger Bands position
double price = SymbolInfoDouble(m_symbol, SYMBOL_BID);
double bb_middle = indicators.GetBBMiddle();
if(price > bb_middle)
bullish_signals++;
else if(price < bb_middle)
bearish_signals++;
// Calculate confluence
int total_signals = bullish_signals + bearish_signals;
if(total_signals > 0)
{
double confluence_ratio = (double)MathMax(bullish_signals, bearish_signals) / total_signals;
score = confluence_ratio * 100;
}
return NormalizeDouble(score, 2);
}
// FACTOR 4: Pattern Recognition (-100 to +100)
double AnalyzePatterns()
{
double score = 0;
MqlRates rates[];
ArraySetAsSeries(rates, true);
if(CopyRates(m_symbol, PERIOD_M1, 0, 5, rates) < 5)
return 0;
// Bullish Engulfing
if(IsBullishEngulfing(rates))
score += 40;
// Bearish Engulfing
if(IsBearishEngulfing(rates))
score -= 40;
// Pin Bar detection
int pinBar = DetectPinBar(rates);
score += pinBar * 30;
// Higher High / Lower Low patterns
if(rates[0].high > rates[1].high && rates[1].high > rates[2].high)
score += 20; // Bullish momentum
else if(rates[0].low < rates[1].low && rates[1].low < rates[2].low)
score -= 20; // Bearish momentum
return NormalizeDouble(MathMax(-100, MathMin(100, score)), 2);
}
bool IsBullishEngulfing(MqlRates &rates[])
{
return (rates[1].close < rates[1].open &&
rates[0].close > rates[0].open &&
rates[0].close > rates[1].open &&
rates[0].open < rates[1].close);
}
bool IsBearishEngulfing(MqlRates &rates[])
{
return (rates[1].close > rates[1].open &&
rates[0].close < rates[0].open &&
rates[0].close < rates[1].open &&
rates[0].open > rates[1].close);
}
int DetectPinBar(MqlRates &rates[])
{
double body = MathAbs(rates[0].close - rates[0].open);
double upperWick = rates[0].high - MathMax(rates[0].close, rates[0].open);
double lowerWick = MathMin(rates[0].close, rates[0].open) - rates[0].low;
double range = rates[0].high - rates[0].low;
if(range == 0) return 0;
if(lowerWick > body * 2 && lowerWick > range * 0.6)
return 1; // Bullish pin
if(upperWick > body * 2 && upperWick > range * 0.6)
return -1; // Bearish pin
return 0;
}
// Update indicators (call on new bar only)
void UpdateIndicators()
{
indicators.UpdateCache();
}
// Update tick data (call every tick)
void UpdateTick(double price)
{
indicators.UpdateTick(price);
}
double GetATR() { return indicators.GetATR(); }
};
//+------------------------------------------------------------------+
//| Lightning-Fast Execution Engine |
//+------------------------------------------------------------------+
class CLightningExecutor
{
private:
CTrade trade;
CSymbolInfo symbolInfo;
CPositionInfo positionInfo;
string m_symbol;
int m_magic;
public:
CLightningExecutor(string symbol, int magic)
{
m_symbol = symbol;
m_magic = magic;
trade.SetExpertMagicNumber(m_magic);
trade.SetDeviationInPoints(MaxSlippagePips * 10);
trade.SetTypeFilling(ORDER_FILLING_IOC); // Immediate or Cancel
trade.SetAsyncMode(false); // Synchronous for reliability
symbolInfo.Name(m_symbol);
}
// Execute BUY with instant SL/TP
bool ExecuteBuy(double lots, double sl, double tp, string comment)
{
symbolInfo.Refresh();
double ask = symbolInfo.Ask();
if(!trade.Buy(lots, m_symbol, ask, sl, tp, comment))
{
Print("BUY FAILED: ", trade.ResultRetcodeDescription());
return false;
}
Print("BUY EXECUTED: ", lots, " lots @ ", ask, " | SL:", sl, " TP:", tp);
return true;
}
// Execute SELL with instant SL/TP
bool ExecuteSell(double lots, double sl, double tp, string comment)
{
symbolInfo.Refresh();
double bid = symbolInfo.Bid();
if(!trade.Sell(lots, m_symbol, bid, sl, tp, comment))
{
Print("SELL FAILED: ", trade.ResultRetcodeDescription());
return false;
}
Print("SELL EXECUTED: ", lots, " lots @ ", bid, " | SL:", sl, " TP:", tp);
return true;
}
// Trailing stop implementation
void ManageTrailingStop(double atr)
{
if(!UseTrailingStop) return;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(!positionInfo.SelectByIndex(i)) continue;
if(positionInfo.Symbol() != m_symbol || positionInfo.Magic() != m_magic) continue;
double trailDistance = atr * TrailingStopATRMultiplier;
double currentPrice = positionInfo.Type() == POSITION_TYPE_BUY ?
symbolInfo.Bid() : symbolInfo.Ask();
double currentSL = positionInfo.StopLoss();
if(positionInfo.Type() == POSITION_TYPE_BUY)
{
double newSL = currentPrice - trailDistance;
if(newSL > currentSL && newSL < currentPrice)
trade.PositionModify(positionInfo.Ticket(), newSL, positionInfo.TakeProfit());
}
else
{
double newSL = currentPrice + trailDistance;
if(newSL < currentSL && newSL > currentPrice)
trade.PositionModify(positionInfo.Ticket(), newSL, positionInfo.TakeProfit());
}
}
}
bool HasOpenPosition()
{
for(int i = 0; i < PositionsTotal(); i++)
{
if(positionInfo.SelectByIndex(i))
{
if(positionInfo.Symbol() == m_symbol && positionInfo.Magic() == m_magic)
return true;
}
}
return false;
}
};
//+------------------------------------------------------------------+
//| Main Ultra-Fast Trading Bot |
//+------------------------------------------------------------------+
class CUltraFastTradingBot
{
private:
CMultiFactorAnalyzer *analyzer;
CLightningExecutor *executor;
UltraFastContext ctx;
datetime lastBarTime;
string m_symbol;
public:
CUltraFastTradingBot()
{
m_symbol = _Symbol;
analyzer = new CMultiFactorAnalyzer(m_symbol);
executor = new CLightningExecutor(m_symbol, MagicNumber);
lastBarTime = 0;
}
~CUltraFastTradingBot()
{
delete analyzer;
delete executor;
}
void OnTick()
{
// Update context
ctx.Reset();
ctx.bid = SymbolInfoDouble(m_symbol, SYMBOL_BID);
ctx.ask = SymbolInfoDouble(m_symbol, SYMBOL_ASK);
ctx.spread = (ctx.ask - ctx.bid) / SymbolInfoDouble(m_symbol, SYMBOL_POINT);
// Check if new bar
datetime currentBarTime = iTime(m_symbol, PERIOD_M1, 0);
if(currentBarTime != lastBarTime)
{
lastBarTime = currentBarTime;
analyzer.UpdateIndicators();
}
// Sub-second tick analysis
if(EnableSubSecondAnalysis)
{
analyzer.UpdateTick(ctx.bid);
ctx.tickCounter++;
}
// Pre-flight checks
if(!PerformPreflightChecks())
return;
// Multi-factor analysis
PerformMultiFactorAnalysis();
// Generate and execute signal
if(ctx.confluenceScore >= MinConfluenceScore && !executor.HasOpenPosition())
{
ExecuteSignal();
}
// Manage existing positions
executor.ManageTrailingStop(ctx.atrValue);
}
bool PerformPreflightChecks()
{
// Spread filter
if(FilterHighSpread && ctx.spread > MaxSpreadPips)
{
ctx.canTrade = false;
return false;
}
// Session filter
if(FilterSessionTimes && !IsValidSession())
{
ctx.canTrade = false;
return false;
}
// Tick confirmation
if(EnableSubSecondAnalysis && ctx.tickCounter < MinTicksBeforeTrade)
{
ctx.canTrade = false;
return false;
}
ctx.canTrade = true;
return true;
}
void PerformMultiFactorAnalysis()
{
// Factor 1: Trend
ctx.trendScore = analyzer.AnalyzeTrendStrength();
// Factor 2: Volatility
ctx.volatilityScore = analyzer.AnalyzeVolatility();
// Factor 3: Indicators
ctx.indicatorScore = analyzer.AnalyzeIndicatorConfluence();
// Factor 4: Patterns
ctx.patternScore = analyzer.AnalyzePatterns();
// Get ATR
ctx.atrValue = analyzer.GetATR();
// Calculate weighted confluence score
double trendComponent = (ctx.trendScore + 100) / 2.0 * TrendWeight / 100.0;
double volatilityComponent = ctx.volatilityScore * VolatilityWeight / 100.0;
double indicatorComponent = ctx.indicatorScore * IndicatorWeight / 100.0;
double patternComponent = (ctx.patternScore + 100) / 2.0 * PatternWeight / 100.0;
ctx.confluenceScore = trendComponent + volatilityComponent +
indicatorComponent + patternComponent;
// Determine direction
double directionScore = (ctx.trendScore + ctx.patternScore) / 2.0;
if(directionScore > 30)
ctx.regime = REGIME_STRONG_UPTREND;
else if(directionScore < -30)
ctx.regime = REGIME_STRONG_DOWNTREND;
else
ctx.regime = REGIME_RANGING;
}
void ExecuteSignal()
{
double lots = CalculatePositionSize();
// Calculate SL/TP
if(ctx.regime == REGIME_STRONG_UPTREND)
{
double sl = ctx.bid - (ctx.atrValue * StopLossATRMultiplier);
double tp = ctx.bid + (ctx.atrValue * TakeProfitATRMultiplier);
executor.ExecuteBuy(lots, sl, tp, TradeComment);
}
else if(ctx.regime == REGIME_STRONG_DOWNTREND)
{
double sl = ctx.ask + (ctx.atrValue * StopLossATRMultiplier);
double tp = ctx.ask - (ctx.atrValue * TakeProfitATRMultiplier);
executor.ExecuteSell(lots, sl, tp, TradeComment);
}
}
double CalculatePositionSize()
{
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double riskAmount = balance * RiskPercentPerTrade / 100.0;
double slDistance = ctx.atrValue * StopLossATRMultiplier;
double tickValue = SymbolInfoDouble(m_symbol, SYMBOL_TRADE_TICK_VALUE);
double tickSize = SymbolInfoDouble(m_symbol, SYMBOL_TRADE_TICK_SIZE);
double point = SymbolInfoDouble(m_symbol, SYMBOL_POINT);
double slValue = slDistance / tickSize * tickValue;
double lots = riskAmount / slValue;
// Normalize lot size
double minLot = SymbolInfoDouble(m_symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(m_symbol, SYMBOL_VOLUME_MAX);
double lotStep = SymbolInfoDouble(m_symbol, SYMBOL_VOLUME_STEP);
lots = MathFloor(lots / lotStep) * lotStep;
lots = MathMax(minLot, MathMin(maxLot, lots));
return lots;
}
bool IsValidSession()
{
MqlDateTime dt;
TimeToStruct(TimeCurrent(), dt);
int hour = dt.hour;
// London: 08:00-17:00 GMT
if(AllowLondonSession && hour >= 8 && hour < 17) return true;
// NY: 13:00-22:00 GMT
if(AllowNYSession && hour >= 13 && hour < 22) return true;
// Asian: 00:00-09:00 GMT
if(AllowAsianSession && hour >= 0 && hour < 9) return true;
return false;
}
};
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
CUltraFastTradingBot *bot;
int OnInit()
{
Print("========================================");
Print(" ULTRA-FAST AI GOLD TRADING SYSTEM");
Print(" Sub-Second Multi-Factor Analysis");
Print("========================================");
Print("Confluence Threshold: ", MinConfluenceScore, "%");
Print("Trend Weight: ", TrendWeight, "%");
Print("Volatility Weight: ", VolatilityWeight, "%");
Print("Indicator Weight: ", IndicatorWeight, "%");
Print("Pattern Weight: ", PatternWeight, "%");
Print("========================================");
bot = new CUltraFastTradingBot();
if(bot == NULL)
{
Print("ERROR: Failed to initialize bot");
return INIT_FAILED;
}
Print("Bot initialized successfully!");
Print("Waiting for trading signals...");
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
Print("========================================");
Print("EA Stopped. Reason: ", reason);
Print("========================================");
delete bot;
}
void OnTick()
{
bot.OnTick();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Dashboard_RiskManagement.mqh |
//| Real-Time Performance & Risk Analytics |
//+------------------------------------------------------------------+
#include <ChartObjects\ChartObjectsTxtControls.mqh>
//+------------------------------------------------------------------+
//| Performance Metrics Tracker |
//+------------------------------------------------------------------+
class CPerformanceTracker
{
private:
struct TradeRecord
{
datetime openTime;
datetime closeTime;
double openPrice;
double closePrice;
double profit;
double lots;
int type; // 0=Buy, 1=Sell
bool isWin;
};
TradeRecord history[];
int totalTrades;
int winningTrades;
int losingTrades;
double totalProfit;
double totalLoss;
double largestWin;
double largestLoss;
double currentDrawdown;
double maxDrawdown;
double initialBalance;
double currentBalance;
// Daily metrics
datetime currentDay;
double dailyProfit;
int dailyTrades;
public:
CPerformanceTracker()
{
Reset();
}
void Reset()
{
totalTrades = 0;
winningTrades = 0;
losingTrades = 0;
totalProfit = 0;
totalLoss = 0;
largestWin = 0;
largestLoss = 0;
currentDrawdown = 0;
maxDrawdown = 0;
initialBalance = AccountInfoDouble(ACCOUNT_BALANCE);
currentBalance = initialBalance;
dailyProfit = 0;
dailyTrades = 0;
currentDay = 0;
}
void RecordTrade(double openPrice, double closePrice, double profit, double lots, int type)
{
totalTrades++;
// Check if new day
datetime now = TimeCurrent();
MqlDateTime dt;
TimeToStruct(now, dt);
datetime today = StringToTime(IntegerToString(dt.year) + "." +
IntegerToString(dt.mon) + "." +
IntegerToString(dt.day));
if(today != currentDay)
{
currentDay = today;
dailyProfit = 0;
dailyTrades = 0;
}
dailyTrades++;
dailyProfit += profit;
// Record win/loss
if(profit > 0)
{
winningTrades++;
totalProfit += profit;
if(profit > largestWin) largestWin = profit;
}
else if(profit < 0)
{
losingTrades++;
totalLoss += MathAbs(profit);
if(MathAbs(profit) > largestLoss) largestLoss = MathAbs(profit);
}
// Update balance
currentBalance += profit;
// Calculate drawdown
if(currentBalance < initialBalance)
{
currentDrawdown = (initialBalance - currentBalance) / initialBalance * 100;
if(currentDrawdown > maxDrawdown)
maxDrawdown = currentDrawdown;
}
else
{
currentDrawdown = 0;
initialBalance = currentBalance; // New high watermark
}
}
double GetWinRate()
{
if(totalTrades == 0) return 0;
return (double)winningTrades / totalTrades * 100;
}
double GetProfitFactor()
{
if(totalLoss == 0) return totalProfit > 0 ? 999 : 0;
return totalProfit / totalLoss;
}
double GetAverageWin()
{
if(winningTrades == 0) return 0;
return totalProfit / winningTrades;
}
double GetAverageLoss()
{
if(losingTrades == 0) return 0;
return totalLoss / losingTrades;
}
double GetExpectancy()
{
if(totalTrades == 0) return 0;
return (totalProfit - totalLoss) / totalTrades;
}
double GetROI()
{
double startBalance = AccountInfoDouble(ACCOUNT_BALANCE) - (currentBalance - initialBalance);
if(startBalance == 0) return 0;
return (currentBalance - startBalance) / startBalance * 100;
}
// Getters
int GetTotalTrades() { return totalTrades; }
int GetWinningTrades() { return winningTrades; }
int GetLosingTrades() { return losingTrades; }
double GetTotalProfit() { return totalProfit; }
double GetTotalLoss() { return totalLoss; }
double GetLargestWin() { return largestWin; }
double GetLargestLoss() { return largestLoss; }
double GetMaxDrawdown() { return maxDrawdown; }
double GetCurrentDrawdown() { return currentDrawdown; }
double GetDailyProfit() { return dailyProfit; }
int GetDailyTrades() { return dailyTrades; }
};
//+------------------------------------------------------------------+
//| Advanced Risk Manager with Real-Time Monitoring |
//+------------------------------------------------------------------+
class CAdvancedRiskManager
{
private:
CPerformanceTracker *tracker;
// Risk limits
double maxDailyLossPercent;
double maxDrawdownPercent;
double maxPositionSize;
// Dynamic risk adjustment
bool useAdaptiveRisk;
double baseRiskPercent;
double currentRiskPercent;
// Circuit breaker
bool circuitBreakerActive;
datetime circuitBreakerUntil;
// Correlation monitor
double correlationThreshold;
public:
CAdvancedRiskManager(double dailyLoss, double maxDD, double baseRisk)
{
tracker = new CPerformanceTracker();
maxDailyLossPercent = dailyLoss;
maxDrawdownPercent = maxDD;
baseRiskPercent = baseRisk;
currentRiskPercent = baseRisk;
useAdaptiveRisk = true;
circuitBreakerActive = false;
}
~CAdvancedRiskManager()
{
delete tracker;
}
// Check if trading is allowed
bool CanTrade()
{
// Circuit breaker check
if(circuitBreakerActive)
{
if(TimeCurrent() < circuitBreakerUntil)
{
Print("CIRCUIT BREAKER ACTIVE - Trading suspended until ", circuitBreakerUntil);
return false;
}
else
{
circuitBreakerActive = false;
Print("Circuit breaker reset - Trading resumed");
}
}
// Daily loss limit
double dailyLoss = -tracker.GetDailyProfit();
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double dailyLossPercent = dailyLoss / balance * 100;
if(dailyLossPercent >= maxDailyLossPercent)
{
ActivateCircuitBreaker(24); // 24 hour suspension
Print("DAILY LOSS LIMIT REACHED: ", dailyLossPercent, "% - Circuit breaker activated");
return false;
}
// Drawdown limit
if(tracker.GetCurrentDrawdown() >= maxDrawdownPercent)
{
ActivateCircuitBreaker(48); // 48 hour suspension
Print("MAX DRAWDOWN REACHED: ", tracker.GetCurrentDrawdown(), "% - Circuit breaker activated");
return false;
}
// Consecutive loss protection
if(GetConsecutiveLosses() >= 5)
{
ActivateCircuitBreaker(6); // 6 hour cooldown
Print("5 CONSECUTIVE LOSSES - Cooling down for 6 hours");
return false;
}
return true;
}
void ActivateCircuitBreaker(int hours)
{
circuitBreakerActive = true;
circuitBreakerUntil = TimeCurrent() + hours * 3600;
}
// Adaptive risk calculation
double GetCurrentRiskPercent()
{
if(!useAdaptiveRisk)
return baseRiskPercent;
// Reduce risk after losses
double winRate = tracker.GetWinRate();
double profitFactor = tracker.GetProfitFactor();
currentRiskPercent = baseRiskPercent;
// Adjust based on performance
if(winRate < 40)
currentRiskPercent *= 0.5; // Reduce risk by 50%
else if(winRate > 60 && profitFactor > 1.5)
currentRiskPercent *= 1.2; // Increase risk by 20%
// Drawdown adjustment
double dd = tracker.GetCurrentDrawdown();
if(dd > 5)
currentRiskPercent *= (1 - dd / 100); // Scale down with drawdown
// Keep within bounds
currentRiskPercent = MathMax(0.25, MathMin(2.0, currentRiskPercent));
return currentRiskPercent;
}
int GetConsecutiveLosses()
{
// Check last 10 positions for consecutive losses
int consecutive = 0;
for(int i = HistoryDealsTotal() - 1; i >= HistoryDealsTotal() - 10 && i >= 0; i--)
{
ulong ticket = HistoryDealGetTicket(i);
if(ticket == 0) continue;
if(HistoryDealGetInteger(ticket, DEAL_ENTRY) == DEAL_ENTRY_OUT)
{
double profit = HistoryDealGetDouble(ticket, DEAL_PROFIT);
if(profit < 0)
consecutive++;
else
break;
}
}
return consecutive;
}
void RecordTrade(double openPrice, double closePrice, double profit, double lots, int type)
{
tracker.RecordTrade(openPrice, closePrice, profit, lots, type);
}
CPerformanceTracker* GetTracker() { return tracker; }
};
//+------------------------------------------------------------------+
//| Real-Time Dashboard Display |
//+------------------------------------------------------------------+
class CPerformanceDashboard
{
private:
CAdvancedRiskManager *riskManager;
// Chart objects
CChartObjectLabel lblTitle;
CChartObjectLabel lblStats[];
int windowIndex;
int xPosition;
int yPosition;
string prefix;
public:
CPerformanceDashboard(CAdvancedRiskManager *rm)
{
riskManager = rm;
prefix = "Dashboard_";
windowIndex = 0;
xPosition = 10;
yPosition = 20;
}
void Initialize()
{
// Create title
lblTitle.Create(0, prefix + "Title", windowIndex, xPosition, yPosition);
lblTitle.Description("═══ AI GOLD SYSTEM PERFORMANCE ═══");
lblTitle.Color(clrYellow);
lblTitle.FontSize(10);
// Create stat labels
ArrayResize(lblStats, 15);
string labels[] = {
"Total Trades:", "Win Rate:", "Profit Factor:",
"Total Profit:", "Max Drawdown:", "Daily P/L:",
"Avg Win:", "Avg Loss:", "Expectancy:",
"ROI:", "Risk Level:", "Status:",
"Largest Win:", "Largest Loss:", "Daily Trades:"
};
for(int i = 0; i < 15; i++)
{
lblStats[i].Create(0, prefix + "Stat" + IntegerToString(i),
windowIndex, xPosition, yPosition + 30 + (i * 18));
lblStats[i].Description(labels[i]);
lblStats[i].Color(clrWhite);
lblStats[i].FontSize(8);
}
}
void Update()
{
CPerformanceTracker *tracker = riskManager.GetTracker();
UpdateLabel(0, "Total Trades: " + IntegerToString(tracker.GetTotalTrades()));
UpdateLabel(1, "Win Rate: " + DoubleToString(tracker.GetWinRate(), 1) + "%",
tracker.GetWinRate() >= 50 ? clrLime : clrRed);
UpdateLabel(2, "Profit Factor: " + DoubleToString(tracker.GetProfitFactor(), 2),
tracker.GetProfitFactor() >= 1.5 ? clrLime : clrOrange);
UpdateLabel(3, "Total Profit: $" + DoubleToString(tracker.GetTotalProfit(), 2),
tracker.GetTotalProfit() > 0 ? clrLime : clrRed);
UpdateLabel(4, "Max DD: " + DoubleToString(tracker.GetMaxDrawdown(), 2) + "%",
tracker.GetMaxDrawdown() < 10 ? clrLime : clrRed);
UpdateLabel(5, "Daily P/L: $" + DoubleToString(tracker.GetDailyProfit(), 2),
tracker.GetDailyProfit() > 0 ? clrLime : clrRed);
UpdateLabel(6, "Avg Win: $" + DoubleToString(tracker.GetAverageWin(), 2));
UpdateLabel(7, "Avg Loss: $" + DoubleToString(tracker.GetAverageLoss(), 2));
UpdateLabel(8, "Expectancy: $" + DoubleToString(tracker.GetExpectancy(), 2),
tracker.GetExpectancy() > 0 ? clrLime : clrRed);
UpdateLabel(9, "ROI: " + DoubleToString(tracker.GetROI(), 2) + "%",
tracker.GetROI() > 0 ? clrLime : clrRed);
UpdateLabel(10, "Risk Level: " + DoubleToString(riskManager.GetCurrentRiskPercent(), 2) + "%");
UpdateLabel(11, riskManager.CanTrade() ? "Status: ACTIVE" : "Status: SUSPENDED",
riskManager.CanTrade() ? clrLime : clrRed);
UpdateLabel(12, "Largest Win: $" + DoubleToString(tracker.GetLargestWin(), 2));
UpdateLabel(13, "Largest Loss: $" + DoubleToString(tracker.GetLargestLoss(), 2));
UpdateLabel(14, "Daily Trades: " + IntegerToString(tracker.GetDailyTrades()));
}
void UpdateLabel(int index, string text, color clr = clrWhite)
{
if(index >= 0 && index < ArraySize(lblStats))
{
lblStats[index].Description(text);
lblStats[index].Color(clr);
}
}
void Destroy()
{
lblTitle.Delete();
for(int i = 0; i < ArraySize(lblStats); i++)
lblStats[i].Delete();
}
};
//+------------------------------------------------------------------+
//| Signal Quality Analyzer - Pre-Trade Validation |
//+------------------------------------------------------------------+
class CSignalQualityAnalyzer
{
private:
double qualityThreshold;
public:
CSignalQualityAnalyzer(double threshold = 70.0)
{
qualityThreshold = threshold;
}
// Comprehensive signal quality scoring (0-100)
double AnalyzeSignalQuality(double trendScore, double volatilityScore,
double indicatorScore, double patternScore,
double atr, double spread)
{
double quality = 0;
// 1. Trend alignment (30 points)
if(MathAbs(trendScore) > 70)
quality += 30;
else if(MathAbs(trendScore) > 40)
quality += 15;
// 2. Volatility appropriateness (20 points)
if(volatilityScore > 40 && volatilityScore < 80)
quality += 20; // Ideal volatility
else if(volatilityScore > 80)
quality += 5; // Too volatile
// 3. Indicator confluence (25 points)
quality += indicatorScore * 0.25;
// 4. Pattern strength (25 points)
if(MathAbs(patternScore) > 60)
quality += 25;
else if(MathAbs(patternScore) > 30)
quality += 12;
// 5. Spread penalty
if(spread > 20)
quality *= 0.8; // 20% penalty
return NormalizeDouble(quality, 2);
}
bool IsHighQualitySignal(double quality)
{
return quality >= qualityThreshold;
}
};
//+------------------------------------------------------------------+