mql5/Experts/OTC_Escape_Learning_V2.mq5
Princeec13 ecd22e8ddd
2025-08-10 17:43:21 -04:00

277 lines
11 KiB
MQL5

//+------------------------------------------------------------------+
//| OTC Escape EA (Learning) V2 |
//| Optimized for OTC Markets |
//| With Machine Learning |
//+------------------------------------------------------------------+
#property version "2.00"
#property strict
//--- Include files
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Arrays\ArrayObj.mqh>
#include <OTCTypes.mqh>
#include <OTCLearningEngine.mqh>
//--- 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;
}
}