From 940931d78a17f7b4b5208d6a024ce065d56c8f73 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Fri, 13 Dec 2024 19:46:00 +0330 Subject: [PATCH] Last ... --- .../BKP/x-121.poi.expert.class copy.mq5 | 0 Experts/x-saherelm.x-121.smc.ea.mq5 | 6 +- Helpers/x-saherelm.x121.helper.mq5 | 9 + Libraries/x-saherelm.x-trade.lib.mq5 | 23 + .../x-121.smc.market.cycle.helper.class.mq5 | 309 +++++ .../x-121.smc.x-tradehandler.class.mq5 | 101 +- X121SMCEA/Experts/x-121.smc.expert.class.mq5 | 2 +- X121SMCEA/Libraries/x-121.smc.lib.mq5 | 14 + .../x-121.smc.test.strategy.class.mq5 | 1154 ++++++++++++++++- 9 files changed, 1602 insertions(+), 16 deletions(-) rename X121SMCEA/Experts/x-121.poi.expert.class.mq5 => Documents/BKP/x-121.poi.expert.class copy.mq5 (100%) diff --git a/X121SMCEA/Experts/x-121.poi.expert.class.mq5 b/Documents/BKP/x-121.poi.expert.class copy.mq5 similarity index 100% rename from X121SMCEA/Experts/x-121.poi.expert.class.mq5 rename to Documents/BKP/x-121.poi.expert.class copy.mq5 diff --git a/Experts/x-saherelm.x-121.smc.ea.mq5 b/Experts/x-saherelm.x-121.smc.ea.mq5 index bc7b4b72..19d6e24e 100644 --- a/Experts/x-saherelm.x-121.smc.ea.mq5 +++ b/Experts/x-saherelm.x-121.smc.ea.mq5 @@ -38,13 +38,13 @@ input string eaLogSuffix = ""; // Log Suffix // // Symbols ... input group "Symbols"; -input bool eaMultiSymbol = false; // Use Multi Symbol -input string eaSymbols = "EURUSDb,GBPUSDb,USDJPYb,USDCHFb,DowJones30,XAUUSDb"; // Trading Symbols +input bool eaMultiSymbol = false; // Use Multi Symbol +input string eaSymbols = "EURUSDb,GBPUSDb,USDJPYb,USDCHFb"; // Trading Symbols // // Volume ... input group "Volume"; -input double eaR2R = 2; // Risk to Reward Ratio +input double eaR2R = 3; // Risk to Reward Ratio input bool eaUseDynamicVolume = false; // Use Dynamic Volume input double eaDynamicVolumeStep = 0.01; // Increase Volume Step input double eaDynamicVolumeBalanceFactor = 200; // Balance Factor for Generate Dynamic Volume diff --git a/Helpers/x-saherelm.x121.helper.mq5 b/Helpers/x-saherelm.x121.helper.mq5 index aecef793..9f4c5ca9 100644 --- a/Helpers/x-saherelm.x121.helper.mq5 +++ b/Helpers/x-saherelm.x121.helper.mq5 @@ -1235,6 +1235,15 @@ class XCX121Helper : public XCBaseHelper // ); } + + /** + * Retrieve DON Chain Length ... + * + * @return ( int ) + */ + int GetDonChainLength() { + return mInputs.donchainLength; + } // // Implement Value Getters ... diff --git a/Libraries/x-saherelm.x-trade.lib.mq5 b/Libraries/x-saherelm.x-trade.lib.mq5 index 547ea974..eedbdecc 100644 --- a/Libraries/x-saherelm.x-trade.lib.mq5 +++ b/Libraries/x-saherelm.x-trade.lib.mq5 @@ -3340,6 +3340,29 @@ struct XSymbolPositions // }; +// +struct XSymbolLastPosition { + // + string symbol; + string provider; + datetime time; + + // + XSymbolLastPosition() { + Clean(); + } + + // + // Tools ... + + void Clean() { + // + time = NULL; + symbol = NULL; + provider = NULL; + } +}; + // // an Structure for Holding Positions Data ... struct XTradeData diff --git a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 index 908908f9..c8b3264d 100644 --- a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 @@ -743,6 +743,315 @@ class XC121SMCCycleHelper : public XCBase return result; } + /** + * Detect XPV Based POI(s) ... + * + * @param barIndex: Start Bar Index ... + * @param minRepetition: minimum Repeate of POI for Validation ... + * @param requiredPivots: Number of Min Requirement POI(s) ... + * @param pivotHelper: XC121SMCCycleHelper instance Pointer ... + * @param orderFlow: XPVPivot instance Array Reference ... + * @param orderFlowDirection: ENUM_X_DIRECTION member Reference which represents OrderFlow Direction ... + * @param maxAllowedLoopbackBars: Integer, Max Allowed Loopback Bars ... + * + * @return ( bool ) + */ + bool DetectOrderFlow( + int barIndex, + XPVPivot &orderFlow[], // OrderFlows ... + ENUM_X_DIRECTION &orderFlowDirection, // Order Flow Direction ... + int minRepetition = 0, + int requiredPivots = 0, + int maxAllowedLoopbackBars = 576 // + ) + { + // + bool result = false; + + // + orderFlowDirection = X_DIRECTION_NONE; + + // + if (maxAllowedLoopbackBars <= 0) + { + maxAllowedLoopbackBars = 1000; + } + + // + if (minRepetition <= 0) + { + minRepetition = mX121Helper.GetDonChainLength(); + } + + // + if (requiredPivots <= 0) + { + requiredPivots = 3; + } + + // + int start = barIndex; + int end = start + maxAllowedLoopbackBars; + + // + Clean(orderFlow); + + // + result = minRepetition > 0 && + requiredPivots > 0; + if (!result) + { + return result; + } + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + double peak = 0; + XPVPivot peaks[]; + int peakRepeate = 0; + int peakToBarIndex = 0; + int peakFromBarIndex = 0; + + // + double vale = 0; + XPVPivot vales[]; + int valeRepeate = 0; + int valeToBarIndex = 0; + int valeFromBarIndex = 0; + + // + bool canLookupPeak = true; + bool canLookupVale = true; + bool canLookup = true; + while (canLookup) + { + // + // Check Peak ... + double iPeak = mX121Helper.GetPeak(barIndex); + if (iPeak != peak) + { + // + if (peak != 0 && + peakRepeate >= minRepetition) + { + // + bool isExists = false; + int count = ArraySize(peaks); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = peaks[i]; + + // + if (iPivot.upper == iPeak) + { + // + isExists = true; + break; + } + } + } + if (!isExists) + { + // + XPVPivot iPivot; + + // + iPivot.lower = 0; + iPivot.upper = peak; + iPivot.symbol = symbol; + iPivot.period = period; + iPivot.type = XPV_PEAK; + iPivot.repetition = peakRepeate; + iPivot.to = iTime( + symbol, + period, + peakToBarIndex // + ); + iPivot.from = iTime( + symbol, + period, + peakFromBarIndex // + ); + + // + iPivot.lower = iPivot.CalculateLower(); + + // + bool isValid = iPivot.IsValid(); + if (isValid) + { + // + AddRef( + iPivot, + peaks // + ); + } + } + } + + // + peak = iPeak; + peakRepeate = 0; + peakFromBarIndex = 0; + peakToBarIndex = barIndex; + } + else if (iPeak == peak) + { + // + peakRepeate++; + peakFromBarIndex = barIndex; + } + + // + // Check Vale ... + double iVale = mX121Helper.GetVale(barIndex); + if (iVale != vale) + { + // + if (vale != 0 && + valeRepeate >= minRepetition) + { + // + bool isExists = false; + int count = ArraySize(vales); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = vales[i]; + + // + if (iPivot.lower == iVale) + { + // + isExists = true; + break; + } + } + } + if (!isExists) + { + // + XPVPivot iPivot; + + // + iPivot.upper = 0; + iPivot.lower = vale; + iPivot.symbol = symbol; + iPivot.period = period; + iPivot.type = XPV_VALE; + iPivot.repetition = valeRepeate; + iPivot.to = iTime( + symbol, + period, + valeToBarIndex // + ); + iPivot.from = iTime( + symbol, + period, + valeFromBarIndex // + ); + + // + iPivot.upper = iPivot.CalculateUpper(); + + // + bool isValid = iPivot.IsValid(); + if (isValid) + { + // + AddRef( + iPivot, + vales // + ); + } + } + } + + // + vale = iVale; + valeRepeate = 0; + valeFromBarIndex = 0; + valeToBarIndex = barIndex; + } + else if (iVale == vale) + { + // + valeRepeate++; + valeFromBarIndex = barIndex; + } + + // + canLookupPeak = ArraySize(peaks) < requiredPivots; + canLookupVale = ArraySize(vales) < requiredPivots; + canLookup = barIndex < end && + (canLookupPeak || + canLookupVale); + if (canLookup) + { + barIndex++; + } + } + + // + result = IsValidSize(ArraySize(peaks)) || + IsValidSize(ArraySize(vales)); + if (!result) + { + return result; + } + + // + // Detect Order Flow ... + Copy( + peaks, + orderFlow, + false // + ); + Copy( + vales, + orderFlow, + false // + ); + int count = ArraySize(orderFlow); + result = IsValidSize(orderFlow); + if (!result) + { + return result; + } + + // + // Sort Pivots ... + SortPivots(orderFlow); + + // + // Filter Broken Order Flows ... + FilterBrokenPivots(orderFlow); + + // + // Detect Order Flow Direction ... + result = DetectPivotDirection( + orderFlow, + orderFlowDirection // + ); + if (!result) + { + return result; + } + + // + return result; + } + // // Change Values Actions ... diff --git a/X121SMCEA/Classes/x-121.smc.x-tradehandler.class.mq5 b/X121SMCEA/Classes/x-121.smc.x-tradehandler.class.mq5 index bb571b5a..03f323e2 100644 --- a/X121SMCEA/Classes/x-121.smc.x-tradehandler.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.x-tradehandler.class.mq5 @@ -2666,6 +2666,29 @@ class XC121SMCTradeHandler : public XCBaseAlert return result; } } + + // + if (!youngestPosition.IsValid()) + { + // + int symbolIDX = FindLastExecutedSignalItem(signal); + if (IsValidIndex(symbolIDX)) + { + // + datetime cTime = TimeCurrent(); + int signalPeriodSeconds = PeriodSeconds(signal.period); + datetime lastExecutedTime = mLastExecutedSignals[symbolIDX].time; + datetime passedTime = ((datetime)lastExecutedTime + + ((mDelayBarBetweenTwoSignal * signalPeriodSeconds))); + + // + result = cTime >= passedTime; + if (!result) + { + return result; + } + } + } } // @@ -2712,6 +2735,9 @@ class XC121SMCTradeHandler : public XCBaseAlert forceTrail // ); + // + HandleSignalExecuted(signal); + // string msg = (signal.type == POSITION_TYPE_BUY ? "Long" : "Short") + " Signal Provided by: " + signal.provider + @@ -3789,7 +3815,8 @@ class XC121SMCTradeHandler : public XCBaseAlert private: // // Props ... - double mAdditionalVolume; // Volume Additional + double mAdditionalVolume; // Volume Additional + XSymbolLastPosition mLastExecutedSignals[]; // Last Executed Signals // // Read Only ... @@ -4131,6 +4158,78 @@ class XC121SMCTradeHandler : public XCBaseAlert mCollector.SaveSignal(item); } + // + int FindLastExecutedSignalItem(XSignal &signal) + { + // + int result = -1; + + // + if (!signal.IsValid()) + { + return result; + } + + // + int count = ArraySize(mLastExecutedSignals); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XSymbolLastPosition iLast = mLastExecutedSignals[i]; + if (iLast.symbol == signal.symbol && + iLast.provider == signal.provider) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + void HandleSignalExecuted(XSignal &signal) + { + // + if (!signal.IsValid()) + { + return; + } + + // + datetime cTime = TimeCurrent(); + int symbolIDX = FindLastExecutedSignalItem(signal); + bool hasItem = IsValidIndex(symbolIDX); + if (hasItem) + { + mLastExecutedSignals[symbolIDX].time = cTime; + } + else + { + // + XSymbolLastPosition item; + + // + item.time = cTime; + item.symbol = signal.symbol; + item.provider = signal.provider; + + // + AddRef( + item, + mLastExecutedSignals // + ); + } + } + // }; diff --git a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 index de52818c..471d5fe4 100644 --- a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 +++ b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 @@ -563,7 +563,7 @@ class XC121SMCExpert : public XCBaseExpert // mTradeHandler.MaxAllowedSLToPause(0); - mTradeHandler.DelayBarBetweenTwoSignal(240); + mTradeHandler.DelayBarBetweenTwoSignal(60); mTradeHandler.MaxAllowedSLReachedPauseDelay(HoursToSeconds(24)); // diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index 9132b985..13893c63 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -35,6 +35,7 @@ const string X121SMCStrategyToken = "X121SMC"; // const string X121SMCSMPVToken = "X121SMCSMPV"; +const string X121SMCRJBPVToken = "X121SMCRJBPV"; const string X121SMCVWAPCToken = "X121SMCVWAPC"; // @@ -44,6 +45,7 @@ enum ENUM_X_121_SMC_PROVIDERS // X_121_SMC_PROVIDER_NONE, X_121_SMC_PROVIDER_SMPV, + X_121_SMC_PROVIDER_RJBPV, X_121_SMC_PROVIDER_VWAPC, }; @@ -1856,6 +1858,11 @@ string ToString(ENUM_X_121_SMC_PROVIDERS value) result = X121SMCSMPVToken; break; + // + case X_121_SMC_PROVIDER_RJBPV: + result = X121SMCRJBPVToken; + break; + // case X_121_SMC_PROVIDER_VWAPC: result = X121SMCVWAPCToken; @@ -1889,6 +1896,10 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value) { result = X_121_SMC_PROVIDER_SMPV; } + else if (Contains(X121SMCRJBPVToken, value)) + { + result = X_121_SMC_PROVIDER_RJBPV; + } else if (Contains(X121SMCVWAPCToken, value)) { result = X_121_SMC_PROVIDER_VWAPC; @@ -1898,4 +1909,7 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value) return result; } +// +// Custom Providers Conditions ... + // \ No newline at end of file diff --git a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 index de9c5de0..8784ce16 100644 --- a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 @@ -148,13 +148,17 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // // Detect Signal Conditions ... - result = DetectSamePeaksAndValesSignal(conditions); - if (!result) - { - // - // TODO: Enable this ... - // result = DetectVWAPSignal(conditions); - } + // X_121_SMC_PROVIDER_SMPV ... + // result = DetectSamePeaksAndValesSignal(conditions); + // if (!result) + // { + // // + // // Detect VWAPC ... + // // X_121_SMC_PROVIDER_VWAPC ... + // result = DetectVWAPCSignal(conditions); + // } + result = DetectRJBPVSignal(conditions); + // result = DetectVWAPCSignal(conditions); // if (!result) @@ -716,17 +720,18 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy symbol, conditions.signalDir // ); - double spread = GetSpread(symbol); double pip = GetPipPrice(symbol); + double spread = GetSpread(symbol); + double points = GetPoints(symbol); // if (isBullish && selectedSL <= entry) { - selectedSL -= (pip * 3) - spread; + selectedSL -= (points * 30) - spread; } else if (isBearish && selectedSL >= entry) { - selectedSL += pip * 3 + spread; + selectedSL += (points * 30) + spread; } // @@ -744,7 +749,8 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy * * @return ( bool ) */ - bool DetectVWAPSignal( + // TODO: Required Calibrate ... + bool DetectVWAPCSignal( X121SMCStrategyConditions &conditions // ) { @@ -835,6 +841,32 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy return result; } + // + bool isBullish = + // + IsBullish(sarDir) && + IsBullish(vwapDir) && + IsBullish(candlesticDir) + // + ; + + // + bool isBearish = + // + IsBearish(sarDir) && + IsBearish(vwapDir) && + IsBearish(candlesticDir) + // + ; + + // + result = + // + isBullish || + isBearish + // + ; + // Print("VWap Signal ..."); @@ -848,6 +880,251 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy return result; } + bool DetectRJBPVSignal( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + return result; + } + + // + string msg = NULL; + + // + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_RJBPV; + string providerStr = ToString(provider); + + // + // Bar High Eqauls to Peaks or Vale ... + double peak = conditions.triggerConditions.x121Conditions.peaksBuffer[2]; + double vale = conditions.triggerConditions.x121Conditions.valesBuffer[2]; + bool isNewPeak = conditions.triggerConditions.x121Conditions.peaksBuffer[2] != conditions.triggerConditions.x121Conditions.peaksBuffer[3]; + bool isNewVale = conditions.triggerConditions.x121Conditions.valesBuffer[2] != conditions.triggerConditions.x121Conditions.valesBuffer[3]; + bool isClosedUnderDonCloseUpper = cBar.close < + conditions.triggerConditions.x121Conditions.donCloseUpperBuffer[1]; + bool isClosedOverDonCloseLower = cBar.close > + conditions.triggerConditions.x121Conditions.donCloseLowerBuffer[1]; + bool isSarBullish = + zBar.low > conditions.triggerConditions.x121Conditions.sarBuffer[0]; + bool isSarBearish = + zBar.high < conditions.triggerConditions.x121Conditions.sarBuffer[0]; + + // + // XPVPivot orderFlow[]; + // ENUM_X_DIRECTION orderFlowDir; + // mTriggerCycleHelper + // .DetectOrderFlow( + // zIndex, + // orderFlow, + // orderFlowDir // + // ); + // int pivotsCount = ArraySize(orderFlow); + // result = IsValidSize(pivotsCount); + // if (!result) + // { + // return result; + // } + // XPVPivot lastPivot = orderFlow[pivotsCount - 1]; + + // + bool isPeakInsideSupplyZone = false; + bool isValeInsideDemandZone = false; + + // + XPOIState state = conditions.consolidationConditions.state; + + // + XCSupplyZone *supplyZone; + int supplyCount = state.CountSupplyZones(); + if (IsValidSize(supplyCount)) + { + // + for (int i = 0; i < supplyCount; i++) + { + // + XCSupplyZone *iZone = state.supplyZones[i]; + isPeakInsideSupplyZone = peak >= iZone.Lower() && + peak <= iZone.Upper() && + bid >= iZone.Lower() + ((iZone.Upper() - iZone.Lower()) / 2); + if (isPeakInsideSupplyZone) + { + // + supplyZone = iZone; + break; + } + } + } + + // + XCDemandZone *demandZone; + int demandCount = state.CountDemandZones(); + if (IsValidSize(demandCount)) + { + // + for (int i = 0; i < demandCount; i++) + { + // + XCDemandZone *iZone = state.demandZones[i]; + isValeInsideDemandZone = vale >= iZone.Lower() && + vale <= iZone.Upper() && + bid <= iZone.Lower() + ((iZone.Upper() - iZone.Lower()) / 2); + if (isValeInsideDemandZone) + { + // + demandZone = iZone; + break; + } + } + } + + // + bool isPeakAttacked = + isNewPeak && + isSarBearish && + pBar.high == peak && + isPeakInsideSupplyZone && + isClosedUnderDonCloseUpper; + + // + bool isValeAttacked = + isNewVale && + isSarBullish && + pBar.low == vale && + isValeInsideDemandZone && + isClosedOverDonCloseLower; + + // + result = isPeakAttacked || + isValeAttacked; + if (!result) + { + return result; + } + + // // + // if (isPeakAttacked) + // { + // // + // supplyZone.To(TimeCurrent()); + // XCSupplyZoneObject *iObj; + // bool isCreated = mPOIDrawer.CreateSupplyZone( + // supplyZone, + // iObj // + // ); + // if (isCreated) + // { + // AddObjectIfNotExists(iObj); + // } + // } + // else + // { + // // + // demandZone.To(TimeCurrent()); + // XCDemandZoneObject *iObj; + // bool isCreated = mPOIDrawer.CreateDemandZone( + // demandZone, + // iObj // + // ); + // if (isCreated) + // { + // AddObjectIfNotExists(iObj); + // } + // } + + // + bool isBullish = + // + isValeAttacked + // + ; + + // + bool isBearish = + // + isPeakAttacked + // + ; + + // + result = + // + isBullish || + isBearish + // + ; + if (!result) + { + return result; + } + + // + // Set SL, Provider and Direction ... + conditions.signalDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + conditions.provider = providerStr; + + // + conditions.sl = + isBullish + ? demandZone.Lower() + : supplyZone.Upper(); + + // + return result; + } + // // Helper Functions ... @@ -1096,9 +1373,56 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy ; } + // + if (forProvider == X_121_SMC_PROVIDER_RJBPV) + { + // + isBullish = + // + // Trigger, Decision and Analyse must be Directional ... + conditions.triggerConditions.x121Conditions.isSarBullish && + conditions.decisionConditions.x121Conditions.isSarBullish && + conditions.analyseConditions.x121Conditions.isSarBullish + // + ; + + // + isBearish = + // + // Trigger, Decision and Analyse must be Directional ... + conditions.triggerConditions.x121Conditions.isSarBearish && + conditions.decisionConditions.x121Conditions.isSarBearish && + conditions.analyseConditions.x121Conditions.isSarBearish + // + ; + } + // if (forProvider == X_121_SMC_PROVIDER_VWAPC) { + // + isBullish = + // + // All Cycles Sars Must be Directional exept Vision ... + conditions.triggerConditions.x121Conditions.isSarBullish && + conditions.decisionConditions.x121Conditions.isSarBullish && + conditions.analyseConditions.x121Conditions.isSarBullish && + conditions.verificationConditions.x121Conditions.isSarBullish && + conditions.consolidationConditions.x121Conditions.isSarBullish + // + ; + + // + isBearish = + // + // All Cycles Sars Must be Directional exept Vision ... + conditions.triggerConditions.x121Conditions.isSarBearish && + conditions.decisionConditions.x121Conditions.isSarBearish && + conditions.analyseConditions.x121Conditions.isSarBearish && + conditions.verificationConditions.x121Conditions.isSarBearish && + conditions.consolidationConditions.x121Conditions.isSarBearish + // + ; } // @@ -1201,6 +1525,47 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // if (forProvider == X_121_SMC_PROVIDER_VWAPC) { + // + isBullish = + // + // All Cycles Must be State and Ordered Directional Except Vision ... + // State ... + conditions.triggerConditions.x121Conditions.isVWapBullishState && + conditions.decisionConditions.x121Conditions.isVWapBullishState && + conditions.analyseConditions.x121Conditions.isVWapBullishState && + conditions.verificationConditions.x121Conditions.isVWapBullishState && + conditions.consolidationConditions.x121Conditions.isVWapBullishState + // + && + // Order ... + conditions.triggerConditions.x121Conditions.isVWapBullishOrdered && + conditions.decisionConditions.x121Conditions.isVWapBullishOrdered && + conditions.analyseConditions.x121Conditions.isVWapBullishOrdered && + conditions.verificationConditions.x121Conditions.isVWapBullishOrdered && + conditions.consolidationConditions.x121Conditions.isVWapBullishOrdered + // + ; + + // + isBearish = + // + // All Cycles Must be State and Ordered Directional Except Vision ... + // State ... + conditions.triggerConditions.x121Conditions.isVWapBearishState && + conditions.decisionConditions.x121Conditions.isVWapBearishState && + conditions.analyseConditions.x121Conditions.isVWapBearishState && + conditions.verificationConditions.x121Conditions.isVWapBearishState && + conditions.consolidationConditions.x121Conditions.isVWapBearishState + // + && + // Order ... + conditions.triggerConditions.x121Conditions.isVWapBearishOrdered && + conditions.decisionConditions.x121Conditions.isVWapBearishOrdered && + conditions.analyseConditions.x121Conditions.isVWapBearishOrdered && + conditions.verificationConditions.x121Conditions.isVWapBearishOrdered && + conditions.consolidationConditions.x121Conditions.isVWapBearishOrdered + // + ; } // @@ -1606,6 +1971,66 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy ; } + // + if (forProvider == X_121_SMC_PROVIDER_RJBPV) + { + // + isBullish = + // + // CBar is Pin, Engulf, Momentum or Rejection ... + ( + // // + // (isCBarMomentum && + // IsBullish(cBarMomentumDir)) + // // + // || + // // + (isCBarRejection && + IsBullish(cBarRejectionDir)) + // // + // || + // // + // (isCBarEngulf && + // IsBullish(cBarEngulfDir)) + // + || + // + (isCBarPin && + IsBullish(cBarPinDir)) + // + ) + // + ; + + // + isBearish = + // + // CBar is Pin, Engulf, Momentum or Rejection ... + ( + // + // (isCBarMomentum && + // IsBearish(cBarMomentumDir)) + // // + // || + // // + (isCBarRejection && + IsBearish(cBarRejectionDir)) + // // + // || + // // + // (isCBarEngulf && + // IsBearish(cBarEngulfDir)) + // + || + // + (isCBarPin && + IsBearish(cBarPinDir)) + // + ) + // + ; + } + // result = isBullish || isBearish; @@ -1931,6 +2356,713 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy return result; } + // + // Drawing Functions ... + + /** + * Draw Pivot ... + * + * @param pivot: XPVPivot instance Reference ... + */ + void DrawPivot(XPVPivot &pivot) + { + // + if (!pivot.IsValid()) + { + return; + } + + // + XCXPVPivotObject *iObj; + iObj = new XCXPVPivotObject(); + bool isCreated = iObj.Create( + mPOIDrawer.ChartIdentification(), + mPOIDrawer.SubWindowIdentification(), + pivot // + ); + if (isCreated) + { + // + if (pivot.IsPeak()) + { + // + iObj.PivotWidth(1); + iObj.PivotFill(false); + iObj.PivotColor(clrAqua); + iObj.PivotStyle(STYLE_SOLID); + } + + // + if (pivot.IsVale()) + { + // + iObj.PivotWidth(1); + iObj.PivotFill(false); + iObj.PivotStyle(STYLE_SOLID); + iObj.PivotColor(clrMagenta); + } + + // + AddObjectIfNotExists(iObj); + } + } + + /** + * Custom Drawing State ... + * + * @param state: XPOIState instance reference, Specified Which state to Draw ... + * @param forceDrawSamePeriod: Boolean ... + */ + void CustomStateDrawing( + XPOIState &state, + bool forceDrawSamePeriod = false, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + // + // Ignores List ... + bool ignoreSwingHighs = false, + bool ignoreSwingLows = false, + bool ignoreSupportZones = false, + bool ignoreResistanceZones = false, + bool ignoreSupplyZones = false, + bool ignoreDemandZones = false, + bool ignoreBullishOrderBlocks = false, + bool ignoreBearishOrderBlocks = false, + bool ignoreBullishFairValueGaps = false, + bool ignoreBearishFairValueGaps = false, + bool ignoreBullishRejectionBars = false, + bool ignoreBearishRejectionBars = false, + bool ignoreBullishMomentumBars = false, + bool ignoreBearishMomentumBars = false // + ) + { + // + XPOIState tmpState = state; + if (forceDrawSamePeriod) + { + // + int count = 0; + ENUM_TIMEFRAMES period = GetPeriod(); + + // + count = state.CountSwingHighs(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing iSwing = state.swingHighs[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.swingHighs, + i, + 1 // + ); + } + } + } + + // + count = state.CountSwingLows(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing iSwing = state.swingLows[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.swingLows, + i, + 1 // + ); + } + } + } + + // + count = state.CountBullishMomentumBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar iMomentum = state.bullishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bullishMomentumBars, + i, + 1 // + ); + } + } + } + + // + count = state.CountBearishMomentumBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar iMomentum = state.bearishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bearishMomentumBars, + i, + 1 // + ); + } + } + } + + // + count = state.CountBullishRejectionBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar iRejection = state.bullishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bullishRejectionBars, + i, + 1 // + ); + } + } + } + + // + count = state.CountBearishRejectionBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar iRejection = state.bearishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bearishRejectionBars, + i, + 1 // + ); + } + } + } + + // + count = state.CountSupportZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone iZone = state.supportZones[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.supportZones, + i, + 1 // + ); + } + } + } + + // + count = state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone iZone = state.resistanceZones[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.resistanceZones, + i, + 1 // + ); + } + } + } + + // + count = state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone iZone = state.supplyZones[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.supplyZones, + i, + 1 // + ); + } + } + } + + // + count = state.CountDemandZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone iZone = state.demandZones[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.demandZones, + i, + 1 // + ); + } + } + } + + // + count = state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock iZone = state.bullishOrderBlocks[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bullishOrderBlocks, + i, + 1 // + ); + } + } + } + + // + count = state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock iZone = state.bearishOrderBlocks[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bearishOrderBlocks, + i, + 1 // + ); + } + } + } + + // + count = state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG iZone = state.bullishFairValueGaps[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillStartBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bullishFairValueGaps, + i, + 1 // + ); + } + } + } + + // + count = state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG iZone = state.bearishFairValueGaps[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillStartBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bearishFairValueGaps, + i, + 1 // + ); + } + } + } + + // + } + + // + bool drawSwingHighs = true; + bool drawSwingLows = true; + bool drawSupportZones = true; + bool drawResistanceZones = true; + bool drawSupplyZones = true; + bool drawDemandZones = true; + bool drawBullishOrderBlocks = true; + bool drawBearishOrderBlocks = true; + bool drawBullishFairValueGaps = true; + bool drawBearishFairValueGaps = true; + bool drawBullishRejectionBars = true; + bool drawBearishRejectionBars = true; + bool drawBullishMomentumBars = true; + bool drawBearishMomentumBars = true; + + // + // Change Drawing Specs Conditions based on + // Provided Direction ... + if (forDir == X_DIRECTION_BULLISH) + { + // + drawSwingLows = true; + drawDemandZones = true; + drawSupportZones = true; + drawBullishOrderBlocks = true; + drawBullishFairValueGaps = true; + drawBullishRejectionBars = true; + drawBullishMomentumBars = true; + + // + drawSwingHighs = false; + drawSupplyZones = false; + drawResistanceZones = false; + drawBearishOrderBlocks = false; + drawBearishFairValueGaps = false; + drawBearishRejectionBars = false; + drawBearishMomentumBars = false; + } + else if (forDir == X_DIRECTION_BEARISH) + { + // + drawSwingLows = false; + drawDemandZones = false; + drawSupportZones = false; + drawBullishOrderBlocks = false; + drawBullishFairValueGaps = false; + drawBullishRejectionBars = false; + drawBullishMomentumBars = false; + + // + drawSwingHighs = true; + drawSupplyZones = true; + drawResistanceZones = true; + drawBearishOrderBlocks = true; + drawBearishFairValueGaps = true; + drawBearishRejectionBars = true; + drawBearishMomentumBars = true; + } + + // + // Apply Ignore List ... + + // + if (ignoreSwingHighs) + { + drawSwingHighs = false; + } + + // + if (ignoreSwingLows) + { + drawSwingLows = false; + } + + // + if (ignoreSupportZones) + { + drawSupportZones = false; + } + + // + if (ignoreResistanceZones) + { + drawResistanceZones = false; + } + + // + if (ignoreSupplyZones) + { + drawSupplyZones = false; + } + + // + if (ignoreDemandZones) + { + drawDemandZones = false; + } + + // + if (ignoreBullishOrderBlocks) + { + drawBullishOrderBlocks = false; + } + + // + if (ignoreBearishOrderBlocks) + { + drawBearishOrderBlocks = false; + } + + // + if (ignoreBullishFairValueGaps) + { + drawBullishFairValueGaps = false; + } + + // + if (ignoreBearishFairValueGaps) + { + drawBearishFairValueGaps = false; + } + + // + if (ignoreBullishRejectionBars) + { + drawBullishRejectionBars = false; + } + + // + if (ignoreBearishRejectionBars) + { + drawBearishRejectionBars = false; + } + + // + if (ignoreBullishMomentumBars) + { + drawBullishMomentumBars = false; + } + + // + if (ignoreBearishMomentumBars) + { + drawBearishMomentumBars = false; + } + + // + DrawState( + tmpState, // State ... + true, // Update To of all Drawings Till now ... + drawSwingHighs, // Draw SwingHighs .. + drawSwingLows, // Draw SwingLows .. + drawSupportZones, // Draw SupportZones .. + drawResistanceZones, // Draw ResistanceZones .. + drawSupplyZones, // Draw SupplyZones .. + drawDemandZones, // Draw DemandZones .. + drawBullishOrderBlocks, // Draw BullishOrderBlocks .. + drawBearishOrderBlocks, // Draw BearishOrderBlocks .. + drawBullishFairValueGaps, // Draw BullishFairValueGaps .. + drawBearishFairValueGaps, // Draw BearishFairValueGaps .. + drawBullishRejectionBars, // Draw BullishRejectionBars .. + drawBearishRejectionBars, // Draw BearishRejectionBars .. + drawBullishMomentumBars, // Draw BullishMomentumBars .. + drawBearishMomentumBars, // Draw BearishMomentumBars .. + true // Draw Ticks Zone ... + ); + } + // };