Files
MyProEA/Include/Strategy.mqh
T
2026-05-28 19:09:09 -04:00

246 lines
7.3 KiB
Plaintext

//+------------------------------------------------------------------+
//| Strategy.mqh - XAUUSD M15 EMA Pullback Continuation Strategy |
//| Trend direction on H1, pullback on M15, RSI and ATR confirmation |
//+------------------------------------------------------------------+
#ifndef __STRATEGY_MQH__
#define __STRATEGY_MQH__
#include "Signal.mqh"
#include "MarketData.mqh"
#include "Logger.mqh"
#include "Config.mqh"
#include "Utilities.mqh"
class CStrategy
{
private:
// Indicator handles
int m_ema_h1_fast_handle;
int m_ema_h1_slow_handle;
int m_ema_m15_fast_handle;
int m_rsi_m15_handle;
int m_atr_m15_handle;
// References
CMarketData *mp_market_data;
CLogger *mp_logger;
// Timeframes
ENUM_TIMEFRAMES m_entry_timeframe;
ENUM_TIMEFRAMES m_trend_timeframe;
// Parameters
int m_trend_fast_ema_period;
int m_trend_slow_ema_period;
int m_entry_fast_ema_period;
int m_entry_pullback_ema_period;
int m_rsi_period;
int m_rsi_buy_threshold;
int m_rsi_sell_threshold;
int m_atr_period;
double m_last_atr_value;
bool m_use_atr_stops;
double m_atr_sl_multiplier;
double m_atr_tp_multiplier;
public:
// Constructor
CStrategy(CMarketData *market_data, CLogger *logger)
{
mp_market_data = market_data;
mp_logger = logger;
m_ema_h1_fast_handle = INVALID_HANDLE;
m_ema_h1_slow_handle = INVALID_HANDLE;
m_ema_m15_fast_handle = INVALID_HANDLE;
m_rsi_m15_handle = INVALID_HANDLE;
m_atr_m15_handle = INVALID_HANDLE;
m_last_atr_value = 0.0;
m_entry_timeframe = g_strategy_entry_timeframe;
m_trend_timeframe = g_strategy_trend_timeframe;
m_trend_fast_ema_period = g_trend_fast_ema_period;
m_trend_slow_ema_period = g_trend_slow_ema_period;
m_entry_fast_ema_period = g_entry_fast_ema_period;
m_entry_pullback_ema_period = g_entry_pullback_ema_period;
m_rsi_period = g_rsi_period;
m_rsi_buy_threshold = g_rsi_buy_threshold;
m_rsi_sell_threshold = g_rsi_sell_threshold;
m_atr_period = g_atr_period;
m_use_atr_stops = g_use_atr_stops;
m_atr_sl_multiplier = g_atr_sl_multiplier;
m_atr_tp_multiplier = g_atr_tp_multiplier;
}
// Destructor - clean up indicator handles
~CStrategy()
{
Cleanup();
}
// Initialize strategy and create indicator handles
bool Init()
{
const string symbol = mp_market_data.GetSymbol();
m_ema_h1_fast_handle = iMA(symbol, m_trend_timeframe,
m_trend_fast_ema_period, 0, MODE_EMA, PRICE_CLOSE);
if(m_ema_h1_fast_handle == INVALID_HANDLE)
{
if(mp_logger)
mp_logger.Error("Failed to create H1 EMA fast indicator");
return false;
}
m_ema_h1_slow_handle = iMA(symbol, m_trend_timeframe,
m_trend_slow_ema_period, 0, MODE_EMA, PRICE_CLOSE);
if(m_ema_h1_slow_handle == INVALID_HANDLE)
{
if(mp_logger)
mp_logger.Error("Failed to create H1 EMA slow indicator");
IndicatorRelease(m_ema_h1_fast_handle);
m_ema_h1_fast_handle = INVALID_HANDLE;
return false;
}
m_ema_m15_fast_handle = iMA(symbol, m_entry_timeframe,
m_entry_fast_ema_period, 0, MODE_EMA, PRICE_CLOSE);
if(m_ema_m15_fast_handle == INVALID_HANDLE)
{
if(mp_logger)
mp_logger.Error("Failed to create M15 EMA fast indicator");
IndicatorRelease(m_ema_h1_fast_handle);
m_ema_h1_fast_handle = INVALID_HANDLE;
IndicatorRelease(m_ema_h1_slow_handle);
m_ema_h1_slow_handle = INVALID_HANDLE;
return false;
}
m_rsi_m15_handle = iRSI(symbol, m_entry_timeframe, m_rsi_period, PRICE_CLOSE);
if(m_rsi_m15_handle == INVALID_HANDLE)
{
if(mp_logger)
mp_logger.Error("Failed to create M15 RSI indicator");
ReleaseAllHandles();
return false;
}
m_atr_m15_handle = iATR(symbol, m_entry_timeframe, m_atr_period);
if(m_atr_m15_handle == INVALID_HANDLE)
{
if(mp_logger)
mp_logger.Error("Failed to create M15 ATR indicator");
ReleaseAllHandles();
return false;
}
if(mp_logger)
mp_logger.Info("Strategy (M15 EMA Pullback Continuation) initialized successfully");
return true;
}
// Generate trading signal based on H1 trend and M15 pullback continuation
E_SIGNAL GetSignal()
{
const string symbol = mp_market_data.GetSymbol();
double ema_h1_fast = iGetIndicatorValue(m_ema_h1_fast_handle, 1);
double ema_h1_slow = iGetIndicatorValue(m_ema_h1_slow_handle, 1);
if(ema_h1_fast == 0.0 || ema_h1_slow == 0.0)
return SIGNAL_NONE;
double ema_m15_fast_last = iGetIndicatorValue(m_ema_m15_fast_handle, 1);
if(ema_m15_fast_last == 0.0)
return SIGNAL_NONE;
double close_last = iClose(symbol, m_entry_timeframe, 1);
double open_last = iOpen(symbol, m_entry_timeframe, 1);
if(close_last <= 0.0 || open_last <= 0.0)
return SIGNAL_NONE;
if(ema_h1_fast > ema_h1_slow)
{
bool entry_condition = (close_last > ema_m15_fast_last && close_last > open_last);
if(entry_condition)
{
if(mp_logger && g_debug_mode)
mp_logger.Info(StringFormat("BUY Signal: H1 EMA50=%.5f > EMA200=%.5f, M15 close=%.5f > EMA20=%.5f",
ema_h1_fast, ema_h1_slow, close_last, ema_m15_fast_last));
return SIGNAL_BUY;
}
}
else if(ema_h1_fast < ema_h1_slow)
{
bool entry_condition = (close_last < ema_m15_fast_last && close_last < open_last);
if(entry_condition)
{
if(mp_logger && g_debug_mode)
mp_logger.Info(StringFormat("SELL Signal: H1 EMA50=%.5f < EMA200=%.5f, M15 close=%.5f < EMA20=%.5f",
ema_h1_fast, ema_h1_slow, close_last, ema_m15_fast_last));
return SIGNAL_SELL;
}
}
return SIGNAL_NONE;
}
double GetLastAtrValue() const
{
return m_last_atr_value;
}
void Cleanup()
{
ReleaseAllHandles();
}
private:
void ReleaseAllHandles()
{
if(m_ema_h1_fast_handle != INVALID_HANDLE)
{
IndicatorRelease(m_ema_h1_fast_handle);
m_ema_h1_fast_handle = INVALID_HANDLE;
}
if(m_ema_h1_slow_handle != INVALID_HANDLE)
{
IndicatorRelease(m_ema_h1_slow_handle);
m_ema_h1_slow_handle = INVALID_HANDLE;
}
if(m_ema_m15_fast_handle != INVALID_HANDLE)
{
IndicatorRelease(m_ema_m15_fast_handle);
m_ema_m15_fast_handle = INVALID_HANDLE;
}
if(m_rsi_m15_handle != INVALID_HANDLE)
{
IndicatorRelease(m_rsi_m15_handle);
m_rsi_m15_handle = INVALID_HANDLE;
}
if(m_atr_m15_handle != INVALID_HANDLE)
{
IndicatorRelease(m_atr_m15_handle);
m_atr_m15_handle = INVALID_HANDLE;
}
}
double iGetIndicatorValue(int handle, int shift)
{
if(handle == INVALID_HANDLE)
return 0.0;
double value[1];
ArraySetAsSeries(value, true);
if(CopyBuffer(handle, 0, shift, 1, value) <= 0)
return 0.0;
return value[0];
}
};
#endif //__STRATEGY_MQH__