/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XC121SMCExpert // Description: provides all based classes for use ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://www.saherelm.ir" #property version "1.00" #property strict // // Imports ... #include "../../Classes/x-saherelm.x-expert.class.mq5" #include "../../Classes/x-saherelm.x-poi.class.mq5" // #include "../Classes/x-121.smc.xtradehandler.class.mq5" // // Definitions ... string XC121SMCExpertToken = "XC121SMCEA"; // // Implementation ... class XC121SMCExpert : public XCBaseExpert { // public: // // // Signal Event Listener ... TOnStopLoss OnPositionSLEventListener; TOnTakeProfit OnPositionTPEventListener; TOnPartialClose OnPositionPartialCloseEventListener; TOnModify OnPositionModifiedEventListener; TOnForceClose OnPositionForceCloseEventListener; // // Getter(s) / Setter(s) ... /** * Get Use Dynamic Volume State ... * * @return ( bool ) */ bool UseDynamicVolume() { return mUseDynamicVolume; } /** * Set Use Dynamic Volume State ... * * @param value: Boolean ... */ void UseDynamicVolume(bool value) { mUseDynamicVolume = value; } /** * Get Increase Volume Step ... * * @return ( double ) */ double DynamicVolumeStep() { return mDynamicVolumeStep; } /** * Set Increase Volume Step ... * * @param value: Double ... */ void DynamicVolumeStep(double value) { // if (value < 0.01) { value = 0.01; } // mDynamicVolumeStep = value; } /** * Get Balance Factor for Generate Dynamic Volume ... * * @return ( double ) */ double DynamicVolumeBalanceFactor() { return mDynamicVolumeBalanceFactor; } /** * Set Balance Factor for Generate Dynamic Volume ... * * @param value: Double ... */ void DynamicVolumeBalanceFactor(double value) { // if (value < 0) { value = 0; } // mDynamicVolumeBalanceFactor = value; } /** * Get Static Volume ... * * @return ( double ) */ double Volume() { return mVolume; } /** * Set Static Volume ... * * @param value: Double ... */ void Volume(double value) { // if (value < 0.01) { value = 0.01; } // mVolume = value; } // // Actions ... // // Override Actions ... /** * Apply Default Configurations ... */ void DefaultConfigure() override { // // Commons ... Slippage(10); TagPrefix(""); MagicNumber(1694056); // // Symbol ... SetSymbol(_Symbol); SetPeriod(_Period); MultiSymbol(false); Symbols("EURUSDb,GBPUSDb,USDJPYb,USDCHFb,DowJones30,XAUUSDb"); // // Signalling ... Disabled(false); AllowLong(true); AllowShort(true); // string tag = GetTag(); // // Alert ... SetAlertPrefix(tag); SetAlertLogAlerts(true); SetAlertPushAlerts(true); SetAlertMailAlerts(false); SetAlertEnableAlerts(true); SetAlertTerminalAlerts(false); // // Reports ... ReportNewDays(true); ReportNewWeeks(false); ReportNewHours(false); ReportNewMonths(false); // // Volume Default Configurations ... Volume(0.01); UseDynamicVolume(false); DynamicVolumeStep(0.01); DynamicVolumeBalanceFactor(200); } /** * Vaslidate Inputs ... * * @return ( bool ) */ bool ValidateInputs() override { // bool result = false; // string errMessage = ""; // bool isCommonValid = ( // Slippage() > 0 && MagicNumber() > 0 // ); if (!isCommonValid) { // errMessage += "common configurations error;" + "\n"; } // // Checking Volume ... bool isVolumeValid = true; if (UseDynamicVolume()) { // isVolumeValid = DynamicVolumeStep() > 0 && DynamicVolumeBalanceFactor() > 0; if (!isVolumeValid) { errMessage += "Dynamic Volume configurations error;" + "\n"; } } isVolumeValid = isVolumeValid && Volume() > 0; if (!isVolumeValid) { errMessage += "Static Volume configurations error;" + "\n"; } // result = // // Common ... isCommonValid && // // Volume Coniguration ... isVolumeValid && // // Otere ... true // ; // if (!result) { // // Since here Logger not Initiallized, we Use Raw Print Command ... errMessage = " Errors: \n" + errMessage; Alert(errMessage); } // return result; } // // Initializers and DeInitializers ... /** * Initial EA Requirements ... * * @return ( bool ) */ bool InitEA() override { // bool result = false; // // Initialize Indicator Helpers ... // string symbol = GetSymbol(); ENUM_TIMEFRAMES period = GetPeriod(); // mPOIDetector = new XCPOIDetector( symbol, period // ); mPOIDetector.Init(); // // Bar Timer ... XCTInputs ctInputs; ctInputs.Default(); // Default Configurations ... mCTHelper = new XCXCTHelper(); result = mCTHelper.Init( GetSymbol(), GetPeriod(), ctInputs // ); if (!result) { return result; } // // Bar Styles ... XCCInputs ccInputs; ccInputs.Default(); // Default Configurations ... mCCHelper = new XCXCCHelper(); result = mCCHelper.Init( GetSymbol(), GetPeriod(), ccInputs // ); if (!result) { return result; } // // Create Trader Instance and Configure it ... mTrader = new XCTrade( Slippage(), MagicNumber() // ); mTrader.AddOnStopLossEventHandler(OnPositionSLEventListener); mTrader.AddOnTakeProfitEventHandler(OnPositionTPEventListener); mTrader.AddOnModifyPositionEventHandler(OnPositionModifiedEventListener); mTrader.AddOnForceClosePositionEventHandler(OnPositionForceCloseEventListener); mTrader.AddOnPartialClosePositionEventHandler(OnPositionPartialCloseEventListener); // // // // Initialize Trade Handler ... // mTradeHandler = new XC121SMCTradeHandler(mTrader); // mTradeHandler.SaveTrades(true); // mTradeHandler.SaveSignals(true); // mTradeHandler.SaveConditions(true); // // // // Configure Alerts ... // mTradeHandler.SetAlertPrefix(GetTag()); // mTradeHandler.SetAlertEnableAlerts(GetAlertEnableAlerts()); // mTradeHandler.SetAlertLogAlerts(GetAlertLogAlerts()); // mTradeHandler.SetAlertMailAlerts(GetAlertMailAlerts()); // mTradeHandler.SetAlertPushAlerts(GetAlertPushAlerts()); // mTradeHandler.SetAlertTerminalAlerts(GetAlertTerminalAlerts()); // // // // TODO: Make This Configurable Later ... // // // mTradeHandler.DelayBarBetweenTwoSignal(3); // mTradeHandler.MaxAllowedSLToPause(0); // mTradeHandler.MaxAllowedSLReachedPauseDelay(HoursToSeconds(24)); // // // // Configure Trade Management ... // mTradeHandler.AllowLong(AllowLong()); // mTradeHandler.AllowShort(AllowShort()); // mTradeHandler.MaxAllowedLongs(0); // mTradeHandler.MaxAllowedShorts(0); // mTradeHandler.UseMaxAllowedTradesPerSymbol(true); // mTradeHandler.MaxDrawdownPercentForOpenTrades(5); // // // // Configure Position Protector ... // // // mTradeHandler.UseForceMomentumsInProtection(true); // mTradeHandler.DelayBarBetweenTwoSignal(2); // // // // Configure Hedging ... // mTradeHandler.AllowHedge(false); // mTradeHandler.HedgeMinVolumeStep(0.01); // mTradeHandler.MinimumOpenPositionsForHEHedge(2); // mTradeHandler.HedgeHEMinProfitPerVolumeStep(0.2); // mTradeHandler.HedgeBEMinProfitPerVolumeStep(0.06); // // // // In Profit Position Protecting ... // // // // Trail ... // mTradeHandler.AllowTrail(false); // mTradeHandler.TrailStep(15); // mTradeHandler.TrailStartDistance(30); // mTradeHandler.OnlyTrailUnprotected(true); // mTradeHandler.RemoveTPAfterTrailedLevel(4); // // // // Partial Close (In Profit) ... // mTradeHandler.PartialCloseInProfitDistance(0); // mTradeHandler.PartialCloseInProfitVolume(0); // // // // In Drawdown Positions Protecting ... // // // // Protect ... // mTradeHandler.AllowProtect(false); // mTradeHandler.ProtectionDelay(20); // mTradeHandler.MaxAllowedProtection(0); // mTradeHandler.UseEntryAsProtectionSL(true); // mTradeHandler.ProtectOnConditions(true); // mTradeHandler.AllowDirectionProtct(false); // mTradeHandler.ProtectionStartDistance(50); // mTradeHandler.ProtectionVolumeMultiplier(2); // // // // Partial Close (In Profit) ... // mTradeHandler.PartialCloseInDrawdownDistance(0); // mTradeHandler.PartialCloseInDrawdownVolume(0); // // Parsers ... XSymbolParser _symbolParser; // // Single Symbol ... if (!MultiSymbol()) { // // Register Strategy ... // // Create Class Instance ... // XCX121SMCBaseStrategy *iX121SMCStrategy; // iX121SMCStrategy = new XCX121SMCTestStrategy( // _Symbol, // _Period // // ); // // // iX121SMCStrategy.AddXSignalEventHandler(OnSignalEventListener); // // // ConfigureStrategy(iX121SMCStrategy); // RegisterStrategy(iX121SMCStrategy); } // // Multi Symbol ... else { // // Parse Symbols ... string symbols[]; int symbolsCount = SplitContent( symbols, Symbols() // ); result = IsValidSize(symbolsCount); if (!result) { return result; } // for (int i = 0; i < symbolsCount; i++) { // // Select Symbol ... string iSymbol = symbols[i]; // // Register Strategy Based On Symbol ... // // Parse Symbol ... bool isEURUSD = _symbolParser.IsEURUSD(_Symbol); bool isGBPUSD = _symbolParser.IsGBPUSD(_Symbol); bool isEURGBP = _symbolParser.IsEURGBP(_Symbol); bool isUSDCHF = _symbolParser.IsUSDCHF(_Symbol); bool isEURCHF = _symbolParser.IsEURCHF(_Symbol); bool isUSDJPY = _symbolParser.IsUSDJPY(_Symbol); bool isEURJPY = _symbolParser.IsEURJPY(_Symbol); bool isUSDCAD = _symbolParser.IsUSDCAD(_Symbol); bool isEURCAD = _symbolParser.IsEURCAD(_Symbol); bool isAUDUSD = _symbolParser.IsAUDUSD(_Symbol); bool isEURAUD = _symbolParser.IsEURAUD(_Symbol); bool isNZDUSD = _symbolParser.IsNZDUSD(_Symbol); bool isEURNZD = _symbolParser.IsEURNZD(_Symbol); // // Check Symbol Can Register or not ... bool canRegisterStrategy = true; // if (canRegisterStrategy) { // // // // Create Class Instance ... // XCX121SMCBaseStrategy *iX121SMCStrategy; // iX121SMCStrategy = new XCX121SMCTestStrategy( // iSymbol, // _Period // // ); // // // iX121SMCStrategy.AddXSignalEventHandler(OnSignalEventListener); // // // // Register Strategy ... // ConfigureStrategy(iX121SMCStrategy); // RegisterStrategy(iX121SMCStrategy); } } } // return result; } /** * Destroy all Initialized EA Requirements ... */ void DestroyEA() override { // delete mCTHelper; delete mCCHelper; // delete mTradeHandler; // // Clean(mStrategies); } /** * Call all Registered Strategies On Tick ... */ void HandleStrategiesOnTick() override { // ENUM_XPOI_EVENTS events[]; mPOIDetector.Update(events); // // int count = ArraySize(mStrategies); // if (!IsValidSize(count)) // { // return; // } // // // for (int i = 0; i < count; i++) // { // // // // Call Tick Handler Function ... // mStrategies[i].HandleTick(); // } } // // Event Handlers ... /** * Calls When a Position's SL Triggered ... * * @param deal: XDeal instance ... */ void HandleOnStopLossTriggered(const XDeal &deal) override { // // Finish ... // mTradeHandler.Finish(deal); // HandleReportBalance(); } /** * Calls When a Position's TP Triggered ... * * @param deal: XDeal instance ... */ void HandleOnTakeProfitTriggered(const XDeal &deal) override { // // Finish ... // mTradeHandler.Finish(deal); // HandleReportBalance(); } /** * Handle Force Close a Position ... * * @param ticket: Position Ticket ... * @param position: XPosition ... * @param comment: Closing Comment ... */ void HandleOnPositionForceClosed( const ulong ticket, const XPosition &position, const string comment // ) override { // // Finish ... // mTradeHandler.Finish( // ticket, // position, // comment // // ); // HandleReportBalance(); } /** * Reset All Paused Symbols on Each New Days ... */ void HandleOnNewDay() override { // mTradeHandler.ResumePausedSymbols(); } /** * Generate Identifier Tag ... * * @return ( string ) */ string GetTag() override { // string result = NULL; // string tagPrefix = TagPrefix(); if (IsValid(tagPrefix)) { result = tagPrefix; } else { result = ""; } // result = XCBaseExpertToken + result; // return result; } // protected: // // // Props ... // datetime mLastSignalOn; // XCPOIDetector *mPOIDetector; // // XC121SMCTradeHandler *mTradeHandler; // Trade Handler ... // XCX121SMCBaseStrategy *mStrategies[]; // Registere Strategies in EA ... // // Actions ... /** * Apply Volume Based On Configurations on Signal ... * * @param signal: XSignal instance */ void ApplyVolumeOnSignal(XSignal &signal) { // // Prepare Signal Dynamic Volume // if Provided ... if (UseDynamicVolume() && DynamicVolumeStep() > 0 && DynamicVolumeBalanceFactor() > 0) { // double dVolume = mTrader.GetDynamicVolume( signal.symbol, DynamicVolumeBalanceFactor(), DynamicVolumeStep() // ); // if (dVolume > 0) { signal.volume = dVolume; } else { signal.volume = Volume(); } } else { signal.volume = Volume(); } // // mTradeHandler.UpdateSignal(signal); } /** * Configure Startegy ... */ // void ConfigureStrategy(XCX121SMCBaseStrategy *&strategy) // { // // // if (strategy == NULL) // { // return; // } // // // // Configure Alerts ... // strategy.SetAlertPrefix(GetTag()); // strategy.SetAlertLogAlerts(GetAlertLogAlerts()); // strategy.SetAlertMailAlerts(GetAlertMailAlerts()); // strategy.SetAlertPushAlerts(GetAlertPushAlerts()); // strategy.SetAlertEnableAlerts(GetAlertEnableAlerts()); // strategy.SetAlertTerminalAlerts(GetAlertTerminalAlerts()); // // // // Confiugre Signalling ... // // // strategy.R2R(2); // strategy.AllowLong(AllowLong()); // strategy.AllowShort(AllowShort()); // // // if (Disabled()) // { // strategy.Disable(); // } // else // { // strategy.Enable(); // } // // // } /** * Register an Strategy in EA ... * * @param strategy: XCX121SMCBaseStrategy instance ... */ // void RegisterStrategy(XCX121SMCBaseStrategy *strategy) // { // // // if (strategy == NULL) // { // return; // } // // // ArrayResize( // mStrategies, // ArraySize(mStrategies) + 1 // // ); // // // mStrategies[ArraySize(mStrategies) - 1] = strategy; // } /** * Re Configure All Registered Strategies ... */ // void ReConfigureAllStrategies() // { // // // int count = ArraySize(mStrategies); // if (!IsValidSize(count)) // { // return; // } // // // for (int i = 0; i < count; i++) // { // // // ConfigureStrategy(mStrategies[i]); // } // } // private: // // // Props ... // // Volume Management ... bool mUseDynamicVolume; // Use Dynamic Volume ... double mDynamicVolumeStep; // Increase Volume Step ... double mDynamicVolumeBalanceFactor; // Balance Factor for Generate Dynamic Volume ... double mVolume; // Static Volume ... // }; //