From 7fbb3970e086a4526e05b3a7241a9a1c4a61fde9 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Sat, 15 Feb 2025 12:57:41 +0330 Subject: [PATCH] last ... --- Libraries/x-saherelm.x-poi.lib.mq5 | 44 +- .../Signals/x-121.smc.xwz.signal.class.mq5 | 932 ++++++++++++++---- .../Signals/x-121.smc.xwz.signal.lib.mq5 | 693 ++++++++++++- 3 files changed, 1453 insertions(+), 216 deletions(-) diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index ce729fdb..2dacb638 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -7037,7 +7037,8 @@ bool IsInside( template bool IsInsideDiff( T *source, - F *dest // + F *dest, + bool forceSideOut = false // ) { // @@ -7068,7 +7069,8 @@ bool IsInsideDiff( // result = IsBoxInside( sourceBox, - destBox // + destBox, + forceSideOut // ); // @@ -7424,12 +7426,14 @@ bool IsBoxAbove( * * @param source: XBoxZone instance Reference ... * @param dest: XBoxZone instance Reference ... + * @param forceSideOut: bool, force check Box has One Side Out ... * * @return ( bool ) */ bool IsBoxInside( XBoxZone &source, - XBoxZone &dest // + XBoxZone &dest, + bool forceSideOut = false // ) { // @@ -7445,8 +7449,30 @@ bool IsBoxInside( } // - result = source.lower >= dest.lower && - source.upper <= dest.upper; + bool isBullish = IsBullish(dest.dir); + + // + if (!forceSideOut) + { + // + result = source.lower >= dest.lower && + source.upper <= dest.upper; + } + else + { + // + bool hasSideIn = + isBullish + ? source.lower >= dest.lower + : source.upper <= dest.upper; + bool hasSideOut = + isBullish + ? source.upper >= dest.upper + : source.lower <= dest.lower; + result = + hasSideIn && + hasSideOut; + } // return result; @@ -7557,8 +7583,8 @@ bool IsBoxUsed( // result = // - box.IsValid() - fromIndex > 0 && + box.IsValid() && + fromIndex > 0 && fromIndex > toIndex // ; @@ -7574,8 +7600,8 @@ bool IsBoxUsed( } // - EUM_X_DIRECT forDir = box.dir; - bool isBllish = IsBullish(forDir); + ENUM_X_DIRECTION forDir = box.dir; + bool isBullish = IsBullish(forDir); // for (int i = fromIndex; i >= toIndex; i--) diff --git a/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 b/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 index 733db5d2..6d681d2d 100644 --- a/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 @@ -336,7 +336,9 @@ class XCX121SMCXWZSignalDetector : public XCBase { // hasWorkingZone = mConditions.ExtractWorkingZone( - visionState // + visionState, + consolidationState, + analyseState // ); } @@ -344,10 +346,13 @@ class XCX121SMCXWZSignalDetector : public XCBase result = hasWorkingZone; if (!result) { + // + mConditions.Clean(); return result; } // + // TODO: Remove ... RemoveWorkingZoneDraws(); DrawWorkingZone( mConditions, @@ -376,215 +381,733 @@ class XCX121SMCXWZSignalDetector : public XCBase } // - // Detect Overal Trend ... - ENUM_X_DIRECTION trend; - bool hasTrend = mConditions.DetectTrend( - trend, - zIndex // - ); - bool hasBullishTrend = - // - hasTrend && - IsBullish(trend) - // - ; - bool hasBearishTrend = - // - hasTrend && - IsBearish(trend) - // - ; - result = hasTrend; - if (!result) - { - return result; - } - - // - // Now We Have to Detect at least One OrderBlock with FVG ... - // for Trend Approvement ... - bool hasOrderBlock = mConditions.HasOrderBlock(); - bool hasFairValueGap = mConditions.HasFairValueGap(); - if (!hasOrderBlock && - !hasFairValueGap) - { - // - int count = 0; - bool has = false; - - // - XCFVG *fvg = NULL; - XCOrderBlock *ob = NULL; - - // - if (hasBullishTrend) - { - // - has = consolidationState.HasBullishOrderBlocks(); - count = consolidationState.CountBullishOrderBlocks(); - - // - if (has) - { - // - // Check Order Block ... - for (int i = 0; i < count; i++) - { - // - XCOrderBlock *iOB = consolidationState.bullishOrderBlocks[i]; - - // - iOB.To(cTime); - - // - // OB Must inside DemandZone ... - bool isInsideDemand = IsInsideDiff( - iOB, - mConditions.demandZone // - ); - if (!isInsideDemand) - { - continue; - } - - // - // Check OB Started ... - XOHCL startedBar; - ENUM_X_DIRECTION startedDir; - bool isStarted = iOB.IsStarted( - X_DIRECTION_BULLISH, - startedBar, - startedDir // - ); - if (!isStarted) - { - // - startedBar.Clean(); - continue; - } - - // - // Converts OB to Box ... - XBoxZone obBox; - bool hasOBBox = ToBox( - obBox, - iOB // - ); - if (!hasOBBox) - { - // - obBox.Clean(); - startedBar.Clean(); - continue; - } - - // - // Check Zone Must not Used before ... - bool isUsed = IsBoxUsed( - obBox, - startedBar.Index() - 1, - zIndex // - ); - if (isUsed) - { - // - obBox.Clean(); - startedBar.Clean(); - continue; - } - - // - ob = iOB; - - // - obBox.Clean(); - startedBar.Clean(); - - // - break; - } - - // - // Detect Fair Value Gap ... - if (ob != NULL && - ob.IsValid()) - { - // - has = analyseState.HasBullishFairValueGaps(); - count = analyseState.CountBullishFairValueGaps(); - if (has) - { - // - } - else - { - // - ob = NULL; - } - } - } - } - else if (hasBearishTrend) - { - // - } - - // - hasOrderBlock = mConditions.HasOrderBlock(); - hasFairValueGap = mConditions.HasFairValueGap(); - } - - // - bool isTrendApproved = hasOrderBlock && - hasFairValueGap; - result = isTrendApproved; - if (!result) - { - return result; - } - - // - // Detect 1H Sup Dem ... - int count = 0; - bool has = false; + Print(""); // // - // // Supply Zones ... - // count = consolidationState.CountSupplyZones(); - // has = consolidationState.HasSupplyZones(); - // if (has) - // { + // // Detect Overal Trend ... + // ENUM_X_DIRECTION trend; + // bool hasTrend = mConditions.DetectTrend( + // trend, + // zIndex // + // ); + // bool hasBullishTrend = // // - // for (int i = 0; i < count; i++) - // { - // // - // XCSupplyZoneObject *iObj; - // bool isCreated = visionCycleHelper - // .mPOIDrawer - // .CreateSupplyZone( - // consolidationState.supplyZones[i], - // iObj // - // ); - // } + // hasTrend && + // IsBullish(trend) + // // + // ; + // bool hasBearishTrend = + // // + // hasTrend && + // IsBearish(trend) + // // + // ; + // result = hasTrend; + // if (!result) + // { + // return result; // } // // - // // Demand Zones ... - // count = consolidationState.CountDemandZones(); - // has = consolidationState.HasDemandZones(); + // // Now We Have to Detect at least One OrderBlock with FVG ... + // // for Trend Approvement ... + // bool hasOrderBlock = mConditions.HasOrderBlock(); + // bool hasFairValueGap = mConditions.HasFairValueGap(); + // if (!hasOrderBlock && + // !hasFairValueGap) + // { + // // + // int count = 0; + // bool has = false; + + // // + // XCFVG *fvg = NULL; + // XCOrderBlock *ob = NULL; + + // // + // if (hasBullishTrend) + // { + // // + // has = consolidationState.HasBullishOrderBlocks(); + // count = consolidationState.CountBullishOrderBlocks(); + + // // + // if (has) + // { + // // + // // Check Order Block ... + // for (int i = 0; i < count; i++) + // { + // // + // XCOrderBlock *iOB = consolidationState.bullishOrderBlocks[i]; + + // // + // iOB.To(cTime); + + // // + // // Check From Passes ... + // bool isFromPassed = iOB.From() > mConditions.demandZone.From(); + // if (!isFromPassed) + // { + // continue; + // } + + // // + // // Must inside DemandZone ... + // bool isInsideDemand = IsInsideDiff( + // iOB, + // mConditions.demandZone // + // ); + // if (!isInsideDemand) + // { + // continue; + // } + + // // + // // Check Started ... + // XOHCL startedBar; + // ENUM_X_DIRECTION startedDir; + // bool isStarted = iOB.IsStarted( + // X_DIRECTION_BULLISH, + // startedBar, + // startedDir // + // ); + // if (!isStarted) + // { + // // + // startedBar.Clean(); + // continue; + // } + + // // + // // Converts to Box ... + // XBoxZone obBox; + // bool hasOBBox = ToBox( + // obBox, + // iOB // + // ); + // if (!hasOBBox) + // { + // // + // obBox.Clean(); + // startedBar.Clean(); + // continue; + // } + + // // + // // Check Zone Must not Used before ... + // bool isUsed = IsBoxUsed( + // obBox, + // startedBar.Index() - 1, + // zIndex // + // ); + // if (isUsed) + // { + // // + // obBox.Clean(); + // startedBar.Clean(); + // continue; + // } + + // // + // ob = iOB; + + // // + // obBox.Clean(); + // startedBar.Clean(); + + // // + // break; + // } + + // // + // // Detect Fair Value Gap ... + // if (ob != NULL && + // ob.IsValid()) + // { + // // + // has = analyseState.HasBullishFairValueGaps(); + // count = analyseState.CountBullishFairValueGaps(); + // if (has) + // { + // // + // // Check Fir Value Gap ... + // for (int i = 0; i < count; i++) + // { + // // + // XCFVG *iFVG = analyseState.bullishFairValueGaps[i]; + + // // + // iFVG.To(cTime); + + // // + // // Check From Passes ... + // bool isFromPassed = iFVG.From() > ob.From(); + // if (!isFromPassed) + // { + // continue; + // } + + // // + // // Check Started ... + // XOHCL startedBar; + // ENUM_X_DIRECTION startedDir; + // bool isStarted = iFVG.IsStarted( + // X_DIRECTION_BULLISH, + // startedBar, + // startedDir // + // ); + // if (!isStarted) + // { + // // + // startedBar.Clean(); + // continue; + // } + + // // + // // Converts to Box ... + // XBoxZone fvgBox; + // bool hasFVGBox = ToBox( + // fvgBox, + // iFVG // + // ); + // if (!hasFVGBox) + // { + // // + // fvgBox.Clean(); + // startedBar.Clean(); + // continue; + // } + + // // + // // Check Inside Order Block ... + // bool isInside = IsInsideDiff( + // iFVG, + // ob, + // true // Force Side Out ... + // ); + // if (!isInside) + // { + // continue; + // } + + // // + // fvg = iFVG; + + // // + // fvgBox.Clean(); + // startedBar.Clean(); + + // // + // break; + // } + // } + // else + // { + // // + // ob = NULL; + // } + // } + // } + // } + // else if (hasBearishTrend) + // { + // // + // has = consolidationState.HasBearishOrderBlocks(); + // count = consolidationState.CountBearishOrderBlocks(); + + // // + // if (has) + // { + // // + // // Check Order Block ... + // for (int i = 0; i < count; i++) + // { + // // + // XCOrderBlock *iOB = consolidationState.bearishOrderBlocks[i]; + + // // + // iOB.To(cTime); + + // // + // // Check From Passes ... + // bool isFromPassed = iOB.From() > mConditions.supplyZone.From(); + // if (!isFromPassed) + // { + // continue; + // } + + // // + // // Must inside DemandZone ... + // bool isInsideDemand = IsInsideDiff( + // iOB, + // mConditions.supplyZone // + // ); + // if (!isInsideDemand) + // { + // continue; + // } + + // // + // // Check Started ... + // XOHCL startedBar; + // ENUM_X_DIRECTION startedDir; + // bool isStarted = iOB.IsStarted( + // X_DIRECTION_BEARISH, + // startedBar, + // startedDir // + // ); + // if (!isStarted) + // { + // // + // startedBar.Clean(); + // continue; + // } + + // // + // // Converts to Box ... + // XBoxZone obBox; + // bool hasOBBox = ToBox( + // obBox, + // iOB // + // ); + // if (!hasOBBox) + // { + // // + // obBox.Clean(); + // startedBar.Clean(); + // continue; + // } + + // // + // // Check Zone Must not Used before ... + // bool isUsed = IsBoxUsed( + // obBox, + // startedBar.Index() - 1, + // zIndex // + // ); + // if (isUsed) + // { + // // + // obBox.Clean(); + // startedBar.Clean(); + // continue; + // } + + // // + // ob = iOB; + + // // + // obBox.Clean(); + // startedBar.Clean(); + + // // + // break; + // } + + // // + // // Detect Fair Value Gap ... + // if (ob != NULL && + // ob.IsValid()) + // { + // // + // has = analyseState.HasBearishFairValueGaps(); + // count = analyseState.CountBearishFairValueGaps(); + // if (has) + // { + // // + // // Check Fir Value Gap ... + // for (int i = 0; i < count; i++) + // { + // // + // XCFVG *iFVG = analyseState.bearishFairValueGaps[i]; + + // // + // iFVG.To(cTime); + + // // + // // Check From Passes ... + // bool isFromPassed = iFVG.From() > ob.From(); + // if (!isFromPassed) + // { + // continue; + // } + + // // + // // Check Started ... + // XOHCL startedBar; + // ENUM_X_DIRECTION startedDir; + // bool isStarted = iFVG.IsStarted( + // X_DIRECTION_BEARISH, + // startedBar, + // startedDir // + // ); + // if (!isStarted) + // { + // // + // startedBar.Clean(); + // continue; + // } + + // // + // // Converts to Box ... + // XBoxZone fvgBox; + // bool hasFVGBox = ToBox( + // fvgBox, + // iFVG // + // ); + // if (!hasFVGBox) + // { + // // + // fvgBox.Clean(); + // startedBar.Clean(); + // continue; + // } + + // // + // // Check Inside Order Block ... + // bool isInside = IsInsideDiff( + // iFVG, + // ob, + // true // Force Side Out ... + // ); + // if (!isInside) + // { + // continue; + // } + + // // + // fvg = iFVG; + + // // + // fvgBox.Clean(); + // startedBar.Clean(); + + // // + // break; + // } + // } + // else + // { + // // + // ob = NULL; + // } + // } + // } + // } + + // // + // if (ob != NULL && + // fvg != NULL) + // { + // // + // mConditions.orderBlock = ob; + // mConditions.fairValueGap = fvg; + // } + + // // + // hasOrderBlock = mConditions.HasOrderBlock(); + // hasFairValueGap = mConditions.HasFairValueGap(); + // } + + // // + // bool isTrendApproved = hasOrderBlock && + // hasFairValueGap; + // result = isTrendApproved; + // if (!result) + // { + // return result; + // } + + // // + // mConditions.UpdateTo(cTime); + + // // + // // TODO: Remove ... + // RemoveDraws(); + // DrawConditions( + // mConditions, + // visionCycleHelper.mPOIDrawer // + // ); + + // // + // // Now We have to Detect Start Zones ... + // int count = 0; + // bool has = false; + + // + + // // + // XBoxZone targetBoxes[]; + // if (hasBullishTrend) + // { + // // + // // + // } + // else if (hasBearishTrend) + // { + // // + // // Demand Zones ... + // has = consolidationState.HasDemandZones(); + // count = consolidationState.CountDemandZones(); + // XBoxZone demandBox; + + // // + // if (has) + // { + // // + // XCDemandZone *demands[]; + // for (int i = 0; i < count; i++) + // { + // // + // XCDemandZone *iZone = consolidationState.demandZones[i]; + + // // + // iZone.To(cTime); + + // // + // // Check Price ... + // bool isPricePassed = decisionCBar.low > iZone.Upper(); + // if (!isPricePassed) + // { + // continue; + // } + + // // + // XBoxZone iBox; + // bool hasBox = ToBox( + // iBox, + // iZone // + // ); + // if (!hasBox) + // { + // // + // iBox.Clean(); + // continue; + // } + + // // // + // // XCDemandZoneObject *iObj; + // // bool isCreated = visionCycleHelper + // // .mPOIDrawer + // // .CreateDemandZone( + // // iZone, + // // iObj // + // // ); + + // // + // Add( + // iZone, + // demands // + // ); + + // // + // // AddRef( + // // iBox, + // // targetBoxes // + // // ); + + // // + // iBox.Clean(); + // } + + // // + // count = ArraySize(demands); + // has = IsValidSize(count); + // if (has) + // { + // // + // int lowestIDX = GetLowest(demands); + // int highestIDX = GetHighest(demands); + // int youngestIDX = GetYoungest(demands); + // bool hasHighAndLow = + // IsValidIndex(lowestIDX) && + // IsValidIndex(highestIDX) && + // IsValidIndex(youngestIDX); + // if (hasHighAndLow) + // { + // // + // XBoxZone box; + + // // + // box.symbol = demands[highestIDX].GetSymbol(); + // box.period = demands[highestIDX].GetPeriod(); + + // // + // box.to = cTime; + // box.dir = X_DIRECTION_BULLISH; + // box.from = demands[youngestIDX].From(); + // box.type = demands[highestIDX].TypeAsString(); + + // // + // box.upper = demands[highestIDX].Upper(); + // box.lower = demands[lowestIDX].Lower(); + + // // + // bool isValid = box.IsValid(); + // if (isValid) + // { + // // // + // // XCBoxObject *iBoxObj; + // // bool isCreated = visionCycleHelper + // // .mPOIDrawer + // // .CreateBox( + // // box, + // // iBoxObj // + // // ); + + // // // + // // if (isCreated) + // // { + // // // + // // color boxColor = + // // IsBullish(box.dir) + // // ? clrAqua + // // : clrMagenta; + + // // // + // // ENUM_LINE_STYLE boxStyle = STYLE_DOT; + + // // // + // // iBoxObj.BoxColor(boxColor); + // // iBoxObj.BoxStyle(boxStyle); + + // // // + // // Print("BOX ..."); + + // // } + + // // + // demandBox = box; + // } + + // // + // box.Clean(); + // } + // } + // } + + // // + // // Bullish Order Blocks ... + // // has = consolidationState.HasBullishOrderBlocks(); + // // count = consolidationState.CountBullishOrderBlocks(); + + // // + // // if (has) + // // { + // // // + // // for (int i = 0; i < count; i++) + // // { + // // // + // // XCOrderBlock *iZone = consolidationState.bullishOrderBlocks[i]; + + // // // + // // iZone.To(cTime); + + // // // + // // // Check Price ... + // // bool isPricePassed = decisionCBar.low > iZone.Upper(); + // // if (!isPricePassed) + // // { + // // continue; + // // } + + // // // + // // XBoxZone iBox; + // // bool hasBox = ToBox( + // // iBox, + // // iZone // + // // ); + // // if (!hasBox) + // // { + // // // + // // iBox.Clean(); + // // continue; + // // } + + // // // + // // AddRef( + // // iBox, + // // targetBoxes // + // // ); + + // // // + // // iBox.Clean(); + // // } + // // } + + // // + // // Bullish Fair Value Gaps ... + // // has = consolidationState.HasBullishFairValueGaps(); + // // count = consolidationState.CountBullishFairValueGaps(); + + // // + // // if (has) + // // { + // // // + // // for (int i = 0; i < count; i++) + // // { + // // // + // // XCFVG *iZone = consolidationState.bullishFairValueGaps[i]; + + // // // + // // iZone.To(cTime); + + // // // + // // // Check Price ... + // // bool isPricePassed = decisionCBar.low > iZone.Upper(); + // // if (!isPricePassed) + // // { + // // continue; + // // } + + // // // + // // XBoxZone iBox; + // // bool hasBox = ToBox( + // // iBox, + // // iZone // + // // ); + // // if (!hasBox) + // // { + // // // + // // iBox.Clean(); + // // continue; + // // } + + // // // + // // AddRef( + // // iBox, + // // targetBoxes // + // // ); + + // // // + // // iBox.Clean(); + // // } + // // } + // } + + // // + // count = ArraySize(targetBoxes); + // has = IsValidSize(count); // if (has) // { // // // for (int i = 0; i < count; i++) // { // // - // XCDemandZoneObject *iObj; + // XBoxZone iBox = targetBoxes[i]; + + // // + // XCBoxObject *iBoxObj; // bool isCreated = visionCycleHelper // .mPOIDrawer - // .CreateDemandZone( - // consolidationState.demandZones[i], - // iObj // + // .CreateBox( + // iBox, + // iBoxObj // // ); + + // // + // iBox.Clean(); // } // } @@ -1867,6 +2390,25 @@ class XCX121SMCXWZSignalDetector : public XCBase // bool isCreated = false; + + // + // Check For Trend Approced ... + bool isTrendApproved = conditions.HasOrderBlock() && + conditions.HasFairValueGap(); + if (isTrendApproved) + { + // + DrawOrderBlock( + conditions.orderBlock, + drawer // + ); + + // + DrawFairValueGap( + conditions.fairValueGap, + drawer // + ); + } // XCSupplyZoneObject *iSupObj; diff --git a/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 index ab131365..92f526e2 100644 --- a/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 @@ -36,6 +36,45 @@ enum ENUM_X121SMC_XWZ_PRIORITY X121SMC_XWZ_PRIORITY_HIGH, }; +// +struct X121SMCXWZOBFVG +{ + // + // Props ... + XCOrderBlock *ob; + XCFVG *fvg; + + // + // Constructor ... + X121SMCXWZOBFVG() + { + Clean(); + } + + // + // Tools ... + + // + void Clean() + { + // + ZeroMemory(ob); + ZeroMemory(fvg); + } + + // + bool IsValid() + { + // + return ob != NULL && + fvg != NULL && + ob.IsValid() && + fvg.IsValid(); + } + + // +}; + // struct X121SMCXWZWorkingZone { @@ -362,6 +401,9 @@ struct X121SMCStrategyXWZSignalConditions XCDemandZone *demandZone; X121SMCXWZWorkingZone workingZone; + // + X121SMCXWZOBFVG startZones[]; + // // Constructor ... X121SMCStrategyXWZSignalConditions() @@ -489,13 +531,20 @@ struct X121SMCStrategyXWZSignalConditions amountPercent = 0; // - delete supplyZone; ZeroMemory(supplyZone); // - delete demandZone; ZeroMemory(demandZone); + // + ZeroMemory(orderBlock); + + // + ZeroMemory(fairValueGap); + + // + Clean(startZones); + // workingZone.Clean(); } @@ -514,12 +563,22 @@ struct X121SMCStrategyXWZSignalConditions // Working Zone is an Area which // we decide to trade inside it ... bool ExtractWorkingZone( - XPOIState &state // + XPOIState &htfState, + XPOIState &mtfState, + XPOIState &stfState, + int barIndex = 0 // ) { // bool result = false; + // + if (barIndex < 0) + { + barIndex = 0; + } + int zIndex = barIndex; + // result = !HasWorkingZone(); if (!result) @@ -528,10 +587,39 @@ struct X121SMCStrategyXWZSignalConditions } // - result = state.IsValid() && - state.HasChild() && - state.HasSupplyZones() && - state.HasDemandZones(); + result = IsValid(symbol) && + IsValid(period); + if (!result) + { + // + Clean(); + return result; + } + + // + datetime cTime = iTime( + symbol, + period, + zIndex // + ); + + // + result = + // + htfState.IsValid() && + htfState.HasChild() && + htfState.HasSupplyZones() && + htfState.HasDemandZones() && + // + mtfState.IsValid() && + mtfState.HasChild() && + mtfState.HasSupplyZones() && + mtfState.HasDemandZones() && + // + stfState.IsValid() && + stfState.HasChild() + // + ; if (!result) { return result; @@ -539,8 +627,8 @@ struct X121SMCStrategyXWZSignalConditions // // Retrieve Highest Supply Zone ... - int hSupplyIDX = GetHighest(state.supplyZones); - int lDemandIDX = GetLowest(state.demandZones); + int hSupplyIDX = GetHighest(htfState.supplyZones); + int lDemandIDX = GetLowest(htfState.demandZones); // result = @@ -555,8 +643,8 @@ struct X121SMCStrategyXWZSignalConditions } // - supplyZone = state.supplyZones[hSupplyIDX]; - demandZone = state.demandZones[lDemandIDX]; + supplyZone = htfState.supplyZones[hSupplyIDX]; + demandZone = htfState.demandZones[lDemandIDX]; // result = @@ -575,6 +663,587 @@ struct X121SMCStrategyXWZSignalConditions } // + // Check Validation of Supply and Demand Zones ... + lDemandIDX = GetLowest(mtfState.demandZones); + hSupplyIDX = GetHighest(mtfState.supplyZones); + result = IsValidIndex(lDemandIDX) && + IsValidIndex(hSupplyIDX); + if (!result) + { + // + Clean(); + return result; + } + + // + // Validate Supply and Demand ... + bool isMTFHSupplyInside = + IsInside( + mtfState.supplyZones[hSupplyIDX], + supplyZone); + bool isMTFLDemandInside = + IsInside( + mtfState.demandZones[lDemandIDX], + demandZone // + ); + if (isMTFHSupplyInside && + !isMTFLDemandInside) + { + demandZone = mtfState.demandZones[lDemandIDX]; + } + else if (!isMTFHSupplyInside && + isMTFLDemandInside) + { + supplyZone = mtfState.supplyZones[hSupplyIDX]; + } + else if (isMTFHSupplyInside && + isMTFLDemandInside) + { + // + supplyZone = mtfState.supplyZones[hSupplyIDX]; + demandZone = mtfState.demandZones[lDemandIDX]; + } + + // + // Check Zones Validation ... + bool hasTrend = + supplyZone != NULL && + supplyZone.IsValid() && + demandZone != NULL && + demandZone.IsValid(); + result = hasTrend; + if (!result) + { + // + Clean(); + return result; + } + + // + datetime from = MathMax( + supplyZone.From(), + demandZone.From()); + + // + int fromIndex = iBarShift( + symbol, + period, + from // + ); + + // + // Detect Trend ... + ENUM_X_DIRECTION trend = X_DIRECTION_NONE; + datetime supplyTouch = NULL; + datetime demandTouch = NULL; + for (int i = zIndex; i < fromIndex; i++) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + symbol, + period, + i // + ); + if (!isInited) + { + continue; + } + + // + bool isTouchSupplyZone = + // + iBar.low < supplyZone.Lower() && + iBar.GetUp() > supplyZone.Lower() + // + ; + if (isTouchSupplyZone && + !IsValid(supplyTouch)) + { + supplyTouch = iBar.time; + } + + // + bool isTouchDemandZone = + // + iBar.high > demandZone.Upper() && + iBar.GetDown() < demandZone.Upper() + // + ; + if (isTouchDemandZone && + !IsValid(demandTouch)) + { + demandTouch = iBar.time; + } + + // + bool canBreak = + IsValid(supplyTouch) && + IsValid(demandTouch); + + // + iBar.Clean(); + + // + if (canBreak) + { + break; + } + } + + // + hasTrend = + // + IsValid(supplyTouch) && + IsValid(demandTouch) + // + ; + if (hasTrend) + { + // + trend = + // + supplyTouch > demandTouch + ? X_DIRECTION_BEARISH + : X_DIRECTION_BULLISH + // + ; + } + + // + // Check Trend ... + result = hasTrend; + if (!result) + { + // + Clean(); + return result; + } + + // + bool hasBullishTrend = IsBullish(trend); + bool hasBearishTrend = IsBearish(trend); + + // + // Find Order Block and FVG for Trend Approve ... + + // + // Now We Have to Detect at least One OrderBlock with FVG ... + // for Trend Approvement ... + bool hasOrderBlock = HasOrderBlock(); + bool hasFairValueGap = HasFairValueGap(); + if (!hasOrderBlock && + !hasFairValueGap) + { + // + int count = 0; + bool has = false; + + // + XCFVG *fvg = NULL; + XCOrderBlock *ob = NULL; + + // + if (hasBullishTrend) + { + // + has = mtfState.HasBullishOrderBlocks(); + count = mtfState.CountBullishOrderBlocks(); + + // + if (has) + { + // + // Check Order Block ... + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = mtfState.bullishOrderBlocks[i]; + + // + iOB.To(cTime); + + // + // Check From Passes ... + bool isFromPassed = iOB.From() > demandZone.From(); + if (!isFromPassed) + { + continue; + } + + // + // Must inside DemandZone ... + bool isInsideDemand = IsInsideDiff( + iOB, + demandZone // + ); + if (!isInsideDemand) + { + continue; + } + + // + // Check Started ... + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iOB.IsStarted( + X_DIRECTION_BULLISH, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + startedBar.Clean(); + continue; + } + + // + // Converts to Box ... + XBoxZone obBox; + bool hasOBBox = ToBox( + obBox, + iOB // + ); + if (!hasOBBox) + { + // + obBox.Clean(); + startedBar.Clean(); + continue; + } + + // + // Check Zone Must not Used before ... + bool isUsed = IsBoxUsed( + obBox, + startedBar.Index() - 1, + zIndex // + ); + if (isUsed) + { + // + obBox.Clean(); + startedBar.Clean(); + continue; + } + + // + ob = iOB; + + // + obBox.Clean(); + startedBar.Clean(); + + // + break; + } + + // + // Detect Fair Value Gap ... + if (ob != NULL && + ob.IsValid()) + { + // + has = stfState.HasBullishFairValueGaps(); + count = stfState.CountBullishFairValueGaps(); + if (has) + { + // + // Check Fir Value Gap ... + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = stfState.bullishFairValueGaps[i]; + + // + iFVG.To(cTime); + + // + // Check From Passes ... + bool isFromPassed = iFVG.From() > ob.From(); + if (!isFromPassed) + { + continue; + } + + // + // Check Started ... + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iFVG.IsStarted( + X_DIRECTION_BULLISH, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + startedBar.Clean(); + continue; + } + + // + // Converts to Box ... + XBoxZone fvgBox; + bool hasFVGBox = ToBox( + fvgBox, + iFVG // + ); + if (!hasFVGBox) + { + // + fvgBox.Clean(); + startedBar.Clean(); + continue; + } + + // + // Check Inside Order Block ... + bool isInside = IsInsideDiff( + iFVG, + ob, + true // Force Side Out ... + ); + if (!isInside) + { + continue; + } + + // + fvg = iFVG; + + // + fvgBox.Clean(); + startedBar.Clean(); + + // + break; + } + } + else + { + // + ob = NULL; + } + } + } + } + else if (hasBearishTrend) + { + // + has = mtfState.HasBearishOrderBlocks(); + count = mtfState.CountBearishOrderBlocks(); + + // + if (has) + { + // + // Check Order Block ... + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = mtfState.bearishOrderBlocks[i]; + + // + iOB.To(cTime); + + // + // Check From Passes ... + bool isFromPassed = iOB.From() > supplyZone.From(); + if (!isFromPassed) + { + continue; + } + + // + // Must inside DemandZone ... + bool isInsideDemand = IsInsideDiff( + iOB, + supplyZone // + ); + if (!isInsideDemand) + { + continue; + } + + // + // Check Started ... + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iOB.IsStarted( + X_DIRECTION_BEARISH, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + startedBar.Clean(); + continue; + } + + // + // Converts to Box ... + XBoxZone obBox; + bool hasOBBox = ToBox( + obBox, + iOB // + ); + if (!hasOBBox) + { + // + obBox.Clean(); + startedBar.Clean(); + continue; + } + + // + // Check Zone Must not Used before ... + bool isUsed = IsBoxUsed( + obBox, + startedBar.Index() - 1, + zIndex // + ); + if (isUsed) + { + // + obBox.Clean(); + startedBar.Clean(); + continue; + } + + // + ob = iOB; + + // + obBox.Clean(); + startedBar.Clean(); + + // + break; + } + + // + // Detect Fair Value Gap ... + if (ob != NULL && + ob.IsValid()) + { + // + has = stfState.HasBearishFairValueGaps(); + count = stfState.CountBearishFairValueGaps(); + if (has) + { + // + // Check Fir Value Gap ... + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = stfState.bearishFairValueGaps[i]; + + // + iFVG.To(cTime); + + // + // Check From Passes ... + bool isFromPassed = iFVG.From() > ob.From(); + if (!isFromPassed) + { + continue; + } + + // + // Check Started ... + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iFVG.IsStarted( + X_DIRECTION_BEARISH, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + startedBar.Clean(); + continue; + } + + // + // Converts to Box ... + XBoxZone fvgBox; + bool hasFVGBox = ToBox( + fvgBox, + iFVG // + ); + if (!hasFVGBox) + { + // + fvgBox.Clean(); + startedBar.Clean(); + continue; + } + + // + // Check Inside Order Block ... + bool isInside = IsInsideDiff( + iFVG, + ob, + true // Force Side Out ... + ); + if (!isInside) + { + continue; + } + + // + fvg = iFVG; + + // + fvgBox.Clean(); + startedBar.Clean(); + + // + break; + } + } + else + { + // + ob = NULL; + } + } + } + } + + // + if (ob != NULL && + fvg != NULL) + { + // + orderBlock = ob; + fairValueGap = fvg; + } + + // + hasOrderBlock = HasOrderBlock(); + hasFairValueGap = HasFairValueGap(); + } + + // + // Check Trend Approved ... + bool isTrendApproved = + hasOrderBlock && + hasFairValueGap; + result = isTrendApproved; + if (!result) + { + // + Clean(); + return result; + } + + // + // Prepare Working Zone ... workingZone.symbol = symbol; workingZone.period = period; @@ -587,7 +1256,7 @@ struct X121SMCStrategyXWZSignalConditions workingZone.zoneLower = demandZone.Lower(); // - workingZone.from = MathMax(supplyZone.From(), demandZone.From()); + workingZone.from = from; // double upper = workingZone.upper;