diff --git a/Classes/x-saherelm.x-poi.drawer.class.mq5 b/Classes/x-saherelm.x-poi.drawer.class.mq5 index e15e5dbf..b3b47860 100644 --- a/Classes/x-saherelm.x-poi.drawer.class.mq5 +++ b/Classes/x-saherelm.x-poi.drawer.class.mq5 @@ -3328,6 +3328,254 @@ class XCPOIDrawer : public XCBase return result; } + int DrawStateZones( + XStateZones &source, + XCBaseObject *&drawnObjects[] // + ) + { + // + int result = 0; + + // + Clean(drawnObjects); + + // + if (!source.IsValid()) + { + return result; + } + + // + // SupportZones ... + int count = source.CountSupportZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iZone = source.supportZones[i]; + XCSupportZoneObject *iObj; + + // + bool isCreated = CreateSupportZone( + iZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + // ResistanceZones ... + count = source.CountResistanceZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iZone = source.resistanceZones[i]; + XCResistanceZoneObject *iObj; + + // + bool isCreated = CreateResistanceZone( + iZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + // SupplyZones ... + count = source.CountSupplyZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *iZone = source.supplyZones[i]; + XCSupplyZoneObject *iObj; + + // + bool isCreated = CreateSupplyZone( + iZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + // DemandZones ... + count = source.CountDemandZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone *iZone = source.demandZones[i]; + XCDemandZoneObject *iObj; + + // + bool isCreated = CreateDemandZone( + iZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + // BullishOrderBlocks ... + count = source.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = source.bullishOrderBlocks[i]; + XCBullishOrderBlockObject *iObj; + + // + bool isCreated = CreateBullishOrderBlock( + iZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + // BearishOrderBlocks ... + count = source.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = source.bearishOrderBlocks[i]; + XCBearishOrderBlockObject *iObj; + + // + bool isCreated = CreateBearishOrderBlock( + iZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + // BullishFairValueGaps ... + count = source.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = source.bullishFairValueGaps[i]; + XCBullishFairValueGapObject *iObj; + + // + bool isCreated = CreateBullishFairValueGap( + iZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + // BearishFairValueGaps ... + count = source.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = source.bearishFairValueGaps[i]; + XCBearishFairValueGapObject *iObj; + + // + bool isCreated = CreateBearishFairValueGap( + iZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + result = ArraySize(drawnObjects); + + // + return result; + } + /** * Draw Specified Market Structure ... * @@ -4223,6 +4471,143 @@ class XCPOIDrawer : public XCBase return result; } + /** + * Draw Specified XFVGOrderBlock Object ... + * + * @param models: XFVGOrderBlock instance Reference ... + * + * @return ( int ) + */ + int DrawFVGOrderBlock( + XFVGOrderBlock &models[], + XCBaseObject *&drawnObjects[] // + ) + { + // + int result = 0; + + // + Clean(drawnObjects); + + // + int count = ArraySize(models); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XFVGOrderBlock iModel = models[i]; + + // + ENUM_X_DIRECTION iDir; + bool hasDirection = iModel.GetDirection(iDir); + if (!hasDirection) + { + continue; + } + + // + bool isBullish = IsBullish(iDir); + + // + if (isBullish) + { + // + // Order Block ... + XCBullishOrderBlockObject *iOBObj; + bool isCreated = CreateBullishOrderBlock( + iModel.orderBlock, + iOBObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iOBObj, + drawnObjects // + ); + } + + // + // FVG ... + XCBullishFairValueGapObject *iFVGObj; + isCreated = CreateBullishFairValueGap( + iModel.fairValueGap, + iFVGObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iOBObj, + drawnObjects // + ); + } + } + else + { + // + // Order Block ... + XCBearishOrderBlockObject *iOBObj; + bool isCreated = CreateBearishOrderBlock( + iModel.orderBlock, + iOBObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iOBObj, + drawnObjects // + ); + } + + // + // FVG ... + XCBearishFairValueGapObject *iFVGObj; + isCreated = CreateBearishFairValueGap( + iModel.fairValueGap, + iFVGObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iFVGObj, + drawnObjects // + ); + } + } + + // + // Price Zone ... + // XCBaseObject *stateZoneObjects[]; + // int stateZoneObjectsCount = DrawStateZones( + // iModel.stateZones, + // stateZoneObjects // + // ); + // if (IsValidSize(stateZoneObjectsCount)) + // { + // // + // Copy( + // stateZoneObjects, + // drawnObjects, + // false // Force Clean ... + // ); + // } + } + + // + result = ArraySize(drawnObjects); + + // + return result; + } + // protected: // diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index e1d05531..c40cf0ad 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -6124,12 +6124,231 @@ struct XMarketStructure // }; +struct XStateZones +{ + // + XCSupportZone *supportZones[]; // Holds Founded Support Zones ... + XCResistanceZone *resistanceZones[]; // Holds Founded Resistance Zones ... + XCSupplyZone *supplyZones[]; // Holds Founded Supply Zones ... + XCDemandZone *demandZones[]; // Holds Founded Demand Zones ... + XCOrderBlock *bullishOrderBlocks[]; // Holds Founded Bullish Order Blocks ... + XCOrderBlock *bearishOrderBlocks[]; // Holds Founded Bearish Order Blocks ... + XCFVG *bullishFairValueGaps[]; // Holds Founded Bullish Fair Value Gaps ... + XCFVG *bearishFairValueGaps[]; // Holds Founded Bearish Fair Value Gaps ... + + // + XStateZones() + { + Clean(); + } + + /** + * Cleaning Model ... + */ + void Clean() + { + // + Clean(supportZones); + Clean(resistanceZones); + Clean(supplyZones); + Clean(demandZones); + Clean(bullishOrderBlocks); + Clean(bearishOrderBlocks); + Clean(bullishFairValueGaps); + Clean(bearishFairValueGaps); + } + + /** + * Validate Model ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValidSize(CountSupportZones()) || + IsValidSize(CountResistanceZones()) || + IsValidSize(CountSupplyZones()) || + IsValidSize(CountDemandZones()) || + IsValidSize(CountBullishOrderBlocks()) || + IsValidSize(CountBearishOrderBlocks()) || + IsValidSize(CountBullishFairValueGaps()) || + IsValidSize(CountBearishFairValueGaps()) + // + ; + + // + return result; + } + + // + // Tools ... + + // + int CountSupportZones() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(supportZones); + + // + return result; + } + + // + int CountResistanceZones() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(resistanceZones); + + // + return result; + } + + // + int CountSupplyZones() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(supplyZones); + + // + return result; + } + + // + int CountDemandZones() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(demandZones); + + // + return result; + } + + // + int CountBullishOrderBlocks() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(bullishOrderBlocks); + + // + return result; + } + + // + int CountBearishOrderBlocks() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(bearishOrderBlocks); + + // + return result; + } + + // + int CountBullishFairValueGaps() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(bullishFairValueGaps); + + // + return result; + } + + // + int CountBearishFairValueGaps() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(bearishFairValueGaps); + + // + return result; + } +}; + struct XFVGOrderBlock { // // Props ... XCOrderBlock *orderBlock; XCFVG *fairValueGap; + // XStateZones stateZones; // XFVGOrderBlock() @@ -6149,7 +6368,7 @@ struct XFVGOrderBlock /** * Validate Model ... - * + * * @return ( bool ) */ bool IsValid() @@ -6162,6 +6381,7 @@ struct XFVGOrderBlock // orderBlock != NULL && fairValueGap != NULL && + // stateZones.IsValid() && ((orderBlock.IsBullish() && fairValueGap.IsBullish()) || ((orderBlock.IsBearish() && @@ -6175,9 +6395,9 @@ struct XFVGOrderBlock /** * Get Model Direction ... - * + * * @param dir: ENUM_X_DIRECTION member ... - * + * * @return ( bool ) */ bool GetDirection( @@ -8172,6 +8392,441 @@ bool CalculatePriceInsideZones( return result; } +bool CalculateStateZones( + XStateZones &zones, + XPOIState &source, + double upper, + double lower, + datetime from // +) +{ + // + bool result = false; + + // + zones.Clean(); + + // + datetime cTime = TimeCurrent(); + + // + result = + // + upper > 0 && + lower > 0 && + upper > lower && + IsValid(from) && + source.IsValid() && + source.HasChild() + // + ; + if (!result) + { + return result; + } + + // + int count = 0; + + // + // Support ... + count = source.CountSupportZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iZone = source.supportZones[i]; + + // + double iUpper = iZone.Upper(); + double iLower = iZone.Lower(); + datetime iFrom = iZone.From(); + + // + bool isAbove = iUpper > upper && + iLower <= upper; + + // + bool isInside = iUpper <= upper && + iLower >= lower; + + // + bool isBelow = iUpper >= lower && + iLower < lower; + + // + bool isValid = + // + iFrom > from && + (isAbove || + isBelow || + isInside) + // + ; + if (isValid) + { + // + iZone.To(cTime); + Add( + iZone, + zones.supportZones // + ); + } + } + } + + // + // Resistance ... + count = source.CountResistanceZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iZone = source.resistanceZones[i]; + + // + double iUpper = iZone.Upper(); + double iLower = iZone.Lower(); + datetime iFrom = iZone.From(); + + // + bool isAbove = iUpper > upper && + iLower <= upper; + + // + bool isInside = iUpper <= upper && + iLower >= lower; + + // + bool isBelow = iUpper >= lower && + iLower < lower; + + // + bool isValid = + // + iFrom > from && + (isAbove || + isBelow || + isInside) + // + ; + if (isValid) + { + // + iZone.To(cTime); + Add( + iZone, + zones.resistanceZones // + ); + } + } + } + + // + // Supply ... + count = source.CountSupplyZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *iZone = source.supplyZones[i]; + + // + double iUpper = iZone.Upper(); + double iLower = iZone.Lower(); + datetime iFrom = iZone.From(); + + // + bool isAbove = iUpper > upper && + iLower <= upper; + + // + bool isInside = iUpper <= upper && + iLower >= lower; + + // + bool isBelow = iUpper >= lower && + iLower < lower; + + // + bool isValid = + // + iFrom > from && + (isAbove || + isBelow || + isInside) + // + ; + if (isValid) + { + // + iZone.To(cTime); + Add( + iZone, + zones.supplyZones // + ); + } + } + } + + // + // Demand ... + count = source.CountDemandZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone *iZone = source.demandZones[i]; + + // + double iUpper = iZone.Upper(); + double iLower = iZone.Lower(); + datetime iFrom = iZone.From(); + + // + bool isAbove = iUpper > upper && + iLower <= upper; + + // + bool isInside = iUpper <= upper && + iLower >= lower; + + // + bool isBelow = iUpper >= lower && + iLower < lower; + + // + bool isValid = + // + iFrom > from && + (isAbove || + isBelow || + isInside) + // + ; + if (isValid) + { + // + iZone.To(cTime); + Add( + iZone, + zones.demandZones // + ); + } + } + } + + // + // Bullish OrderBlocks ... + count = source.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = source.bullishOrderBlocks[i]; + + // + double iUpper = iZone.Upper(); + double iLower = iZone.Lower(); + datetime iFrom = iZone.From(); + + // + bool isAbove = iUpper > upper && + iLower <= upper; + + // + bool isInside = iUpper <= upper && + iLower >= lower; + + // + bool isBelow = iUpper >= lower && + iLower < lower; + + // + bool isValid = + // + iFrom > from && + (isAbove || + isBelow || + isInside) + // + ; + if (isValid) + { + // + iZone.To(cTime); + Add( + iZone, + zones.bullishOrderBlocks // + ); + } + } + } + + // + // Bearish OrderBlocks ... + count = source.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = source.bearishOrderBlocks[i]; + + // + double iUpper = iZone.Upper(); + double iLower = iZone.Lower(); + datetime iFrom = iZone.From(); + + // + bool isAbove = iUpper > upper && + iLower <= upper; + + // + bool isInside = iUpper <= upper && + iLower >= lower; + + // + bool isBelow = iUpper >= lower && + iLower < lower; + + // + bool isValid = + // + iFrom > from && + (isAbove || + isBelow || + isInside) + // + ; + if (isValid) + { + // + iZone.To(cTime); + Add( + iZone, + zones.bearishOrderBlocks // + ); + } + } + } + + // + // Bullish FairValueGaps ... + count = source.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = source.bullishFairValueGaps[i]; + + // + double iUpper = iZone.Upper(); + double iLower = iZone.Lower(); + datetime iFrom = iZone.From(); + + // + bool isAbove = iUpper > upper && + iLower <= upper; + + // + bool isInside = iUpper <= upper && + iLower >= lower; + + // + bool isBelow = iUpper >= lower && + iLower < lower; + + // + bool isValid = + // + iFrom > from && + (isAbove || + isBelow || + isInside) + // + ; + if (isValid) + { + // + iZone.To(cTime); + Add( + iZone, + zones.bullishFairValueGaps // + ); + } + } + } + + // + // Bearish FairValueGaps ... + count = source.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = source.bearishFairValueGaps[i]; + + // + double iUpper = iZone.Upper(); + double iLower = iZone.Lower(); + datetime iFrom = iZone.From(); + + // + bool isAbove = iUpper > upper && + iLower <= upper; + + // + bool isInside = iUpper <= upper && + iLower >= lower; + + // + bool isBelow = iUpper >= lower && + iLower < lower; + + // + bool isValid = + // + iFrom > from && + (isAbove || + isBelow || + isInside) + // + ; + if (isValid) + { + // + iZone.To(cTime); + Add( + iZone, + zones.bearishFairValueGaps // + ); + } + } + } + + // + result = zones.IsValid(); + + // + return result; +} + /** * Add Value Change instance to Exists Collection if it's not Exists ... * diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index 793edd0a..1d281d6a 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -719,13 +719,12 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value) // bool TestPOIState( - XCPOIDrawer *drawer, ENUM_X_DIRECTION &forDir, // Test For Specified Direction ... XFVGOrderBlock &bullishOrderBlocks[], // Bullish Order Blocks ... XFVGOrderBlock &bearishOrderBlocks[], // Bearish Order Blocks ... XPOIState &orderBlockState, // Order Block Detection TF POI(s) ... XPOIState &fairValueGapState, // Fair Value Gap Detection TF POI(s) ... - XPOIState &triggerState, // Trigger TF POI(s) ... + XPOIState &decisionState, // Decision TF POI(s) ... int barIndex = 0 // Bar Index ... ) { @@ -744,10 +743,9 @@ bool TestPOIState( // // Validate Args ... result = - drawer != NULL && orderBlockState.HasChild() && fairValueGapState.HasChild() && - triggerState.HasChild(); + decisionState.HasChild(); if (!result) { return result; @@ -771,6 +769,20 @@ bool TestPOIState( int count = 0; datetime cTime = TimeCurrent(); + // + XOHCL jBar; + result = jBar.Init( + fairValueGapState.symbol, + fairValueGapState.period, + barIndex // + ); + if (!result) + { + return result; + } + double jBarLL = jBar.FindLowest(3, MODE_LOW); + double jBarHH = jBar.FindHighest(3, MODE_HIGH); + // // Bullish ... int bullishOrderBlocksCount = orderBlockState.CountBullishOrderBlocks(); @@ -782,6 +794,7 @@ bool TestPOIState( { // XCFVG *iFVG = NULL; + XStateZones iStateZones; XCOrderBlock *iOb = orderBlockState.bullishOrderBlocks[i]; iOb.To(cTime); @@ -829,13 +842,14 @@ bool TestPOIState( // bool isValid = // - jFVG.IsBullish() - // && - // jFVG.From() > iOb.From() && - // ((jFVG.Upper() > iOb.Upper() && - // jFVG.Lower() <= iOb.Upper()) || - // (jFVG.Upper() <= iOb.Upper() && - // jFVG.Lower() >= iOb.Lower())) + jFVG.IsBullish() && + jBarLL > jFVG.Upper() && + jBar.low > jFVG.Upper() && + jFVG.From() >= iOb.From() && + ((jFVG.Upper() > iOb.Upper() && + jFVG.Lower() <= iOb.Upper()) || + (jFVG.Upper() <= iOb.Upper() && + jFVG.Lower() >= iOb.Lower())) // ; if (isValid) @@ -852,40 +866,41 @@ bool TestPOIState( result = hasFVG; if (!result) { - return result; + continue; } + // // + // double upper = MathMax(iOb.Upper(), iFVG.Upper()); + // double lower = MathMin(iOb.Lower(), iFVG.Lower()); + // datetime from = iFVG.From(); + + // // + // // Detect Price Zones ... + // // Based On Decision State ... + // bool hasStateZones = CalculateStateZones( + // iStateZones, + // decisionState, + // upper, + // lower, + // from // + // ); + // result = hasStateZones; + // if (!result) + // { + // continue; + // } + // XFVGOrderBlock iModel; iModel.orderBlock = iOb; iModel.fairValueGap = iFVG; + // iModel.stateZones = iStateZones; // AddRef( iModel, bullishOrderBlocks // ); - - // - XCBullishOrderBlockObject *iOBObject; - bool isInited = drawer.CreateBullishOrderBlock( - iOb, - iOBObject // - ); - if (isInited) - { - } - - // - XCOHCLObject *iBarObj; - isInited = drawer.CreateBar( - breakerBar, - iBarObj, - cTime // - ); - if (isInited) - { - } } } @@ -900,6 +915,7 @@ bool TestPOIState( { // XCFVG *iFVG = NULL; + XStateZones iStateZones; XCOrderBlock *iOb = orderBlockState.bearishOrderBlocks[i]; iOb.To(cTime); @@ -947,11 +963,14 @@ bool TestPOIState( // bool isValid = // - jFVG.IsBearish() - // && - // jFVG.From() > iOb.From() && - // jFVG.Upper() > iOb.Lower() && - // jFVG.Lower() <= iOb.Lower() + jFVG.IsBearish() && + jBarHH < jFVG.Lower() && + jBar.high < jFVG.Lower() && + jFVG.From() >= iOb.From() && + ((jFVG.Upper() > iOb.Lower() && + jFVG.Lower() <= iOb.Lower()) || + (jFVG.Upper() <= iOb.Upper() && + jFVG.Lower() >= iOb.Lower())) // ; if (isValid) @@ -968,40 +987,41 @@ bool TestPOIState( result = hasFVG; if (!result) { - return result; + continue; } + // + double upper = MathMax(iOb.Upper(), iFVG.Upper()); + double lower = MathMin(iOb.Lower(), iFVG.Lower()); + datetime from = iFVG.From(); + + // // + // // Detect Price Zones ... + // // Based On Decision State ... + // bool hasStateZones = CalculateStateZones( + // iStateZones, + // decisionState, + // upper, + // lower, + // from // + // ); + // result = hasStateZones; + // if (!result) + // { + // continue; + // } + // XFVGOrderBlock iModel; iModel.orderBlock = iOb; iModel.fairValueGap = iFVG; + // iModel.stateZones = iStateZones; // AddRef( iModel, - bullishOrderBlocks // + bearishOrderBlocks // ); - - // - XCBearishOrderBlockObject *iOBObject; - bool isInited = drawer.CreateBearishOrderBlock( - iOb, - iOBObject // - ); - if (isInited) - { - } - - // - XCOHCLObject *iBarObj; - isInited = drawer.CreateBar( - breakerBar, - iBarObj, - cTime // - ); - if (isInited) - { - } } } @@ -1030,7 +1050,6 @@ bool TestPOIState( // bool isBullish = hasBullishOrderBlocks && !hasBearishOrderBlocks; bool isBearish = hasBearishOrderBlocks && !hasBullishOrderBlocks; - bool isAll = hasBullishOrderBlocks && hasBearishOrderBlocks; // forDir = @@ -1038,8 +1057,6 @@ bool TestPOIState( ? X_DIRECTION_BULLISH : isBearish ? X_DIRECTION_BEARISH - : isAll - ? X_DIRECTION_ALL : X_DIRECTION_NONE; // diff --git a/X121SMCEA/Signals/x-121.smc.xtwpv.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xtwpv.signal.lib.mq5 index 6a63b917..80c375c4 100644 --- a/X121SMCEA/Signals/x-121.smc.xtwpv.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xtwpv.signal.lib.mq5 @@ -49,9 +49,8 @@ struct X121SMCStrategyXTWPVSignalConditions datetime triggerTime; // - // ENUM_X_DIRECTION orderBlockDir; - // XCOrderBlock *bullishOrderBlocks[]; - // XCOrderBlock *bearishOrderBlocks[]; + XFVGOrderBlock bullishOrderBlocks[]; + XFVGOrderBlock bearishOrderBlocks[]; // // Constructor ... @@ -168,9 +167,39 @@ struct X121SMCStrategyXTWPVSignalConditions void ExtensionClean() { // - // Clean(bullishOrderBlocks); - // Clean(bearishOrderBlocks); - // orderBlockDir = X_DIRECTION_NONE; + Clean(bullishOrderBlocks); + Clean(bearishOrderBlocks); + } + + /** + * Update Order Blocks Date ... + */ + void UpdateOrderBlocks() { + // + int count = 0; + datetime cTime = TimeCurrent(); + + // + count = ArraySize(bullishOrderBlocks); + if (IsValidSize(count)) { + // + for (int i = 0; i < count; i++) { + // + bullishOrderBlocks[i].orderBlock.To(cTime); + bullishOrderBlocks[i].fairValueGap.To(cTime); + } + } + + // + count = ArraySize(bearishOrderBlocks); + if (IsValidSize(count)) { + // + for (int i = 0; i < count; i++) { + // + bearishOrderBlocks[i].orderBlock.To(cTime); + bearishOrderBlocks[i].fairValueGap.To(cTime); + } + } } // @@ -192,9 +221,7 @@ bool DetectX121SMCXTWPVSiganlSetup( XC121SMCCycleHelper *analyseCycleHelper, XC121SMCCycleHelper *verificationCycleHelper, XC121SMCCycleHelper *consolidationCycleHelper, - XC121SMCCycleHelper *visionCycleHelper, - // - XCPOIDrawer *drawer // + XC121SMCCycleHelper *visionCycleHelper // ) { @@ -393,7 +420,6 @@ bool DetectX121SMCXTWPVSiganlSetup( XFVGOrderBlock bullishOrderBlocks[]; XFVGOrderBlock bearishOrderBlocks[]; bool isTested = TestPOIState( - drawer, forDir, bullishOrderBlocks, bearishOrderBlocks, @@ -402,6 +428,15 @@ bool DetectX121SMCXTWPVSiganlSetup( decisionState // ); + // + isBullish = + isTested && + IsBullish(forDir); + // + isBearish = + isTested && + IsBearish(forDir); + // result = isBullish || isBearish; @@ -410,6 +445,17 @@ bool DetectX121SMCXTWPVSiganlSetup( return result; } + // + conditions.dir = forDir; + Copy( + bullishOrderBlocks, + conditions.bullishOrderBlocks // + ); + Copy( + bearishOrderBlocks, + conditions.bearishOrderBlocks // + ); + // conditions.setupTime = cTime; conditions.dir = @@ -437,7 +483,7 @@ bool DetectX121SMCXTWPVSiganlTrigger( XC121SMCCycleHelper *consolidationCycleHelper, XC121SMCCycleHelper *visionCycleHelper, // - int maxAllowedSetupAge = 60 // + int maxAllowedSetupAge = 0 // // ) { @@ -638,6 +684,91 @@ bool DetectX121SMCXTWPVSiganlTrigger( // // Trigger Conditions ... + // + // Waits For Price to Go Inside FVG ... + XFVGOrderBlock fvgOrderBlock; + bool isPriceInsideOB = false; + bool isPriceInsideFVG = false; + if (isBullish) + { + // + int count = ArraySize(conditions.bullishOrderBlocks); + for (int i = 0; i < count; i++) + { + // + XFVGOrderBlock iModel = conditions.bullishOrderBlocks[i]; + + // + isPriceInsideOB = IsPriceInsideZone( + cBar, + iModel.orderBlock // + ); + + // + isPriceInsideFVG = IsPriceInsideZone( + cBar, + iModel.fairValueGap // + ); + + // + if (isPriceInsideOB && + isPriceInsideFVG) + { + // + fvgOrderBlock = iModel; + break; + } + + // + isPriceInsideOB = false; + isPriceInsideFVG = false; + } + } + else + { + // + int count = ArraySize(conditions.bearishOrderBlocks); + for (int i = 0; i < count; i++) + { + // + XFVGOrderBlock iModel = conditions.bearishOrderBlocks[i]; + + // + isPriceInsideOB = IsPriceInsideZone( + cBar, + iModel.orderBlock // + ); + + // + isPriceInsideFVG = IsPriceInsideZone( + cBar, + iModel.fairValueGap // + ); + + // + if (isPriceInsideOB && + isPriceInsideFVG) + { + // + fvgOrderBlock = iModel; + break; + } + + // + isPriceInsideOB = false; + isPriceInsideFVG = false; + } + } + + // + result = isPriceInsideOB && + isPriceInsideFVG && + fvgOrderBlock.IsValid(); + if (!result) + { + return result; + } + // // Detect Bullish Conditions ... isBullish = @@ -657,13 +788,13 @@ bool DetectX121SMCXTWPVSiganlTrigger( { // // Cleanup Setup Conditions ... - int setupAge = conditions.GetSetupAge(); - if (IsValidSize(setupAge) && - IsValidSize(maxAllowedSetupAge) && - setupAge >= maxAllowedSetupAge) - { - conditions.Clean(); - } + // int setupAge = conditions.GetSetupAge(); + // if (IsValidSize(setupAge) && + // IsValidSize(maxAllowedSetupAge) && + // setupAge >= maxAllowedSetupAge) + // { + // conditions.Clean(); + // } // return result; diff --git a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 index cb3c6212..5ad6d411 100644 --- a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 @@ -518,8 +518,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy mAnalyseCycleHelper, mVerificationCycleHelper, mConsolidationCycleHelper, - mVisionCycleHelper, - mPOIDrawer // + mVisionCycleHelper // ); // @@ -528,18 +527,33 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy } // - // if (mXTWPVConditions.HasPriceZone()) - // { - // // - // XCBaseObject *objects[]; - // mPOIDrawer.DrawPriceZone( - // mXTWPVConditions.priceZone, - // objects // - // ); + if (isSetuped) + { + // + mXTWPVConditions.UpdateOrderBlocks(); - // // - // Print(""); - // } + // + XCBaseObject *bullDrawnObjects[]; + int bullDrawnObjectsCount = mPOIDrawer.DrawFVGOrderBlock( + mXTWPVConditions.bullishOrderBlocks, + bullDrawnObjects // + ); + if (IsValidSize(bullDrawnObjectsCount)) + { + AddObjectsIfNotExists(bullDrawnObjects); + } + + // + XCBaseObject *bearDrawnObjects[]; + int bearDrwanObjectsCount = mPOIDrawer.DrawFVGOrderBlock( + mXTWPVConditions.bearishOrderBlocks, + bearDrawnObjects // + ); + if (IsValidSize(bearDrwanObjectsCount)) + { + AddObjectsIfNotExists(bearDrawnObjects); + } + } // result = isSetuped; @@ -690,20 +704,20 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy x121Inputs.xpvInputs.hcPeriod = hcPeriod; // - x121Inputs.xpvInputs.showSar = false; - x121Inputs.xpvInputs.showPeaks = false; - x121Inputs.xpvInputs.showVales = false; + x121Inputs.xpvInputs.showSar = true; + x121Inputs.xpvInputs.showPeaks = true; + x121Inputs.xpvInputs.showVales = true; // // XATR ... - x121Inputs.xatrInputs.showATRUpper = false; - x121Inputs.xatrInputs.showATRLower = false; + x121Inputs.xatrInputs.showATRUpper = true; + x121Inputs.xatrInputs.showATRLower = true; // // XSTR ... - x121Inputs.xstrInputs.showStr = false; - x121Inputs.xstrInputs.showStrUpper = false; - x121Inputs.xstrInputs.showStrLower = false; + x121Inputs.xstrInputs.showStr = true; + x121Inputs.xstrInputs.showStrUpper = true; + x121Inputs.xstrInputs.showStrLower = true; // // XDON ...