From e12f7f72c596fc562ee77c6cbc1ccdccbd775667 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Fri, 14 Jun 2024 05:39:49 +0330 Subject: [PATCH] last works ... --- Classes/x-saherelm.x121.setup.class.mq5 | 268 +++++++++++++++++++++--- Classes/x-saherelm.x121.setup.xea.mq5 | 92 ++++---- Classes/x-saherelm.xczone.class.mq5 | 63 +++++- Classes/x-saherelm.xea.class.mq5 | 255 +++++++++++++++++++++- Classes/x-saherelm.xtrade.class.mq5 | 1 + Experts/x-saherelm.x121.ea.mq5 | 28 ++- Libraries/x-saherelm.xtrade.lib.mq5 | 45 ++++ 7 files changed, 655 insertions(+), 97 deletions(-) diff --git a/Classes/x-saherelm.x121.setup.class.mq5 b/Classes/x-saherelm.x121.setup.class.mq5 index 4f392757..60cff64b 100644 --- a/Classes/x-saherelm.x121.setup.class.mq5 +++ b/Classes/x-saherelm.x121.setup.class.mq5 @@ -25,9 +25,8 @@ // #include "../Libraries/x-saherelm.xtrade.lib.mq5" - -// #include "../Classes/x-saherelm.xalert.class.mq5" +#include "../Classes/x-saherelm.xczone.class.mq5" // #include "../Helpers/x-saherelm.xtd.helper.mq5" @@ -727,6 +726,30 @@ struct X121SignalGenerator { // string version; + double hotLevels[]; + + // + // Constructor ... + void X121SignalGenerator() + { + // + Add( + 0.25, + hotLevels // + ); + + // + Add( + 0.20, + hotLevels // + ); + + // + Add( + 0.15, + hotLevels // + ); + } // // Retrieve OSC Based Long Verifications ... @@ -1326,8 +1349,8 @@ struct X121SignalGenerator result = // pusher >= 1 && - !isOSCShortVerified && - bullishScore > bearishScore * 2 && + // !isOSCShortVerified && + // bullishScore > bearishScore * 2 && ( // long1 @@ -1923,8 +1946,8 @@ struct X121SignalGenerator result = // pusher >= 1 && - !isOSCLongVerified && - bearishScore > bullishScore * 2 && + // !isOSCLongVerified && + // bearishScore > bullishScore * 2 && ( // short1 @@ -2014,7 +2037,7 @@ struct X121SignalGenerator // // TODO Filter ... - result = provider == ToString(PROVIDER_XVLM); + result = true; // provider == ToString(PROVIDER_XVLM); // return result; @@ -2033,7 +2056,7 @@ struct X121SignalGenerator // // TODO Filter ... - result = provider == ToString(PROVIDER_XVLM); + result = true; // provider == ToString(PROVIDER_XVLM); // return result; @@ -2186,6 +2209,39 @@ struct X121SignalGenerator return result; } + // + // Calculate Ticks Zone ... + XSCZones *zones = new XSCZones( + signal.symbol, + signal.period // + ); + + // + XSCZonesInput zonesInput; + zonesInput.length = 71; + zonesInput.numberOfZones = 10; + + // + zonesInput.AddLevelColor( + hotLevels[0], + clrRed // + ); + zonesInput.AddLevelColor( + hotLevels[1], + clrOrange // + ); + zonesInput.AddLevelColor( + hotLevels[2], + clrLightCoral // + ); + + // + bool canUseZones = zones.Init(zonesInput); + if (canUseZones) + { + signal.zones = zones; + } + // // Generate Support Signals ... if (_useSupport) @@ -2203,40 +2259,202 @@ struct X121SignalGenerator // void GenerateSupportSignals( XSignal &signal // Source Signal for Support Generating ... - ) { + ) + { // // Validate Signal ... - if (!signal.IsValid()) { + if (!signal.IsValid()) + { return; } + // + // Retrieve Signal Direction ... + bool isLong = IsLong(signal.type); + + // + bool canUseZones = signal.zones != NULL; + // // Check Signal Has TP and SL ... - if (signal.tp > 0 && signal.sl > 0) { + if (signal.tp > 0 && signal.sl > 0) + { // // Here we Can Provide Orders based on Signal TP and SL ... - // - // Retrieve Signal Direction ... - bool isLong = IsLong(signal.type); - // // Calculate TP/Entry Distance ... - double tpDistance = - isLong - ? signal.tp - signal.entry - : signal.entry - signal.tp; - + double tpDistance = + isLong + ? signal.tp - signal.entry + : signal.entry - signal.tp; + // // Calculate Recovery Zone Step ... double slDistance = isLong - ? signal.entry - signal.sl - : signal.sl - signal.entry; - + ? signal.entry - signal.sl + : signal.sl - signal.entry; + } + + // + // Add Zone Based Signals ... + if (canUseZones) + { // - // Calculate Ticks Zone ... - + // signal.zones.DrawZones(); + + // + // Try to Find a Hot Level based on Signal Direction + // as Resistance ... + + // + XSignal rSignal; // Recovery Signal ... + + // + double rSL = 0; // Recovery Stop Loss ... + double rTP = 0; // Recovery Take Profit ... + double rEntry = 0; // Recovery Entry Point ... + double rVolume = signal.volume * 2; // Recovery Volume ... + ENUM_POSITION_TYPE rType; // Recovery Signal Type ... + ENUM_X_ORDER_MODES rMode; // Recovery Signal Mode ... + bool isSignalPrepared = false; // Check Signal Preparation Succeed ... + + // + double onePointValue = PointToPrice(1, signal.symbol); + + // + for (int i = 0; i < signal.zones.CountZones(); i++) + { + // + // Retrieve Indexed Zone ... + XSCZone *iZone = signal.zones.GetZone(i); + + // + // Check Zone is Hot Zone or not ... + bool isHotZone = false; + for (int j = 0; j < ArraySize(hotLevels); j++) + { + // + isHotZone = (iZone.percent / 100 >= hotLevels[j]); + if (isHotZone) + { + break; + } + } + + // + // Prevent Moving Forward if there isn't Hot Zone ... + if (!isHotZone) + { + continue; + } + + // + if (iZone.high > signal.entry && iZone.low > signal.entry) + { + // + // Here we can Use Resistance Zone as SL Recovery for + // Short Positions ... + if (!isLong && + (signal.sl <= 0 + ? true + : iZone.high < signal.sl && iZone.low < signal.sl)) + { + // + // Opposit Support on Resistance Upper ... + + // + rTP = signal.sl <= 0 + ? iZone.high - (onePointValue * 15) + : signal.sl; + rSL = signal.entry; + rType = POSITION_TYPE_BUY; + rEntry = iZone.high + (onePointValue * 2); + rMode = X_ORDER_MODE_STOP; + + // + isSignalPrepared = rSignal.Prepare( + signal.symbol, + signal.provider, + signal.period, + rType, + rMode, + rEntry, + rVolume, + rSL, + rTP // + ); + if (isSignalPrepared) + { + // + AddRef( + rSignal, + signal.supports // + ); + + // + rSignal.Clean(); + + // + rSL = 0; + rTP = 0; + rEntry = 0; + isSignalPrepared = false; + } + + // + // Support Directional on Resistance Lower ... + + // + rTP = signal.entry; + rSL = signal.sl <= 0 + ? signal.entry - (onePointValue * 15) + : signal.sl; + rEntry = iZone.low - (onePointValue * 2); + rVolume = signal.volume * 3; + rType = POSITION_TYPE_SELL; + rMode = X_ORDER_MODE_LIMIT; + + // + isSignalPrepared = rSignal.Prepare( + signal.symbol, + signal.provider, + signal.period, + rType, + rMode, + rEntry, + rVolume, + rSL, + rTP // + ); + if (isSignalPrepared) + { + // + AddRef( + rSignal, + signal.supports // + ); + + // + rSignal.Clean(); + + // + rSL = 0; + rTP = 0; + rEntry = 0; + isSignalPrepared = false; + rVolume = signal.volume * 2; + } + } + } + + // + if (iZone.high < signal.entry && iZone.low < signal.entry) + { + // + } + } } } diff --git a/Classes/x-saherelm.x121.setup.xea.mq5 b/Classes/x-saherelm.x121.setup.xea.mq5 index f7fa8990..f2e2cf15 100644 --- a/Classes/x-saherelm.x121.setup.xea.mq5 +++ b/Classes/x-saherelm.x121.setup.xea.mq5 @@ -25,7 +25,6 @@ // #include "../Classes/x-saherelm.xea.class.mq5" -#include "../Classes/x-saherelm.xczone.class.mq5" #include "../Classes/x-saherelm.x121.setup.cycle.class.mq5" // @@ -1263,9 +1262,13 @@ public: // Check Final Bullish and Bearish Score ... bool isScorePassed = // - IsLong(cSignal.type) - ? mBullishScore > (mBearishScore * 2) - : mBearishScore > (mBullishScore * 2) + true + // isLong + // ? mBearishScore > mBullishScore + // : mBullishScore > mBearishScore + // isLong + // ? mBullishScore > (mBearishScore * 2) + // : mBearishScore > (mBullishScore * 2) // ; @@ -1312,9 +1315,13 @@ public: // Check Final Bullish and Bearish Score ... bool isScorePassed = // - IsLong(cSignal.type) - ? mBullishScore > (mBearishScore * 2) - : mBearishScore > (mBullishScore * 2) + true + // isLong + // ? mBearishScore > mBullishScore + // : mBullishScore > mBearishScore + // isLong + // ? mBullishScore > (mBearishScore * 2) + // : mBearishScore > (mBullishScore * 2) // ; @@ -1361,9 +1368,13 @@ public: // Check Final Bullish and Bearish Score ... bool isScorePassed = // - IsLong(cSignal.type) - ? mBullishScore > (mBearishScore * 2) - : mBearishScore > (mBullishScore * 2) + true + // isLong + // ? mBearishScore > mBullishScore + // : mBullishScore > mBearishScore + // isLong + // ? mBullishScore > (mBearishScore * 2) + // : mBearishScore > (mBullishScore * 2) // ; @@ -1410,9 +1421,13 @@ public: // Check Final Bullish and Bearish Score ... bool isScorePassed = // - IsLong(cSignal.type) - ? mBullishScore > (mBearishScore * 2) - : mBearishScore > (mBullishScore * 2) + true + // isLong + // ? mBearishScore > mBullishScore + // : mBullishScore > mBearishScore + // isLong + // ? mBullishScore > (mBearishScore * 2) + // : mBearishScore > (mBullishScore * 2) // ; @@ -1459,9 +1474,13 @@ public: // Check Final Bullish and Bearish Score ... bool isScorePassed = // - IsLong(cSignal.type) - ? mBullishScore > (mBearishScore * 2) - : mBearishScore > (mBullishScore * 2) + true + // isLong + // ? mBearishScore > mBullishScore + // : mBullishScore > mBearishScore + // isLong + // ? mBullishScore > (mBearishScore * 2) + // : mBearishScore > (mBullishScore * 2) // ; @@ -1632,41 +1651,12 @@ public: // // Do all State Management here ... - // // - // // Check State Interval ... - // static datetime lastStateManaged = NULL; - - // // - // datetime cTime = TimeCurrent(); - // int interval = PeriodSeconds(PERIOD_M3); - - // // - // bool canManageState = - // // - // !IsValid(lastStateManaged) - // ? true - // : (int)cTime >= (int)lastStateManaged + interval; - // // - // ; - // if (!canManageState) - // { - // return result; - // } - - // // - // lastStateManaged = cTime; - - // // - // // Retrieve Account Profit ... - // double profit = mTrader.Profit(); - - // // - // // Check EQM Orders and Handle Hedging ... - // DoEQMHedge(); + // + DoEQMHedge(); // // Handle Close All Positions on Specific Time ... - HandleEQMCloseOnSpecificTime(); + DoEQMCloseOnSpecificTime(); // // if Returns true, Signal Execution failed ... @@ -2074,10 +2064,6 @@ private: // // EQM Functions ... - // - // Check and Hedge ... - void DoEQMHedge() {} - // // Remove Untriggered EQM Orders ... void RemoveEQMOrders() @@ -2309,7 +2295,7 @@ private: // // Handle Close Trades on Specific Time ... - void HandleEQMCloseOnSpecificTime() + void DoEQMCloseOnSpecificTime() { // bool canClose = CanCloseOnTime(); diff --git a/Classes/x-saherelm.xczone.class.mq5 b/Classes/x-saherelm.xczone.class.mq5 index cff23ddc..3325003f 100644 --- a/Classes/x-saherelm.xczone.class.mq5 +++ b/Classes/x-saherelm.xczone.class.mq5 @@ -24,6 +24,7 @@ #include #include #include "../Classes/x-saherelm.base.class.mq5" +#include "../Libraries/x-saherelm.draw.lib.mq5" #include // @@ -135,6 +136,7 @@ struct XSCZonesInput tmpLevels // ); ArraySort(tmpLevels); + ArrayReverse(tmpLevels); // // Size of Looping ... @@ -186,6 +188,7 @@ public: double high; double low; int ticks; + double percent; // // Compare Two Zone With Each Other ... @@ -356,7 +359,7 @@ public: // // Find Lowest Value in Range ... - mRangeLow = mLows[ArrayMaximum(mLows)]; + mRangeLow = mLows[ArrayMinimum(mLows)]; // double mRangeSize = GetRange(); @@ -419,10 +422,28 @@ public: } } + // + // Calculating Zone Percents ... + for (int i = 0; i < mZones.Total(); i++) + { + // + XSCZone *iZone = mZones.At(i); + + // + double percent = CalculateZoneTickPercent(iZone); + iZone.percent = percent; + } + // mZones.Sort(); } + // + int CountZones() + { + return mZones.Total(); + } + // XSCZone *GetZone(int index) { @@ -483,12 +504,24 @@ public: return result; } + // + mZones.Sort(); + + // + int ticksCount = CountTicks(); + result = IsValidSize(ticksCount); + if (!result) + { + return result; + } + // double levels[]; color colors[]; mInputs.RetrieveSortedLevels( levels, - colors); + colors // + ); int levelsCount = ArraySize(levels); int colorsCount = ArraySize(colors); bool canSetLevels = IsValidSize(levelsCount) && @@ -526,7 +559,7 @@ public: // // Set Default Rectangle Color ... - iRect.Color(defZoneBGColor); + // iRect.Color(defZoneBGColor); iRect.Fill(true); // @@ -548,13 +581,31 @@ public: iLabel.Color(defZoneLBLColor); // - double iPercentage = CalculateZoneTickPercent(iZone); - iLabel.Description(ToString(iPercentage) + "%"); + iLabel.Description(ToString(iZone.percent) + "%"); // // Set Levels and Colors if Provided ... - if (canSetLevels) { + if (canSetLevels) + { + // + color iRectColor = defZoneBGColor; + for (int z = 0; z < levelsCount; z++) + { + // + double zLevel = levels[z]; + color zColor = colors[z]; + // + if (iZone.ticks >= ticksCount * zLevel) + { + // + iRectColor = zColor; + break; + } + } + + // + iRect.Color(iRectColor); } // diff --git a/Classes/x-saherelm.xea.class.mq5 b/Classes/x-saherelm.xea.class.mq5 index 08866b55..3a8e7d50 100644 --- a/Classes/x-saherelm.xea.class.mq5 +++ b/Classes/x-saherelm.xea.class.mq5 @@ -1825,6 +1825,12 @@ public: return mTrader.GetMagicNumber(); } + // + double GetDrawdownPercent() + { + return mDrawdownPercent; + } + // void AddOnSignalEventHandler(TOnSignal handler) { @@ -1836,9 +1842,66 @@ public: } // - double GetDrawdownPercent() + double MinRequiredProfitPerTrade() { - return mDrawdownPercent; + return mMinRequiredProfitPerTrade; + } + + // + void MinRequiredProfitPerTrade(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMinRequiredProfitPerTrade = value; + } + + // + double MinRequiredProfitPerVolumeFactor() + { + return mMinRequiredProfitPerVolumeFactor; + } + + // + void MinRequiredProfitPerVolumeFactor(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + if (value > 0 && value < 0.01) + { + value = 0.01; + } + + // + mMinRequiredProfitPerVolumeFactor = value; + } + + // + int RestingAfterHedge() + { + return mRestingAfterHedge; + } + + // + void RestingAfterHedge(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mRestingAfterHedge = value; } // @@ -1897,6 +1960,9 @@ public: // HandleProfitManageMent(); + // + SyncSupports(); + // // First Check For Any Guard Actions ... // then Handle Guards if Provided ... @@ -2892,6 +2958,186 @@ protected: } } + // + // Search Positions and Remove + // non Exists Positions Support Orders ... + void SyncSupports() + { + // + XOrder orders[]; + int ordersCount = mTrader.GetOrders( + orders, + NULL, // All Symbols ... + NULL, // All Providers ... + NULL, // All Periods ... + X_POSITION_TYPE_ALL, // All Types ... + ORDER_STATE_PLACED, // Placed Untriggered Orders ... + true // Filter by Magic ... + ); + if (!IsValidSize(ordersCount)) + { + return; + } + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions( + positions // + ); + if (!IsValidSize(positions)) + { + // + mTrader.CancelOrders(orders); + return; + } + + // + XOrder mustCancel[]; + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + // Check Order is Support or not ... + ulong iParentTicket = ExtractSupportedTicket(iOrder.comment); + if (iParentTicket <= 0) + { + continue; + } + + // + // We Sure it is support Order ... + XPosition parent; + bool isParentExists = mTrader.GetPosition( + iParentTicket, + parent // + ); + if (!isParentExists) + { + // + AddRef( + iOrder, + mustCancel // + ); + } + } + + // + int mustCancelCount = ArraySize(mustCancel); + if (!IsValidSize(mustCancelCount)) + { + return; + } + + // + mTrader.CancelOrders(mustCancel); + } + + // + // Hedging ... + + // + // Check Required Properties Setted for Hedge or not ... + bool AllowHedge() + { + // + bool result = false; + + // + result = + // + mMinRequiredProfitPerTrade > 0 && + mMinRequiredProfitPerVolumeFactor > 0 + // + ; + + // + return result; + } + + // + // Check Hedge Conditions is Happens or not ... + // if true doing Hedge ... + bool DoEQMHedge() + { + // + bool result = false; + + // + result = AllowHedge(); + if (!result) + { + return result; + } + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions(positions); + result = IsValidSize(positions); + if (!result) + { + return result; + } + + // + // Check At Least One Support Positions Open For Hedging ... + XPosition supports[]; + int supportsCount = ExtractSupportPositions( + positions, + supports // + ); + result = IsValidSize(supportsCount); + if (!result) + { + return result; + } + + // + double profits = SpecifiedCalculatePositionsProfit(positions); + double requiredProfit = SpecifiedCalculateRequiredProfitForHedge( + positions, + mMinRequiredProfitPerTrade, + mMinRequiredProfitPerVolumeFactor // + ); + + // + result = profits >= requiredProfit; + if (!result) + { + return result; + } + + // + string comment = XEQMSupportToken + " Hedge ..."; + + // + int closed = mTrader.Close( + positions, + comment // + ); + result = IsValidSize(closed); + if (!result) + { + return result; + } + + // + string message = XEQMSupportToken + " Hedge: " + ToString(profits) + " ..."; + + // + Alert(message); + + // + if (mRestingAfterHedge > 0) + { + Sleep(mRestingAfterHedge * 1000); + } + + // + return result; + } + // // Guards ... @@ -3447,6 +3693,11 @@ private: // // Props ... + // + int mRestingAfterHedge; // Resting Bars After Hedge + double mMinRequiredProfitPerTrade; // Minimum Required Profit for Hedging + double mMinRequiredProfitPerVolumeFactor; // Minimum Required Profit for Hedging Per Velume + // // Signal Event Listeners ... TOnSignal mOnSignalEventHandlers[]; diff --git a/Classes/x-saherelm.xtrade.class.mq5 b/Classes/x-saherelm.xtrade.class.mq5 index 8302ee54..55809295 100644 --- a/Classes/x-saherelm.xtrade.class.mq5 +++ b/Classes/x-saherelm.xtrade.class.mq5 @@ -1304,6 +1304,7 @@ public: // int supIndex = i + 1; string iComment = GenerateSupportTag(ticket); + iSupport.comment = iComment; // bool isExecuted = ExecuteSignal( diff --git a/Experts/x-saherelm.x121.ea.mq5 b/Experts/x-saherelm.x121.ea.mq5 index a424aefb..e28f8185 100644 --- a/Experts/x-saherelm.x121.ea.mq5 +++ b/Experts/x-saherelm.x121.ea.mq5 @@ -36,26 +36,29 @@ int x121EASlippage = 10; // Slippgae // // Trading Symbols ... -input string x121EASymbols = "EURUSDb"; // Symbols +string x121EASymbols = "EURUSDb"; // Symbols // EURUSDb,GBPUSDb,XAUUSDb,USDCHFb,USDJPYb // // Signals ... bool x121EAAllowLong = true; // Allow Long Trades bool x121EAAllowShort = true; // Allow Short Trades -int x121EAReuiredSignalVerifications = 4; // Required Verifications for Signals +int x121EAReuiredSignalVerifications = 6; // Required Verifications for Signals // // Risk Management ... -double x121EAVolume = 0.01; // Static Volume -double x121EATPPoint = 100; // TP Point -double x121EASLPoint = 500; // SL Point -int x121EAMaxAllowedTrades = 10; // Max Allowed Positions -bool x121EAIgnoreSL = false; // Ignore Calculated SL -bool x121EAIgnoreTP = false; // Ignore Calculated TP -bool x121EAUseSupport = true; // Use Support Signals -int x121EACloseOnSpecificTime = -1; // Close All Trades in Specific Time -bool x121EACloseOnOpposit = false; // Close all Positions on Opposit +double x121EAVolume = 0.01; // Static Volume +double x121EATPPoint = 50; // TP Point +double x121EASLPoint = 500; // SL Point +int x121EAMaxAllowedTrades = 0; // Max Allowed Positions +bool x121EAIgnoreSL = false; // Ignore Calculated SL +bool x121EAIgnoreTP = false; // Ignore Calculated TP +bool x121EAUseSupport = false; // Use Support Signals +double x121EAMinRequiredProfitPerTrade = 0; // Minimum Required Profit for Hedging +double x121EAMinRequiredProfitPerVolumeFactor = 0; // Minimum Required Profit for Hedging Per Velume +int x121EARestingAfterHedge = 300; // Resting Seconds After Hedge +int x121EACloseOnSpecificTime = -1; // Close All Trades in Specific Time +bool x121EACloseOnOpposit = false; // Close all Positions on Opposit // // Alert ... @@ -172,8 +175,11 @@ bool InitialEA() x121EA.UseSupport(x121EAUseSupport); x121EA.CloseOnOpposit(x121EACloseOnOpposit); x121EA.MaxAllowedTrades(x121EAMaxAllowedTrades); + x121EA.RestingAfterHedge(x121EARestingAfterHedge); x121EA.CloseOnSpecificTime(x121EACloseOnSpecificTime); + x121EA.MinRequiredProfitPerTrade(x121EAMinRequiredProfitPerTrade); x121EA.ReuiredSignalVerifications(x121EAReuiredSignalVerifications); + x121EA.MinRequiredProfitPerVolumeFactor(x121EAMinRequiredProfitPerVolumeFactor); // // Configure Alert ... diff --git a/Libraries/x-saherelm.xtrade.lib.mq5 b/Libraries/x-saherelm.xtrade.lib.mq5 index c2bc8b45..e8a94f31 100644 --- a/Libraries/x-saherelm.xtrade.lib.mq5 +++ b/Libraries/x-saherelm.xtrade.lib.mq5 @@ -23,6 +23,7 @@ // Imports ... #include #include "../Libraries/x-saherelm.draw.lib.mq5" +#include "../Classes/x-saherelm.xczone.class.mq5" #include "../Libraries/x-saherelm.common.lib.mq5" // @@ -678,6 +679,10 @@ struct XSignal // XSignal supports[]; // a Collecion of Support Signals ... + // + // Zones for Signal ... + XSCZones *zones; + // // Constructor ... XSignal() @@ -4031,6 +4036,46 @@ ulong ExtractSupportedTicket(string value) ); } +// +int ExtractSupportPositions( + XPosition &source[], + XPosition &dest[] // Result ... +) { + // + int result = 0; + + // + Clean(dest); + + // + int sourceCount = ArraySize(source); + if (!IsValidSize(sourceCount)) { + return result; + } + + // + for (int i = 0; i < sourceCount; i++) { + // + XPosition iSource = source[i]; + + // + ulong iParentTicket = ExtractSupportedTicket(iSource.comment); + if (iParentTicket > 0) { + // + AddRef( + iSource, + dest // + ); + } + } + + // + result = ArraySize(dest); + + // + return result; +} + // // Generate EQM Support Comment Tag ... string GenerateEQMSupportTag(ulong ticket)