Files
MyProEA/MyProEA.mq5
T
2026-05-28 17:34:34 -04:00

253 lines
7.0 KiB
Plaintext

//+------------------------------------------------------------------+
//| MyProEA.mq5 - Professional Expert Advisor |
//| Main EA file with clean lifecycle and separation of concerns |
//+------------------------------------------------------------------+
#property copyright "Educational EA - BackTesting Only"
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#property description "Professional modular EA with MA crossover strategy"
#property description "For educational and backtesting purposes only"
// Include all class definitions
#include "Include/Config.mqh"
#include "Include/Logger.mqh"
#include "Include/Utilities.mqh"
#include "Include/MarketData.mqh"
#include "Include/Signal.mqh"
#include "Include/Strategy.mqh"
#include "Include/RiskManager.mqh"
#include "Include/PositionManager.mqh"
#include "Include/TradeManager.mqh"
#include "Include/TrailingStop.mqh"
//+------------------------------------------------------------------+
// Global class instances
//+------------------------------------------------------------------+
CLogger *g_logger = NULL;
CMarketData *g_market_data = NULL;
CStrategy *g_strategy = NULL;
CRiskManager *g_risk_manager = NULL;
CPositionManager *g_position_manager = NULL;
CTradeManager *g_trade_manager = NULL;
CTrailingStop *g_trailing_stop = NULL;
//+------------------------------------------------------------------+
// EA Initialization
//+------------------------------------------------------------------+
int OnInit()
{
// Create logger instance
g_logger = new CLogger(g_debug_mode);
g_logger.Info("===== EA INITIALIZATION START =====");
// Create market data handler
g_market_data = new CMarketData(_Symbol, g_logger);
if(!g_market_data.IsTradingAllowed())
{
g_logger.Error("Trading not allowed for this symbol");
delete g_market_data;
g_market_data = NULL;
delete g_logger;
g_logger = NULL;
return INIT_FAILED;
}
// Create strategy
g_strategy = new CStrategy(g_market_data, g_logger);
if(!g_strategy.Init())
{
g_logger.Error("Failed to initialize strategy");
delete g_strategy;
g_strategy = NULL;
delete g_market_data;
g_market_data = NULL;
delete g_logger;
g_logger = NULL;
return INIT_FAILED;
}
// Create risk manager
g_risk_manager = new CRiskManager(g_market_data, g_logger);
// Create position manager
g_position_manager = new CPositionManager(g_logger);
// Create trade manager
g_trade_manager = new CTradeManager(g_logger, g_risk_manager);
// Create trailing stop manager
g_trailing_stop = new CTrailingStop(g_market_data, g_logger, g_trade_manager);
// Log configuration
g_logger.Info(StringFormat("Magic Number: %d", g_magic_number));
g_logger.Info(StringFormat("Symbol: %s", _Symbol));
g_logger.Info(StringFormat("Timeframe: %s", EnumToString(PERIOD_CURRENT)));
g_logger.Info(StringFormat("Lot Mode: %s",
g_lot_mode == LOT_MODE_FIXED ? "FIXED" : "RISK"));
g_logger.Info(StringFormat("Stop Loss: %d points, Take Profit: %d points",
g_stop_loss_points, g_take_profit_points));
g_logger.Info(StringFormat("Max Positions: %d, Max Spread: %d points",
g_max_positions, g_max_spread_points));
g_logger.Info("===== EA INITIALIZATION COMPLETE =====");
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
// EA Deinitialization
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
g_logger.Info("===== EA DEINITIALIZATION START =====");
string reason_text = "";
switch(reason)
{
case REASON_ACCOUNT: reason_text = "Account changed"; break;
case REASON_CHARTCHANGE: reason_text = "Chart changed"; break;
case REASON_CHARTCLOSE: reason_text = "Chart closed"; break;
case REASON_PARAMETERS: reason_text = "Parameters changed"; break;
case REASON_RECOMPILE: reason_text = "EA recompiled"; break;
case REASON_REMOVE: reason_text = "EA removed"; break;
default: reason_text = "Unknown reason"; break;
}
g_logger.Info(StringFormat("Deinit reason: %s (%d)", reason_text, reason));
// Clean up strategy (release indicator handles)
if(g_strategy != NULL)
{
delete g_strategy;
g_strategy = NULL;
}
// Clean up all other objects
if(g_trailing_stop != NULL)
{
delete g_trailing_stop;
g_trailing_stop = NULL;
}
if(g_trade_manager != NULL)
{
delete g_trade_manager;
g_trade_manager = NULL;
}
if(g_position_manager != NULL)
{
delete g_position_manager;
g_position_manager = NULL;
}
if(g_risk_manager != NULL)
{
delete g_risk_manager;
g_risk_manager = NULL;
}
if(g_market_data != NULL)
{
delete g_market_data;
g_market_data = NULL;
}
if(g_logger != NULL)
{
g_logger.Info("===== EA DEINITIALIZATION COMPLETE =====");
delete g_logger;
g_logger = NULL;
}
}
//+------------------------------------------------------------------+
// Main EA Logic - OnTick()
//+------------------------------------------------------------------+
void OnTick()
{
// Step 1: Update market data (always)
if(!g_market_data.IsTradingAllowed())
{
return;
}
// Step 2: Check spread - if spread is too wide, don't trade
if(!g_risk_manager.IsSpreadAcceptable())
{
return;
}
// Step 3: Check trading hours
if(!g_risk_manager.IsTradingHourValid())
{
return;
}
// Step 4: Manage existing positions (trailing stop, break-even)
g_trailing_stop.UpdateAllPositions();
// Step 5: Only process signals on new bar
if(!g_market_data.IsNewBar())
{
return;
}
// Step 6: Get trading signal from strategy
E_SIGNAL signal = g_strategy.GetSignal();
if(signal == SIGNAL_NONE)
{
return;
}
// Step 7: Check if we already have a position
if(g_position_manager.HasOpenPosition(_Symbol))
{
if(g_debug_mode)
g_logger.Info("Already have open position, skipping entry");
return;
}
// Step 8: Check if new position is allowed
if(!g_position_manager.IsNewPositionAllowed(_Symbol))
{
g_logger.Warning("New position not allowed (max positions reached)");
return;
}
// Step 9: Calculate lot size
double lot = g_risk_manager.CalculateLotSize(g_stop_loss_points);
if(lot <= 0)
{
g_logger.Error("Invalid lot size calculated");
return;
}
// Step 10: Execute trade based on signal
bool trade_success = false;
if(signal == SIGNAL_BUY)
{
trade_success = g_trade_manager.OpenBuyTrade(_Symbol, lot);
}
else if(signal == SIGNAL_SELL)
{
trade_success = g_trade_manager.OpenSellTrade(_Symbol, lot);
}
if(trade_success)
{
if(g_logger)
g_logger.Info("Trade executed successfully");
}
else
{
if(g_logger)
g_logger.Error("Trade execution failed");
}
}