From d01e1036ce90a0f714fa1d24a9b85274ca920ab7 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Mon, 2 Jun 2025 08:46:42 +0330 Subject: [PATCH] last ... --- Libraries/x-saherelm.x-poi.extensions.lib.mq5 | 43 + XCATBEA/Classes/xcatbea.expert.class.mq5 | 19 +- XCATBEA/Classes/xcatbea.signaller.class.mq5 | 767 +++++++++++++++--- .../Classes/xcatbea.x-poi.detector.class.mq5 | 84 +- XCATBEA/Libraries/xcatbea.signaller.lib.mq5 | 62 ++ 5 files changed, 854 insertions(+), 121 deletions(-) diff --git a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 index 9faf9f94..fa3c03f7 100644 --- a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 @@ -1624,6 +1624,49 @@ bool HasInsideBox( return result; } +/** + * Remove Specified Box from Collection ... + */ +bool RemoveBox( + XBoxZone &box, + XBoxZone &boxes[] // +) +{ + // + bool result = false; + + // + result = + box.IsValid() && + HasChild(boxes); + if (!result) + { + return result; + } + + // + int idx = -1; + result = FindBoxIndex( + idx, + box, + boxes // + ); + if (!result) + { + return result; + } + + // + result = ArrayRemove( + boxes, + idx, + 1 // + ); + + // + return result; +} + /** * Converts to XBoxZone ... * diff --git a/XCATBEA/Classes/xcatbea.expert.class.mq5 b/XCATBEA/Classes/xcatbea.expert.class.mq5 index eed7c4c0..cf1c1f81 100644 --- a/XCATBEA/Classes/xcatbea.expert.class.mq5 +++ b/XCATBEA/Classes/xcatbea.expert.class.mq5 @@ -1052,26 +1052,25 @@ class XCXCATBEAExpert : public XCBase XCATBEAStrategyConditions iConditions = conditions[i]; // - // Prepare Signal Based on Conditions ... + // Define Signal Structure ... XSignal iSignal; // - // Check if a Trigger Block Attached and Has Signal ... - // use it ... + // Check Conditions is Valid Triggered Conditions ... has = iConditions.IsValid() && iConditions.IsSetuped() && - iConditions.CanTrigger() && - iConditions.triggerBlock.IsValid() && - iConditions.triggerBlock.signal.IsValid(); + iConditions.CanTrigger(); if (has) { - iSignal = iConditions.triggerBlock.signal; + // + // Preparing Signal ... + has = ToSignal( + iSignal, + iConditions // + ); } - // - // if we Have any other Signalling senarios we can Handle them here ... - // // Validate Signal ... has = iSignal.IsValid(); diff --git a/XCATBEA/Classes/xcatbea.signaller.class.mq5 b/XCATBEA/Classes/xcatbea.signaller.class.mq5 index 56ccb6e9..7e28d507 100644 --- a/XCATBEA/Classes/xcatbea.signaller.class.mq5 +++ b/XCATBEA/Classes/xcatbea.signaller.class.mq5 @@ -137,6 +137,8 @@ class XCXCATBEASignaller : XCBase XBoxZone unavailableZones[]; // Un Available Zones ... XTriggerBlock cTriggerBlock; // Currently Selected Trigger Block ... XTriggerBlock triggerBlocks[]; // Founded Trigger Blocks ... + bool waitsUntilPeakInvalidate; // Waits Until Peak Invalidate ... + bool waitsUntilValeInvalidate; // Waits Until Vale Invalidate ... XTriggerBlock cInsideTriggerBlock; // a TriggerBlock which Currently Selected Trigger Block is Inside it ... // @@ -330,20 +332,22 @@ class XCXCATBEASignaller : XCBase // Draw POI(s) ... if (allowDraws) { - drawer.Draw(bar.time); + // drawer.Draw(bar.time); } // // Detect Trigger Blocks and Collect them ... XTriggerBlock iTriggerBlock; X121XCatbConditions iConditions; + XTriggerBlockFilters iFilters; + XTriggerBlockValidationRules iValidations; has = DetectTriggerBlock( helper, barAnalyser, iTriggerBlock, iConditions, - validations, - filters, + iValidations, + iFilters, barIndex, 10 // Loopback ... ); @@ -420,6 +424,174 @@ class XCXCATBEASignaller : XCBase // Update All Required Buffers ... helper.Update(barIndex); + // + datetime cTime = TimeCurrent(); + + // + // cPeak and cVale ... + // these Helpes Us to Detect Price Levels ... + // + // Draw Peak and Vale if Exists ... + + // + // Peak ... + if (cPeak.IsValid()) + { + // + cPeak.to = cTime; + drawer.DrawBox(cPeak); + } + + // + // Vale ... + if (cVale.IsValid()) + { + // + cVale.to = cTime; + drawer.DrawBox(cVale); + } + + // + // Try to Validate cPeak an cVale if Exists ... + XOHCL zBar; + XOHCL cBar; + bool isInited = zBar.Init( + symbol, + period, + barIndex // + ); + isInited = zBar.GetPreviousBar(cBar); + isInited = helper.GetConditions( + mConditions.conditions, + barIndex, + 10 // + ); + if (isInited) + { + // + // Validate cPeak and cVale if Exists ... + + // + // cPeak ... + if (cPeak.IsValid()) + { + // + isInited = cBar.high < cPeak.lower; + if (!isInited) + { + // + cPeak.Clean(); + cVale.Clean(); + + // + waitsUntilPeakInvalidate = false; + waitsUntilValeInvalidate = false; + } + } + + // + // cVale ... + if (cVale.IsValid()) + { + // + isInited = cBar.low > cVale.upper; + if (!isInited) + { + // + cPeak.Clean(); + cVale.Clean(); + + // + waitsUntilPeakInvalidate = false; + waitsUntilValeInvalidate = false; + } + } + + // + // Try To Detect Peak and Vale based on cBar ... + + // + // Selecting Peak ... + if (!cPeak.IsValid()) + { + // + XBoxZone tmpPeaks[]; + detector.FillPeakPivots(tmpPeaks); + while (HasChild(tmpPeaks)) + { + // + // Find Index ... + int idx = GetLowest(tmpPeaks); + if (!IsValidIndex(idx)) + { + break; + } + + // + // Select ... + cPeak = tmpPeaks[idx]; + ArrayRemove( + tmpPeaks, + idx, + 1 // + ); + + // + // Validate Peak ... + bool isValid = cPeak.lower > cBar.high; + if (isValid) + { + break; + } + + // + cPeak.Clean(); + } + Clean(tmpPeaks); + } + + // + // Selecting Vale ... + if (!cVale.IsValid()) + { + // + XBoxZone tmpVales[]; + detector.FillValePivots(tmpVales); + while (HasChild(tmpVales)) + { + // + // Find Index ... + int idx = GetHighest(tmpVales); + if (!IsValidIndex(idx)) + { + break; + } + + // + // Select ... + cVale = tmpVales[idx]; + ArrayRemove( + tmpVales, + idx, + 1 // + ); + + // + // Validate Vale ... + bool isValid = cVale.upper < cTriggerBlock.trigger.lower && + cVale.upper < cInsideTriggerBlock.trigger.lower; + if (isValid) + { + break; + } + + // + cVale.Clean(); + } + Clean(tmpVales); + } + } + // // Detect Signal Setup Based on Market Conditions ... if (!result && @@ -545,114 +717,342 @@ class XCXCATBEASignaller : XCBase allowSignallingBasedOnTriggerBlocksInsideOther) { // - // First We Hvae to Select Peak and Vale ... - - // - // Check Peak and Vale Exists ... - int peakIDX = GetYoungest(detector.peakPivots); - int valeIDX = GetYoungest(detector.valePivots); - result = IsValidIndex(peakIDX) && - IsValidIndex(valeIDX); + // Trigger Block Detection ... + result = HasChild(triggerBlocks) && + ArraySize(triggerBlocks) > 1 && + !waitsUntilPeakInvalidate && + !waitsUntilValeInvalidate; if (result) { // - cPeak = detector.peakPivots[peakIDX]; - cVale = detector.valePivots[valeIDX]; + // Check Newest Trigger Block ... + bool isTriggerBlockSelected = false; + XTriggerBlock tmpTBs[]; + Copy( + triggerBlocks, + tmpTBs // + ); + while (HasChild(tmpTBs)) + { + // + int idx = GetYoungest(tmpTBs); + if (!IsValidIndex(idx)) + { + break; + } + + // + // Select ... + // and Remove From Collection ... + cTriggerBlock = tmpTBs[idx]; + ArrayRemove( + tmpTBs, + idx, + 1 // + ); + + // + // Validate ... + isTriggerBlockSelected = + // + // Check Bar is Valid ... + cBar.IsValid() && + // + // Currently Happens ... + (cTriggerBlock.trigger.to == zBar.time || + cTriggerBlock.trigger.to == cBar.time) && + // + // Price Validations ... + (cTriggerBlock.IsBullish() + ? cBar.low > cTriggerBlock.trigger.lower + : cBar.high < cTriggerBlock.trigger.upper) + // + ; + if (isTriggerBlockSelected) + { + break; + } + + // + // Clean Trigger Block ... + cTriggerBlock.Clean(); + } + Clean(tmpTBs); // - // Trigger Block Detection ... - result = HasChild(triggerBlocks) && - ArraySize(triggerBlocks) > 1; + // Check Trigger Block Selection ... + result = isTriggerBlockSelected; if (result) { // - // Check Newest Trigger Block ... - int newestIDX = GetYoungest(triggerBlocks); - result = IsValidIndex(newestIDX); + bool isBullish = cTriggerBlock.IsBullish(); + bool isBearish = cTriggerBlock.IsBearish(); + + // + // Now we have to Check Newest Trigger Block Place ... + int insideTBIDX = DetectInsideTriggerBlock( + cTriggerBlock, + cInsideTriggerBlock, + triggerBlocks // + ); + + // + // Check InsideTB is Exists and Valid ... + result = + cInsideTriggerBlock.IsValid() && + IsValidIndex(insideTBIDX); if (result) { // - cTriggerBlock = triggerBlocks[newestIDX]; + // Now we Have to Detect Peak and Vales ... + result = + cPeak.IsValid() && + cVale.IsValid(); // - // Check Trigger Block is New ... - int toIDX = cTriggerBlock.ToIndex() == 0; - bool isNewest = toIDX == 0; - if (isNewest) + // If Exists Before Validate them based Trigger Blocks ... + if (result) { // - // Now we have to Check Newest Trigger Block Place ... - int insideTBIDX = DetectInsideTriggerBlock( + // Validate cPeak and cVale based on + // cTriggerBlock and cInsideTriggerBlock ... + result = + // + // Peak ... + cPeak.lower > cTriggerBlock.trigger.upper && + cPeak.lower > cInsideTriggerBlock.trigger.upper && + // + // Vale ... + cVale.upper < cTriggerBlock.trigger.lower && + cVale.upper < cInsideTriggerBlock.trigger.lower && + // + // Bar Validation ... + cBar.IsValid() && + cBar.low > cVale.upper && + cBar.high < cPeak.lower + // + ; + if (!result) + { + // + cPeak.Clean(); + cVale.Clean(); + + // + waitsUntilPeakInvalidate = false; + waitsUntilValeInvalidate = false; + } + } + + // + // if not Exists, or Clean them on Invalidating Process, try to Find Corrects ... + if (!result) + { + // + // Selecting Peak ... + XBoxZone tmpPeaks[]; + detector.FillPeakPivots(tmpPeaks); + while (HasChild(tmpPeaks)) + { + // + // Find Index ... + int idx = GetLowest(tmpPeaks); + if (!IsValidIndex(idx)) + { + break; + } + + // + // Select ... + cPeak = tmpPeaks[idx]; + ArrayRemove( + tmpPeaks, + idx, + 1 // + ); + + // + // Validate Peak ... + bool isValid = + // + // Bar Validation ... + cBar.IsValid() && + cBar.high < cPeak.lower && + // + // Peak Validation ... + cPeak.lower > cTriggerBlock.trigger.upper && + cPeak.lower > cInsideTriggerBlock.trigger.upper; + if (isValid) + { + break; + } + + // + cPeak.Clean(); + } + Clean(tmpPeaks); + + // + // Selecting Vale ... + XBoxZone tmpVales[]; + detector.FillValePivots(tmpVales); + while (HasChild(tmpVales)) + { + // + // Find Index ... + int idx = GetHighest(tmpVales); + if (!IsValidIndex(idx)) + { + break; + } + + // + // Select ... + cVale = tmpVales[idx]; + ArrayRemove( + tmpVales, + idx, + 1 // + ); + + // + // Validate Vale ... + bool isValid = + // + // Bar Validation ... + cBar.IsValid() && + cBar.low > cVale.upper && + // + // Vale Validation ... + cVale.upper < cTriggerBlock.trigger.lower && + cVale.upper < cInsideTriggerBlock.trigger.lower; + if (isValid) + { + break; + } + + // + cVale.Clean(); + } + Clean(tmpVales); + + // + // Summarizing Result ... + result = + cPeak.IsValid() && + cVale.IsValid(); + } + + // + // Check Peak and Vale Exists ... + if (result) + { + // + // Remove Peak from Detector Collections ... + // and Make it unavailable ... + UseBox(cPeak); + + // + // Remove Vale from Detector Collections ... + // and Make it unavailable ... + UseBox(cVale); + + // + // Remove Selected Trigger Block ... + // and Make it unavailable ... + RemoveTriggerBlock( cTriggerBlock, + triggerBlocks // + ); + UseTriggerBlock(cTriggerBlock); + + // + // Remove Selected Inside Trigger Block ... + // and Make it unavailable ... + RemoveTriggerBlock( cInsideTriggerBlock, triggerBlocks // ); + UseTriggerBlock(cInsideTriggerBlock); // - // Check InsideTB is Exists and Valid ... - result = - cInsideTriggerBlock.IsValid() && - IsValidIndex(insideTBIDX); - if (result) + // Update Peak and Vales To ... + cPeak.to = cTime; + cVale.to = cTime; + + // + // Draw Peak and Vales ... + if (allowDraws) { // - // Remove Peak from Detector Collections ... - // and Make it unavailable ... - ArrayRemove( - detector.peakPivots, - peakIDX, - 1 // - ); - AddRef( - cPeak, - unavailableZones // - ); + drawer.DrawBox(cPeak); + drawer.DrawBox(cVale); + } + + // + // Validate Peaks and Vales ... + bool isPeakPassed = false; + bool isValePassed = false; + cInsideTriggerBlock.trigger.to = cTime; + int toIDX = cInsideTriggerBlock.ToIndex(); + int fromIDX = cInsideTriggerBlock.FromIndex(); + for (int i = toIDX; i < fromIDX; i++) + { + // + // Reading Values ... // - // Remove Vale from Detector Collections ... - // and Make it unavailable ... - ArrayRemove( - detector.peakPivots, - peakIDX, - 1 // - ); - AddRef( - cVale, - unavailableZones // - ); + double iPeak = helper.GetPeak(i); + double iPPeak = helper.GetPeak(i + 1); // - // Remove Selected Trigger Block ... - // and Make it unavailable ... - RemoveTriggerBlock( - cTriggerBlock, - triggerBlocks // - ); - UseTriggerBlock(cTriggerBlock); + double iVale = helper.GetVale(i); + double iPVale = helper.GetVale(i + 1); // - // Remove Selected Inside Trigger Block ... - // and Make it unavailable ... - RemoveTriggerBlock( - cInsideTriggerBlock, - triggerBlocks // - ); - UseTriggerBlock(cInsideTriggerBlock); + bool isPeakOverLast = iPeak > iPPeak; + bool isPeakUnderLast = iPeak < iPPeak; // - CleanupArray( - unavailableZones, - maxAllowedCollection // - ); + bool isValeOverLast = iVale > iPVale; + bool isValeUnderLast = iVale < iPVale; + // + if (!isPeakPassed) + { + // + isPeakPassed = + isBullish ? isPeakOverLast + : isPeakUnderLast; + } + + // + if (!isValePassed) + { + // + isValePassed = + isBullish + ? isValeUnderLast + : isPeakOverLast; + } + + // + result = + isPeakPassed && + isValePassed; + if (result) + { + break; + } + } + if (result) + { // // Draw Trigger Blocks if Allowed ... if (allowDraws) { - // // // Draw Blocks ... - datetime cTime = TimeCurrent(); // // mObjects.Clear(); @@ -679,12 +1079,140 @@ class XCXCATBEASignaller : XCBase } // - Print("Salam ..."); + if (isBullish) + { + waitsUntilPeakInvalidate = true; + } + else if (isBearish) + { + waitsUntilValeInvalidate = true; + } + + // + mConditions.triggerBlock = cTriggerBlock; } } } } } + + // + // Preparing Conditions based on result ... + if (result) + { + // + bool isBullish = mConditions.triggerBlock.IsBullish(); + + // + // Preparing mConditions ... + mConditions.dir = + mConditions + .triggerBlock + .GetDirection(); + mConditions.symbol = symbol; + mConditions.period = period; + mConditions.provider = provider; + mConditions.reward = riskToRewardRatio; + mConditions.time = mConditions.conditions.bars[0].time; + mConditions.setupTime = mConditions.conditions.bars[0].time; + + // + // Prepare Target ... + double targets[]; + for (int i = 1; i <= riskToRewardRatio; i++) + { + // + Add( + (double)i, + targets // + ); + } + + // + // Calculate SL Additions ... + double iATR = 0; + if (barIndex > 0 && + barIndex < ArraySize(helper.atrBuffer)) + { + iATR = helper.atrBuffer[barIndex]; + } + double slAdditional = slATRMultiplier * iATR; + + // + // Preparing Signal ... + result = ToSignal( + mConditions.triggerBlock.trigger, + mConditions.triggerBlock.signal, + targets, + slAdditional // + ); + XSignal insideTBSignal; + result = + result && + ToSignal( + cInsideTriggerBlock.trigger, + insideTBSignal, + targets, + slAdditional // + ); + if (result) + { + // + // Try to Use SL Based on Inside Trigger Block ... + double sl = 0; + double tp = 0; + bool useInsideTBForSL = true; + if (useInsideTBForSL) + { + // + sl = insideTBSignal.sl; + tp = insideTBSignal.tp; + + // + // Add Target for usuall Signal TP ... + XTarget iTarget; + iTarget.doRF = true; + iTarget.target = mConditions.triggerBlock.signal.tp; + + // + AddRef( + iTarget, + mConditions.targets); + + // + iTarget.Clean(); + } + else + { + // + sl = mConditions.triggerBlock.signal.sl; + tp = mConditions.triggerBlock.signal.tp; + } + + // + mConditions.sl = sl; + mConditions.tp = tp; + mConditions.pivot = sl; + mConditions.triggerBlock.signal.provider = provider; + mConditions.entry = mConditions.triggerBlock.signal.entry; + mConditions.point = mConditions.triggerBlock.signal.entry; + mConditions.type = ToPositionType(mConditions.triggerBlock.signal.type); + + // + // Draw Trigger Block ... + if (allowDraws) + { + // + DrawTriggerBlock( + mConditions.triggerBlock, + drawer.drawer, + mObjects, + NULL, // To ... + false // Draw Signal ... + ); + } + } + } } // @@ -694,6 +1222,10 @@ class XCXCATBEASignaller : XCBase // // Cleanup Resource ... + zBar.Clean(); + cBar.Clean(); + cTriggerBlock.Clean(); + cInsideTriggerBlock.Clean(); // return result; @@ -852,8 +1384,8 @@ class XCXCATBEASignaller : XCBase // allowSignallingBasedOnConditions = false; - allowSignallingBasedOnTriggerBlocks = true; - allowSignallingBasedOnTriggerBlocksInsideOther = false; + allowSignallingBasedOnTriggerBlocks = false; + allowSignallingBasedOnTriggerBlocksInsideOther = true; // bool has = inputs.IsValid(); @@ -1090,6 +1622,52 @@ class XCXCATBEASignaller : XCBase return result; } + /** + * Use Specified Box and make it Unavailable ... + * + * @param box: XBoxZone instance reference ... + */ + void UseBox(XBoxZone &box) + { + // + // Validate Box ... + bool has = box.IsValid(); + if (!has) + { + return; + } + + // + // Check Box Added Before or not ... + int idx = -1; + has = FindBoxIndex( + idx, + box, + unavailableZones // + ); + if (has) + { + return; + } + + // + // Adding Box Reference to + // Unavailable Zones ... + AddRef( + box, + unavailableZones // + ); + + // + // Cleanup Array ... + CleanupArray( + unavailableZones, + maxAllowedCollection // + ); + + // + } + /** * Use Specified Trigger Block and Make it Un Available ... * @@ -1109,11 +1687,7 @@ class XCXCATBEASignaller : XCBase has = tb.trigger.IsValid(); if (has) { - // - AddRef( - tb.trigger, - unavailableZones // - ); + UseBox(tb.trigger); } // @@ -1121,11 +1695,7 @@ class XCXCATBEASignaller : XCBase has = tb.ob.IsValid(); if (has) { - // - AddRef( - tb.ob, - unavailableZones // - ); + UseBox(tb.ob); } // @@ -1133,11 +1703,7 @@ class XCXCATBEASignaller : XCBase has = tb.fvg.IsValid(); if (has) { - // - AddRef( - tb.fvg, - unavailableZones // - ); + UseBox(tb.fvg); } // @@ -1145,11 +1711,7 @@ class XCXCATBEASignaller : XCBase has = tb.fLiquidity.IsValid(); if (has) { - // - AddRef( - tb.fLiquidity, - unavailableZones // - ); + UseBox(tb.fLiquidity); } // @@ -1157,19 +1719,8 @@ class XCXCATBEASignaller : XCBase has = tb.rLiquidity.IsValid(); if (has) { - // - AddRef( - tb.rLiquidity, - unavailableZones // - ); + UseBox(tb.rLiquidity); } - - // - // Cleaning Up ... - CleanupArray( - unavailableZones, - maxAllowedCollection // - ); } /** diff --git a/XCATBEA/Classes/xcatbea.x-poi.detector.class.mq5 b/XCATBEA/Classes/xcatbea.x-poi.detector.class.mq5 index 150164d9..39734bb8 100644 --- a/XCATBEA/Classes/xcatbea.x-poi.detector.class.mq5 +++ b/XCATBEA/Classes/xcatbea.x-poi.detector.class.mq5 @@ -32,9 +32,9 @@ // enum ENUM_XCATB_PIVOTS { - XCA_NONE, // None - XCA_PEAK, // Peak - XCA_VALE, // Vale + XCA_NONE, // None + XCA_PEAK, // Peak + XCA_VALE, // Vale }; // @@ -1258,6 +1258,45 @@ class XCXCATBEAPOIDetector : public XCBase return ArraySize(peakPivots); } + // + int FillPeakPivots(XBoxZone &pivots[]) + { + // + int result = 0; + + // + Clean(pivots); + + // + if (!HasPeakPivots()) + { + return result; + } + + // + int count = CountPeakPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iPivot = peakPivots[i]; + + // + AddRef( + iPivot, + pivots // + ); + + // + iPivot.Clean(); + } + + // + result = ArraySize(pivots); + + // + return result; + } + // // VALE ... @@ -1279,6 +1318,45 @@ class XCXCATBEAPOIDetector : public XCBase return ArraySize(valePivots); } + // + int FillValePivots(XBoxZone &pivots[]) + { + // + int result = 0; + + // + Clean(pivots); + + // + if (!HasValePivots()) + { + return result; + } + + // + int count = CountValePivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iPivot = valePivots[i]; + + // + AddRef( + iPivot, + pivots // + ); + + // + iPivot.Clean(); + } + + // + result = ArraySize(pivots); + + // + return result; + } + // // Protected ... protected: diff --git a/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 b/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 index 2875ca73..928cd78d 100644 --- a/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 +++ b/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 @@ -275,6 +275,68 @@ struct XCATBEAStrategyConditions // }; +/** + * Converts Strategy Conditions to Signal ... + */ +bool ToSignal( + XSignal &signal, + XCATBEAStrategyConditions &conditions // +) +{ + // + bool result = false; + + // + // Normalize Args ... + signal.Clean(); + + // + // Validate Args ... + result = + conditions.IsValid() && + conditions.IsSetuped() && + conditions.CanTrigger(); + if (!result) + { + return result; + } + + // + // Do Converting ... + signal.volume = 0.01; + signal.tp = conditions.tp; + signal.sl = conditions.sl; + signal.entry = conditions.entry; + signal.symbol = conditions.symbol; + signal.period = conditions.period; + signal.mode = X_ORDER_MODE_MARKET; + signal.time = conditions.triggerTime; + signal.provider = conditions.provider; + signal.type = conditions.type == + X_POSITION_TYPE_LONG + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + signal.conditions = conditions + .conditions + .GenerateSummary( + false, + true, + true, + false // Ignore False Conditions ... + ); + Copy( + conditions.targets, + signal.targets // + ); + + // + // Validate Result ... + result = signal.IsValid(); + + // + return result; +} + /** * Detect Signal Zone based on Market Conditions ... *