mql5/Experts/Advisors/DualEA/Include/Strategies/ForexTrendStrategy.mqh
Princeec13 123a9cbe6b
2026-02-05 23:31:20 -05:00

175 lines
6.1 KiB
MQL5

#include "..\IStrategy.mqh"
#include "..\KnowledgeBase.mqh"
#include "..\TradeManager.mqh"
class CForexTrendStrategy : public IStrategy
{
private:
// Trend indicators
int m_emaFast, m_emaMedium, m_emaSlow;
int m_ichimokuTenkan, m_ichimokuKijun, m_ichimokuSenkou;
double m_parabolicStep, m_parabolicMax;
// Momentum indicators
int m_rsiPeriod, m_adxPeriod;
// Cached values
double m_ema_fast, m_ema_medium, m_ema_slow;
double m_tenkan, m_kijun, m_senkou_a, m_senkou_b;
double m_parabolic, m_rsi, m_adx;
double m_close0, m_close1;
public:
CForexTrendStrategy(const string symbol, const ENUM_TIMEFRAMES tf) : IStrategy("ForexTrendStrategy", symbol, tf)
{
// EMA periods for trend identification
m_emaFast = 8; m_emaMedium = 21; m_emaSlow = 50;
// Ichimoku parameters
m_ichimokuTenkan = 9; m_ichimokuKijun = 26; m_ichimokuSenkou = 52;
// Parabolic SAR
m_parabolicStep = 0.02; m_parabolicMax = 0.2;
// Momentum
m_rsiPeriod = 14; m_adxPeriod = 14;
ResetValues();
}
virtual string Name() { return "ForexTrendStrategy"; }
void ResetValues()
{
m_ema_fast = m_ema_medium = m_ema_slow = 0;
m_tenkan = m_kijun = m_senkou_a = m_senkou_b = 0;
m_parabolic = m_rsi = m_adx = 0;
m_close0 = m_close1 = 0;
}
virtual void Refresh()
{
ResetValues();
m_close0 = iClose(m_symbol, m_timeframe, 0);
m_close1 = iClose(m_symbol, m_timeframe, 1);
// EMAs
double ema_fast_buffer[], ema_medium_buffer[], ema_slow_buffer[];
int ema_fast_handle = iMA(m_symbol, m_timeframe, m_emaFast, 0, MODE_EMA, PRICE_CLOSE);
int ema_medium_handle = iMA(m_symbol, m_timeframe, m_emaMedium, 0, MODE_EMA, PRICE_CLOSE);
int ema_slow_handle = iMA(m_symbol, m_timeframe, m_emaSlow, 0, MODE_EMA, PRICE_CLOSE);
if(ema_fast_handle > 0) CopyBuffer(ema_fast_handle, 0, 0, 1, ema_fast_buffer);
if(ema_medium_handle > 0) CopyBuffer(ema_medium_handle, 0, 0, 1, ema_medium_buffer);
if(ema_slow_handle > 0) CopyBuffer(ema_slow_handle, 0, 0, 1, ema_slow_buffer);
m_ema_fast = ema_fast_buffer[0];
m_ema_medium = ema_medium_buffer[0];
m_ema_slow = ema_slow_buffer[0];
// Ichimoku
double tenkan_buffer[], kijun_buffer[], senkou_a_buffer[], senkou_b_buffer[];
int ichimoku_handle = iIchimoku(m_symbol, m_timeframe, m_ichimokuTenkan, m_ichimokuKijun, m_ichimokuSenkou);
if(ichimoku_handle > 0)
{
CopyBuffer(ichimoku_handle, 0, 0, 1, tenkan_buffer);
CopyBuffer(ichimoku_handle, 1, 0, 1, kijun_buffer);
CopyBuffer(ichimoku_handle, 2, 0, 1, senkou_a_buffer);
CopyBuffer(ichimoku_handle, 3, 0, 1, senkou_b_buffer);
m_tenkan = tenkan_buffer[0];
m_kijun = kijun_buffer[0];
m_senkou_a = senkou_a_buffer[0];
m_senkou_b = senkou_b_buffer[0];
}
// Parabolic SAR
double sar_buffer[];
int sar_handle = iSAR(m_symbol, m_timeframe, m_parabolicStep, m_parabolicMax);
if(sar_handle > 0) CopyBuffer(sar_handle, 0, 0, 1, sar_buffer);
m_parabolic = sar_buffer[0];
// RSI
double rsi_buffer[];
int rsi_handle = iRSI(m_symbol, m_timeframe, m_rsiPeriod, PRICE_CLOSE);
if(rsi_handle > 0) CopyBuffer(rsi_handle, 0, 0, 1, rsi_buffer);
m_rsi = rsi_buffer[0];
// ADX
double adx_buffer[];
int adx_handle = iADX(m_symbol, m_timeframe, m_adxPeriod);
if(adx_handle > 0) CopyBuffer(adx_handle, 0, 0, 1, adx_buffer);
m_adx = adx_buffer[0];
}
virtual TradeOrder CheckSignal()
{
TradeOrder ord; ord.strategy_name = Name();
// Trend alignment checks
bool ema_bullish = m_ema_fast > m_ema_medium && m_ema_medium > m_ema_slow;
bool ema_bearish = m_ema_fast < m_ema_medium && m_ema_medium < m_ema_slow;
// Ichimoku cloud
bool above_cloud = m_close0 > m_senkou_a && m_close0 > m_senkou_b;
bool below_cloud = m_close0 < m_senkou_a && m_close0 < m_senkou_b;
// Parabolic SAR
bool sar_bullish = m_close0 > m_parabolic;
bool sar_bearish = m_close0 < m_parabolic;
// Momentum filters
bool rsi_oversold = m_rsi < 30;
bool rsi_overbought = m_rsi > 70;
bool strong_trend = m_adx > 25;
// Bullish setup
if(ema_bullish && above_cloud && sar_bullish && strong_trend && rsi_oversold)
{
ord.action = ACTION_BUY;
ord.order_type = ORDER_TYPE_BUY;
ord.stop_loss = m_ema_medium;
ord.take_profit = m_close0 + (m_close0 - m_ema_medium) * 2;
ord.trailing_enabled = true;
ord.trailing_type = TRAIL_FIXED_POINTS;
ord.trail_activation_points = 30;
ord.trail_distance_points = 20;
ord.trail_step_points = 5;
return ord;
}
// Bearish setup
else if(ema_bearish && below_cloud && sar_bearish && strong_trend && rsi_overbought)
{
ord.action = ACTION_SELL;
ord.order_type = ORDER_TYPE_SELL;
ord.stop_loss = m_ema_medium;
ord.take_profit = m_close0 - (m_ema_medium - m_close0) * 2;
ord.trailing_enabled = true;
ord.trailing_type = TRAIL_FIXED_POINTS;
ord.trail_activation_points = 30;
ord.trail_distance_points = 20;
ord.trail_step_points = 5;
return ord;
}
return ord;
}
virtual void ExportFeatures(CFeaturesKB* kb, const datetime ts)
{
if(CheckPointer(kb)==POINTER_INVALID) return;
// Trend strength indicators
double trend_strength = 0;
if(m_ema_fast > m_ema_medium) trend_strength += 1;
if(m_ema_medium > m_ema_slow) trend_strength += 1;
if(m_close0 > m_senkou_a && m_close0 > m_senkou_b) trend_strength += 1;
(*kb).WriteKV(ts, m_symbol, Name(), "trend_strength", trend_strength);
(*kb).WriteKV(ts, m_symbol, Name(), "rsi", m_rsi);
(*kb).WriteKV(ts, m_symbol, Name(), "adx", m_adx);
(*kb).WriteKV(ts, m_symbol, Name(), "ema_distance", MathAbs(m_close0 - m_ema_medium) / m_ema_medium * 100);
}
};