From 4362b1aeafefdc0a71e3c2c251f0851e3c31c89f Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Sat, 2 Nov 2024 05:52:16 +0330 Subject: [PATCH] Last ... --- Classes/x-saherelm.x-chart-objects.class.mq5 | 9 +- Classes/x-saherelm.x-poi.drawer.class.mq5 | 8 +- Documents/BKP/121.smc.poi.detector.mq5 | 1411 +++++++++++++++++ Experts/x-saherelm.x-121.smc.ea.mq5 | 13 + Libraries/x-saherelm.common.lib.mq5 | 19 +- Libraries/x-saherelm.x-poi.lib.mq5 | 363 ++++- .../x-saherelm.x121.smc.trade.handler.mq5 | 1 + X121SMCEA/Libraries/x-121.smc.lib.mq5 | 85 + .../Strategy/x-121.smc.strategy.class.mq5 | Bin 134108 -> 194982 bytes 9 files changed, 1893 insertions(+), 16 deletions(-) create mode 100644 Documents/BKP/121.smc.poi.detector.mq5 create mode 100644 X121SMCEA/Handler/x-saherelm.x121.smc.trade.handler.mq5 diff --git a/Classes/x-saherelm.x-chart-objects.class.mq5 b/Classes/x-saherelm.x-chart-objects.class.mq5 index 4c1fbeb1..398dd25e 100644 --- a/Classes/x-saherelm.x-chart-objects.class.mq5 +++ b/Classes/x-saherelm.x-chart-objects.class.mq5 @@ -799,6 +799,9 @@ class XCSignalObject : public XCBaseObject return result; } + // + string nameMD5 = ToMD5(name); + // int delay = (PeriodSeconds(signal.period) * 2); datetime time1 = (datetime)((int)signal.time - delay); @@ -806,7 +809,7 @@ class XCSignalObject : public XCBaseObject // // TP ... - string tpName = ToString(X_TP) + "_" + name; + string tpName = ToString(X_TP) + "_" + nameMD5; result = mTPTrend.Create( chart_id, tpName, @@ -823,7 +826,7 @@ class XCSignalObject : public XCBaseObject // // SL ... - string slName = ToString(X_SL) + "_" + name; + string slName = ToString(X_SL) + "_" + nameMD5; result = mSLTrend.Create( chart_id, slName, @@ -842,7 +845,7 @@ class XCSignalObject : public XCBaseObject // // ENTRY ... - string entrName = ToString(X_ENTRY) + "_" + name; + string entrName = ToString(X_ENTRY) + "_" + nameMD5; result = mEntryTrend.Create( chart_id, entrName, diff --git a/Classes/x-saherelm.x-poi.drawer.class.mq5 b/Classes/x-saherelm.x-poi.drawer.class.mq5 index 103484cd..77b51714 100644 --- a/Classes/x-saherelm.x-poi.drawer.class.mq5 +++ b/Classes/x-saherelm.x-poi.drawer.class.mq5 @@ -1738,7 +1738,8 @@ class XCPOIDrawer : public XSCBase */ bool CreateResistanceZone( XOHCL &bar, - XCResistanceZoneObject *&object // + XCResistanceZoneObject *&object, + datetime destTime = NULL // ) { // @@ -1762,7 +1763,10 @@ class XCPOIDrawer : public XSCBase string name = bar.GetTag(ToString(X_POI_RESISTANCE_ZONE)); // - datetime time2 = (datetime)((int)bar.time + (PeriodSeconds(bar.period) * 5)); + datetime time2 = + IsValid(destTime) + ? destTime + : (datetime)((int)bar.time + (PeriodSeconds(bar.period) * 5)); // bool fill = ResistanceZoneFill(); diff --git a/Documents/BKP/121.smc.poi.detector.mq5 b/Documents/BKP/121.smc.poi.detector.mq5 new file mode 100644 index 00000000..2704e058 --- /dev/null +++ b/Documents/BKP/121.smc.poi.detector.mq5 @@ -0,0 +1,1411 @@ + // // 4H ... + // int orderBlocksCount = ArraySize(h4State.bearishOrderBlocks); + // if (IsValidSize(orderBlocksCount)) + // { + // // + // for (int j = 0; j < orderBlocksCount; j++) + // { + // // + // XZone jZone = h4State.bearishOrderBlocks[j]; + + // // + // bool isInside = IsInside( + // jZone, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // jZone.to = TimeCurrent(); + + // // + // AddIfNotExists( + // jZone, + // conditions.bearishOrderBlocks // + // ); + // } + // } + // } + // // 15M ... + // orderBlocksCount = ArraySize(m15State.bearishOrderBlocks); + // if (IsValidSize(orderBlocksCount)) + // { + // // + // for (int j = 0; j < orderBlocksCount; j++) + // { + // // + // XZone jZone = m15State.bearishOrderBlocks[j]; + + // // + // bool isInside = IsInside( + // jZone, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // jZone.to = TimeCurrent(); + + // // + // AddIfNotExists( + // jZone, + // conditions.bearishOrderBlocks // + // ); + // } + // } + // } + // // 5M ... + // orderBlocksCount = ArraySize(m5State.bearishOrderBlocks); + // if (IsValidSize(orderBlocksCount)) + // { + // // + // for (int j = 0; j < orderBlocksCount; j++) + // { + // // + // XZone jZone = m5State.bearishOrderBlocks[j]; + + // // + // bool isInside = IsInside( + // jZone, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // jZone.to = TimeCurrent(); + + // // + // AddIfNotExists( + // jZone, + // conditions.bearishOrderBlocks // + // ); + // } + // } + // } + // // 1M ... + // orderBlocksCount = ArraySize(m1State.bearishOrderBlocks); + // if (IsValidSize(orderBlocksCount)) + // { + // // + // for (int j = 0; j < orderBlocksCount; j++) + // { + // // + // XZone jZone = m1State.bearishOrderBlocks[j]; + + // // + // bool isInside = IsInside( + // jZone, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // jZone.to = TimeCurrent(); + + // // + // AddIfNotExists( + // jZone, + // conditions.bearishOrderBlocks // + // ); + // } + // } + // } + + // // 4H ... + // int resistancesCount = ArraySize(h4State.resistanceZones); + // if (IsValidSize(resistancesCount)) + // { + // // + // for (int j = 0; j < resistancesCount; j++) + // { + // // + // XOHCL jBar = h4State.resistanceZones[j]; + + // // + // bool isInside = IsInside( + // jBar, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.resistances // + // ); + // } + // } + // } + // // 15M ... + // resistancesCount = ArraySize(m15State.resistanceZones); + // if (IsValidSize(resistancesCount)) + // { + // // + // for (int j = 0; j < resistancesCount; j++) + // { + // // + // XOHCL jBar = m15State.resistanceZones[j]; + + // // + // bool isInside = IsInside( + // jBar, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.resistances // + // ); + // } + // } + // } + // // 5M ... + // resistancesCount = ArraySize(m5State.resistanceZones); + // if (IsValidSize(resistancesCount)) + // { + // // + // for (int j = 0; j < resistancesCount; j++) + // { + // // + // XOHCL jBar = m5State.resistanceZones[j]; + + // // + // bool isInside = IsInside( + // jBar, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.resistances // + // ); + // } + // } + // } + // // 1M ... + // resistancesCount = ArraySize(m1State.resistanceZones); + // if (IsValidSize(resistancesCount)) + // { + // // + // for (int j = 0; j < resistancesCount; j++) + // { + // // + // XOHCL jBar = m1State.resistanceZones[j]; + + // // + // bool isInside = IsInside( + // jBar, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.resistances // + // ); + // } + // } + // } + + // // 4H ... + // int fvgsCount = ArraySize(h4State.bearishFVGs); + // if (IsValidSize(fvgsCount)) + // { + // // + // for (int j = 0; j < fvgsCount; j++) + // { + // // + // XZone jFVG = h4State.bearishFVGs[j]; + + // // + // bool isInside = IsInside( + // jFVG, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // jFVG.to = TimeCurrent(); + + // // + // AddIfNotExists( + // jFVG, + // conditions.bearishFVGs // + // ); + // } + // } + // } + // // 15M ... + // fvgsCount = ArraySize(m15State.bearishFVGs); + // if (IsValidSize(fvgsCount)) + // { + // // + // for (int j = 0; j < fvgsCount; j++) + // { + // // + // XZone jFVG = m15State.bearishFVGs[j]; + + // // + // bool isInside = IsInside( + // jFVG, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // jFVG.to = TimeCurrent(); + + // // + // AddIfNotExists( + // jFVG, + // conditions.bearishFVGs // + // ); + // } + // } + // } + // // 5M ... + // fvgsCount = ArraySize(m5State.bearishFVGs); + // if (IsValidSize(fvgsCount)) + // { + // // + // for (int j = 0; j < fvgsCount; j++) + // { + // // + // XZone jFVG = m5State.bearishFVGs[j]; + + // // + // bool isInside = IsInside( + // jFVG, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // jFVG.to = TimeCurrent(); + + // // + // AddIfNotExists( + // jFVG, + // conditions.bearishFVGs // + // ); + // } + // } + // } + // // 1M ... + // fvgsCount = ArraySize(m1State.bearishFVGs); + // if (IsValidSize(fvgsCount)) + // { + // // + // for (int j = 0; j < fvgsCount; j++) + // { + // // + // XZone jFVG = m1State.bearishFVGs[j]; + + // // + // bool isInside = IsInside( + // jFVG, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // jFVG.to = TimeCurrent(); + + // // + // AddIfNotExists( + // jFVG, + // conditions.bearishFVGs // + // ); + // } + // } + // } + + // // 4H ... + // int swingsCount = ArraySize(h4State.swingHighs); + // if (IsValidSize(swingsCount)) + // { + // // + // for (int j = 0; j < swingsCount; j++) + // { + // // + // XOHCL jBar = h4State.swingHighs[j]; + + // // + // bool isInside = IsInside( + // jBar, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.swingHighs // + // ); + // } + // } + // } + // // 15M ... + // swingsCount = ArraySize(m15State.swingHighs); + // if (IsValidSize(swingsCount)) + // { + // // + // for (int j = 0; j < swingsCount; j++) + // { + // // + // XOHCL jBar = m15State.swingHighs[j]; + + // // + // bool isInside = IsInside( + // jBar, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.swingHighs // + // ); + // } + // } + // } + // // 5M ... + // swingsCount = ArraySize(m5State.swingHighs); + // if (IsValidSize(swingsCount)) + // { + // // + // for (int j = 0; j < swingsCount; j++) + // { + // // + // XOHCL jBar = m5State.swingHighs[j]; + + // // + // bool isInside = IsInside( + // jBar, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.swingHighs // + // ); + // } + // } + // } + // // 1M ... + // swingsCount = ArraySize(m1State.swingHighs); + // if (IsValidSize(swingsCount)) + // { + // // + // for (int j = 0; j < swingsCount; j++) + // { + // // + // XOHCL jBar = m1State.swingHighs[j]; + + // // + // bool isInside = IsInside( + // jBar, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.swingHighs // + // ); + // } + // } + // } + + + // // 4H ... + // int momentumBarsCount = ArraySize(h4State.momentumBars); + // if (IsValidSize(momentumBarsCount)) + // { + // // + // for (int j = 0; j < momentumBarsCount; j++) + // { + // // + // XOHCL jBar = h4State.momentumBars[j]; + + // // + // bool isInside = + // jBar.IsBearish() && + // jBar.time > iSupplyZone.from && + // IsInside( + // jBar, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.bearishMomentumBars // + // ); + // } + // } + // } + // // 15M ... + // momentumBarsCount = ArraySize(m15State.momentumBars); + // if (IsValidSize(momentumBarsCount)) + // { + // // + // for (int j = 0; j < momentumBarsCount; j++) + // { + // // + // XOHCL jBar = m15State.momentumBars[j]; + + // // + // bool isInside = + // jBar.IsBearish() && + // jBar.time > iSupplyZone.from && + // IsInside( + // jBar, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.bearishMomentumBars // + // ); + // } + // } + // } + // // 5M ... + // momentumBarsCount = ArraySize(m5State.momentumBars); + // if (IsValidSize(momentumBarsCount)) + // { + // // + // for (int j = 0; j < momentumBarsCount; j++) + // { + // // + // XOHCL jBar = m5State.momentumBars[j]; + + // // + // bool isInside = + // jBar.IsBearish() && + // jBar.time > iSupplyZone.from && + // IsInside( + // jBar, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.bearishMomentumBars // + // ); + // } + // } + // } + // // 1M ... + // momentumBarsCount = ArraySize(m1State.momentumBars); + // if (IsValidSize(momentumBarsCount)) + // { + // // + // for (int j = 0; j < momentumBarsCount; j++) + // { + // // + // XOHCL jBar = m1State.momentumBars[j]; + + // // + // bool isInside = + // jBar.IsBearish() && + // jBar.time > iSupplyZone.from && + // IsInside( + // jBar, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.bearishMomentumBars // + // ); + // } + // } + // } + + // // 4H ... + // int rejectionBarsCount = ArraySize(h4State.rejectionBars); + // if (IsValidSize(rejectionBarsCount)) + // { + // // + // for (int j = 0; j < rejectionBarsCount; j++) + // { + // // + // XOHCL jBar = h4State.rejectionBars[j]; + + // // + // bool isInside = + // jBar.GetLowShadow() < jBar.GetHighShadow() && + // jBar.time > iSupplyZone.from && + // IsInside( + // jBar, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.bearishRejectionBars // + // ); + // } + // } + // } + // // 15M ... + // rejectionBarsCount = ArraySize(m15State.rejectionBars); + // if (IsValidSize(rejectionBarsCount)) + // { + // // + // for (int j = 0; j < rejectionBarsCount; j++) + // { + // // + // XOHCL jBar = m15State.rejectionBars[j]; + + // // + // bool isInside = + // jBar.GetLowShadow() < jBar.GetHighShadow() && + // jBar.time > iSupplyZone.from && + // IsInside( + // jBar, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.bearishRejectionBars // + // ); + // } + // } + // } + // // 5M ... + // rejectionBarsCount = ArraySize(m5State.rejectionBars); + // if (IsValidSize(rejectionBarsCount)) + // { + // // + // for (int j = 0; j < rejectionBarsCount; j++) + // { + // // + // XOHCL jBar = m5State.rejectionBars[j]; + + // // + // bool isInside = + // jBar.GetLowShadow() < jBar.GetHighShadow() && + // jBar.time > iSupplyZone.from && + // IsInside( + // jBar, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.bearishRejectionBars // + // ); + // } + // } + // } + // // 1M ... + // rejectionBarsCount = ArraySize(m1State.rejectionBars); + // if (IsValidSize(rejectionBarsCount)) + // { + // // + // for (int j = 0; j < rejectionBarsCount; j++) + // { + // // + // XOHCL jBar = m1State.rejectionBars[j]; + + // // + // bool isInside = + // jBar.GetLowShadow() < jBar.GetHighShadow() && + // jBar.time > iSupplyZone.from && + // IsInside( + // jBar, + // iSupplyZone, + // X_ZONE_UPPER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.bearishRejectionBars // + // ); + // } + // } + // } + + + // // 4H ... + // int orderBlocksCount = ArraySize(h4State.bullishOrderBlocks); + // if (IsValidSize(orderBlocksCount)) + // { + // // + // for (int j = 0; j < orderBlocksCount; j++) + // { + // // + // XZone jZone = h4State.bullishOrderBlocks[j]; + + // // + // bool isInside = IsInside( + // jZone, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // jZone.to = TimeCurrent(); + + // // + // AddIfNotExists( + // jZone, + // conditions.bullishOrderBlocks // + // ); + // } + // } + // } + // // 15M ... + // orderBlocksCount = ArraySize(m15State.bullishOrderBlocks); + // if (IsValidSize(orderBlocksCount)) + // { + // // + // for (int j = 0; j < orderBlocksCount; j++) + // { + // // + // XZone jZone = m15State.bullishOrderBlocks[j]; + + // // + // bool isInside = IsInside( + // jZone, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // jZone.to = TimeCurrent(); + + // // + // AddIfNotExists( + // jZone, + // conditions.bullishOrderBlocks // + // ); + // } + // } + // } + // // 5M ... + // orderBlocksCount = ArraySize(m5State.bullishOrderBlocks); + // if (IsValidSize(orderBlocksCount)) + // { + // // + // for (int j = 0; j < orderBlocksCount; j++) + // { + // // + // XZone jZone = m5State.bullishOrderBlocks[j]; + + // // + // bool isInside = IsInside( + // jZone, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // jZone.to = TimeCurrent(); + + // // + // AddIfNotExists( + // jZone, + // conditions.bullishOrderBlocks // + // ); + // } + // } + // } + // // 1M ... + // orderBlocksCount = ArraySize(m1State.bullishOrderBlocks); + // if (IsValidSize(orderBlocksCount)) + // { + // // + // for (int j = 0; j < orderBlocksCount; j++) + // { + // // + // XZone jZone = m1State.bullishOrderBlocks[j]; + + // // + // bool isInside = IsInside( + // jZone, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // jZone.to = TimeCurrent(); + + // // + // AddIfNotExists( + // jZone, + // conditions.bullishOrderBlocks // + // ); + // } + // } + // } + + + // // 4H ... + // int supportsCount = ArraySize(h4State.supportZones); + // if (IsValidSize(supportsCount)) + // { + // // + // for (int j = 0; j < supportsCount; j++) + // { + // // + // XOHCL jBar = h4State.supportZones[j]; + + // // + // bool isInside = IsInside( + // jBar, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.supports // + // ); + // } + // } + // } + // // 15M ... + // supportsCount = ArraySize(m15State.supportZones); + // if (IsValidSize(supportsCount)) + // { + // // + // for (int j = 0; j < supportsCount; j++) + // { + // // + // XOHCL jBar = m15State.supportZones[j]; + + // // + // bool isInside = IsInside( + // jBar, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.supports // + // ); + // } + // } + // } + // // 5M ... + // supportsCount = ArraySize(m5State.supportZones); + // if (IsValidSize(supportsCount)) + // { + // // + // for (int j = 0; j < supportsCount; j++) + // { + // // + // XOHCL jBar = m5State.supportZones[j]; + + // // + // bool isInside = IsInside( + // jBar, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.supports // + // ); + // } + // } + // } + // // 1M ... + // supportsCount = ArraySize(m1State.supportZones); + // if (IsValidSize(supportsCount)) + // { + // // + // for (int j = 0; j < supportsCount; j++) + // { + // // + // XOHCL jBar = m1State.supportZones[j]; + + // // + // bool isInside = IsInside( + // jBar, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.supports // + // ); + // } + // } + // } + + + // // 4H ... + // int fvgsCount = ArraySize(h4State.bullishFVGs); + // if (IsValidSize(fvgsCount)) + // { + // // + // for (int j = 0; j < fvgsCount; j++) + // { + // // + // XZone jFVG = h4State.bullishFVGs[j]; + + // // + // bool isInside = IsInside( + // jFVG, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // jFVG.to = TimeCurrent(); + + // // + // AddIfNotExists( + // jFVG, + // conditions.bullishFVGs // + // ); + // } + // } + // } + // // 15M ... + // fvgsCount = ArraySize(m15State.bullishFVGs); + // if (IsValidSize(fvgsCount)) + // { + // // + // for (int j = 0; j < fvgsCount; j++) + // { + // // + // XZone jFVG = m15State.bullishFVGs[j]; + + // // + // bool isInside = IsInside( + // jFVG, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // jFVG.to = TimeCurrent(); + + // // + // AddIfNotExists( + // jFVG, + // conditions.bullishFVGs // + // ); + // } + // } + // } + // // 5M ... + // fvgsCount = ArraySize(m5State.bullishFVGs); + // if (IsValidSize(fvgsCount)) + // { + // // + // for (int j = 0; j < fvgsCount; j++) + // { + // // + // XZone jFVG = m5State.bullishFVGs[j]; + + // // + // bool isInside = IsInside( + // jFVG, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // jFVG.to = TimeCurrent(); + + // // + // AddIfNotExists( + // jFVG, + // conditions.bullishFVGs // + // ); + // } + // } + // } + // // 1M ... + // fvgsCount = ArraySize(m1State.bullishFVGs); + // if (IsValidSize(fvgsCount)) + // { + // // + // for (int j = 0; j < fvgsCount; j++) + // { + // // + // XZone jFVG = m1State.bullishFVGs[j]; + + // // + // bool isInside = IsInside( + // jFVG, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // jFVG.to = TimeCurrent(); + + // // + // AddIfNotExists( + // jFVG, + // conditions.bullishFVGs // + // ); + // } + // } + // } + + + // // 4H ... + // int swingsCount = ArraySize(h4State.swingLows); + // if (IsValidSize(swingsCount)) + // { + // // + // for (int j = 0; j < swingsCount; j++) + // { + // // + // XOHCL jBar = h4State.swingLows[j]; + + // // + // bool isInside = IsInside( + // jBar, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.swingLows // + // ); + // } + // } + // } + // // 15M ... + // swingsCount = ArraySize(m15State.swingLows); + // if (IsValidSize(swingsCount)) + // { + // // + // for (int j = 0; j < swingsCount; j++) + // { + // // + // XOHCL jBar = m15State.swingLows[j]; + + // // + // bool isInside = IsInside( + // jBar, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.swingLows // + // ); + // } + // } + // } + // // 5M ... + // swingsCount = ArraySize(m5State.swingLows); + // if (IsValidSize(swingsCount)) + // { + // // + // for (int j = 0; j < swingsCount; j++) + // { + // // + // XOHCL jBar = m5State.swingLows[j]; + + // // + // bool isInside = IsInside( + // jBar, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.swingLows // + // ); + // } + // } + // } + // // 1M ... + // swingsCount = ArraySize(m1State.swingLows); + // if (IsValidSize(swingsCount)) + // { + // // + // for (int j = 0; j < swingsCount; j++) + // { + // // + // XOHCL jBar = m1State.swingLows[j]; + + // // + // bool isInside = IsInside( + // jBar, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.swingLows // + // ); + // } + // } + // } + + + + // // 4H ... + // int momentumBarsCount = ArraySize(h4State.momentumBars); + // if (IsValidSize(momentumBarsCount)) + // { + // // + // for (int j = 0; j < momentumBarsCount; j++) + // { + // // + // XOHCL jBar = h4State.momentumBars[j]; + + // // + // bool isInside = + // jBar.IsBullish() && + // jBar.time > iDemandZone.from && + // IsInside( + // jBar, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.bullishMomentumBars // + // ); + // } + // } + // } + // // 15M ... + // momentumBarsCount = ArraySize(m15State.momentumBars); + // if (IsValidSize(momentumBarsCount)) + // { + // // + // for (int j = 0; j < momentumBarsCount; j++) + // { + // // + // XOHCL jBar = m15State.momentumBars[j]; + + // // + // bool isInside = + // jBar.IsBullish() && + // jBar.time > iDemandZone.from && + // IsInside( + // jBar, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.bullishMomentumBars // + // ); + // } + // } + // } + // // 5M ... + // momentumBarsCount = ArraySize(m5State.momentumBars); + // if (IsValidSize(momentumBarsCount)) + // { + // // + // for (int j = 0; j < momentumBarsCount; j++) + // { + // // + // XOHCL jBar = m5State.momentumBars[j]; + + // // + // bool isInside = + // jBar.IsBullish() && + // jBar.time > iDemandZone.from && + // IsInside( + // jBar, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.bullishMomentumBars // + // ); + // } + // } + // } + // // 1M ... + // momentumBarsCount = ArraySize(m1State.momentumBars); + // if (IsValidSize(momentumBarsCount)) + // { + // // + // for (int j = 0; j < momentumBarsCount; j++) + // { + // // + // XOHCL jBar = m1State.momentumBars[j]; + + // // + // bool isInside = + // jBar.IsBullish() && + // jBar.time > iDemandZone.from && + // IsInside( + // jBar, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.bullishMomentumBars // + // ); + // } + // } + // } + + + // // 4H ... + // int rejectionBarsCount = ArraySize(h4State.rejectionBars); + // if (IsValidSize(rejectionBarsCount)) + // { + // // + // for (int j = 0; j < rejectionBarsCount; j++) + // { + // // + // XOHCL jBar = h4State.rejectionBars[j]; + + // // + // bool isInside = + // jBar.GetLowShadow() > jBar.GetHighShadow() && + // jBar.time > iDemandZone.from && + // IsInside( + // jBar, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.bullishRejectionBars // + // ); + // } + // } + // } + // // 15M ... + // rejectionBarsCount = ArraySize(m15State.rejectionBars); + // if (IsValidSize(rejectionBarsCount)) + // { + // // + // for (int j = 0; j < rejectionBarsCount; j++) + // { + // // + // XOHCL jBar = m15State.rejectionBars[j]; + + // // + // bool isInside = + // jBar.GetLowShadow() > jBar.GetHighShadow() && + // jBar.time > iDemandZone.from && + // IsInside( + // jBar, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.bullishRejectionBars // + // ); + // } + // } + // } + // // 5M ... + // rejectionBarsCount = ArraySize(m5State.rejectionBars); + // if (IsValidSize(rejectionBarsCount)) + // { + // // + // for (int j = 0; j < rejectionBarsCount; j++) + // { + // // + // XOHCL jBar = m5State.rejectionBars[j]; + + // // + // bool isInside = + // jBar.GetLowShadow() > jBar.GetHighShadow() && + // jBar.time > iDemandZone.from && + // IsInside( + // jBar, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.bullishRejectionBars // + // ); + // } + // } + // } + // // 1M ... + // rejectionBarsCount = ArraySize(m1State.rejectionBars); + // if (IsValidSize(rejectionBarsCount)) + // { + // // + // for (int j = 0; j < rejectionBarsCount; j++) + // { + // // + // XOHCL jBar = m1State.rejectionBars[j]; + + // // + // bool isInside = + // jBar.GetLowShadow() > jBar.GetHighShadow() && + // jBar.time > iDemandZone.from && + // IsInside( + // jBar, + // iDemandZone, + // X_ZONE_LOWER_EDGE, + // true // + // ); + // if (isInside) + // { + // // + // AddIfNotExists( + // jBar, + // conditions.bullishRejectionBars // + // ); + // } + // } + // } diff --git a/Experts/x-saherelm.x-121.smc.ea.mq5 b/Experts/x-saherelm.x-121.smc.ea.mq5 index 6c7685a7..869c8cea 100644 --- a/Experts/x-saherelm.x-121.smc.ea.mq5 +++ b/Experts/x-saherelm.x-121.smc.ea.mq5 @@ -276,6 +276,13 @@ void OnSignalRecieved( { // // TODO: Implement this ... + + // + ENUM_X_SIGNAL_EXECUTION_RESULT state; + eaTrader.ExecuteSignal( + signal, + state // + ); } // @@ -446,6 +453,9 @@ bool InitEA() _Period // ); + // + iX121SMCStrategy.AddXSignalEventHandler(OnSignalRecieved); + // ConfigureStrategy(iX121SMCStrategy); RegisterStrategy(iX121SMCStrategy); @@ -508,6 +518,9 @@ bool InitEA() _Period // ); + // + iX121SMCStrategy.AddXSignalEventHandler(OnSignalRecieved); + // // Register Strategy ... ConfigureStrategy(iX121SMCStrategy); diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index b91ce672..2bfb7208 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -538,39 +538,40 @@ struct XOHCL time = iTime( mSymbol, mPeriod, - barIndex - // + barIndex // ); // open = iOpen( mSymbol, mPeriod, - barIndex - // + barIndex // ); + open = NormalizePrice(open, mSymbol); // close = iClose( mSymbol, mPeriod, - barIndex - // + barIndex // ); + close = NormalizePrice(close, mSymbol); // high = iHigh( mSymbol, mPeriod, - barIndex); + barIndex // + ); + high = NormalizePrice(high, mSymbol); // low = iLow( mSymbol, mPeriod, - barIndex - // + barIndex // ); + low = NormalizePrice(low, mSymbol); // bool result = IsValid(); diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 9f617936..0421af76 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -436,6 +436,45 @@ struct XZone return result; } + // + double GetRange() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = upper - lower; + + // + return result; + } + + // + double GetMiddle() + { + // + double result = 0; + + // + double range = GetRange(); + if (range <= 0) + { + return result; + } + + // + result = lower + (range / 2); + + // + return result; + } + // string GetTag() { @@ -1730,11 +1769,12 @@ bool IsInside( double upper = edge == X_ZONE_UPPER_EDGE ? source.high - : source.GetDown(); + : source.GetUp(); double lower = edge == X_ZONE_UPPER_EDGE - ? source.GetUp() + ? source.GetDown() : source.low; + result = iSource.Init( upper, lower, @@ -1759,9 +1799,328 @@ bool IsInside( return result; } +/** + * Check a Zone is Between to other Zones ... + * + * @param source: XZone instance ... + * @param upper: XZone instance ... + * @param lower: XZone instance ... + * + * @return ( bool ) + */ +bool IsBetween( + XZone &source, + XZone &upper, + XZone &lower // +) +{ + // + bool result = false; + + // + result = source.IsValid(); + if (!result) + { + return result; + } + + // + bool isUpperValid = upper.IsValid(); + bool isLowerValid = lower.IsValid(); + + // + result = isUpperValid || + isLowerValid; + if (!result) + { + return result; + } + + // + if (isUpperValid) + { + // + result = source.upper < upper.lower; + if (!result) + { + return result; + } + } + + // + if (isLowerValid) + { + // + result = source.lower > lower.upper; + if (!result) + { + return result; + } + } + + // + return result; +} +bool IsBetween( + XOHCL &source, + XZone &upper, + XZone &lower // +) +{ + // + bool result = false; + + // + result = source.IsValid(); + if (!result) + { + return result; + } + + // + bool isUpperValid = upper.IsValid(); + bool isLowerValid = lower.IsValid(); + + // + result = isUpperValid || + isLowerValid; + if (!result) + { + return result; + } + + // + if (isUpperValid) + { + // + result = source.high < upper.lower; + if (!result) + { + return result; + } + } + + // + if (isLowerValid) + { + // + result = source.low > lower.upper; + if (!result) + { + return result; + } + } + + // + return result; +} + // // State Extensions ... +/** + * Normalize and Combine States ... + * + * @param dest: XPOIState instance ...ّ + * @param states: XPOIState instance ...ّ + */ +void CombineStates( + XPOIState &dest, + XPOIState &states[] // +) +{ + // + dest.Clean(); + + // + int count = ArraySize(states); + if (!IsValidSize(count)) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + XPOIState iState = states[i]; + + // + dest.symbol = iState.symbol; + dest.period = + !IsValid(dest.period) || + PeriodSeconds(dest.period) < PeriodSeconds(iState.period) + ? iState.period + : dest.period; + dest.reportedAt = + !IsValid(dest.reportedAt) || + dest.reportedAt > iState.reportedAt + ? iState.reportedAt + : dest.reportedAt; + + // + // Demand ... + int iCount = ArraySize(iState.demandZones); + if (IsValidSize(iCount)) + { + // + Copy( + iState.demandZones, + dest.demandZones, + false // + ); + } + + // + // Supply ... + iCount = ArraySize(iState.supplyZones); + if (IsValidSize(iCount)) + { + // + Copy( + iState.supplyZones, + dest.supplyZones, + false // + ); + } + + // + // Order Blocks ... + + // + iCount = ArraySize(iState.bullishOrderBlocks); + if (IsValidSize(iCount)) + { + // + Copy( + iState.bullishOrderBlocks, + dest.bullishOrderBlocks, + false // + ); + } + + // + iCount = ArraySize(iState.bearishOrderBlocks); + if (IsValidSize(iCount)) + { + // + Copy( + iState.bearishOrderBlocks, + dest.bearishOrderBlocks, + false // + ); + } + + // + // Fair Value Gaps ... + + // + iCount = ArraySize(iState.bullishFVGs); + if (IsValidSize(iCount)) + { + // + Copy( + iState.bullishFVGs, + dest.bullishFVGs, + false // + ); + } + + // + iCount = ArraySize(iState.bearishFVGs); + if (IsValidSize(iCount)) + { + // + Copy( + iState.bearishFVGs, + dest.bearishFVGs, + false // + ); + } + + // + // Supports ... + iCount = ArraySize(iState.supportZones); + if (IsValidSize(iCount)) + { + // + Copy( + iState.supportZones, + dest.supportZones, + false // + ); + } + + // + // Resistances ... + iCount = ArraySize(iState.resistanceZones); + if (IsValidSize(iCount)) + { + // + Copy( + iState.resistanceZones, + dest.resistanceZones, + false // + ); + } + + // + // Swings ... + + // + // Swing Highs ... + iCount = ArraySize(iState.swingHighs); + if (IsValidSize(iCount)) + { + // + Copy( + iState.swingHighs, + dest.swingHighs, + false // + ); + } + + // + // Swing Lows ... + iCount = ArraySize(iState.swingLows); + if (IsValidSize(iCount)) + { + // + Copy( + iState.swingLows, + dest.swingLows, + false // + ); + } + + // + // Momentum Bars ... + iCount = ArraySize(iState.momentumBars); + if (IsValidSize(iCount)) + { + // + Copy( + iState.momentumBars, + dest.momentumBars, + false // + ); + } + + // + // Rejection Bars ... + iCount = ArraySize(iState.rejectionBars); + if (IsValidSize(iCount)) + { + // + Copy( + iState.rejectionBars, + dest.rejectionBars, + false // + ); + } + } +} + /** * Check State has Bullish Trend or not ... * diff --git a/X121SMCEA/Handler/x-saherelm.x121.smc.trade.handler.mq5 b/X121SMCEA/Handler/x-saherelm.x121.smc.trade.handler.mq5 new file mode 100644 index 00000000..8d763b8d --- /dev/null +++ b/X121SMCEA/Handler/x-saherelm.x121.smc.trade.handler.mq5 @@ -0,0 +1 @@ +// Complete this ... \ No newline at end of file diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index 09e60860..3b7b40b3 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -121,6 +121,34 @@ struct X121SMCStrategyConditions Clean(bullishRejectionBars); } + void CleanDemand() + { + // + demandZone.Clean(); + + // + Clean(supports); + Clean(swingLows); + Clean(bullishFVGs); + Clean(bullishOrderBlocks); + Clean(bullishMomentumBars); + Clean(bullishRejectionBars); + } + + void CleanSupply() + { + // + supplyZone.Clean(); + + // + Clean(swingHighs); + Clean(resistances); + Clean(bearishFVGs); + Clean(bearishOrderBlocks); + Clean(bearishMomentumBars); + Clean(bearishRejectionBars); + } + // // Validate ... bool IsValid() @@ -263,6 +291,63 @@ struct X121SMCStrategyConditions // }; +// +// Market Structure Models ... +struct X121SMCMarketStructure +{ + // + XZone demandZone; + XZone supplyZone; + + // + XZone demandZones[]; + XZone supplyZones[]; + + // + XZone bearishOrderBlocks[]; + XZone bearishFVGs[]; + + // + XOHCL swingHighs[]; + XOHCL resistances[]; + XOHCL bearishMomentumBars[]; + XOHCL bearishRejectionBars[]; + + // + XZone bullishOrderBlocks[]; + XZone bullishFVGs[]; + + // + XOHCL supports[]; + XOHCL swingLows[]; + XOHCL bullishMomentumBars[]; + XOHCL bullishRejectionBars[]; + + // + void Clean() + { + // + demandZone.Clean(); + supplyZone.Clean(); + + // + Clean(supports); + Clean(swingLows); + Clean(swingHighs); + Clean(demandZones); + Clean(supplyZones); + Clean(bearishFVGs); + Clean(resistances); + Clean(bullishFVGs); + Clean(bearishOrderBlocks); + Clean(bullishOrderBlocks); + Clean(bearishMomentumBars); + Clean(bearishRejectionBars); + Clean(bullishMomentumBars); + Clean(bullishRejectionBars); + } +}; + // // On Signal Event Handler ... typedef void (*TOnX121SMCSignal)( diff --git a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 index d6d114a3b9af393b4c21dd1e7874595c9784df4c..9b4753c74c7eca14d9f578c4c674a0173229e8e6 100644 GIT binary patch delta 17642 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 delta 4297 zcmcgweQZ-z6yLd9W+|oCy3AVZe3Vg2t)ooPWz42d#5w0|5J5*>>Y^wF@QG6+;4EYs zB4immW+yR-jUthckj5&V24RK?#-Qo=@&jCo9}6+rd=W$vaeD9V+OB-18pj_^-h21l z_kKIS-}#+;w)xc9WqUNe|V<}z%1<{)O$_t|X4>ssgxnmj*HZJF{&~@%*#aR1d33+$1A_^UYGVEDc z(Q&o_Pd-+ML5~4f+s$}VEuroTR*$~MQjFhOMBOK#Lc%%obP%UKX~EEfVp8UV8GRoV zqM^AIL&uz?>X{J}>N@l{6rm|ph@O{>^v%lE%?@oN20-HCD73_hcqjj+3}nNwXdlN=QdSIVB&hw3ms`Z@^c-_+b;GsSF~$+ zBYVH)RlptZ7UJitZJ7Adh}z3u3hTj3?T><!oaTh6Zm?_uLGfzjM=fQ}xdKaK}v>3nWEvJwME-X9f z?O3Qt$<&X7DoJNkog#O{$3b=eQ+d;H{gJ5@Sq&EP6uS=vr3}bt0VnP_?5FtEY!QZz zn1*8)lIKR|>HLkEDdK`TIP|TLf3uFXe0Z4rW~e01!m21S0V*+mW+`9SQ}|j4QhOb% zApb;Y;E!rL9bh5N#SG+cg<|S!gL3(K(_bEnOlJ*JrWEL7IxM^2Dwh(66dXF>#*Ifx zbAgM&UNeskTsgS-+x;@Lm_%xW={cu%NuG$kBB`wvwdSX#uQMlxj~Ou~2dO~y239V3 zrW0G>4w3cFjbJC=R`7_Mj4-In#!65fbW_m9)uHwo<*rrRU=nWbyDdBCq}&ePOKF6H zpTOrLVirXVz%A$oPI>r;N=zw1fXo)crthsn2sF4Q2`gueSlVTxb=$x;8W_{;C*g7S z|3ebF4rmmTSWDgGST#k8SoKH?kPbKGV{Td6tNJI<%A0uC>E?wt_)~d?ZQSv5wX^}M z84r?aT-87SJd%U+s z>o3j;vEUuo_4}_7;*=87VDm+J=bYYT@D)g}bb^_r^zzh~)icLPX^4hYA!{0(a2>= zQ19WCw@qP{(&|4Qx(7{vKc1%FO(*w25jA>*E?lhOg3gYg4oxB>z{S)+2>^Z|&s`3Q zDa=9Yo&0=w=^n3+FGynQo6n6&nEh8nJU&;<((w-r*+v<2N)VU@SK9r*OR@0$QB83V zwcD77jAJ>4d>XQ29?g^{$`{CtyqgIP`{zYKse6JUVJ^h^LIWW8h6VCEgcCk?o)DfJ58 z65ViH3Q;nz%06obnkhB?B>zBfk7>l3n1w2bH(Pk1Gj*Nv%*BsS;gF>PhI!CrjGg-# zwi{#N-{IgxF`t(;Gt$PhH5BsmS@h(a$$>BywzI7e