Files
MyProEA/Include/Strategy.mqh
T
2026-05-28 17:34:34 -04:00

157 lines
4.1 KiB
Plaintext

//+------------------------------------------------------------------+
//| Strategy.mqh - Trading strategy implementation |
//| Simple MA crossover: Buy when Fast MA > Slow MA, Sell opposite |
//+------------------------------------------------------------------+
#ifndef __STRATEGY_MQH__
#define __STRATEGY_MQH__
#include "Signal.mqh"
#include "MarketData.mqh"
#include "Logger.mqh"
#include "Config.mqh"
class CStrategy
{
private:
int m_ma_fast_handle;
int m_ma_slow_handle;
CMarketData *mp_market_data;
CLogger *mp_logger;
int m_fast_period;
int m_slow_period;
int m_ma_shift;
ENUM_MA_METHOD m_ma_method;
ENUM_APPLIED_PRICE m_ma_price;
public:
// Constructor
CStrategy(CMarketData *market_data, CLogger *logger)
{
mp_market_data = market_data;
mp_logger = logger;
m_fast_period = g_ma_fast_period;
m_slow_period = g_ma_slow_period;
m_ma_shift = g_ma_shift;
m_ma_method = g_ma_method;
m_ma_price = g_ma_price;
m_ma_fast_handle = INVALID_HANDLE;
m_ma_slow_handle = INVALID_HANDLE;
}
// Destructor - clean up indicator handles
~CStrategy()
{
Cleanup();
}
// Initialize strategy and create indicator handles
bool Init()
{
// Create fast MA handle
m_ma_fast_handle = iMA(mp_market_data.GetSymbol(), PERIOD_CURRENT,
m_fast_period, m_ma_shift, m_ma_method, m_ma_price);
if(m_ma_fast_handle == INVALID_HANDLE)
{
if(mp_logger)
mp_logger.Error("Failed to create Fast MA indicator");
return false;
}
// Create slow MA handle
m_ma_slow_handle = iMA(mp_market_data.GetSymbol(), PERIOD_CURRENT,
m_slow_period, m_ma_shift, m_ma_method, m_ma_price);
if(m_ma_slow_handle == INVALID_HANDLE)
{
if(m_ma_fast_handle != INVALID_HANDLE)
{
IndicatorRelease(m_ma_fast_handle);
m_ma_fast_handle = INVALID_HANDLE;
}
if(mp_logger)
mp_logger.Error("Failed to create Slow MA indicator");
return false;
}
if(mp_logger)
mp_logger.Info("Strategy initialized successfully");
return true;
}
// Generate trading signal
E_SIGNAL GetSignal()
{
if(m_ma_fast_handle == INVALID_HANDLE || m_ma_slow_handle == INVALID_HANDLE)
return SIGNAL_NONE;
double ma_fast = iGetMainValue(m_ma_fast_handle, 0);
double ma_slow = iGetMainValue(m_ma_slow_handle, 0);
if(ma_fast == 0 || ma_slow == 0)
return SIGNAL_NONE;
// Get previous values for confirmation
double ma_fast_prev = iGetMainValue(m_ma_fast_handle, 1);
double ma_slow_prev = iGetMainValue(m_ma_slow_handle, 1);
if(ma_fast_prev == 0 || ma_slow_prev == 0)
return SIGNAL_NONE;
// Simple MA crossover logic
// BUY: Fast MA crosses above Slow MA
if(ma_fast_prev <= ma_slow_prev && ma_fast > ma_slow)
{
if(mp_logger && g_debug_mode)
mp_logger.Info(StringFormat("BUY Signal: MA Fast=%.5f > MA Slow=%.5f", ma_fast, ma_slow));
return SIGNAL_BUY;
}
// SELL: Fast MA crosses below Slow MA
if(ma_fast_prev >= ma_slow_prev && ma_fast < ma_slow)
{
if(mp_logger && g_debug_mode)
mp_logger.Info(StringFormat("SELL Signal: MA Fast=%.5f < MA Slow=%.5f", ma_fast, ma_slow));
return SIGNAL_SELL;
}
return SIGNAL_NONE;
}
// Clean up indicator handles
void Cleanup()
{
if(m_ma_fast_handle != INVALID_HANDLE)
{
IndicatorRelease(m_ma_fast_handle);
m_ma_fast_handle = INVALID_HANDLE;
}
if(m_ma_slow_handle != INVALID_HANDLE)
{
IndicatorRelease(m_ma_slow_handle);
m_ma_slow_handle = INVALID_HANDLE;
}
}
private:
// Safe way to get indicator value
double iGetMainValue(int handle, int shift)
{
double value[];
ArraySetAsSeries(value, true);
if(CopyBuffer(handle, 0, shift, 1, value) <= 0)
return 0.0;
return value[0];
}
};
#endif //__STRATEGY_MQH__