/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class // ------------------------------------------------- // Name: XCXOM1EAExpret ... // Description: XCXOM1EA Expert Class ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm XCXOM1EA Expert Class" #property strict // // Imports ... #include "../../Classes/x-saherelm.base.class.mq5" #include "../../Classes/x-saherelm.x-alert.class.mq5" #include "../../Classes/x-saherelm.x-guard.class.mq5" #include "../../Classes/x-saherelm.x-target.class.mq5" #include "../../Classes/x-saherelm.x-trade-manager.class.mq5" #include "../../Classes/x-saherelm.x-volume.class.mq5" #include "../Classes/xom1ea.signaller.class.mq5" // // Definitions ... // // Implementation ... class XCXOM1EAExpert : public XCBase { // // Public ... public: // // Props ... // // Common ... long eaMagicNumber; // Magic Number int eaSlippage; // Slippgae string eaLogSuffix; // Log Suffix // // Symbol Configurations ... string eaSymbolConfiguration; // Symbol Configurations ... // // Management ... bool eaAllowGuards; // Allow Guards bool eaAllowTrade; // Allow Trade on Signals bool eaAllowLongs; // Allow Long Trades bool eaAllowShorts; // Allow Short Trades double eaMaxAllowedDrawdownFactor; // Max Allowed DrawDown for Trade // // Volume ... ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect; // Volume Applying Type double eaStaticVoluem; // Static Volume double eaDynamicVolumeStepBalance; // Step of Balance for Increase Volume double eaDynamicVolumeStepVolume; // Step of Volume Increasing double eaConstantRiskBalance; // Constant Risk Balance per Trade double eaConstantPercent; // Constant Percent of Balance Per Trade double eaConstantBalance; // Constant Balance for Calculations // // Alert ... bool eaEnableAlerts; // Enable Alerts bool eaSaveAlerts; // Save Alerts bool eaLogAlerts; // Log Alerts bool eaMailAlerts; // Mail Alerts bool eaPushAlerts; // Push Alerts bool eaTerminalAlerts; // Terminal Alerts // // Reports ... bool eaReportNewMonths; // Report New Month bool eaReportNewWeeks; // Report New Weeks bool eaReportNewDays; // Report New Days bool eaReportNewHours; // Report New Hours bool eaReportTrades; // Report Trades bool eaReportSignals; // Report Signals bool eaReportProtector; // Report Protector Actions bool eaReportRestrictions; // Report Restrictions bool eaReportAfterTradesBalance; // Report Balance after a Trade Finished // // Collector ... bool eaSaveTrades; // Save Trades bool eaSaveSignals; // Save Signals bool eaSaveWins; // Save Winning Conditions bool eaSaveLosts; // Save Lost Conditions bool eaSaveRestrictions; // Save Restriction Reports // // Requirements ... // XCAlert *eaAlert; // EA Scope Alert Handler ... XCVolume *eaVolume; // EA Scope Voluem Handler ... XCGuard *eaGuard; // EA Scope Guard Handler ... XCTrade *eaTrade; // EA Scope Trade Handler ... XCTarget *eaTarget; // EA Scope Target Handler ... XTimeTracker eaTimeTracker; // EA Scope Time Tracker ... XCTradeManager *eaTradeManager; // EA Scope Trade Handler ... // // Tools / Actions / Handlers ... // TOnGuarded onGuardedEventHandler; TCanAnalyse canAnalyseEventHandler; TCheckForGuard checkForGuardEventHandler; // // Signal Event Handlers ... // void AddOnSignalEventHandler(TOnSignal handler) { // if (handler == NULL) { return; } // Add( handler, mOnSignalEventHandlers // ); } // // Trade Event Handlers ... // void AddOnStopLossEventHandler(TOnStopLoss handler) { // if (handler == NULL) { return; } // Add( handler, mStopLossEventHandlers // ); } // void AddOnTakeProfitEventHandler(TOnTakeProfit handler) { // if (handler == NULL) { return; } // Add( handler, mTakeProfitEventHandlers // ); } // void AddOnDealsChangedEventHandler(TOnDealsChanged handler) { // if (handler == NULL) { return; } // Add( handler, mDealsChangedEventHandlers // ); } // void AddOnOrdersChangedEventHandler(TOnOrdersChanged handler) { // if (handler == NULL) { return; } // Add( handler, mOrdersChangedEventHandlers // ); } // void AddOnModifyPositionEventHandler(TOnModify handler) { // if (handler == NULL) { return; } // Add( handler, mOnModifyEventHandlers // ); } // void AddOnPositionsChangedEventHandler(TOnPositionsChanged handler) { // if (handler == NULL) { return; } // Add( handler, mPositionsChangedEventHandlers // ); } // void AddOnTradeStateChangedEventHandler(TOnTradeStateChanged handler) { // if (handler == NULL) { return; } // Add( handler, mTradeStateChangedEventHandlers // ); } // void AddOnForceClosePositionEventHandler(TOnForceClose handler) { // if (handler == NULL) { return; } // Add( handler, mOnForceCloseEventHandlers // ); } // void AddOnPartialClosePositionEventHandler(TOnPartialClose handler) { // if (handler == NULL) { return; } // Add( handler, mOnPartialCloseEventHandlers // ); } // // Validators ... /** * Validate Inputs ... * * @return ( bool ) */ bool ValidateInputs() { // bool result = false; // // TODO: Handle this ... result = true; // return result; } // // Expert Advisor Event Handlers ... /** * Handle Initialization of Expert ... * * @return ( bool ) */ bool HandleOnInit() { // bool result = false; // // Validate Inputs ... result = ValidateInputs(); if (!result) { return result; } // int count = 0; bool has = false; // // Initialize Alert Handler ... eaAlert = new XCAlert(); eaAlert.SetPrefix(eaLogSuffix); eaAlert.SetLogAlerts(eaLogAlerts); eaAlert.SetMailAlerts(eaMailAlerts); eaAlert.SetPushAlerts(eaPushAlerts); eaAlert.SetSaveAlerts(eaSaveAlerts); eaAlert.SetEnableAlerts(eaEnableAlerts); eaAlert.SetTerminalAlerts(eaTerminalAlerts); // // Initialize Volume Manager ... eaVolume = new XCVolume(); result = eaVolume.Init( eaVolumeSelect, eaStaticVoluem, eaDynamicVolumeStepBalance, eaDynamicVolumeStepVolume, eaConstantRiskBalance, eaConstantPercent, eaConstantBalance // ); if (!result) { return result; } // // Initialize Trader ... eaTrade = new XCTrade( eaSlippage, eaMagicNumber, 0, 0, eaMaxAllowedDrawdownFactor // ); // // Trade Handler Attachments ... // // Position Modifiy Event Handlers ... count = ArraySize(mOnModifyEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrade.AddOnModifyPositionEventHandler(mOnModifyEventHandlers[i]); } } // // Position Stop Loss Event Handlers ... count = ArraySize(mStopLossEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrade.AddOnStopLossEventHandler(mStopLossEventHandlers[i]); } } // // Position Take Profit Event Handlers ... count = ArraySize(mTakeProfitEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrade.AddOnTakeProfitEventHandler(mTakeProfitEventHandlers[i]); } } // // Position Force Close Event Handlers ... count = ArraySize(mOnForceCloseEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrade.AddOnForceClosePositionEventHandler(mOnForceCloseEventHandlers[i]); } } // // Deals Changed Event Handlers ... count = ArraySize(mDealsChangedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrade.AddOnDealsChangedEventHandler(mDealsChangedEventHandlers[i]); } } // // Orders Changed Event Handlers ... count = ArraySize(mOrdersChangedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrade.AddOnOrdersChangedEventHandler(mOrdersChangedEventHandlers[i]); } } // // Positions Changed Event Handlers ... count = ArraySize(mPositionsChangedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrade.AddOnPositionsChangedEventHandler(mPositionsChangedEventHandlers[i]); } } // // Trade Changed Event Handlers ... count = ArraySize(mTradeStateChangedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrade.AddOnTradeStateChangedEventHandler(mTradeStateChangedEventHandlers[i]); } } // // Postion Partially Close Event Handlers ... count = ArraySize(mOnPartialCloseEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrade.AddOnPartialClosePositionEventHandler(mOnPartialCloseEventHandlers[i]); } } // // Initialize Guard Handler ... eaGuard = new XCGuard( eaAlert, eaTrade // ); // // Attach Event Handler ... eaGuard.onGuardEventListener = onGuardedEventHandler; // // Initialize Trae Manager ... eaTradeManager = new XCTradeManager( eaAlert, eaTrade, eaVolume, eaGuard, eaTarget // ); // // Configuring Trade Manager ... // // Attache Check For Guard Event Listener ... eaTradeManager.checkForGuardEventListener = checkForGuardEventHandler; // eaTradeManager.SaveWins(eaSaveWins); eaTradeManager.SaveLosts(eaSaveLosts); eaTradeManager.SaveTrades(eaSaveTrades); eaTradeManager.SaveSignals(eaSaveSignals); eaTradeManager.SaveRestrictions(eaSaveRestrictions); // // Setting Trade Reports ... eaTradeManager .SetTradeReports( eaReportTrades, eaReportSignals, eaReportProtector, eaReportRestrictions, eaReportAfterTradesBalance // ); // // Setting Trade Permissions ... eaTradeManager .SetTradePermissions( eaAllowTrade, eaAllowLongs, eaAllowShorts // ); // // Setting Symbol Configuration ... XSymbolTradeConfig symbolConfigurations[]; eaTradeManager.SetSymbolConfigurations(eaSymbolConfiguration); count = eaTradeManager.FillSymbolConfigurations(symbolConfigurations); has = IsValidSize(count); if (has) { // // XFIMA ... // XOM1Inputs iFIMAOMInputs; iFIMAOMInputs.Default(); iFIMAOMInputs.showFiboZone = true; // XOM1SignallerConfig iFIMASignallerConfig; iFIMASignallerConfig.processAllTicks = false; // XCXOM1SignallerBase *iFIMASignaller = NULL; // // iMAC5020 ... // XOM1Inputs iMAC5020OMINputs; iMAC5020OMINputs.Default(); iMAC5020OMINputs.showPV = false; iMAC5020OMINputs.showSAR = false; iMAC5020OMINputs.maFastLength = 20; iMAC5020OMINputs.maSlowLength = 50; iMAC5020OMINputs.showFiboZone = false; // XOM1SignallerConfig iMAC5020SignallerConfig; iMAC5020SignallerConfig.processAllTicks = false; // XCXIMAC5020Signaller *iMAC5020Signaller = NULL; // // Configure Signallers ... for (int i = 0; i < count; i++) { // // Register XFIMA Signaller ... // iFIMASignaller = new XCXOM1FIMASignaller( // "XDZN", // symbolConfigurations[i].symbol, // symbolConfigurations[i].period, // iFIMAOMInputs, // iFIMASignallerConfig // // ); // if (iFIMASignaller != NULL) // { // // // // Register Signaller ... // XCXOM1SignallerBase *signaller = iFIMASignaller; // RegisterSignaller(signaller); // ZeroMemory(signaller); // } // // Register XIMAC5020 Signaller ... iMAC5020Signaller = new XCXIMAC5020Signaller( "XIMAC5020", symbolConfigurations[i].symbol, symbolConfigurations[i].period, iMAC5020OMINputs, iMAC5020SignallerConfig // ); if (iMAC5020Signaller != NULL) { // // Register Signaller ... XCXOM1SignallerBase *signaller = iMAC5020Signaller; RegisterSignaller(signaller); ZeroMemory(signaller); } } // // Cleanup Resources ... // iFIMAOMInputs.Clean(); iMAC5020OMINputs.Clean(); ZeroMemory(iFIMASignaller); iFIMASignallerConfig.Clean(); ZeroMemory(iMAC5020Signaller); iMAC5020SignallerConfig.Clean(); } SpecifiedClean(symbolConfigurations); // return result; } /** * Handle De Initialization of Expert ... */ void HandleOnDeInit() { // // delete eaTrade; ZeroMemory(eaTrade); // delete eaGuard; ZeroMemory(eaGuard); // delete eaVolume; ZeroMemory(eaVolume); // delete eaTradeManager; ZeroMemory(eaTradeManager); // eaTimeTracker.Clean(); // SpecifiedClean(eaSignallers); SpecifiedClean(mOnSignalEventHandlers); SpecifiedClean(mOnModifyEventHandlers); SpecifiedClean(mStopLossEventHandlers); SpecifiedClean(mTakeProfitEventHandlers); SpecifiedClean(mOnForceCloseEventHandlers); SpecifiedClean(mDealsChangedEventHandlers); SpecifiedClean(mOrdersChangedEventHandlers); SpecifiedClean(mOnPartialCloseEventHandlers); SpecifiedClean(mPositionsChangedEventHandlers); SpecifiedClean(mTradeStateChangedEventHandlers); // string message = "DeInitialized Successfully ..."; eaAlert.SendAlert(message); // delete eaAlert; ZeroMemory(eaAlert); } /** * Handle Tick ... */ void HandleOnTick() { // // Time Report ... HandleTimeReport(); // // Manage Trades ... eaTradeManager.Manage(); // int count = ArraySize(eaSignallers); bool has = IsValidSize(count); if (!has) { return; } // // Loop through Signallers ... for (int i = 0; i < count; i++) { // // Calling Process Ticks on Signaller ... eaSignallers[i].ProcessTick(0); } // // Guard Implememnting ... // TODO: Implement this ... } /** * Handle Trade ... */ void HandleOnTrade() { eaTrade.HandleOnTrade(); } /** * Handle Timer ... */ void HandleOnTimer() { } /** * Handle Chart Event ... * * @param id: int, Event id ... * @param lparam: long, Event Long Parameter ... * @param dparam: double, Event Double Parameter ... * @param sparam: string, Event String Parameter ... */ void HandleOnChartEvent( const int id, const long &lparam, const double &dparam, const string &sparam // ) { } // // Signal Event Handler ... void HandleOnSignalTriggered(XSignal &signal) { eaTradeManager.HandleSignal(signal); } /** * Check For Guard Event Handler ... * * @param guards: XGuard[] * * @return ( int ) */ int CheckForGuardTriggered(XGuard &guards[]) { // int result = 0; // if (!HasChild(eaSignallers)) { return result; } // int count = ArraySize(eaSignallers); for (int i = 0; i < count; i++) { // XGuard iGuards[]; int iGuardsCount = eaSignallers[i].CheckForGuard(iGuards); if (IsValidSize(iGuardsCount)) { // Copy( iGuards, guards, false // ); } // SpecifiedClean(iGuards); } // result = ArraySize(guards); // return result; } /** * Handle Guard Events ... * * @param action: ENUM_X_GUARD_ACTIONS * @param positions: XPosition[] */ void OnGuardedTriggered( ENUM_X_GUARD_ACTIONS action, XPosition &positions[] // ) { eaTradeManager.HandleGuardEvent(action, positions); } // // Check Can Analyse ... bool HandleCanAnalyseEventTriggered( string symbol, ENUM_TIMEFRAMES period, datetime time // ) { return eaTradeManager.CanAnalyse( symbol, period, time // ); } // // Trade Event Handlers ... /** * Handle Stop Loss Event Triggered ... * * @param deal: XDeal instance refrence, provides Triggered Deal info ... */ void HandleOnStopLossTriggered(const XDeal &deal) { eaTradeManager.HandleSL(deal); } /** * Handle Take Profit Event Triggered ... * * @param deal: XDeal instance refrence, provides Triggered Deal info ... */ void HandleOnTakeProfitTriggered(const XDeal &deal) { eaTradeManager.HandleTP(deal); } /** * Handle Position Force Closed Event ... * * @param ticket: ulong, triggered Positions ticket ... * @param position: XPosition instance refrence, Triggered Position ... * @param comment: string, Comment ... */ void HandleOnPositionForceClosed( const ulong ticket, const XPosition &position, const string comment // ) { eaTradeManager.HandleForceClose(position); } /** * Handle Position Partially Closed Event ... * * @param ticket: ulong, triggered Positions ticket ... * @param profit: double, Position Profit ... * @param comment: string, Comment ... */ void HandleOnPositionPartialClosed( const ulong ticket, const double profit, const string comment // ) { // eaTradeManager.HandlePartiallyClosed( ticket, profit, comment // ); } /** * Handle Deals Changed ... * * @param count: int, number of changes ... * if the count is positive, means new added ... * if the count is negative, means removed ... */ void HandleOnDealsChanged(int count) { } /** * Handle Orders Changed ... * * @param count: int, number of changes ... * if the count is positive, means new added ... * if the count is negative, means removed ... */ void HandleOnOrdersChanged(int count) { } /** * Handle Positions Changed ... * * @param count: int, number of changes ... * if the count is positive, means new added ... * if the count is negative, means removed ... */ void HandleOnPositionsChanged(int count) { } /** * Handle Position Modified Event ... * * @param ticket: ulong, triggered Positions ticket ... * @param profit: double, Position Profit ... * @param comment: string, Comment ... */ void HandleOnPositionModified( const ulong ticket, const double profit, const string comment // ) { } /** * Handle all Trades States Changed Event ... * * @param state: XOnTradeHandlerState instance refrence, Changed Trade State data ... */ void HandleOnTradeStateChanged(const XOnTradeHandlerState &state) { } // // Protected ... protected: // /** * Report Time Changes based on Given Configurations ... */ void HandleTimeReport() { // if (eaAlert == NULL) { return; } // // Monthly Report .... if (eaReportNewMonths && eaTimeTracker.IsNewMonth()) { // string msg = "New Month ..."; // eaAlert.SendAlert(msg); } // // Weekly Report .... if (eaReportNewWeeks && eaTimeTracker.IsNewWeek()) { // string msg = "New Week ..."; // eaAlert.SendAlert(msg); } // // Daily Report .... if (eaReportNewDays && eaTimeTracker.IsNewDay()) { // string msg = "New Day ..."; // eaAlert.SendAlert(msg); } // // Hourly Report .... if (eaReportNewHours && eaTimeTracker.IsNewHour()) { // string msg = "New Hour ..."; // eaAlert.SendAlert(msg); } } /** * Register Signaller ... */ void RegisterSignaller(XCXOM1SignallerBase *signaller) { // // Validate Signaller ... if (signaller == NULL) { return; } // // Attach Signaller OnSignal Event Handlers if Exists ... int count = ArraySize(mOnSignalEventHandlers); bool has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { signaller.AddOnSignalEventHandler(mOnSignalEventHandlers[i]); } } // // Attach Can Analyse Event Handler ... signaller.canAnalyseEventListener = canAnalyseEventHandler; // // Register Signaller ... Add( signaller, eaSignallers // ); } // // Private ... private: // // Props ... // TOnModify mOnModifyEventHandlers[]; TOnStopLoss mStopLossEventHandlers[]; TOnTakeProfit mTakeProfitEventHandlers[]; TOnForceClose mOnForceCloseEventHandlers[]; TOnDealsChanged mDealsChangedEventHandlers[]; TOnOrdersChanged mOrdersChangedEventHandlers[]; TOnPartialClose mOnPartialCloseEventHandlers[]; TOnPositionsChanged mPositionsChangedEventHandlers[]; TOnTradeStateChanged mTradeStateChangedEventHandlers[]; // TOnSignal mOnSignalEventHandlers[]; // Signal Recieved Event Handlers ... // XCXOM1SignallerBase *eaSignallers[]; // All Registered Signallers ... }; //