/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class // ------------------------------------------------- // Name: XCXCATBEAExpert ... // Description: XCATB 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 XCATB Expert Class" #property strict // // Imports ... #include "../../Classes/x-saherelm.x-guard.class.mq5" #include "../../Classes/x-saherelm.x-trade.class.mq5" #include "../../Classes/x-saherelm.x-volume.class.mq5" #include "../Classes/xcatbea.signaller.class.mq5" #include "../Classes/xcatbea.x-trade.manager.class.mq5" // // Definitions ... // // Implementation ... class XCXCATBEAExpert : public XCBase { // // public ... public: // // Props ... // // Common ... long eaMagicNumber; // Magic Number int eaSlippage; // Slippgae string eaLogSuffix; // Log Suffix // // Detector ... // // Validating ... bool eaForceHasSwing; // Force Block to Has Propper Swing bool eaForceOBBarType; // Force Order Block to Has InDirectional Bars int eaMinRequiredOBBar; // Min Required OB Bar bool eaForceFVGBarType; // Force Fair Value Gaps Bars Type int eaLiquidityLoopback; // Liquidity Detection Loopback double eaMaxAllowedRange; // Max Allowed Order Block Range double eaMinAllowedRange; // Min Allowed Order Block Range bool eaForceHasFLiquidity; // Force Order Block To Has Reversal Liquidity bool eaForceHasRLiquidity; // Force Order Block to Has Following Liquidity bool eaValidateGapSequence; // Validate Fair Value Gaps Bar Sequences int eaMinAllowedBlockLength; // Min Allowed Block Length bool eaValidateBlockEdgeBreakout; // Validate Order Block Edge Breakeout // // Filtering ... bool eaFilterBasedOnKI; // Filter Based On KI Flats bool eaFilterBasedOnPV; // Filter Based On PV int eaBosLoopback; // PV Based Filtering BOS Lookup bool eaFilterBasedOnSar; // Filter Based On SAR bool eaForceSarSwitched; // SAR Switched on Sides for Filtering bool eaForceSarOnBothSide; // SAR Check on Both Sides for Filtering bool eaForceSarHasBreakout; // SAR Must Breakout bool eaForceSarHasReversalSide; // SAR Must Has Reversal Direction bool eaFilterBasedOnRSI; // Filter Based On RSI bool eaForceHasRSITrending; // RSI Must Has Trending bool eaForceHasRSIVPattern; // RSI Must Has Pattern bool eaForceHasRSICrossing; // RSI Must Has Crossing Levels bool eaFilterBasedOnADX; // Filter Based On ADX bool eaForceHasADXTrending; // ADX Must Has Trending bool eaForceHasADXCrossing; // ADX Must Has Crossing +DI/-DI bool eaFilterBasedOnATR; // Filter Based On ATR bool eaForceHasATRTrending; // ATR Must Has Trending bool eaForceHasATRBreakout; // ATR Must Has Breakout bool eaFilterBasedOnTrend; // Filter Based On Trend bool eaForceHasTrendDir; // TREND Must Has Following Direction bool eaForceHasTrendPlace; // TREND Place Based Filtering bool eaForceHasTrendChange; // TREND Change Filtering bool eaForceHasTrendTrending; // TREND Must Has Trending bool eaForceHasTrendRejection; // TREND Line Must Rejected bool eaForceHasTrendLineInside; // TREND Line has Inside bool eaForceHasTrendDirOnBothSide; // TREND Must Has Following Direction in Both Side bool eaFilterBasedOnDelta; // Filter Based On Delta bool eaFilterBasedOnVolume; // Filter Based On Volume bool eaFilterBasedOnSignalBar; // Filter Based on Signal Bar bool eaFilterBasedOnRoundPrice; // Filter Based On Round Prices bool eaFilterBasedOnHKSignalBar; // Filter Based On HK Signal Bar // // Signal ... int eaSignalR2R; // Risk Reward Ratio double eaSLATRMultiplier; // ATR Multiplier for SL // // 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 // // Management ... string eaSymbols; // Allowed Trading Symbols bool eaAllowGuards; // Allow Guards bool eaAllowTrade; // Allow Trade on Signals bool eaAllowLongs; // Allow Long Trades bool eaAllowShorts; // Allow Short Trades string eaSessions; // Active Sessions ENUM_XCATBEA_TRADE_RESTRICTION_PERIOD eaRestrictionsPeriod; // Restrictions Period int eaMaxAllowedTPs; // Max Allowed TP(s) in Restrictions Period int eaMaxAllowedSLs; // Max Allowed SL(s) in Restrictions Period int eaMaxAllowedTrades; // Max Allowed Trades in Restrictions Period int eaMaxAllowedPositions; // Max Allowed Same Time Trades double eaMaxAllowedSpread; // Max Allowed Spread For Trade double eaMaxAllowedDrawdownFactor; // Max Allowed DrawDown for Trade string eaCloseAllOpenTradesAt; // Close All Open Trades per Day At Specified Time // // Alert ... bool eaEnableAlerts; // Enable Alerts bool eaLogAlerts; // Log Alerts bool eaMailAlerts; // Mail Alerts bool eaPushAlerts; // Push Alerts bool eaTerminalAlerts; // Terminal Alerts // // Time Report ... 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 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 // // Trade Event Handlers ... TOnModify OnModifyEventHandler; TOnStopLoss OnStopLossEventHandler; TOnForceClose OnForceCloseEventHandler; TOnTakeProfit OnTakeProfitEventHandler; TOnPartialClose OnPartialCloseEventHandler; TOnDealsChanged OnDealsChangedEventHandler; TOnOrdersChanged OnOrdersChangedEventHandler; TOnPositionsChanged OnPositionsChangedEventHandler; TOnTradeStateChanged OnTradeStateChangedEventHandler; // // Requirements ... // XCAlert *eaAlert; // EA Scope Alert Handler ... XCTrade *eaTrade; // EA Scope Trade Handler ... XCGuard *eaGuard; // EA Scope Guard Handler ... XCVolume *eaVolume; // EA Scope Voluem Handler ... XTimeTracker eaTimeTracker; // EA Scope Time Tracker ... XCXCATBEASignaller *eaSignallers[]; // EA Signallers Collection ... XCXCATBEATradeManager *eaTradeManager; // EA Scope Trade Manager ... // // Tools / Actions / Handlers ... // // Validators ... /** * Validate Inputs ... * * @return ( bool ) */ bool ValidateInputs() { // bool result = false; // // Implement all Inputs Validation ... result = eaMagicNumber > 0 && eaSignalR2R > 0; // 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; } // // Initialize Alert Handler ... eaAlert = new XCAlert(); eaAlert.SetPrefix(eaLogSuffix); eaAlert.SetLogAlerts(eaLogAlerts); eaAlert.SetMailAlerts(eaMailAlerts); eaAlert.SetPushAlerts(eaPushAlerts); 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, eaMaxAllowedSpread, eaMaxAllowedPositions, eaMaxAllowedDrawdownFactor // ); eaTrade.AddOnStopLossEventHandler(OnStopLossEventHandler); eaTrade.AddOnTakeProfitEventHandler(OnTakeProfitEventHandler); eaTrade.AddOnModifyPositionEventHandler(OnModifyEventHandler); eaTrade.AddOnDealsChangedEventHandler(OnDealsChangedEventHandler); eaTrade.AddOnOrdersChangedEventHandler(OnOrdersChangedEventHandler); eaTrade.AddOnForceClosePositionEventHandler(OnForceCloseEventHandler); eaTrade.AddOnPartialClosePositionEventHandler(OnPartialCloseEventHandler); eaTrade.AddOnPositionsChangedEventHandler(OnPositionsChangedEventHandler); eaTrade.AddOnTradeStateChangedEventHandler(OnTradeStateChangedEventHandler); // // Initialize Guard Handler ... eaGuard = new XCGuard( eaTrade // ); // eaGuard.SetAlertPrefix(eaLogSuffix); eaGuard.SetAlertLogAlerts(eaLogAlerts); eaGuard.SetAlertMailAlerts(eaMailAlerts); eaGuard.SetAlertPushAlerts(eaPushAlerts); eaGuard.SetAlertEnableAlerts(eaEnableAlerts); eaGuard.SetAlertTerminalAlerts(eaTerminalAlerts); // // Initialize Trae Manager ... eaTradeManager = new XCXCATBEATradeManager( eaTrade // ); // eaTradeManager.SetAlertPrefix(eaLogSuffix); eaTradeManager.SetAlertLogAlerts(eaLogAlerts); eaTradeManager.SetAlertMailAlerts(eaMailAlerts); eaTradeManager.SetAlertPushAlerts(eaPushAlerts); eaTradeManager.SetAlertEnableAlerts(eaEnableAlerts); eaTradeManager.SetAlertTerminalAlerts(eaTerminalAlerts); // eaTradeManager.SaveWins(eaSaveWins); eaTradeManager.SaveLosts(eaSaveLosts); eaTradeManager.SaveTrades(eaSaveTrades); eaTradeManager.SaveSignals(eaSaveSignals); // // Setting Trade Reports ... eaTradeManager .SetTradeReports( eaReportTrades, eaReportSignals, eaReportProtector, eaReportAfterTradesBalance // ); // // Setting Trade Permissions ... eaTradeManager .SetTradePermissions( eaAllowTrade, eaAllowLongs, eaAllowShorts // ); // // Setting Trade Restrictions ... eaTradeManager .SetTradeRestrictions( eaRestrictionsPeriod, eaMaxAllowedTPs, eaMaxAllowedSLs, eaMaxAllowedTrades // ); // // Parsing Symbols ... // string symbols[]; int symbolsCount = 0; if (IsValid(eaSymbols)) { // symbolsCount = SplitContent( symbols, eaSymbols, "," // ); } // // Adding Default Symbol, if eaSymbols not Filled ... if (!HasChild(symbols)) { // Add( _Symbol, symbols // ); // symbolsCount = ArraySize(symbols); } bool hasSymbols = HasChild(symbols); // // Initializing Sessions ... string sessions[]; int sessionsCount = 0; bool hasSession = IsValid(eaSessions); if (hasSession) { // // Extract Per Symbol Sessions ... sessionsCount = SplitContent( sessions, eaSessions, "," // ); // // Try to Extract Start and End Times Series ... hasSession = IsValidSize(sessionsCount); if (hasSession) { // // Iterate Sessions ... for (int i = 0; i < sessionsCount; i++) { // // Ignore unused Cases and Extracts only Content ... string iSessionDescriptorStr = ExtractString(sessions[i]); bool isInited = IsValid(iSessionDescriptorStr); if (isInited) { // // Extract Session Descriptor Data ... string parts[]; int partsCount = SplitContent( parts, iSessionDescriptorStr, "_" // ); isInited = IsValidSize(partsCount) && partsCount == 3; if (isInited) { // string iName = parts[0]; string iStart = parts[1]; string iEnd = parts[2]; isInited = IsValid(iName) && IsValid(iStart) && IsValid(iEnd); if (isInited) { // // Set Active Session Per Symbols ... if (hasSymbols) { // for (int j = 0; j < symbolsCount; j++) { // eaTradeManager .SetTradeSession( symbols[j], iStart, iEnd, iName // ); } } } } } } } } // // Initialize Signallers ... if (hasSymbols) { // // Prepare Signaller Inputs ... XCATBEASignallerInputs iSignallerInputs; // // Common Configs ... // // Provider Name ... iSignallerInputs.period = _Period; iSignallerInputs.allowDraws = true; iSignallerInputs.provider = "XTRGB"; iSignallerInputs.allowGuards = eaAllowGuards; iSignallerInputs.riskToRewardRatio = eaSignalR2R; iSignallerInputs.slATRMultiplier = eaSLATRMultiplier; // // CATB Indicator ... iSignallerInputs.catbInputs.Default(); iSignallerInputs.catbInputs.Hide(); // // Make Available all Requirement Buffers of XCATB indicator ... iSignallerInputs.catbInputs.showPV = true; iSignallerInputs.catbInputs.showKI = true; iSignallerInputs.catbInputs.showATRBand = true; iSignallerInputs.catbInputs.showPVGolden = true; // // Prepare Trigger Block Validations ... // iSignallerInputs.validations.forceHasSwing = eaForceHasSwing; iSignallerInputs.validations.forceOBBarType = eaForceOBBarType; iSignallerInputs.validations.minRequiredOBBar = eaMinRequiredOBBar; iSignallerInputs.validations.forceFVGBarType = eaForceFVGBarType; iSignallerInputs.validations.liquidityLoopback = eaLiquidityLoopback; iSignallerInputs.validations.maxAllowedRange = eaMaxAllowedRange; iSignallerInputs.validations.minAllowedRange = eaMinAllowedRange; iSignallerInputs.validations.forceHasFLiquidity = eaForceHasFLiquidity; iSignallerInputs.validations.forceHasRLiquidity = eaForceHasRLiquidity; iSignallerInputs.validations.validateGapSequence = eaValidateGapSequence; iSignallerInputs.validations.minAllowedBlockLength = eaMinAllowedBlockLength; iSignallerInputs.validations.validateBlockEdgeBreakout = eaValidateBlockEdgeBreakout; // // Prepare Trigger Block Filters ... // iSignallerInputs.filters.filterBasedOnPV = eaFilterBasedOnPV; iSignallerInputs.filters.bosLoopback = eaBosLoopback; // iSignallerInputs.filters.filterBasedOnSar = eaFilterBasedOnSar; iSignallerInputs.filters.forceSarSwitched = eaForceSarSwitched; iSignallerInputs.filters.forceSarOnBothSide = eaForceSarOnBothSide; iSignallerInputs.filters.forceSarHasBreakout = eaForceSarHasBreakout; iSignallerInputs.filters.forceSarHasReversalSide = eaForceSarHasReversalSide; // iSignallerInputs.filters.filterBasedOnRSI = eaFilterBasedOnRSI; iSignallerInputs.filters.forceHasRSITrending = eaForceHasRSITrending; iSignallerInputs.filters.forceHasRSIVPattern = eaForceHasRSIVPattern; iSignallerInputs.filters.forceHasRSICrossing = eaForceHasRSICrossing; // iSignallerInputs.filters.filterBasedOnADX = eaFilterBasedOnADX; iSignallerInputs.filters.forceHasADXTrending = eaForceHasADXTrending; iSignallerInputs.filters.forceHasADXCrossing = eaForceHasADXCrossing; // iSignallerInputs.filters.filterBasedOnATR = eaFilterBasedOnATR; iSignallerInputs.filters.forceHasATRTrending = eaForceHasATRTrending; iSignallerInputs.filters.forceHasATRBreakout = eaForceHasATRBreakout; // iSignallerInputs.filters.filterBasedOnTrend = eaFilterBasedOnTrend; iSignallerInputs.filters.forceHasTrendDir = eaForceHasTrendDir; iSignallerInputs.filters.forceHasTrendPlace = eaForceHasTrendPlace; iSignallerInputs.filters.forceHasTrendChange = eaForceHasTrendChange; iSignallerInputs.filters.forceHasTrendTrending = eaForceHasTrendTrending; iSignallerInputs.filters.forceHasTrendRejection = eaForceHasTrendRejection; iSignallerInputs.filters.forceHasTrendLineInside = eaForceHasTrendLineInside; iSignallerInputs.filters.forceHasTrendDirOnBothSide = eaForceHasTrendDirOnBothSide; // iSignallerInputs.filters.filterBasedOnKI = eaFilterBasedOnKI; iSignallerInputs.filters.filterBasedOnDelta = eaFilterBasedOnDelta; iSignallerInputs.filters.filterBasedOnVolume = eaFilterBasedOnVolume; iSignallerInputs.filters.filterBasedOnSignalBar = eaFilterBasedOnSignalBar; iSignallerInputs.filters.filterBasedOnRoundPrice = eaFilterBasedOnRoundPrice; iSignallerInputs.filters.filterBasedOnHKSignalBar = eaFilterBasedOnHKSignalBar; // // Loop through Symbols and Initialize Signaller // for it, then Attached it to eaSignallers ... for (int i = 0; i < symbolsCount; i++) { // iSignallerInputs.symbol = symbols[i]; if (iSignallerInputs.IsValid()) { // // Initialize Signaller ... XCXCATBEASignaller *iSignaller = new XCXCATBEASignaller(iSignallerInputs); // // Add it to the Signallers List ... Add( iSignaller, eaSignallers // ); // ZeroMemory(iSignaller); } } // // Cleanup Resources ... iSignallerInputs.Clean(); } // // since atleast one Signaller must // exists to Expert works ... // we check it as Last Step ... result = hasSymbols && HasChild(eaSignallers); // return result; } /** * Handle De Initialization of Expert ... */ void HandleOnDeInit() { // delete eaAlert; ZeroMemory(eaAlert); // delete eaTrade; ZeroMemory(eaTrade); // delete eaGuard; ZeroMemory(eaGuard); // delete eaVolume; ZeroMemory(eaVolume); // eaTimeTracker.Clean(); // Clean(eaSignallers); // delete eaTradeManager; ZeroMemory(eaTradeManager); } /** * Handle Tick ... */ void HandleOnTick() { // // Time Report Handling ... HandleTimeReport(); // // Position Management / Protections Handling ... eaTradeManager.Manage(); // // Check Signallers Registered ... bool has = HasChild(eaSignallers); if (!has) { return; } // // Define Collection of Requirements ... XGuard guards[]; XCATBEAStrategyConditions conditions[]; // // Loop through Registered Signallers to Proccess Ticks and // Collect: // - Guards; // - Triggered Conditions; // - ... int count = ArraySize(eaSignallers); for (int i = 0; i < count; i++) { // // Retrieve indexed Signaller ... XCXCATBEASignaller *iSignaller = eaSignallers[i]; // string iSymbol = iSignaller.GetSymbol(); string iProvider = iSignaller.GetProvider(); ENUM_TIMEFRAMES iPeriod = iSignaller.GetPeriod(); // // Now we Have to Check Handle Tick Resoult ... // // Requirements ... XGuard iGuards[]; // Hold Provided Guards ... XPosition iPositions[]; // Retrieve Signaller Positions ... XCATBEAStrategyConditions iConditions; // Recieve Triggered Conditions ... // // Reading Signaller Positions ... eaTradeManager.GetPositions( iPositions, iSymbol, iProvider, iPeriod // ); // // Processing Tick for Signaller ... iSignaller.ProcessTick( iPositions, iGuards, iConditions // ); // // Check Results ... has = HasChild(iGuards); if (has) { // Copy( iGuards, guards, false // Force Clean ... ); } // // Check Triggered Conditions ... has = iConditions.IsValid() && iConditions.IsSetuped() && iConditions.CanTrigger(); if (has) { // AddRef( iConditions, conditions // ); } // // Cleanup Resources ... Clean(iGuards); Clean(iPositions); iConditions.Clean(); } // // Do Actions Based on Provided Info ... // // Guards ... has = HasChild(guards); if (has) { // // Handle Guards Firing ... eaGuard.DoGuards(guards); } // // Triggers ... has = HasChild(conditions); if (has) { // // Handle Conditions Triggering ... TriggerConditions(conditions); } // // Cleanup Resources ... // Clean(guards); Clean(conditions); } /** * Handle Trade ... */ void 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 // ) { } // // Trade Event Handlers ... /** * Handle Stop Loss Event Triggered ... * * @param deal: XDeal instance refrence, provides Triggered Deal info ... */ void HandleOnStopLossTriggered(const XDeal &deal) { } /** * Handle Take Profit Event Triggered ... * * @param deal: XDeal instance refrence, provides Triggered Deal info ... */ void HandleOnTakeProfitTriggered(const XDeal &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 // ) { } /** * 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 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 // ) { } /** * 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 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); } } /** * Update Signal Targets ... */ void UpdateSignalTargets(XSignal &signal) { // bool has = signal.IsValid(); if (!has) { return; } // // Clean Signal Targets ... Clean(signal.targets); // // Calculate Requirements ... double r2r = eaSignalR2R > 0 ? eaSignalR2R : 1; double risk = signal.GetRisk(); double reward = risk * r2r; // double isLong = IsLong(signal.type); // // Handling Signal TP ... signal.tp = isLong ? signal.entry + reward : signal.entry - reward; // // Try to Apply Money Management ... // // Sort Targets ... ENUM_X_DIRECTION sortingDir = isLong ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; ApplySortOnTargets( sortingDir, signal.targets // ); } /** * Convert a Triggered Conditions to Signal and * Execute it ... */ void TriggerConditions(XCATBEAStrategyConditions &conditions[]) { // int count = 0; bool has = false; // has = HasChild(conditions); if (!has) { return; } // count = ArraySize(conditions); for (int i = 0; i < count; i++) { // // Retrieve Indexed Conditions ... XCATBEAStrategyConditions iConditions = conditions[i]; // // Prepare Signal Based on Conditions ... XSignal iSignal; // // Check if a Trigger Block Attached and Has Signal ... // use it ... has = iConditions.IsValid() && iConditions.IsSetuped() && iConditions.CanTrigger() && iConditions.triggerBlock.IsValid() && iConditions.triggerBlock.signal.IsValid(); if (has) { iSignal = iConditions.triggerBlock.signal; } // // if we Have any other Signalling senarios we can Handle them here ... // // Validate Signal ... has = iSignal.IsValid(); if (has) { // // Retrieve Signal Type ... bool isLong = IsLong(iSignal.type); // // Update Signal Entry ... iSignal.entry = GetEntry( iSignal.symbol, iSignal.type // ); // // Update Signal Targets ... UpdateSignalTargets(iSignal); // // Handle Volume Management ... double iVolume = eaVolume.CalculateVolume(iSignal); has = iVolume > X_MIN_VOLUME && iVolume != iSignal.volume; if (has) { iSignal.volume = iVolume; } // // Execute Signal ... has = eaTradeManager.Execute( iSignal, iConditions // ); } // // Cleanup Resources ... // iSignal.Clean(); iConditions.Clean(); } } // // private ... private: // // }; //