157 lines
4.1 KiB
Plaintext
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__
|