/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Expert Advisor // ------------------------------------------------- // Name: XBaseEA // Description: Base Expert Advisor as Template ... // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property icon "../Images/SaherElm_Logo_Color.ico" #property description "SaherElm Based Expert Advisor" #property strict // #define ShortName "XBaseEA" // // Importts ... #include "../Classes/x-saherelm.x-expert.class.mq5" // // Inputs ... // // Common ... input group "Common"; input long eaMagicNumber = 1694056; // Magic Number input int eaSlippage = 10; // Slippgae input string eaLogSuffix = ""; // Log Suffix // // Symbols // [ // Name| // Symbol| // period| // (ST_04:00_08:30),(TL_10:30_12:00),(NY_16:00_20:00)| // maxAllowedSpread| // maxAllowedPosition| // ( // restrictionsPeriod, // restrictionsMultiplier, // maxAllowedTPs, // maxAllowedSLs, // maxAllowedTrades, // closeAllOpenTradesAt // ) // ] // // // [XNAME|XAUUSDb|M5|(ST_04:00_08:30),(TL_10:30_12:00),(NY_16:00_20:00)|25.0|5|(XTRADE_RESTRICATION_DAILY,1,0,2,0)] input string eaSymbolConfiguration = "[XNAME|XAUUSDb|M5|(ST_04:00_08:30),(TL_10:30_12:00),(NY_16:00_20:00)|25.0|5|(XTRADE_RESTRICATION_DAILY,3,0,2,0)]"; // Symbol Configurations // // Management ... input group "Management"; input bool eaAllowGuards = false; // Allow Guards input bool eaAllowTrade = true; // Allow Trade on Signals input bool eaAllowLongs = true; // Allow Long Trades input bool eaAllowShorts = true; // Allow Short Trades input double eaMaxAllowedDrawdownFactor = 0.3; // Max Allowed DrawDown for Trade // // Volume ... input group "Volume"; input ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect = X_VOLUME_CONSTANT; // Volume Applying Type input double eaStaticVoluem = 0.0; // Static Volume input double eaDynamicVolumeStepBalance = 0.0; // Step of Balance for Increase Volume input double eaDynamicVolumeStepVolume = X_MIN_VOLUME; // Step of Volume Increasing input double eaConstantRiskBalance = 0.0; // Constant Risk Balance per Trade input double eaConstantPercent = 1; // Constant Percent of Balance Per Trade input double eaConstantBalance = 1000.0; // Constant Balance for Calculations // // Alert ... input group "Alert"; input bool eaEnableAlerts = true; // Enable Alerts input bool eaSaveAlerts = true; // Save Alerts input bool eaLogAlerts = true; // Log Alerts input bool eaMailAlerts = false; // Mail Alerts input bool eaPushAlerts = true; // Push Alerts input bool eaTerminalAlerts = false; // Terminal Alerts // // Reports ... input group "Reports"; input bool eaReportNewMonths = false; // Report New Month input bool eaReportNewWeeks = false; // Report New Weeks input bool eaReportNewDays = true; // Report New Days input bool eaReportNewHours = false; // Report New Hours input bool eaReportTrades = true; // Report Trades input bool eaReportSignals = true; // Report Signals input bool eaReportRestrictions = true; // Report Restrictions input bool eaReportProtector = true; // Report Protector Actions input bool eaReportAfterTradesBalance = true; // Report Balance after a Trade Finished // // Collector ... input group "Collector"; input bool eaSaveTrades = true; // Save Trades input bool eaSaveSignals = true; // Save Signals input bool eaSaveWins = true; // Save Winning Conditions input bool eaSaveLosts = true; // Save Lost Conditions input bool eaSaveRestrictions = true; // Save Restriction Reports // // Management Panel ... input group "Management Panel"; input bool eaShowPanel = false; // Show Management Panel double eaPanelAllowedTPSLStep = 10; // Value for Change TP/SL in Each Step double eaPanelMinAllowedRiskInPoint = 20; // Min Allowed Risk in Point double eaPanelRiskInPoint = 50; // Risk in Point per Trades double eaPanelRiskToRewardRatio = 2.0; // Risk To Reward per Trades double eaPanelVolume = X_MIN_VOLUME; // Default volume Per Trade // // Variables ... // XCBaseExpert *eaExpert; // // Event Handlers ... /** * Initialize EA Process ... * * @return ( int ) */ int OnInit() { // // Preparing Tags ... string eaTag = (IsValid(eaLogSuffix) ? eaLogSuffix + "_" : "") + ShortName; // // Validate Inputs and Required Parameters ... // for EA to Works fine ... if (!ValidateInputs()) { return INIT_PARAMETERS_INCORRECT; } // // Initialize Timer ... if (!InitTimer()) { return INIT_FAILED; } // // Configure EA Expert Class ... eaExpert = new XCBaseExpert(); // // Setting All Inputs to Expert Adviser Class ... // // Common ... eaExpert.eaMagicNumber = eaMagicNumber; eaExpert.eaSlippage = eaSlippage; eaExpert.eaLogSuffix = eaTag; // // Symbols ... eaExpert.eaSymbolConfiguration = eaSymbolConfiguration; // // Management ... eaExpert.eaAllowGuards = eaAllowGuards; eaExpert.eaAllowTrade = eaAllowTrade; eaExpert.eaAllowLongs = eaAllowLongs; eaExpert.eaAllowShorts = eaAllowShorts; eaExpert.eaMaxAllowedDrawdownFactor = eaMaxAllowedDrawdownFactor; // // Volume ... eaExpert.eaVolumeSelect = eaVolumeSelect; eaExpert.eaStaticVoluem = eaStaticVoluem; eaExpert.eaDynamicVolumeStepBalance = eaDynamicVolumeStepBalance; eaExpert.eaDynamicVolumeStepVolume = eaDynamicVolumeStepVolume; eaExpert.eaConstantRiskBalance = eaConstantRiskBalance; eaExpert.eaConstantPercent = eaConstantPercent; eaExpert.eaConstantBalance = eaConstantBalance; // // Alert ... eaExpert.eaEnableAlerts = eaEnableAlerts; eaExpert.eaSaveAlerts = eaSaveAlerts; eaExpert.eaLogAlerts = eaLogAlerts; eaExpert.eaMailAlerts = eaMailAlerts; eaExpert.eaPushAlerts = eaPushAlerts; eaExpert.eaTerminalAlerts = eaTerminalAlerts; // // Reports ... eaExpert.eaReportNewMonths = eaReportNewMonths; eaExpert.eaReportNewWeeks = eaReportNewWeeks; eaExpert.eaReportNewDays = eaReportNewDays; eaExpert.eaReportNewHours = eaReportNewHours; eaExpert.eaReportTrades = eaReportTrades; eaExpert.eaReportSignals = eaReportSignals; eaExpert.eaReportRestrictions = eaReportRestrictions; eaExpert.eaReportProtector = eaReportProtector; eaExpert.eaReportAfterTradesBalance = eaReportAfterTradesBalance; // // Collector ... eaExpert.eaSaveTrades = eaSaveTrades; eaExpert.eaSaveSignals = eaSaveSignals; eaExpert.eaSaveWins = eaSaveWins; eaExpert.eaSaveLosts = eaSaveLosts; eaExpert.eaSaveRestrictions = eaSaveRestrictions; // // Management Panel ... eaExpert.eaShowPanel = eaShowPanel; eaExpert.eaPanelAllowedTPSLStep = eaPanelAllowedTPSLStep; eaExpert.eaPanelMinAllowedRiskInPoint = eaPanelMinAllowedRiskInPoint; eaExpert.eaPanelRiskInPoint = eaPanelRiskInPoint; eaExpert.eaPanelRiskToRewardRatio = eaPanelRiskToRewardRatio; eaExpert.eaPanelVolume = eaPanelVolume; // // Attach Event Handlers ... eaExpert.AddOnSignalEventHandler(OnSignalTriggered); eaExpert.onGuardedEventHandler = OnGuardedTriggered; eaExpert.AddOnDealsChangedEventHandler(OnDealsChanged); eaExpert.AddOnStopLossEventHandler(OnStopLossTriggered); eaExpert.AddOnOrdersChangedEventHandler(OnOrdersChanged); eaExpert.AddOnSignalExecutedEventHandler(OnSignalExecuted); eaExpert.canAnalyseEventHandler = CanAnalyseEventTriggered; eaExpert.AddOnTakeProfitEventHandler(OnTakeProfitTriggered); eaExpert.checkForGuardEventHandler = CheckForGuardTriggered; eaExpert.AddOnModifyPositionEventHandler(OnPositionModified); eaExpert.AddOnPositionsChangedEventHandler(OnPositionsChanged); eaExpert.AddOnTradeStateChangedEventHandler(OnTradeStateChanged); eaExpert.AddOnForceClosePositionEventHandler(OnPositionForceClosed); eaExpert.AddOnPartialClosePositionEventHandler(OnPositionPartialClosed); // // Try to Initialize eaExpert ... bool isInited = eaExpert.HandleOnInit(); if (!isInited) { // Print(ShortName, ": Initialization Failed ..."); return INIT_FAILED; } // Print(ShortName, ": Initialized Successfully ..."); return INIT_SUCCEEDED; } /** * De Initialize Expert ... * * @param reason: int, DeInitialization Reason ... * * REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function * REASON_REMOVE 1 Program removed from a chart * REASON_RECOMPILE 2 Program recompiled * REASON_CHARTCHANGE 3 A symbol or a chart period is changed * REASON_CHARTCLOSE 4 Chart closed * REASON_PARAMETERS 5 Inputs changed by a user * REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings * REASON_TEMPLATE 7 Another chart template applied * REASON_INITFAILED 8 The OnInit() handler returned a non-zero value * REASON_CLOSE 9 Terminal closed * */ void OnDeinit(const int reason) { // // Destroy Timer ... // If Initialized ... // // De Init Expert Class Instance ... eaExpert.HandleOnDeInit(); // // Cleanup Resources ... delete eaExpert; ZeroMemory(eaExpert); } /** * Handle Tick for Processing ... */ void OnTick() { eaExpert.HandleOnTick(); } /** * Handle On Trade Processing ... */ void OnTrade() { eaExpert.HandleOnTrade(); } /** * Handle On Timer Processing ... */ void OnTimer() { eaExpert.HandleOnTimer(); } /** * Handle On Chart Event Processing ... * @param id: int, Specified Event ID ... * @param lparam: long, type event parameter * @param dparam: double, type event parameter * @param sparam: string, type event parameter */ void OnChartEvent( const int id, const long &lparam, const double &dparam, const string &sparam // ) { eaExpert.HandleOnChartEvent(id, lparam, dparam, sparam); } // // Event Listeners ... /** * Handle CanAnalyse Event Triggered ... * * @param symbol: Symbol ... * @param period: Period ... * @param time: Analysing Time ... * * @return ( bool ) */ bool CanAnalyseEventTriggered( string symbol, ENUM_TIMEFRAMES period, datetime time // ) { return eaExpert.HandleCanAnalyseEventTriggered( symbol, period, time // ); } /** * Check For Guard ... * * @param guards: XGuard, reference Collection to holds result ... * @param positions: XPosition, refrence collection to Provides Positions ... * @param barIndex: int, Specified Bar index ... * * @return ( int ) */ int CheckForGuardTriggered( XGuard &guards[], XPosition &positions[], int barIndex = 0 // ) { // return eaExpert.CheckForGuardTriggered( guards, positions, barIndex // ); } /** * Handle Guard Events ... * * @param action: ENUM_X_GUARD_ACTIONS * @param positions: XPosition[] */ void OnGuardedTriggered( ENUM_X_GUARD_ACTIONS action, XPosition &positions[] // ) { eaExpert.OnGuardedTriggered(action, positions); } /** * Trigger OnSignal Event ... * * @param signal: XSignal */ void OnSignalTriggered(XSignal &signal) { eaExpert.HandleOnSignalTriggered(signal); } /** * Trigger OnSignal Executed Event ... * * @param signal: XSignal */ void OnSignalExecuted(XSignal &signal) { eaExpert.HandleOnSignalExecuted(signal); } /** * Handle StopLoss Triggered Positions ... * * @param deal: XDeal instance ... */ void OnStopLossTriggered(const XDeal &deal) { eaExpert.HandleOnStopLossTriggered(deal); } /** * Handle Take Profit Triggered Positions ... * * @param deal: XDeal instance ... */ void OnTakeProfitTriggered(const XDeal &deal) { eaExpert.HandleOnTakeProfitTriggered(deal); } /** * Handle Force Close a Position ... * * @param ticket: ULONG ... * @param position: XPosition instance ... * @param comment: String ... */ void OnPositionForceClosed( const ulong ticket, const XPosition &position, const string comment // ) { // eaExpert.HandleOnPositionForceClosed( ticket, position, comment // ); } /** * Handle Deals Changes ... * * @param count: Integer, Number of Changes ... */ void OnDealsChanged(int count) { eaExpert.HandleOnDealsChanged(count); } /** * Handle Orders Changes ... * * @param count: Integer, Number of Changes ... */ void OnOrdersChanged(int count) { eaExpert.HandleOnOrdersChanged(count); } /** * Handle Positions Changes ... * * @param count: Integer, Number of Changes ... */ void OnPositionsChanged(int count) { eaExpert.HandleOnPositionsChanged(count); } /** * Handle Position Modified ... * * @param ticket: ulong, Position Ticket ... * @param profit: double, Position Profit ... * @param comment: string, Comment ... */ void OnPositionModified( const ulong ticket, const double profit, const string comment // ) { // eaExpert.HandleOnPositionModified( ticket, profit, comment // ); } /** * Handle Position Partial Closed ... * * @param ticket: ulong, Position Ticket ... * @param profit: double, Position Profit ... * @param comment: string, Comment ... */ void OnPositionPartialClosed( const ulong ticket, const double profit, const string comment // ) { // eaExpert.HandleOnPositionPartialClosed( ticket, profit, comment // ); } /** * Handle Trade State Changed ... * * @param state: XOnTradeHandlerState instance ... */ void OnTradeStateChanged(const XOnTradeHandlerState &state) { eaExpert.HandleOnTradeStateChanged(state); } // // Custom Functions ... /** * Validate all Inputs of Expert Adviser ... * * @return ( bool ) */ bool ValidateInputs() { // bool result = false; // string errMessage = ""; // bool isCommonValid = ( // eaSlippage > 0 && eaMagicNumber > 0 // ); if (!isCommonValid) { // errMessage += "common configurations error;" + "\n"; } // result = // // Common ... isCommonValid && // // Otere ... true // ; // if (!result) { // // Since here Logger not Initiallized, we Use Raw Print Command ... Print(ShortName + " Errors: \n", errMessage); } // return result; } /** * Initialize Timer ... * * @return ( bool ) */ bool InitTimer() { // bool result = false; // // TODO: Initialize Timer if necessary ... // result = EventSetTimer(1); // result = EventSetMillisecondTimer(100); result = true; // return result; } /** * Destroy Timer ... */ void DestroyTimer() { // // TODO: Use This ... // EventKillTimer(); } //