//+------------------------------------------------------------------+ //| OTC Escape EA (Learning) V2 | //| Optimized for OTC Markets | //| With Machine Learning | //+------------------------------------------------------------------+ #property version "2.00" #property strict //--- Include files #include #include #include #include #include #include #include //--- Global Objects CPositionInfo m_position; // trade position object CTrade m_trade; // trading object CSymbolInfo m_symbol; // symbol info object CAccountInfo m_account; // account info wrapper CLearningEngine *learning_engine = NULL; // learning engine object //--- Indicator Handles int handle_ma_fast, handle_ma_slow, handle_rsi, handle_adx, handle_atr; //--- Indicator Buffers double ma_fast_buffer[], ma_slow_buffer[], rsi_buffer[], adx_buffer[], atr_buffer[]; //--- Input Parameters input ulong InpMagicNumber = 12345; // Magic Number input ushort InpTakeProfit = 40; // TakeProfit for positions (pips) input ushort InpStopLoss = 30; // StopLoss for positions (pips) input bool InpUseStopLoss = true; // Use stop loss input bool InpUseTakeProfit= true; // Use take profit input string InpName_Expert = "OTC_Escape_Learning_V2"; // Expert Name input ulong InpSlippage = 3; // Slippage (points) input double InpLots = 0.02; // Lot size input int InpMAPeriod1 = 5; // Fast MA Period input int InpMAPeriod2 = 10; // Slow MA Period input ENUM_MA_METHOD InpMAMethod = MODE_SMA; // MA Method input ENUM_APPLIED_PRICE InpMAPrice = PRICE_CLOSE; // MA Price input group "=== Advanced Strategy Settings ===" input int InpRSI_Period = 14; // RSI Period input int InpADX_Period = 14; // ADX Period input int InpATR_Period = 14; // ATR Period input double InpADX_Threshold = 25.0; // ADX trend strength threshold input double InpATR_SL_Multiplier = 2.0; // ATR multiplier for Stop Loss input double InpATR_TP_Multiplier = 1.5; // Reward:Risk Ratio for Take Profit input group "=== Order Settings ===" input int InpMaxOpenTrades = 5; // Maximum number of open trades input group "=== Learning Engine Settings ===" input bool InpUseLearning = true; // Enable learning engine input bool InpUseAdaptiveLogic = true; // Enable adaptive SL/TP logic input int InpMinTradesForAnalysis = 50; // Min trades per regime to adapt input double InpVolatilityThreshold = 0.001; // Volatility threshold for regime change input double InpTrendThreshold = 20.0; // Trend strength threshold for regime change //--- Global Variables for Adaptive Logic double g_adaptive_sl_pips = 0; double g_adaptive_tp_pips = 0; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { m_symbol.Name(Symbol()); m_trade.SetExpertMagicNumber(InpMagicNumber); m_trade.SetTypeFilling(ORDER_FILLING_FOK); handle_ma_fast = iMA(Symbol(), Period(), InpMAPeriod1, 0, InpMAMethod, InpMAPrice); handle_ma_slow = iMA(Symbol(), Period(), InpMAPeriod2, 0, InpMAMethod, InpMAPrice); handle_rsi = iRSI(Symbol(), Period(), InpRSI_Period, InpMAPrice); handle_adx = iADX(Symbol(), Period(), InpADX_Period); handle_atr = iATR(Symbol(), Period(), InpATR_Period); if(handle_ma_fast == INVALID_HANDLE || handle_ma_slow == INVALID_HANDLE || handle_rsi == INVALID_HANDLE || handle_adx == INVALID_HANDLE || handle_atr == INVALID_HANDLE) { Print("Error creating indicators"); return(INIT_FAILED); } if(InpUseLearning) { learning_engine = new CLearningEngine(InpVolatilityThreshold, InpTrendThreshold); if(CheckPointer(learning_engine) == POINTER_INVALID) { learning_engine = new CLearningEngine(); if(CheckPointer(learning_engine) == POINTER_INVALID) { ExpertRemove(); return(INIT_FAILED); } } learning_engine->Init(Symbol(), Period()); learning_engine->SetMinTradesForAnalysis(InpMinTradesForAnalysis); } Print("OTC Escape EA V2 initialized successfully"); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { IndicatorRelease(handle_ma_fast); IndicatorRelease(handle_ma_slow); IndicatorRelease(handle_rsi); IndicatorRelease(handle_adx); IndicatorRelease(handle_atr); if(CheckPointer(learning_engine) == POINTER_DYNAMIC) { delete learning_engine; } Print("OTC Escape EA V2 deinitialized"); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { m_symbol.RefreshRates(); static datetime last_bar = 0; datetime current_bar = (datetime)SeriesInfoInteger(Symbol(), Period(), SERIES_LASTBAR_DATE); if(last_bar == current_bar) return; last_bar = current_bar; //--- Copy indicator data ArraySetAsSeries(ma_fast_buffer, true); ArraySetAsSeries(ma_slow_buffer, true); ArraySetAsSeries(rsi_buffer, true); ArraySetAsSeries(adx_buffer, true); ArraySetAsSeries(atr_buffer, true); if(CopyBuffer(handle_ma_fast, 0, 0, 2, ma_fast_buffer) < 2 || CopyBuffer(handle_ma_slow, 0, 0, 2, ma_slow_buffer) < 2 || CopyBuffer(handle_rsi, 0, 0, 2, rsi_buffer) < 2 || CopyBuffer(handle_adx, 0, 0, 2, adx_buffer) < 2 || CopyBuffer(handle_atr, 0, 0, 2, atr_buffer) < 2) { Print("Error copying indicator buffers in OnTick"); return; } if(InpUseAdaptiveLogic) { AdaptParameters(); } CheckForOpen(); } //+------------------------------------------------------------------+ //| Check for new trade signals | //+------------------------------------------------------------------+ void CheckForOpen() { if(m_position.Select(Symbol())) { return; // Position already exists } bool buy_signal = ma_fast_buffer[1] > ma_slow_buffer[1] && adx_buffer[1] > InpADX_Threshold; bool sell_signal = ma_fast_buffer[1] < ma_slow_buffer[1] && adx_buffer[1] > InpADX_Threshold; // Determine SL and TP in pips double sl_pips, tp_pips; if(InpUseAdaptiveLogic && g_adaptive_sl_pips > 0) { sl_pips = g_adaptive_sl_pips; tp_pips = g_adaptive_tp_pips; } else { double atr_value = atr_buffer[1]; if(atr_value <= 0) return; // Cannot set SL/TP without ATR sl_pips = atr_value / _Point * InpATR_SL_Multiplier; tp_pips = sl_pips * InpATR_TP_Multiplier; } if(buy_signal) { OpenTrade(ORDER_TYPE_BUY, InpLots, sl_pips, tp_pips); } if(sell_signal) { OpenTrade(ORDER_TYPE_SELL, InpLots, sl_pips, tp_pips); } } //+------------------------------------------------------------------+ //| Open a new trade | //+------------------------------------------------------------------+ void OpenTrade(ENUM_ORDER_TYPE OrderType, double LotSize, double sl_pips, double tp_pips) { double price = (OrderType == ORDER_TYPE_BUY) ? m_symbol.Ask() : m_symbol.Bid(); // Calculate SL/TP prices from pips double sl_price = (sl_pips > 0) ? ((OrderType == ORDER_TYPE_BUY) ? price - sl_pips * _Point : price + sl_pips * _Point) : 0; double tp_price = (tp_pips > 0) ? ((OrderType == ORDER_TYPE_BUY) ? price + tp_pips * _Point : price - tp_pips * _Point) : 0; //--- High-Precision Diagnostic Log string log_message = StringFormat("Attempting PositionOpen: symbol=%s, type=%s, lot=%.2f, entry=%.5f, sl=%.5f, tp=%.5f", _Symbol, (OrderType == ORDER_TYPE_BUY ? "BUY" : "SELL"), LotSize, price, sl_price, tp_price); Print(log_message); // Corrected call using PositionOpen if(!m_trade.PositionOpen(_Symbol, OrderType, LotSize, price, sl_price, tp_price, "EA V2 Trade")) { PrintFormat("PositionOpen failed: %d - %s", m_trade.ResultRetcode(), m_trade.ResultComment()); } else { Print("Position opened successfully"); if(InpUseLearning && CheckPointer(learning_engine) == POINTER_DYNAMIC) { STradeRecord *trade_record = new STradeRecord(); if(CheckPointer(trade_record) != POINTER_INVALID) { trade_record->trade_type = OrderType; trade_record->entry_time = TimeCurrent(); trade_record->entry_price = m_trade.ResultPrice(); trade_record->lot_size = LotSize; trade_record->stop_loss = m_trade.ResultSL(); trade_record->take_profit = m_trade.ResultTP(); trade_record->spread = (m_symbol.Ask() - m_symbol.Bid()) / _Point; trade_record->volatility = atr_buffer[1]; trade_record->trend_strength = adx_buffer[1]; trade_record->market_regime = learning_engine->GetCurrentMarketRegime(trade_record->volatility, trade_record->trend_strength); learning_engine->AddTrade(trade_record); } } } } //+------------------------------------------------------------------+ //| Adapt strategy parameters based on learned data | //+------------------------------------------------------------------+ void AdaptParameters() { if(CheckPointer(learning_engine) == POINTER_INVALID) return; double current_volatility = atr_buffer[1]; double current_trend = adx_buffer[1]; SMarketState market_state; market_state.Reset(); market_state.regime = learning_engine->GetCurrentMarketRegime(current_volatility, current_trend); if(learning_engine->GetOptimizedParameters(market_state)) { if(market_state.optimal_sl > 0 && market_state.optimal_tp > 0) { g_adaptive_tp_pips = market_state.optimal_tp; g_adaptive_sl_pips = market_state.optimal_sl; PrintFormat("AdaptParameters: Parameters updated for regime %s. New TP: %.1f, SL: %.1f", EnumToString(market_state.regime), g_adaptive_tp_pips, g_adaptive_sl_pips); } } else { g_adaptive_sl_pips = 0; g_adaptive_tp_pips = 0; } }