From 43dd4268ab4bf1f8e3bb5ea6617d8e1761935f51 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Mon, 4 Nov 2024 01:36:42 +0330 Subject: [PATCH] Last Works On Test ... --- Classes/x-saherelm.x-poi.drawer.class.mq5 | 2 +- Documents/BKP/121.smc.draw.conditions.mq5 | 836 ++++++++++++++++++ Libraries/x-saherelm.common.lib.mq5 | 3 +- Libraries/x-saherelm.x-poi.lib.mq5 | 80 ++ X121SMCEA/Experts/x-121.smc.expert.class.mq5 | 1 + X121SMCEA/Libraries/x-121.smc.lib.mq5 | 10 +- .../x-121.smc.test.strategy.class.mq5 | Bin 134170 -> 140622 bytes 7 files changed, 929 insertions(+), 3 deletions(-) create mode 100644 Documents/BKP/121.smc.draw.conditions.mq5 diff --git a/Classes/x-saherelm.x-poi.drawer.class.mq5 b/Classes/x-saherelm.x-poi.drawer.class.mq5 index 77b51714..550fa934 100644 --- a/Classes/x-saherelm.x-poi.drawer.class.mq5 +++ b/Classes/x-saherelm.x-poi.drawer.class.mq5 @@ -2207,7 +2207,7 @@ class XCPOIDrawer : public XSCBase // string name = zone.GetTag(); result = Contains( - ToString(X_POI_BEARISH_ORDERBLOCK), + ToString(X_POI_BEARISH_FVG), name // ); if (!result) diff --git a/Documents/BKP/121.smc.draw.conditions.mq5 b/Documents/BKP/121.smc.draw.conditions.mq5 new file mode 100644 index 00000000..c48a295d --- /dev/null +++ b/Documents/BKP/121.smc.draw.conditions.mq5 @@ -0,0 +1,836 @@ + + // + // Draw Functions ... + + /** + * Draw Specific Condition ... + * + * @param conditions: X121SMCStrategyConditions instance ... + */ + void DrawConditions(X121SMCStrategyConditions &conditions) + { + // + // Draw Configurations ... + + // + bool drawMainDemand = true; + bool drawMainSupply = true; + + // + bool drawMainBullishOrderBlock = true; + bool drawMainBearishOrderBlock = true; + + // + bool drawMainBullishFVG = true; + bool drawMainBearishFVG = true; + + // + bool drawOrderBlocks = false; + bool drawFVGs = false; + bool drawSupportResistances = false; + bool drawSwings = false; + bool drawMomentumBars = false; + bool drawRejectionBars = false; + + // + if (!conditions.IsValid()) + { + return; + } + + // + datetime time = TimeCurrent(); + bool hasValidDemand = conditions.ValidateDemand(); + bool hasValidSupply = conditions.ValidateSupply(); + if (!hasValidDemand && !hasValidSupply) + { + return; + } + + // + // Demand Zone ... + if (hasValidDemand) + { + // + // Demand ... + if (drawMainDemand) + { + // + XCDemandZoneObject *iObj; + bool isCreated = mPOIDrawer.CreateDemandZone( + conditions.demandZone, + iObj // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + + // + if (drawMainBullishOrderBlock) + { + // + XCBullishOrderBlockObject *iObj; + bool isCreated = mPOIDrawer.CreateBullishOrderBlock( + conditions.bullishOrderBlock, + iObj // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + + // + if (drawMainBullishFVG) + { + // + XCBullishFVGObject *iObj; + bool isCreated = mPOIDrawer.CreateBullishFVG( + conditions.bullishFVG, + iObj // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + + // + // Order Blocks ... + int obsCount = ArraySize(conditions.bullishOrderBlocks); + if (drawOrderBlocks && + IsValidSize(obsCount)) + { + // + for (int i = 0; i < obsCount; i++) + { + // + XZone iZone = conditions.bullishOrderBlocks[i]; + + // + XCBullishOrderBlockObject *iObj; + bool isCreated = mPOIDrawer.CreateBullishOrderBlock( + iZone, + iObj // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + } + + // + // Fair Value Gaps ... + int fvgsCount = ArraySize(conditions.bullishFVGs); + if (drawFVGs && + IsValidSize(fvgsCount)) + { + // + for (int i = 0; i < fvgsCount; i++) + { + // + XZone iZone = conditions.bullishFVGs[i]; + + // + XCBullishFVGObject *iObj; + bool isCreated = mPOIDrawer.CreateBullishFVG( + iZone, + iObj // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + } + + // + // Supports ... + int supportsCount = ArraySize(conditions.supports); + if (drawSupportResistances && + IsValidSize(supportsCount)) + { + // + for (int i = 0; i < supportsCount; i++) + { + // + XOHCL iBar = conditions.supports[i]; + + // + XCSupportZoneObject *iObj; + bool isCreated = mPOIDrawer.CreateSupportZone( + iBar, + iObj, + time // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + } + + // + // Swings ... + int swingsCount = ArraySize(conditions.swingLows); + if (drawSwings && + IsValidSize(swingsCount)) + { + // + for (int i = 0; i < swingsCount; i++) + { + // + XOHCL iBar = conditions.swingLows[i]; + + // + XCSwingLowObject *iObj; + bool isCreated = mPOIDrawer.CreateSwingLow( + iBar, + iObj // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + } + + // + // Momentum Bars ... + int momentumBarsCount = ArraySize(conditions.bullishMomentumBars); + if (drawMomentumBars && + IsValidSize(momentumBarsCount)) + { + // + for (int i = 0; i < momentumBarsCount; i++) + { + // + XOHCL iBar = conditions.bullishMomentumBars[i]; + + // + XCBullishMomentumBarObject *iObj; + bool isCreated = mPOIDrawer.CreateBullishMomentumBar( + iBar, + iObj // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + } + + // + // Rejection Bars ... + int rejectionBarsCount = ArraySize(conditions.bullishRejectionBars); + if (drawRejectionBars && + IsValidSize(rejectionBarsCount)) + { + // + for (int i = 0; i < rejectionBarsCount; i++) + { + // + XOHCL iBar = conditions.bullishRejectionBars[i]; + + // + XCBullishRejectionBarObject *iObj; + bool isCreated = mPOIDrawer.CreateBullishRejectionBar( + iBar, + iObj // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + } + } + + // + // Supply Zone ... + if (hasValidSupply) + { + // + // Supply ... + if (drawMainSupply) + { + // + XCSupplyZoneObject *iObj; + bool isCreated = mPOIDrawer.CreateSupplyZone( + conditions.supplyZone, + iObj // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + + // + if (drawMainBearishOrderBlock) + { + // + XCBearishOrderBlockObject *iObj; + bool isCreated = mPOIDrawer.CreateBearishOrderBlock( + conditions.bearishOrderBlock, + iObj // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + + // + if (drawMainBearishFVG) + { + // + XCBearishFVGObject *iObj; + bool isCreated = mPOIDrawer.CreateBearishFVG( + conditions.bearishFVG, + iObj // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + + // + // Order Blocks ... + int obsCount = ArraySize(conditions.bearishOrderBlocks); + if (drawOrderBlocks && + IsValidSize(obsCount)) + { + // + for (int i = 0; i < obsCount; i++) + { + // + XZone iZone = conditions.bearishOrderBlocks[i]; + + // + XCBearishOrderBlockObject *iObj; + bool isCreated = mPOIDrawer.CreateBearishOrderBlock( + iZone, + iObj // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + } + + // + // Fair Value Gaps ... + int fvgsCount = ArraySize(conditions.bearishFVGs); + if (drawFVGs && + IsValidSize(fvgsCount)) + { + // + for (int i = 0; i < fvgsCount; i++) + { + // + XZone iZone = conditions.bearishFVGs[i]; + + // + XCBearishFVGObject *iObj; + bool isCreated = mPOIDrawer.CreateBearishFVG( + iZone, + iObj // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + } + + // + // Resistances ... + int resistancesCount = ArraySize(conditions.resistances); + if (drawSupportResistances && + IsValidSize(resistancesCount)) + { + // + for (int i = 0; i < resistancesCount; i++) + { + // + XOHCL iBar = conditions.resistances[i]; + + // + XCResistanceZoneObject *iObj; + bool isCreated = mPOIDrawer.CreateResistanceZone( + iBar, + iObj, + time // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + } + + // + // Swings ... + int swingsCount = ArraySize(conditions.swingHighs); + if (drawSwings && + IsValidSize(swingsCount)) + { + // + for (int i = 0; i < swingsCount; i++) + { + // + XOHCL iBar = conditions.swingHighs[i]; + + // + XCSwingHighObject *iObj; + bool isCreated = mPOIDrawer.CreateSwingHigh( + iBar, + iObj // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + } + + // + // Momentum Bars ... + int momentumBarsCount = ArraySize(conditions.bearishMomentumBars); + if (drawMomentumBars && + IsValidSize(momentumBarsCount)) + { + // + for (int i = 0; i < momentumBarsCount; i++) + { + // + XOHCL iBar = conditions.bearishMomentumBars[i]; + + // + XCBearishMomentumBarObject *iObj; + bool isCreated = mPOIDrawer.CreateBearishMomentumBar( + iBar, + iObj // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + } + + // + // Rejection Bars ... + int rejectionBarsCount = ArraySize(conditions.bearishRejectionBars); + if (drawRejectionBars && + IsValidSize(rejectionBarsCount)) + { + // + for (int i = 0; i < rejectionBarsCount; i++) + { + // + XOHCL iBar = conditions.bearishRejectionBars[i]; + + // + XCBearishRejectionBarObject *iObj; + bool isCreated = mPOIDrawer.CreateBearishRejectionBar( + iBar, + iObj // + ); + if (isCreated) + { + mDrawnObjects.Add(iObj); + } + } + } + } + } + + /** + * Draw Specified Market Struture ... + * + * @param structure: X121SMCMarketStructure instance ... + */ + void DrawMarketStructure( + X121SMCMarketStructure &structure, + ENUM_X_POSITION_TYPES type = X_POSITION_TYPE_ALL // + ) + { + // + datetime cTime = TimeCurrent(); + + // + bool canAll = type == X_POSITION_TYPE_ALL; + bool canLong = type == X_POSITION_TYPE_LONG; + bool canShort = type == X_POSITION_TYPE_SHORT; + + // + // Supply Zones ... + int supplysCount = ArraySize(structure.supplyZones); + if ((canAll || canLong) && IsValidSize(supplysCount)) + { + // + for (int i = 0; i < supplysCount; i++) + { + // + XZone iZone = structure.supplyZones[i]; + + // + XCSupplyZoneObject *iObj; + bool isCreated = mPOIDrawer.CreateSupplyZone( + iZone, + iObj // + ); + if (isCreated) + { + // + mDrawnObjects.Add(iObj); + } + } + } + + // + // Demand Zones ... + int demandsCount = ArraySize(structure.demandZones); + if ((canAll || canShort) && IsValidSize(demandsCount)) + { + // + for (int i = 0; i < demandsCount; i++) + { + // + XZone iZone = structure.demandZones[i]; + + // + XCDemandZoneObject *iObj; + bool isCreated = mPOIDrawer.CreateDemandZone( + iZone, + iObj // + ); + if (isCreated) + { + // + mDrawnObjects.Add(iObj); + } + } + } + + // + // Order Blocks ... + + // + // Bullish OBs ... + int bullishOBsCount = ArraySize(structure.bullishOrderBlocks); + if ((canAll || canShort) && IsValidSize(bullishOBsCount)) + { + // + for (int i = 0; i < bullishOBsCount; i++) + { + // + XZone iZone = structure.bullishOrderBlocks[i]; + + // + XCBullishOrderBlockObject *iObj; + bool isCreated = mPOIDrawer.CreateBullishOrderBlock( + iZone, + iObj // + ); + if (isCreated) + { + // + mDrawnObjects.Add(iObj); + } + } + } + + // + // Bearish OBs ... + int bearishOBsCount = ArraySize(structure.bearishOrderBlocks); + if ((canAll || canLong) && IsValidSize(bearishOBsCount)) + { + // + for (int i = 0; i < bearishOBsCount; i++) + { + // + XZone iZone = structure.bearishOrderBlocks[i]; + + // + XCBearishOrderBlockObject *iObj; + bool isCreated = mPOIDrawer.CreateBearishOrderBlock( + iZone, + iObj // + ); + if (isCreated) + { + // + mDrawnObjects.Add(iObj); + } + } + } + + // + // Fair Value Gaps ... + + // + // Bullish FVGs ... + int bullishFVGsCount = ArraySize(structure.bullishFVGs); + if ((canAll || canShort) && IsValidSize(bullishFVGsCount)) + { + // + for (int i = 0; i < bullishFVGsCount; i++) + { + // + XZone iZone = structure.bullishFVGs[i]; + + // + XCBullishFVGObject *iObj; + bool isCreated = mPOIDrawer.CreateBullishFVG( + iZone, + iObj // + ); + if (isCreated) + { + // + mDrawnObjects.Add(iObj); + } + } + } + + // + // Bearish FVGs ... + int bearishFVGsCount = ArraySize(structure.bearishFVGs); + if ((canAll || canLong) && IsValidSize(bearishFVGsCount)) + { + // + for (int i = 0; i < bearishFVGsCount; i++) + { + // + XZone iZone = structure.bearishFVGs[i]; + + // + XCBearishFVGObject *iObj; + bool isCreated = mPOIDrawer.CreateBearishFVG( + iZone, + iObj // + ); + if (isCreated) + { + // + mDrawnObjects.Add(iObj); + } + } + } + + // + // Swing Highs ... + int swingHighsCount = ArraySize(structure.swingHighs); + if ((canAll || canLong) && IsValidSize(swingHighsCount)) + { + // + for (int i = 0; i < swingHighsCount; i++) + { + // + XOHCL iBar = structure.swingHighs[i]; + + // + XCSwingHighObject *iObj; + bool isCreated = mPOIDrawer.CreateSwingHigh( + iBar, + iObj // + ); + if (isCreated) + { + // + mDrawnObjects.Add(iObj); + } + } + } + + // + // Swing Lows ... + int swingLowsCount = ArraySize(structure.swingLows); + if ((canAll || canShort) && IsValidSize(swingLowsCount)) + { + // + for (int i = 0; i < swingLowsCount; i++) + { + // + XOHCL iBar = structure.swingLows[i]; + + // + XCSwingLowObject *iObj; + bool isCreated = mPOIDrawer.CreateSwingLow( + iBar, + iObj // + ); + if (isCreated) + { + // + mDrawnObjects.Add(iObj); + } + } + } + + // + // Support Zones ... + int supportsCount = ArraySize(structure.supports); + if ((canAll || canShort) && IsValidSize(supportsCount)) + { + // + for (int i = 0; i < supportsCount; i++) + { + // + XOHCL iBar = structure.supports[i]; + + // + XCSupportZoneObject *iObj; + bool isCreated = mPOIDrawer.CreateSupportZone( + iBar, + iObj, + cTime // + ); + if (isCreated) + { + // + mDrawnObjects.Add(iObj); + } + } + } + + // + // Resistance Zones ... + int resistancesCount = ArraySize(structure.resistances); + if ((canAll || canLong) && IsValidSize(resistancesCount)) + { + // + for (int i = 0; i < resistancesCount; i++) + { + // + XOHCL iBar = structure.resistances[i]; + + // + XCResistanceZoneObject *iObj; + bool isCreated = mPOIDrawer.CreateResistanceZone( + iBar, + iObj, + cTime // + ); + if (isCreated) + { + // + mDrawnObjects.Add(iObj); + } + } + } + + // + // Momentum Bars ... + + // + // Bullish Momentum Bars ... + int momentumBarCount = ArraySize(structure.bullishMomentumBars); + if ((canAll || canShort) && IsValidSize(momentumBarCount)) + { + // + for (int i = 0; i < momentumBarCount; i++) + { + // + XOHCL iBar = structure.bullishMomentumBars[i]; + + // + XCBullishMomentumBarObject *iObj; + bool isCreated = mPOIDrawer.CreateBullishMomentumBar( + iBar, + iObj // + ); + if (isCreated) + { + // + mDrawnObjects.Add(iObj); + } + } + } + + // + // Bearish Momentum Bars ... + momentumBarCount = ArraySize(structure.bearishMomentumBars); + if ((canAll || canLong) && IsValidSize(momentumBarCount)) + { + // + for (int i = 0; i < momentumBarCount; i++) + { + // + XOHCL iBar = structure.bearishMomentumBars[i]; + + // + XCBearishMomentumBarObject *iObj; + bool isCreated = mPOIDrawer.CreateBearishMomentumBar( + iBar, + iObj // + ); + if (isCreated) + { + // + mDrawnObjects.Add(iObj); + } + } + } + + // + // Rejection Bars ... + + // + // Bullish Rejection Bars ... + int rejectionBarCount = ArraySize(structure.bullishRejectionBars); + if ((canAll || canShort) && IsValidSize(rejectionBarCount)) + { + // + for (int i = 0; i < rejectionBarCount; i++) + { + // + XOHCL iBar = structure.bullishRejectionBars[i]; + + // + XCBullishRejectionBarObject *iObj; + bool isCreated = mPOIDrawer.CreateBullishRejectionBar( + iBar, + iObj // + ); + if (isCreated) + { + // + mDrawnObjects.Add(iObj); + } + } + } + + // + // Bearish Rejection Bars ... + rejectionBarCount = ArraySize(structure.bearishRejectionBars); + if ((canAll || canLong) && IsValidSize(rejectionBarCount)) + { + // + for (int i = 0; i < rejectionBarCount; i++) + { + // + XOHCL iBar = structure.bearishRejectionBars[i]; + + // + XCBearishRejectionBarObject *iObj; + bool isCreated = mPOIDrawer.CreateBearishRejectionBar( + iBar, + iObj // + ); + if (isCreated) + { + // + mDrawnObjects.Add(iObj); + } + } + } + } diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index 2bfb7208..a1673603 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -7874,9 +7874,10 @@ double GetPriceChanged( { return result; } + ArrayReverse(closes); // - double change = (closes[0] - closes[5]) / closes[5] * 100; + double change = (closes[0] - closes[_length - 1]) / closes[_length - 1] * 100; result = change; // diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 0421af76..a42109f0 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -1915,6 +1915,86 @@ bool IsBetween( return result; } +/** + * Check Source breaked Dest from Upper ... + * + * @param source: XZone instance ... + * @param dest: XZone instance ... + * + * @return ( bool ) + */ +bool IsBreakeUpper( + XZone &source, + XZone &dest // +) +{ + // + bool result = false; + + // + result = source.IsValid() && + dest.IsValid(); + if (!result) + { + return result; + } + + // + result = + // + // Check Boundary ... + source.lower <= dest.upper && + source.lower >= dest.lower && + // + // Check Break ... + source.upper > dest.upper + // + ; + + // + return result; +} + +/** + * Check Source breaked Dest from Lower ... + * + * @param source: XZone instance ... + * @param dest: XZone instance ... + * + * @return ( bool ) + */ +bool IsBreakeLower( + XZone &source, + XZone &dest // +) +{ + // + bool result = false; + + // + result = source.IsValid() && + dest.IsValid(); + if (!result) + { + return result; + } + + // + result = + // + // Check Boundary ... + source.upper <= dest.upper && + source.upper >= dest.lower && + // + // Check Break ... + source.lower < dest.lower + // + ; + + // + return result; +} + // // State Extensions ... diff --git a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 index 939e61da..f60004a2 100644 --- a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 +++ b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 @@ -829,6 +829,7 @@ class XC121SMCExpert : public XCBaseExpert // Confiugre Signalling ... // + strategy.R2R(2); strategy.AllowLong(AllowLong()); strategy.AllowShort(AllowShort()); diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index 124c0fde..9b1df689 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -56,6 +56,7 @@ struct X121SMCStrategyConditions // XZone supplyZone; XZone bearishOrderBlock; + XZone bearishFVG; // XZone bearishOrderBlocks[]; @@ -70,6 +71,7 @@ struct X121SMCStrategyConditions // XZone demandZone; XZone bullishOrderBlock; + XZone bullishFVG; // XZone bullishOrderBlocks[]; @@ -102,6 +104,7 @@ struct X121SMCStrategyConditions // supplyZone.Clean(); + bearishFVG.Clean(); bearishOrderBlock.Clean(); // @@ -110,7 +113,8 @@ struct X121SMCStrategyConditions // demandZone.Clean(); - bearishOrderBlock.Clean(); + bullishFVG.Clean(); + bullishOrderBlock.Clean(); // Clean(bullishFVGs); @@ -133,6 +137,7 @@ struct X121SMCStrategyConditions { // demandZone.Clean(); + bullishFVG.Clean(); bullishOrderBlock.Clean(); // @@ -148,6 +153,7 @@ struct X121SMCStrategyConditions { // supplyZone.Clean(); + bearishFVG.Clean(); bearishOrderBlock.Clean(); // @@ -175,6 +181,7 @@ struct X121SMCStrategyConditions result = // supplyZone.IsValid() && + bearishFVG.IsValid() && bearishOrderBlock.IsValid() && (ArraySize(swingHighs) > 0 || ArraySize(bearishFVGs) > 0 || @@ -205,6 +212,7 @@ struct X121SMCStrategyConditions result = // demandZone.IsValid() && + bullishFVG.IsValid() && bullishOrderBlock.IsValid() && (ArraySize(supports) > 0 || ArraySize(swingLows) > 0 || diff --git a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 index 1d0bb171158b64b581305477478b8a5a93f8d4b0..9f60be188a5d215309c4e39718a82fcea0240598 100644 GIT binary patch delta 8969 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 v;F-sG65PQ