763 lines
25 KiB
MQL5
763 lines
25 KiB
MQL5
|
//+------------------------------------------------------------------+
|
||
|
//| IndicatorEngine.mqh - Advanced Technical Indicator System |
|
||
|
//| Multi-timeframe Technical Analysis Engine |
|
||
|
//+------------------------------------------------------------------+
|
||
|
|
||
|
#ifndef INDICATOR_ENGINE_MQH
|
||
|
#define INDICATOR_ENGINE_MQH
|
||
|
|
||
|
enum ENUM_TRADE_SIGNAL
|
||
|
{
|
||
|
SIGNAL_NONE = 0,
|
||
|
SIGNAL_BUY = 1,
|
||
|
SIGNAL_SELL = 2,
|
||
|
SIGNAL_CLOSE_BUY = 3,
|
||
|
SIGNAL_CLOSE_SELL = 4,
|
||
|
SIGNAL_CLOSE_ALL = 5
|
||
|
};
|
||
|
|
||
|
enum ENUM_SIGNAL_STRENGTH
|
||
|
{
|
||
|
SIGNAL_WEAK = 1,
|
||
|
SIGNAL_MODERATE = 2,
|
||
|
SIGNAL_STRONG = 3,
|
||
|
SIGNAL_VERY_STRONG = 4
|
||
|
};
|
||
|
|
||
|
// Intelligence levels for AI analysis
|
||
|
enum ENUM_CONVICTION_LEVEL
|
||
|
{
|
||
|
CONVICTION_WEAK = 1,
|
||
|
CONVICTION_MODERATE = 2,
|
||
|
CONVICTION_STRONG = 3,
|
||
|
CONVICTION_VERY_STRONG = 4
|
||
|
};
|
||
|
|
||
|
// Market edge strength
|
||
|
enum ENUM_EDGE_STRENGTH
|
||
|
{
|
||
|
EDGE_NONE = 0,
|
||
|
EDGE_WEAK = 1,
|
||
|
EDGE_MODERATE = 2,
|
||
|
EDGE_STRONG = 3,
|
||
|
EDGE_VERY_STRONG = 4,
|
||
|
EDGE_VERY_WEAK = -1
|
||
|
};
|
||
|
|
||
|
// Smart trading intelligence structure
|
||
|
struct TradingIntelligence
|
||
|
{
|
||
|
ENUM_TRADE_SIGNAL signal;
|
||
|
ENUM_CONVICTION_LEVEL conviction;
|
||
|
string reason;
|
||
|
double risk_reward_ratio;
|
||
|
double probability_success;
|
||
|
double optimal_position_size;
|
||
|
string key_level;
|
||
|
string market_narrative;
|
||
|
};
|
||
|
|
||
|
// Market edge analysis
|
||
|
struct MarketEdge
|
||
|
{
|
||
|
ENUM_EDGE_STRENGTH strength;
|
||
|
double confidence;
|
||
|
string reason;
|
||
|
bool trend_alignment;
|
||
|
int supporting_timeframes;
|
||
|
};
|
||
|
|
||
|
// Risk scenario analysis
|
||
|
struct RiskScenario
|
||
|
{
|
||
|
double best_case_profit;
|
||
|
double base_case_profit;
|
||
|
double base_case_loss;
|
||
|
double worst_case_loss;
|
||
|
double max_account_risk;
|
||
|
string risk_level;
|
||
|
string exit_strategy;
|
||
|
};
|
||
|
|
||
|
enum ENUM_TREND_STATE
|
||
|
{
|
||
|
TREND_BULLISH,
|
||
|
TREND_BEARISH,
|
||
|
TREND_SIDEWAYS,
|
||
|
TREND_UNCERTAIN
|
||
|
};
|
||
|
|
||
|
struct IndicatorSignal
|
||
|
{
|
||
|
ENUM_TRADE_SIGNAL signal;
|
||
|
ENUM_SIGNAL_STRENGTH strength;
|
||
|
double confidence;
|
||
|
string reason;
|
||
|
datetime timestamp;
|
||
|
};
|
||
|
|
||
|
struct MarketStructure
|
||
|
{
|
||
|
ENUM_TREND_STATE trend;
|
||
|
double support;
|
||
|
double resistance;
|
||
|
double momentum;
|
||
|
double volatility;
|
||
|
bool breakout;
|
||
|
};
|
||
|
|
||
|
struct MultiTimeframeAnalysis
|
||
|
{
|
||
|
ENUM_TREND_STATE trendM1;
|
||
|
ENUM_TREND_STATE trendM5;
|
||
|
ENUM_TREND_STATE trendM15;
|
||
|
ENUM_TREND_STATE trendH1;
|
||
|
ENUM_TREND_STATE trendH4;
|
||
|
ENUM_TREND_STATE trendD1;
|
||
|
double overallBias;
|
||
|
bool alignment;
|
||
|
};
|
||
|
|
||
|
class CAdvancedIndicatorEngine
|
||
|
{
|
||
|
private:
|
||
|
string m_symbol;
|
||
|
ENUM_TIMEFRAMES m_timeframe;
|
||
|
|
||
|
// Indicator handles
|
||
|
int m_handleMA20;
|
||
|
int m_handleMA50;
|
||
|
int m_handleMA200;
|
||
|
int m_handleRSI;
|
||
|
int m_handleMACD;
|
||
|
int m_handleBB;
|
||
|
int m_handleStoch;
|
||
|
int m_handleATR;
|
||
|
int m_handleADX;
|
||
|
int m_handleCCI;
|
||
|
|
||
|
// Buffers
|
||
|
double m_ma20[];
|
||
|
double m_ma50[];
|
||
|
double m_ma200[];
|
||
|
double m_rsi[];
|
||
|
double m_macdMain[];
|
||
|
double m_macdSignal[];
|
||
|
double m_bbUpper[];
|
||
|
double m_bbLower[];
|
||
|
double m_bbMiddle[];
|
||
|
double m_stochMain[];
|
||
|
double m_stochSignal[];
|
||
|
double m_atr[];
|
||
|
double m_adx[];
|
||
|
double m_cci[];
|
||
|
|
||
|
// Analysis parameters
|
||
|
int m_lookbackPeriod;
|
||
|
double m_rsiOverbought;
|
||
|
double m_rsiOversold;
|
||
|
double m_stochOverbought;
|
||
|
double m_stochOversold;
|
||
|
|
||
|
public:
|
||
|
CAdvancedIndicatorEngine(void);
|
||
|
~CAdvancedIndicatorEngine(void);
|
||
|
|
||
|
// Initialization
|
||
|
bool Initialize(string symbol, ENUM_TIMEFRAMES timeframe);
|
||
|
void SetParameters(int lookback, double rsiOB, double rsiOS, double stochOB, double stochOS);
|
||
|
|
||
|
// Core Analysis
|
||
|
IndicatorSignal GetSignal(void);
|
||
|
MarketStructure GetMarketStructure(void);
|
||
|
MultiTimeframeAnalysis GetMultiTimeframeAnalysis(void);
|
||
|
|
||
|
// Individual Indicators
|
||
|
IndicatorSignal AnalyzeMovingAverages(void);
|
||
|
IndicatorSignal AnalyzeRSI(void);
|
||
|
IndicatorSignal AnalyzeMACD(void);
|
||
|
IndicatorSignal AnalyzeBollingerBands(void);
|
||
|
IndicatorSignal AnalyzeStochastic(void);
|
||
|
IndicatorSignal AnalyzeADX(void);
|
||
|
IndicatorSignal AnalyzeCCI(void);
|
||
|
|
||
|
// Support/Resistance
|
||
|
double FindSupport(int bars = 50);
|
||
|
double FindResistance(int bars = 50);
|
||
|
bool IsAtSupport(double price, double tolerance = 0.0005);
|
||
|
bool IsAtResistance(double price, double tolerance = 0.0005);
|
||
|
|
||
|
// Pattern Recognition
|
||
|
bool IsBullishEngulfing(void);
|
||
|
bool IsBearishEngulfing(void);
|
||
|
bool IsHammer(void);
|
||
|
bool IsDojiPattern(void);
|
||
|
|
||
|
// Trend Analysis
|
||
|
ENUM_TREND_STATE GetTrend(ENUM_TIMEFRAMES tf = PERIOD_CURRENT);
|
||
|
double GetTrendStrength(void);
|
||
|
bool IsTrendChanging(void);
|
||
|
|
||
|
// Volatility Analysis
|
||
|
double GetVolatility(void);
|
||
|
bool IsHighVolatility(void);
|
||
|
bool IsLowVolatility(void);
|
||
|
|
||
|
// Utility Methods
|
||
|
double GetCurrentPrice(void);
|
||
|
bool UpdateIndicators(void);
|
||
|
void PrintAnalysis(void);
|
||
|
string GetSignalDescription(IndicatorSignal signal);
|
||
|
};
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Constructor |
|
||
|
//+------------------------------------------------------------------+
|
||
|
CAdvancedIndicatorEngine::CAdvancedIndicatorEngine(void)
|
||
|
{
|
||
|
m_symbol = "";
|
||
|
m_timeframe = PERIOD_CURRENT;
|
||
|
m_lookbackPeriod = 14;
|
||
|
m_rsiOverbought = 70;
|
||
|
m_rsiOversold = 30;
|
||
|
m_stochOverbought = 80;
|
||
|
m_stochOversold = 20;
|
||
|
|
||
|
// Initialize handles
|
||
|
m_handleMA20 = INVALID_HANDLE;
|
||
|
m_handleMA50 = INVALID_HANDLE;
|
||
|
m_handleMA200 = INVALID_HANDLE;
|
||
|
m_handleRSI = INVALID_HANDLE;
|
||
|
m_handleMACD = INVALID_HANDLE;
|
||
|
m_handleBB = INVALID_HANDLE;
|
||
|
m_handleStoch = INVALID_HANDLE;
|
||
|
m_handleATR = INVALID_HANDLE;
|
||
|
m_handleADX = INVALID_HANDLE;
|
||
|
m_handleCCI = INVALID_HANDLE;
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Destructor |
|
||
|
//+------------------------------------------------------------------+
|
||
|
CAdvancedIndicatorEngine::~CAdvancedIndicatorEngine(void)
|
||
|
{
|
||
|
// Release indicator handles
|
||
|
if(m_handleMA20 != INVALID_HANDLE) IndicatorRelease(m_handleMA20);
|
||
|
if(m_handleMA50 != INVALID_HANDLE) IndicatorRelease(m_handleMA50);
|
||
|
if(m_handleMA200 != INVALID_HANDLE) IndicatorRelease(m_handleMA200);
|
||
|
if(m_handleRSI != INVALID_HANDLE) IndicatorRelease(m_handleRSI);
|
||
|
if(m_handleMACD != INVALID_HANDLE) IndicatorRelease(m_handleMACD);
|
||
|
if(m_handleBB != INVALID_HANDLE) IndicatorRelease(m_handleBB);
|
||
|
if(m_handleStoch != INVALID_HANDLE) IndicatorRelease(m_handleStoch);
|
||
|
if(m_handleATR != INVALID_HANDLE) IndicatorRelease(m_handleATR);
|
||
|
if(m_handleADX != INVALID_HANDLE) IndicatorRelease(m_handleADX);
|
||
|
if(m_handleCCI != INVALID_HANDLE) IndicatorRelease(m_handleCCI);
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Initialize indicator engine |
|
||
|
//+------------------------------------------------------------------+
|
||
|
bool CAdvancedIndicatorEngine::Initialize(string symbol, ENUM_TIMEFRAMES timeframe)
|
||
|
{
|
||
|
m_symbol = symbol;
|
||
|
m_timeframe = timeframe;
|
||
|
|
||
|
// Create indicator handles
|
||
|
m_handleMA20 = iMA(m_symbol, m_timeframe, 20, 0, MODE_SMA, PRICE_CLOSE);
|
||
|
m_handleMA50 = iMA(m_symbol, m_timeframe, 50, 0, MODE_SMA, PRICE_CLOSE);
|
||
|
m_handleMA200 = iMA(m_symbol, m_timeframe, 200, 0, MODE_SMA, PRICE_CLOSE);
|
||
|
m_handleRSI = iRSI(m_symbol, m_timeframe, m_lookbackPeriod, PRICE_CLOSE);
|
||
|
m_handleMACD = iMACD(m_symbol, m_timeframe, 12, 26, 9, PRICE_CLOSE);
|
||
|
m_handleBB = iBands(m_symbol, m_timeframe, 20, 0, 2.0, PRICE_CLOSE);
|
||
|
m_handleStoch = iStochastic(m_symbol, m_timeframe, 5, 3, 3, MODE_SMA, STO_LOWHIGH);
|
||
|
m_handleATR = iATR(m_symbol, m_timeframe, 14);
|
||
|
m_handleADX = iADX(m_symbol, m_timeframe, 14);
|
||
|
m_handleCCI = iCCI(m_symbol, m_timeframe, 14, PRICE_TYPICAL);
|
||
|
|
||
|
// Check if all handles are valid
|
||
|
bool allValid = (m_handleMA20 != INVALID_HANDLE && m_handleMA50 != INVALID_HANDLE &&
|
||
|
m_handleMA200 != INVALID_HANDLE && m_handleRSI != INVALID_HANDLE &&
|
||
|
m_handleMACD != INVALID_HANDLE && m_handleBB != INVALID_HANDLE &&
|
||
|
m_handleStoch != INVALID_HANDLE && m_handleATR != INVALID_HANDLE &&
|
||
|
m_handleADX != INVALID_HANDLE && m_handleCCI != INVALID_HANDLE);
|
||
|
|
||
|
if(!allValid)
|
||
|
{
|
||
|
Print("❌ Failed to initialize some indicators");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Initialize arrays
|
||
|
ArraySetAsSeries(m_ma20, true);
|
||
|
ArraySetAsSeries(m_ma50, true);
|
||
|
ArraySetAsSeries(m_ma200, true);
|
||
|
ArraySetAsSeries(m_rsi, true);
|
||
|
ArraySetAsSeries(m_macdMain, true);
|
||
|
ArraySetAsSeries(m_macdSignal, true);
|
||
|
ArraySetAsSeries(m_bbUpper, true);
|
||
|
ArraySetAsSeries(m_bbLower, true);
|
||
|
ArraySetAsSeries(m_bbMiddle, true);
|
||
|
ArraySetAsSeries(m_stochMain, true);
|
||
|
ArraySetAsSeries(m_stochSignal, true);
|
||
|
ArraySetAsSeries(m_atr, true);
|
||
|
ArraySetAsSeries(m_adx, true);
|
||
|
ArraySetAsSeries(m_cci, true);
|
||
|
|
||
|
Print("✅ Indicator Engine initialized for ", m_symbol, " ", EnumToString(m_timeframe));
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Update all indicators |
|
||
|
//+------------------------------------------------------------------+
|
||
|
bool CAdvancedIndicatorEngine::UpdateIndicators(void)
|
||
|
{
|
||
|
int copied = 0;
|
||
|
|
||
|
// Copy indicator data
|
||
|
copied += CopyBuffer(m_handleMA20, 0, 0, 3, m_ma20);
|
||
|
copied += CopyBuffer(m_handleMA50, 0, 0, 3, m_ma50);
|
||
|
copied += CopyBuffer(m_handleMA200, 0, 0, 3, m_ma200);
|
||
|
copied += CopyBuffer(m_handleRSI, 0, 0, 3, m_rsi);
|
||
|
copied += CopyBuffer(m_handleMACD, 0, 0, 3, m_macdMain);
|
||
|
copied += CopyBuffer(m_handleMACD, 1, 0, 3, m_macdSignal);
|
||
|
copied += CopyBuffer(m_handleBB, 1, 0, 3, m_bbUpper);
|
||
|
copied += CopyBuffer(m_handleBB, 2, 0, 3, m_bbLower);
|
||
|
copied += CopyBuffer(m_handleBB, 0, 0, 3, m_bbMiddle);
|
||
|
copied += CopyBuffer(m_handleStoch, 0, 0, 3, m_stochMain);
|
||
|
copied += CopyBuffer(m_handleStoch, 1, 0, 3, m_stochSignal);
|
||
|
copied += CopyBuffer(m_handleATR, 0, 0, 3, m_atr);
|
||
|
copied += CopyBuffer(m_handleADX, 0, 0, 3, m_adx);
|
||
|
copied += CopyBuffer(m_handleCCI, 0, 0, 3, m_cci);
|
||
|
|
||
|
return (copied > 30); // Should be 42 total (14 * 3)
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get main trading signal |
|
||
|
//+------------------------------------------------------------------+
|
||
|
IndicatorSignal CAdvancedIndicatorEngine::GetSignal(void)
|
||
|
{
|
||
|
IndicatorSignal signal;
|
||
|
signal.signal = SIGNAL_NONE;
|
||
|
signal.strength = SIGNAL_WEAK;
|
||
|
signal.confidence = 0;
|
||
|
signal.reason = "No clear signal";
|
||
|
signal.timestamp = TimeCurrent();
|
||
|
|
||
|
if(!UpdateIndicators()) return signal;
|
||
|
|
||
|
// Analyze individual indicators
|
||
|
IndicatorSignal maSignal = AnalyzeMovingAverages();
|
||
|
IndicatorSignal rsiSignal = AnalyzeRSI();
|
||
|
IndicatorSignal macdSignal = AnalyzeMACD();
|
||
|
IndicatorSignal bbSignal = AnalyzeBollingerBands();
|
||
|
IndicatorSignal stochSignal = AnalyzeStochastic();
|
||
|
IndicatorSignal adxSignal = AnalyzeADX();
|
||
|
|
||
|
// Score system
|
||
|
int buyScore = 0;
|
||
|
int sellScore = 0;
|
||
|
double totalConfidence = 0;
|
||
|
string reasons = "";
|
||
|
|
||
|
// Weight the signals based on reliability
|
||
|
if(maSignal.signal == SIGNAL_BUY) buyScore += 2;
|
||
|
else if(maSignal.signal == SIGNAL_SELL) sellScore += 2;
|
||
|
|
||
|
if(rsiSignal.signal == SIGNAL_BUY) buyScore += 1;
|
||
|
else if(rsiSignal.signal == SIGNAL_SELL) sellScore += 1;
|
||
|
|
||
|
if(macdSignal.signal == SIGNAL_BUY) buyScore += 2;
|
||
|
else if(macdSignal.signal == SIGNAL_SELL) sellScore += 2;
|
||
|
|
||
|
if(bbSignal.signal == SIGNAL_BUY) buyScore += 1;
|
||
|
else if(bbSignal.signal == SIGNAL_SELL) sellScore += 1;
|
||
|
|
||
|
if(stochSignal.signal == SIGNAL_BUY) buyScore += 1;
|
||
|
else if(stochSignal.signal == SIGNAL_SELL) sellScore += 1;
|
||
|
|
||
|
// Calculate confidence
|
||
|
totalConfidence = (maSignal.confidence + rsiSignal.confidence + macdSignal.confidence +
|
||
|
bbSignal.confidence + stochSignal.confidence + adxSignal.confidence) / 6.0;
|
||
|
|
||
|
// Determine final signal
|
||
|
if(buyScore > sellScore && buyScore >= 3)
|
||
|
{
|
||
|
signal.signal = SIGNAL_BUY;
|
||
|
signal.confidence = totalConfidence;
|
||
|
signal.reason = "Multiple bullish indicators aligned";
|
||
|
|
||
|
if(buyScore >= 5) signal.strength = SIGNAL_VERY_STRONG;
|
||
|
else if(buyScore >= 4) signal.strength = SIGNAL_STRONG;
|
||
|
else signal.strength = SIGNAL_MODERATE;
|
||
|
}
|
||
|
else if(sellScore > buyScore && sellScore >= 3)
|
||
|
{
|
||
|
signal.signal = SIGNAL_SELL;
|
||
|
signal.confidence = totalConfidence;
|
||
|
signal.reason = "Multiple bearish indicators aligned";
|
||
|
|
||
|
if(sellScore >= 5) signal.strength = SIGNAL_VERY_STRONG;
|
||
|
else if(sellScore >= 4) signal.strength = SIGNAL_STRONG;
|
||
|
else signal.strength = SIGNAL_MODERATE;
|
||
|
}
|
||
|
|
||
|
return signal;
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Analyze Moving Averages |
|
||
|
//+------------------------------------------------------------------+
|
||
|
IndicatorSignal CAdvancedIndicatorEngine::AnalyzeMovingAverages(void)
|
||
|
{
|
||
|
IndicatorSignal signal;
|
||
|
signal.signal = SIGNAL_NONE;
|
||
|
signal.strength = SIGNAL_WEAK;
|
||
|
signal.confidence = 0;
|
||
|
signal.timestamp = TimeCurrent();
|
||
|
|
||
|
if(ArraySize(m_ma20) < 2 || ArraySize(m_ma50) < 2) return signal;
|
||
|
|
||
|
double currentPrice = GetCurrentPrice();
|
||
|
|
||
|
// Golden Cross / Death Cross
|
||
|
bool goldenCross = (m_ma20[0] > m_ma50[0] && m_ma20[1] <= m_ma50[1]);
|
||
|
bool deathCross = (m_ma20[0] < m_ma50[0] && m_ma20[1] >= m_ma50[1]);
|
||
|
|
||
|
// Price relative to MAs
|
||
|
bool priceAboveMA20 = currentPrice > m_ma20[0];
|
||
|
bool priceAboveMA50 = currentPrice > m_ma50[0];
|
||
|
bool ma20AboveMA50 = m_ma20[0] > m_ma50[0];
|
||
|
|
||
|
if(goldenCross || (priceAboveMA20 && priceAboveMA50 && ma20AboveMA50))
|
||
|
{
|
||
|
signal.signal = SIGNAL_BUY;
|
||
|
signal.confidence = goldenCross ? 0.8 : 0.6;
|
||
|
signal.strength = goldenCross ? SIGNAL_STRONG : SIGNAL_MODERATE;
|
||
|
signal.reason = goldenCross ? "Golden Cross detected" : "Price above MAs, bullish alignment";
|
||
|
}
|
||
|
else if(deathCross || (!priceAboveMA20 && !priceAboveMA50 && !ma20AboveMA50))
|
||
|
{
|
||
|
signal.signal = SIGNAL_SELL;
|
||
|
signal.confidence = deathCross ? 0.8 : 0.6;
|
||
|
signal.strength = deathCross ? SIGNAL_STRONG : SIGNAL_MODERATE;
|
||
|
signal.reason = deathCross ? "Death Cross detected" : "Price below MAs, bearish alignment";
|
||
|
}
|
||
|
|
||
|
return signal;
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Analyze RSI |
|
||
|
//+------------------------------------------------------------------+
|
||
|
IndicatorSignal CAdvancedIndicatorEngine::AnalyzeRSI(void)
|
||
|
{
|
||
|
IndicatorSignal signal;
|
||
|
signal.signal = SIGNAL_NONE;
|
||
|
signal.strength = SIGNAL_WEAK;
|
||
|
signal.confidence = 0;
|
||
|
signal.timestamp = TimeCurrent();
|
||
|
|
||
|
if(ArraySize(m_rsi) < 2) return signal;
|
||
|
|
||
|
double currentRSI = m_rsi[0];
|
||
|
double previousRSI = m_rsi[1];
|
||
|
|
||
|
// RSI Divergence and Oversold/Overbought
|
||
|
if(currentRSI <= m_rsiOversold && previousRSI > currentRSI)
|
||
|
{
|
||
|
signal.signal = SIGNAL_BUY;
|
||
|
signal.confidence = 0.7;
|
||
|
signal.strength = SIGNAL_MODERATE;
|
||
|
signal.reason = "RSI oversold condition";
|
||
|
}
|
||
|
else if(currentRSI >= m_rsiOverbought && previousRSI < currentRSI)
|
||
|
{
|
||
|
signal.signal = SIGNAL_SELL;
|
||
|
signal.confidence = 0.7;
|
||
|
signal.strength = SIGNAL_MODERATE;
|
||
|
signal.reason = "RSI overbought condition";
|
||
|
}
|
||
|
else if(currentRSI > 50 && previousRSI <= 50)
|
||
|
{
|
||
|
signal.signal = SIGNAL_BUY;
|
||
|
signal.confidence = 0.5;
|
||
|
signal.strength = SIGNAL_WEAK;
|
||
|
signal.reason = "RSI bullish momentum";
|
||
|
}
|
||
|
else if(currentRSI < 50 && previousRSI >= 50)
|
||
|
{
|
||
|
signal.signal = SIGNAL_SELL;
|
||
|
signal.confidence = 0.5;
|
||
|
signal.strength = SIGNAL_WEAK;
|
||
|
signal.reason = "RSI bearish momentum";
|
||
|
}
|
||
|
|
||
|
return signal;
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Analyze MACD |
|
||
|
//+------------------------------------------------------------------+
|
||
|
IndicatorSignal CAdvancedIndicatorEngine::AnalyzeMACD(void)
|
||
|
{
|
||
|
IndicatorSignal signal;
|
||
|
signal.signal = SIGNAL_NONE;
|
||
|
signal.strength = SIGNAL_WEAK;
|
||
|
signal.confidence = 0;
|
||
|
signal.timestamp = TimeCurrent();
|
||
|
|
||
|
if(ArraySize(m_macdMain) < 2 || ArraySize(m_macdSignal) < 2) return signal;
|
||
|
|
||
|
double currentMACD = m_macdMain[0];
|
||
|
double currentSignal = m_macdSignal[0];
|
||
|
double previousMACD = m_macdMain[1];
|
||
|
double previousSignal = m_macdSignal[1];
|
||
|
|
||
|
// MACD Signal Line Crossover
|
||
|
bool bullishCrossover = (currentMACD > currentSignal && previousMACD <= previousSignal);
|
||
|
bool bearishCrossover = (currentMACD < currentSignal && previousMACD >= previousSignal);
|
||
|
|
||
|
// MACD Zero Line Cross
|
||
|
bool bullishZeroCross = (currentMACD > 0 && previousMACD <= 0);
|
||
|
bool bearishZeroCross = (currentMACD < 0 && previousMACD >= 0);
|
||
|
|
||
|
if(bullishCrossover || bullishZeroCross)
|
||
|
{
|
||
|
signal.signal = SIGNAL_BUY;
|
||
|
signal.confidence = bullishZeroCross ? 0.8 : 0.7;
|
||
|
signal.strength = bullishZeroCross ? SIGNAL_STRONG : SIGNAL_MODERATE;
|
||
|
signal.reason = bullishZeroCross ? "MACD bullish zero cross" : "MACD bullish crossover";
|
||
|
}
|
||
|
else if(bearishCrossover || bearishZeroCross)
|
||
|
{
|
||
|
signal.signal = SIGNAL_SELL;
|
||
|
signal.confidence = bearishZeroCross ? 0.8 : 0.7;
|
||
|
signal.strength = bearishZeroCross ? SIGNAL_STRONG : SIGNAL_MODERATE;
|
||
|
signal.reason = bearishZeroCross ? "MACD bearish zero cross" : "MACD bearish crossover";
|
||
|
}
|
||
|
|
||
|
return signal;
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Analyze Bollinger Bands |
|
||
|
//+------------------------------------------------------------------+
|
||
|
IndicatorSignal CAdvancedIndicatorEngine::AnalyzeBollingerBands(void)
|
||
|
{
|
||
|
IndicatorSignal signal;
|
||
|
signal.signal = SIGNAL_NONE;
|
||
|
signal.strength = SIGNAL_WEAK;
|
||
|
signal.confidence = 0;
|
||
|
signal.timestamp = TimeCurrent();
|
||
|
|
||
|
if(ArraySize(m_bbUpper) < 1 || ArraySize(m_bbLower) < 1) return signal;
|
||
|
|
||
|
double currentPrice = GetCurrentPrice();
|
||
|
double upperBand = m_bbUpper[0];
|
||
|
double lowerBand = m_bbLower[0];
|
||
|
double middleBand = m_bbMiddle[0];
|
||
|
|
||
|
// BB Squeeze and Breakouts
|
||
|
double bandWidth = (upperBand - lowerBand) / middleBand;
|
||
|
|
||
|
if(currentPrice <= lowerBand)
|
||
|
{
|
||
|
signal.signal = SIGNAL_BUY;
|
||
|
signal.confidence = 0.6;
|
||
|
signal.strength = SIGNAL_MODERATE;
|
||
|
signal.reason = "Price at BB lower band (oversold)";
|
||
|
}
|
||
|
else if(currentPrice >= upperBand)
|
||
|
{
|
||
|
signal.signal = SIGNAL_SELL;
|
||
|
signal.confidence = 0.6;
|
||
|
signal.strength = SIGNAL_MODERATE;
|
||
|
signal.reason = "Price at BB upper band (overbought)";
|
||
|
}
|
||
|
else if(currentPrice > middleBand)
|
||
|
{
|
||
|
signal.signal = SIGNAL_BUY;
|
||
|
signal.confidence = 0.4;
|
||
|
signal.strength = SIGNAL_WEAK;
|
||
|
signal.reason = "Price above BB middle line";
|
||
|
}
|
||
|
else if(currentPrice < middleBand)
|
||
|
{
|
||
|
signal.signal = SIGNAL_SELL;
|
||
|
signal.confidence = 0.4;
|
||
|
signal.strength = SIGNAL_WEAK;
|
||
|
signal.reason = "Price below BB middle line";
|
||
|
}
|
||
|
|
||
|
return signal;
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Analyze Stochastic |
|
||
|
//+------------------------------------------------------------------+
|
||
|
IndicatorSignal CAdvancedIndicatorEngine::AnalyzeStochastic(void)
|
||
|
{
|
||
|
IndicatorSignal signal;
|
||
|
signal.signal = SIGNAL_NONE;
|
||
|
signal.strength = SIGNAL_WEAK;
|
||
|
signal.confidence = 0;
|
||
|
signal.timestamp = TimeCurrent();
|
||
|
|
||
|
if(ArraySize(m_stochMain) < 2 || ArraySize(m_stochSignal) < 2) return signal;
|
||
|
|
||
|
double currentK = m_stochMain[0];
|
||
|
double currentD = m_stochSignal[0];
|
||
|
double previousK = m_stochMain[1];
|
||
|
double previousD = m_stochSignal[1];
|
||
|
|
||
|
// Stochastic Crossover
|
||
|
bool bullishCross = (currentK > currentD && previousK <= previousD);
|
||
|
bool bearishCross = (currentK < currentD && previousK >= previousD);
|
||
|
|
||
|
if(bullishCross && currentK < m_stochOversold)
|
||
|
{
|
||
|
signal.signal = SIGNAL_BUY;
|
||
|
signal.confidence = 0.7;
|
||
|
signal.strength = SIGNAL_MODERATE;
|
||
|
signal.reason = "Stochastic bullish crossover in oversold";
|
||
|
}
|
||
|
else if(bearishCross && currentK > m_stochOverbought)
|
||
|
{
|
||
|
signal.signal = SIGNAL_SELL;
|
||
|
signal.confidence = 0.7;
|
||
|
signal.strength = SIGNAL_MODERATE;
|
||
|
signal.reason = "Stochastic bearish crossover in overbought";
|
||
|
}
|
||
|
|
||
|
return signal;
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Analyze ADX |
|
||
|
//+------------------------------------------------------------------+
|
||
|
IndicatorSignal CAdvancedIndicatorEngine::AnalyzeADX(void)
|
||
|
{
|
||
|
IndicatorSignal signal;
|
||
|
signal.signal = SIGNAL_NONE;
|
||
|
signal.strength = SIGNAL_WEAK;
|
||
|
signal.confidence = 0;
|
||
|
signal.timestamp = TimeCurrent();
|
||
|
|
||
|
if(ArraySize(m_adx) < 1) return signal;
|
||
|
|
||
|
double currentADX = m_adx[0];
|
||
|
|
||
|
// ADX indicates trend strength, not direction
|
||
|
if(currentADX > 25)
|
||
|
{
|
||
|
signal.confidence = 0.8; // Strong trend
|
||
|
signal.reason = "Strong trend detected (ADX > 25)";
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
signal.confidence = 0.3; // Weak trend
|
||
|
signal.reason = "Weak trend (ADX < 25)";
|
||
|
}
|
||
|
|
||
|
return signal;
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get current price |
|
||
|
//+------------------------------------------------------------------+
|
||
|
double CAdvancedIndicatorEngine::GetCurrentPrice(void)
|
||
|
{
|
||
|
return SymbolInfoDouble(m_symbol, SYMBOL_BID);
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get market structure |
|
||
|
//+------------------------------------------------------------------+
|
||
|
MarketStructure CAdvancedIndicatorEngine::GetMarketStructure(void)
|
||
|
{
|
||
|
MarketStructure structure;
|
||
|
|
||
|
structure.trend = GetTrend();
|
||
|
structure.support = FindSupport();
|
||
|
structure.resistance = FindResistance();
|
||
|
structure.momentum = ArraySize(m_rsi) > 0 ? m_rsi[0] : 50;
|
||
|
structure.volatility = GetVolatility();
|
||
|
|
||
|
double currentPrice = GetCurrentPrice();
|
||
|
structure.breakout = (currentPrice > structure.resistance || currentPrice < structure.support);
|
||
|
|
||
|
return structure;
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get trend for timeframe |
|
||
|
//+------------------------------------------------------------------+
|
||
|
ENUM_TREND_STATE CAdvancedIndicatorEngine::GetTrend(ENUM_TIMEFRAMES tf = PERIOD_CURRENT)
|
||
|
{
|
||
|
if(tf == PERIOD_CURRENT) tf = m_timeframe;
|
||
|
|
||
|
if(!UpdateIndicators()) return TREND_UNCERTAIN;
|
||
|
|
||
|
if(ArraySize(m_ma20) < 1 || ArraySize(m_ma50) < 1) return TREND_UNCERTAIN;
|
||
|
|
||
|
double currentPrice = GetCurrentPrice();
|
||
|
|
||
|
if(currentPrice > m_ma20[0] && m_ma20[0] > m_ma50[0])
|
||
|
return TREND_BULLISH;
|
||
|
else if(currentPrice < m_ma20[0] && m_ma20[0] < m_ma50[0])
|
||
|
return TREND_BEARISH;
|
||
|
else
|
||
|
return TREND_SIDEWAYS;
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Find support level |
|
||
|
//+------------------------------------------------------------------+
|
||
|
double CAdvancedIndicatorEngine::FindSupport(int bars = 50)
|
||
|
{
|
||
|
double lowest = iLow(m_symbol, m_timeframe, iLowest(m_symbol, m_timeframe, MODE_LOW, bars, 0));
|
||
|
return lowest;
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Find resistance level |
|
||
|
//+------------------------------------------------------------------+
|
||
|
double CAdvancedIndicatorEngine::FindResistance(int bars = 50)
|
||
|
{
|
||
|
double highest = iHigh(m_symbol, m_timeframe, iHighest(m_symbol, m_timeframe, MODE_HIGH, bars, 0));
|
||
|
return highest;
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Get volatility |
|
||
|
//+------------------------------------------------------------------+
|
||
|
double CAdvancedIndicatorEngine::GetVolatility(void)
|
||
|
{
|
||
|
if(ArraySize(m_atr) > 0)
|
||
|
return m_atr[0];
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Print analysis report |
|
||
|
//+------------------------------------------------------------------+
|
||
|
void CAdvancedIndicatorEngine::PrintAnalysis(void)
|
||
|
{
|
||
|
IndicatorSignal signal = GetSignal();
|
||
|
MarketStructure structure = GetMarketStructure();
|
||
|
|
||
|
Print("=== TECHNICAL ANALYSIS REPORT ===");
|
||
|
Print("Signal: ", EnumToString(signal.signal));
|
||
|
Print("Strength: ", EnumToString(signal.strength));
|
||
|
Print("Confidence: ", DoubleToString(signal.confidence * 100, 1), "%");
|
||
|
Print("Reason: ", signal.reason);
|
||
|
Print("Trend: ", EnumToString(structure.trend));
|
||
|
Print("Support: ", DoubleToString(structure.support, 5));
|
||
|
Print("Resistance: ", DoubleToString(structure.resistance, 5));
|
||
|
Print("Volatility: ", DoubleToString(structure.volatility, 5));
|
||
|
Print("===============================");
|
||
|
}
|
||
|
|
||
|
#endif // INDICATOR_ENGINE_MQH
|