From 7e32ebab826a5b8a51ee70ff5bf03b022fd48ee1 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Tue, 4 Feb 2025 03:33:59 +0330 Subject: [PATCH] last ... --- Classes/x-saherelm.x-cobject.class.mq5 | 160 - Classes/x-saherelm.x-poi.drawer.class.mq5 | 1133 -- Documents/BKP/1/liveob.mq5 | 138 + Documents/BKP/1/poilib.bkp.mq5 | 7950 ++++++++++ Documents/BKP/1/signals/tmp.codes.signals.mq5 | 2995 ++++ .../BKP/1/signals/x-121.smc.x.signal.lib.mq5 | 1744 +++ .../1/signals}/x-121.smc.xhkpv.signal.lib.mq5 | 0 .../signals}/x-121.smc.xiobpv.signal.lib.mq5 | 0 .../1/signals}/x-121.smc.xobpv.signal.lib.mq5 | 0 .../1/signals/x-121.smc.xobs.signal.lib.mq5 | 1738 +++ Documents/BKP/1/x-121.smc.guard.lib.mq5 | 1699 +++ .../BKP/1/x-121.smc.xobs.signal.lib copy.mq5 | 1609 ++ Documents/BKP/1/x-saherelm.x-poi.lib.mq5 | 12364 ++++++++++++++++ Libraries/x-saherelm.x-poi.lib.mq5 | 7150 +-------- .../x-121.smc.market.cycle.helper.class.mq5 | 1231 -- X121SMCEA/Libraries/x-121.smc.guard.lib.mq5 | 629 +- X121SMCEA/Libraries/x-121.smc.lib.mq5 | 985 -- X121SMCEA/Signals/x-121.smc.x.signal.lib.mq5 | 582 +- .../Signals/x-121.smc.xobs.signal.lib.mq5 | 737 +- .../Strategy/x-121.smc.strategy.class.mq5 | 756 +- 20 files changed, 31271 insertions(+), 12329 deletions(-) create mode 100644 Documents/BKP/1/liveob.mq5 create mode 100644 Documents/BKP/1/poilib.bkp.mq5 create mode 100644 Documents/BKP/1/signals/tmp.codes.signals.mq5 create mode 100644 Documents/BKP/1/signals/x-121.smc.x.signal.lib.mq5 rename {X121SMCEA/Signals => Documents/BKP/1/signals}/x-121.smc.xhkpv.signal.lib.mq5 (100%) rename {X121SMCEA/Signals => Documents/BKP/1/signals}/x-121.smc.xiobpv.signal.lib.mq5 (100%) rename {X121SMCEA/Signals => Documents/BKP/1/signals}/x-121.smc.xobpv.signal.lib.mq5 (100%) create mode 100644 Documents/BKP/1/signals/x-121.smc.xobs.signal.lib.mq5 create mode 100644 Documents/BKP/1/x-121.smc.guard.lib.mq5 create mode 100644 Documents/BKP/1/x-121.smc.xobs.signal.lib copy.mq5 create mode 100644 Documents/BKP/1/x-saherelm.x-poi.lib.mq5 diff --git a/Classes/x-saherelm.x-cobject.class.mq5 b/Classes/x-saherelm.x-cobject.class.mq5 index 2f3c4880..24356081 100644 --- a/Classes/x-saherelm.x-cobject.class.mq5 +++ b/Classes/x-saherelm.x-cobject.class.mq5 @@ -2077,166 +2077,6 @@ class XCSignalObject : public XCBaseObject CChartObjectTrend mTargetTrend; }; -// -// XPVPivot Object ... -class XCXPVPivotObject : public XCBaseObject -{ - // - public: - // - - /** - * Creator ... - * - * @param chart_id: Long, Specified Chart ID ... - * @param window: Integer, Specified Chart Window ID ... - * @param pivot: XPVPivot instance ... - * @param prefix: String ... - * - * @return ( bool ) - */ - bool Create( - long chart_id, - int window, - XPVPivot &pivot, - string prefix = NULL // - ) - { - // - bool result = false; - - // - result = pivot.IsValid(); - if (!result) - { - return result; - } - - // - string name = pivot.GetTag(); - if (IsValid(prefix)) - { - name = prefix + "_" + name; - } - - // - result = mRect.Create( - chart_id, - name, - window, - pivot.from, - pivot.upper, - pivot.to, - pivot.lower // - ); - - // - if (result) - { - ObjName(name); - } - - // - string mTrendName = "MID_" + name; - double mid = pivot.CalculateMid(); - result = mTrend.Create( - chart_id, - mTrendName, - window, - pivot.from, - mid, - pivot.to, - mid // - ); - if (!result) - { - // - mRect.Delete(); - mRect.Detach(); - } - - // - return result; - } - - // - // Getter(s) / Setter(s) ... - - /** - * Set Pivot Width ... - * - * @param value: Integer ... - */ - void PivotWidth(int value) - { - // - if (value < 1) - { - value = 1; - } - - // - mRect.Width(value); - mTrend.Width(value); - } - - /** - * Set Pivot Color ... - * - * @param value: Color ... - */ - void PivotColor(color value) - { - // - mRect.Color(value); - mTrend.Color(value); - } - - /** - * Set Pivot Style ... - * - * @param value: ENUM_LINE_STYLE member ... - */ - void PivotStyle(ENUM_LINE_STYLE value) - { - // - mRect.Style(value); - mTrend.Style(value); - } - - /** - * Set Pivot Fill ... - * - * @param value: Boolean ... - */ - void PivotFill(bool value) - { - mRect.Fill(value); - } - - // - // Virtual ... - - /** - * Retrieve Object Type ... - * - * @return ( ENUM_XCHARTOBJECTS ) - */ - virtual ENUM_XCHARTOBJECTS Type() - { - return X_XPVPIVOT_OBJ; - } - - // - private: - // - - // - // Props ... - CChartObjectRectangle mRect; - CChartObjectTrend mTrend; -}; - class XCOHCLObject : public XCBaseObject { // diff --git a/Classes/x-saherelm.x-poi.drawer.class.mq5 b/Classes/x-saherelm.x-poi.drawer.class.mq5 index 6d76f2ef..8f1bb320 100644 --- a/Classes/x-saherelm.x-poi.drawer.class.mq5 +++ b/Classes/x-saherelm.x-poi.drawer.class.mq5 @@ -3063,801 +3063,6 @@ class XCPOIDrawer : public XCBase return result; } - /** - * Draw Price Zone ... - * - * @param zone: XPriceZones instance Reference ... - * @param forDir: ENUM_X_DIRECTION member ... - * - * @return ( int ) - */ - int DrawPriceZone( - XPriceZones &zone, - XCBaseObject *&drawnObjects[], - ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, - bool onlyBoundary = false // - ) - { - // - int result = 0; - - // - Clean(drawnObjects); - - // - if (!zone.IsValid()) - { - return result; - } - - // - bool isBullish = IsBullish(forDir); - bool isBearish = IsBearish(forDir); - bool isAll = forDir == X_DIRECTION_ALL || - forDir == X_DIRECTION_NONE; - - // - if (isAll || isBullish) - { - // - if (onlyBoundary) - { - // - double upper = 0; - double lower = 0; - datetime to = NULL; - datetime from = NULL; - - // - bool isRetrieved = zone.GetBoxData( - X_DIRECTION_NONE, - upper, - lower, - from, - to // - ); - if (isRetrieved) - { - // - color clr = - isBullish - ? BarBullishColor() - : isBearish - ? BarBearishColor() - : clrGray; - XCBoxObject *iObj; - result = CreateBox( - iObj, - upper, - lower, - from, - to, - clr, - 1, - false, - STYLE_DOT // - ); - if (result) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - } - else - { - // - // Support Zone ... - if (zone.HasSupportZone()) - { - // - XCSupportZoneObject *iObj; - bool isCreated = CreateSupportZone( - zone.supportZone, - iObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - - // - // Demand Zone ... - if (zone.HasDemandZone()) - { - // - XCDemandZoneObject *iObj; - bool isCreated = CreateDemandZone( - zone.demandZone, - iObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - - // - // OrderBlock ... - if (zone.HasOrderBlock() && - zone.orderBlock.IsBullish()) - { - // - XCBullishOrderBlockObject *iObj; - bool isCreated = CreateBullishOrderBlock( - zone.orderBlock, - iObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - - // - // FairValueGap ... - if (zone.HasFairValueGap() && - zone.fairValueGap.IsBullish()) - { - // - XCBullishFairValueGapObject *iObj; - bool isCreated = CreateBullishFairValueGap( - zone.fairValueGap, - iObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - } - } - - // - if (isAll || isBearish) - { - // - if (onlyBoundary) - { - // - double upper = 0; - double lower = 0; - datetime to = NULL; - datetime from = NULL; - - // - bool isRetrieved = zone.GetBoxData( - X_DIRECTION_NONE, - upper, - lower, - from, - to // - ); - if (isRetrieved) - { - // - color clr = - isBullish - ? BarBullishColor() - : isBearish - ? BarBearishColor() - : clrGray; - XCBoxObject *iObj; - result = CreateBox( - iObj, - upper, - lower, - from, - to, - clr, - 1, - false, - STYLE_DOT // - ); - if (result) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - } - else - { - // - // Resistance Zone ... - if (zone.HasResistanceZone()) - { - // - XCResistanceZoneObject *iObj; - bool isCreated = CreateResistanceZone( - zone.resistanceZone, - iObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - - // - // Supply Zone ... - if (zone.HasSupplyZone()) - { - // - XCSupplyZoneObject *iObj; - bool isCreated = CreateSupplyZone( - zone.supplyZone, - iObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - - // - // OrderBlock ... - if (zone.HasOrderBlock() && - zone.orderBlock.IsBearish()) - { - // - XCBearishOrderBlockObject *iObj; - bool isCreated = CreateBearishOrderBlock( - zone.orderBlock, - iObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - - // - // FairValueGap ... - if (zone.HasFairValueGap() && - zone.fairValueGap.IsBearish()) - { - // - XCBearishFairValueGapObject *iObj; - bool isCreated = CreateBearishFairValueGap( - zone.fairValueGap, - iObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - } - } - - // - result = ArraySize(drawnObjects); - - // - return result; - } - - /** - * Draw Specified State Zone ... - * - * @param source: XStateZones instance Reference ... - * - * @return ( int ) - */ - 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 ... - * - * @param model: XMarketStructure instance Reference ... - * - * @return ( int ) - */ - int DrawMarketStructure( - XMarketStructure &model, - XCBaseObject *&drawnObjects[] // - ) - { - // - int result = 0; - - // - Clean(drawnObjects); - - // - datetime cTime = TimeCurrent(); - - // - bool isValid = - model.IsValid(); - if (!isValid) - { - return result; - } - - // - if (model.lowestValeBar.IsValid()) - { - // - XCOHCLObject *iObj; - bool isCreated = CreateBar( - model.lowestValeBar, - iObj, - cTime // - ); - - // - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - - // - if (model.lowestValePeakBreakeUpBar.IsValid()) - { - // - XCOHCLObject *iObj; - bool isCreated = CreateBar( - model.lowestValePeakBreakeUpBar, - iObj, - cTime // - ); - - // - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - - // - if (model.valeAboveLowestValePeakBar.IsValid()) - { - // - XCOHCLObject *iObj; - bool isCreated = CreateBar( - model.valeAboveLowestValePeakBar, - iObj, - cTime // - ); - - // - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - - // - if (model.highestPeakBar.IsValid()) - { - // - XCOHCLObject *iObj; - bool isCreated = CreateBar( - model.highestPeakBar, - iObj, - cTime // - ); - - // - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - - // - if (model.peakBelowHighestPeakValeBar.IsValid()) - { - // - XCOHCLObject *iObj; - bool isCreated = CreateBar( - model.peakBelowHighestPeakValeBar, - iObj, - cTime // - ); - - // - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - - // - if (model.highestPeakValeBreakeDownBar.IsValid()) - { - // - XCOHCLObject *iObj; - bool isCreated = CreateBar( - model.highestPeakValeBreakeDownBar, - iObj, - cTime // - ); - - // - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - - // - if (HasChild(model.valePriceZones)) - { - // - int count = ArraySize(model.valePriceZones); - for (int i = 0; i < count; i++) - { - // - XPriceZones ipZone = model.valePriceZones[i]; - - // - XCBaseObject *ipObjects[]; - int ipDrawnObjects = DrawPriceZone( - ipZone, - ipObjects, - model.bias // - ); - if (IsValidSize(ipObjects)) - { - // - Copy( - ipObjects, - drawnObjects, - false // - ); - } - } - } - - // - if (HasChild(model.peakPriceZones)) - { - // - int count = ArraySize(model.peakPriceZones); - for (int i = 0; i < count; i++) - { - // - XPriceZones ipZone = model.peakPriceZones[i]; - - // - XCBaseObject *ipObjects[]; - int ipDrawnObjects = DrawPriceZone( - ipZone, - ipObjects, - model.bias // - ); - if (IsValidSize(ipObjects)) - { - // - Copy( - ipObjects, - drawnObjects, - false // - ); - } - } - } - - // - result = ArraySize(drawnObjects); - - // - return result; - } - /** * Draw Specified POI State ... * @@ -4385,344 +3590,6 @@ class XCPOIDrawer : public XCBase return result; } - /** - * Draw Specific Pivot ... - * - * @param pivot: XPVPivot instance Reference ... - * @param drawState: Boolean ... - * @param drawTicksZone: Boolean ... - * @param ignoreSwingHighs: Boolean ... - * @param ignoreSwingLows: Boolean ... - * @param ignoreSupportZones: Boolean ... - * @param ignoreResistanceZones: Boolean ... - * @param ignoreSupplyZones: Boolean ... - * @param ignoreDemandZones: Boolean ... - * @param ignoreBullishOrderBlocks: Boolean ... - * @param ignoreBearishOrderBlocks: Boolean ... - * @param ignoreBullishFairValueGaps: Boolean ... - * @param ignoreBearishFairValueGaps: Boolean ... - * @param ignoreBullishRejectionBars: Boolean ... - * @param ignoreBearishRejectionBars: Boolean ... - * @param ignoreBullishMomentumBars: Boolean ... - * @param ignoreBearishMomentumBars: Boolean ... - */ - int DrawPivot( - XPVPivot &pivot, - XCBaseObject *&drawnObjects[], - bool drawState = false, - bool drawStateAsBox = false, - bool drawTicksZone = false, - bool ignoreSwingHighs = false, - bool ignoreSwingLows = false, - bool ignoreSupportZones = false, - bool ignoreResistanceZones = false, - bool ignoreSupplyZones = false, - bool ignoreDemandZones = false, - bool ignoreBullishOrderBlocks = false, - bool ignoreBearishOrderBlocks = false, - bool ignoreBullishFairValueGaps = false, - bool ignoreBearishFairValueGaps = false, - bool ignoreBullishRejectionBars = false, - bool ignoreBearishRejectionBars = false, - bool ignoreBullishMomentumBars = false, - bool ignoreBearishMomentumBars = false // - ) - { - // - int result = 0; - - // - Clean(drawnObjects); - - // - if (!pivot.IsValid()) - { - return result; - } - - // - string prefix = Prefix(); - long chartID = ChartIdentification(); - int window = SubWindowIdentification(); - - // - // Draw Pivot it self ... - XCXPVPivotObject *iPivotObj; - iPivotObj = new XCXPVPivotObject(); - bool isCreated = iPivotObj.Create( - chartID, - window, - pivot, - prefix // - ); - if (!isCreated) - { - return result; - } - - // - color clrPivotColor = pivot.IsPeak() - ? clrAqua - : clrMagenta; - iPivotObj.PivotColor(clrPivotColor); - iPivotObj.PivotWidth(2); - - // - Add( - (XCBaseObject *)iPivotObj, - drawnObjects // - ); - - // - result = ArraySize(drawnObjects); - - // - if (!drawState) - { - return result; - } - - // - if (!pivot.state.IsValid()) - { - return result; - } - - // - XCBaseObject *stateObjects[]; - int stateCount = 0; - - // - if (!drawStateAsBox) - { - // - stateCount = DrawState( - pivot.state, - stateObjects, - drawTicksZone, - ignoreSwingHighs, - ignoreSwingLows, - ignoreSupportZones, - ignoreResistanceZones, - ignoreSupplyZones, - ignoreDemandZones, - ignoreBullishOrderBlocks, - ignoreBearishOrderBlocks, - ignoreBullishFairValueGaps, - ignoreBearishFairValueGaps, - ignoreBullishRejectionBars, - ignoreBearishRejectionBars, - ignoreBullishMomentumBars, - ignoreBearishMomentumBars // - ); - } - else - { - // - double peakUpper = 0; - double peakLower = 0; - double valeUpper = 0; - double valeLower = 0; - - // - datetime peakTo = NULL; - datetime valeTo = NULL; - datetime peakFrom = NULL; - datetime valeFrom = NULL; - - // - bool hasBoxData = DetectPivotStateBoxData( - pivot, - peakUpper, - peakLower, - peakFrom, - peakTo, - valeUpper, - valeLower, - valeFrom, - valeTo // - ); - - // - if (hasBoxData) - { - // - XCBoxObject *peakBox; - bool isCreated = CreateBox( - peakBox, - peakUpper, - peakLower, - peakFrom, - peakTo, - clrMagenta, - 1, - false, - STYLE_DASHDOT // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)peakBox, - stateObjects // - ); - } - - // - XCBoxObject *valeBox; - isCreated = CreateBox( - valeBox, - valeUpper, - valeLower, - valeFrom, - valeTo, - clrAqua, - 1, - false, - STYLE_DASHDOT // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)valeBox, - stateObjects // - ); - } - } - } - - // - if (IsValidSize(stateCount)) - { - // - Copy( - stateObjects, - drawnObjects, - false // Doesn't Clean ... - ); - - // - Clean(stateObjects); - } - - // - result = ArraySize(drawnObjects); - - // - return result; - } - - /** - * Draw Specified XFVGOrderBlock Object ... - * - * @param models: XFVGOrderBlock instance Reference ... - * - * @return ( int ) - */ - int DrawFVGOrderBlock( - XFVGOrderBlock &model, - XCBaseObject *&drawnObjects[] // - ) - { - // - int result = 0; - - // - Clean(drawnObjects); - - // - if (!model.IsValid()) - { - return result; - } - - // - ENUM_X_DIRECTION iDir; - result = model.GetDirection(iDir); - if (!result) - { - return result; - } - - // - bool isBullish = IsBullish(iDir); - if (isBullish) - { - // - // Order Block ... - XCBullishOrderBlockObject *iOBObj; - bool isCreated = CreateBullishOrderBlock( - model.orderBlock, - iOBObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iOBObj, - drawnObjects // - ); - } - - // - // FVG ... - XCBullishFairValueGapObject *iFVGObj; - isCreated = CreateBullishFairValueGap( - model.fairValueGap, - iFVGObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iOBObj, - drawnObjects // - ); - } - } - else - { - // - // Order Block ... - XCBearishOrderBlockObject *iOBObj; - bool isCreated = CreateBearishOrderBlock( - model.orderBlock, - iOBObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iOBObj, - drawnObjects // - ); - } - - // - // FVG ... - XCBearishFairValueGapObject *iFVGObj; - isCreated = CreateBearishFairValueGap( - model.fairValueGap, - iFVGObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iFVGObj, - drawnObjects // - ); - } - } - - // - result = ArraySize(drawnObjects); - - // - return result; - } - // protected: // diff --git a/Documents/BKP/1/liveob.mq5 b/Documents/BKP/1/liveob.mq5 new file mode 100644 index 00000000..4eb0ea91 --- /dev/null +++ b/Documents/BKP/1/liveob.mq5 @@ -0,0 +1,138 @@ + // + // Detect New Order Blocks ... + bool hasNewBullishOB = Contains( + X_BULLISH_ORDERBLOCK_DETECTED, + consolidationPoiEvents // + ); + bool hasNewBearishOB = Contains( + X_BEARISH_ORDERBLOCK_DETECTED, + consolidationPoiEvents // + ); + bool hasNewOB = hasNewBullishOB || + hasNewBearishOB; + result = hasNewOB; + if (!result) + { + return result; + } + + // + // Make Sure New Order Block Detected ... + XCOrderBlock *liveOB = NULL; + if (hasNewBullishOB) + { + // + bool hasBullishOBs = consolidationState.HasBullishOrderBlocks(); + int bullishOBsCount = consolidationState.CountBullishOrderBlocks(); + if (hasBullishOBs) + { + liveOB = consolidationState.bullishOrderBlocks[bullishOBsCount - 1]; + } + } + else if (hasNewBearishOB) + { + // + bool hasBearishOBs = consolidationState.HasBearishOrderBlocks(); + int bearishOBsCount = consolidationState.CountBearishOrderBlocks(); + if (hasBearishOBs) + { + liveOB = consolidationState.bearishOrderBlocks[bearishOBsCount - 1]; + } + } + bool hasLiveOB = liveOB != NULL && + liveOB.IsValid(); + result = hasLiveOB; + if (!result) + { + return result; + } + + // + bool isLiveOBBullish = liveOB.IsBullish(); + bool isLiveOBBearish = liveOB.IsBearish(); + + // + ENUM_X_DIRECTION forDir = + isLiveOBBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isLiveOBStarted = liveOB.IsStarted( + forDir, + startedBar, + startedDir // + ); + + // + XOHCL activatedBar; + ENUM_X_DIRECTION activatedDir; + bool isLiveOBActivated = liveOB.IsActivated( + forDir, + activatedBar, + activatedDir // + ); + + // + // DRAW ... + // + + // + if (isLiveOBStarted) + { + // + XCOHCLObject *barObj; + bool isCreated = consolidationCycleHelper + .mPOIDrawer + .CreateBar( + startedBar, + barObj // + ); + } + + // + if (isLiveOBActivated) + { + // + XCOHCLObject *barObj; + bool isCreated = consolidationCycleHelper + .mPOIDrawer + .CreateBar( + activatedBar, + barObj // + ); + if (isCreated) + { + // + barObj.BodyColor(clrGold); + barObj.HighShadowColor(clrGold); + barObj.LowShadowColor(clrGold); + } + } + + // + // Draw Live OB ... + if (isLiveOBBullish) + { + // + XCBullishOrderBlockObject *iObj; + bool isCreated = consolidationCycleHelper + .mPOIDrawer + .CreateBullishOrderBlock( + liveOB, + iObj // + ); + } + else + { + // + XCBearishOrderBlockObject *iObj; + bool isCreated = consolidationCycleHelper + .mPOIDrawer + .CreateBearishOrderBlock( + liveOB, + iObj // + ); + } diff --git a/Documents/BKP/1/poilib.bkp.mq5 b/Documents/BKP/1/poilib.bkp.mq5 new file mode 100644 index 00000000..d997474c --- /dev/null +++ b/Documents/BKP/1/poilib.bkp.mq5 @@ -0,0 +1,7950 @@ + +/** + * Calculate Target for Specified Direction ... + * + * @param bar: XOHCL instance Reference ... + * @param state: XPOIState instance Reference ... + * @param forDir: ENUM_S_DIRECTION member ... + * + * @return ( double ) + */ +double CalculateTarget( + XOHCL &bar, + XPOIState &state, + ENUM_X_DIRECTION forDir // +) +{ + // + double result = 0; + + // + if (!state.IsValid() || + !state.HasChild() || + !HasDirection(forDir)) + { + return result; + } + + // + XCFVG *iFVG = NULL; + XCOrderBlock *iOB = NULL; + XCSupplyZone *iSupply = NULL; + XCDemandZone *iDemand = NULL; + XCSupportZone *iSupport = NULL; + XCResistanceZone *iResistance = NULL; + + // + bool hasOB = false; + bool hasFVG = false; + bool hasSupply = false; + bool hasDemand = false; + bool hasSupport = false; + bool hasResistance = false; + + // + int count = 0; + + // + if (IsBearish(forDir)) + { + // + // FVG ... + count = state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCFVG *iZone = state.bullishFairValueGaps[i]; + + // + bool isValid = IsPriceAboveZone( + bar, + iZone // + ); + if (isValid) + { + // + iFVG = iZone; + hasFVG = true; + break; + } + } + } + + // + // OB ... + count = state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCOrderBlock *iZone = state.bullishOrderBlocks[i]; + + // + bool isValid = IsPriceAboveZone( + bar, + iZone // + ); + if (isValid) + { + // + iOB = iZone; + hasOB = true; + break; + } + } + } + + // + // SUPPORT ... + count = state.CountSupportZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCSupportZone *iZone = state.supportZones[i]; + + // + bool isValid = IsPriceAboveZone( + bar, + iZone // + ); + if (isValid) + { + // + iSupport = iZone; + hasSupport = true; + break; + } + } + } + + // + // DEMAND ... + count = state.CountDemandZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCDemandZone *iZone = state.demandZones[i]; + + // + bool isValid = IsPriceAboveZone( + bar, + iZone // + ); + if (isValid) + { + // + iDemand = iZone; + hasDemand = true; + break; + } + } + } + + // + // Summary ... + result = + hasFVG + ? iFVG.Upper() + : hasOB + ? iOB.Upper() + : hasSupport + ? iSupport.Upper() + : hasDemand + ? iDemand.Upper() + : 0; + if (hasFVG) + { + result = MathMax(result, iFVG.Upper()); + } + if (hasOB) + { + result = MathMax(result, iOB.Upper()); + } + if (hasSupport) + { + result = MathMax(result, iSupport.Upper()); + } + if (hasDemand) + { + result = MathMax(result, iDemand.Upper()); + } + } + + // + if (IsBullish(forDir)) + { + // + // FVG ... + count = state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCFVG *iZone = state.bearishFairValueGaps[i]; + + // + bool isValid = IsPriceBelowZone( + bar, + iZone // + ); + if (isValid) + { + // + iFVG = iZone; + hasFVG = true; + break; + } + } + } + + // + // OB ... + count = state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCOrderBlock *iZone = state.bearishOrderBlocks[i]; + + // + bool isValid = IsPriceBelowZone( + bar, + iZone // + ); + if (isValid) + { + // + iOB = iZone; + hasOB = true; + break; + } + } + } + + // + // RESISTANCE ... + count = state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCResistanceZone *iZone = state.resistanceZones[i]; + + // + bool isValid = IsPriceBelowZone( + bar, + iZone // + ); + if (isValid) + { + // + iResistance = iZone; + hasResistance = true; + break; + } + } + } + + // + // SUPPLY ... + count = state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCSupplyZone *iZone = state.supplyZones[i]; + + // + bool isValid = IsPriceBelowZone( + bar, + iZone // + ); + if (isValid) + { + // + iSupply = iZone; + hasSupply = true; + break; + } + } + } + + // + // Summary ... + result = + hasFVG + ? iFVG.Lower() + : hasOB + ? iOB.Lower() + : hasSupport + ? iSupport.Lower() + : hasDemand + ? iDemand.Lower() + : 0; + if (hasFVG) + { + result = MathMin(result, iFVG.Lower()); + } + if (hasOB) + { + result = MathMin(result, iOB.Lower()); + } + if (hasSupport) + { + result = MathMin(result, iSupport.Lower()); + } + if (hasDemand) + { + result = MathMin(result, iDemand.Lower()); + } + } + + // + return result; +} + +/** + * Detect Valid Order Blocks ... + * + * @param forDir: ENUM_X_DIRECTION member ... + * @param source: XPOIState instance Reference ... + * + * @return ( int ) + */ +int DetectValidOrderBlocks( + ENUM_X_DIRECTION forDir, + XPOIState &source, + XCOrderBlock *&orderBlocks[] // +) +{ + // + int result = 0; + + // + Clean(orderBlocks); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + HasDirection(forDir) + // + ; + if (!isValid) + { + return result; + } + + // + datetime cTime = TimeCurrent(); + + // + XOHCL cBar; + bool isInited = cBar.Init( + source.symbol, + source.period, + 1 // + ); + if (!isInited) + { + return result; + } + + // + int count = 0; + + // + // Bullish ... + count = source.CountBullishOrderBlocks(); + isValid = IsValidSize(count) && + IsBullish(forDir); + if (isValid) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = source.bullishOrderBlocks[i]; + + // + // Update Order Block Time ... + iOB.To(cTime); + + // + // Check Order Block Validation ... + isValid = IsValid( + forDir, + cBar.symbol, + cBar.period, + iOB.Upper(), + iOB.Lower(), + iOB.From(), + iOB.To() // + ); + if (isValid) + { + // + Add( + iOB, + orderBlocks // + ); + } + } + } + + // + // Bearish ... + count = source.CountBearishOrderBlocks(); + isValid = IsValidSize(count) && + IsBearish(forDir); + if (isValid) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = source.bearishOrderBlocks[i]; + + // + // Update Order Block Time ... + iOB.To(cTime); + + // + // Check Order Block Validation ... + isValid = IsValid( + forDir, + cBar.symbol, + cBar.period, + iOB.Upper(), + iOB.Lower(), + iOB.From(), + iOB.To() // + ); + if (isValid) + { + // + Add( + iOB, + orderBlocks // + ); + } + } + } + + // + result = ArraySize(orderBlocks); + + // + return result; +} + +/** + * Detect Valid Fair Value Gaps ... + * + * @param forDir: ENUM_X_DIRECTION member ... + * @param source: XPOIState instance Reference ... + * + * @return ( int ) + */ +int DetectValidFairValueGaps( + ENUM_X_DIRECTION forDir, + XPOIState &source, + XCFVG *&fairValueGaps[] // +) +{ + // + int result = 0; + + // + Clean(fairValueGaps); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + HasDirection(forDir) + // + ; + if (!isValid) + { + return result; + } + + // + datetime cTime = TimeCurrent(); + + // + XOHCL cBar; + bool isInited = cBar.Init( + source.symbol, + source.period, + 1 // + ); + if (!isInited) + { + return result; + } + + // + int count = 0; + + // + // Bullish ... + count = source.CountBullishFairValueGaps(); + isValid = IsValidSize(count) && + IsBullish(forDir); + if (isValid) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = source.bullishFairValueGaps[i]; + + // + // Update FVG Time ... + iFVG.To(cTime); + + // + // Check FVG Validation ... + isValid = IsValid( + forDir, + cBar.symbol, + cBar.period, + iFVG.Upper(), + iFVG.Lower(), + iFVG.From(), + iFVG.To() // + ); + if (isValid) + { + // + Add( + iFVG, + fairValueGaps // + ); + } + } + } + + // + // Bearish ... + count = source.CountBearishFairValueGaps(); + isValid = IsValidSize(count) && + IsBearish(forDir); + if (isValid) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = source.bearishFairValueGaps[i]; + + // + // Update Order Block Time ... + iFVG.To(cTime); + + // + // Check Order Block Validation ... + isValid = IsValid( + forDir, + cBar.symbol, + cBar.period, + iFVG.Upper(), + iFVG.Lower(), + iFVG.From(), + iFVG.To() // + ); + if (isValid) + { + // + Add( + iFVG, + fairValueGaps // + ); + } + } + } + + // + result = ArraySize(fairValueGaps); + + // + return result; +} + +/** + * Detect Valid Support Zones ... + * + * @param source: XPOIState instance ... + * + * @return ( int ) + */ +int DetectValidSupportZones( + XPOIState &source, + XCOrderBlock *&bullishOrderBlocks[], + XCFVG *&bullishFairValueGaps[], + XCSupportZone *&supportZones[] // +) +{ + // + int result = 0; + + // + Clean(supportZones); + + // + int obsCount = ArraySize(bullishOrderBlocks); + int fvgsCount = ArraySize(bullishFairValueGaps); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + IsValidSize(obsCount + fvgsCount) + // + ; + if (!isValid) + { + return result; + } + + // + int count = source.CountSupportZones(); + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iZone = source.supportZones[i]; + + // + bool isAdded = false; + + // + for (int j = 0; j < obsCount; j++) + { + // + XCOrderBlock *iOB = bullishOrderBlocks[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iOB.Upper(), + iOB.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iOB.Upper(), + iOB.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + supportZones // + ); + + // + isAdded = true; + break; + } + } + + // + if (isAdded) + { + continue; + } + + // + for (int j = 0; j < fvgsCount; j++) + { + // + XCFVG *iFVG = bullishFairValueGaps[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + supportZones // + ); + + // + isAdded = true; + break; + } + } + } + + // + result = ArraySize(supportZones); + + // + return result; +} + +/** + * Detect Valid Resistance Zones ... + * + * @param source: XPOIState instance ... + * + * @return ( int ) + */ +int DetectValidResistanceZones( + XPOIState &source, + XCOrderBlock *&bearishOrderBlocks[], + XCFVG *&bearishFairValueGaps[], + XCResistanceZone *&resistanceZones[] // +) +{ + // + int result = 0; + + // + Clean(resistanceZones); + + // + int obsCount = ArraySize(bearishOrderBlocks); + int fvgsCount = ArraySize(bearishFairValueGaps); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + IsValidSize(obsCount + fvgsCount) + // + ; + if (!isValid) + { + return result; + } + + // + int count = source.CountResistanceZones(); + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iZone = source.resistanceZones[i]; + + // + bool isAdded = false; + + // + for (int j = 0; j < obsCount; j++) + { + // + XCOrderBlock *iOB = bearishOrderBlocks[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iOB.Upper(), + iOB.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iOB.Upper(), + iOB.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + resistanceZones // + ); + + // + isAdded = true; + break; + } + } + + // + if (isAdded) + { + continue; + } + + // + for (int j = 0; j < fvgsCount; j++) + { + // + XCFVG *iFVG = bearishFairValueGaps[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + resistanceZones // + ); + + // + isAdded = true; + break; + } + } + } + + // + result = ArraySize(resistanceZones); + + // + return result; +} + +/** + * Detect Valid Support Zones ... + * + * @param source: XPOIState instance ... + * + * @return ( int ) + */ +int DetectValidDemandZones( + XPOIState &source, + XCOrderBlock *&bullishOrderBlocks[], + XCFVG *&bullishFairValueGaps[], + XCDemandZone *&demandZones[] // +) +{ + // + int result = 0; + + // + Clean(demandZones); + + // + int obsCount = ArraySize(bullishOrderBlocks); + int fvgsCount = ArraySize(bullishFairValueGaps); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + IsValidSize(obsCount + fvgsCount) + // + ; + if (!isValid) + { + return result; + } + + // + int count = source.CountDemandZones(); + for (int i = 0; i < count; i++) + { + // + XCDemandZone *iZone = source.demandZones[i]; + + // + bool isAdded = false; + + // + for (int j = 0; j < obsCount; j++) + { + // + XCOrderBlock *iOB = bullishOrderBlocks[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iOB.Upper(), + iOB.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iOB.Upper(), + iOB.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + demandZones // + ); + + // + isAdded = true; + break; + } + } + + // + if (isAdded) + { + continue; + } + + // + for (int j = 0; j < fvgsCount; j++) + { + // + XCFVG *iFVG = bullishFairValueGaps[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + demandZones // + ); + + // + isAdded = true; + break; + } + } + } + + // + result = ArraySize(demandZones); + + // + return result; +} + +/** + * Detect Valid Resistance Zones ... + * + * @param source: XPOIState instance ... + * + * @return ( int ) + */ +int DetectValidSupplyZones( + XPOIState &source, + XCOrderBlock *&bearishOrderBlocks[], + XCFVG *&bearishFairValueGaps[], + XCSupplyZone *&supplyZones[] // +) +{ + // + int result = 0; + + // + Clean(supplyZones); + + // + int obsCount = ArraySize(bearishOrderBlocks); + int fvgsCount = ArraySize(bearishFairValueGaps); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + IsValidSize(obsCount + fvgsCount) + // + ; + if (!isValid) + { + return result; + } + + // + int count = source.CountSupplyZones(); + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *iZone = source.supplyZones[i]; + + // + bool isAdded = false; + + // + for (int j = 0; j < obsCount; j++) + { + // + XCOrderBlock *iOB = bearishOrderBlocks[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iOB.Upper(), + iOB.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iOB.Upper(), + iOB.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + supplyZones // + ); + + // + isAdded = true; + break; + } + } + + // + if (isAdded) + { + continue; + } + + // + for (int j = 0; j < fvgsCount; j++) + { + // + XCFVG *iFVG = bearishFairValueGaps[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + supplyZones // + ); + + // + isAdded = true; + break; + } + } + } + + // + result = ArraySize(supplyZones); + + // + return result; +} + +/** + * Detect a Zone Breaker Bar ... + * + * @param toBar: XOHCL instance Reference ... + * @param fromBar: XOHCL instance Reference ... + * @param breakerBar: XOHCL instance Reference ... + * @param forDir: ENUM_X_DIRECTION member ... + * @param symbol: String ... + * @param period: ENUM_TIMEFRAMES member ... + * + * @return ( bool ) + */ +bool HasBreakerBar( + XOHCL &toBar, + XOHCL &fromBar, + XOHCL &breakerBar, + ENUM_X_DIRECTION forDir, + string symbol, + ENUM_TIMEFRAMES period, + double upper, + double lower, + datetime from, + datetime to // +) +{ + // + bool result = false; + + // + toBar.Clean(); + fromBar.Clean(); + breakerBar.Clean(); + + // + result = + // + upper > 0 && + lower > 0 && + IsValid(to) && + upper > lower && + IsValid(from) && + IsValid(symbol) && + IsValid(period) && + HasDirection(forDir) + // + ; + if (!result) + { + return result; + } + + // + result = fromBar.Init( + symbol, + period, + from // + ); + if (!result) + { + return result; + } + + // + result = toBar.Init( + symbol, + period, + to // + ); + if (!result) + { + return result; + } + + // + int toIndex = toBar.Index(); + int fromIndex = fromBar.Index(); + + // + // Detect Zone BreakerBar ... + for (int i = fromIndex; i >= toIndex; i--) + { + // + XOHCL iBar; + result = iBar.Init( + symbol, + period, + i // + ); + + // + if (!result) + { + continue; + } + + // + result = + // + IsBullish(forDir) + ? + // + iBar.low < upper && + iBar.high > upper && + iBar.GetUp() > upper + // + : + // + iBar.high > lower && + iBar.low < lower && + iBar.GetDown() < lower + // + ; + if (result) + { + // + breakerBar = iBar; + break; + } + } + + // + result = breakerBar.IsValid(); + + // + return result; +} + +/** + * Validate Specified Order Block ... + * + * @param forDir: ENUM_X_DIRECTION member ... + * @param symbol: String ... + * @param period: ENUM_TIMEFRAMES member ... + * + * @return ( bool ) + */ +bool IsValid( + ENUM_X_DIRECTION forDir, + string symbol, + ENUM_TIMEFRAMES period, + double upper, + double lower, + datetime from, + datetime to, + bool ignoreBreakerBar = false // +) +{ + // + bool result = false; + + // + result = + upper > 0 && + lower > 0 && + IsValid(to) && + upper > lower && + IsValid(from) && + IsValid(symbol) && + IsValid(period) && + HasDirection(forDir) + // + ; + if (!result) + { + return result; + } + + // + XOHCL toBar; + XOHCL fromBar; + XOHCL breakerBar; + + // + if (!ignoreBreakerBar) + { + // + result = HasBreakerBar( + toBar, + fromBar, + breakerBar, + forDir, + symbol, + period, + upper, + lower, + from, + to // + ); + if (!result) + { + return result; + } + } + else + { + // + result = toBar.Init( + symbol, + period, + to // + ); + if (!result) + { + return result; + } + + // + result = fromBar.Init( + symbol, + period, + from // + ); + if (!result) + { + return result; + } + + // + breakerBar = fromBar; + } + + // + int toIndex = toBar.Index(); + int fromIndex = fromBar.Index(); + int breakerIndex = breakerBar.Index(); + + // + bool isBreaked = false; + for (int i = breakerIndex - 1; i >= toIndex; i--) + { + // + XOHCL iBar; + result = iBar.Init( + fromBar.symbol, + fromBar.period, + i // + ); + + // + if (!result) + { + continue; + } + + // + isBreaked = + // + IsBullish(forDir) + // + ? + // + iBar.low < upper + // + : + // + iBar.high > lower + // + ; + if (isBreaked) + { + break; + } + } + + // + result = !isBreaked; + + // + return result; +} + +/** + * Get Oldest Zone ... + * + * @return ( int ) + */ +int GetOldest( + XCZone *&source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XCZone *oldest = NULL; + for (int i = 0; i < count; i++) + { + // + XCZone *iZone = source[i]; + + // + bool canSet = + oldest == NULL || + (oldest != NULL && + oldest.From() > iZone.From()); + if (canSet) + { + // + result = i; + oldest = iZone; + } + } + + // + return result; +} + +/** + * Get Youngest Zone ... + * + * @return ( int ) + */ +int GetYoungest( + XCZone *&source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XCZone *youngest = NULL; + for (int i = 0; i < count; i++) + { + // + XCZone *iZone = source[i]; + + // + bool canSet = + youngest == NULL || + (youngest != NULL && + youngest.From() < iZone.From()); + if (canSet) + { + // + result = i; + youngest = iZone; + } + } + + // + return result; +} + +template +bool ToZone( + T *&source[], + XCZone *&dest[] // +) +{ + // + bool result = false; + + // + Clean(dest); + + // + int count = ArraySize(source); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + T *item = source[i]; + + // + if (item != NULL) + { + // + Add( + (XCZone *)item, + dest // + ); + } + } + + // + int destCount = ArraySize(dest); + result = IsValidSize(destCount); + + // + return result; +} + +///////////////////////////////////////////////////////////////////// + +/** + * Find Oldest Pivot Index ... + * + * @param pivots: XPVPivot instance ... + * @return ( int ) + */ +int FindOldestPivotIndex( + XPVPivot &pivots[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(pivots); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = pivots[i]; + + // + bool isOldest = true; + for (int j = 0; j < count; j++) + { + // + XPVPivot jPivot = pivots[j]; + + // + isOldest = iPivot.from <= jPivot.from; + if (!isOldest) + { + break; + } + } + + // + if (isOldest) + { + // + result = i; + break; + } + } + + // + return result; +} + +/** + * Sort Pivots Based On From Date ... + * + * @param pivots: XPVPivot instance Collection reference ... + */ +void SortPivots( + XPVPivot &pivots[] // +) +{ + // + XPVPivot tmp[]; + Copy( + pivots, + tmp // + ); + + // + Clean(pivots); + + // + while (ArraySize(tmp) > 0) + { + // + if (ArraySize(tmp) == 1) + { + // + AddRef( + tmp[0], + pivots // + ); + + // + ArrayRemove( + tmp, + 0, + 1); + } + else + { + // + int idx = FindOldestPivotIndex(tmp); + if (IsValidIndex(idx)) + { + // + AddRef( + tmp[idx], + pivots // + ); + + // + ArrayRemove( + tmp, + idx, + 1 // + ); + } + } + } + + // + Clean(tmp); +} + +bool IsPivotBreaked( + XPVPivot &pivot, + XPVPivot &pivots[] // +) +{ + // + bool result = false; + + // + result = pivot.IsValid(); + if (!result) + { + return result; + } + + // + int count = ArraySize(pivots); + result = IsValidSize(pivots); + if (!result) + { + return result; + } + + // + // For Peaks Highs Must not Broked ... + // For Vales Lows Must not Broked ... + bool isPeak = pivot.IsPeak(); + + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = pivots[i]; + + // + result = isPeak + ? iPivot.upper > pivot.upper + : iPivot.lower < pivot.lower; + if (result) + { + break; + } + } + + // + return result; +} + +/** + * Filter Broken Pivots for Detect Order Flow ... + * + * @param pivots: XPVPivot instance Collection reference ... + */ +void FilterBrokenPivots( + XPVPivot &pivots[] // +) +{ + // + XPVPivot tmp[]; + Copy( + pivots, + tmp // + ); + + // + Clean(pivots); + + // + while (ArraySize(tmp) > 0) + { + // + if (ArraySize(tmp) == 1) + { + // + AddRef( + tmp[0], + pivots // + ); + + // + ArrayRemove( + tmp, + 0, + 1 // + ); + } + else + { + // + XPVPivot pivot = tmp[0]; + + // + ArrayRemove( + tmp, + 0, + 1 // + ); + + // + bool isBreaked = IsPivotBreaked( + pivot, + tmp // + ); + if (!isBreaked) + { + // + AddRef( + pivot, + pivots // + ); + } + } + } + + // + Clean(tmp); +} + +/** + * Calculate Order Flow Direction ... + * + * @param orderFlow: XPVPivot instance Collection reference ... + * @param dir: ENUM_X_DIRECTION member reference, Hold's Calculated Direction ... + * + * @return ( bool ) + */ +bool DetectPivotDirection( + XPVPivot &orderFlow[], + ENUM_X_DIRECTION &dir // +) +{ + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + + // + int count = ArraySize(orderFlow); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + // For Bullish Direction all Exists lowers must be Greater or Equal Prev ... + bool isBullish = false; + bool canLookupForBullish = true; + + // + // For Bearish Direction all Exists uppers must be Lesser or Equal Prev ... + bool isBearish = false; + bool canLookupForBearish = true; + + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = orderFlow[i]; + + // + XPVPivot tmp[]; + Copy( + orderFlow, + tmp // + ); + ArrayRemove( + tmp, + 0, + i + 1 // + ); + + // + int tmpCount = ArraySize(tmp); + if (IsValidSize(tmpCount)) + { + // + for (int j = 0; j < tmpCount; j++) + { + // + XPVPivot jPivot = tmp[j]; + + // + // Check Bullish Direction ... + isBullish = + canLookupForBullish && + jPivot.lower >= iPivot.lower; + if (!isBullish) + { + canLookupForBullish = false; + } + + // + // Check Bearish Direction ... + isBearish = + canLookupForBearish && + jPivot.upper <= iPivot.upper; + if (!isBearish) + { + canLookupForBearish = false; + } + + // + if (!canLookupForBullish && + !canLookupForBearish) + { + break; + } + } + } + Clean(tmp); + } + + // + if (isBullish && + !isBearish) + { + dir = X_DIRECTION_BULLISH; + } + else if (isBearish && + !isBullish) + { + dir = X_DIRECTION_BEARISH; + } + + // + result = dir != X_DIRECTION_NONE; + + // + return result; +} + +/** + * Detect all POIs which inside a Pivot ... + * + * @param pivot: XPVPivot instance, Specified Pivot ... + * @param source: XPOIState instance, Reference to Source State ... + * @param state: XPOIState instance, Reference to Detected Pivots ... + * @param lookupSwingHighs: Boolean ... + * @param lookupSwingLows: Boolean ... + * @param lookupSupportZones: Boolean ... + * @param lookupResistanceZones: Boolean ... + * @param lookupSupplyZones: Boolean ... + * @param lookupDemandZones: Boolean ... + * @param lookupBullishOrderBlocks: Boolean ... + * @param lookupBearishOrderBlocks: Boolean ... + * @param lookupBullishFairValueGaps: Boolean ... + * @param lookupBearishFairValueGaps: Boolean ... + * @param lookupBullishRejectionBars: Boolean ... + * @param lookupBearishRejectionBars: Boolean ... + * @param lookupBullishMomentumBars: Boolean ... + * @param lookupBearishMomentumBars: Boolean ... + */ +void DetectPivotPOIs( + XPVPivot &pivot, + XPOIState &source, + XPOIState &state, + bool lookupSwingHighs = true, + bool lookupSwingLows = true, + bool lookupSupportZones = true, + bool lookupResistanceZones = true, + bool lookupSupplyZones = true, + bool lookupDemandZones = true, + bool lookupBullishOrderBlocks = true, + bool lookupBearishOrderBlocks = true, + bool lookupBullishFairValueGaps = true, + bool lookupBearishFairValueGaps = true, + bool lookupBullishRejectionBars = true, + bool lookupBearishRejectionBars = true, + bool lookupBullishMomentumBars = true, + bool lookupBearishMomentumBars = true // +) +{ + // + state.Clean(); + + // + if (!pivot.IsValid()) + { + return; + } + + // + int count = 0; + + // + state.symbol = pivot.symbol; + state.period = pivot.period; + state.time = TimeCurrent(); + + // + // Swings ... + + // + // Swing High ... + if (lookupSwingHighs) + { + // + count = ArraySize(source.swingHighs); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = source.swingHighs[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.high <= pivot.upper; + if (isInside) + { + // + // iSwing.To(pivot.to); + + // + Add( + iSwing, + state.swingHighs // + ); + } + } + } + } + + // + // Swing Low ... + if (lookupSwingLows) + { + // + count = ArraySize(source.swingLows); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = source.swingLows[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.low >= pivot.lower; + if (isInside) + { + // + // iSwing.To(pivot.to); + + // + Add( + iSwing, + state.swingLows // + ); + } + } + } + } + + // + // Support and Resistance Zones ... + + // + // Support Zones ... + if (lookupSupportZones) + { + // + count = ArraySize(source.supportZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iZone = source.supportZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + iZone.To(pivot.to); + + // + Add( + iZone, + state.supportZones // + ); + } + } + } + } + + // + // Resistance Zones ... + if (lookupResistanceZones) + { + // + count = ArraySize(source.resistanceZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iZone = source.resistanceZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + iZone.To(pivot.to); + + // + Add( + iZone, + state.resistanceZones // + ); + } + } + } + } + + // + // Supply and Demand Zones ... + + // + // Supply Zones ... + if (lookupSupplyZones) + { + // + count = ArraySize(source.supplyZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *iZone = source.supplyZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + iZone.To(pivot.to); + + // + Add( + iZone, + state.supplyZones // + ); + } + } + } + } + + // + // Demand Zones ... + if (lookupDemandZones) + { + // + count = ArraySize(source.demandZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone *iZone = source.demandZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + iZone.To(pivot.to); + + // + Add( + iZone, + state.demandZones // + ); + } + } + } + } + + // + // Order Blocks ... + + // + // Bullish Order Blocks ... + if (lookupBullishOrderBlocks) + { + // + count = ArraySize(source.bullishOrderBlocks); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = source.bullishOrderBlocks[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + iZone.To(pivot.to); + + // + Add( + iZone, + state.bullishOrderBlocks // + ); + } + } + } + } + + // + // Bearish Order Blocks ... + if (lookupBearishOrderBlocks) + { + // + count = ArraySize(source.bearishOrderBlocks); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = source.bearishOrderBlocks[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + iZone.To(pivot.to); + + // + Add( + iZone, + state.bearishOrderBlocks // + ); + } + } + } + } + + // + // Fair Value Gaps ... + + // + // Bullish Fair Value Gaps ... + if (lookupBullishFairValueGaps) + { + // + count = ArraySize(source.bullishFairValueGaps); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = source.bullishFairValueGaps[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + iZone.To(pivot.to); + + // + Add( + iZone, + state.bullishFairValueGaps // + ); + } + } + } + } + + // + // Bearish Fair Value Gaps ... + if (lookupBearishFairValueGaps) + { + // + count = ArraySize(source.bearishFairValueGaps); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = source.bearishFairValueGaps[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + iZone.To(pivot.to); + + // + Add( + iZone, + state.bearishFairValueGaps // + ); + } + } + } + } + + // + // Rejection Bars ... + + // + // Bullish Rejection Bars ... + if (lookupBullishRejectionBars) + { + // + count = ArraySize(source.bullishRejectionBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iRejection = source.bullishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.low <= pivot.upper && + iBar.low >= pivot.lower; + if (isInside) + { + // + iRejection.To(pivot.to); + + // + Add( + iRejection, + state.bullishRejectionBars // + ); + } + } + } + } + + // + // Bearish Rejection Bars ... + if (lookupBearishRejectionBars) + { + // + count = ArraySize(source.bearishRejectionBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iRejection = source.bearishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.high <= pivot.upper && + iBar.high >= pivot.lower; + if (isInside) + { + // + iRejection.To(pivot.to); + + // + Add( + iRejection, + state.bearishRejectionBars // + ); + } + } + } + } + + // + // Momentum Bars ... + + // + // Bullish Momentum Bars ... + if (lookupBullishMomentumBars) + { + // + count = ArraySize(source.bullishMomentumBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar *iMomentum = source.bullishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.low <= pivot.upper && + iBar.low >= pivot.lower; + if (isInside) + { + // + iMomentum.To(pivot.to); + + // + Add( + iMomentum, + state.bullishMomentumBars // + ); + } + } + } + } + + // + // Bearish Momenum Bars ... + if (lookupBearishMomentumBars) + { + // + count = ArraySize(source.bearishMomentumBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar *iMomentum = source.bearishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.high <= pivot.upper && + iBar.high >= pivot.lower; + if (isInside) + { + // + iMomentum.To(pivot.to); + + // + Add( + iMomentum, + state.bearishMomentumBars // + ); + } + } + } + } +} + +/** + * Fill Pivot Tick Zone ... + * + * @param pivot: XPVPivot instance Reference ... + */ +void CalculatePivotTickZone( + XPVPivot &pivot, + int ticksLevels, + int ticksRange, + ENUM_TIMEFRAMES _period = NULL // +) +{ + // + string symbol = pivot.symbol; + ENUM_TIMEFRAMES period = IsValid(_period) + ? _period + : pivot.period; + + // + bool isInited = false; + + // + datetime from = pivot.from; + XOHCL iFromBar; + int iFromBarIndex = iBarShift( + symbol, + period, + from // + ); + isInited = iFromBar.Init( + symbol, + period, + iFromBarIndex // + ); + if (!isInited) + { + return; + } + + // + datetime to = pivot.to; + XOHCL iToBar; + int iToBarIndex = iBarShift( + symbol, + period, + to // + ); + isInited = iToBar.Init( + symbol, + period, + iToBarIndex // + ); + if (!isInited) + { + return; + } + + // + if (iFromBarIndex <= iToBarIndex) + { + return; + } + + // + XCTicksZone *iZone; + iZone = new XCTicksZone(); + + // + isInited = ticksLevels > 0 && + ticksRange > 0; + if (!isInited) + { + return; + } + + // + isInited = iZone.Init( + iFromBar, + iToBar // + ); + if (!isInited) + { + return; + } + + // + pivot.state.ticksZone = iZone; +} + +/** + * Filter State based on Pivot ... + * + * @param pivot: XPVPivot instance Reference ... + * @param state: XPOIState instance Reference ... + */ +void FilterPivotState( + XPVPivot &pivot, + XPOIState &state // +) +{ + // + bool isValid = + pivot.IsValid() && + state.IsValid() && + state.HasChild(); + if (!isValid) + { + return; + } + + // + int count = 0; + + // + double upper = pivot.upper; + double lower = pivot.lower; + + // + // + // + + // + // Resistance ... + count = state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + XCResistanceZone *tmp[]; + Copy( + state.resistanceZones, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *item = tmp[i]; + + // + bool isValid = IsPriceInsideZone( + upper, + item // + ); + if (!isValid) + { + // + ArrayRemove( + state.resistanceZones, + i, + 1 // + ); + } + } + + // + Clean(tmp); + } + + // + // Supply ... + count = state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + XCSupplyZone *tmp[]; + Copy( + state.supplyZones, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *item = tmp[i]; + + // + bool isValid = IsPriceInsideZone( + upper, + item // + ); + if (!isValid) + { + // + ArrayRemove( + state.supplyZones, + i, + 1 // + ); + } + } + + // + Clean(tmp); + } + + // + // Bearish Order Block ... + count = state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + XCOrderBlock *tmp[]; + Copy( + state.bearishOrderBlocks, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *item = tmp[i]; + + // + bool isValid = IsPriceInsideZone( + upper, + item // + ); + if (!isValid) + { + // + ArrayRemove( + state.bearishOrderBlocks, + i, + 1 // + ); + } + } + + // + Clean(tmp); + } + + // + // Bearish Fair Value Gap ... + count = state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + XCFVG *tmp[]; + Copy( + state.bearishFairValueGaps, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCFVG *item = tmp[i]; + + // + bool isValid = IsPriceInsideZone( + upper, + item // + ); + if (!isValid) + { + // + ArrayRemove( + state.bearishFairValueGaps, + i, + 1 // + ); + } + } + + // + Clean(tmp); + } + + // + // + // + + // + // Support ... + count = state.CountSupportZones(); + if (IsValidSize(count)) + { + // + XCSupportZone *tmp[]; + Copy( + state.supportZones, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone *item = tmp[i]; + + // + bool isValid = IsPriceInsideZone( + lower, + item // + ); + if (!isValid) + { + // + ArrayRemove( + state.supportZones, + i, + 1 // + ); + } + } + + // + Clean(tmp); + } + + // + // Demand ... + count = state.CountDemandZones(); + if (IsValidSize(count)) + { + // + XCDemandZone *tmp[]; + Copy( + state.demandZones, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone *item = tmp[i]; + + // + bool isValid = IsPriceInsideZone( + lower, + item // + ); + if (!isValid) + { + // + ArrayRemove( + state.demandZones, + i, + 1 // + ); + } + } + + // + Clean(tmp); + } + + // + // Bullish Order Block ... + count = state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + XCOrderBlock *tmp[]; + Copy( + state.bullishOrderBlocks, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *item = tmp[i]; + + // + bool isValid = IsPriceInsideZone( + lower, + item // + ); + if (!isValid) + { + // + ArrayRemove( + state.bullishOrderBlocks, + i, + 1 // + ); + } + } + + // + Clean(tmp); + } + + // + // Bullish Fair Value Gap ... + count = state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + XCFVG *tmp[]; + Copy( + state.bullishFairValueGaps, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCFVG *item = tmp[i]; + + // + bool isValid = IsPriceInsideZone( + lower, + item // + ); + if (!isValid) + { + // + ArrayRemove( + state.bullishFairValueGaps, + i, + 1 // + ); + } + } + + // + Clean(tmp); + } +} + +/** + * Detect Box Date of Specified Pivot ... + */ +bool DetectPivotStateBoxData( + XPVPivot &pivot, + double &peakUpper, + double &peakLower, + datetime &peakFrom, + datetime &peakTo, + double &valeUpper, + double &valeLower, + datetime &valeFrom, + datetime &valeTo // +) +{ + // + bool result = false; + + // + peakUpper = 0; + peakLower = 0; + valeUpper = 0; + valeLower = 0; + + // + peakFrom = NULL; + peakTo = NULL; + valeFrom = NULL; + valeTo = NULL; + + // + result = pivot.IsValid(); + if (!result) + { + return result; + } + + // + int count = 0; + + // + // + // + + // + // Resistance ... + count = pivot.state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + XCResistanceZone *tmp[]; + Copy( + pivot.state.resistanceZones, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *item = tmp[i]; + + // + if (peakUpper == 0 || + peakUpper < item.Upper()) + { + peakUpper = item.Upper(); + } + + // + if (peakLower == 0 || + peakLower > item.Lower()) + { + peakLower = item.Lower(); + } + + // + if (!IsValid(peakFrom) || + peakFrom > item.From()) + { + peakFrom = item.From(); + } + + // + if (!IsValid(peakTo) || + peakTo < item.To()) + { + peakTo = item.To(); + } + } + + // + Clean(tmp); + } + + // + // Supply ... + count = pivot.state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + XCSupplyZone *tmp[]; + Copy( + pivot.state.supplyZones, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *item = tmp[i]; + + // + if (peakUpper == 0 || + peakUpper < item.Upper()) + { + peakUpper = item.Upper(); + } + + // + if (peakLower == 0 || + peakLower > item.Lower()) + { + peakLower = item.Lower(); + } + + // + if (!IsValid(peakFrom) || + peakFrom > item.From()) + { + peakFrom = item.From(); + } + + // + if (!IsValid(peakTo) || + peakTo < item.To()) + { + peakTo = item.To(); + } + } + + // + Clean(tmp); + } + + // + // Bearish Order Block ... + count = pivot.state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + XCOrderBlock *tmp[]; + Copy( + pivot.state.bearishOrderBlocks, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *item = tmp[i]; + + // + if (peakUpper == 0 || + peakUpper < item.Upper()) + { + peakUpper = item.Upper(); + } + + // + if (peakLower == 0 || + peakLower > item.Lower()) + { + peakLower = item.Lower(); + } + + // + if (!IsValid(peakFrom) || + peakFrom > item.From()) + { + peakFrom = item.From(); + } + + // + if (!IsValid(peakTo) || + peakTo < item.To()) + { + peakTo = item.To(); + } + } + + // + Clean(tmp); + } + + // + // Bearish Fair Value Gap ... + count = pivot.state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + XCFVG *tmp[]; + Copy( + pivot.state.bearishFairValueGaps, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCFVG *item = tmp[i]; + + // + if (peakUpper == 0 || + peakUpper < item.Upper()) + { + peakUpper = item.Upper(); + } + + // + if (peakLower == 0 || + peakLower > item.Lower()) + { + peakLower = item.Lower(); + } + + // + if (!IsValid(peakFrom) || + peakFrom > item.From()) + { + peakFrom = item.From(); + } + + // + if (!IsValid(peakTo) || + peakTo < item.To()) + { + peakTo = item.To(); + } + } + + // + Clean(tmp); + } + + // + // + // + + // + // Support ... + count = pivot.state.CountSupportZones(); + if (IsValidSize(count)) + { + // + XCSupportZone *tmp[]; + Copy( + pivot.state.supportZones, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone *item = tmp[i]; + + // + if (valeUpper == 0 || + valeUpper < item.Upper()) + { + valeUpper = item.Upper(); + } + + // + if (valeLower == 0 || + valeLower > item.Lower()) + { + valeLower = item.Lower(); + } + + // + if (!IsValid(valeFrom) || + valeFrom > item.From()) + { + valeFrom = item.From(); + } + + // + if (!IsValid(valeTo) || + valeTo < item.To()) + { + valeTo = item.To(); + } + } + + // + Clean(tmp); + } + + // + // Demand ... + count = pivot.state.CountDemandZones(); + if (IsValidSize(count)) + { + // + XCDemandZone *tmp[]; + Copy( + pivot.state.demandZones, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone *item = tmp[i]; + + // + if (valeUpper == 0 || + valeUpper < item.Upper()) + { + valeUpper = item.Upper(); + } + + // + if (valeLower == 0 || + valeLower > item.Lower()) + { + valeLower = item.Lower(); + } + + // + if (!IsValid(valeFrom) || + valeFrom > item.From()) + { + valeFrom = item.From(); + } + + // + if (!IsValid(valeTo) || + valeTo < item.To()) + { + valeTo = item.To(); + } + } + + // + Clean(tmp); + } + + // + // Bullish Order Block ... + count = pivot.state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + XCOrderBlock *tmp[]; + Copy( + pivot.state.bullishOrderBlocks, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *item = tmp[i]; + + // + if (valeUpper == 0 || + valeUpper < item.Upper()) + { + valeUpper = item.Upper(); + } + + // + if (valeLower == 0 || + valeLower > item.Lower()) + { + valeLower = item.Lower(); + } + + // + if (!IsValid(valeFrom) || + valeFrom > item.From()) + { + valeFrom = item.From(); + } + + // + if (!IsValid(valeTo) || + valeTo < item.To()) + { + valeTo = item.To(); + } + } + + // + Clean(tmp); + } + + // + // Bullish Fair Value Gap ... + count = pivot.state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + XCFVG *tmp[]; + Copy( + pivot.state.bullishFairValueGaps, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCFVG *item = tmp[i]; + + // + if (valeUpper == 0 || + valeUpper < item.Upper()) + { + valeUpper = item.Upper(); + } + + // + if (valeLower == 0 || + valeLower > item.Lower()) + { + valeLower = item.Lower(); + } + + // + if (!IsValid(valeFrom) || + valeFrom > item.From()) + { + valeFrom = item.From(); + } + + // + if (!IsValid(valeTo) || + valeTo < item.To()) + { + valeTo = item.To(); + } + } + + // + Clean(tmp); + } + + // + result = peakUpper > 0 && + peakLower > 0 && + valeUpper > 0 && + valeLower > 0 && + IsValid(peakTo) && + IsValid(valeTo) && + IsValid(peakFrom) && + IsValid(valeFrom) && + peakTo > peakFrom && + valeTo > valeFrom && + peakUpper > peakLower && + valeUpper > valeLower; + + // + return result; +} + +/** + * Detect Price Inside Zones ... + * + * @param state: XPOIState instance Reference ... + * @param bar: XOHCL instance Reference ... + * @param hasSupport: Boolean ... + * @param hasResistanceZone: Boolean ... + * @param hasSupplyZone: Boolean ... + * @param hasDemandZone: Boolean ... + * @param hasOrderBlock: Boolean ... + * @param hasFairValueGap: Boolean ... + * @return ( bool ) + */ +bool DetectPriceInsideZones( + XPOIState &state, + XOHCL &bar, + int &zonesCount, + bool &hasSupportZone, + XCSupportZone *&supportZone, + bool &hasResistanceZone, + XCResistanceZone *&resistanceZone, + bool &hasSupplyZone, + XCSupplyZone *&supplyZone, + bool &hasDemandZone, + XCDemandZone *&demandZone, + bool &hasOrderBlock, + XCOrderBlock *&orderBlock, + bool &hasFairValueGap, + XCFVG *&fairValueGap // +) +{ + // + bool result = false; + + // + zonesCount = 0; + + // + hasSupportZone = false; + hasResistanceZone = false; + hasSupplyZone = false; + hasDemandZone = false; + hasOrderBlock = false; + hasFairValueGap = false; + + // + supportZone = NULL; + resistanceZone = NULL; + supplyZone = NULL; + demandZone = NULL; + orderBlock = NULL; + fairValueGap = NULL; + + // + datetime cTime = TimeCurrent(); + + // + result = bar.IsValid() && + state.IsValid() && + state.HasChild(); + if (!result) + { + return result; + } + + // + int count = 0; + + // + // Support Zone ... + count = state.CountSupportZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCSupportZone *iZone = state.supportZones[i]; + + // + bool isValid = IsPriceInsideZone(bar, iZone); + if (isValid) + { + // + supportZone = iZone; + } + } + + // + hasSupportZone = supportZone != NULL && + supportZone.IsValid(); + if (hasSupportZone) + { + // + zonesCount++; + supportZone.To(cTime); + } + } + + // + // Resistance Zone ... + count = state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCResistanceZone *iZone = state.resistanceZones[i]; + + // + bool isValid = IsPriceInsideZone(bar, iZone); + if (isValid) + { + // + resistanceZone = iZone; + } + } + + // + hasResistanceZone = resistanceZone != NULL && + resistanceZone.IsValid(); + if (hasResistanceZone) + { + // + zonesCount++; + resistanceZone.To(cTime); + } + } + + // + // Supply Zone ... + count = state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCSupplyZone *iZone = state.supplyZones[i]; + + // + bool isValid = IsPriceInsideZone(bar, iZone); + if (isValid) + { + // + supplyZone = iZone; + } + } + + // + hasSupplyZone = supplyZone != NULL && + supplyZone.IsValid(); + if (hasSupplyZone) + { + // + zonesCount++; + supplyZone.To(cTime); + } + } + + // + // Demand Zone ... + count = state.CountDemandZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCDemandZone *iZone = state.demandZones[i]; + + // + bool isValid = IsPriceInsideZone(bar, iZone); + if (isValid) + { + // + demandZone = iZone; + } + } + + // + hasDemandZone = demandZone != NULL && + demandZone.IsValid(); + if (hasDemandZone) + { + // + zonesCount++; + demandZone.To(cTime); + } + } + + // + // OrderBlock ... + count = state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCOrderBlock *iZone = state.bullishOrderBlocks[i]; + + // + bool isValid = IsPriceInsideZone(bar, iZone); + if (isValid) + { + // + orderBlock = iZone; + } + } + + // + hasOrderBlock = orderBlock != NULL && + orderBlock.IsValid(); + if (hasOrderBlock) + { + // + zonesCount++; + orderBlock.To(cTime); + } + } + if (!hasOrderBlock) + { + // + count = state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCOrderBlock *iZone = state.bearishOrderBlocks[i]; + + // + bool isValid = IsPriceInsideZone(bar, iZone); + if (isValid) + { + // + orderBlock = iZone; + } + } + + // + hasOrderBlock = orderBlock != NULL && + orderBlock.IsValid(); + if (hasOrderBlock) + { + // + zonesCount++; + orderBlock.To(cTime); + } + } + } + + // + // Fair Value Gap ... + count = state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCFVG *iZone = state.bullishFairValueGaps[i]; + + // + bool isValid = IsPriceInsideZone(bar, iZone); + if (isValid) + { + // + fairValueGap = iZone; + } + } + + // + hasFairValueGap = fairValueGap != NULL && + fairValueGap.IsValid(); + if (hasFairValueGap) + { + // + zonesCount++; + fairValueGap.To(cTime); + } + } + if (!hasFairValueGap) + { + // + count = state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCFVG *iZone = state.bearishFairValueGaps[i]; + + // + bool isValid = IsPriceInsideZone(bar, iZone); + if (isValid) + { + // + fairValueGap = iZone; + } + } + + // + hasFairValueGap = fairValueGap != NULL && + fairValueGap.IsValid(); + if (hasFairValueGap) + { + // + zonesCount++; + fairValueGap.To(cTime); + } + } + } + + // + result = + // + hasSupportZone || + hasResistanceZone || + hasSupplyZone || + hasDemandZone || + hasOrderBlock || + hasFairValueGap + // + ; + + // + return result; +} + +/** + * Detect Price Inside Zones ... + * + * @param state: XPOIState instance Reference ... + * @param price: Double ... + * @param hasSupport: Boolean ... + * @param hasResistanceZone: Boolean ... + * @param hasSupplyZone: Boolean ... + * @param hasDemandZone: Boolean ... + * @param hasOrderBlock: Boolean ... + * @param hasFairValueGap: Boolean ... + * @return ( bool ) + */ +bool DetectPriceInsideZones( + XPOIState &state, + double price, + int &zonesCount, + bool &hasSupportZone, + XCSupportZone *&supportZone, + bool &hasResistanceZone, + XCResistanceZone *&resistanceZone, + bool &hasSupplyZone, + XCSupplyZone *&supplyZone, + bool &hasDemandZone, + XCDemandZone *&demandZone, + bool &hasOrderBlock, + XCOrderBlock *&orderBlock, + bool &hasFairValueGap, + XCFVG *&fairValueGap // +) +{ + // + bool result = false; + + // + zonesCount = 0; + + // + hasSupportZone = false; + hasResistanceZone = false; + hasSupplyZone = false; + hasDemandZone = false; + hasOrderBlock = false; + hasFairValueGap = false; + + // + supportZone = NULL; + resistanceZone = NULL; + supplyZone = NULL; + demandZone = NULL; + orderBlock = NULL; + fairValueGap = NULL; + + // + datetime cTime = TimeCurrent(); + + // + result = price > 0 && + state.IsValid() && + state.HasChild(); + if (!result) + { + return result; + } + + // + int count = 0; + + // + // Support Zone ... + count = state.CountSupportZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCSupportZone *iZone = state.supportZones[i]; + + // + bool isValid = IsPriceInsideZone(price, iZone); + if (isValid) + { + // + supportZone = iZone; + } + } + + // + hasSupportZone = supportZone != NULL && + supportZone.IsValid(); + if (hasSupportZone) + { + // + zonesCount++; + supportZone.To(cTime); + } + } + + // + // Resistance Zone ... + count = state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCResistanceZone *iZone = state.resistanceZones[i]; + + // + bool isValid = IsPriceInsideZone(price, iZone); + if (isValid) + { + // + resistanceZone = iZone; + } + } + + // + hasResistanceZone = resistanceZone != NULL && + resistanceZone.IsValid(); + if (hasResistanceZone) + { + // + zonesCount++; + resistanceZone.To(cTime); + } + } + + // + // Supply Zone ... + count = state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCSupplyZone *iZone = state.supplyZones[i]; + + // + bool isValid = IsPriceInsideZone(price, iZone); + if (isValid) + { + // + supplyZone = iZone; + } + } + + // + hasSupplyZone = supplyZone != NULL && + supplyZone.IsValid(); + if (hasSupplyZone) + { + // + zonesCount++; + supplyZone.To(cTime); + } + } + + // + // Demand Zone ... + count = state.CountDemandZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCDemandZone *iZone = state.demandZones[i]; + + // + bool isValid = IsPriceInsideZone(price, iZone); + if (isValid) + { + // + demandZone = iZone; + } + } + + // + hasDemandZone = demandZone != NULL && + demandZone.IsValid(); + if (hasDemandZone) + { + // + zonesCount++; + demandZone.To(cTime); + } + } + + // + // OrderBlock ... + count = state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCOrderBlock *iZone = state.bullishOrderBlocks[i]; + + // + bool isValid = IsPriceInsideZone(price, iZone); + if (isValid) + { + // + orderBlock = iZone; + } + } + + // + hasOrderBlock = orderBlock != NULL && + orderBlock.IsValid(); + if (hasOrderBlock) + { + // + zonesCount++; + orderBlock.To(cTime); + } + } + if (!hasOrderBlock) + { + // + count = state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCOrderBlock *iZone = state.bearishOrderBlocks[i]; + + // + bool isValid = IsPriceInsideZone(price, iZone); + if (isValid) + { + // + orderBlock = iZone; + } + } + + // + hasOrderBlock = orderBlock != NULL && + orderBlock.IsValid(); + if (hasOrderBlock) + { + // + zonesCount++; + orderBlock.To(cTime); + } + } + } + + // + // Fair Value Gap ... + count = state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCFVG *iZone = state.bullishFairValueGaps[i]; + + // + bool isValid = IsPriceInsideZone(price, iZone); + if (isValid) + { + // + fairValueGap = iZone; + } + } + + // + hasFairValueGap = fairValueGap != NULL && + fairValueGap.IsValid(); + if (hasFairValueGap) + { + // + zonesCount++; + fairValueGap.To(cTime); + } + } + if (!hasFairValueGap) + { + // + count = state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCFVG *iZone = state.bearishFairValueGaps[i]; + + // + bool isValid = IsPriceInsideZone(price, iZone); + if (isValid) + { + // + fairValueGap = iZone; + } + } + + // + hasFairValueGap = fairValueGap != NULL && + fairValueGap.IsValid(); + if (hasFairValueGap) + { + // + zonesCount++; + fairValueGap.To(cTime); + } + } + } + + // + result = + // + hasSupportZone || + hasResistanceZone || + hasSupplyZone || + hasDemandZone || + hasOrderBlock || + hasFairValueGap + // + ; + + // + return result; +} + +bool CalculatePriceInsideZones( + XPriceZones &zone, + XPOIState &state, + double price // +) +{ + // + bool result = false; + + // + zone.Clean(); + + // + int zonesCount = 0; + bool hasSupplyZone = false; + bool hasDemandZone = false; + bool hasOrderBlock = false; + bool hasSupportZone = false; + bool hasFairValueGap = false; + bool hasResistanceZone = false; + + // + result = DetectPriceInsideZones( + state, + price, + zone.count, + hasSupportZone, + zone.supportZone, + hasResistanceZone, + zone.resistanceZone, + hasSupplyZone, + zone.supplyZone, + hasDemandZone, + zone.demandZone, + hasOrderBlock, + zone.orderBlock, + hasFairValueGap, + zone.fairValueGap // + ); + if (!result) + { + return result; + } + + // + zone.price = price; + + // + result = zone.IsValid(); + + // + return result; +} + +bool CalculatePriceInsideZones( + XPriceZones &zone, + XPOIState &state, + XOHCL &bar // +) +{ + // + bool result = false; + + // + zone.Clean(); + + // + int zonesCount = 0; + bool hasSupplyZone = false; + bool hasDemandZone = false; + bool hasOrderBlock = false; + bool hasSupportZone = false; + bool hasFairValueGap = false; + bool hasResistanceZone = false; + + // + result = DetectPriceInsideZones( + state, + bar, + zone.count, + hasSupportZone, + zone.supportZone, + hasResistanceZone, + zone.resistanceZone, + hasSupplyZone, + zone.supplyZone, + hasDemandZone, + zone.demandZone, + hasOrderBlock, + zone.orderBlock, + hasFairValueGap, + zone.fairValueGap // + ); + if (!result) + { + return result; + } + + // + zone.bar = bar; + + // + result = zone.IsValid(); + + // + return result; +} + +/** + * Calculate Zone by Providing Specified Data ... + * + * @param zones: XStateZone instance Reference ... + * @param source: XPOIState instance Reference ... + * @param upper: Double ... + * @param lower: Double ... + * @param from: DateTime ... + * + * @return ( bool ) + */ +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 ... + * + * @param item: XValueChange instance Reference ... + * @param items: XValueChange instance Array Reference ... + * + * @return ( int ) + */ +int AddIfNotExists( + XValueChange &item, + XValueChange &items[] // +) +{ + // + int result = 0; + + // + result = item.IsValid(); + if (!result) + { + return result; + } + + // + bool canAdd = false; + int count = ArraySize(items); + if (!IsValidSize(count)) + { + canAdd = true; + } + else + { + // + XValueChange last; + bool hasItem = GetLastItem( + last, + items // + ); + if (!hasItem) + { + canAdd = true; + } + else + { + // + // Compare Last Item with Current ... + canAdd = item.time > last.time; + } + } + + // + // Add Item if Allowed ... + if (canAdd) + { + // + AddRef( + item, + items // + ); + } + + // + result = ArraySize(items); + + // + return result; +} + +///////////////////////////////////////////////////////////////////////// + +// +// +// + +// +// Pivot Types ... +enum ENUM_XPV_PIVOTS +{ + XPV_NONE, + XPV_PEAK, + XPV_VALE, +}; + +// +// Model a Pivot structure ... +struct XPVPivot +{ + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double upper; + double lower; + + // + datetime from; + datetime to; + + // + int repetition; + + // + ENUM_XPV_PIVOTS type; + + // + // Combined all States ... + XPOIState state; + + // + XPVPivot() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + upper = 0; + lower = 0; + + // + to = NULL; + from = NULL; + symbol = NULL; + period = NULL; + + // + repetition = 0; + + // + type = XPV_NONE; + + // + state.Clean(); + + // + ZeroMemory(this); + } + + /** + * Validation ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(to) && + IsValid(from) && + IsValid(symbol) && + IsValid(period) && + repetition > 0 && + type != XPV_NONE && + (upper > 0 || lower > 0) + // + ; + + // + return result; + } + + /** + * Check Pivot is Peak ... + * + * @return ( bool ) + */ + bool IsPeak() + { + // + bool result = false; + + // + result = IsValid() && + type == XPV_PEAK; + + // + return result; + } + + /** + * Check Pivot is Vale ... + * + * @return ( bool ) + */ + bool IsVale() + { + // + bool result = false; + + // + result = IsValid() && + type == XPV_VALE; + + // + return result; + } + + /** + * Calculate Lower for Peaks ... + * + * @return ( double ) + */ + double CalculateLower() + { + // + double result = 0; + + // + if (!IsValid() || + !IsPeak()) + { + return result; + } + + // + int fromIndex = iBarShift( + symbol, + period, + from // + ); + + // + int toIndex = iBarShift( + symbol, + period, + to // + ); + + // + int count = + fromIndex - toIndex; + + // + int llIDX = iLowest( + symbol, + period, + MODE_LOW, + count, + toIndex // + ); + + // + result = + iLow( + symbol, + period, + llIDX // + ); + + // + return result; + } + + /** + * Calculate Upper for Vales ... + * + * @return ( double ) + */ + double CalculateUpper() + { + // + double result = 0; + + // + if (!IsValid() || + !IsVale()) + { + return result; + } + + // + int fromIndex = iBarShift( + symbol, + period, + from // + ); + + // + int toIndex = iBarShift( + symbol, + period, + to // + ); + + // + int count = + fromIndex - toIndex; + + // + int hhIDX = iHighest( + symbol, + period, + MODE_HIGH, + count, + toIndex // + ); + + // + result = + iHigh( + symbol, + period, + hhIDX // + ); + + // + return result; + } + + /** + * Calculate Range of Pivot ... + * + * @return ( double ) + */ + double CalculateRange() + { + // + double result = 0; + + // + if (!IsValid() || + upper <= 0 || + lower <= 0) + { + return result; + } + + // + result = upper - lower; + + // + return result; + } + + /** + * Calculate Middle of Pivot ... + * Used for + * @return ( double ) + */ + double CalculateMid() + { + // + double result = 0; + + // + double range = CalculateRange(); + if (range <= 0) + { + return result; + } + + // + result = lower + (range / 2); + + // + return result; + } + + /** + * Calculate Liquidity Percent for Specified Direction ... + * + * @param forDirection: ENUM_X_DIRECTION member, Specified Liquidity ... + * @param price: Double, Specified Price ... + * + * @return ( double ) + */ + double CalculateLiquidityPercent( + ENUM_X_DIRECTION forDirection, + double price = 0 // + ) + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = state + .CalculateLiquidityPercent( + forDirection, + price // + ); + + // + return result; + } + + /** + * Check Price in Premium or not ... + * + * @return ( bool ) + */ + bool IsPriceInPremium() + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + + // + double mid = CalculateMid(); + + // + result = + // + ask > mid && + bid > mid + // + ; + + // + return result; + } + + /** + * Check Price in Discount or not ... + * + * @return ( bool ) + */ + bool IsPriceInDiscount() + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + + // + double mid = CalculateMid(); + + // + result = + // + ask > mid && + bid > mid + // + ; + + // + return result; + } + + // + + /** + * Get Unique Identifier ... + * + * @return ( string ) + */ + string GetTag() + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + string hash = symbol + "_" + + ToString(period) + "_" + + ToString(upper) + "," + + ToString(lower) + "_" + + ToString(from) + "," + + ToString(to); + hash = ToMD5(hash); + + // + string typeStr = + type == XPV_PEAK + ? "Peak" + : "Vale"; + + // + result = + // + "XPV_" + + typeStr + "_" + + symbol + "_" + + ToString(period) + + "_" + hash + // + ; + + // + return result; + } + + // +}; + +// +// Pivots ... +struct XPVPivotPoint +{ + // + // Props ... + double value; + int repetition; + datetime time; + ENUM_XPV_PIVOTS type; + + // + // Constructor ... + XPVPivotPoint() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + value = 0; + time = NULL; + repetition = 0; + type = XPV_NONE; + + // + ZeroMemory(this); + } + + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + value > 0 && + IsValid(time) && + repetition > 0 && + type != XPV_NONE + // + ; + + // + return result; + } + + /** + * Check current Pivot Point is Peak or not ... + * + * @return ( bool ) + */ + bool IsPeak() + { + // + bool result = false; + + // + result = IsValid() && + type == XPV_PEAK; + + // + return result; + } + + /** + * Check current Pivot Point is Vale or not ... + * + * @return ( bool ) + */ + bool IsVale() + { + // + bool result = false; + + // + result = IsValid() && + type == XPV_VALE; + + // + return result; + } + + // +}; + +// +// +// + +// +// Model Value Changed ... +struct XValueChange +{ + // + // Props ... + double before; // Before Change Value ... + double after; // After Change Value ... + datetime time; // Change Time ... + ENUM_X_DIRECTION dir; // Change Direction ... + + // + // Constructor ... + XValueChange() + { + Clean(); + } + + // + // Tools ... + + /** + * Initialize ... + * + * @param _before: Double, Value Before Change ... + * @param _after: Double, Value After Change ... + * @param _time: Datetime, Change Time ... + * @param _dir: ENUM_X_DIRECTION member, Specified Changed Direction ... + * + * @return ( bool ) + */ + bool Init( + double _before, // Before Change Value ... + double _after, // After Change Value ... + ENUM_X_DIRECTION _dir, // Change Direction ... + datetime _time = NULL // Change Time ... + ) + { + // + bool result = false; + + // + _time = NormalizeTime(_time); + + // + // Validate Inputs ... + result = + // + _after > 0 && + _before > 0 && + IsValid(_time) && + _after != _before && + HasDirection(_dir) + // + ; + if (!result) + { + return result; + } + + // + // Set Validated Values ... + dir = _dir; + time = _time; + after = _after; + before = _before; + + // + result = IsValid(); + + // + return result; + } + + /** + * Cleaning Up ... + */ + void Clean() + { + // + after = 0; + before = 0; + time = NULL; + dir = X_DIRECTION_NONE; + + // + ZeroMemory(this); + } + + /** + * Validate Model ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + after > 0 && + before > 0 && + IsValid(time) && + after != before && + HasDirection(dir) + // + ; + + // + return result; + } + + /** + * Fill Change Bar ... + * + * @param bar: XOHCL instance Reference, holds Change Bar ... + * @param _symbol: String, Specified Symbol ... + * @param _period: ENUM_TIMEFRAMES _period member, Specified Period ... + * + * @return ( bool ) + */ + bool FillBar( + XOHCL &bar, + string _symbol = NULL, + ENUM_TIMEFRAMES _period = NULL // + ) + { + // + bool result = false; + + // + bar.Clean(); + _symbol = NormalizeSymbol(_symbol); + _period = NormalizePeriod(_period); + + // + result = IsValid() && + IsValid(_symbol) && + IsValid(_period); + if (!result) + { + return result; + } + + // + result = bar.Init( + _symbol, + _period, + time // + ); + + // + return result; + } + + // +}; + +// +// Price Zones Model ... +struct XPriceZones +{ + // + XOHCL bar; // if Based On Bar it's Filled ... + double price; // if Based on Price, it's Filled ... + + // + int count; // Exists Zones Count ... + + // + XCFVG *fairValueGap; // Exists Fair Value Gap ... + XCSupplyZone *supplyZone; // Exists Supply Zone ... + XCDemandZone *demandZone; // Exists Demand Zone ... + XCOrderBlock *orderBlock; // Exists Order Block ... + XCSupportZone *supportZone; // Exists Support Zone ... + XCResistanceZone *resistanceZone; // Exists Resistance Zone ...Ù‘ + + // + // Constructor ... + XPriceZones() + { + Clean(); + } + + /** + * Cleanup ... + */ + void Clean() + { + // + bar.Clean(); + price = 0; + + // + supplyZone = NULL; + demandZone = NULL; + orderBlock = NULL; + supportZone = NULL; + fairValueGap = NULL; + resistanceZone = NULL; + + // + ZeroMemory(this); + } + + /** + * Check Zone is Valid ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + (IsBasedOnBar() || + IsBasedOnPrice()) && + IsValidSize(count) + // + ; + + // + return result; + } + + /** + * Check Zones Base on Bar ... + * + * @return ( bool ) + */ + bool IsBasedOnBar() + { + return bar.IsValid(); + } + + /** + * Check Zones Based on Price ... + * + * @return ( bool ) + */ + bool IsBasedOnPrice() + { + return price > 0; + } + + /** + * Check Has Supply Zone ... + * + * @return ( bool ) + */ + bool HasSupplyZone() + { + // + return IsValidSize(count) && + supplyZone != NULL && + supplyZone.IsValid(); + } + + /** + * Check Has Demand Zone ... + * + * @return ( bool ) + */ + bool HasDemandZone() + { + // + return IsValidSize(count) && + demandZone != NULL && + demandZone.IsValid(); + } + + /** + * Check Has OrderBlock ... + * + * @return ( bool ) + */ + bool HasOrderBlock() + { + // + return IsValidSize(count) && + orderBlock != NULL && + orderBlock.IsValid(); + } + + /** + * Check Has Support Zone ... + * + * @return ( bool ) + */ + bool HasSupportZone() + { + // + return IsValidSize(count) && + supportZone != NULL && + supportZone.IsValid(); + } + + /** + * Check Has FairValueGap ... + * + * @return ( bool ) + */ + bool HasFairValueGap() + { + // + return IsValidSize(count) && + fairValueGap != NULL && + fairValueGap.IsValid(); + } + + /** + * Check Has Resistance Zone ... + * + * @return ( bool ) + */ + bool HasResistanceZone() + { + // + return IsValidSize(count) && + resistanceZone != NULL && + resistanceZone.IsValid(); + } + + /** + * Check Zones are Overal Bullish ... + * + * @return ( bool ) + */ + bool IsBullish() + { + // + bool result = false; + + // + result = + // + HasDemandZone() + // + || + // + HasSupportZone() + // + || + // + (HasOrderBlock() && + orderBlock.IsBullish()) + // + || + // + (HasFairValueGap() && + fairValueGap.IsBullish()) + // + ; + + // + return result; + } + + /** + * Check Zones are Overal Bearish ... + * + * @return ( bool ) + */ + bool IsBearish() + { + // + bool result = false; + + // + result = + // + HasSupplyZone() + // + || + // + HasResistanceZone() + // + || + // + (HasOrderBlock() && + orderBlock.IsBearish()) + // + || + // + (HasFairValueGap() && + fairValueGap.IsBearish()) + // + ; + + // + return result; + } + + /** + * Fill Zones Based On required Direction ... + * + * @param dir: ENUM_X_DIRECTION member ... + * + * @return ( int ) + */ + int FillZones( + ENUM_X_DIRECTION dir, + XCZone *&zones[] // + ) + { + // + int result = 0; + + // + Clean(zones); + + // + bool isBullish = IsBullish(dir); + bool isBoth = dir == X_DIRECTION_ALL || + dir == X_DIRECTION_NONE; + + // + if (isBoth || isBullish) + { + // + if (HasSupportZone()) + { + // + Add( + (XCZone *)supportZone, + zones // + ); + } + + // + if (HasDemandZone()) + { + // + Add( + (XCZone *)demandZone, + zones // + ); + } + + // + if (HasOrderBlock() && + orderBlock.IsBullish()) + { + // + Add( + (XCZone *)orderBlock, + zones // + ); + } + + // + if (HasFairValueGap() && + fairValueGap.IsBullish()) + { + // + Add( + (XCZone *)fairValueGap, + zones // + ); + } + } + + // + if (isBoth || !isBullish) + { + // + if (HasResistanceZone()) + { + // + Add( + (XCZone *)resistanceZone, + zones // + ); + } + + // + if (HasSupplyZone()) + { + // + Add( + (XCZone *)supplyZone, + zones // + ); + } + + // + if (HasOrderBlock() && + orderBlock.IsBearish()) + { + // + Add( + (XCZone *)orderBlock, + zones // + ); + } + + // + if (HasFairValueGap() && + fairValueGap.IsBearish()) + { + // + Add( + (XCZone *)fairValueGap, + zones // + ); + } + } + + // s + result = ArraySize(zones); + + // + return result; + } + + /** + * Calculate Boundary of Zones ... + * + * @param dir: ENUM_X_DIRECTION Member, Specified Direction ... + * @param upper: Double ... + * @param lower: Double ... + * + * @return ( bool ) + */ + bool GetBoundary( + ENUM_X_DIRECTION dir, + double &upper, + double &lower // + ) + { + // + bool result = false; + + // + upper = 0; + lower = 0; + + // + XCZone *zones[]; + int mCount = FillZones(dir, zones); + result = IsValidSize(mCount); + if (!result) + { + return result; + } + + // + for (int i = 0; i < mCount; i++) + { + // + XCZone *iZone = zones[i]; + + // + double iUpper = iZone.Upper(); + double iLower = iZone.Lower(); + + // + upper = + upper == 0 + ? iUpper + : iUpper > upper + ? iUpper + : upper; + + // + lower = + lower == 0 + ? iLower + : iLower < lower + ? iLower + : lower; + } + + // + return result; + } + + /** + * Calculate Lifetime of Zones ... + * + * @param dir: ENUM_X_DIRECTION Member, Specified Direction ... + * @param from: DateTime ... + * @param to: DateTime ... + * + * @return ( bool ) + */ + bool GetLifetime( + ENUM_X_DIRECTION dir, + datetime &from, + datetime &to // + ) + { + // + bool result = false; + + // + to = NULL; + from = NULL; + + // + XCZone *zones[]; + int mCount = FillZones(dir, zones); + result = IsValidSize(mCount); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(dir); + bool isAll = dir == X_DIRECTION_NONE || + dir == X_DIRECTION_ALL; + + // + if (isAll || isBullish) + { + // + // Support Zone ... + bool hasSupportZone = HasSupportZone(); + if (hasSupportZone) + { + // + XCSupportZone *zone = supportZone; + + // + from = + !IsValid(from) || + from > zone.From() + ? zone.From() + : from; + + // + to = + !IsValid(to) || + to < zone.To() + ? zone.To() + : from; + } + + // + // Demand Zone ... + bool hasDemandZone = HasDemandZone(); + if (hasDemandZone) + { + // + XCDemandZone *zone = demandZone; + + // + from = + !IsValid(from) || + from > zone.From() + ? zone.From() + : from; + + // + to = + !IsValid(to) || + to < zone.To() + ? zone.To() + : from; + } + + // + // Order Block ... + bool hasOrderBlock = HasOrderBlock() && + orderBlock.IsBullish(); + if (hasOrderBlock) + { + // + XCOrderBlock *zone = orderBlock; + + // + from = + !IsValid(from) || + from > zone.From() + ? zone.From() + : from; + + // + to = + !IsValid(to) || + to < zone.To() + ? zone.To() + : from; + } + + // + // Fair Value Gap ... + bool hasFairValueGap = HasFairValueGap() && + fairValueGap.IsBullish(); + if (hasFairValueGap) + { + // + XCFVG *zone = fairValueGap; + + // + from = + !IsValid(from) || + from > zone.From() + ? zone.From() + : from; + + // + to = + !IsValid(to) || + to < zone.To() + ? zone.To() + : from; + } + } + + // + if (isAll || !isBullish) + { + // + // Resistance Zone ... + bool hasResistanceZone = HasResistanceZone(); + if (hasResistanceZone) + { + // + XCResistanceZone *zone = resistanceZone; + + // + from = + !IsValid(from) || + from > zone.From() + ? zone.From() + : from; + + // + to = + !IsValid(to) || + to < zone.To() + ? zone.To() + : from; + } + + // + // Supply Zone ... + bool hasSupplyZone = HasSupplyZone(); + if (hasSupplyZone) + { + // + XCSupplyZone *zone = supplyZone; + + // + from = + !IsValid(from) || + from > zone.From() + ? zone.From() + : from; + + // + to = + !IsValid(to) || + to < zone.To() + ? zone.To() + : from; + } + + // + // Order Block ... + bool hasOrderBlock = HasOrderBlock() && + orderBlock.IsBearish(); + if (hasOrderBlock) + { + // + XCOrderBlock *zone = orderBlock; + + // + from = + !IsValid(from) || + from > zone.From() + ? zone.From() + : from; + + // + to = + !IsValid(to) || + to < zone.To() + ? zone.To() + : from; + } + + // + // Fair Value Gap ... + bool hasFairValueGap = HasFairValueGap() && + fairValueGap.IsBearish(); + if (hasFairValueGap) + { + // + XCFVG *zone = fairValueGap; + + // + from = + !IsValid(from) || + from > zone.From() + ? zone.From() + : from; + + // + to = + !IsValid(to) || + to < zone.To() + ? zone.To() + : from; + } + } + + // + result = + to > from && + IsValid(to) && + IsValid(from); + + // + return result; + } + + /** + * Calculate Box Model Data ... + * + * @param dir: ENUM_X_DIRECTION Member, Specified Direction ... + * @param upper: Double ... + * @param lower: Double ... + * @param from: DateTime ... + * @param to: DateTime ... + * + * @return ( bool ) + */ + bool GetBoxData( + ENUM_X_DIRECTION dir, + double &upper, + double &lower, + datetime &from, + datetime &to // + ) + { + // + bool result = false; + + // + bool hasBoundary = GetBoundary( + dir, + upper, + lower // + ); + + // + bool hasLifetime = GetLifetime( + dir, + from, + to // + ); + + // + result = + hasBoundary && + hasLifetime; + + // + return result; + } + + // +}; + +// +// Market Strucutre Model ... +struct XMarketStructure +{ + // + string symbol; + ENUM_TIMEFRAMES period; + + // + ENUM_X_DIRECTION bias; + + // + XPVPivotPoint vales[]; + XPriceZones valePriceZones[]; + + // + XPVPivotPoint peaks[]; + XPriceZones peakPriceZones[]; + + // + XOHCL lowestValeBar; + XOHCL lowestValePeakBreakeUpBar; + XOHCL valeAboveLowestValePeakBar; + + // + XOHCL highestPeakBar; + XOHCL peakBelowHighestPeakValeBar; + XOHCL highestPeakValeBreakeDownBar; + + // + XMarketStructure() + { + Clean(); + } + + /** + * Cleanup ... + */ + void Clean() + { + // + symbol = NULL; + period = NULL; + bias = X_DIRECTION_NONE; + + // + Clean(vales); + Clean(peaks); + Clean(valePriceZones); + Clean(peakPriceZones); + + // + lowestValeBar.Clean(); + lowestValePeakBreakeUpBar.Clean(); + valeAboveLowestValePeakBar.Clean(); + + // + highestPeakBar.Clean(); + peakBelowHighestPeakValeBar.Clean(); + highestPeakValeBreakeDownBar.Clean(); + + // + ZeroMemory(this); + } + + /** + * Validate Model ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + IsValid(symbol) && + IsValid(period) && + bias != X_DIRECTION_NONE; + + // + return result; + } + + /** + * Check Bullish Trend ... + * + * @return ( bool ) + */ + bool IsBullish() + { + // + bool result = false; + + // + result = + // + IsValid() && + IsBullish(bias) && + HasChild(peaks) && + HasDirection(bias) && + lowestValeBar.IsValid() && + HasChild(peakPriceZones) && + lowestValePeakBreakeUpBar.IsValid() && + valeAboveLowestValePeakBar.IsValid() + // + ; + + // + return result; + } + + /** + * Check Bearish Trend ... + * + * @return ( bool ) + */ + bool IsBearish() + { + // + bool result = false; + + // + result = + // + IsValid() && + IsBearish(bias) && + HasChild(vales) && + HasDirection(bias) && + highestPeakBar.IsValid() && + HasChild(valePriceZones) && + peakBelowHighestPeakValeBar.IsValid() && + highestPeakValeBreakeDownBar.IsValid() + // + ; + + // + return result; + } + + /** + * Check Has Trend ... + * + * @return ( bool ) + */ + bool HasTrend() + { + // + bool result = false; + + // + result = IsValid() && + (IsBullish() || + IsBearish()); + + // + return result; + } + + // +}; + +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); + + // + ZeroMemory(this); + } + + /** + * 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; + + // + result = ArraySize(supportZones); + + // + return result; + } + + // + int CountResistanceZones() + { + // + int result = 0; + + // + result = ArraySize(resistanceZones); + + // + return result; + } + + // + int CountSupplyZones() + { + // + int result = 0; + + // + result = ArraySize(supplyZones); + + // + return result; + } + + // + int CountDemandZones() + { + // + int result = 0; + + // + result = ArraySize(demandZones); + + // + return result; + } + + // + int CountBullishOrderBlocks() + { + // + int result = 0; + + // + result = ArraySize(bullishOrderBlocks); + + // + return result; + } + + // + int CountBearishOrderBlocks() + { + // + int result = 0; + + // + result = ArraySize(bearishOrderBlocks); + + // + return result; + } + + // + int CountBullishFairValueGaps() + { + // + int result = 0; + + // + result = ArraySize(bullishFairValueGaps); + + // + return result; + } + + // + int CountBearishFairValueGaps() + { + // + int result = 0; + + // + result = ArraySize(bearishFairValueGaps); + + // + return result; + } +}; + +struct XFVGOrderBlock +{ + // + // Props ... + XCOrderBlock *orderBlock; + XCFVG *fairValueGap; + // XStateZones stateZones; + + // + XFVGOrderBlock() + { + Clean(); + } + + /** + * Cleanup Model ... + */ + void Clean() + { + // + orderBlock = NULL; + fairValueGap = NULL; + + // + ZeroMemory(this); + } + + /** + * Validate Model ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + orderBlock != NULL && + fairValueGap != NULL && + // stateZones.IsValid() && + ((orderBlock.IsBullish() && + fairValueGap.IsBullish()) || + ((orderBlock.IsBearish() && + fairValueGap.IsBearish()))) + // + ; + + // + return result; + } + + /** + * Get Model Direction ... + * + * @param dir: ENUM_X_DIRECTION member ... + * + * @return ( bool ) + */ + bool GetDirection( + ENUM_X_DIRECTION &dir // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + dir = orderBlock.IsBullish() + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; + } + + /** + * Retrieve Boundary of Zone ... + * + * @param upper: Upper Boundary ...Ù‘ + * @param lower: Lower Bondary ... + * @return ( bool ) + */ + bool GetBoundary( + double &upper, + double &lower // + ) + { + // + bool result = false; + + // + upper = 0; + lower = 0; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + upper = orderBlock.Upper(); + upper = MathMax(upper, fairValueGap.Upper()); + + // + lower = orderBlock.Lower(); + lower = MathMax(lower, fairValueGap.Lower()); + + // + result = lower > 0 && + upper > 0 && + upper > lower; + + // + return result; + } + + /** + * Check Model is same as another Istance ... + * + * @param value: XFVGOrderBlock instance Reference ... + * + * @return ( bool ) + */ + bool IsSameAs(XFVGOrderBlock &value) + { + // + bool result = false; + + // + result = + IsValid() && + value.IsValid(); + if (!result) + { + return result; + } + + // + ENUM_X_DIRECTION dir; + result = GetDirection(dir); + if (!result) + { + return result; + } + + // + ENUM_X_DIRECTION valueDir; + result = value.GetDirection(valueDir); + if (!result) + { + return result; + } + + // + result = + // + dir == valueDir + // + && + // + orderBlock.From() == value.orderBlock.From() && + orderBlock.Upper() == value.orderBlock.Upper() && + orderBlock.Lower() == value.orderBlock.Lower() + // + && + // + fairValueGap.From() == value.fairValueGap.From() && + fairValueGap.Upper() == value.fairValueGap.Upper() && + fairValueGap.Lower() == value.fairValueGap.Lower() + // + ; + + // + return result; + } + // +}; + +// +// +// + +// +// XPVPivot Object ... +class XCXPVPivotObject : public XCBaseObject +{ + // + public: + // + + /** + * Creator ... + * + * @param chart_id: Long, Specified Chart ID ... + * @param window: Integer, Specified Chart Window ID ... + * @param pivot: XPVPivot instance ... + * @param prefix: String ... + * + * @return ( bool ) + */ + bool Create( + long chart_id, + int window, + XPVPivot &pivot, + string prefix = NULL // + ) + { + // + bool result = false; + + // + result = pivot.IsValid(); + if (!result) + { + return result; + } + + // + string name = pivot.GetTag(); + if (IsValid(prefix)) + { + name = prefix + "_" + name; + } + + // + result = mRect.Create( + chart_id, + name, + window, + pivot.from, + pivot.upper, + pivot.to, + pivot.lower // + ); + + // + if (result) + { + ObjName(name); + } + + // + string mTrendName = "MID_" + name; + double mid = pivot.CalculateMid(); + result = mTrend.Create( + chart_id, + mTrendName, + window, + pivot.from, + mid, + pivot.to, + mid // + ); + if (!result) + { + // + mRect.Delete(); + mRect.Detach(); + } + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + /** + * Set Pivot Width ... + * + * @param value: Integer ... + */ + void PivotWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + mRect.Width(value); + mTrend.Width(value); + } + + /** + * Set Pivot Color ... + * + * @param value: Color ... + */ + void PivotColor(color value) + { + // + mRect.Color(value); + mTrend.Color(value); + } + + /** + * Set Pivot Style ... + * + * @param value: ENUM_LINE_STYLE member ... + */ + void PivotStyle(ENUM_LINE_STYLE value) + { + // + mRect.Style(value); + mTrend.Style(value); + } + + /** + * Set Pivot Fill ... + * + * @param value: Boolean ... + */ + void PivotFill(bool value) + { + mRect.Fill(value); + } + + // + // Virtual ... + + /** + * Retrieve Object Type ... + * + * @return ( ENUM_XCHARTOBJECTS ) + */ + virtual ENUM_XCHARTOBJECTS Type() + { + return X_XPVPIVOT_OBJ; + } + + // + private: + // + + // + // Props ... + CChartObjectRectangle mRect; + CChartObjectTrend mTrend; +}; + +// +// +// + +/** + * Draw Specified State Zone ... + * + * @param source: XStateZones instance Reference ... + * + * @return ( int ) + */ +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 ... + * + * @param model: XMarketStructure instance Reference ... + * + * @return ( int ) + */ +int DrawMarketStructure( + XMarketStructure &model, + XCBaseObject *&drawnObjects[] // +) +{ + // + int result = 0; + + // + Clean(drawnObjects); + + // + datetime cTime = TimeCurrent(); + + // + bool isValid = + model.IsValid(); + if (!isValid) + { + return result; + } + + // + if (model.lowestValeBar.IsValid()) + { + // + XCOHCLObject *iObj; + bool isCreated = CreateBar( + model.lowestValeBar, + iObj, + cTime // + ); + + // + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + if (model.lowestValePeakBreakeUpBar.IsValid()) + { + // + XCOHCLObject *iObj; + bool isCreated = CreateBar( + model.lowestValePeakBreakeUpBar, + iObj, + cTime // + ); + + // + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + if (model.valeAboveLowestValePeakBar.IsValid()) + { + // + XCOHCLObject *iObj; + bool isCreated = CreateBar( + model.valeAboveLowestValePeakBar, + iObj, + cTime // + ); + + // + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + if (model.highestPeakBar.IsValid()) + { + // + XCOHCLObject *iObj; + bool isCreated = CreateBar( + model.highestPeakBar, + iObj, + cTime // + ); + + // + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + if (model.peakBelowHighestPeakValeBar.IsValid()) + { + // + XCOHCLObject *iObj; + bool isCreated = CreateBar( + model.peakBelowHighestPeakValeBar, + iObj, + cTime // + ); + + // + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + if (model.highestPeakValeBreakeDownBar.IsValid()) + { + // + XCOHCLObject *iObj; + bool isCreated = CreateBar( + model.highestPeakValeBreakeDownBar, + iObj, + cTime // + ); + + // + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + if (HasChild(model.valePriceZones)) + { + // + int count = ArraySize(model.valePriceZones); + for (int i = 0; i < count; i++) + { + // + XPriceZones ipZone = model.valePriceZones[i]; + + // + XCBaseObject *ipObjects[]; + int ipDrawnObjects = DrawPriceZone( + ipZone, + ipObjects, + model.bias // + ); + if (IsValidSize(ipObjects)) + { + // + Copy( + ipObjects, + drawnObjects, + false // + ); + } + } + } + + // + if (HasChild(model.peakPriceZones)) + { + // + int count = ArraySize(model.peakPriceZones); + for (int i = 0; i < count; i++) + { + // + XPriceZones ipZone = model.peakPriceZones[i]; + + // + XCBaseObject *ipObjects[]; + int ipDrawnObjects = DrawPriceZone( + ipZone, + ipObjects, + model.bias // + ); + if (IsValidSize(ipObjects)) + { + // + Copy( + ipObjects, + drawnObjects, + false // + ); + } + } + } + + // + result = ArraySize(drawnObjects); + + // + return result; +} + +// +// +// + +/** + * Draw Specific Pivot ... + * + * @param pivot: XPVPivot instance Reference ... + * @param drawState: Boolean ... + * @param drawTicksZone: Boolean ... + * @param ignoreSwingHighs: Boolean ... + * @param ignoreSwingLows: Boolean ... + * @param ignoreSupportZones: Boolean ... + * @param ignoreResistanceZones: Boolean ... + * @param ignoreSupplyZones: Boolean ... + * @param ignoreDemandZones: Boolean ... + * @param ignoreBullishOrderBlocks: Boolean ... + * @param ignoreBearishOrderBlocks: Boolean ... + * @param ignoreBullishFairValueGaps: Boolean ... + * @param ignoreBearishFairValueGaps: Boolean ... + * @param ignoreBullishRejectionBars: Boolean ... + * @param ignoreBearishRejectionBars: Boolean ... + * @param ignoreBullishMomentumBars: Boolean ... + * @param ignoreBearishMomentumBars: Boolean ... + */ +int DrawPivot( + XPVPivot &pivot, + XCBaseObject *&drawnObjects[], + bool drawState = false, + bool drawStateAsBox = false, + bool drawTicksZone = false, + bool ignoreSwingHighs = false, + bool ignoreSwingLows = false, + bool ignoreSupportZones = false, + bool ignoreResistanceZones = false, + bool ignoreSupplyZones = false, + bool ignoreDemandZones = false, + bool ignoreBullishOrderBlocks = false, + bool ignoreBearishOrderBlocks = false, + bool ignoreBullishFairValueGaps = false, + bool ignoreBearishFairValueGaps = false, + bool ignoreBullishRejectionBars = false, + bool ignoreBearishRejectionBars = false, + bool ignoreBullishMomentumBars = false, + bool ignoreBearishMomentumBars = false // +) +{ + // + int result = 0; + + // + Clean(drawnObjects); + + // + if (!pivot.IsValid()) + { + return result; + } + + // + string prefix = Prefix(); + long chartID = ChartIdentification(); + int window = SubWindowIdentification(); + + // + // Draw Pivot it self ... + XCXPVPivotObject *iPivotObj; + iPivotObj = new XCXPVPivotObject(); + bool isCreated = iPivotObj.Create( + chartID, + window, + pivot, + prefix // + ); + if (!isCreated) + { + return result; + } + + // + color clrPivotColor = pivot.IsPeak() + ? clrAqua + : clrMagenta; + iPivotObj.PivotColor(clrPivotColor); + iPivotObj.PivotWidth(2); + + // + Add( + (XCBaseObject *)iPivotObj, + drawnObjects // + ); + + // + result = ArraySize(drawnObjects); + + // + if (!drawState) + { + return result; + } + + // + if (!pivot.state.IsValid()) + { + return result; + } + + // + XCBaseObject *stateObjects[]; + int stateCount = 0; + + // + if (!drawStateAsBox) + { + // + stateCount = DrawState( + pivot.state, + stateObjects, + drawTicksZone, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + } + else + { + // + double peakUpper = 0; + double peakLower = 0; + double valeUpper = 0; + double valeLower = 0; + + // + datetime peakTo = NULL; + datetime valeTo = NULL; + datetime peakFrom = NULL; + datetime valeFrom = NULL; + + // + bool hasBoxData = DetectPivotStateBoxData( + pivot, + peakUpper, + peakLower, + peakFrom, + peakTo, + valeUpper, + valeLower, + valeFrom, + valeTo // + ); + + // + if (hasBoxData) + { + // + XCBoxObject *peakBox; + bool isCreated = CreateBox( + peakBox, + peakUpper, + peakLower, + peakFrom, + peakTo, + clrMagenta, + 1, + false, + STYLE_DASHDOT // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)peakBox, + stateObjects // + ); + } + + // + XCBoxObject *valeBox; + isCreated = CreateBox( + valeBox, + valeUpper, + valeLower, + valeFrom, + valeTo, + clrAqua, + 1, + false, + STYLE_DASHDOT // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)valeBox, + stateObjects // + ); + } + } + } + + // + if (IsValidSize(stateCount)) + { + // + Copy( + stateObjects, + drawnObjects, + false // Doesn't Clean ... + ); + + // + Clean(stateObjects); + } + + // + result = ArraySize(drawnObjects); + + // + return result; +} + +/** + * Draw Specified XFVGOrderBlock Object ... + * + * @param models: XFVGOrderBlock instance Reference ... + * + * @return ( int ) + */ +int DrawFVGOrderBlock( + XFVGOrderBlock &model, + XCBaseObject *&drawnObjects[] // +) +{ + // + int result = 0; + + // + Clean(drawnObjects); + + // + if (!model.IsValid()) + { + return result; + } + + // + ENUM_X_DIRECTION iDir; + result = model.GetDirection(iDir); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(iDir); + if (isBullish) + { + // + // Order Block ... + XCBullishOrderBlockObject *iOBObj; + bool isCreated = CreateBullishOrderBlock( + model.orderBlock, + iOBObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iOBObj, + drawnObjects // + ); + } + + // + // FVG ... + XCBullishFairValueGapObject *iFVGObj; + isCreated = CreateBullishFairValueGap( + model.fairValueGap, + iFVGObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iOBObj, + drawnObjects // + ); + } + } + else + { + // + // Order Block ... + XCBearishOrderBlockObject *iOBObj; + bool isCreated = CreateBearishOrderBlock( + model.orderBlock, + iOBObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iOBObj, + drawnObjects // + ); + } + + // + // FVG ... + XCBearishFairValueGapObject *iFVGObj; + isCreated = CreateBearishFairValueGap( + model.fairValueGap, + iFVGObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iFVGObj, + drawnObjects // + ); + } + } + + // + result = ArraySize(drawnObjects); + + // + return result; +} + +// +// +// + + + /** + * Draw Price Zone ... + * + * @param zone: XPriceZones instance Reference ... + * @param forDir: ENUM_X_DIRECTION member ... + * + * @return ( int ) + */ + int DrawPriceZone( + XPriceZones &zone, + XCBaseObject *&drawnObjects[], + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + bool onlyBoundary = false // + ) + { + // + int result = 0; + + // + Clean(drawnObjects); + + // + if (!zone.IsValid()) + { + return result; + } + + // + bool isBullish = IsBullish(forDir); + bool isBearish = IsBearish(forDir); + bool isAll = forDir == X_DIRECTION_ALL || + forDir == X_DIRECTION_NONE; + + // + if (isAll || isBullish) + { + // + if (onlyBoundary) + { + // + double upper = 0; + double lower = 0; + datetime to = NULL; + datetime from = NULL; + + // + bool isRetrieved = zone.GetBoxData( + X_DIRECTION_NONE, + upper, + lower, + from, + to // + ); + if (isRetrieved) + { + // + color clr = + isBullish + ? BarBullishColor() + : isBearish + ? BarBearishColor() + : clrGray; + XCBoxObject *iObj; + result = CreateBox( + iObj, + upper, + lower, + from, + to, + clr, + 1, + false, + STYLE_DOT // + ); + if (result) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + else + { + // + // Support Zone ... + if (zone.HasSupportZone()) + { + // + XCSupportZoneObject *iObj; + bool isCreated = CreateSupportZone( + zone.supportZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + // Demand Zone ... + if (zone.HasDemandZone()) + { + // + XCDemandZoneObject *iObj; + bool isCreated = CreateDemandZone( + zone.demandZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + // OrderBlock ... + if (zone.HasOrderBlock() && + zone.orderBlock.IsBullish()) + { + // + XCBullishOrderBlockObject *iObj; + bool isCreated = CreateBullishOrderBlock( + zone.orderBlock, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + // FairValueGap ... + if (zone.HasFairValueGap() && + zone.fairValueGap.IsBullish()) + { + // + XCBullishFairValueGapObject *iObj; + bool isCreated = CreateBullishFairValueGap( + zone.fairValueGap, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + if (isAll || isBearish) + { + // + if (onlyBoundary) + { + // + double upper = 0; + double lower = 0; + datetime to = NULL; + datetime from = NULL; + + // + bool isRetrieved = zone.GetBoxData( + X_DIRECTION_NONE, + upper, + lower, + from, + to // + ); + if (isRetrieved) + { + // + color clr = + isBullish + ? BarBullishColor() + : isBearish + ? BarBearishColor() + : clrGray; + XCBoxObject *iObj; + result = CreateBox( + iObj, + upper, + lower, + from, + to, + clr, + 1, + false, + STYLE_DOT // + ); + if (result) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + else + { + // + // Resistance Zone ... + if (zone.HasResistanceZone()) + { + // + XCResistanceZoneObject *iObj; + bool isCreated = CreateResistanceZone( + zone.resistanceZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + // Supply Zone ... + if (zone.HasSupplyZone()) + { + // + XCSupplyZoneObject *iObj; + bool isCreated = CreateSupplyZone( + zone.supplyZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + // OrderBlock ... + if (zone.HasOrderBlock() && + zone.orderBlock.IsBearish()) + { + // + XCBearishOrderBlockObject *iObj; + bool isCreated = CreateBearishOrderBlock( + zone.orderBlock, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + // FairValueGap ... + if (zone.HasFairValueGap() && + zone.fairValueGap.IsBearish()) + { + // + XCBearishFairValueGapObject *iObj; + bool isCreated = CreateBearishFairValueGap( + zone.fairValueGap, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + result = ArraySize(drawnObjects); + + // + return result; + } + + +// +// +// + diff --git a/Documents/BKP/1/signals/tmp.codes.signals.mq5 b/Documents/BKP/1/signals/tmp.codes.signals.mq5 new file mode 100644 index 00000000..97a6c928 --- /dev/null +++ b/Documents/BKP/1/signals/tmp.codes.signals.mq5 @@ -0,0 +1,2995 @@ +#include "../Signals/x-121.smc.xhkpv.signal.lib.mq5" +#include "../Signals/x-121.smc.xiobpv.signal.lib.mq5" +#include "../Signals/x-121.smc.xobpv.signal.lib.mq5" + +///////////////////////////////////////////////////////////////////// + +bool useXHKPVSignal; +bool useXOBPVSignal; +bool useXIOBPVSignal; + +Clean(mXHKPVConditionsCollection); +Clean(mXOBPVConditionsCollection); +Clean(mXIOBPVConditionsCollection); + +bool hasXHKPVSignal = false; +bool hasXOBPVSignal = false; +bool hasXIOBPVSignal = false; + +useXHKPVSignal = false; +useXOBPVSignal = false; +useXIOBPVSignal = false; + +// +// XHKPV Signal ... +if (useXHKPVSignal && !hasSignal) +{ + // + hasXHKPVSignal = DetectXHKPVSignal(conditions); + hasSignal = hasXHKPVSignal; +} + +// +// XOBPV Signal ... +if (useXOBPVSignal && !hasSignal) +{ + // + hasXOBPVSignal = DetectXOBPVSignal(conditions); + hasSignal = hasXOBPVSignal; +} + +// +// XIOBPV Signal ... +if (useXIOBPVSignal && !hasSignal) +{ + // + hasXIOBPVSignal = DetectXIOBPVSignal(conditions); + hasSignal = hasXIOBPVSignal; +} + +// +// XHKPV Guard Detection ... +if (useXHKPVSignal) +{ + // + bool hasGuard = DetectX121SMCXHKPVGuards( + guards, + positions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); +} + +// +// XOBPV Guard Detection ... +if (useXOBPVSignal) +{ + // + bool hasGuard = DetectX121SMCXOBPVGuards( + guards, + positions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); +} + +// +// XIOBPV Guard Detection ... +if (useXIOBPVSignal) +{ + // + bool hasGuard = DetectX121SMCXIOBPVGuards( + guards, + positions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); +} + +// +// XHKPV Signal ... +bool DetectXHKPVSignal( + X121SMCStrategyConditions &conditions // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + return result; + } + + // + double cLL = cBar.FindLowest(7, MODE_LOW); + double cHH = cBar.FindHighest(7, MODE_HIGH); + + // + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XHKPV; + string providerStr = ToString(provider); + + // + // Detect Setup Conditions ... + datetime setupTime = mXHKPVConditions.setupTime; + bool isSetuped = mXHKPVConditions.IsSetuped(); + ENUM_X_DIRECTION setupDir = mXHKPVConditions.dir; + if (!isSetuped) + { + // + // Detect Signal Setup ... + isSetuped = DetectX121SMCXHKPVSignalSetup( + symbol, + period, + mXHKPVConditions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + setupDir = mXHKPVConditions.dir; + setupTime = mXHKPVConditions.setupTime; + + // + if (isSetuped) + { + // + int items = AddX121SMCXHKPVConditionsIfNotExists( + mXHKPVConditions, + mXHKPVConditionsCollection // + ); + + // + mXHKPVConditions.Clean(); + } + } + + // + int conditionsCount = ArraySize(mXHKPVConditionsCollection); + result = IsValidSize(conditionsCount); + if (!result) + { + return result; + } + + // + // Looking For Conditions ... + int selectedIndex = 0; + X121SMCStrategyXHKPVSignalConditions mTmpConditions[]; + Copy( + mXHKPVConditionsCollection, + mTmpConditions // + ); + X121SMCStrategyXHKPVSignalConditions mConditions; + for (int i = 0; i < conditionsCount; i++) + { + // + // Check Triggers ... + bool canTrigger = mTmpConditions[i].CanTrigger(); + datetime triggerTime = mTmpConditions[i].triggerTime; + if (!canTrigger) + { + // + // Detect Signal Trigger ... + canTrigger = DetectX121SMCXHKPVSignalTrigger( + mTmpConditions[i], + symbol, + period, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = canTrigger; + if (!result) + { + // + bool isISetuped = mTmpConditions[i].IsSetuped(); + if (!isISetuped) + { + // + ArrayRemove( + mXHKPVConditionsCollection, + i, + 1 // + ); + } + continue; + } + + // + triggerTime = mTmpConditions[i].triggerTime; + } + + // + if (canTrigger) + { + // + selectedIndex = i; + mConditions = mTmpConditions[i]; + break; + } + } + + // + result = IsValid(mConditions.setupTime) && + HasDirection(mConditions.dir); + if (!result) + { + return result; + } + + // + // Remove Selected Index from Main Collection ... + ArrayRemove( + mXHKPVConditionsCollection, + selectedIndex, + 1 // + ); + + // + // Check Signal Direction ... + isBullish = IsBullish(mConditions.dir); + isBearish = IsBearish(mConditions.dir); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Issues Signal on Conditions ... + conditions.sl = mConditions.sl; + conditions.provider = providerStr; + conditions.signalDir = mConditions.dir; + conditions.target = mConditions.target; + + // + return result; +} + +// +// XOBPV Signal ... +bool DetectXOBPVSignal( + X121SMCStrategyConditions &conditions // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + return result; + } + + // + double cLL = cBar.FindLowest(7, MODE_LOW); + double cHH = cBar.FindHighest(7, MODE_HIGH); + + // + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XOBPV; + string providerStr = ToString(provider); + + // + // Detect Setup Conditions ... + datetime setupTime = mXOBPVConditions.setupTime; + bool isSetuped = mXOBPVConditions.IsSetuped(); + ENUM_X_DIRECTION setupDir = mXOBPVConditions.dir; + if (!isSetuped) + { + // + // Detect Signal Setup ... + isSetuped = DetectX121SMCXOBPVSignalSetup( + symbol, + period, + mXOBPVConditions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + setupDir = mXOBPVConditions.dir; + setupTime = mXOBPVConditions.setupTime; + + // + if (isSetuped) + { + // + int items = AddX121SMCXOBPVConditionsIfNotExists( + mXOBPVConditions, + mXOBPVConditionsCollection // + ); + + // + mXOBPVConditions.Clean(); + } + } + + // + int conditionsCount = ArraySize(mXOBPVConditionsCollection); + result = IsValidSize(conditionsCount); + if (!result) + { + return result; + } + + // + // Looking For Conditions ... + int selectedIndex = 0; + X121SMCStrategyXOBPVSignalConditions mTmpConditions[]; + Copy( + mXOBPVConditionsCollection, + mTmpConditions // + ); + X121SMCStrategyXOBPVSignalConditions mConditions; + for (int i = 0; i < conditionsCount; i++) + { + // + // Check Triggers ... + bool canTrigger = mTmpConditions[i].CanTrigger(); + datetime triggerTime = mTmpConditions[i].triggerTime; + if (!canTrigger) + { + // + // Detect Signal Trigger ... + canTrigger = DetectX121SMCXOBPVSignalTrigger( + mTmpConditions[i], + symbol, + period, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = canTrigger; + if (!result) + { + // + bool isISetuped = mTmpConditions[i].IsSetuped(); + if (!isISetuped) + { + // + ArrayRemove( + mXOBPVConditionsCollection, + i, + 1 // + ); + } + continue; + } + + // + triggerTime = mTmpConditions[i].triggerTime; + } + + // + if (canTrigger) + { + // + selectedIndex = i; + mConditions = mTmpConditions[i]; + break; + } + } + + // + result = IsValid(mConditions.setupTime) && + HasDirection(mConditions.dir); + if (!result) + { + return result; + } + + // + // Remove Selected Index from Main Collection ... + ArrayRemove( + mXOBPVConditionsCollection, + selectedIndex, + 1 // + ); + + // + // Check Signal Direction ... + isBullish = IsBullish(mConditions.dir); + isBearish = IsBearish(mConditions.dir); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Issues Signal on Conditions ... + conditions.sl = mConditions.sl; + conditions.provider = providerStr; + conditions.signalDir = mConditions.dir; + conditions.target = mConditions.target; + + // + return result; +} + +// +// XIOBPV Signal ... +bool DetectXIOBPVSignal( + X121SMCStrategyConditions &conditions // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + return result; + } + + // + double cLL = cBar.FindLowest(7, MODE_LOW); + double cHH = cBar.FindHighest(7, MODE_HIGH); + + // + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XIOBPV; + string providerStr = ToString(provider); + + // + // Detect Setup Conditions ... + datetime setupTime = mXIOBPVConditions.setupTime; + bool isSetuped = mXIOBPVConditions.IsSetuped(); + ENUM_X_DIRECTION setupDir = mXIOBPVConditions.dir; + if (!isSetuped) + { + // + // Detect Signal Setup ... + isSetuped = DetectX121SMCXIOBPVSignalSetup( + symbol, + period, + mXIOBPVConditions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + setupDir = mXIOBPVConditions.dir; + setupTime = mXIOBPVConditions.setupTime; + + // + if (isSetuped) + { + // + int items = AddX121SMCXIOBPVConditionsIfNotExists( + mXIOBPVConditions, + mXIOBPVConditionsCollection // + ); + + // + mXIOBPVConditions.Clean(); + } + } + + // + int conditionsCount = ArraySize(mXIOBPVConditionsCollection); + result = IsValidSize(conditionsCount); + if (!result) + { + return result; + } + + // + // Looking For Conditions ... + int selectedIndex = 0; + X121SMCStrategyXIOBPVSignalConditions mTmpConditions[]; + Copy( + mXIOBPVConditionsCollection, + mTmpConditions // + ); + X121SMCStrategyXIOBPVSignalConditions mConditions; + for (int i = 0; i < conditionsCount; i++) + { + // + // Check Triggers ... + bool canTrigger = mTmpConditions[i].CanTrigger(); + datetime triggerTime = mTmpConditions[i].triggerTime; + if (!canTrigger) + { + // + // Detect Signal Trigger ... + canTrigger = DetectX121SMCXIOBPVSignalTrigger( + mTmpConditions[i], + symbol, + period, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = canTrigger; + if (!result) + { + // + bool isISetuped = mTmpConditions[i].IsSetuped(); + if (!isISetuped) + { + // + ArrayRemove( + mXIOBPVConditionsCollection, + i, + 1 // + ); + } + continue; + } + + // + triggerTime = mTmpConditions[i].triggerTime; + } + + // + if (canTrigger) + { + // + selectedIndex = i; + mConditions = mTmpConditions[i]; + break; + } + } + + // + result = IsValid(mConditions.setupTime) && + HasDirection(mConditions.dir); + if (!result) + { + return result; + } + + // + // Remove Selected Index from Main Collection ... + ArrayRemove( + mXIOBPVConditionsCollection, + selectedIndex, + 1 // + ); + + // + // Check Signal Direction ... + isBullish = IsBullish(mConditions.dir); + isBearish = IsBearish(mConditions.dir); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Issues Signal on Conditions ... + conditions.sl = mConditions.sl; + conditions.provider = providerStr; + conditions.signalDir = mConditions.dir; + conditions.target = mConditions.target; + + // + return result; +} + +///////////////////////////////////////////////////////////////////// + +const string X121SMCXHKPVToken = "X121XHKPV"; +const string X121SMCXOBPVToken = "X121XOBPV"; +const string X121SMCXIOBPVToken = "X121XIOBPV"; + + X_121_SMC_PROVIDER_XHKPV, + X_121_SMC_PROVIDER_XOBPV, + X_121_SMC_PROVIDER_XIOBPV, + + + // + case X_121_SMC_PROVIDER_XHKPV: + result = X121SMCXHKPVToken; + break; + + // + case X_121_SMC_PROVIDER_XOBPV: + result = X121SMCXOBPVToken; + break; + + // + case X_121_SMC_PROVIDER_XIOBPV: + result = X121SMCXIOBPVToken; + break; + + else if (Contains(X121SMCXHKPVToken, value)) + { + result = X_121_SMC_PROVIDER_XHKPV; + } + else if (Contains(X121SMCXOBPVToken, value)) + { + result = X_121_SMC_PROVIDER_XOBPV; + } + else if (Contains(X121SMCXIOBPVToken, value)) + { + result = X_121_SMC_PROVIDER_XIOBPV; + } + +///////////////////////////////////////////////////////////////////// + + + /** + * Detect Market Structure Method 2 ... + * + * @param model: XMarketStructure instance Reference ... + * + * @return ( bool ) + */ + bool DetectMarketStructure( + ENUM_X_DIRECTION &dir, + int pivotsCount = 3 // + ) + { + // + bool result = false; + + // + int barIndex = 0; + + // + if (pivotsCount < 3) + { + pivotsCount = 3; + } + + // + dir = X_DIRECTION_NONE; + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + int hpIndex = -1; + int hpIndexes[]; + double hpValues[]; + + // + int lvIndex = -1; + int lvIndexes[]; + double lvValues[]; + + // + for (int i = 0; i < pivotsCount; i++) + { + // + hpIndex = barIndex; + lvIndex = barIndex; + + // + double lastHP = 0; + double lastLV = 0; + + // + int hpCount = ArraySize(hpIndexes); + int lvCount = ArraySize(lvIndexes); + + // + if (IsValidSize(hpCount)) + { + // + lastHP = hpValues[hpCount - 1]; + hpIndex = hpIndexes[hpCount - 1]; + } + + // + if (IsValidSize(lvCount)) + { + // + lastLV = lvValues[lvCount - 1]; + lvIndex = lvIndexes[lvCount - 1]; + } + + // + if (lastHP == 0) + { + // + lastHP = mX121Helper + .xpvHelper + .GetPeak(hpIndex); + } + + // + if (lastLV == 0) + { + // + lastLV = mX121Helper + .xpvHelper + .GetVale(lvIndex); + } + + // + int highestPeakIndex = -1; + double highesrPeak = + mX121Helper + .xpvHelper + .GetHigherPeak( + highestPeakIndex, + lastHP, + hpIndex // + ); + if (IsValidIndex(highestPeakIndex)) + { + // + Add( + highestPeakIndex, + hpIndexes // + ); + + // + Add( + highesrPeak, + hpValues // + ); + } + + // + int lowestValeIndex = -1; + double lowestVale = + mX121Helper + .xpvHelper + .GetLowerVale( + lowestValeIndex, + lastLV, + lvIndex // + ); + if (IsValidIndex(lowestValeIndex)) + { + // + Add( + lowestValeIndex, + lvIndexes // + ); + + // + Add( + lowestVale, + lvValues // + ); + } + + // + bool canBreak = ArraySize(hpIndexes) >= pivotsCount || + ArraySize(lvIndexes) >= pivotsCount; + if (canBreak) + { + break; + } + } + + // + ArrayReverse(hpValues); + ArrayReverse(hpIndexes); + int countHPs = ArraySize(hpIndexes); + + // + ArrayReverse(lvValues); + ArrayReverse(lvIndexes); + int countLVs = ArraySize(lvIndexes); + + // + bool isValidHPs = countHPs >= pivotsCount; + bool isValidLVs = countLVs >= pivotsCount; + + // + result = isValidHPs || + isValidLVs; + if (!result) + { + return result; + } + + // + if (isValidHPs && isValidLVs) + { + // + hpIndex = hpIndexes[countHPs - 1]; + lvIndex = lvIndexes[countLVs - 1]; + } + + // + dir = + !isValidHPs && isValidLVs + ? X_DIRECTION_BULLISH + : !isValidLVs && isValidHPs + ? X_DIRECTION_BEARISH + : hpIndex < lvIndex + ? X_DIRECTION_BEARISH + : lvIndex < hpIndex + ? X_DIRECTION_BULLISH + : X_DIRECTION_ALL; + + // + return result; + } + + /** + * Detect Order Blocks ... + * + * @return ( bool ) + */ + bool DetectOrderBlocks( + XCOrderBlock *&bullishOrderBlocks[], + XCOrderBlock *&bearishOrderBlocks[] // + ) + { + // + bool result = false; + + // + Clean(bullishOrderBlocks); + Clean(bearishOrderBlocks); + + // + XPOIState state; + mPOIDetector.GetState(state); + bool isValid = state.IsValid() && + state.HasChild(); + if (!isValid) + { + return result; + } + + // + int bullOBsCount = DetectValidOrderBlocks( + X_DIRECTION_BULLISH, + state, + bullishOrderBlocks // + ); + + // + int bearOBsCount = DetectValidOrderBlocks( + X_DIRECTION_BEARISH, + state, + bearishOrderBlocks // + ); + + // + result = IsValidSize(bullOBsCount + + bearOBsCount); + + // + return result; + } + + /** + * Detect Fair Value Gaps ... + * + * @return ( bool ) + */ + bool DetectFairValueGaps( + XCFVG *&bullishFairValueGaps[], + XCFVG *&bearishFairValueGaps[] // + ) + { + // + bool result = false; + + // + Clean(bullishFairValueGaps); + Clean(bearishFairValueGaps); + + // + XPOIState state; + mPOIDetector.GetState(state); + bool isValid = state.IsValid() && + state.HasChild(); + if (!isValid) + { + return result; + } + + // + int bullFVGsCount = DetectValidFairValueGaps( + X_DIRECTION_BULLISH, + state, + bullishFairValueGaps // + ); + + // + int bearFVGsCount = DetectValidFairValueGaps( + X_DIRECTION_BEARISH, + state, + bearishFairValueGaps // + ); + + // + result = IsValidSize(bullFVGsCount + + bearFVGsCount); + + // + return result; + } + + /** + * Detect Support Zones ... + * + * @return ( bool ) + */ + bool DetectSupportZones( + XCOrderBlock *&bullishOrderBlocks[], + XCFVG *&bullishFairValueGaps[], + XCSupportZone *&supportZones[] // + ) + { + // + bool result = false; + + // + Clean(supportZones); + + // + int obsCount = ArraySize(bullishOrderBlocks); + int fvgsCount = ArraySize(bullishFairValueGaps); + + // + XPOIState state; + mPOIDetector.GetState(state); + bool isValid = state.IsValid() && + state.HasChild() && + IsValidSize(obsCount + fvgsCount); + if (!isValid) + { + return result; + } + + // + int supportZonesCount = DetectValidSupportZones( + state, + bullishOrderBlocks, + bullishFairValueGaps, + supportZones // + ); + + // + result = IsValidSize(supportZonesCount); + + // + return result; + } + + /** + * Detect Resistance Zones ... + * + * @return ( bool ) + */ + bool DetectResistanceZones( + XCOrderBlock *&bearishOrderBlocks[], + XCFVG *&bearishFairValueGaps[], + XCResistanceZone *&resistanceZones[] // + ) + { + // + bool result = false; + + // + Clean(resistanceZones); + + // + int obsCount = ArraySize(bearishOrderBlocks); + int fvgsCount = ArraySize(bearishFairValueGaps); + + // + XPOIState state; + mPOIDetector.GetState(state); + bool isValid = state.IsValid() && + state.HasChild() && + IsValidSize(obsCount + fvgsCount); + if (!isValid) + { + return result; + } + + // + int resistanceZonesCount = DetectValidResistanceZones( + state, + bearishOrderBlocks, + bearishFairValueGaps, + resistanceZones // + ); + + // + result = IsValidSize(resistanceZonesCount); + + // + return result; + } + + /** + * Detect Demand Zones ... + * + * @return ( bool ) + */ + bool DetectDemandZones( + XCOrderBlock *&bullishOrderBlocks[], + XCFVG *&bullishFairValueGaps[], + XCDemandZone *&demandZones[] // + ) + { + // + bool result = false; + + // + Clean(demandZones); + + // + int obsCount = ArraySize(bullishOrderBlocks); + int fvgsCount = ArraySize(bullishFairValueGaps); + + // + XPOIState state; + mPOIDetector.GetState(state); + bool isValid = state.IsValid() && + state.HasChild() && + IsValidSize(obsCount + fvgsCount); + if (!isValid) + { + return result; + } + + // + int demandZonesCount = DetectValidDemandZones( + state, + bullishOrderBlocks, + bullishFairValueGaps, + demandZones // + ); + + // + result = IsValidSize(demandZonesCount); + + // + return result; + } + + /** + * Detect Supply Zones ... + * + * @return ( bool ) + */ + bool DetectSupplyZones( + XCOrderBlock *&bearishOrderBlocks[], + XCFVG *&bearishFairValueGaps[], + XCSupplyZone *&supplyZones[] // + ) + { + // + bool result = false; + + // + Clean(supplyZones); + + // + int obsCount = ArraySize(bearishOrderBlocks); + int fvgsCount = ArraySize(bearishFairValueGaps); + + // + XPOIState state; + mPOIDetector.GetState(state); + bool isValid = state.IsValid() && + state.HasChild() && + IsValidSize(obsCount + fvgsCount); + if (!isValid) + { + return result; + } + + // + int supplyZonesCount = DetectValidSupplyZones( + state, + bearishOrderBlocks, + bearishFairValueGaps, + supplyZones // + ); + + // + result = IsValidSize(supplyZonesCount); + + // + return result; + } + + /** + * Count Prev Peak Repetition ... + * + * @param barIndex: Integer ... + * + * @return ( int ) + */ + int CountPrevPeakRepetition( + int barIndex = 0// + ) { + // + int result = 0; + + // + if (barIndex < 0) { + barIndex = 0; + } + + // + int index = barIndex + 1; + double value = mX121Helper.xpvHelper.GetPeak(index); + index++; + + // + bool canContinue = true; + while(canContinue) { + // + double iValue = mX121Helper.xpvHelper.GetPeak(index); + + // + canContinue = iValue == value; + if (canContinue) { + // + index++; + result++; + } + } + + // + return result; + } + + /** + * Count Prev Vale Repetition ... + * + * @param barIndex: Integer ... + * + * @return ( int ) + */ + int CountPrevValeRepetition( + int barIndex = 0// + ) { + // + int result = 0; + + // + if (barIndex < 0) { + barIndex = 0; + } + + // + int index = barIndex + 1; + double value = mX121Helper.xpvHelper.GetVale(index); + index++; + + // + bool canContinue = true; + while(canContinue) { + // + double iValue = mX121Helper.xpvHelper.GetVale(index); + + // + canContinue = iValue == value; + if (canContinue) { + // + index++; + result++; + } + } + + // + return result; + } + + /** + * Get Cycle State and Update it ... + * + * @param state: X121SMCCycleState instance Reference ... + * + * @return ( bool ) + */ + bool GetCycleState(X121SMCCycleState &state) + { + // + bool result = false; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + state.symbol = symbol; + state.period = period; + + // + datetime cTime = TimeCurrent(); + + // + // Detect Order Block ... + + // + bool hasBullishOBs = state.HasBullishOBs(); + int bullishOBsCount = state.CountBullishOBs(); + + // + bool hasBearishOBs = state.HasBearishOBs(); + int bearishOBsCount = state.CountBearishOBs(); + + // + bool hasOBs = hasBullishOBs && + hasBearishOBs; + if (!hasOBs) + { + // + XCOrderBlock *bullishOBs[]; + XCOrderBlock *bearishOBs[]; + hasOBs = DetectOrderBlocks( + bullishOBs, + bearishOBs // + ); + + // + if (hasOBs && + !hasBullishOBs) + { + // + Copy( + bullishOBs, + state.bullishOBs // + ); + } + + // + if (hasOBs && + !hasBearishOBs) + { + // + Copy( + bearishOBs, + state.bearishOBs // + ); + } + + // + hasBullishOBs = state.HasBullishOBs(); + bullishOBsCount = state.CountBullishOBs(); + + // + hasBearishOBs = state.HasBearishOBs(); + bearishOBsCount = state.CountBearishOBs(); + } + + // + // Update Order Blocks Time ... + if (hasOBs) + { + // + if (hasBullishOBs) + { + // + for (int i = 0; i < bullishOBsCount; i++) + { + state.bullishOBs[i].To(cTime); + } + } + + // + if (hasBearishOBs) + { + // + for (int i = 0; i < bearishOBsCount; i++) + { + state.bearishOBs[i].To(cTime); + } + } + } + + // + // Detect Fair Value Gap ... + + // + bool hasBullishFVGs = state.HasBullishFVGs(); + int bullishFVGsCount = state.CountBullishFVGs(); + + // + bool hasBearishFVGs = state.HasBearishFVGs(); + int bearishFVGsCount = state.CountBearishFVGs(); + + // + bool hasFVGs = hasBullishFVGs && + hasBearishFVGs; + if (!hasFVGs) + { + // + XCFVG *bullishFVGs[]; + XCFVG *bearishFVGs[]; + hasFVGs = DetectFairValueGaps( + bullishFVGs, + bearishFVGs // + ); + + // + if (hasFVGs && + !hasBullishFVGs) + { + // + Copy( + bullishFVGs, + state.bullishFVGs // + ); + } + + // + if (hasFVGs && + !hasBearishFVGs) + { + // + Copy( + bearishFVGs, + state.bearishFVGs // + ); + } + + // + hasBullishFVGs = state.HasBullishFVGs(); + bullishFVGsCount = state.CountBullishFVGs(); + + // + hasBearishFVGs = state.HasBearishFVGs(); + bearishFVGsCount = state.CountBearishFVGs(); + } + + // + // Update Fair Value Gaps Time ... + if (hasFVGs) + { + // + if (hasBullishFVGs) + { + // + for (int i = 0; i < bullishFVGsCount; i++) + { + state.bullishFVGs[i].To(cTime); + } + } + + // + if (hasBearishFVGs) + { + // + for (int i = 0; i < bearishFVGsCount; i++) + { + state.bearishFVGs[i].To(cTime); + } + } + } + + // + // Detect Support Zones ... + + // + bool hasSupportZones = state.HasSupportZones(); + int supportZonesCount = state.CountSupportZones(); + + // + if (!hasSupportZones) + { + // + XCSupportZone *supportZones[]; + hasSupportZones = DetectSupportZones( + state.bullishOBs, + state.bullishFVGs, + supportZones // + ); + + // + if (hasSupportZones) + { + // + Copy( + supportZones, + state.supportZones // + ); + + // + supportZonesCount = state.CountSupportZones(); + } + } + + // + // Update Support Zones Time ... + if (hasSupportZones) + { + // + for (int i = 0; i < supportZonesCount; i++) + { + state.supportZones[i].To(cTime); + } + } + + // + // Detect Demand Zones ... + + // + bool hasDemandZones = state.HasDemandZones(); + int demandZonesCount = state.CountDemandZones(); + + // + if (!hasDemandZones) + { + // + XCDemandZone *demandZones[]; + hasDemandZones = DetectDemandZones( + state.bullishOBs, + state.bullishFVGs, + demandZones // + ); + + // + if (hasDemandZones) + { + // + Copy( + demandZones, + state.demandZones // + ); + + // + demandZonesCount = state.CountDemandZones(); + } + } + + // + // Update Support Zones Time ... + if (hasDemandZones) + { + // + for (int i = 0; i < demandZonesCount; i++) + { + state.demandZones[i].To(cTime); + } + } + + // + // Detect Resistance Zones ... + + // + bool hasResistanceZones = state.HasResistanceZones(); + int resistanceZonesCount = state.CountResistanceZones(); + + // + if (!hasResistanceZones) + { + // + XCResistanceZone *resistanceZones[]; + hasResistanceZones = DetectResistanceZones( + state.bearishOBs, + state.bearishFVGs, + resistanceZones // + ); + + // + if (hasResistanceZones) + { + // + for (int i = 0; i < ArraySize(resistanceZones); i++) + { + resistanceZones[i].To(cTime); + } + + // + Copy( + resistanceZones, + state.resistanceZones // + ); + + // + resistanceZonesCount = state.CountResistanceZones(); + } + } + + // + // Update Resistance Zones Time ... + if (hasResistanceZones) + { + // + for (int i = 0; i < resistanceZonesCount; i++) + { + state.resistanceZones[i].To(cTime); + } + } + + // + // Detect Supply Zones ... + + // + bool hasSupplyZones = state.HasSupplyZones(); + int supplyZonesCount = state.CountSupplyZones(); + + // + if (!hasSupplyZones) + { + // + XCSupplyZone *supplyZones[]; + hasSupplyZones = DetectSupplyZones( + state.bearishOBs, + state.bearishFVGs, + supplyZones // + ); + + // + if (hasSupplyZones) + { + // + Copy( + supplyZones, + state.supplyZones // + ); + + // + supplyZonesCount = state.CountSupplyZones(); + } + } + + // + // Update Resistance Zones Time ... + if (hasSupplyZones) + { + // + for (int i = 0; i < supplyZonesCount; i++) + { + state.supplyZones[i].To(cTime); + } + } + + // + result = state.IsValid(); + + // + return result; + } + +///////////////////////////////////////////////////////////////////// + +// +// Model Cycle State ... +struct X121SMCCycleState +{ + // + // Props ... + string symbol; + ENUM_TIMEFRAMES period; + + // + // Bullish ... + XCFVG *bullishFVGs[]; + XCOrderBlock *bullishOBs[]; + XCDemandZone *demandZones[]; + XCSupportZone *supportZones[]; + + // + // Bearish ... + XCFVG *bearishFVGs[]; + XCOrderBlock *bearishOBs[]; + XCSupplyZone *supplyZones[]; + XCResistanceZone *resistanceZones[]; + + // + // Constructor ... + X121SMCCycleState() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup Model ... + */ + void Clean() + { + // + symbol = NULL; + period = NULL; + + // + Clean(bullishFVGs); + Clean(bullishOBs); + Clean(demandZones); + Clean(supportZones); + + // + Clean(bearishFVGs); + Clean(bearishOBs); + Clean(supplyZones); + Clean(resistanceZones); + + // + ZeroMemory(this); + } + + /** + * Validate Model ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(symbol) && + IsValid(period) && + ( + // + (HasBullishOBs() && + (HasBullishFVGs() || + HasSupportZones() || + HasDemandZones())) + // + || + (HasBearishOBs() && + (HasSupplyZones() || + HasBearishFVGs() || + HasResistanceZones())) + // + ) + // + ; + + // + return result; + } + + // + int CountBullishOBs() + { + return ArraySize(bullishOBs); + } + + // + bool HasBullishOBs() + { + return IsValidSize(CountBullishOBs()); + } + + // + int CountBearishOBs() + { + return ArraySize(bearishOBs); + } + + // + bool HasBearishOBs() + { + return IsValidSize(CountBearishOBs()); + } + + // + int CountSupportZones() + { + return ArraySize(supportZones); + } + + // + bool HasSupportZones() + { + return IsValidSize(CountSupportZones()); + } + + // + int CountResistanceZones() + { + return ArraySize(resistanceZones); + } + + // + bool HasResistanceZones() + { + return IsValidSize(CountResistanceZones()); + } + + // + int CountDemandZones() + { + return ArraySize(demandZones); + } + + // + bool HasDemandZones() + { + return IsValidSize(CountDemandZones()); + } + + // + int CountSupplyZones() + { + return ArraySize(supplyZones); + } + + // + bool HasSupplyZones() + { + return IsValidSize(CountSupplyZones()); + } + + // + int CountBullishFVGs() + { + return ArraySize(bullishFVGs); + } + + // + bool HasBullishFVGs() + { + return IsValidSize(CountBullishFVGs()); + } + + // + int CountBearishFVGs() + { + return ArraySize(bearishFVGs); + } + + // + bool HasBearishFVGs() + { + return IsValidSize(CountBearishFVGs()); + } + + // + bool GetOldestOB( + XCOrderBlock *&orderBlock // + ) + { + // + bool result = false; + + // + orderBlock = NULL; + + // + bool hasBullishOB = HasBullishOBs(); + bool hasBearishOB = HasBearishOBs(); + result = hasBullishOB || + hasBearishOB; + if (!result) + { + return result; + } + + // + int iBullOBIDX = -1; + bool iHasBullOB = false; + XCOrderBlock *iBullOB = NULL; + if (hasBullishOB) + { + // + XCZone *iZones[]; + ToZone( + bullishOBs, + iZones // + ); + + // + iBullOBIDX = GetOldest( + iZones // + ); + + // + iHasBullOB = IsValidIndex(iBullOBIDX); + if (iHasBullOB) + { + iBullOB = bullishOBs[iBullOBIDX]; + } + } + + // + int iBearOBIDX = -1; + bool iHasBearOB = false; + XCOrderBlock *iBearOB = NULL; + if (hasBearishOB) + { + // + XCZone *iZones[]; + ToZone( + bearishOBs, + iZones // + ); + + // + iBearOBIDX = GetOldest( + iZones // + ); + + // + iHasBearOB = IsValidIndex(iBearOBIDX); + if (iHasBearOB) + { + iBearOB = bearishOBs[iBearOBIDX]; + } + } + + // + if (iHasBullOB) + { + orderBlock = iBullOB; + } + + // + if (iHasBearOB) + { + // + bool canSet = orderBlock == NULL || + orderBlock.From() > iBearOB.From(); + if (canSet) + { + orderBlock = iBearOB; + } + } + + // + result = orderBlock != NULL && + orderBlock.IsValid(); + + // + return result; + } + + // + bool GetYoungestOB( + XCOrderBlock *&orderBlock // + ) + { + // + bool result = false; + + // + orderBlock = NULL; + + // + bool hasBullishOB = HasBullishOBs(); + bool hasBearishOB = HasBearishOBs(); + result = hasBullishOB || + hasBearishOB; + if (!result) + { + return result; + } + + // + int iBullOBIDX = -1; + bool iHasBullOB = false; + XCOrderBlock *iBullOB = NULL; + if (hasBullishOB) + { + // + XCZone *iZones[]; + ToZone( + bullishOBs, + iZones // + ); + + // + iBullOBIDX = GetYoungest( + iZones // + ); + + // + iHasBullOB = IsValidIndex(iBullOBIDX); + if (iHasBullOB) + { + iBullOB = bullishOBs[iBullOBIDX]; + } + } + + // + int iBearOBIDX = -1; + bool iHasBearOB = false; + XCOrderBlock *iBearOB = NULL; + if (hasBearishOB) + { + // + XCZone *iZones[]; + ToZone( + bearishOBs, + iZones // + ); + + // + iBearOBIDX = GetYoungest( + iZones // + ); + + // + iHasBearOB = IsValidIndex(iBearOBIDX); + if (iHasBearOB) + { + iBearOB = bearishOBs[iBearOBIDX]; + } + } + + // + if (iHasBullOB) + { + orderBlock = iBullOB; + } + + // + if (iHasBearOB) + { + // + bool canSet = orderBlock == NULL || + orderBlock.From() < iBearOB.From(); + if (canSet) + { + orderBlock = iBearOB; + } + } + + // + result = orderBlock != NULL && + orderBlock.IsValid(); + + // + return result; + } + + // +}; + + +/** + * Detect Price inside Box ... + * + * @param box: XBoxZone instance Reference, Founded Price Inside Box ... + * @param orderBlock: XCOrderBlock pointer Reference, Founded Price Inside Order Block ... + * @param xConditions: X121Conditions instance Reference, provides Market Conditions ... + * @param state: X121SMCCycleState instance Reference ... + * + * @return ( bool ) + */ +bool DetectPriceInsideBox( + XBoxZone &box, // Price Inside Bo ... + XCOrderBlock *&orderBlock, // Price Inside Order Block ... + X121Conditions &xConditions, // X121Conditions for Validation ... + X121SMCCycleState &state // Cycle State ... +) +{ + // + bool result = false; + + // + box.Clean(); + + // + string symbol = state.symbol; + ENUM_TIMEFRAMES period = state.period; + + // + box.symbol = symbol; + box.period = period; + + // + result = state.IsValid(); + if (!result) + { + return result; + } + + // + // Detect Price Inside Order Block ... + + // + bool hasBullishOBs = state.HasBullishOBs(); + int bullishOBsCount = state.CountBullishOBs(); + + // + bool hasBearishOBs = state.HasBearishOBs(); + int bearishOBsCount = state.CountBearishOBs(); + + // + bool hasOBs = + // + hasBullishOBs || + hasBearishOBs + // + ; + result = hasOBs; + if (!result) + { + return result; + } + + // + bool hasPriceInsideOB = false; + XCOrderBlock *priceInsideOB = NULL; + ENUM_X_DIRECTION boxDir = X_DIRECTION_NONE; + + // + if (hasBullishOBs && + !hasPriceInsideOB) + { + // + for (int i = 0; i < bullishOBsCount; i++) + { + // + XCOrderBlock *iOb = state.bullishOBs[i]; + + // + bool isInside = IsPriceInsideZone( + xConditions.valesBuffer[1], + (XCZone *)iOb // + ); + if (isInside) + { + // + priceInsideOB = iOb; + hasPriceInsideOB = true; + boxDir = X_DIRECTION_BULLISH; + break; + } + } + } + + // + if (hasBearishOBs && + !hasPriceInsideOB) + { + // + for (int i = 0; i < bearishOBsCount; i++) + { + // + XCOrderBlock *iOb = state.bearishOBs[i]; + + // + bool isInside = IsPriceInsideZone( + xConditions.peaksBuffer[1], + (XCZone *)iOb // + ); + if (isInside) + { + // + priceInsideOB = iOb; + hasPriceInsideOB = true; + boxDir = X_DIRECTION_BEARISH; + break; + } + } + } + + // + if (hasPriceInsideOB) + { + // + orderBlock = priceInsideOB; + boxDir = priceInsideOB.IsBullish() + ? X_DIRECTION_BULLISH + : priceInsideOB.IsBearish() + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + } + + // + bool hasBullishFVGs = state.HasBullishFVGs(); + bool hasBearishFVGs = state.HasBearishFVGs(); + bool hasDemandZones = state.HasDemandZones(); + bool hasSupplyZones = state.HasSupplyZones(); + bool hasSupportZones = state.HasSupportZones(); + bool hasResistanceZones = state.HasResistanceZones(); + + // + bool hasBullishZones = + // + hasBullishFVGs || + hasDemandZones || + hasSupportZones + // + ; + + // + bool hasBearishZones = + // + hasBearishFVGs || + hasSupplyZones || + hasResistanceZones + // + ; + + // + bool hasPropperZones = + // + IsBullish(boxDir) + ? hasBullishZones + : IsBearish(boxDir) + ? hasBearishZones + : false + // + ; + + // + if (!hasPropperZones && + hasPriceInsideOB) + { + // + // Use Price Inside OB as Box ... + box.dir = boxDir; + box.to = priceInsideOB.To(); + box.from = priceInsideOB.From(); + box.upper = priceInsideOB.Upper(); + box.lower = priceInsideOB.Lower(); + } + else if (hasPropperZones && + hasPriceInsideOB) + { + // + // Detect Validate Zones ... + int count = 0; + XBoxZone boxes[]; + double upper = 0; + double lower = 0; + double price = 0; + datetime to = NULL; + datetime from = NULL; + ENUM_X_DIRECTION dir = X_DIRECTION_NONE; + if (IsBullish(boxDir)) + { + // + double price = xConditions.valesBuffer[1]; + dir = X_DIRECTION_BULLISH; + + // + // Bullish FVG ... + count = state.CountBullishFVGs(); + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = state.bullishFVGs[i]; + + // + to = iFVG.To(); + from = iFVG.From(); + upper = iFVG.Upper(); + lower = iFVG.Lower(); + + // + bool isInside = IsPriceInsideZone( + price, + upper, + lower // + ); + if (isInside) + { + // + XBoxZone iBox; + + // + iBox.dir = dir; + iBox.symbol = symbol; + iBox.period = period; + + // + iBox.to = to; + iBox.from = from; + iBox.upper = upper; + iBox.lower = lower; + + // + if (iBox.IsValid()) + { + // + AddRef( + iBox, + boxes // + ); + } + } + } + + // + // Demand Zones ... + count = state.CountDemandZones(); + for (int i = 0; i < count; i++) + { + // + XCDemandZone *iDemand = state.demandZones[i]; + + // + to = iDemand.To(); + from = iDemand.From(); + upper = iDemand.Upper(); + lower = iDemand.Lower(); + + // + bool isInside = IsPriceInsideZone( + price, + upper, + lower // + ); + if (isInside) + { + // + XBoxZone iBox; + + // + iBox.dir = dir; + iBox.symbol = symbol; + iBox.period = period; + + // + iBox.to = to; + iBox.from = from; + iBox.upper = upper; + iBox.lower = lower; + + // + if (iBox.IsValid()) + { + // + AddRef( + iBox, + boxes // + ); + } + } + } + + // + // Support Zones ... + count = state.CountSupportZones(); + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iSupport = state.supportZones[i]; + + // + to = iSupport.To(); + from = iSupport.From(); + upper = iSupport.Upper(); + lower = iSupport.Lower(); + + // + bool isInside = IsPriceInsideZone( + price, + upper, + lower // + ); + if (isInside) + { + // + XBoxZone iBox; + + // + iBox.dir = dir; + iBox.symbol = symbol; + iBox.period = period; + + // + iBox.to = to; + iBox.from = from; + iBox.upper = upper; + iBox.lower = lower; + + // + if (iBox.IsValid()) + { + // + AddRef( + iBox, + boxes // + ); + } + } + } + } + else + { + // + double price = xConditions.peaksBuffer[1]; + dir = X_DIRECTION_BEARISH; + + // + // Bearish FVG ... + count = state.CountBearishFVGs(); + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = state.bearishFVGs[i]; + + // + to = iFVG.To(); + from = iFVG.From(); + upper = iFVG.Upper(); + lower = iFVG.Lower(); + + // + bool isInside = IsPriceInsideZone( + price, + upper, + lower // + ); + if (isInside) + { + // + XBoxZone iBox; + + // + iBox.dir = dir; + iBox.symbol = symbol; + iBox.period = period; + + // + iBox.to = to; + iBox.from = from; + iBox.upper = upper; + iBox.lower = lower; + + // + if (iBox.IsValid()) + { + // + AddRef( + iBox, + boxes // + ); + } + } + } + + // + // Supply Zones ... + count = state.CountSupplyZones(); + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *iSupply = state.supplyZones[i]; + + // + to = iSupply.To(); + from = iSupply.From(); + upper = iSupply.Upper(); + lower = iSupply.Lower(); + + // + bool isInside = IsPriceInsideZone( + price, + upper, + lower // + ); + if (isInside) + { + // + XBoxZone iBox; + + // + iBox.dir = dir; + iBox.symbol = symbol; + iBox.period = period; + + // + iBox.to = to; + iBox.from = from; + iBox.upper = upper; + iBox.lower = lower; + + // + if (iBox.IsValid()) + { + // + AddRef( + iBox, + boxes // + ); + } + } + } + + // + // Demand Zones ... + count = state.CountResistanceZones(); + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iResistance = state.resistanceZones[i]; + + // + to = iResistance.To(); + from = iResistance.From(); + upper = iResistance.Upper(); + lower = iResistance.Lower(); + + // + bool isInside = IsPriceInsideZone( + price, + upper, + lower // + ); + if (isInside) + { + // + XBoxZone iBox; + + // + iBox.dir = dir; + iBox.symbol = symbol; + iBox.period = period; + + // + iBox.to = to; + iBox.from = from; + iBox.upper = upper; + iBox.lower = lower; + + // + if (iBox.IsValid()) + { + // + AddRef( + iBox, + boxes // + ); + } + } + } + } + + // + int boxesCount = ArraySize(boxes); + bool hasBoxes = IsValidSize(boxes); + if (hasBoxes) + { + // + // Filter Boxes ... + for (int i = 0; i < boxesCount; i++) + { + // + XBoxZone iBox = boxes[i]; + + // + // Direction ... + if (!HasDirection(box.dir) || box.dir != iBox.dir) + { + box.dir = iBox.dir; + } + + // + // Upper ... + if (box.upper == 0 || box.upper < iBox.upper) + { + box.upper = iBox.upper; + } + + // + // Lower ... + if (box.lower == 0 || box.lower < iBox.lower) + { + box.lower = iBox.lower; + } + + // + // To ... + if (!IsValid(box.to) || box.to < iBox.to) + { + box.to = iBox.to; + } + + // + // From ... + if (!IsValid(box.from) || box.from > iBox.from) + { + box.from = iBox.from; + } + } + } + else + { + // + // Use Price Inside OB as Box ... + box.dir = boxDir; + box.to = priceInsideOB.To(); + box.from = priceInsideOB.From(); + box.upper = priceInsideOB.Upper(); + box.lower = priceInsideOB.Lower(); + } + } + + // + result = box.IsValid(); + + // + return result; +} + + /** + * Draw Cycle State ... + * + * @param state: X121SMCCyleState instance Reference ... + * + * @return ( int ) + */ + int DrawCycleState( + X121SMCCycleState &state, + XCBaseObject *&drawnObjects[], + bool drawOrderBlocks = true, + bool drawFairValueGaps = true, + bool drawSupplyAndDemandZones = false, + bool drawSupportAndResistanceZones = false // + ) + { + // + int result = 0; + + // + // Order Blocks ... + if (drawOrderBlocks) + { + // + // Bullish ... + bool hasBullishOBs = state.HasBullishOBs(); + int bullishOBsCount = state.CountBullishOBs(); + if (hasBullishOBs) + { + // + for (int i = 0; i < bullishOBsCount; i++) + { + // + XCOrderBlock *iOb = state.bullishOBs[i]; + + // + XCBullishOrderBlockObject *iObObj; + bool isCreated = mPOIDrawer + .CreateBullishOrderBlock( + iOb, + iObObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObObj, + drawnObjects // + ); + } + } + } + + // + // Bearish ... + bool hasBearishOBs = state.HasBearishOBs(); + int bearishOBsCount = state.CountBearishOBs(); + if (hasBearishOBs) + { + // + for (int i = 0; i < bearishOBsCount; i++) + { + // + XCOrderBlock *iOb = state.bearishOBs[i]; + + // + XCBearishOrderBlockObject *iObObj; + bool isCreated = mPOIDrawer + .CreateBearishOrderBlock( + iOb, + iObObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObObj, + drawnObjects // + ); + } + } + } + } + + // + // Fair Value Gaps ... + if (drawFairValueGaps) + { + // + // Bullish ... + bool hasBullishFVGs = state.HasBullishFVGs(); + int bullishFVGsCount = state.CountBullishFVGs(); + if (hasBullishFVGs) + { + // + for (int i = 0; i < bullishFVGsCount; i++) + { + // + XCFVG *iFVG = state.bullishFVGs[i]; + + // + XCBullishFairValueGapObject *iFVGObj; + bool isCreated = mPOIDrawer + .CreateBullishFairValueGap( + iFVG, + iFVGObj // + ); + if (isCreated) + { + // + iFVGObj.ZoneColor(clrLime); + + // + Add( + (XCBaseObject *)iFVGObj, + drawnObjects // + ); + } + } + } + + // + // Bearish ... + bool hasBearishFVGs = state.HasBearishFVGs(); + int bearishFVGsCount = state.CountBearishFVGs(); + if (hasBearishFVGs) + { + // + for (int i = 0; i < bearishFVGsCount; i++) + { + // + XCFVG *iFVG = state.bearishFVGs[i]; + + // + XCBearishFairValueGapObject *iFVGObj; + bool isCreated = mPOIDrawer + .CreateBearishFairValueGap( + iFVG, + iFVGObj // + ); + if (isCreated) + { + // + iFVGObj.ZoneColor(clrRed); + + // + Add( + (XCBaseObject *)iFVGObj, + drawnObjects // + ); + } + } + } + } + + // + // Support and Resistance Zones ... + if (drawSupportAndResistanceZones) + { + // + // Support Zones ... + bool hasSupportZones = state.HasSupportZones(); + int supportZonesCount = state.CountSupportZones(); + if (hasSupportZones) + { + // + for (int i = 0; i < supportZonesCount; i++) + { + // + XCSupportZoneObject *iObj; + bool isCreated = mPOIDrawer + .CreateSupportZone( + state.supportZones[i], + iObj // + ); + + // + if (isCreated) + { + // + iObj.ZoneColor(clrDarkSeaGreen); + + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + // Resistance Zones ... + bool hasResistanceZones = state.HasResistanceZones(); + int resistanceZonesCount = state.CountResistanceZones(); + if (hasResistanceZones) + { + // + for (int i = 0; i < resistanceZonesCount; i++) + { + // + XCResistanceZoneObject *iObj; + bool isCreated = mPOIDrawer + .CreateResistanceZone( + state.resistanceZones[i], + iObj // + ); + + // + if (isCreated) + { + // + iObj.ZoneColor(clrSaddleBrown); + + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + // Supply and Demand Zones ... + if (drawSupplyAndDemandZones) + { + // + // Demand Zones ... + bool hasDemandZones = state.HasDemandZones(); + int demandZonesCount = state.CountDemandZones(); + if (hasDemandZones) + { + // + for (int i = 0; i < demandZonesCount; i++) + { + // + XCDemandZoneObject *iObj; + bool isCreated = mPOIDrawer + .CreateDemandZone( + state.demandZones[i], + iObj // + ); + + // + if (isCreated) + { + // + iObj.ZoneColor(clrDarkTurquoise); + + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + // Supply Zones ... + bool hasSupplyZones = state.HasSupplyZones(); + int supplyZonesCount = state.CountSupplyZones(); + if (hasSupplyZones) + { + // + for (int i = 0; i < supplyZonesCount; i++) + { + // + XCSupplyZoneObject *iObj; + bool isCreated = mPOIDrawer + .CreateSupplyZone( + state.supplyZones[i], + iObj // + ); + + // + if (isCreated) + { + // + iObj.ZoneColor(clrChocolate); + + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + result = ArraySize(drawnObjects); + + // + return result; + } + +///////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////// diff --git a/Documents/BKP/1/signals/x-121.smc.x.signal.lib.mq5 b/Documents/BKP/1/signals/x-121.smc.x.signal.lib.mq5 new file mode 100644 index 00000000..c5bdd020 --- /dev/null +++ b/Documents/BKP/1/signals/x-121.smc.x.signal.lib.mq5 @@ -0,0 +1,1744 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: X +// Description: provide all Signalling functions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +// #include "../../Libraries/x-trade.lib" +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Libraries/x-121.smc.lib.mq5" +#include "../Libraries/x-121.smc.guard.lib.mq5" + +// +// Definitions ... +struct X121SMCStrategyXSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + double pivot; + double point; + + // + XCOrderBlock *bullishOBs[]; + XCOrderBlock *bearishOBs[]; + + // + // Constructor ... + X121SMCStrategyXSignalConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + sl = 0; + target = 0; + + // + dir = X_DIRECTION_NONE; + type = X_POSITION_TYPE_NONE; + + // + symbol = NULL; + period = NULL; + setupTime = NULL; + triggerTime = NULL; + + // + ExtensionClean(); + + // + ZeroMemory(this); + } + + /** + * Check Condition is Setting Up ... + * + * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... + * + * @return ( bool ) + */ + bool IsSetuped() + { + // + bool result = false; + + // + result = IsValid(setupTime) && + HasDirection(dir); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Calculate Setup Age ... + * + * @return ( int ) + */ + int GetSetupAge() + { + // + int result = 0; + + // + if (!IsSetuped()) + { + return result; + } + + // + result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); + + // + return result; + } + + /** + * Detect How we Can Trigger Signal ... + * + * @return ( bool ) + */ + bool CanTrigger() + { + // + bool result = false; + + // + result = + // + sl > 0 && + IsValid(symbol) && + IsValid(period) && + IsValid(triggerTime) && + type != X_POSITION_TYPE_ALL && + type != X_POSITION_TYPE_NONE + // + ; + + // + return result; + } + + // + // Extensions ... + + /** + * Clean Additional Properties ... + */ + void ExtensionClean() + { + // + pivot = 0; + point = 0; + + // + Clean(bullishOBs); + Clean(bearishOBs); + + // + } + + // + int CountBullishOBs() + { + return ArraySize(bullishOBs); + } + + // + bool HasBullishOBs() + { + return IsValidSize(CountBullishOBs()); + } + + // + int CountBearishOBs() + { + return ArraySize(bearishOBs); + } + + // + bool HasBearishOBs() + { + return IsValidSize(CountBearishOBs()); + } + + // +}; + +// +// Signaller Data Sources ... +X121SMCStrategyXSignalConditions mXConditions; +X121SMCStrategyXSignalConditions mXConditionsCollection[]; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCXSignalSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyXSignalConditions &conditions, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + conditions.symbol = symbol; + conditions.period = period; + + // + XOHCL zBar; + result = decisionCycleHelper.GetBar( + zBar, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = decisionCycleHelper.GetBar( + cBar, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = decisionCycleHelper.GetBar( + pBar, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + int swingLoopback = 3; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions triggerXConditions = triggerConditions.x121Conditions; + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + X121Conditions analyseXConditions = analyseConditions.x121Conditions; + X121Conditions verificationXConditions = verificationConditions.x121Conditions; + X121Conditions consolidationXConditions = consolidationConditions.x121Conditions; + X121Conditions visionXConditions = visionConditions.x121Conditions; + + // + // Setup Conditions ... + + // + // Detect Trend ... + + // + // Consolidation ... + ENUM_X_DIRECTION consolidationTrendDir; + bool hasConsolidationTrend = + consolidationCycleHelper + .DetectMarketStructure( + consolidationTrendDir // + ); + bool hasConsolidationBullishTrend = + hasConsolidationTrend && + IsBullish(consolidationTrendDir); + bool hasConsolidationBearishTrend = + hasConsolidationTrend && + IsBearish(consolidationTrendDir); + + // + // Verification ... + ENUM_X_DIRECTION verificationTrendDir; + bool hasVerificationTrend = + verificationCycleHelper + .DetectMarketStructure( + verificationTrendDir // + ); + bool hasVerificationBullishTrend = + hasVerificationTrend && + IsBullish(verificationTrendDir); + bool hasVerificationBearishTrend = + hasVerificationTrend && + IsBearish(verificationTrendDir); + + // + // Analyse ... + ENUM_X_DIRECTION analyseTrendDir; + bool hasAnalyseTrend = + analyseCycleHelper + .DetectMarketStructure( + analyseTrendDir // + ); + bool hasAnalyseBullishTrend = + hasAnalyseTrend && + IsBullish(analyseTrendDir); + bool hasAnalyseBearishTrend = + hasAnalyseTrend && + IsBearish(analyseTrendDir); + + // + // Decision ... + ENUM_X_DIRECTION decisionTrendDir; + bool hasDecisionTrend = + decisionCycleHelper + .DetectMarketStructure( + decisionTrendDir // + ); + bool hasDecisionBullishTrend = + hasDecisionTrend && + IsBullish(decisionTrendDir); + bool hasDecisionBearishTrend = + hasDecisionTrend && + IsBearish(decisionTrendDir); + + // + // Detect Bar State ... + + // + // PinBar ... + ENUM_X_DIRECTION cBarPinDir; + bool isCBarPin = decisionCycleHelper + .mBarAnalyser + .IsPinBar( + cBar, + cBarPinDir, + 1 // + ); + bool isCBarBullishPin = + isCBarPin && + IsBullish(cBarPinDir); + bool isCBarBearishPin = + isCBarPin && + IsBearish(cBarPinDir); + + // + // Engulf ... + ENUM_X_DIRECTION cBarEngulfDir; + bool isCBarEngulfed = decisionCycleHelper + .mBarAnalyser + .IsEngulfBar( + cBar, + cBarEngulfDir, + 0 // Extended ... + ); + bool isCBarBullishEngulfed = + isCBarEngulfed && + IsBullish(cBarEngulfDir); + bool isCBarBearishEngulfed = + isCBarEngulfed && + IsBearish(cBarEngulfDir); + + // + // Momentum ... + ENUM_X_DIRECTION cBarMomentumDir; + bool isCBarMomentum = decisionCycleHelper + .mBarAnalyser + .IsMomentumBar( + cBar, + cBarMomentumDir, + 0 // Extended ... + ); + bool isCBarBullishMomentum = + isCBarMomentum && + IsBullish(cBarMomentumDir); + bool isCBarBearishMomentum = + isCBarMomentum && + IsBearish(cBarMomentumDir); + + // + // Reject ... + ENUM_X_DIRECTION cBarRejectDir; + bool isCBarRejected = decisionCycleHelper + .mBarAnalyser + .IsRejectionBar( + cBar, + cBarRejectDir, + 0 // Extended ... + ); + bool isCBarBullishRejected = + isCBarRejected && + IsBullish(cBarRejectDir); + bool isCBarBearishRejected = + isCBarRejected && + IsBearish(cBarRejectDir); + + // + // Pull Back ... + ENUM_X_DIRECTION cBarPullbackDir; + bool isCBarPullbacked = + decisionCycleHelper + .mBarAnalyser + .HasPullBack( + cBarPullbackDir, + cBar // + ); + bool isCBarBullishPullbacked = + isCBarPullbacked && + IsBullish(cBarPullbackDir); + bool isCBarBearishPullbacked = + isCBarPullbacked && + IsBearish(cBarPullbackDir); + + // + // HH/LL Break ... + + // + bool isCBarBreaksUpHH = IsBarBreak( + hh, + X_DIRECTION_BULLISH, + cBar // + ); + + // + bool isCBarBreaksDownLL = IsBarBreak( + hh, + X_DIRECTION_BEARISH, + cBar // + ); + + // + // Bars Pattern and Power and Pressures ... + + // + bool hasCBarBullishPattern = + decisionCycleHelper + .mBarAnalyser + .HasBullishPattern( + cBar, + 2 // + ); + + // + bool hasCBarBearishPattern = + decisionCycleHelper + .mBarAnalyser + .HasBearishPattern( + cBar, + 2 // + ); + + // + bool isCBarHasBullishPower = + decisionCycleHelper + .mBarAnalyser + .HasBullishPower( + cBar, + 2 // + ); + + // + bool isCBarHasBearishPower = + decisionCycleHelper + .mBarAnalyser + .HasBearishPower( + cBar, + 2 // + ); + + // + bool isCBarHasBullishPressure = + decisionCycleHelper + .mBarAnalyser + .HasBullishPressure( + cBar, + 2 // + ); + + // + bool isCBarHasBearishPressure = + decisionCycleHelper + .mBarAnalyser + .HasBearishPressure( + cBar, + 2 // + ); + + // + // Bar Checking Summary ... + + // + // Bullish ... + bool isCBarBullishFormed = + // + ( + // + hasCBarBullishPattern && + isCBarHasBullishPower && + isCBarHasBullishPressure + // + ) + // + || + // + ( + // + isCBarBullishPin || + isCBarBreaksUpHH || + isCBarBullishEngulfed || + isCBarBullishMomentum || + isCBarBullishRejected + // + ) + // + ; + + // + // Bearish ... + bool isCBarBearishFormed = + // + ( + // + hasCBarBearishPattern && + isCBarHasBearishPower && + isCBarHasBearishPressure + // + ) + // + || + // + ( + // + isCBarBearishPin || + isCBarBreaksDownLL || + isCBarBearishEngulfed || + isCBarBearishMomentum || + isCBarBearishRejected + // + ) + // + ; + + // + // Detect Order Block ... + + // + bool hasBullishOrderBlocks = conditions.HasBullishOBs(); + int bullishOrderBlocksCount = conditions.CountBullishOBs(); + + // + bool hasBearishOrderBlocks = conditions.HasBearishOBs(); + int bearishOrderBlocksCount = conditions.CountBearishOBs(); + + // + bool hasOrderBlocks = hasBullishOrderBlocks && + hasBearishOrderBlocks; + if (!hasOrderBlocks) + { + // + XCOrderBlock *bullishOBs[]; + XCOrderBlock *bearishOBs[]; + bool hasOrderBlocks = visionCycleHelper.DetectOrderBlocks( + bullishOBs, + bearishOBs // + ); + + // + if (!hasBullishOrderBlocks) + { + // + Copy( + bullishOBs, + conditions.bullishOBs // + ); + } + + // + if (!hasBearishOrderBlocks) + { + // + Copy( + bearishOBs, + conditions.bearishOBs // + ); + } + + // + hasBullishOrderBlocks = conditions.HasBullishOBs(); + bullishOrderBlocksCount = conditions.CountBullishOBs(); + + // + hasBearishOrderBlocks = conditions.HasBearishOBs(); + bearishOrderBlocksCount = conditions.CountBearishOBs(); + } + + // + bool hasOldestBullishOB = false; + bool hasYoungestBullishOB = false; + XCOrderBlock *oldestBullishOB = NULL; + XCOrderBlock *youngestBullishOB = NULL; + if (hasBullishOrderBlocks) + { + // + XCZone *zones[]; + bool isConverted = ToZone( + conditions.bullishOBs, + zones // + ); + + // + int oldestIDX = GetOldest(zones); + hasOldestBullishOB = IsValidIndex(oldestIDX); + if (hasOldestBullishOB) + { + oldestBullishOB = conditions.bullishOBs[oldestIDX]; + } + + // + int youngestIDX = GetYoungest(zones); + hasYoungestBullishOB = IsValidIndex(youngestIDX); + if (hasYoungestBullishOB) + { + youngestBullishOB = conditions.bullishOBs[youngestIDX]; + } + } + + // + bool hasOldestBearishOB = false; + bool hasYoungestBearishOB = false; + XCOrderBlock *oldestBearishOB = NULL; + XCOrderBlock *youngestBearishOB = NULL; + if (hasBearishOrderBlocks) + { + // + XCZone *zones[]; + bool isConverted = ToZone( + conditions.bearishOBs, + zones // + ); + + // + int oldestIDX = GetOldest(zones); + hasOldestBearishOB = IsValidIndex(oldestIDX); + if (hasOldestBearishOB) + { + oldestBearishOB = conditions.bearishOBs[oldestIDX]; + } + + // + int youngestIDX = GetYoungest(zones); + hasYoungestBearishOB = IsValidIndex(youngestIDX); + if (hasYoungestBearishOB) + { + youngestBearishOB = conditions.bearishOBs[youngestIDX]; + } + } + + // + bool hasPriceInsideOB = false; + XCOrderBlock *priceInsideOB = NULL; + + // + if (!hasPriceInsideOB && + hasBullishOrderBlocks) + { + // + for (int i = 0; i < bullishOrderBlocksCount; i++) + { + // + XCOrderBlock *iOb = conditions.bullishOBs[i]; + + // + bool isInside = IsPriceInsideZone( + decisionXConditions.valesBuffer[1], + (XCZone *)iOb // + ); + if (isInside) + { + // + hasPriceInsideOB = true; + priceInsideOB = iOb; + break; + } + } + } + + // + if (!hasPriceInsideOB && + hasBearishOrderBlocks) + { + // + for (int i = 0; i < bearishOrderBlocksCount; i++) + { + // + XCOrderBlock *iOb = conditions.bearishOBs[i]; + + // + bool isInside = IsPriceInsideZone( + decisionXConditions.peaksBuffer[1], + (XCZone *)iOb // + ); + if (isInside) + { + // + hasPriceInsideOB = true; + priceInsideOB = iOb; + break; + } + } + } + + // + XStateZones obState; + bool hasOBState = false; + XOHCL priceInsideOBBreakerBar; + if (hasPriceInsideOB) + { + // + XOHCL toBar; + XOHCL fromBar; + ENUM_X_DIRECTION forDir = + priceInsideOB.IsBullish() + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + bool hasBreakerBar = HasBreakerBar( + toBar, + fromBar, + priceInsideOBBreakerBar, + forDir, + priceInsideOB.GetSymbol(), + priceInsideOB.GetPeriod(), + priceInsideOB.Upper(), + priceInsideOB.Lower(), + priceInsideOB.From(), + priceInsideOB.To() // + ); + if (hasBreakerBar) + { + // + CalculateStateZones( + obState, + consolidationState, + priceInsideOB.Upper(), + priceInsideOB.Lower(), + priceInsideOBBreakerBar.time // + ); + } + + // + hasOBState = obState.IsValid(); + } + + // + bool isSameCyclesPeak = + // + triggerXConditions.peaksBuffer[1] == decisionXConditions.peaksBuffer[1] && + decisionXConditions.peaksBuffer[1] == analyseXConditions.peaksBuffer[1] && + analyseXConditions.peaksBuffer[1] == verificationXConditions.peaksBuffer[1] && + verificationXConditions.peaksBuffer[1] == consolidationXConditions.peaksBuffer[1] + // + ; + + // + bool isSameCyclesVale = + // + triggerXConditions.valesBuffer[1] == decisionXConditions.valesBuffer[1] && + decisionXConditions.valesBuffer[1] == analyseXConditions.valesBuffer[1] && + analyseXConditions.valesBuffer[1] == verificationXConditions.valesBuffer[1] && + verificationXConditions.valesBuffer[1] == consolidationXConditions.valesBuffer[1] + // + ; + + // + bool hasSameCyclesPV = + hasOBState && + hasPriceInsideOB && + (isSameCyclesPeak || + isSameCyclesVale); + + // + // DRAW ... + // + + // + XCBaseObject *drawnObjects[]; + + // + if (hasBullishOrderBlocks) + { + // + for (int i = 0; i < bullishOrderBlocksCount; i++) + { + // + XCOrderBlock *iOb = conditions.bullishOBs[i]; + + // + XCBullishOrderBlockObject *iObObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateBullishOrderBlock( + iOb, + iObObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObObj, + drawnObjects // + ); + } + } + } + + // + if (hasBearishOrderBlocks) + { + // + for (int i = 0; i < bearishOrderBlocksCount; i++) + { + // + XCOrderBlock *iOb = conditions.bearishOBs[i]; + + // + XCBearishOrderBlockObject *iObObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateBearishOrderBlock( + iOb, + iObObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObObj, + drawnObjects // + ); + } + } + } + + // + // if (hasOldestBullishOB) + // { + // // + // XCBullishOrderBlockObject *iObj; + // bool isCreated = visionCycleHelper + // .mPOIDrawer + // .CreateBullishOrderBlock( + // oldestBullishOB, + // iObj // + // ); + // if (isCreated) + // { + // } + // } + + // // + // if (hasYoungestBullishOB) + // { + // // + // XCBullishOrderBlockObject *iObj; + // bool isCreated = visionCycleHelper + // .mPOIDrawer + // .CreateBullishOrderBlock( + // youngestBullishOB, + // iObj // + // ); + // if (isCreated) + // { + // } + // } + + // // + // if (hasOldestBearishOB) + // { + // // + // XCBearishOrderBlockObject *iObj; + // bool isCreated = visionCycleHelper + // .mPOIDrawer + // .CreateBearishOrderBlock( + // oldestBearishOB, + // iObj // + // ); + // if (isCreated) + // { + // } + // } + + // // + // if (hasYoungestBearishOB) + // { + // // + // XCBearishOrderBlockObject *iObj; + // bool isCreated = visionCycleHelper + // .mPOIDrawer + // .CreateBearishOrderBlock( + // youngestBearishOB, + // iObj // + // ); + // if (isCreated) + // { + // } + // } + + // + if (hasPriceInsideOB) + { + // + bool isBullish = priceInsideOB.IsBullish(); + + // + bool isCreated = false; + XCBaseObject *iObObj = NULL; + if (isBullish) + { + // + XCBullishOrderBlockObject *iObj; + isCreated = visionCycleHelper + .mPOIDrawer + .CreateBullishOrderBlock( + priceInsideOB, + iObj // + ); + + // + if (isCreated) + { + // + iObj.ZoneColor(clrYellow); + iObObj = (XCBaseObject *)iObj; + } + } + else + { + // + XCBearishOrderBlockObject *iObj; + isCreated = visionCycleHelper + .mPOIDrawer + .CreateBearishOrderBlock( + priceInsideOB, + iObj // + ); + + // + if (isCreated) + { + // + iObj.ZoneColor(clrOrangeRed); + iObObj = (XCBaseObject *)iObj; + } + } + + // + if (isCreated) + { + // + Add( + iObObj, + drawnObjects // + ); + } + } + + // + if (hasOBState) + { + // + XCBaseObject *stateObjects[]; + int stateObjectsCount = consolidationCycleHelper + .mPOIDrawer + .DrawStateZones( + obState, + stateObjects // + ); + if (IsValidSize(stateObjectsCount)) + { + // + Copy( + stateObjects, + drawnObjects, + false // + ); + } + } + + // + int drawnCount = ArraySize(drawnObjects); + if (IsValidSize(drawnCount)) + { + } + + // + // + // + + // + // Summarize Conditions ... + + // + bool isCondition1Bullish = + // + hasSameCyclesPV && + isCBarBullishFormed && + priceInsideOB.IsBullish() && + // + (decisionXConditions.isBreakedUpPrevSar || + decisionXConditions.isBreakedUpPrevStr || + decisionXConditions.isVWapMaxBreakedUp || + decisionXConditions.isBreakedUpPrevCheMax || + decisionXConditions.isBreakedUpPrevAtrLower) && + // + (decisionXConditions.isSarSwitchedToBullish || + decisionXConditions.isStrSwitchedToBullish || + decisionXConditions.isCheSwitchedToBullish || + decisionXConditions.isVWapSwitchedToBullishState || + decisionXConditions.isVWapSwitchedToBullishOrdered) + // + ; + + // + bool isCondition1Bearish = + // + hasSameCyclesPV && + isCBarBearishFormed && + priceInsideOB.IsBearish() && + // + (decisionXConditions.isBreakedDownPrevSar || + decisionXConditions.isBreakedDownPrevStr || + decisionXConditions.isVWapMinBreakedDown || + decisionXConditions.isBreakedDownPrevCheMin || + decisionXConditions.isBreakedDownPrevAtrUpper) && + // + (decisionXConditions.isSarSwitchedToBearish || + decisionXConditions.isStrSwitchedToBearish || + decisionXConditions.isCheSwitchedToBearish || + decisionXConditions.isVWapSwitchedToBearishState || + decisionXConditions.isVWapSwitchedToBearishOrdered) + // + ; + + // + bool hasCondition1 = isCondition1Bullish || + isCondition1Bearish; + if (hasCondition1) + { + // + ENUM_X_DIRECTION pzDir = + isCondition1Bullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + double point = GetEntry( + conditions.symbol, + pzDir // + ); + + // + // Manipulate Conditions Point ... + + // + conditions.point = point; + + // + // Manipulate Conditions Pivot ... + + // + conditions.pivot = + isCondition1Bullish + ? priceInsideOB.Upper() + : priceInsideOB.Lower(); + } + + // + // + // + + // + isBullish = + // + isCondition1Bullish + // + ; + + // + isBearish = + // + isCondition1Bearish + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Arrays ... + Clean(triggerPoiEvents); + Clean(triggerCycleEvents); + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + Clean(analysePoiEvents); + Clean(analyseCycleEvents); + Clean(verificationPoiEvents); + Clean(verificationCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + Clean(visionPoiEvents); + Clean(visionCycleEvents); + + // + return result; + } + + // + conditions.setupTime = cTime; + conditions.dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // Cleanup Arrays ... + Clean(triggerPoiEvents); + Clean(triggerCycleEvents); + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + Clean(analysePoiEvents); + Clean(analyseCycleEvents); + Clean(verificationPoiEvents); + Clean(verificationCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + Clean(visionPoiEvents); + Clean(visionCycleEvents); + + // + return result; +} + +// +// Detect Trigger Conditions ... +bool DetectX121SMCXSignalTrigger( + // + X121SMCStrategyXSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 60 // + // +) +{ + // + bool result = false; + + // + result = conditions.IsSetuped(); + if (!result) + { + return result; + } + + // + datetime setupTime = conditions.setupTime; + ENUM_X_DIRECTION setupDir = conditions.dir; + + // + bool isBullish = IsBullish(setupDir); + bool isBearish = IsBearish(setupDir); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + XOHCL zBar; + result = decisionCycleHelper.GetBar( + zBar, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = decisionCycleHelper.GetBar( + cBar, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = decisionCycleHelper.GetBar( + pBar, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + int swingLoopback = 9; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // Cycles Conditions ... + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState decisionState = decisionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + + // + // Trigger Conditions ... + + // + // Slopes ... + + // + bool isRsiSlopeBullish = decisionXConditions.isRsiSlopeBullish; + bool isStrSlopeBullish = decisionXConditions.isStrSlopeBullish; + bool isAtrUpperSlopeBullish = decisionXConditions.isAtrUpperSlopeBullish; + bool isAtrLowerSlopeBullish = decisionXConditions.isAtrLowerSlopeBullish; + bool isVwapFastSlopeBullish = decisionXConditions.isVwapFastSlopeBullish; + bool isVwapMidSlopeBullish = decisionXConditions.isVwapMidSlopeBullish; + bool isVwapSlowSlopeBullish = decisionXConditions.isVwapSlowSlopeBullish; + + // + bool isRsiSlopeBearish = decisionXConditions.isRsiSlopeBearish; + bool isStrSlopeBearish = decisionXConditions.isStrSlopeBearish; + bool isAtrUpperSlopeBearish = decisionXConditions.isAtrUpperSlopeBearish; + bool isAtrLowerSlopeBearish = decisionXConditions.isAtrLowerSlopeBearish; + bool isVwapFastSlopeBearish = decisionXConditions.isVwapFastSlopeBearish; + bool isVwapMidSlopeBearish = decisionXConditions.isVwapMidSlopeBearish; + bool isVwapSlowSlopeBearish = decisionXConditions.isVwapSlowSlopeBearish; + + // + bool isSlopesBullish = + isRsiSlopeBullish && + isStrSlopeBullish && + isAtrUpperSlopeBullish && + isAtrLowerSlopeBullish && + isVwapFastSlopeBullish && + isVwapMidSlopeBullish && + isVwapSlowSlopeBullish; + + // + bool isSlopesBearish = + isRsiSlopeBearish && + isStrSlopeBearish && + isAtrUpperSlopeBearish && + isAtrLowerSlopeBearish && + isVwapFastSlopeBearish && + isVwapMidSlopeBearish && + isVwapSlowSlopeBearish; + + // + double point = conditions.point; + bool isPointBreaked = IsBarBreak( + point, + setupDir, + cBar // + ); + + // + // Summary ... + + // + isBullish = + // + isBullish // && + // isPointBreaked && + // isSlopesBullish + // + ; + + // + isBearish = + // + isBearish // && + // isPointBreaked && + // isSlopesBearish + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + // Cleanup Arrays ... + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + return result; + } + + // + // Detect Nearest Pivot Point ... + + // + double entry = GetEntry( + conditions.symbol, + setupDir // + ); + + // + double sls[]; + Add( + conditions.pivot, + sls // + ); + + // + double iAtr = decisionConditions.x121Conditions.atrBuffer[1]; + iAtr *= 1.5; + + // + double slsMin = GetMin(sls); + double slsMax = GetMax(sls); + + // + double sl = isBullish + ? slsMin - iAtr + : slsMax + iAtr; + double risk = MathAbs(entry - sl); + + // + // Filling Conditions Props ... + conditions.sl = sl; + // conditions.target = target; + conditions.triggerTime = cTime; + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + // Cleanup Arrays ... + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + return result; +} + +// +// Detect Guards ... +bool DetectX121SMCXGuards( + X121SMCGuard &guards[], + const XPosition &positions[], + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper // +) +{ + // + bool result = false; + + // + string provider = ToString(X_121_SMC_PROVIDER_X); + + // + result = DetectX121SMCGuards( + provider, + guards, + positions, + triggerCycleHelper, + decisionCycleHelper, + analyseCycleHelper, + verificationCycleHelper, + consolidationCycleHelper, + visionCycleHelper, + // + true, // CloseOnTPNear Guard ... + true, // CloseLongsOnBearishTrend Guard ... + true, // CloseShortsOnBullishTrend Guard ... + true, // CloseAllWeekend Guard ... + true, // PartialCloseOnTrendChange Guard ... + true, // TrailStop Guard ... + true, // TrailTarget Guard ... + true // Hedge Guard ... + // + ); + + // + return result; +} + +// +// Add Conditions to Conditions Collection ... +int AddX121SMCXConditionsIfNotExists( + X121SMCStrategyXSignalConditions &item, + X121SMCStrategyXSignalConditions &items[], + int maxAllowed = 10 // +) +{ + // + int result = 0; + + // + bool isSetuped = IsValid(item.setupTime) && + HasDirection(item.dir); + if (!isSetuped) + { + return result; + } + + // + int count = ArraySize(items); + if (IsValidSize(count)) + { + // + // Copy Original Items ... + X121SMCStrategyXSignalConditions tmpItems[]; + Copy( + items, + tmpItems // + ); + + // + // Prese Item Data ... + bool isBullish = IsBullish(item.dir); + + // + for (int i = 0; i < count; i++) + { + // + X121SMCStrategyXSignalConditions iItem = tmpItems[i]; + + // + bool canRemove = item.dir == iItem.dir && + item.pivot == iItem.pivot; + if (canRemove) + { + // + ArrayRemove( + items, + i, + 1 // + ); + } + } + + // + Clean(tmpItems); + } + + // + AddRef( + item, + items // + ); + + // + // Remove Olds ... + CleanupArray( + items, + maxAllowed // + ); + + // + result = ArraySize(items); + + // + return result; +} + +// +// Draw Conditions ... +int DrawX121SMCXConditions( + X121SMCStrategyXSignalConditions &conditions, + XCBaseObject *&drawnObjects[], + XCPOIDrawer *drawer // +) +{ + // + int result = 0; + + // + Clean(drawnObjects); + + // + if (drawer == NULL) + { + return result; + } + + // + bool isSetuped = conditions.IsSetuped(); + if (!isSetuped) + { + return result; + } + + // + return result; +} + +// diff --git a/X121SMCEA/Signals/x-121.smc.xhkpv.signal.lib.mq5 b/Documents/BKP/1/signals/x-121.smc.xhkpv.signal.lib.mq5 similarity index 100% rename from X121SMCEA/Signals/x-121.smc.xhkpv.signal.lib.mq5 rename to Documents/BKP/1/signals/x-121.smc.xhkpv.signal.lib.mq5 diff --git a/X121SMCEA/Signals/x-121.smc.xiobpv.signal.lib.mq5 b/Documents/BKP/1/signals/x-121.smc.xiobpv.signal.lib.mq5 similarity index 100% rename from X121SMCEA/Signals/x-121.smc.xiobpv.signal.lib.mq5 rename to Documents/BKP/1/signals/x-121.smc.xiobpv.signal.lib.mq5 diff --git a/X121SMCEA/Signals/x-121.smc.xobpv.signal.lib.mq5 b/Documents/BKP/1/signals/x-121.smc.xobpv.signal.lib.mq5 similarity index 100% rename from X121SMCEA/Signals/x-121.smc.xobpv.signal.lib.mq5 rename to Documents/BKP/1/signals/x-121.smc.xobpv.signal.lib.mq5 diff --git a/Documents/BKP/1/signals/x-121.smc.xobs.signal.lib.mq5 b/Documents/BKP/1/signals/x-121.smc.xobs.signal.lib.mq5 new file mode 100644 index 00000000..bc3be793 --- /dev/null +++ b/Documents/BKP/1/signals/x-121.smc.xobs.signal.lib.mq5 @@ -0,0 +1,1738 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: XOBS +// Description: provide all Signalling functions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +// #include "../../Libraries/x-trade.lib" +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Libraries/x-121.smc.guard.lib.mq5" +#include "../Libraries/x-121.smc.lib.mq5" + +// +struct XOBTest +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + XCOrderBlock *ob; + XCFVG *fvg; + + // + datetime fvgActivatedAt; + datetime rewardedAt; + + // + double reward; + + // + // Constructor ... + XOBTest() + { + Clean(); + } + + // + // Tools ... + + // + void Clean() + { + // + ob = NULL; + fvg = NULL; + symbol = NULL; + period = NULL; + rewardedAt = NULL; + fvgActivatedAt = NULL; + + // + reward = 0; + } +}; + +// +// Definitions ... +struct X121SMCStrategyXOBSSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + double pivot; + double point; + + // + // Extwnsion ... + XOBTest obTests[]; + + // + // Constructor ... + X121SMCStrategyXOBSSignalConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + sl = 0; + target = 0; + + // + dir = X_DIRECTION_NONE; + type = X_POSITION_TYPE_NONE; + + // + symbol = NULL; + period = NULL; + setupTime = NULL; + triggerTime = NULL; + + // + ExtensionClean(); + + // + ZeroMemory(this); + } + + /** + * Check Condition is Setting Up ... + * + * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... + * + * @return ( bool ) + */ + bool IsSetuped() + { + // + bool result = false; + + // + result = IsValid(setupTime) && + HasDirection(dir); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Calculate Setup Age ... + * + * @return ( int ) + */ + int GetSetupAge() + { + // + int result = 0; + + // + if (!IsSetuped()) + { + return result; + } + + // + result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); + + // + return result; + } + + /** + * Detect How we Can Trigger Signal ... + * + * @return ( bool ) + */ + bool CanTrigger() + { + // + bool result = false; + + // + result = + // + sl > 0 && + IsValid(symbol) && + IsValid(period) && + IsValid(triggerTime) && + type != X_POSITION_TYPE_ALL && + type != X_POSITION_TYPE_NONE + // + ; + + // + return result; + } + + // + // Extensions ... + + /** + * Clean Additional Properties ... + */ + void ExtensionClean() + { + // + pivot = 0; + point = 0; + + // + Clean(obTests); + } + + // +}; + +// +// Signaller Data Sources ... +X121SMCStrategyXOBSSignalConditions mXOBSConditions; +X121SMCStrategyXOBSSignalConditions mXOBSConditionsCollection[]; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCXOBSSignalSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyXOBSSignalConditions &conditions, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int resetAfterUnActedZoneInMinutes = 120 + // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + conditions.symbol = symbol; + conditions.period = period; + + // + XC121SMCCycleHelper *barCycle = triggerCycleHelper; + + // + XOHCL zBar; + result = barCycle.GetBar( + zBar, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = barCycle.GetBar( + cBar, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = barCycle.GetBar( + pBar, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + int swingLoopback = 7; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double ll50 = cBar.FindLowest(50, MODE_LOW); + double hh50 = cBar.FindHighest(50, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions triggerXConditions = triggerConditions.x121Conditions; + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + X121Conditions analyseXConditions = analyseConditions.x121Conditions; + X121Conditions verificationXConditions = verificationConditions.x121Conditions; + X121Conditions consolidationXConditions = consolidationConditions.x121Conditions; + X121Conditions visionXConditions = visionConditions.x121Conditions; + + // + // Setup Conditions ... + + // + // Detect Trend ... + + // + // Vision ... + ENUM_X_DIRECTION visionTrendDir; + bool hasVisionTrend = + visionCycleHelper + .DetectMarketStructure( + visionTrendDir // + ); + bool hasVisionBullishTrend = + hasVisionTrend && + IsBullish(visionTrendDir); + bool hasVisionBearishTrend = + hasVisionTrend && + IsBearish(visionTrendDir); + + // + // Consolidation ... + ENUM_X_DIRECTION consolidationTrendDir; + bool hasConsolidationTrend = + consolidationCycleHelper + .DetectMarketStructure( + consolidationTrendDir // + ); + bool hasConsolidationBullishTrend = + hasConsolidationTrend && + IsBullish(consolidationTrendDir); + bool hasConsolidationBearishTrend = + hasConsolidationTrend && + IsBearish(consolidationTrendDir); + + // + // Verification ... + ENUM_X_DIRECTION verificationTrendDir; + bool hasVerificationTrend = + verificationCycleHelper + .DetectMarketStructure( + verificationTrendDir // + ); + bool hasVerificationBullishTrend = + hasVerificationTrend && + IsBullish(verificationTrendDir); + bool hasVerificationBearishTrend = + hasVerificationTrend && + IsBearish(verificationTrendDir); + + // + // Analyse ... + ENUM_X_DIRECTION analyseTrendDir; + bool hasAnalyseTrend = + analyseCycleHelper + .DetectMarketStructure( + analyseTrendDir // + ); + bool hasAnalyseBullishTrend = + hasAnalyseTrend && + IsBullish(analyseTrendDir); + bool hasAnalyseBearishTrend = + hasAnalyseTrend && + IsBearish(analyseTrendDir); + + // + // Decision ... + ENUM_X_DIRECTION decisionTrendDir; + bool hasDecisionTrend = + decisionCycleHelper + .DetectMarketStructure( + decisionTrendDir // + ); + bool hasDecisionBullishTrend = + hasDecisionTrend && + IsBullish(decisionTrendDir); + bool hasDecisionBearishTrend = + hasDecisionTrend && + IsBearish(decisionTrendDir); + + // + // Detect Bar State ... + + // + // PinBar ... + ENUM_X_DIRECTION cBarPinDir; + bool isCBarPin = decisionCycleHelper + .mBarAnalyser + .IsPinBar( + cBar, + cBarPinDir, + 1 // + ); + bool isCBarBullishPin = + isCBarPin && + IsBullish(cBarPinDir); + bool isCBarBearishPin = + isCBarPin && + IsBearish(cBarPinDir); + + // + // Engulf ... + ENUM_X_DIRECTION cBarEngulfDir; + bool isCBarEngulfed = decisionCycleHelper + .mBarAnalyser + .IsEngulfBar( + cBar, + cBarEngulfDir, + 0 // Extended ... + ); + bool isCBarBullishEngulfed = + isCBarEngulfed && + IsBullish(cBarEngulfDir); + bool isCBarBearishEngulfed = + isCBarEngulfed && + IsBearish(cBarEngulfDir); + + // + // Momentum ... + ENUM_X_DIRECTION cBarMomentumDir; + bool isCBarMomentum = decisionCycleHelper + .mBarAnalyser + .IsMomentumBar( + cBar, + cBarMomentumDir, + 0 // Extended ... + ); + bool isCBarBullishMomentum = + isCBarMomentum && + IsBullish(cBarMomentumDir); + bool isCBarBearishMomentum = + isCBarMomentum && + IsBearish(cBarMomentumDir); + + // + // Reject ... + ENUM_X_DIRECTION cBarRejectDir; + bool isCBarRejected = decisionCycleHelper + .mBarAnalyser + .IsRejectionBar( + cBar, + cBarRejectDir, + 0 // Extended ... + ); + bool isCBarBullishRejected = + isCBarRejected && + IsBullish(cBarRejectDir); + bool isCBarBearishRejected = + isCBarRejected && + IsBearish(cBarRejectDir); + + // + // Pull Back ... + ENUM_X_DIRECTION cBarPullbackDir; + bool isCBarPullbacked = + decisionCycleHelper + .mBarAnalyser + .HasPullBack( + cBarPullbackDir, + cBar // + ); + bool isCBarBullishPullbacked = + isCBarPullbacked && + IsBullish(cBarPullbackDir); + bool isCBarBearishPullbacked = + isCBarPullbacked && + IsBearish(cBarPullbackDir); + + // + // HH/LL Break ... + + // + bool isCBarBreaksUpHH = IsBarBreak( + hh, + X_DIRECTION_BULLISH, + cBar // + ); + + // + bool isCBarBreaksDownLL = IsBarBreak( + hh, + X_DIRECTION_BEARISH, + cBar // + ); + + // + // Bars Pattern and Power and Pressures ... + + // + bool hasCBarBullishPattern = + decisionCycleHelper + .mBarAnalyser + .HasBullishPattern( + cBar, + 2 // + ); + + // + bool hasCBarBearishPattern = + decisionCycleHelper + .mBarAnalyser + .HasBearishPattern( + cBar, + 2 // + ); + + // + bool isCBarHasBullishPower = + decisionCycleHelper + .mBarAnalyser + .HasBullishPower( + cBar, + 2 // + ); + + // + bool isCBarHasBearishPower = + decisionCycleHelper + .mBarAnalyser + .HasBearishPower( + cBar, + 2 // + ); + + // + bool isCBarHasBullishPressure = + decisionCycleHelper + .mBarAnalyser + .HasBullishPressure( + cBar, + 2 // + ); + + // + bool isCBarHasBearishPressure = + decisionCycleHelper + .mBarAnalyser + .HasBearishPressure( + cBar, + 2 // + ); + + // + // Bar Checking Summary ... + + // + // Bullish ... + bool isCBarBullishFormed = + // + ( + // + hasCBarBullishPattern && + isCBarHasBullishPower && + isCBarHasBullishPressure + // + ) + // + || + // + ( + // + isCBarBullishPin || + isCBarBreaksUpHH || + isCBarBullishEngulfed || + isCBarBullishMomentum || + isCBarBullishRejected + // + ) + // + ; + + // + // Bearish ... + bool isCBarBearishFormed = + // + ( + // + hasCBarBearishPattern && + isCBarHasBearishPower && + isCBarHasBearishPressure + // + ) + // + || + // + ( + // + isCBarBearishPin || + isCBarBreaksDownLL || + isCBarBearishEngulfed || + isCBarBearishMomentum || + isCBarBearishRejected + // + ) + // + ; + + // + // Detect New Order Blocks ... + bool hasNewBullishOB = Contains( + X_BULLISH_ORDERBLOCK_DETECTED, + consolidationPoiEvents // + ); + bool hasNewBearishOB = Contains( + X_BEARISH_ORDERBLOCK_DETECTED, + consolidationPoiEvents // + ); + bool hasNewOB = hasNewBullishOB || + hasNewBearishOB; + result = hasNewOB; + if (!result) + { + return result; + } + + // + // Make Sure New Order Block Detected ... + XCOrderBlock *liveOB = NULL; + if (hasNewBullishOB) + { + // + bool hasBullishOBs = consolidationState.HasBullishOrderBlocks(); + int bullishOBsCount = consolidationState.CountBullishOrderBlocks(); + if (hasBullishOBs) + { + liveOB = consolidationState.bullishOrderBlocks[bullishOBsCount - 1]; + } + } + else if (hasNewBearishOB) + { + // + bool hasBearishOBs = consolidationState.HasBearishOrderBlocks(); + int bearishOBsCount = consolidationState.CountBearishOrderBlocks(); + if (hasBearishOBs) + { + liveOB = consolidationState.bearishOrderBlocks[bearishOBsCount - 1]; + } + } + bool hasLiveOB = liveOB != NULL && + liveOB.IsValid(); + result = hasLiveOB; + if (!result) + { + return result; + } + + // + bool isLiveOBBullish = liveOB.IsBullish(); + bool isLiveOBBearish = liveOB.IsBearish(); + + // + ENUM_X_DIRECTION forDir = + isLiveOBBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isLiveOBStarted = liveOB.IsStarted( + forDir, + startedBar, + startedDir // + ); + + // + XOHCL activatedBar; + ENUM_X_DIRECTION activatedDir; + bool isLiveOBActivated = liveOB.IsActivated( + forDir, + activatedBar, + activatedDir // + ); + + // + // DRAW ... + // + + // + if (isLiveOBStarted) + { + // + XCOHCLObject *barObj; + bool isCreated = consolidationCycleHelper + .mPOIDrawer + .CreateBar( + startedBar, + barObj // + ); + } + + // + if (isLiveOBActivated) + { + // + XCOHCLObject *barObj; + bool isCreated = consolidationCycleHelper + .mPOIDrawer + .CreateBar( + activatedBar, + barObj // + ); + if (isCreated) + { + // + barObj.BodyColor(clrGold); + barObj.HighShadowColor(clrGold); + barObj.LowShadowColor(clrGold); + } + } + + // + // Draw Live OB ... + if (isLiveOBBullish) + { + // + XCBullishOrderBlockObject *iObj; + bool isCreated = consolidationCycleHelper + .mPOIDrawer + .CreateBullishOrderBlock( + liveOB, + iObj // + ); + } + else + { + // + XCBearishOrderBlockObject *iObj; + bool isCreated = consolidationCycleHelper + .mPOIDrawer + .CreateBearishOrderBlock( + liveOB, + iObj // + ); + } + + // + // END DRAW ... + // + + // + // Test Market For Order Flow ... + int obTestsCount = ArraySize(conditions.obTests); + bool isOBTested = obTestsCount == 2; + if (!isOBTested) + { + // + XOBTest test; + bool hasTest = ReTestMarket( + test, + conditions.obTests, + consolidationState, + analyseState, + decisionState, + visionCycleHelper.mPOIDrawer // + ); + if (hasTest) + { + // + AddRef( + test, + conditions.obTests); + } + } + + // + // TODO: + return false; + + // + double upper = 0; + double lower = 0; + + // + // + // + + // + // Summarize Conditions ... + + // + bool isCondition1Bullish = + // + false + // + ; + + // + bool isCondition1Bearish = + // + false + // + ; + + // + bool hasCondition1 = isCondition1Bullish || + isCondition1Bearish; + if (hasCondition1) + { + // + ENUM_X_DIRECTION pzDir = + isCondition1Bullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + double point = GetEntry( + conditions.symbol, + pzDir // + ); + + // + double longPivot = lower; // triggerXConditions.valesBuffer[1]; + double shortPivot = upper; // triggerXConditions.peaksBuffer[1]; + + // + // Manipulate Conditions Point ... + + // + conditions.point = + isCondition1Bullish + ? shortPivot + : longPivot; + + // + // Manipulate Conditions Pivot ... + + // + conditions.pivot = + isCondition1Bullish + ? longPivot + : shortPivot; + } + + // + // + // + + // + isBullish = + // + isCondition1Bullish + // + ; + + // + isBearish = + // + isCondition1Bearish + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Detect PriceOB Lifetime Bars ... + + // + // Cleanup Arrays ... + Clean(triggerPoiEvents); + Clean(triggerCycleEvents); + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + Clean(analysePoiEvents); + Clean(analyseCycleEvents); + Clean(verificationPoiEvents); + Clean(verificationCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + Clean(visionPoiEvents); + Clean(visionCycleEvents); + + // + return result; + } + + // + conditions.setupTime = cTime; + conditions.dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // Cleanup Arrays ... + Clean(triggerPoiEvents); + Clean(triggerCycleEvents); + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + Clean(analysePoiEvents); + Clean(analyseCycleEvents); + Clean(verificationPoiEvents); + Clean(verificationCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + Clean(visionPoiEvents); + Clean(visionCycleEvents); + + // + return result; +} + +// +// Detect Trigger Conditions ... +bool DetectX121SMCXOBSSignalTrigger( + // + X121SMCStrategyXOBSSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 60 // + // +) +{ + // + bool result = false; + + // + result = conditions.IsSetuped(); + if (!result) + { + return result; + } + + // + datetime setupTime = conditions.setupTime; + ENUM_X_DIRECTION setupDir = conditions.dir; + + // + bool isBullish = IsBullish(setupDir); + bool isBearish = IsBearish(setupDir); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + XOHCL zBar; + result = decisionCycleHelper.GetBar( + zBar, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = decisionCycleHelper.GetBar( + cBar, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = decisionCycleHelper.GetBar( + pBar, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + int swingLoopback = 9; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // Cycles Conditions ... + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState decisionState = decisionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + + // + // Trigger Conditions ... + + // + // Slopes ... + + // + bool isRsiSlopeBullish = decisionXConditions.isRsiSlopeBullish; + bool isStrSlopeBullish = decisionXConditions.isStrSlopeBullish; + bool isAtrUpperSlopeBullish = decisionXConditions.isAtrUpperSlopeBullish; + bool isAtrLowerSlopeBullish = decisionXConditions.isAtrLowerSlopeBullish; + bool isVwapFastSlopeBullish = decisionXConditions.isVwapFastSlopeBullish; + bool isVwapMidSlopeBullish = decisionXConditions.isVwapMidSlopeBullish; + bool isVwapSlowSlopeBullish = decisionXConditions.isVwapSlowSlopeBullish; + + // + bool isRsiSlopeBearish = decisionXConditions.isRsiSlopeBearish; + bool isStrSlopeBearish = decisionXConditions.isStrSlopeBearish; + bool isAtrUpperSlopeBearish = decisionXConditions.isAtrUpperSlopeBearish; + bool isAtrLowerSlopeBearish = decisionXConditions.isAtrLowerSlopeBearish; + bool isVwapFastSlopeBearish = decisionXConditions.isVwapFastSlopeBearish; + bool isVwapMidSlopeBearish = decisionXConditions.isVwapMidSlopeBearish; + bool isVwapSlowSlopeBearish = decisionXConditions.isVwapSlowSlopeBearish; + + // + bool isSlopesBullish = + isRsiSlopeBullish && + isStrSlopeBullish && + isAtrUpperSlopeBullish && + isAtrLowerSlopeBullish && + isVwapFastSlopeBullish && + isVwapMidSlopeBullish && + isVwapSlowSlopeBullish; + + // + bool isSlopesBearish = + isRsiSlopeBearish && + isStrSlopeBearish && + isAtrUpperSlopeBearish && + isAtrLowerSlopeBearish && + isVwapFastSlopeBearish && + isVwapMidSlopeBearish && + isVwapSlowSlopeBearish; + + // + double point = conditions.point; + bool isPointBreaked = IsBarBreak( + point, + setupDir, + cBar // + ); + + // + // Summary ... + + // + isBullish = + // + isBullish && + isPointBreaked && + isSlopesBullish + // + ; + + // + isBearish = + // + isBearish && + isPointBreaked && + isSlopesBearish + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + // Cleanup Arrays ... + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + return result; + } + + // + // Detect Nearest Pivot Point ... + + // + double entry = GetEntry( + conditions.symbol, + setupDir // + ); + + // + double sls[]; + Add( + conditions.pivot, + sls // + ); + + // + double iAtr = decisionConditions.x121Conditions.atrBuffer[1]; + iAtr *= 1.5; + + // + double slsMin = GetMin(sls); + double slsMax = GetMax(sls); + + // + double sl = isBullish + ? slsMin - iAtr + : slsMax + iAtr; + double risk = MathAbs(entry - sl); + + // + // Filling Conditions Props ... + conditions.sl = sl; + // conditions.target = target; + conditions.triggerTime = cTime; + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + // Cleanup Arrays ... + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + return result; +} + +// +// Detect Guards ... +bool DetectX121SMCXOBSGuards( + X121SMCGuard &guards[], + const XPosition &positions[], + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper // +) +{ + // + bool result = false; + + // + string provider = ToString(X_121_SMC_PROVIDER_X); + + // + result = DetectX121SMCGuards( + provider, + guards, + positions, + triggerCycleHelper, + decisionCycleHelper, + analyseCycleHelper, + verificationCycleHelper, + consolidationCycleHelper, + visionCycleHelper, + // + true, // CloseOnTPNear Guard ... + true, // CloseLongsOnBearishTrend Guard ... + true, // CloseShortsOnBullishTrend Guard ... + true, // CloseAllWeekend Guard ... + true, // PartialCloseOnTrendChange Guard ... + true, // TrailStop Guard ... + true, // TrailTarget Guard ... + true // Hedge Guard ... + // + ); + + // + return result; +} + +// +// Add Conditions to Conditions Collection ... +int AddX121SMCXOBSConditionsIfNotExists( + X121SMCStrategyXOBSSignalConditions &item, + X121SMCStrategyXOBSSignalConditions &items[], + int maxAllowed = 10 // +) +{ + // + int result = 0; + + // + bool isSetuped = IsValid(item.setupTime) && + HasDirection(item.dir); + if (!isSetuped) + { + return result; + } + + // + int count = ArraySize(items); + if (IsValidSize(count)) + { + // + // Copy Original Items ... + X121SMCStrategyXOBSSignalConditions tmpItems[]; + Copy( + items, + tmpItems // + ); + + // + // Prese Item Data ... + bool isBullish = IsBullish(item.dir); + + // + for (int i = 0; i < count; i++) + { + // + X121SMCStrategyXOBSSignalConditions iItem = tmpItems[i]; + + // + bool canRemove = item.dir == iItem.dir && + item.pivot == iItem.pivot; + if (canRemove) + { + // + ArrayRemove( + items, + i, + 1 // + ); + } + } + + // + Clean(tmpItems); + } + + // + AddRef( + item, + items // + ); + + // + // Remove Olds ... + CleanupArray( + items, + maxAllowed // + ); + + // + result = ArraySize(items); + + // + return result; +} + +// +// +// + +bool ReTestMarket( + XOBTest &test, + XOBTest &tests[], + XPOIState &htfState, + XPOIState &mtfState, + XPOIState &ttfState, // + // + XCPOIDrawer *drawer + // +) +{ + // + bool result = false; + + // + test.Clean(); + + // + int testsCount = ArraySize(tests); + bool hasTests = IsValidSize(testsCount); + XOBTest lastTest; + if (hasTests) + { + lastTest = tests[testsCount - 1]; + } + + // + // Detect Order Blocks ... + // HTF ... + + // + // Bullish OBs ... + XCOrderBlock *bullOBs[]; + int bullOBsCount = ExtractUnActivatedOBs( + htfState.bullishOrderBlocks, + bullOBs, + drawer // + ); + + // + bool isBullOBsPassed = bullOBsCount >= 1; + + // + // Bearish OBs ... + XCOrderBlock *bearOBs[]; + int bearOBsCount = ExtractUnActivatedOBs( + htfState.bearishOrderBlocks, + bearOBs, + drawer // + ); + + // + bool isBearOBsPassed = bearOBsCount >= 1; + + // + result = isBullOBsPassed || + isBearOBsPassed; + if (!result) + { + return result; + } + + // + Print("OBs Passed ..."); + + // + return result; +} + +int ExtractUnActivatedOBs( + XCOrderBlock *&source[], + XCOrderBlock *&obs[], // + // + XCPOIDrawer *drawer + // +) +{ + // + int result = 0; + + // + Clean(obs); + + // + int count = ArraySize(source); + bool hasOB = IsValidSize(count); + if (!hasOB) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + bool isBullish = source[i].IsBullish(); + ENUM_X_DIRECTION forDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = source[i].IsStarted( + forDir, + startedBar, + startedDir // + ); + // if (isStarted) + // { + // // + // XCOHCLObject *barObj; + // bool isCreated = drawer.CreateBar( + // startedBar, + // barObj // + // ); + // + // // + // if (isBullish) + // { + // // + // XCBullishOrderBlockObject *iObj; + // bool isCreated = drawer.CreateBullishOrderBlock( + // source[i], + // iObj // + // ); + // } + // else + // { + // // + // XCBearishOrderBlockObject *iObj; + // bool isCreated = drawer.CreateBearishOrderBlock( + // source[i], + // iObj // + // ); + // } + // + // // + // Print("Started ..."); + // } + + // + // + // + + // + XOHCL activatedBar; + ENUM_X_DIRECTION activatedDir; + bool isActivated = source[i].IsActivated( + forDir, + activatedBar, + activatedDir // + ); + if (isActivated) + { + // // + // XCOHCLObject *barObj; + // bool isCreated = drawer.CreateBar( + // activatedBar, + // barObj // + // ); + + // // + // if (isBullish) + // { + // // + // XCBullishOrderBlockObject *iObj; + // bool isCreated = drawer.CreateBullishOrderBlock( + // source[i], + // iObj // + // ); + // } + // else + // { + // // + // XCBearishOrderBlockObject *iObj; + // bool isCreated = drawer.CreateBearishOrderBlock( + // source[i], + // iObj // + // ); + // } + + // // + // Print("Activated ..."); + } + else + { + // + Print("UnActivated ..."); + } + + // + // + // + + // + // if (isBullish) + // { + // // + // XCBullishOrderBlockObject *iObj; + // bool isCreated = drawer.CreateBullishOrderBlock( + // source[i], + // iObj // + // ); + // } + // else + // { + // // + // XCBearishOrderBlockObject *iObj; + // bool isCreated = drawer.CreateBearishOrderBlock( + // source[i], + // iObj // + // ); + // } + + // // + // XOHCL activatedBar; + // ENUM_X_DIRECTION activatedDir; + // ENUM_X_DIRECTION forDir = + // isBullish + // ? X_DIRECTION_BULLISH + // : X_DIRECTION_BEARISH; + // bool isActivated = source[i].IsActivated( + // forDir, + // activatedBar, + // activatedDir // + // ); + // if (!isActivated) + // { + // // + // XCOHCLObject *barObj; + // bool isCreated = drawer.CreateBar( + // activatedBar, + // barObj // + // ); + + // // + // bool isBullish = source[i].IsBullish(); + // if (isBullish) + // { + // // + // XCBullishOrderBlockObject *iObj; + // bool isCreated = drawer.CreateBullishOrderBlock( + // source[i], + // iObj // + // ); + // } + // else + // { + // // + // XCBearishOrderBlockObject *iObj; + // bool isCreated = drawer.CreateBearishOrderBlock( + // source[i], + // iObj // + // ); + // } + // // + // Add( + // source[i], + // obs // + // ); + // } + } + + // + result = ArraySize(obs); + + // + return result; +} + +// diff --git a/Documents/BKP/1/x-121.smc.guard.lib.mq5 b/Documents/BKP/1/x-121.smc.guard.lib.mq5 new file mode 100644 index 00000000..994ee91d --- /dev/null +++ b/Documents/BKP/1/x-121.smc.guard.lib.mq5 @@ -0,0 +1,1699 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: +// Description: provide all Global Guarding functions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Libraries/x-121.smc.lib.mq5" + +// +XPriceZones x121SMCDecisionPriceZone; +XPriceZones x121SMCAnalysePriceZone; +XPriceZones x121SMCVerificationPriceZone; +XConsolidationZone x121SMCConsolidationZone; +bool DetectX121SMCGuards( + string provider, // Provider ... + X121SMCGuard &guards[], + const XPosition &positions[], + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + // Guard Types ... + bool ignoreCloseOnTPNearGuard = false, + bool ignoreCloseLongsOnBearishTrendGuard = false, + bool ignoreCloseShortsOnBullishTrendGuard = false, + bool ignoreCloseAllWeekendGuard = false, + bool ignorePartialCloseOnTrendChangeGuard = false, + bool ignoreTrailStopGuard = false, + bool ignoreTrailTargetGuard = false, + bool ignoreHedgeGuard = false + // +) +{ + // + bool result = false; + + // + bool isAllIgnore = + // + ignoreCloseOnTPNearGuard && + ignoreCloseLongsOnBearishTrendGuard && + ignoreCloseShortsOnBullishTrendGuard && + ignoreCloseAllWeekendGuard && + ignorePartialCloseOnTrendChangeGuard && + ignoreTrailStopGuard && + ignoreTrailTargetGuard && + ignoreHedgeGuard + // + ; + result = !isAllIgnore; + if (!result) + { + return result; + } + + // + int count = ArraySize(positions); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + string symbol = triggerCycleHelper.GetSymbol(); + ENUM_TIMEFRAMES period = triggerCycleHelper.GetPeriod(); + + // + XPosition ownPositions[]; + XPosition ownLongPositions[]; + XPosition ownShortPositions[]; + for (int i = 0; i < count; i++) + { + // + XPosition iPosition = positions[i]; + bool isOwn = iPosition + .IsFiltersPassed( + symbol, + provider, + NULL, + X_POSITION_TYPE_ALL, + iPosition.magic // + ); + if (isOwn) + { + // + AddRef( + iPosition, + ownPositions // + ); + + // + bool isLong = IsLong(positions[i].type); + if (isLong) + { + // + AddRef( + iPosition, + ownLongPositions // + ); + } + else + { + // + AddRef( + iPosition, + ownShortPositions // + ); + } + } + } + + // + count = ArraySize(ownPositions); + + // + int longsCount = ArraySize(ownLongPositions); + bool hasLongs = IsValidSize(longsCount); + + // + int shortsCount = ArraySize(ownShortPositions); + bool hasShorts = IsValidSize(shortsCount); + + // + result = IsValidSize(count); + if (!result) + { + // + Clean(ownPositions); + Clean(ownLongPositions); + Clean(ownShortPositions); + + // + x121SMCAnalysePriceZone.Clean(); + x121SMCDecisionPriceZone.Clean(); + x121SMCConsolidationZone.Clean(); + x121SMCVerificationPriceZone.Clean(); + + // + return result; + } + + // + // Here we Are Sure there is Positions to Guard ... + // based on Current Provider ... + + // + // Detect Required Data for Analyse Market to Guard Positions ... + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + int swingLoopback = 3; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions triggerXConditions = triggerConditions.x121Conditions; + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + X121Conditions analyseXConditions = analyseConditions.x121Conditions; + X121Conditions verificationXConditions = verificationConditions.x121Conditions; + X121Conditions consolidationXConditions = consolidationConditions.x121Conditions; + X121Conditions visionXConditions = visionConditions.x121Conditions; + + // + // Trigger ... + ENUM_X_DIRECTION triggerTrendDir; + bool hasTriggerTrend = + triggerCycleHelper + .DetectMarketStructure( + triggerTrendDir // + ); + bool hasTriggerBullishTrend = + hasTriggerTrend && + IsBullish(triggerTrendDir); + bool hasTriggerBearishTrend = + hasTriggerTrend && + IsBearish(triggerTrendDir); + + // + // Decision ... + ENUM_X_DIRECTION decisionTrendDir; + bool hasDecisionTrend = + decisionCycleHelper + .DetectMarketStructure( + decisionTrendDir // + ); + bool hasDecisionBullishTrend = + hasDecisionTrend && + IsBullish(decisionTrendDir); + bool hasDecisionBearishTrend = + hasDecisionTrend && + IsBearish(decisionTrendDir); + + // + // Analyse ... + ENUM_X_DIRECTION analyseTrendDir; + bool hasAnalyseTrend = + analyseCycleHelper + .DetectMarketStructure( + analyseTrendDir // + ); + bool hasAnalyseBullishTrend = + hasAnalyseTrend && + IsBullish(analyseTrendDir); + bool hasAnalyseBearishTrend = + hasAnalyseTrend && + IsBearish(analyseTrendDir); + + // + // + // + + // + // Detect Consolidation Zone ... + + // + int consolidationLoopback = 7; + double consolidationZoneLower = 0; + double consolidationZoneUpper = 0; + bool isConsolidationZoneBreaked = false; + bool isConsolidationZoneBreakedUp = false; + bool isConsolidationZoneBreakedDown = false; + bool hasConsolidationZone = x121SMCConsolidationZone.IsValid(); + + // + if (!hasConsolidationZone) + { + // + double upper = 0; + double lower = 0; + hasConsolidationZone = + triggerCycleHelper + .mBarAnalyser + .IsConsolidate( + cBar, + upper, + lower, + consolidationLoopback // + ); + + // + if (hasConsolidationZone) + { + // + hasConsolidationZone = x121SMCConsolidationZone.Init( + cBar.symbol, + cBar.period, + upper, + lower, + consolidationLoopback // + ); + } + } + + // + if (hasConsolidationZone) + { + // + x121SMCConsolidationZone.Update(); + + // + consolidationZoneUpper = x121SMCConsolidationZone.upper; + consolidationZoneLower = x121SMCConsolidationZone.lower; + + // + isConsolidationZoneBreaked = x121SMCConsolidationZone.IsBreaked(); + isConsolidationZoneBreakedUp = + isConsolidationZoneBreaked && + IsBullish(x121SMCConsolidationZone.breakDirection); + isConsolidationZoneBreakedDown = + isConsolidationZoneBreaked && + IsBearish(x121SMCConsolidationZone.breakDirection); + + // + consolidationZoneUpper = triggerXConditions.peaksBuffer[1]; + consolidationZoneLower = triggerXConditions.valesBuffer[1]; + + // + if (isConsolidationZoneBreaked) + { + x121SMCConsolidationZone.Clean(); + } + } + + // + // Detect Price Zones ... + + // + // Decision ... + double decisionPriceZoneUpper = 0; + double decisionPriceZoneLower = 0; + bool isDecisionPriceZoneBearish = false; + bool isDecisionPriceZoneBullish = false; + bool isDecisionPriceZoneValidForPeak = false; + bool isDecisionPriceZoneValidForVale = false; + bool isDecisionPriceZoneLowerRejected = false; + bool isDecisionPriceZoneUpperRejected = false; + bool isDecisionPriceZoneUpperBreakedUp = false; + bool isDecisionPriceZoneLowerBreakedDown = false; + bool hasDecisionPriceZone = x121SMCDecisionPriceZone.IsValid(); + + // + if (!hasDecisionPriceZone) + { + // + hasDecisionPriceZone = CalculatePriceInsideZones( + x121SMCDecisionPriceZone, + decisionState, + cBar // + ); + } + + // + if (hasDecisionPriceZone) + { + // + bool hasBoundary = x121SMCDecisionPriceZone.GetBoundary( + X_DIRECTION_ALL, + decisionPriceZoneUpper, + decisionPriceZoneLower // + ); + + // + isDecisionPriceZoneBearish = x121SMCDecisionPriceZone.IsBearish(); + isDecisionPriceZoneBullish = x121SMCDecisionPriceZone.IsBullish(); + + // + XOHCL iBar; + bool isInited = iBar.Init( + symbol, + decisionXConditions.period, + cIndex // + ); + + // + if (hasBoundary) + { + // + isDecisionPriceZoneValidForPeak = + decisionXConditions.peaksBuffer[1] <= decisionPriceZoneUpper && + decisionXConditions.peaksBuffer[1] >= decisionPriceZoneLower; + + // + isDecisionPriceZoneValidForVale = + decisionXConditions.valesBuffer[1] <= decisionPriceZoneUpper && + decisionXConditions.valesBuffer[1] >= decisionPriceZoneLower; + + // + isDecisionPriceZoneLowerRejected = + isInited && + IsBarReject( + decisionPriceZoneLower, + X_DIRECTION_BULLISH, + iBar // + ); + + // + isDecisionPriceZoneUpperRejected = + isInited && + IsBarReject( + decisionPriceZoneUpper, + X_DIRECTION_BEARISH, + iBar // + ); + + // + isDecisionPriceZoneUpperBreakedUp = + isInited && + IsBarBreak( + decisionPriceZoneUpper, + X_DIRECTION_BULLISH, + iBar // + ); + + // + isDecisionPriceZoneLowerBreakedDown = + isInited && + IsBarBreak( + decisionPriceZoneUpper, + X_DIRECTION_BEARISH, + iBar // + ); + } + + // + // Clear Price Zone ... + bool canReset = + // + (!isInited || + !hasBoundary) + // + || + // + (isInited && + hasBoundary && + (iBar.high < decisionPriceZoneLower || + iBar.low > decisionPriceZoneUpper)) + // + ; + if (canReset) + { + // + x121SMCDecisionPriceZone.Clean(); + + // + decisionPriceZoneUpper = 0; + decisionPriceZoneLower = 0; + isDecisionPriceZoneBearish = false; + isDecisionPriceZoneBullish = false; + isDecisionPriceZoneValidForPeak = false; + isDecisionPriceZoneValidForVale = false; + isDecisionPriceZoneLowerRejected = false; + isDecisionPriceZoneUpperRejected = false; + isDecisionPriceZoneUpperBreakedUp = false; + isDecisionPriceZoneLowerBreakedDown = false; + } + } + + // + // Analyse ... + double analysePriceZoneUpper = 0; + double analysePriceZoneLower = 0; + bool isAnalysePriceZoneBearish = false; + bool isAnalysePriceZoneBullish = false; + bool isAnalysePriceZoneValidForPeak = false; + bool isAnalysePriceZoneValidForVale = false; + bool isAnalysePriceZoneLowerRejected = false; + bool isAnalysePriceZoneUpperRejected = false; + bool isAnalysePriceZoneUpperBreakedUp = false; + bool isAnalysePriceZoneLowerBreakedDown = false; + bool hasAnalysePriceZone = x121SMCAnalysePriceZone.IsValid(); + + // + if (!hasAnalysePriceZone) + { + // + hasAnalysePriceZone = CalculatePriceInsideZones( + x121SMCAnalysePriceZone, + analyseState, + cBar // + ); + } + + // + if (hasAnalysePriceZone) + { + // + bool hasBoundary = x121SMCAnalysePriceZone.GetBoundary( + X_DIRECTION_ALL, + analysePriceZoneUpper, + analysePriceZoneLower // + ); + + // + isAnalysePriceZoneBearish = x121SMCAnalysePriceZone.IsBearish(); + isAnalysePriceZoneBullish = x121SMCAnalysePriceZone.IsBullish(); + + // + XOHCL iBar; + bool isInited = iBar.Init( + symbol, + analyseXConditions.period, + cIndex // + ); + + // + if (hasBoundary) + { + // + isAnalysePriceZoneValidForPeak = + analyseXConditions.peaksBuffer[1] <= analysePriceZoneUpper && + analyseXConditions.peaksBuffer[1] >= analysePriceZoneLower; + + // + isAnalysePriceZoneValidForVale = + analyseXConditions.valesBuffer[1] <= analysePriceZoneUpper && + analyseXConditions.valesBuffer[1] >= analysePriceZoneLower; + + // + isAnalysePriceZoneLowerRejected = + isInited && + IsBarReject( + analysePriceZoneLower, + X_DIRECTION_BULLISH, + iBar // + ); + + // + isAnalysePriceZoneUpperRejected = + isInited && + IsBarReject( + analysePriceZoneUpper, + X_DIRECTION_BEARISH, + iBar // + ); + + // + isAnalysePriceZoneUpperBreakedUp = + isInited && + IsBarBreak( + analysePriceZoneUpper, + X_DIRECTION_BULLISH, + iBar // + ); + + // + isAnalysePriceZoneLowerBreakedDown = + isInited && + IsBarBreak( + analysePriceZoneUpper, + X_DIRECTION_BEARISH, + iBar // + ); + } + + // + // Clear Price Zone ... + bool canReset = + // + (!isInited || + !hasBoundary) + // + || + // + (isInited && + hasBoundary && + (iBar.high < analysePriceZoneLower || + iBar.low > analysePriceZoneUpper)) + // + ; + if (canReset) + { + // + x121SMCAnalysePriceZone.Clean(); + + // + analysePriceZoneUpper = 0; + analysePriceZoneLower = 0; + isAnalysePriceZoneBearish = false; + isAnalysePriceZoneBullish = false; + isAnalysePriceZoneValidForPeak = false; + isAnalysePriceZoneValidForVale = false; + isAnalysePriceZoneLowerRejected = false; + isAnalysePriceZoneUpperRejected = false; + isAnalysePriceZoneUpperBreakedUp = false; + isAnalysePriceZoneLowerBreakedDown = false; + } + } + + // + // Verification ... + double verificationPriceZoneUpper = 0; + double verificationPriceZoneLower = 0; + bool isVerificationPriceZoneBearish = false; + bool isVerificationPriceZoneBullish = false; + bool isVerificationPriceZoneValidForPeak = false; + bool isVerificationPriceZoneValidForVale = false; + bool isVerificationPriceZoneLowerRejected = false; + bool isVerificationPriceZoneUpperRejected = false; + bool isVerificationPriceZoneUpperBreakedUp = false; + bool isVerificationPriceZoneLowerBreakedDown = false; + bool hasVerificationPriceZone = x121SMCVerificationPriceZone.IsValid(); + + // + if (!hasVerificationPriceZone) + { + // + hasVerificationPriceZone = CalculatePriceInsideZones( + x121SMCVerificationPriceZone, + verificationState, + cBar // + ); + } + + // + if (hasVerificationPriceZone) + { + // + bool hasBoundary = x121SMCVerificationPriceZone.GetBoundary( + X_DIRECTION_ALL, + verificationPriceZoneUpper, + verificationPriceZoneLower // + ); + + // + isVerificationPriceZoneBearish = x121SMCVerificationPriceZone.IsBearish(); + isVerificationPriceZoneBullish = x121SMCVerificationPriceZone.IsBullish(); + + // + XOHCL iBar; + bool isInited = iBar.Init( + symbol, + verificationXConditions.period, + cIndex // + ); + + // + if (hasBoundary) + { + // + isVerificationPriceZoneValidForPeak = + verificationXConditions.peaksBuffer[1] <= verificationPriceZoneUpper && + verificationXConditions.peaksBuffer[1] >= verificationPriceZoneLower; + + // + isVerificationPriceZoneValidForVale = + verificationXConditions.valesBuffer[1] <= verificationPriceZoneUpper && + verificationXConditions.valesBuffer[1] >= verificationPriceZoneLower; + + // + isVerificationPriceZoneLowerRejected = + isInited && + IsBarReject( + verificationPriceZoneLower, + X_DIRECTION_BULLISH, + iBar // + ); + + // + isVerificationPriceZoneUpperRejected = + isInited && + IsBarReject( + verificationPriceZoneUpper, + X_DIRECTION_BEARISH, + iBar // + ); + + // + isVerificationPriceZoneUpperBreakedUp = + isInited && + IsBarBreak( + verificationPriceZoneUpper, + X_DIRECTION_BULLISH, + iBar // + ); + + // + isVerificationPriceZoneLowerBreakedDown = + isInited && + IsBarBreak( + verificationPriceZoneUpper, + X_DIRECTION_BEARISH, + iBar // + ); + } + + // + // Clear Price Zone ... + bool canReset = + // + (!isInited || + !hasBoundary) + // + || + // + (isInited && + hasBoundary && + (iBar.high < verificationPriceZoneLower || + iBar.low > verificationPriceZoneUpper)) + // + ; + if (canReset) + { + // + x121SMCVerificationPriceZone.Clean(); + + // + verificationPriceZoneUpper = 0; + verificationPriceZoneLower = 0; + isVerificationPriceZoneBearish = false; + isVerificationPriceZoneBullish = false; + isVerificationPriceZoneValidForPeak = false; + isVerificationPriceZoneValidForVale = false; + isVerificationPriceZoneLowerRejected = false; + isVerificationPriceZoneUpperRejected = false; + isVerificationPriceZoneUpperBreakedUp = false; + isVerificationPriceZoneLowerBreakedDown = false; + } + } + + // + // Here We Have all Requirements for Guarding Positions ... + + // + // + // + + // + // Close ... + if (!ignoreCloseOnTPNearGuard) + { + // + double tpCloseDiff = (15 * points); + for (int i = 0; i < count; i++) + { + // + XPosition iPosition = ownPositions[i]; + + // + // Position Must be In Profit ... + if (iPosition.profit <= 0) + { + continue; + } + + // + bool isPricePassed = MathAbs(iPosition.tp - iPosition.price) <= tpCloseDiff; + if (!isPricePassed) + { + continue; + } + + // + bool isLong = IsLong(iPosition.type); + + // + bool iHasGuard = + // + isLong + ? // + (hasDecisionPriceZone && + isDecisionPriceZoneBearish && + isDecisionPriceZoneValidForPeak) + // + || + // + (hasAnalysePriceZone && + isAnalysePriceZoneBearish && + isAnalysePriceZoneValidForPeak) + // + || + // + (hasVerificationPriceZone && + isVerificationPriceZoneBearish && + isVerificationPriceZoneValidForPeak) + : // + (hasDecisionPriceZone && + isDecisionPriceZoneBullish && + isDecisionPriceZoneValidForVale) + // + || + // + (hasAnalysePriceZone && + isAnalysePriceZoneBullish && + isAnalysePriceZoneValidForVale) + // + || + // + (hasVerificationPriceZone && + isVerificationPriceZoneBullish && + isVerificationPriceZoneValidForVale) + // + ; + if (iHasGuard) + { + // + X121SMCGuard iGuard; + + // + iGuard.time = cTime; + iGuard.symbol = symbol; + iGuard.provider = provider; + iGuard.action = X_121_SMC_GUARD_ACTION_CLOSE; + + // + iGuard.ticket = iPosition.ticket; + + // + AddGuard( + iGuard, + guards // + ); + } + } + } + + // + if (hasLongs) + { + // + if (!ignoreCloseLongsOnBearishTrendGuard) + { + // + bool hasGuard = hasDecisionBearishTrend; + + // + if (hasGuard) + { + // + for (int i = 0; i < longsCount; i++) + { + // + XPosition iPosition = ownLongPositions[i]; + + // + // Position must be in Draw Down ... + if (iPosition.profit > 0) + { + continue; + } + + // + X121SMCGuard iGuard; + + // + iGuard.time = cTime; + iGuard.symbol = symbol; + iGuard.provider = provider; + iGuard.action = X_121_SMC_GUARD_ACTION_CLOSE; + + // + iGuard.ticket = iPosition.ticket; + + // + AddGuard( + iGuard, + guards // + ); + } + } + } + } + + // + if (hasShorts) + { + // + if (!ignoreCloseShortsOnBullishTrendGuard) + { + // + bool hasGuard = hasDecisionBullishTrend; + + // + if (hasGuard) + { + // + for (int i = 0; i < shortsCount; i++) + { + // + XPosition iPosition = ownShortPositions[i]; + + // + // Position must be in Draw Down ... + if (iPosition.profit > 0) + { + continue; + } + + // + X121SMCGuard iGuard; + + // + iGuard.time = cTime; + iGuard.symbol = symbol; + iGuard.provider = provider; + iGuard.action = X_121_SMC_GUARD_ACTION_CLOSE; + + // + iGuard.ticket = iPosition.ticket; + + // + AddGuard( + iGuard, + guards // + ); + } + } + } + } + + // + // Close All ... + + // + // Close All Weekend ... + if (!ignoreCloseAllWeekendGuard) + { + // + MqlDateTime mDate; + bool hasDate = TimeCurrent(mDate); + if (hasDate) + { + // + ENUM_X_WEEK_DAYS dayOfWeek = GetDayOfWeek(); + + // + bool isWeekend = dayOfWeek == X_WEEK_DAY_FRIDAY; + if (isWeekend && mDate.hour == 23 && mDate.min == 30) + { + // + X121SMCGuard guard; + + // + guard.time = cTime; + guard.symbol = symbol; + guard.provider = provider; + guard.action = X_121_SMC_GUARD_ACTION_CLOSE_ALL; + + // + AddGuard( + guard, + guards // + ); + } + } + } + + // + // Close Longs ... + if (hasLongs) + { + // + bool hasGuard = + // + hasAnalyseBearishTrend && + hasDecisionBearishTrend + // + ; + + // + if (hasGuard) + { + // + X121SMCGuard guard; + + // + guard.time = cTime; + guard.symbol = symbol; + guard.provider = provider; + guard.action = X_121_SMC_GUARD_ACTION_CLOSE_LONGS; + + // + AddGuard( + guard, + guards // + ); + } + } + + // + // Close Shorts ... + if (hasShorts) + { + // + bool hasGuard = + // + hasAnalyseBullishTrend && + hasDecisionBullishTrend + // + ; + + // + if (hasGuard) + { + // + X121SMCGuard guard; + + // + guard.time = cTime; + guard.symbol = symbol; + guard.provider = provider; + guard.action = X_121_SMC_GUARD_ACTION_CLOSE_SHORTS; + + // + AddGuard( + guard, + guards // + ); + } + } + + // + // Partial Close ... + + // + if (!ignorePartialCloseOnTrendChangeGuard) + { + // + if (hasLongs) + { + // + bool hasGuard = + // + hasTriggerBearishTrend || + !hasDecisionBullishTrend + // + ; + + // + if (hasGuard) + { + // + for (int i = 0; i < longsCount; i++) + { + // + XPosition iPosition = ownLongPositions[i]; + + // + X121SMCGuard iGuard; + + // + iGuard.time = cTime; + iGuard.symbol = symbol; + iGuard.provider = provider; + iGuard.action = X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE; + + // + iGuard.ticket = iPosition.ticket; + iGuard.volumeMultiplier = 0.5; + + // + AddGuard( + iGuard, + guards // + ); + } + } + } + + // + if (hasShorts) + { + // + bool hasGuard = + // + hasTriggerBullishTrend || + !hasDecisionBearishTrend + // + ; + + // + if (hasGuard) + { + // + for (int i = 0; i < shortsCount; i++) + { + // + XPosition iPosition = ownShortPositions[i]; + + // + X121SMCGuard iGuard; + + // + iGuard.time = cTime; + iGuard.symbol = symbol; + iGuard.provider = provider; + iGuard.action = X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE; + + // + iGuard.ticket = iPosition.ticket; + iGuard.volumeMultiplier = 0.5; + + // + AddGuard( + iGuard, + guards // + ); + } + } + } + } + + // + // Trail Stop ... + if (!ignoreTrailStopGuard) + { + // + if (hasLongs) + { + // + bool hasTrendGuard = hasDecisionBearishTrend; + + // + bool hasConsolidationGuard = + (hasConsolidationZone && + isConsolidationZoneBreaked && + isConsolidationZoneBreakedUp); + + // + bool hasDecisionPriceZoneGuard = + (hasDecisionPriceZone && + isDecisionPriceZoneBullish && + isDecisionPriceZoneValidForVale && + isDecisionPriceZoneUpperBreakedUp); + + // + bool hasAnalysePriceZoneGuard = + (hasAnalysePriceZone && + isAnalysePriceZoneBullish && + isAnalysePriceZoneValidForVale && + isAnalysePriceZoneUpperBreakedUp); + + // + bool hasVerificationPriceZoneGuard = + (hasVerificationPriceZone && + isVerificationPriceZoneBullish && + isVerificationPriceZoneValidForVale && + isVerificationPriceZoneUpperBreakedUp); + + // + bool hasGuard = + // + hasTrendGuard || + hasConsolidationGuard || + hasDecisionPriceZoneGuard || + hasAnalysePriceZoneGuard || + hasVerificationPriceZoneGuard + // + ; + + // + double guardStop = + hasConsolidationGuard + ? consolidationZoneLower + : hasDecisionPriceZoneGuard + ? decisionPriceZoneLower + : hasAnalysePriceZoneGuard + ? analysePriceZoneLower + : hasVerificationPriceZoneGuard + ? verificationPriceZoneLower + : 0; + + // + if (hasGuard) + { + // + for (int i = 0; i < longsCount; i++) + { + // + XPosition iPosition = ownLongPositions[i]; + + // + // Position Must Be In Profit ... + if (iPosition.profit <= 0) + { + continue; + } + + // + if (hasTrendGuard) + { + guardStop = decisionXConditions.strBuffer[1] - decisionXConditions.atrBuffer[1]; + } + + // + // Price Must Greater than Zone Lower ... + if (iPosition.price < guardStop) + { + continue; + } + + // + // Position Entry Must Lesser than Zone Lower ... + if (iPosition.entry > guardStop) + { + continue; + } + + // + // Position SL must be Zero or Lesser than Zone Lower ... + if (iPosition.sl != 0 && + iPosition.sl > guardStop) + { + continue; + } + + // + X121SMCGuard iGuard; + + // + iGuard.time = cTime; + iGuard.symbol = symbol; + iGuard.provider = provider; + iGuard.action = X_121_SMC_GUARD_ACTION_TRAIL_STOP; + + // + iGuard.sl = guardStop; + iGuard.ticket = iPosition.ticket; + + // + AddGuard( + iGuard, + guards // + ); + } + } + } + + // + if (hasShorts) + { + // + bool hasTrendGuard = hasDecisionBullishTrend; + + // + bool hasConsolidationGuard = + (hasConsolidationZone && + isConsolidationZoneBreaked && + isConsolidationZoneBreakedDown); + + // + bool hasDecisionPriceZoneGuard = + (hasDecisionPriceZone && + isDecisionPriceZoneBearish && + isDecisionPriceZoneValidForPeak && + isDecisionPriceZoneLowerBreakedDown); + + // + bool hasAnalysePriceZoneGuard = + (hasAnalysePriceZone && + isAnalysePriceZoneBearish && + isAnalysePriceZoneValidForPeak && + isAnalysePriceZoneLowerBreakedDown); + + // + bool hasVerificationPriceZoneGuard = + (hasVerificationPriceZone && + isVerificationPriceZoneBearish && + isVerificationPriceZoneValidForPeak && + isVerificationPriceZoneLowerBreakedDown); + + // + bool hasGuard = + // + hasTrendGuard || + hasConsolidationGuard || + hasDecisionPriceZoneGuard || + hasAnalysePriceZoneGuard || + hasVerificationPriceZoneGuard + // + ; + + // + double guardStop = + hasConsolidationGuard + ? consolidationZoneUpper + : hasDecisionPriceZoneGuard + ? decisionPriceZoneUpper + : hasAnalysePriceZoneGuard + ? analysePriceZoneUpper + : hasVerificationPriceZoneGuard + ? verificationPriceZoneUpper + : 0; + + // + if (hasGuard) + { + // + for (int i = 0; i < shortsCount; i++) + { + // + XPosition iPosition = ownShortPositions[i]; + + // + // Position Must Be In Profit ... + if (iPosition.profit <= 0) + { + continue; + } + + // + if (hasTrendGuard) + { + guardStop = decisionXConditions.strBuffer[1] + decisionXConditions.atrBuffer[1]; + } + + // + // Price Must Lesser than Zone Upper ... + if (iPosition.price > guardStop) + { + continue; + } + + // + // Position Entry Must Greater than Zone Upper ... + if (iPosition.entry < guardStop) + { + continue; + } + + // + // Position SL must be Zero or Greater than Zone Upper ... + if (iPosition.sl != 0 && + iPosition.sl < guardStop) + { + continue; + } + + // + X121SMCGuard iGuard; + + // + iGuard.time = cTime; + iGuard.symbol = symbol; + iGuard.provider = provider; + iGuard.action = X_121_SMC_GUARD_ACTION_TRAIL_STOP; + + // + iGuard.sl = guardStop; + iGuard.ticket = iPosition.ticket; + + // + AddGuard( + iGuard, + guards // + ); + } + } + } + } + + // + // Trail Target ... + if (!ignoreTrailTargetGuard) + { + // + if (hasLongs) + { + // + bool hasAnalyseGuard = + // + (hasAnalysePriceZone && + isAnalysePriceZoneValidForPeak && + isAnalysePriceZoneUpperRejected) + // + ; + + // + bool hasVerificationGuard = + // + (hasVerificationPriceZone && + isVerificationPriceZoneValidForPeak && + isVerificationPriceZoneUpperRejected) + // + ; + + // + bool hasGuard = + // + hasAnalyseGuard || + hasVerificationGuard + // + ; + + // + double guardTP = + hasAnalyseGuard + ? analysePriceZoneUpper + : hasVerificationGuard + ? verificationPriceZoneUpper + : 0; + + // + if (hasGuard) + { + // + for (int i = 0; i < longsCount; i++) + { + // + XPosition iPosition = ownLongPositions[i]; + + // + // Position Must Be In Profit ... + if (iPosition.profit <= 0) + { + continue; + } + + // + X121SMCGuard iGuard; + + // + iGuard.time = cTime; + iGuard.symbol = symbol; + iGuard.provider = provider; + iGuard.action = X_121_SMC_GUARD_ACTION_TRAIL_TARGET; + + // + iGuard.tp = guardTP; + iGuard.ticket = iPosition.ticket; + + // + AddGuard( + iGuard, + guards // + ); + } + } + } + + // + if (hasShorts) + { + // + bool hasAnalyseGuard = + // + (hasAnalysePriceZone && + isAnalysePriceZoneValidForVale && + isAnalysePriceZoneLowerRejected) + // + ; + + // + bool hasVerificationGuard = + // + (hasVerificationPriceZone && + isVerificationPriceZoneValidForVale && + isVerificationPriceZoneLowerRejected) + // + ; + + // + bool hasGuard = + // + hasAnalyseGuard || + hasVerificationGuard + // + ; + + // + double guardTP = + hasAnalyseGuard + ? analysePriceZoneLower + : hasVerificationGuard + ? verificationPriceZoneLower + : 0; + + // + if (hasGuard) + { + // + for (int i = 0; i < shortsCount; i++) + { + // + XPosition iPosition = ownShortPositions[i]; + + // + // Position Must Be In Profit ... + if (iPosition.profit <= 0) + { + continue; + } + + // + X121SMCGuard iGuard; + + // + iGuard.time = cTime; + iGuard.symbol = symbol; + iGuard.provider = provider; + iGuard.action = X_121_SMC_GUARD_ACTION_TRAIL_TARGET; + + // + iGuard.tp = guardTP; + iGuard.ticket = iPosition.ticket; + + // + AddGuard( + iGuard, + guards // + ); + } + } + } + } + + // + // Hedge ... + if (!ignoreHedgeGuard) + { + } + + // + // Cleanup Collections ... + + // + Clean(ownPositions); + Clean(ownLongPositions); + Clean(ownShortPositions); + + // + x121SMCAnalysePriceZone.Clean(); + x121SMCDecisionPriceZone.Clean(); + x121SMCConsolidationZone.Clean(); + x121SMCVerificationPriceZone.Clean(); + + // + // Release Arrays ... + Clean(ownPositions); + Clean(ownLongPositions); + Clean(ownShortPositions); + Clean(triggerPoiEvents); + Clean(triggerCycleEvents); + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + Clean(analysePoiEvents); + Clean(analyseCycleEvents); + Clean(verificationPoiEvents); + Clean(verificationCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + Clean(visionPoiEvents); + Clean(visionCycleEvents); + + // + count = ArraySize(guards); + result = IsValidSize(count); + + // + return result; +} diff --git a/Documents/BKP/1/x-121.smc.xobs.signal.lib copy.mq5 b/Documents/BKP/1/x-121.smc.xobs.signal.lib copy.mq5 new file mode 100644 index 00000000..bf0e592d --- /dev/null +++ b/Documents/BKP/1/x-121.smc.xobs.signal.lib copy.mq5 @@ -0,0 +1,1609 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: XOBS +// Description: provide all Signalling functions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +// #include "../../Libraries/x-trade.lib" +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Libraries/x-121.smc.guard.lib.mq5" +#include "../Libraries/x-121.smc.lib.mq5" + +// +// Definitions ... +struct X121SMCStrategyXOBSSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + double pivot; + double point; + + // + // Extwnsion ... + + // + datetime cOBAt; + XCOrderBlock *cOB; + bool isCOBActivated; + datetime cOBActivatedAt; + + // + datetime aOBAt; + XCOrderBlock *aOB; + bool isAOBActivated; + datetime aOBActivatedAt; + + // + // Constructor ... + X121SMCStrategyXOBSSignalConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + sl = 0; + target = 0; + + // + dir = X_DIRECTION_NONE; + type = X_POSITION_TYPE_NONE; + + // + symbol = NULL; + period = NULL; + setupTime = NULL; + triggerTime = NULL; + + // + ExtensionClean(); + + // + ZeroMemory(this); + } + + /** + * Check Condition is Setting Up ... + * + * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... + * + * @return ( bool ) + */ + bool IsSetuped() + { + // + bool result = false; + + // + result = IsValid(setupTime) && + HasDirection(dir); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Calculate Setup Age ... + * + * @return ( int ) + */ + int GetSetupAge() + { + // + int result = 0; + + // + if (!IsSetuped()) + { + return result; + } + + // + result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); + + // + return result; + } + + /** + * Detect How we Can Trigger Signal ... + * + * @return ( bool ) + */ + bool CanTrigger() + { + // + bool result = false; + + // + result = + // + sl > 0 && + IsValid(symbol) && + IsValid(period) && + IsValid(triggerTime) && + type != X_POSITION_TYPE_ALL && + type != X_POSITION_TYPE_NONE + // + ; + + // + return result; + } + + // + // Extensions ... + + /** + * Clean Additional Properties ... + */ + void ExtensionClean() + { + // + pivot = 0; + point = 0; + + // + cOB = NULL; + cOBAt = NULL; + cOBActivatedAt = NULL; + isCOBActivated = false; + + // + aOB = NULL; + aOBAt = NULL; + aOBActivatedAt = NULL; + isAOBActivated = false; + } + + // +}; + +// +// Signaller Data Sources ... +X121SMCStrategyXOBSSignalConditions mXOBSConditions; +X121SMCStrategyXOBSSignalConditions mXOBSConditionsCollection[]; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCXOBSSignalSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyXOBSSignalConditions &conditions, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int resetAfterUnActedZoneInMinutes = 120 + // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + conditions.symbol = symbol; + conditions.period = period; + + // + XC121SMCCycleHelper *barCycle = triggerCycleHelper; + + // + XOHCL zBar; + result = barCycle.GetBar( + zBar, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = barCycle.GetBar( + cBar, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = barCycle.GetBar( + pBar, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + int swingLoopback = 7; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double ll50 = cBar.FindLowest(50, MODE_LOW); + double hh50 = cBar.FindHighest(50, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions triggerXConditions = triggerConditions.x121Conditions; + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + X121Conditions analyseXConditions = analyseConditions.x121Conditions; + X121Conditions verificationXConditions = verificationConditions.x121Conditions; + X121Conditions consolidationXConditions = consolidationConditions.x121Conditions; + X121Conditions visionXConditions = visionConditions.x121Conditions; + + // + // Setup Conditions ... + + // + // Detect Trend ... + + // + // Vision ... + ENUM_X_DIRECTION visionTrendDir; + bool hasVisionTrend = + visionCycleHelper + .DetectMarketStructure( + visionTrendDir // + ); + bool hasVisionBullishTrend = + hasVisionTrend && + IsBullish(visionTrendDir); + bool hasVisionBearishTrend = + hasVisionTrend && + IsBearish(visionTrendDir); + + // + // Consolidation ... + ENUM_X_DIRECTION consolidationTrendDir; + bool hasConsolidationTrend = + consolidationCycleHelper + .DetectMarketStructure( + consolidationTrendDir // + ); + bool hasConsolidationBullishTrend = + hasConsolidationTrend && + IsBullish(consolidationTrendDir); + bool hasConsolidationBearishTrend = + hasConsolidationTrend && + IsBearish(consolidationTrendDir); + + // + // Verification ... + ENUM_X_DIRECTION verificationTrendDir; + bool hasVerificationTrend = + verificationCycleHelper + .DetectMarketStructure( + verificationTrendDir // + ); + bool hasVerificationBullishTrend = + hasVerificationTrend && + IsBullish(verificationTrendDir); + bool hasVerificationBearishTrend = + hasVerificationTrend && + IsBearish(verificationTrendDir); + + // + // Analyse ... + ENUM_X_DIRECTION analyseTrendDir; + bool hasAnalyseTrend = + analyseCycleHelper + .DetectMarketStructure( + analyseTrendDir // + ); + bool hasAnalyseBullishTrend = + hasAnalyseTrend && + IsBullish(analyseTrendDir); + bool hasAnalyseBearishTrend = + hasAnalyseTrend && + IsBearish(analyseTrendDir); + + // + // Decision ... + ENUM_X_DIRECTION decisionTrendDir; + bool hasDecisionTrend = + decisionCycleHelper + .DetectMarketStructure( + decisionTrendDir // + ); + bool hasDecisionBullishTrend = + hasDecisionTrend && + IsBullish(decisionTrendDir); + bool hasDecisionBearishTrend = + hasDecisionTrend && + IsBearish(decisionTrendDir); + + // + // Detect Bar State ... + + // + // PinBar ... + ENUM_X_DIRECTION cBarPinDir; + bool isCBarPin = decisionCycleHelper + .mBarAnalyser + .IsPinBar( + cBar, + cBarPinDir, + 1 // + ); + bool isCBarBullishPin = + isCBarPin && + IsBullish(cBarPinDir); + bool isCBarBearishPin = + isCBarPin && + IsBearish(cBarPinDir); + + // + // Engulf ... + ENUM_X_DIRECTION cBarEngulfDir; + bool isCBarEngulfed = decisionCycleHelper + .mBarAnalyser + .IsEngulfBar( + cBar, + cBarEngulfDir, + 0 // Extended ... + ); + bool isCBarBullishEngulfed = + isCBarEngulfed && + IsBullish(cBarEngulfDir); + bool isCBarBearishEngulfed = + isCBarEngulfed && + IsBearish(cBarEngulfDir); + + // + // Momentum ... + ENUM_X_DIRECTION cBarMomentumDir; + bool isCBarMomentum = decisionCycleHelper + .mBarAnalyser + .IsMomentumBar( + cBar, + cBarMomentumDir, + 0 // Extended ... + ); + bool isCBarBullishMomentum = + isCBarMomentum && + IsBullish(cBarMomentumDir); + bool isCBarBearishMomentum = + isCBarMomentum && + IsBearish(cBarMomentumDir); + + // + // Reject ... + ENUM_X_DIRECTION cBarRejectDir; + bool isCBarRejected = decisionCycleHelper + .mBarAnalyser + .IsRejectionBar( + cBar, + cBarRejectDir, + 0 // Extended ... + ); + bool isCBarBullishRejected = + isCBarRejected && + IsBullish(cBarRejectDir); + bool isCBarBearishRejected = + isCBarRejected && + IsBearish(cBarRejectDir); + + // + // Pull Back ... + ENUM_X_DIRECTION cBarPullbackDir; + bool isCBarPullbacked = + decisionCycleHelper + .mBarAnalyser + .HasPullBack( + cBarPullbackDir, + cBar // + ); + bool isCBarBullishPullbacked = + isCBarPullbacked && + IsBullish(cBarPullbackDir); + bool isCBarBearishPullbacked = + isCBarPullbacked && + IsBearish(cBarPullbackDir); + + // + // HH/LL Break ... + + // + bool isCBarBreaksUpHH = IsBarBreak( + hh, + X_DIRECTION_BULLISH, + cBar // + ); + + // + bool isCBarBreaksDownLL = IsBarBreak( + hh, + X_DIRECTION_BEARISH, + cBar // + ); + + // + // Bars Pattern and Power and Pressures ... + + // + bool hasCBarBullishPattern = + decisionCycleHelper + .mBarAnalyser + .HasBullishPattern( + cBar, + 2 // + ); + + // + bool hasCBarBearishPattern = + decisionCycleHelper + .mBarAnalyser + .HasBearishPattern( + cBar, + 2 // + ); + + // + bool isCBarHasBullishPower = + decisionCycleHelper + .mBarAnalyser + .HasBullishPower( + cBar, + 2 // + ); + + // + bool isCBarHasBearishPower = + decisionCycleHelper + .mBarAnalyser + .HasBearishPower( + cBar, + 2 // + ); + + // + bool isCBarHasBullishPressure = + decisionCycleHelper + .mBarAnalyser + .HasBullishPressure( + cBar, + 2 // + ); + + // + bool isCBarHasBearishPressure = + decisionCycleHelper + .mBarAnalyser + .HasBearishPressure( + cBar, + 2 // + ); + + // + // Bar Checking Summary ... + + // + // Bullish ... + bool isCBarBullishFormed = + // + ( + // + hasCBarBullishPattern && + isCBarHasBullishPower && + isCBarHasBullishPressure + // + ) + // + || + // + ( + // + isCBarBullishPin || + isCBarBreaksUpHH || + isCBarBullishEngulfed || + isCBarBullishMomentum || + isCBarBullishRejected + // + ) + // + ; + + // + // Bearish ... + bool isCBarBearishFormed = + // + ( + // + hasCBarBearishPattern && + isCBarHasBearishPower && + isCBarHasBearishPressure + // + ) + // + || + // + ( + // + isCBarBearishPin || + isCBarBreaksDownLL || + isCBarBearishEngulfed || + isCBarBearishMomentum || + isCBarBearishRejected + // + ) + // + ; + + // + // Detect OrderBlocks ... + + // + bool hasCOB = + conditions.cOB != NULL && + conditions.cOB.IsValid() && + IsValid(conditions.cOBAt); + + // + if (!hasCOB) + { + // + int poiEvntsCount = ArraySize(consolidationPoiEvents); + bool hasEvent = IsValidSize(poiEvntsCount); + if (hasEvent) + { + // + bool hasNewBullOB = Contains( + X_BULLISH_ORDERBLOCK_DETECTED, + consolidationPoiEvents // + ); + + // + bool hasNewBearOB = Contains( + X_BEARISH_ORDERBLOCK_DETECTED, + consolidationPoiEvents // + ); + + // + bool hasNewOB = + hasNewBullOB || + hasNewBearOB; + + // + if (hasNewOB) + { + // + XCOrderBlock *ob = NULL; + if (hasNewBullOB) + { + // + int lastIDX = consolidationState.CountBullishOrderBlocks() - 1; + ob = consolidationState.bullishOrderBlocks[lastIDX]; + + // + // Validate OB ... + } + else if (hasNewBearOB) + { + // + int lastIDX = consolidationState.CountBearishOrderBlocks() - 1; + ob = consolidationState.bearishOrderBlocks[lastIDX]; + + // + // Validate OB ... + } + + // + if (ob != NULL && ob.IsValid()) + { + // + conditions.cOB = ob; + + // + conditions.cOBAt = cTime; + + // + hasCOB = + conditions.cOB != NULL && + conditions.cOB.IsValid() && + IsValid(conditions.cOBAt); + } + } + } + } + + // + if (hasCOB) + { + conditions.cOB.To(cTime); + } + + // + bool hasAOB = + conditions.aOB != NULL && + conditions.aOB.IsValid() && + IsValid(conditions.aOBAt); + + // + if (hasCOB && + !hasAOB) + { + // + int poiEvntsCount = ArraySize(analysePoiEvents); + bool hasEvent = IsValidSize(poiEvntsCount); + if (hasEvent) + { + // + bool hasNewBullOB = Contains( + X_BULLISH_ORDERBLOCK_DETECTED, + analysePoiEvents // + ); + + // + bool hasNewBearOB = Contains( + X_BEARISH_ORDERBLOCK_DETECTED, + analysePoiEvents // + ); + + // + bool hasNewOB = + hasNewBullOB || + hasNewBearOB; + + // + if (hasNewOB) + { + // + XCOrderBlock *ob = NULL; + if (hasNewBullOB) + { + // + int lastIDX = analyseState.CountBullishOrderBlocks() - 1; + ob = analyseState.bullishOrderBlocks[lastIDX]; + + // + // Validate OB ... + } + else if (hasNewBearOB) + { + // + int lastIDX = analyseState.CountBearishOrderBlocks() - 1; + ob = analyseState.bearishOrderBlocks[lastIDX]; + + // + // Validate OB ... + } + + // + if (ob != NULL && ob.IsValid()) + { + // + conditions.aOB = ob; + + // + conditions.aOBAt = cTime; + + // + hasAOB = + conditions.aOB != NULL && + conditions.aOB.IsValid() && + IsValid(conditions.aOBAt); + } + } + } + } + + // + if (hasAOB) + { + conditions.aOB.To(cTime); + } + + // + result = hasCOB && + hasAOB; + if (!result) + { + return result; + } + + // + // DRAW ... + // + + // + // Draw Orer Block ... + bool isBullishCOB = conditions.cOB.IsBullish(); + if (isBullishCOB) + { + // + XCBullishOrderBlockObject *iObj; + bool isCreated = consolidationCycleHelper + .mPOIDrawer + .CreateBullishOrderBlock( + conditions.cOB, + iObj // + ); + } + else + { + // + XCBearishOrderBlockObject *iObj; + bool isCreated = consolidationCycleHelper + .mPOIDrawer + .CreateBearishOrderBlock( + conditions.cOB, + iObj // + ); + } + + bool isBullishAOB = conditions.aOB.IsBullish(); + if (isBullishAOB) + { + // + XCBullishOrderBlockObject *iObj; + bool isCreated = analyseCycleHelper + .mPOIDrawer + .CreateBullishOrderBlock( + conditions.aOB, + iObj // + ); + } + else + { + // + XCBearishOrderBlockObject *iObj; + bool isCreated = analyseCycleHelper + .mPOIDrawer + .CreateBearishOrderBlock( + conditions.aOB, + iObj // + ); + } + + // + // Draw From Bar ... + XOHCL cOBFromBar; + bool hasCOBFromBar = cOBFromBar.Init( + conditions.cOB.GetSymbol(), + conditions.cOB.GetPeriod(), + conditions.cOB.From() // + ); + if (hasCOBFromBar) + { + // + XCOHCLObject *barObject; + bool iCreated = consolidationCycleHelper + .mPOIDrawer + .CreateBar( + cOBFromBar, + barObject // + ); + } + + // + // Draw From Bar ... + XOHCL aOBFromBar; + bool hasAOBFromBar = aOBFromBar.Init( + conditions.aOB.GetSymbol(), + conditions.aOB.GetPeriod(), + conditions.aOB.From() // + ); + if (hasAOBFromBar) + { + // + XCOHCLObject *barObject; + bool iCreated = analyseCycleHelper + .mPOIDrawer + .CreateBar( + aOBFromBar, + barObject // + ); + } + + // + // END DRAW ... + // + + // + // Check AOB Activation ... + if (!conditions.isAOBActivated) + { + // + int aPeakRepetition = analyseCycleHelper.CountPrevPeakRepetition(); + int aValeRepetition = analyseCycleHelper.CountPrevValeRepetition(); + + // + bool isActivated = + // + bid >= conditions.aOB.Lower() && + bid <= conditions.aOB.Upper() && + // + cBar.low >= conditions.aOB.Lower() && + cBar.high <= conditions.aOB.Upper() && + // + (conditions.aOB.IsBullish() + ? decisionXConditions.valesBuffer[1] >= conditions.aOB.Lower() && + decisionXConditions.valesBuffer[1] <= conditions.aOB.Upper() + : decisionXConditions.peaksBuffer[1] >= conditions.aOB.Lower() && + decisionXConditions.peaksBuffer[1] <= conditions.aOB.Upper()) + // + ; + + // + if (isActivated) + { + // + conditions.aOBActivatedAt = cTime; + conditions.isAOBActivated = isActivated; + } + } + + // + // Check COB Activation ... + if (!conditions.isCOBActivated) + { + // + int aPeakRepetition = analyseCycleHelper.CountPrevPeakRepetition(); + int aValeRepetition = analyseCycleHelper.CountPrevValeRepetition(); + + // + bool isActivated = + // + bid >= conditions.cOB.Lower() && + bid <= conditions.cOB.Upper() && + // + cBar.low >= conditions.cOB.Lower() && + cBar.high <= conditions.cOB.Upper() && + // + (conditions.cOB.IsBullish() + ? decisionXConditions.valesBuffer[1] >= conditions.cOB.Lower() && + decisionXConditions.valesBuffer[1] <= conditions.cOB.Upper() + : decisionXConditions.peaksBuffer[1] >= conditions.cOB.Lower() && + decisionXConditions.peaksBuffer[1] <= conditions.cOB.Upper()) + // + ; + + // + if (isActivated) + { + // + conditions.cOBActivatedAt = cTime; + conditions.isCOBActivated = isActivated; + } + } + + // + result = conditions.isAOBActivated || + conditions.isCOBActivated; + if (!result) + { + return result; + } + + // + double upper = 0; + double lower = 0; + + // + // + // + + // + // Summarize Conditions ... + + // + bool isCondition1Bullish = + // + false + // + ; + + // + bool isCondition1Bearish = + // + false + // + ; + + // + bool hasCondition1 = isCondition1Bullish || + isCondition1Bearish; + if (hasCondition1) + { + // + ENUM_X_DIRECTION pzDir = + isCondition1Bullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + double point = GetEntry( + conditions.symbol, + pzDir // + ); + + // + double longPivot = lower; // triggerXConditions.valesBuffer[1]; + double shortPivot = upper; // triggerXConditions.peaksBuffer[1]; + + // + // Manipulate Conditions Point ... + + // + conditions.point = + isCondition1Bullish + ? shortPivot + : longPivot; + + // + // Manipulate Conditions Pivot ... + + // + conditions.pivot = + isCondition1Bullish + ? longPivot + : shortPivot; + } + + // + // + // + + // + isBullish = + // + isCondition1Bullish + // + ; + + // + isBearish = + // + isCondition1Bearish + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Detect PriceOB Lifetime Bars ... + + // + // Cleanup Arrays ... + Clean(triggerPoiEvents); + Clean(triggerCycleEvents); + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + Clean(analysePoiEvents); + Clean(analyseCycleEvents); + Clean(verificationPoiEvents); + Clean(verificationCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + Clean(visionPoiEvents); + Clean(visionCycleEvents); + + // + return result; + } + + // + conditions.setupTime = cTime; + conditions.dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // Cleanup Arrays ... + Clean(triggerPoiEvents); + Clean(triggerCycleEvents); + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + Clean(analysePoiEvents); + Clean(analyseCycleEvents); + Clean(verificationPoiEvents); + Clean(verificationCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + Clean(visionPoiEvents); + Clean(visionCycleEvents); + + // + return result; +} + +// +// Detect Trigger Conditions ... +bool DetectX121SMCXOBSSignalTrigger( + // + X121SMCStrategyXOBSSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 60 // + // +) +{ + // + bool result = false; + + // + result = conditions.IsSetuped(); + if (!result) + { + return result; + } + + // + datetime setupTime = conditions.setupTime; + ENUM_X_DIRECTION setupDir = conditions.dir; + + // + bool isBullish = IsBullish(setupDir); + bool isBearish = IsBearish(setupDir); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + XOHCL zBar; + result = decisionCycleHelper.GetBar( + zBar, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = decisionCycleHelper.GetBar( + cBar, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = decisionCycleHelper.GetBar( + pBar, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + int swingLoopback = 9; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // Cycles Conditions ... + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState decisionState = decisionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + + // + // Trigger Conditions ... + + // + // Slopes ... + + // + bool isRsiSlopeBullish = decisionXConditions.isRsiSlopeBullish; + bool isStrSlopeBullish = decisionXConditions.isStrSlopeBullish; + bool isAtrUpperSlopeBullish = decisionXConditions.isAtrUpperSlopeBullish; + bool isAtrLowerSlopeBullish = decisionXConditions.isAtrLowerSlopeBullish; + bool isVwapFastSlopeBullish = decisionXConditions.isVwapFastSlopeBullish; + bool isVwapMidSlopeBullish = decisionXConditions.isVwapMidSlopeBullish; + bool isVwapSlowSlopeBullish = decisionXConditions.isVwapSlowSlopeBullish; + + // + bool isRsiSlopeBearish = decisionXConditions.isRsiSlopeBearish; + bool isStrSlopeBearish = decisionXConditions.isStrSlopeBearish; + bool isAtrUpperSlopeBearish = decisionXConditions.isAtrUpperSlopeBearish; + bool isAtrLowerSlopeBearish = decisionXConditions.isAtrLowerSlopeBearish; + bool isVwapFastSlopeBearish = decisionXConditions.isVwapFastSlopeBearish; + bool isVwapMidSlopeBearish = decisionXConditions.isVwapMidSlopeBearish; + bool isVwapSlowSlopeBearish = decisionXConditions.isVwapSlowSlopeBearish; + + // + bool isSlopesBullish = + isRsiSlopeBullish && + isStrSlopeBullish && + isAtrUpperSlopeBullish && + isAtrLowerSlopeBullish && + isVwapFastSlopeBullish && + isVwapMidSlopeBullish && + isVwapSlowSlopeBullish; + + // + bool isSlopesBearish = + isRsiSlopeBearish && + isStrSlopeBearish && + isAtrUpperSlopeBearish && + isAtrLowerSlopeBearish && + isVwapFastSlopeBearish && + isVwapMidSlopeBearish && + isVwapSlowSlopeBearish; + + // + double point = conditions.point; + bool isPointBreaked = IsBarBreak( + point, + setupDir, + cBar // + ); + + // + // Summary ... + + // + isBullish = + // + isBullish && + isPointBreaked && + isSlopesBullish + // + ; + + // + isBearish = + // + isBearish && + isPointBreaked && + isSlopesBearish + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + // Cleanup Arrays ... + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + return result; + } + + // + // Detect Nearest Pivot Point ... + + // + double entry = GetEntry( + conditions.symbol, + setupDir // + ); + + // + double sls[]; + Add( + conditions.pivot, + sls // + ); + + // + double iAtr = decisionConditions.x121Conditions.atrBuffer[1]; + iAtr *= 1.5; + + // + double slsMin = GetMin(sls); + double slsMax = GetMax(sls); + + // + double sl = isBullish + ? slsMin - iAtr + : slsMax + iAtr; + double risk = MathAbs(entry - sl); + + // + // Filling Conditions Props ... + conditions.sl = sl; + // conditions.target = target; + conditions.triggerTime = cTime; + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + // Cleanup Arrays ... + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + return result; +} + +// +// Detect Guards ... +bool DetectX121SMCXOBSGuards( + X121SMCGuard &guards[], + const XPosition &positions[], + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper // +) +{ + // + bool result = false; + + // + string provider = ToString(X_121_SMC_PROVIDER_X); + + // + result = DetectX121SMCGuards( + provider, + guards, + positions, + triggerCycleHelper, + decisionCycleHelper, + analyseCycleHelper, + verificationCycleHelper, + consolidationCycleHelper, + visionCycleHelper, + // + true, // CloseOnTPNear Guard ... + true, // CloseLongsOnBearishTrend Guard ... + true, // CloseShortsOnBullishTrend Guard ... + true, // CloseAllWeekend Guard ... + true, // PartialCloseOnTrendChange Guard ... + true, // TrailStop Guard ... + true, // TrailTarget Guard ... + true // Hedge Guard ... + // + ); + + // + return result; +} + +// +// Add Conditions to Conditions Collection ... +int AddX121SMCXOBSConditionsIfNotExists( + X121SMCStrategyXOBSSignalConditions &item, + X121SMCStrategyXOBSSignalConditions &items[], + int maxAllowed = 10 // +) +{ + // + int result = 0; + + // + bool isSetuped = IsValid(item.setupTime) && + HasDirection(item.dir); + if (!isSetuped) + { + return result; + } + + // + int count = ArraySize(items); + if (IsValidSize(count)) + { + // + // Copy Original Items ... + X121SMCStrategyXOBSSignalConditions tmpItems[]; + Copy( + items, + tmpItems // + ); + + // + // Prese Item Data ... + bool isBullish = IsBullish(item.dir); + + // + for (int i = 0; i < count; i++) + { + // + X121SMCStrategyXOBSSignalConditions iItem = tmpItems[i]; + + // + bool canRemove = item.dir == iItem.dir && + item.pivot == iItem.pivot; + if (canRemove) + { + // + ArrayRemove( + items, + i, + 1 // + ); + } + } + + // + Clean(tmpItems); + } + + // + AddRef( + item, + items // + ); + + // + // Remove Olds ... + CleanupArray( + items, + maxAllowed // + ); + + // + result = ArraySize(items); + + // + return result; +} + +// diff --git a/Documents/BKP/1/x-saherelm.x-poi.lib.mq5 b/Documents/BKP/1/x-saherelm.x-poi.lib.mq5 new file mode 100644 index 00000000..bf485fb3 --- /dev/null +++ b/Documents/BKP/1/x-saherelm.x-poi.lib.mq5 @@ -0,0 +1,12364 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Seriallize Library +// --------------------------------------- +// Name: XPOILib +// Description: All models related to POIs ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright `023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.base.class.mq5" +#include + +// +// Definitions ... + +// +// Definitions ... + +// +// All Available POI(s) ... +enum ENUM_XPOIS +{ + // + X_POI_NONE, + // + X_POI_TICKS_ZONES, // Ticks Zone ... + // + // Trading Day ... + X_POI_TRADING_DAY, // Trading Day ... + // + // Market Session ... + X_POI_MARKET_SESSION, // Market Session ... + // + // Momentum Bar ... + X_POI_MOMENTUM_BAR, // Momentum Bar ... + // + // Rejection Bar ... + X_POI_REJECTION_BAR, // Rejection Bar ... + // + // Swings ... + X_POI_SWING_HIGH, // Simple Swing High ... + X_POI_SWING_LOW, // Simple Swing Low ... + // + // Support nad Resistance ... + X_POI_SUPPORT_ZONE, // Support Zone ... + X_POI_RESISTANCE_ZONE, // Resistance Zone ... + // + // Supply and Demand Zones ... + X_POI_SUPPLY_ZONE, // Supply Zone ... + X_POI_DEMAND_ZONE, // Demand Zone ... + // + // Order Blocks ... + X_POI_BULLISH_ORDERBLOCK, // Bullish Order Block ... + X_POI_BEARISH_ORDERBLOCK, // Bearish Order Block ... + // + // Fair Value Gaps ... + X_POI_BULLISH_FVG, // Bullish Order Block ... + X_POI_BEARISH_FVG, // Bearish Order Block ... +}; + +// +// Event Types ... +enum ENUM_XPOI_EVENTS +{ + // + // Trading Days ... + X_TRADE_DAY_FIRST_BAR, // Trading Day First Bar ... + X_TRADE_DAY_LAST_BAR, // Trading Day Last Bar ... + // + // Session ... + X_SESSION_FIRST_BAR, // Session First Bar ... + X_SESSION_LAST_BAR, // Session Last Bar ... + // + // Momentum Bar ... + X_BULLISH_MOMENTUM_BAR_DETECTED, + X_BEARISH_MOMENTUM_BAR_DETECTED, + // + // Rejection Bar ... + X_BULLISH_REJECTION_BAR_DETECTED, + X_BEARISH_REJECTION_BAR_DETECTED, + // + // Swings ... + X_SWING_HIGH_DETECTED, + X_SWING_LOW_DETECTED, + // + // Support nad Resistance ... + X_SUPPORT_ZONE_DETECTED, // Support Zone ... + X_RESISTANCE_ZONE_DETECTED, // Resistance Zone ... + // + // Supply nad Demand ... + X_SUPPLY_ZONE_DETECTED, // Supply Zone ... + X_DEMAND_ZONE_DETECTED, // Demand Zone ... + // + // Order Blocks ... + X_BULLISH_ORDERBLOCK_DETECTED, // Bullish Order Block ... + X_BEARISH_ORDERBLOCK_DETECTED, // Bearish Order Block ... + // + // Fair Value Gaps ... + X_BULLISH_FVG_DETECTED, // Bullish Fair Value GapÙ‘ ... + X_BEARISH_FVG_DETECTED, // Bearish Fair Value GapÙ‘ ... +}; + +// +// Forext Sessions ... +enum ENUM_XSESSION +{ + X_TOKYO, + X_SYDNEY, + X_LONDON, + X_NEW_YORK, + X_FRANKFORT, +}; + +// +// Implementation ... + +// +// Base POI Model Class ... +class XCBasePOI : public XCBase +{ + // + public: + // + + // + // Constructor ... + void XCBasePOI() + { + // + Clean(); + + // + mSep = "_"; + mLineSep = "\n"; + } + + // + // Deconstructor ... + void ~XCBasePOI() + { + Clean(); + } + + // + // Virtual ... + + /** + * Cleanup ... + */ + virtual void Clean() + { + mType = X_POI_NONE; + } + + /** + * Validate ... + * + * @return ( virtual bool ) + */ + virtual bool IsValid() + { + return false; + } + + /** + * Retrieve POI Type ... + * + * @return ( virtual ENUM_XPOIS member ) + */ + virtual ENUM_XPOIS Type() + { + return mType; + } + + /** + * Retrieve POI Type ... + * + * @return ( virtual string ) + */ + virtual string TypeAsString() + { + return ToString(mType); + } + + /** + * Retrieve POI Tag ... + * + * @return ( virtual string ) + */ + virtual string GetTag() + { + return NULL; + } + + /** + * Retrieve POI Tooltip ... + * + * @return ( virtual string ) + */ + virtual string GetTooltip() + { + return NULL; + } + + // + protected: + // + // Props ... + string mSep; // Separator ... + string mLineSep; // Line Separator ... + ENUM_XPOIS mType; // Type ... + + // + private: + // +}; + +// +// Zone POI Class ... +class XCZone : public XCBasePOI +{ + // + public: + // + + // + // Constructor ... + void XCZone() + { + } + + // + // Deconstructor ... + void ~XCZone() + { + } + + // + // Tools ... + + // + // Getter(s) / Setter(s) ... + + /** + * Get Zone Upper Boundary ... + * + * @return ( double ) + */ + double Upper() + { + return mUpper; + } + + /** + * Set Zone Upper Boundary ... + */ + void Upper(double value) + { + mUpper = value; + } + + /** + * Get Zone Lower Boundary ... + * + * @return ( double ) + */ + double Lower() + { + return mLower; + } + + /** + * Set Zone Lower Boundary ... + */ + void Lower(double value) + { + mLower = value; + } + + /** + * Retrieve Zone Range ... + * + * @return ( double ) + */ + double Range() + { + // + double result = 0; + + // + double upper = Upper(); + double lower = Lower(); + + // + if (upper > 0 && lower > 0 && upper > lower) + { + result = upper - lower; + } + + // + return result; + } + + double RangePercent() + { + // + double result = 0; + + // + double range = Range(); + if (range > 0) + { + result = range / 100; + } + + // + return result; + } + + // + // Virtuals ... + + /** + * Get Zone Start Date ... + * + * @return ( virtual datetime ) + */ + virtual datetime From() + { + return NULL; + } + + /** + * Get Zone End Date ... + * + * @return ( virtual datetime ) + */ + virtual datetime To() + { + return NULL; + } + + // + // Getter(s) / Setter(s) ... + + // + // Overrides ... + + // + // Validators ... + + /** + * Validate Upper and Lower of Zone ... + * + * @return ( bool ) + */ + bool IsValidBoundary() + { + // + bool result = false; + + // + result = + // + mUpper > 0 && + mLower > 0 && + mUpper >= mLower + // + ; + + // + return result; + } + + /** + * Check From Date of Zone is Valid ... + * + * @return ( bool ) + */ + bool IsValidFrom() + { + // + bool result = false; + + // + datetime from = From(); + result = IsSpecifiedValid(from); + + // + return result; + } + + // + protected: + // + // Props ... + double mUpper; // Zone Upper ... + double mLower; // Zone Lower ... + + // + private: + // + // Props ... + + // +}; + +// +// From To Zone ... +class XCFromToZone : public XCBasePOI +{ + // + public: + // + + // + // Constructor ... + void XCFromToZone() + { + } + + // + // Deconstructor ... + void ~XCFromToZone() + { + } + + // + // Tools ... + + bool InitFromTo( + ENUM_XPOIS type, + string title, + datetime from // + ) + { + // + bool result = false; + + // + result = type != X_POI_NONE && + IsSpecifiedValid(from) && + IsSpecifiedValid(title); + + // + mType = type; + mFrom = from; + mTitle = title; + mTo = TimeCurrent(); + + // + result = IsValid(); + + // + return result; + } + + bool InitFromTo( + ENUM_XPOIS type, + string title, + datetime from, + datetime to // + ) + { + // + bool result = false; + + // + result = IsValid(); + + // + result = InitFromTo( + type, + title, + from // + ); + if (!result) + { + return result; + } + + // + to = NormalizeTime(to); + mTo = to; + + // + result = IsValid(); + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + /** + * Get Zone Start Time ... + * + * @return ( datetime ) + */ + datetime From() + { + return mFrom; + } + + /** + * Set Zone Start Time ... + * + * @param value: Datetime + */ + void From(datetime value) + { + // + value = NormalizeTime(value); + + // + mFrom = value; + } + + /** + * Get Zone End Time ... + * + * @return ( datetime ) + */ + datetime To() + { + return mTo; + } + + /** + * Set Zone End Time ... + * + * @param value: Datetime + */ + void To(datetime value) + { + // + value = NormalizeTime(value); + + // + mTo = value; + } + + /** + * Get Title ... + * + * @return ( string ) + */ + string Title() + { + return mTitle; + } + + /** + * Set Title ... + * + * @param value: String ... + */ + // void Title(string value) + // { + // mTitle = value; + // } + + // + // Overrides ... + + void Clean() override + { + // + mTo = NULL; + mFrom = NULL; + mType = X_POI_NONE; + } + + bool IsValid() override + { + // + bool result = false; + + // + result = + // + mType != X_POI_NONE && + IsSpecifiedValid(mTo) && + IsSpecifiedValid(mFrom) && + IsSpecifiedValid(mTitle) + // + ; + + // + return result; + } + + string GetTag() override + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + string hash = TypeAsString() + mSep + ToString(From()) + mSep + Title(); + hash = ToMD5(hash); + + // + result = TypeAsString() + "[" + Title() + "]" + mSep + hash; + + // + return result; + } + + // + protected: + // + + // + private: + // + // Props ... + datetime mFrom; // Start Date + datetime mTo; // End Date + string mTitle; // Zone Title + + // +}; + +// +// Bar Zone ... +class XCBarZone : public XCZone +{ + // + public: + // + + // + // Constructor ... + void XCBarZone() + { + } + + // + // Deconstructor ... + void ~XCBarZone() + { + } + + // + // Tools ... + + /** + * Initialize POI ... + * + * @param bar: XOHCL instance ... + * @param type: ENUM_XPOIS member ... + * @param upperPrice: ENUM_X_PRICE member ... + * @param lowerPrice: ENUM_X_PRICE member ... + * + * @return ( bool ) + */ + bool InitBarZone( + XOHCL &bar, + ENUM_XPOIS type, + ENUM_X_PRICE upperPrice, + ENUM_X_PRICE lowerPrice // + ) + { + // + bool result = false; + + // + result = bar.IsValid() && + type != X_POI_NONE && + upperPrice != lowerPrice; + if (!result) + { + return result; + } + + // + mBar = bar; + mType = type; + mUpperPrice = upperPrice; + mLowerPrice = lowerPrice; + mUpper = bar.GetPrice(upperPrice); + mLower = bar.GetPrice(lowerPrice); + + // + result = IsValidBarZone(); + if (result) + { + // + From(bar.time); + To(TimeCurrent()); + } + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + /** + * Fill Bar as XOHCL struct ... + * + * @param bar: XOHCL instance ... + * + * @return ( bool ) + */ + bool FillBar( + XOHCL &bar // + ) + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + bar = mBar; + result = mBar.IsValid(); + + // + return result; + } + + /** + * Set From Date ... + * + * @param value: DateTime ... + */ + void From(datetime value) + { + // + if (!IsValidBarZone()) + { + return; + } + + // + value = NormalizeTime(value); + + // + mFrom = value; + } + + /** + * Set To Date ... + * + * @param value: DateTime ... + */ + void To(datetime value) + { + // + if (!IsValidBarZone()) + { + return; + } + + // + value = NormalizeTime(value); + + // + mTo = value; + } + + /** + * Retrieve Bar Time ... + * + * @return ( datetime ) + */ + datetime BarTime() + { + return mBar.time; + } + + /** + * Get Symbol ... + * + * @return ( string ) + */ + string GetSymbol() + { + // + string result = NULL; + + // + if (!mBar.IsValid()) + { + return result; + } + + // + return mBar.symbol; + + // + return result; + } + + /** + * Get Period ... + * + * @return ( int ) + */ + ENUM_TIMEFRAMES GetPeriod() + { + // + ENUM_TIMEFRAMES result = NULL; + + // + if (!mBar.IsValid()) + { + return result; + } + + // + return mBar.period; + + // + return result; + } + + /** + * Is Activated Zone or not ... + * + * @param activatedBar: XOHCL instance Reference ... + * @param activatedDir: ENUM_X_DIRECTION member ... + * + * @return ( bool ) + */ + bool IsActivated( + ENUM_X_DIRECTION forDir, + XOHCL &activatedBar, + ENUM_X_DIRECTION &activatedDir // + ) + { + // + bool result = false; + + // + activatedBar.Clean(); + activatedDir = X_DIRECTION_NONE; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = IsStarted( + forDir, + startedBar, + startedDir // + ); + result = isStarted; + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(forDir); + bool isBearish = IsBearish(forDir); + + // + int startIndex = startedBar.Index() - 1; + + // + for (int i = startIndex; i >= 0; i--) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + GetSymbol(), + GetPeriod(), + i // + ); + result = isInited; + if (!result) + { + continue; + } + + // + XOHCL iPBar; + isInited = iBar.GetPreviousBar(iPBar); + result = isInited; + if (!result) + { + continue; + } + + // + bool isActivedFromUpper = + // + isBullish && + // + ( + // + (iPBar.low > Upper() && + iBar.low <= Upper()) + // + ) + // + ; + + // + bool isActivedFromLower = + // + isBearish && + // + ( + // + (iPBar.high < Lower() && + iBar.high >= Lower()) + // + ) + // + ; + + // + bool isActivated = + isActivedFromUpper || + isActivedFromLower; + if (isActivated) + { + // + result = isActivated; + activatedBar = iBar; + activatedDir = + isActivedFromUpper + ? X_DIRECTION_BEARISH + : X_DIRECTION_BULLISH; + break; + } + } + + // + result = activatedBar.IsValid() && + HasDirection(activatedDir); + + // + return result; + } + + /** + * Is Breaked Zone or not ... + * + * @param breakerBar: XOHCL instance Reference ... + * @param breakerDir: ENUM_X_DIRECTION member ... + * + * @return ( bool ) + */ + bool IsBreaked( + ENUM_X_DIRECTION forDir, + XOHCL &breakerBar, + ENUM_X_DIRECTION &breakerDir // + ) + { + // + bool result = false; + + // + breakerBar.Clean(); + breakerDir = X_DIRECTION_NONE; + + // + result = IsValid() && + HasDirection(forDir); + if (!result) + { + return result; + } + + // + XOHCL activatedBar; + ENUM_X_DIRECTION activatedDir; + bool isActivated = IsActivated( + forDir, + activatedBar, + activatedDir // + ); + result = isActivated; + if (!result) + { + return result; + } + + // + int activatedIndex = activatedBar.Index(); + activatedIndex--; + + // + for (int i = activatedIndex; i >= 0; i--) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + GetSymbol(), + GetPeriod(), + i // + ); + result = isInited; + if (!result) + { + continue; + } + + // + XOHCL iPBar; + isInited = iBar + .GetPreviousBar(iPBar); + result = isInited; + if (!result) + { + continue; + } + + // + bool isBreakedFromUpper = + // + (iPBar.high <= Upper() && + iBar.low > Upper()) + // + ; + + // + bool isBreakedFromLower = + // + (iPBar.low >= Lower() && + iBar.low < Lower()) + // + ; + + // + bool isBreaked = + isBreakedFromUpper || + isBreakedFromLower; + if (isBreaked) + { + // + result = isBreaked; + breakerBar = iBar; + breakerDir = + isBreakedFromUpper + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + break; + } + } + + // + result = breakerBar.IsValid() && + HasDirection(breakerDir); + + // + return result; + } + + /** + * Retrieve Order Zone First Breaker Bar ... + * + * @param breakerBar: XOHCL instance Reference ... + * @param breakerDir: ENUM_X_DIRECTION member ... + * + * @return ( bool ) + */ + bool IsStarted( + ENUM_X_DIRECTION forDir, + XOHCL &startedBar, + ENUM_X_DIRECTION &startedDir // + ) + { + // + bool result = false; + + // + startedBar.Clean(); + startedDir = X_DIRECTION_NONE; + + // + result = IsValid() && + HasDirection(forDir); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(forDir); + bool isBearish = IsBearish(forDir); + + // + // Detect From Bar Index ... + int fromIndex = iBarShift( + GetSymbol(), + GetPeriod(), + From() // + ); + + // + for (int i = fromIndex; i >= 0; i--) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + GetSymbol(), + GetPeriod(), + i // + ); + result = isInited; + if (!result) + { + continue; + } + + // + bool isBreakedFromUpper = + // + isBullish && + // + ( + // + iBar.low > Upper() || + (iBar.low <= Upper() && + iBar.high > Upper()) + // + ) + // + ; + + // + bool isBreakedFromLower = + // + isBearish && + // + ( + // + iBar.low < Lower() || + (iBar.high >= Lower() && + iBar.low < Lower()) + // + ) + // + ; + + // + bool isBreaked = + isBreakedFromUpper || + isBreakedFromLower; + if (isBreaked) + { + // + result = isBreaked; + startedBar = iBar; + startedDir = + isBreakedFromUpper + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + break; + } + } + + // + result = startedBar.IsValid() && + HasDirection(startedDir); + + // + return result; + } + + // + // Overrides ... + + void Clean() override + { + // + mBar.Clean(); + mUpper = 0; + mLower = 0; + mType = X_POI_NONE; + } + + datetime From() override + { + return mFrom; + } + + datetime To() override + { + return mTo; + } + + string GetTag() override + { + // + string result = NULL; + + // + if (!IsValidBarZone()) + { + return result; + } + + // + string hash = ToMD5(mBar.GetTag()); + + // + result = + // + TypeAsString() + mSep + + ToString(mBar.period) + mSep + + hash + // + ; + + // + return result; + } + + string GetTooltip() override + { + // + string result = NULL; + + // + if (!IsValidBarZone()) + { + return result; + } + + // + return result; + } + + // + protected: + // + // Props ... + XOHCL mBar; // Bar ... + ENUM_X_PRICE mUpperPrice; // Upper Price Selection + ENUM_X_PRICE mLowerPrice; // Lower Price Selection + + /** + * Check Bar Zone Validation ... + * + * @return ( bool ) + */ + bool IsValidBarZone() + { + // + bool result = false; + + // + result = mBar.IsValid() && + mType != X_POI_NONE && + IsValidBoundary(); + + // + return result; + } + + // + private: + // + // Props ... + datetime mFrom; + datetime mTo; + + // +}; +class XCTwoBarZone : public XCZone +{ + // + public: + // + + // + // Constructor ... + void XCTwoBarZone() + { + } + + // + // Deconstructor ... + void ~XCTwoBarZone() + { + } + + // + // Tools ... + + /** + * Initialize POI ... + * + * @param bar: XOHCL instance ... + * @param type: ENUM_XPOIS member ... + * @param upperPrice: ENUM_X_PRICE member ... + * @param lowerPrice: ENUM_X_PRICE member ... + * + * @return ( bool ) + */ + bool InitTwoBarZone( + XOHCL &startBar, + XOHCL &endBar, + ENUM_XPOIS type, + bool useStartBarForUpper, + ENUM_X_PRICE upperPrice, + ENUM_X_PRICE lowerPrice // + ) + { + // + bool result = false; + + // + result = startBar.IsValid() && + endBar.IsValid() && + startBar.symbol == endBar.symbol && + startBar.period == endBar.period && + startBar.time < endBar.time && + type != X_POI_NONE; + if (!result) + { + return result; + } + + // + mType = type; + mEndBar = endBar; + mStartBar = startBar; + mUpperPrice = upperPrice; + mLowerPrice = lowerPrice; + mUseStartBarForUpper = useStartBarForUpper; + + mUpper = + useStartBarForUpper + ? startBar.GetPrice(upperPrice) + : endBar.GetPrice(upperPrice); + mLower = + useStartBarForUpper + ? endBar.GetPrice(lowerPrice) + : startBar.GetPrice(lowerPrice); + + // + result = IsValidTwoBarZone(); + if (result) + { + // + From(startBar.time); + To(endBar.time); + } + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + /** + * Set From Date ... + * + * @param value: DateTime ... + */ + void From(datetime value) + { + // + if (!IsValidTwoBarZone()) + { + return; + } + + // + value = NormalizeTime(value); + + // + mFrom = value; + } + + /** + * Set To Date ... + * + * @param value: DateTime ... + */ + void To(datetime value) + { + // + if (!IsValidTwoBarZone()) + { + return; + } + + // + value = NormalizeTime(value); + + // + mTo = value; + } + + /** + * Fill Start Bar ... + * + * @param bar: XOHCL instance ... + * + * @return ( bool ) + */ + bool FillStartBar(XOHCL &bar) + { + // + bool result = false; + + // + result = IsValidTwoBarZone(); + if (!result) + { + return result; + } + + // + bar = mStartBar; + + // + return result; + } + + /** + * Fill End Bar ... + * + * @param bar: XOHCL instance ... + * + * @return ( bool ) + */ + bool FillEndBar(XOHCL &bar) + { + // + bool result = false; + + // + result = IsValidTwoBarZone(); + if (!result) + { + return result; + } + + // + bar = mEndBar; + + // + return result; + } + + /** + * Get Symbol ... + * + * @return ( string ) + */ + string GetSymbol() + { + // + string result = NULL; + + // + if (!mStartBar.IsValid()) + { + return result; + } + + // + return mStartBar.symbol; + + // + return result; + } + + /** + * Get Period ... + * + * @return ( int ) + */ + ENUM_TIMEFRAMES GetPeriod() + { + // + ENUM_TIMEFRAMES result = NULL; + + // + if (!mStartBar.IsValid()) + { + return result; + } + + // + return mStartBar.period; + + // + return result; + } + + /** + * Is Activated Zone or not ... + * + * @param activatedBar: XOHCL instance Reference ... + * @param activatedDir: ENUM_X_DIRECTION member ... + * + * @return ( bool ) + */ + bool IsActivated( + XOHCL &activatedBar, + ENUM_X_DIRECTION &activatedDir // + ) + { + // + bool result = false; + + // + activatedBar.Clean(); + activatedDir = X_DIRECTION_NONE; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + // Detect From Bar Index ... + int fromIndex = iBarShift( + GetSymbol(), + GetPeriod(), + From() // + ); + fromIndex--; + + // + for (int i = fromIndex; i >= 0; i--) + { + // + if (i == fromIndex) + { + continue; + } + + // + XOHCL iBar; + bool isInited = iBar.Init( + GetSymbol(), + GetPeriod(), + i // + ); + result = isInited; + if (!result) + { + continue; + } + + // + XOHCL iPBar; + isInited = iBar + .GetPreviousBar(iPBar); + result = isInited; + if (!result) + { + continue; + } + + // + bool isActivedFromUpper = + // + (iPBar.low > Upper() && + iBar.low <= Upper()) + // + ; + + // + bool isActivedFromLower = + // + (iPBar.high < Lower() && + iBar.high >= Lower()) + // + ; + + // + bool isActivated = + isActivedFromUpper || + isActivedFromLower; + if (isActivated) + { + // + result = isActivated; + activatedBar = iBar; + activatedDir = + isActivedFromUpper + ? X_DIRECTION_BEARISH + : X_DIRECTION_BULLISH; + break; + } + } + + // + return result; + } + + /** + * Is Breaked Zone or not ... + * + * @param breakerBar: XOHCL instance Reference ... + * @param breakerDir: ENUM_X_DIRECTION member ... + * + * @return ( bool ) + */ + bool IsBreaked( + XOHCL &breakerBar, + ENUM_X_DIRECTION &breakerDir // + ) + { + // + bool result = false; + + // + breakerBar.Clean(); + breakerDir = X_DIRECTION_NONE; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + XOHCL activatedBar; + ENUM_X_DIRECTION activatedDir; + bool isActivated = IsActivated( + activatedBar, + activatedDir // + ); + result = isActivated; + if (!result) + { + return result; + } + + // + int activatedIndex = activatedBar.Index(); + activatedIndex--; + + // + for (int i = activatedIndex; i >= 0; i--) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + GetSymbol(), + GetPeriod(), + i // + ); + result = isInited; + if (!result) + { + continue; + } + + // + XOHCL iPBar; + isInited = iBar + .GetPreviousBar(iPBar); + result = isInited; + if (!result) + { + continue; + } + + // + bool isBreakedFromUpper = + // + (iPBar.high <= Upper() && + iBar.low > Upper()) + // + ; + + // + bool isBreakedFromLower = + // + (iPBar.low >= Lower() && + iBar.low < Lower()) + // + ; + + // + bool isBreaked = + isBreakedFromUpper || + isBreakedFromLower; + if (isBreaked) + { + // + result = isBreaked; + breakerBar = iBar; + breakerDir = + isBreakedFromUpper + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + break; + } + } + + // + return result; + } + + // + // Overrides ... + + void Clean() override + { + // + mStartBar.Clean(); + mEndBar.Clean(); + mUpper = 0; + mLower = 0; + mUseStartBarForUpper = false; + mType = X_POI_NONE; + } + + datetime From() override + { + return mFrom; + } + + datetime To() override + { + return mTo; + } + + string GetTag() override + { + // + string result = NULL; + + // + if (!IsValidTwoBarZone()) + { + return result; + } + + // + string hash = ToMD5(mStartBar.GetTag() + mSep + mEndBar.GetTag()); + + // + result = + // + TypeAsString() + mSep + + ToString(mStartBar.period) + mSep + + hash + // + ; + + // + return result; + } + + string GetTooltip() override + { + // + string result = NULL; + + // + if (!IsValidTwoBarZone()) + { + return result; + } + + // + return result; + } + + // + protected: + // + // Props ... + XOHCL mStartBar; // Start (Oldest) Bar ... + XOHCL mEndBar; // End (Newest) Bar ... + bool mUseStartBarForUpper; // Use Start Bar for Upper Calculation ... + ENUM_X_PRICE mUpperPrice; // Upper Price Selection + ENUM_X_PRICE mLowerPrice; // Lower Price Selection + + /** + * Check Two Bar Zone Validation ... + * + * @return ( bool ) + */ + bool IsValidTwoBarZone() + { + // + bool result = false; + + // + result = mStartBar.IsValid() && + mEndBar.IsValid() && + mStartBar.symbol == mEndBar.symbol && + mStartBar.period == mEndBar.period && + mStartBar.time < mEndBar.time && + mType != X_POI_NONE && + IsValidBoundary(); + + // + return result; + } + + // + private: + // + // Props ... + datetime mFrom; + datetime mTo; + + // +}; + +// +// Swing Class ... +class XCSwing : public XCBasePOI +{ + // + public: + // + + // + // Constructor ... + void XCSwing() + { + } + + // + // Deconstructor ... + void ~XCSwing() + { + } + + // + // Tools ... + + /** + * Initialize POI ... + * + * @param bar: XOHCL instance ... + * @param type: ENUM_XPOIS member ... + * + * @return ( bool ) + */ + bool Init( + XOHCL &bar, + ENUM_XPOIS type // + ) + { + // + bool result = false; + + // + result = bar.IsValid() && + (type == X_POI_SWING_HIGH || + type == X_POI_SWING_LOW); + if (!result) + { + return result; + } + + // + mBar = bar; + mType = type; + + // + result = IsValid(); + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + /** + * Fill Bar as XOHCL struct ... + * + * @param bar: XOHCL instance ... + * + * @return ( bool ) + */ + bool FillBar( + XOHCL &bar // + ) + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + bar = mBar; + result = mBar.IsValid(); + + // + return result; + } + + /** + * Get Time of Swing ... + * + * @return ( datetime ) + */ + datetime GetTime() + { + // + datetime result = NULL; + + // + if (!IsValid() || !mBar.IsValid()) + { + return result; + } + + // + result = mBar.time; + + // + return result; + } + + ENUM_TIMEFRAMES GetPeriod() + { + // + ENUM_TIMEFRAMES result = NULL; + + // + XOHCL bar; + bool isFilled = FillBar(bar); + if (!isFilled) + { + return result; + } + + // + result = bar.period; + + // + return result; + } + + /** + * Check Swing High or not ... + * + * @return ( bool ) + */ + bool IsSwingHigh() + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + result = + Type() == X_POI_SWING_HIGH; + + // + return result; + } + + /** + * Check Swing Low or not ... + * + * @return ( bool ) + */ + bool IsSwingLow() + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + result = + Type() == X_POI_SWING_LOW; + + // + return result; + } + + /** + * Get Swing Value ... + * + * @return ( double ) + */ + double GetValue() + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = + IsSwingHigh() + ? mBar.high + : mBar.low; + + // + return result; + } + + // + // Overrides ... + + void Clean() override + { + // + mBar.Clean(); + mType = X_POI_NONE; + } + + bool IsValid() override + { + // + bool result = false; + + // + result = mBar.IsValid() && + (mType == X_POI_SWING_HIGH || + mType == X_POI_SWING_LOW); + + // + return result; + } + + string GetTag() override + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + string hash = ToMD5(mBar.GetTag()); + + // + string subType = IsSwingHigh() + ? "High" + : "Low"; + + // + result = + // + TypeAsString() + mSep + + subType + mSep + + ToString(mBar.period) + mSep + + hash + // + ; + + // + return result; + } + + string GetTooltip() override + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + return result; + } + + // + protected: + // + // Props ... + XOHCL mBar; // Swing Bar ... + + // + private: + // +}; + +// +// Supply Zone ... +class XCSupplyZone : public XCBarZone +{ + // + public: + // + + // + // Constructor ... + void XCSupplyZone() + { + } + + // + // Deconstructor ... + void ~XCSupplyZone() + { + } + + // + // Tools ... + + /** + * Initialize POI ... + * + * @param bar: XOHCL instance ... + * @param range: Integer, Detection Range ... + * + * @return ( bool ) + */ + bool Init( + XOHCL &bar, + int range = 0 // + ) + { + // + bool result = false; + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + result = InitBarZone( + bar, + X_POI_SUPPLY_ZONE, + X_PRICE_HIGH, + X_PRICE_LOW // + ); + if (!result) + { + return result; + } + + // + result = IsValid(); + if (result && + range > 0) + { + // + datetime time = bar.time; + int periodSeconds = PeriodSeconds(bar.period); + + // + datetime from = (datetime)((int)time - (range * periodSeconds)); + datetime to = (datetime)((int)time + (range * periodSeconds)); + + // + From(from); + To(to); + } + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + // + // Overrides ... + + bool IsValid() override + { + // + bool result = false; + + // + result = IsValidBarZone() && + mType == X_POI_SUPPLY_ZONE; + + // + return result; + } + + // + protected: + // + + // + private: + // + + // +}; + +// +// Demand Zone ... +class XCDemandZone : public XCBarZone +{ + // + public: + // + + // + // Constructor ... + void XCDemandZone() + { + } + + // + // Deconstructor ... + void ~XCDemandZone() + { + } + + // + // Tools ... + + /** + * Initialize POI ... + * + * @param bar: XOHCL instance ... + * @param range: Integer, Detection Range ... + * + * @return ( bool ) + */ + bool Init( + XOHCL &bar, + int range = 0 // + ) + { + // + bool result = false; + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + result = InitBarZone( + bar, + X_POI_DEMAND_ZONE, + X_PRICE_HIGH, + X_PRICE_LOW // + ); + if (!result) + { + return result; + } + + // + result = IsValid(); + if (result && + range > 0) + { + // + datetime time = bar.time; + int periodSeconds = PeriodSeconds(bar.period); + + // + datetime from = (datetime)((int)time - (range * periodSeconds)); + datetime to = (datetime)((int)time + (range * periodSeconds)); + + // + From(from); + To(to); + } + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + // + // Overrides ... + + bool IsValid() override + { + // + bool result = false; + + // + result = IsValidBarZone() && + mType == X_POI_DEMAND_ZONE; + + // + return result; + } + + // + protected: + // + + // + private: + // + + // +}; + +// +// Support Zone ... +class XCSupportZone : public XCBarZone +{ + // + public: + // + + // + // Constructor ... + void XCSupportZone() + { + } + + // + // Deconstructor ... + void ~XCSupportZone() + { + } + + // + // Tools ... + + /** + * Initialize POI ... + * + * @param bar: XOHCL instance ... + * @param range: Integer, Detection Range ... + * + * @return ( bool ) + */ + bool Init( + XOHCL &bar, + int range = 0 // + ) + { + // + bool result = false; + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + result = InitBarZone( + bar, + X_POI_SUPPORT_ZONE, + X_PRICE_DOWN, + X_PRICE_LOW // + ); + if (!result) + { + return result; + } + + // + result = IsValid(); + if (result && + range > 0) + { + // + datetime time = bar.time; + int periodSeconds = PeriodSeconds(bar.period); + + // + datetime from = (datetime)((int)time - (range * periodSeconds)); + datetime to = (datetime)((int)time + (range * periodSeconds)); + + // + From(from); + To(to); + } + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + // + // Overrides ... + + bool IsValid() override + { + // + bool result = false; + + // + result = IsValidBarZone() && + mType == X_POI_SUPPORT_ZONE; + + // + return result; + } + + // + protected: + // + + // + private: + // + + // +}; + +// +// Resistance Zone ... +class XCResistanceZone : public XCBarZone +{ + // + public: + // + + // + // Constructor ... + void XCResistanceZone() + { + } + + // + // Deconstructor ... + void ~XCResistanceZone() + { + } + + // + // Tools ... + + /** + * Initialize POI ... + * + * @param bar: XOHCL instance ... + * @param range: Integer, Detection Range ... + * + * @return ( bool ) + */ + bool Init( + XOHCL &bar, + int range = 0 // + ) + { + // + bool result = false; + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + result = InitBarZone( + bar, + X_POI_RESISTANCE_ZONE, + X_PRICE_HIGH, + X_PRICE_UP // + ); + if (!result) + { + return result; + } + + // + result = IsValid(); + if (result && + range > 0) + { + // + datetime time = bar.time; + int periodSeconds = PeriodSeconds(bar.period); + + // + datetime from = (datetime)((int)time - (range * periodSeconds)); + datetime to = (datetime)((int)time + (range * periodSeconds)); + + // + From(from); + To(to); + } + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + // + // Overrides ... + + bool IsValid() override + { + // + bool result = false; + + // + result = IsValidBarZone() && + mType == X_POI_RESISTANCE_ZONE; + + // + return result; + } + + // + protected: + // + + // + private: + // + + // +}; + +// +// Order Block ... +class XCOrderBlock : public XCBarZone +{ + // + public: + // + + // + // Constructor ... + void XCOrderBlock() + { + } + + // + // Deconstructor ... + void ~XCOrderBlock() + { + } + + // + // Tools ... + + /** + * Initialize POI ... + * + * @param bar: XOHCL instance ... + * @param dir: ENUM_X_DIRECTION member ... + * + * @return ( bool ) + */ + bool Init( + XOHCL &bar, + ENUM_X_DIRECTION dir // + ) + { + // + bool result = false; + + // + result = bar.IsValid() && + (dir == X_DIRECTION_BULLISH || + dir == X_DIRECTION_BEARISH); + if (!result) + { + return result; + } + + // + ENUM_XPOIS mTT = + IsSpecifiedBullish(dir) + ? X_POI_BULLISH_ORDERBLOCK + : X_POI_BEARISH_ORDERBLOCK; + + // + result = InitBarZone( + bar, + mTT, + X_PRICE_HIGH, + X_PRICE_LOW // + ); + if (!result) + { + return result; + } + + // + result = IsValid(); + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + /** + * Check is Bullish ... + * + * @return ( bool ) + */ + bool IsBullish() + { + // + bool result = false; + + // + result = IsValid() && + Type() == X_POI_BULLISH_ORDERBLOCK; + + // + return result; + } + + /** + * Check is Bearish ... + * + * @return ( bool ) + */ + bool IsBearish() + { + // + bool result = false; + + // + result = IsValid() && + Type() == X_POI_BEARISH_ORDERBLOCK; + + // + return result; + } + + // + // Overrides ... + + bool IsValid() override + { + // + bool result = false; + + // + result = IsValidBarZone() && + (mType == X_POI_BULLISH_ORDERBLOCK || + mType == X_POI_BEARISH_ORDERBLOCK); + + // + return result; + } + + // + protected: + // + + // + private: + // + + // +}; + +// +// Rejection Bar ... +class XCRejectionBar : public XCBarZone +{ + // + public: + // + + // + // Constructor ... + void XCRejectionBar() + { + } + + // + // Deconstructor ... + void ~XCRejectionBar() + { + } + + // + // Tools ... + + /** + * Initialize POI ... + * + * @param bar: XOHCL instance ... + * + * @return ( bool ) + */ + bool Init( + XOHCL &bar // + ) + { + // + bool result = false; + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + bool isBullish = + bar.GetLowShadow() > bar.GetHighShadow(); + bool isBearish = + bar.GetHighShadow() > bar.GetLowShadow(); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + ENUM_X_PRICE upPrice = isBullish + ? X_PRICE_HIGH + : X_PRICE_DOWN; + // + ENUM_X_PRICE loPrice = isBullish + ? X_PRICE_UP + : X_PRICE_LOW; + + // + result = InitBarZone( + bar, + X_POI_REJECTION_BAR, + upPrice, + loPrice // + ); + if (!result) + { + return result; + } + + // + result = IsValid(); + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + /** + * Check is Bullish ... + * + * @return ( bool ) + */ + bool IsBullish() + { + // + bool result = false; + + // + result = IsValid() && + Type() == X_POI_REJECTION_BAR && + mBar.GetLowShadow() > mBar.GetHighShadow(); + + // + return result; + } + + /** + * Check is Bearish ... + * + * @return ( bool ) + */ + bool IsBearish() + { + // + bool result = false; + + // + result = IsValid() && + Type() == X_POI_REJECTION_BAR && + mBar.GetHighShadow() > mBar.GetLowShadow(); + + // + return result; + } + + // + // Overrides ... + + bool IsValid() override + { + // + bool result = false; + + // + result = IsValidBarZone() && + mType == X_POI_REJECTION_BAR; + + // + return result; + } + + // + protected: + // + + // + private: + // + + // +}; + +// +// Momentum Bar ... +class XCMomentumBar : public XCBarZone +{ + // + public: + // + + // + // Constructor ... + void XCMomentumBar() + { + } + + // + // Deconstructor ... + void ~XCMomentumBar() + { + } + + // + // Tools ... + + /** + * Initialize POI ... + * + * @param bar: XOHCL instance ... + * + * @return ( bool ) + */ + bool Init( + XOHCL &bar // + ) + { + // + bool result = false; + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + bool isBullish = bar.IsBullish(); + bool isBearish = bar.IsBearish(); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + result = InitBarZone( + bar, + X_POI_MOMENTUM_BAR, + X_PRICE_HIGH, + X_PRICE_LOW // + ); + if (!result) + { + return result; + } + + // + result = IsValid(); + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + /** + * Check is Bullish ... + * + * @return ( bool ) + */ + bool IsBullish() + { + // + bool result = false; + + // + result = IsValid() && + mBar.IsBullish() && + Type() == X_POI_MOMENTUM_BAR; + + // + return result; + } + + /** + * Check is Bearish ... + * + * @return ( bool ) + */ + bool IsBearish() + { + // + bool result = false; + + // + result = IsValid() && + mBar.IsBearish() && + Type() == X_POI_MOMENTUM_BAR; + + // + return result; + } + + // + // Overrides ... + + bool IsValid() override + { + // + bool result = false; + + // + result = IsValidBarZone() && + mType == X_POI_MOMENTUM_BAR; + + // + return result; + } + + // + protected: + // + + // + private: + // + + // +}; + +// +// Fair Value Gap ... +class XCFVG : public XCTwoBarZone +{ + // + public: + // + + // + // Constructor ... + void XCFVG() + { + } + + // + // Deconstructor ... + void ~XCFVG() + { + } + + // + // Tools ... + + /** + * Initialize POI ... + * + * @param startBar: XOHCL instance ... + * @param endBar: XOHCL instance ... + * @param dir: ENUM_X_DIRECTION member ... + * + * @return ( bool ) + */ + bool Init( + XOHCL &startBar, + XOHCL &endBar, + ENUM_X_DIRECTION dir // + ) + { + // + bool result = false; + + // + result = endBar.IsValid() && + startBar.IsValid() && + (dir == X_DIRECTION_BULLISH || + dir == X_DIRECTION_BEARISH); + if (!result) + { + return result; + } + + // + bool isDirBullish = IsSpecifiedBullish(dir); + ENUM_XPOIS mTT = + isDirBullish + ? X_POI_BULLISH_FVG + : X_POI_BEARISH_FVG; + + // + bool useFistForUpper = isDirBullish + ? false + : true; + ENUM_X_PRICE upPrice = isDirBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + ENUM_X_PRICE loPrice = isDirBullish + ? X_PRICE_HIGH + : X_PRICE_LOW; + + // + result = InitTwoBarZone( + startBar, + endBar, + mTT, + useFistForUpper, + upPrice, + loPrice // + ); + if (!result) + { + return result; + } + + // + result = IsValid(); + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + /** + * Check is Bullish ... + * + * @return ( bool ) + */ + bool IsBullish() + { + // + bool result = false; + + // + result = IsValid() && + Type() == X_POI_BULLISH_FVG; + + // + return result; + } + + /** + * Check is Bearish ... + * + * @return ( bool ) + */ + bool IsBearish() + { + // + bool result = false; + + // + result = IsValid() && + Type() == X_POI_BEARISH_FVG; + + // + return result; + } + + // + // Overrides ... + + bool IsValid() override + { + // + bool result = false; + + // + result = IsValidTwoBarZone() && + (mType == X_POI_BULLISH_FVG || + mType == X_POI_BEARISH_FVG); + + // + return result; + } + + // + protected: + // + + // + private: + // + + // +}; + +// +// Ticks Zones ... + +// +class XCTickZone : public CObject +{ + // + // Public ... + public: + // + // Props ... + string symbol; + ENUM_TIMEFRAMES period; + + // + double high; + double low; + int ticks; + double percent; + + // + ulong volume; + double volumePercent; + + // + // Compare Two Zone With Each Other ... + virtual int Compare( + const CObject *node, + const int mode = 0 // + ) const + { + // + const XCTickZone *other = (XCTickZone *)node; + + // + return other.ticks - ticks; + } + + // + bool IsValid() + { + // + bool result = false; + + // + result = high > 0 && + low > 0 && + high > low && + ticks > 0 && + percent > 0; + + // + return result; + } + + // + // Protected ... + protected: + // + // Private ... + private: + // +}; + +// +class XCTicksZone : public XCTwoBarZone +{ + // + public: + // + + // + // Constructor ... + void XCTicksZone() + { + Default(); + } + + // + // Deconstructor ... + void ~XCTicksZone() + { + } + + // + // Getter(s) / Setter(s) ... + + /** + * Get Number of Ticks Levels ... + * + * @return ( int ) + */ + int Levels() + { + return mLevels; + } + + /** + * Set Number of Ticks Levels ... + * + * @return ( int ) + */ + void Levels(int value) + { + // + if (value < 2) + { + value = 2; + } + + // + mLevels = value; + } + + /** + * Apply Default Config ... + */ + virtual void Default() + { + // + Levels(10); + } + + // + // Tools ... + + /** + * Initialize POI ... + * + * @param startBar: XOHCL instance ... + * @param endBar: XOHCL instance ... + * + * @return ( bool ) + */ + bool Init( + XOHCL &startBar, + XOHCL &endBar // + ) + { + // + bool result = false; + + // + result = endBar.IsValid() && + startBar.IsValid(); + if (!result) + { + return result; + } + + // + // Calculate Start and End Time ... + datetime from = startBar.time; + datetime to = endBar.time; + ulong fromM = ((ulong)startBar.time * 1000); + ulong toM = ((ulong)endBar.time * 1000); + + // + // Symbol and Period ... + string symbol = startBar.symbol; + ENUM_TIMEFRAMES period = startBar.period; + + // + // Prepare Zones Array ... + mZones.Clear(); + + // + // Retrieve Ticks between Times ... + SpecificClean(mTicks); + CopyTicksRange( + symbol, + mTicks, + COPY_TICKS_ALL, + fromM, + toM // + ); + + // + // Ticks Volumes ... + int ticksVolumeCount = CopyTickVolume( + symbol, + PERIOD_M1, + from, + to, + mTickVolumes // + ); + if (IsValidSize(ticksVolumeCount)) + { + // + mVolumes = 0; + for (int i = 0; i < ticksVolumeCount; i++) + { + mVolumes += mTickVolumes[i]; + } + } + + // + // Retrieve Highs ... + SpecificClean(mHighs); + CopyHigh( + symbol, + period, + from, + to, + mHighs // + ); + + // + // Retrieve Lows ... + SpecificClean(mLows); + CopyLow( + symbol, + period, + from, + to, + mLows // + ); + + // + // Find Highest Value in Range ... + int highIDX = ArrayMaximum(mHighs); + mRangeHigh = mHighs[highIDX]; + + // + // Find Lowest Value in Range ... + int lowIDX = ArrayMinimum(mLows); + mRangeLow = mLows[lowIDX]; + + // + datetime mTimes[]; + CopyTime( + symbol, + period, + from, + to, + mTimes // + ); + mRangeHighTime = mTimes[highIDX]; + mRangeLowTime = mTimes[lowIDX]; + + // + double mRangeSize = mRangeHigh - mRangeLow; + + // + // Create Zones ... + for (int i = 0; i < Levels(); i++) + { + // + // Instance a New Zone ... + XCTickZone *iZone = new XCTickZone(); + + // + iZone.symbol = symbol; + iZone.period = period; + + // + // Calculate Each Zones High / Low based on Range ... + double iH = mRangeHigh - mRangeSize * i / Levels(); + double iL = mRangeHigh - mRangeSize * (i + 1) / Levels(); + + // + // Set Zone High Low Properties ... + iZone.low = iL; + iZone.high = iH; + + // + // Add Zone to Zone Array Objects ... + mZones.Add(iZone); + } + + // + // Calculate Each Zone Ticks ... + int ticksCount = ArraySize(mTicks); + for (int i = 0; i < ticksCount; i++) + { + // + // Retrieve Tick ... + MqlTick iTick = mTicks[i]; + + // + // Loop through Zones ... + for (int j = 0; j < Levels(); j++) + { + // + // Rejrieve j indexed Zone Object ... + XCTickZone *jZone = mZones.At(j); + + // + bool isInRange = IsTickInZoneRange( + iTick, + jZone // + ); + if (isInRange) + { + // + jZone.ticks++; + break; + } + } + } + + // + // Calculating Zone Percents ... + for (int i = 0; i < Levels(); i++) + { + // + XCTickZone *iZone = mZones.At(i); + + // + double percent = CalculateZoneTickPercent(iZone); + iZone.percent = percent; + } + + // + // Sort Zones Based on Percents ... + mZones.Sort(); + + // + mUpper = mRangeHigh; + mLower = mRangeLow; + mType = X_POI_TICKS_ZONES; + mEndBar = endBar; + mStartBar = startBar; + From(startBar.time); + To(endBar.time); + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + // Try to Find Out PERIOD_1M times in each zone ... + datetime to1M = (datetime)((int)endBar.time + PeriodSeconds(period) - 60); + int to1MIndex = iBarShift( + symbol, + PERIOD_M1, + to1M // + ); + int from1MIndex = iBarShift( + symbol, + PERIOD_M1, + from // + ); + for (int i = from1MIndex; i > to1MIndex; i--) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + symbol, + PERIOD_M1, + i // + ); + if (!isInited) + { + continue; + } + ulong iVolume = iTickVolume( + symbol, + PERIOD_M1, + i // + ); + + // + // Loop through Zones ... + for (int j = 0; j < Levels(); j++) + { + // + XCTickZone *jZone = mZones.At(j); + if (!jZone.IsValid()) + { + continue; + } + + // + // Check iBar is Inside jZone ... + bool isIBarInside = + iBar.GetUp() < jZone.high && + iBar.GetDown() > jZone.low; + // iBar.low < jZone.high || + // iBar.high > jZone.low; + if (isIBarInside) + { + jZone.volume += iVolume; + } + } + } + + // + // Calculate Volume Percent ... + for (int i = 0; i < Levels(); i++) + { + // + XCTickZone *iZone = mZones.At(i); + + // + if (mVolumes > 0) + { + iZone.volumePercent = (double)(iZone.volume * 100 / mVolumes); + } + } + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + /** + * Retrieve Zones Count ... + * + * @return ( int ) + */ + int Count() + { + return mZones.Total(); + } + + /** + * Retrieve Specified Sorted Zones ... + * + * @param index: Integer ... + * + * @return ( XCTickZone * ) + */ + XCTickZone *GetZone(int index) + { + // + if (!IsValidIndex(index)) + { + return NULL; + } + + // + return mZones.At(index); + } + + /** + * Calculate Liquidity Percent for Specified Direction ... + * + * @param forDirection: ENUM_X_DIRECTION member, Specified Liquidity ... + * @param price: Double, Specified Price ... + * + * @return ( double ) + */ + double CalculateLiquidityPercent( + ENUM_X_DIRECTION forDirection, + double price // + ) + { + // + double result = 0; + + // + int count = Count(); + if (price <= 0 || + !IsValid() || + !IsValidSize(count) || + forDirection == X_DIRECTION_ALL || + forDirection == X_DIRECTION_NONE) + { + return result; + } + + // + bool isBullish = forDirection == X_DIRECTION_BULLISH; + + // + for (int i = 0; i < count; i++) + { + // + XCTickZone *iZone = GetZone(i); + + // + if (iZone.IsValid()) + { + // + result += !isBullish && + price > iZone.high + ? iZone.percent + : isBullish && + price < iZone.low + ? iZone.percent + : 0; + } + } + + // + return result; + } + + // + // Overrides ... + bool IsValid() override + { + // + bool result = false; + + // + result = + IsValidFrom() && + IsValidTwoBarZone() && + Levels() > 0 && + mZones.Total() == Levels() && + mRangeHigh > 0 && + mRangeLow > 0; + + // + return result; + } + + // + protected: + // + + // + private: + // + // Props ... + + // + MqlTick mTicks[]; + double mHighs[]; + double mLows[]; + ulong mVolumes; + ulong mTickVolumes[]; + double mRangeHigh; + datetime mRangeHighTime; + double mRangeLow; + datetime mRangeLowTime; + + // + int mLevels; // Number of Ticks Levels ... + + // + CArrayObj mZones; + + /** + * Check a Tick is in a Zone rage or not ... + * + * @param tick: MqlTick instance ... + * @param zone: XCTickZone instance ... + * + * @return ( bool ) + */ + bool IsTickInZoneRange( + MqlTick &tick, + XCTickZone *zone // + ) + { + // + bool result = false; + + // + result = + // + tick.bid >= zone.low && + tick.bid <= zone.high + // + ; + + // + return result; + } + + /** + * Calculate Zone Tick Percent ... + * + * @param zone: XCTickZone instance ... + * @param normalizationDigits: Integer ... + * + * @return ( double ) + */ + double CalculateZoneTickPercent( + XCTickZone *zone, + int normalizationDigits = 2 // + ) + { + // + double result = 0; + + // + if (normalizationDigits < 2 || normalizationDigits > 5) + { + normalizationDigits = 2; + } + + // + int ticksCount = ArraySize(mTicks); + if (ticksCount <= 0) + { + return result; + } + + // + result = (double)zone.ticks / ticksCount * 100; + result = NormalizeDouble(result, normalizationDigits); + + // + return result; + } + + // +}; + +// +// Trading Day ... +class XCDay : public XCFromToZone +{ + // + public: + // + + // + // Constructor ... + void XCDay() + { + } + + // + // Deconstructor ... + void ~XCDay() + { + } + + // + // Tools ... + + /** + * Initialize POI ... + * + * @return ( bool ) + */ + bool Init() + { + // + bool result = false; + + // + result = IsValid(); + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + // + // Overrides ... + + // + protected: + // + + // + private: + // + + // +}; + +// +// Trading Session ... +class XCSession : public XCFromToZone +{ + // + public: + // + + // + // Constructor ... + void XCSession() + { + } + + // + // Deconstructor ... + void ~XCSession() + { + } + + // + // Tools ... + + /** + * Initialize POI ... + * + * @return ( bool ) + */ + bool Init() + { + // + bool result = false; + + // + result = IsValid(); + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + // + // Overrides ... + + // + protected: + // + + // + private: + // + + // +}; + +// +// +// Model Exists Founded POIs ... +struct XPOIState +{ + // + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + XCTicksZone *ticksZone; // Ticks Zone ... + + // + XCSwing *swingHighs[]; // Holds Founded Swing Highs ... + XCSwing *swingLows[]; // Holds Founded Swing Lows ... + XCMomentumBar *bullishMomentumBars[]; // Holds Founded Bullish Momentum Bars ... + XCMomentumBar *bearishMomentumBars[]; // Holds Founded Bearish Momentum Bars ... + XCRejectionBar *bullishRejectionBars[]; // Holds Founded Bullish Rejection Bars ... + XCRejectionBar *bearishRejectionBars[]; // Holds Founded Bearish Rejection Bars ... + 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 ... + + // + // Constructor ... + void XPOIState() + { + Clean(); + } + + // + // Actions ... + + /** + * Cleanup all props ... + */ + void Clean() + { + // + symbol = NULL; + period = NULL; + time = NULL; + + // + ticksZone = NULL; + + // + Clean(swingHighs); + Clean(swingLows); + Clean(bullishMomentumBars); + Clean(bearishMomentumBars); + Clean(bullishRejectionBars); + Clean(bearishRejectionBars); + Clean(supportZones); + Clean(resistanceZones); + Clean(supplyZones); + Clean(demandZones); + Clean(bullishOrderBlocks); + Clean(bearishOrderBlocks); + Clean(bullishFairValueGaps); + Clean(bearishFairValueGaps); + + // + ZeroMemory(this); + } + + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + IsSpecifiedValid(symbol) && + IsSpecifiedValid(period) && + IsSpecifiedValid(time); + + // + return result; + } + + /** + * Check State has Childs or not ... + * + * @return ( bool ) + */ + bool HasChild() + { + // + bool result = false; + + // + result = + // + IsValidSize(CountSwingHighs()) || + IsValidSize(CountSwingLows()) || + IsValidSize(CountBullishMomentumBars()) || + IsValidSize(CountBearishMomentumBars()) || + IsValidSize(CountBullishRejectionBars()) || + IsValidSize(CountBearishRejectionBars()) || + IsValidSize(CountSupportZones()) || + IsValidSize(CountResistanceZones()) || + IsValidSize(CountSupplyZones()) || + IsValidSize(CountDemandZones()) || + IsValidSize(CountBullishOrderBlocks()) || + IsValidSize(CountBearishOrderBlocks()) || + IsValidSize(CountBullishFairValueGaps()) || + IsValidSize(CountBearishFairValueGaps()) + // + ; + + // + return result; + } + + /** + * Fill Dest State by Current State's Data ... + * + * @param dest: XPOIState instance, reference to specified dest ... + * + */ + void Fill(XPOIState &dest) + { + // + if (!IsValid() || + !HasChild()) + { + return; + } + + // + dest.symbol = symbol; + dest.period = period; + dest.time = time; + + // + Copy( + swingHighs, + dest.swingHighs, + false // + ); + Copy( + swingLows, + dest.swingLows, + false // + ); + Copy( + bullishMomentumBars, + dest.bullishMomentumBars, + false // + ); + Copy( + bearishMomentumBars, + dest.bearishMomentumBars, + false // + ); + Copy( + bullishRejectionBars, + dest.bullishRejectionBars, + false // + ); + Copy( + bearishRejectionBars, + dest.bearishRejectionBars, + false // + ); + Copy( + supportZones, + dest.supportZones, + false // + ); + Copy( + resistanceZones, + dest.resistanceZones, + false // + ); + Copy( + supplyZones, + dest.supplyZones, + false // + ); + Copy( + demandZones, + dest.demandZones, + false // + ); + Copy( + bullishOrderBlocks, + dest.bullishOrderBlocks, + false // + ); + Copy( + bearishOrderBlocks, + dest.bearishOrderBlocks, + false // + ); + Copy( + bullishFairValueGaps, + dest.bullishFairValueGaps, + false // + ); + Copy( + bearishFairValueGaps, + dest.bearishFairValueGaps, + false // + ); + + // + } + + /** + * Calculate Liquidity Percent for Specified Direction ... + * + * @param forDirection: ENUM_X_DIRECTION member, Specified Liquidity ... + * @param price: Double, Specified Price ... + * + * @return ( double ) + */ + double CalculateLiquidityPercent( + ENUM_X_DIRECTION forDirection, + double price = 0 // + ) + { + // + double result = 0; + + // + if (!IsValid() || + ticksZone == NULL) + { + return result; + } + + // + // Normalize Price for Actions ... + if (price <= 0) + { + // + MqlTick mTick; + bool isTickRetrieved = GetTick( + symbol, + mTick // + ); + if (isTickRetrieved) + { + price = mTick.bid; + } + } + + // + result = ticksZone + .CalculateLiquidityPercent( + forDirection, + price // + ); + + // + return result; + } + + // + // Counters ... + + // + int CountSwingHighs() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(swingHighs); + + // + return result; + } + + // + bool HasSwingHighs() + { + return IsValidSize(CountSwingHighs()); + } + + // + int CountSwingLows() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(swingLows); + + // + return result; + } + + // + bool HasSwingLows() + { + return IsValidSize(CountSwingLows()); + } + + // + int CountBullishMomentumBars() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(bullishMomentumBars); + + // + return result; + } + + // + bool HasBullishMomentumBars() + { + return IsValidSize(CountBullishMomentumBars()); + } + + // + int CountBearishMomentumBars() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(bearishMomentumBars); + + // + return result; + } + + // + bool HasBearishMomentumBars() + { + return IsValidSize(CountBearishMomentumBars()); + } + + // + int CountBullishRejectionBars() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(bullishRejectionBars); + + // + return result; + } + + // + bool HasBullishRejectionBars() + { + return IsValidSize(CountBullishRejectionBars()); + } + + // + int CountBearishRejectionBars() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(bearishRejectionBars); + + // + return result; + } + + // + bool HasBearishRejectionBars() + { + return IsValidSize(CountBearishRejectionBars()); + } + + // + int CountSupportZones() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(supportZones); + + // + return result; + } + + // + bool HasSupportZones() + { + return IsValidSize(CountSupportZones()); + } + + // + int CountResistanceZones() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(resistanceZones); + + // + return result; + } + + // + bool HasResistanceZones() + { + return IsValidSize(CountResistanceZones()); + } + + // + int CountSupplyZones() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(supplyZones); + + // + return result; + } + + // + bool HasSupplyZones() + { + return IsValidSize(CountSupplyZones()); + } + + // + int CountDemandZones() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(demandZones); + + // + return result; + } + + // + bool HasDemandZones() + { + return IsValidSize(CountDemandZones()); + } + + // + int CountBullishOrderBlocks() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(bullishOrderBlocks); + + // + return result; + } + + // + bool HasBullishOrderBlocks() + { + return IsValidSize(CountBullishOrderBlocks()); + } + + // + int CountBearishOrderBlocks() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(bearishOrderBlocks); + + // + return result; + } + + // + bool HasBearishOrderBlocks() + { + return IsValidSize(CountBearishOrderBlocks()); + } + + // + int CountBullishFairValueGaps() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(bullishFairValueGaps); + + // + return result; + } + + // + bool HasBullishFairValueGaps() + { + return IsValidSize(CountBullishFairValueGaps()); + } + + // + int CountBearishFairValueGaps() + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = ArraySize(bearishFairValueGaps); + + // + return result; + } + + // + bool HasBearishFairValueGaps() + { + return IsValidSize(CountBearishFairValueGaps()); + } + + // +}; + +// +// +// + +// +// Pivot Types ... +enum ENUM_XPV_PIVOTS +{ + XPV_NONE, + XPV_PEAK, + XPV_VALE, +}; + +// +// Model a Pivot structure ... +struct XPVPivot +{ + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double upper; + double lower; + + // + datetime from; + datetime to; + + // + int repetition; + + // + ENUM_XPV_PIVOTS type; + + // + // Combined all States ... + XPOIState state; + + // + XPVPivot() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + upper = 0; + lower = 0; + + // + to = NULL; + from = NULL; + symbol = NULL; + period = NULL; + + // + repetition = 0; + + // + type = XPV_NONE; + + // + state.Clean(); + + // + ZeroMemory(this); + } + + /** + * Validation ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(to) && + IsValid(from) && + IsValid(symbol) && + IsValid(period) && + repetition > 0 && + type != XPV_NONE && + (upper > 0 || lower > 0) + // + ; + + // + return result; + } + + /** + * Check Pivot is Peak ... + * + * @return ( bool ) + */ + bool IsPeak() + { + // + bool result = false; + + // + result = IsValid() && + type == XPV_PEAK; + + // + return result; + } + + /** + * Check Pivot is Vale ... + * + * @return ( bool ) + */ + bool IsVale() + { + // + bool result = false; + + // + result = IsValid() && + type == XPV_VALE; + + // + return result; + } + + /** + * Calculate Lower for Peaks ... + * + * @return ( double ) + */ + double CalculateLower() + { + // + double result = 0; + + // + if (!IsValid() || + !IsPeak()) + { + return result; + } + + // + int fromIndex = iBarShift( + symbol, + period, + from // + ); + + // + int toIndex = iBarShift( + symbol, + period, + to // + ); + + // + int count = + fromIndex - toIndex; + + // + int llIDX = iLowest( + symbol, + period, + MODE_LOW, + count, + toIndex // + ); + + // + result = + iLow( + symbol, + period, + llIDX // + ); + + // + return result; + } + + /** + * Calculate Upper for Vales ... + * + * @return ( double ) + */ + double CalculateUpper() + { + // + double result = 0; + + // + if (!IsValid() || + !IsVale()) + { + return result; + } + + // + int fromIndex = iBarShift( + symbol, + period, + from // + ); + + // + int toIndex = iBarShift( + symbol, + period, + to // + ); + + // + int count = + fromIndex - toIndex; + + // + int hhIDX = iHighest( + symbol, + period, + MODE_HIGH, + count, + toIndex // + ); + + // + result = + iHigh( + symbol, + period, + hhIDX // + ); + + // + return result; + } + + /** + * Calculate Range of Pivot ... + * + * @return ( double ) + */ + double CalculateRange() + { + // + double result = 0; + + // + if (!IsValid() || + upper <= 0 || + lower <= 0) + { + return result; + } + + // + result = upper - lower; + + // + return result; + } + + /** + * Calculate Middle of Pivot ... + * Used for + * @return ( double ) + */ + double CalculateMid() + { + // + double result = 0; + + // + double range = CalculateRange(); + if (range <= 0) + { + return result; + } + + // + result = lower + (range / 2); + + // + return result; + } + + /** + * Calculate Liquidity Percent for Specified Direction ... + * + * @param forDirection: ENUM_X_DIRECTION member, Specified Liquidity ... + * @param price: Double, Specified Price ... + * + * @return ( double ) + */ + double CalculateLiquidityPercent( + ENUM_X_DIRECTION forDirection, + double price = 0 // + ) + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = state + .CalculateLiquidityPercent( + forDirection, + price // + ); + + // + return result; + } + + /** + * Check Price in Premium or not ... + * + * @return ( bool ) + */ + bool IsPriceInPremium() + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + + // + double mid = CalculateMid(); + + // + result = + // + ask > mid && + bid > mid + // + ; + + // + return result; + } + + /** + * Check Price in Discount or not ... + * + * @return ( bool ) + */ + bool IsPriceInDiscount() + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + + // + double mid = CalculateMid(); + + // + result = + // + ask > mid && + bid > mid + // + ; + + // + return result; + } + + // + + /** + * Get Unique Identifier ... + * + * @return ( string ) + */ + string GetTag() + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + string hash = symbol + "_" + + ToString(period) + "_" + + ToString(upper) + "," + + ToString(lower) + "_" + + ToString(from) + "," + + ToString(to); + hash = ToMD5(hash); + + // + string typeStr = + type == XPV_PEAK + ? "Peak" + : "Vale"; + + // + result = + // + "XPV_" + + typeStr + "_" + + symbol + "_" + + ToString(period) + + "_" + hash + // + ; + + // + return result; + } + + // +}; + +// +// Pivots ... +struct XPVPivotPoint +{ + // + // Props ... + double value; + int repetition; + datetime time; + ENUM_XPV_PIVOTS type; + + // + // Constructor ... + XPVPivotPoint() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + value = 0; + time = NULL; + repetition = 0; + type = XPV_NONE; + + // + ZeroMemory(this); + } + + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + value > 0 && + IsValid(time) && + repetition > 0 && + type != XPV_NONE + // + ; + + // + return result; + } + + /** + * Check current Pivot Point is Peak or not ... + * + * @return ( bool ) + */ + bool IsPeak() + { + // + bool result = false; + + // + result = IsValid() && + type == XPV_PEAK; + + // + return result; + } + + /** + * Check current Pivot Point is Vale or not ... + * + * @return ( bool ) + */ + bool IsVale() + { + // + bool result = false; + + // + result = IsValid() && + type == XPV_VALE; + + // + return result; + } + + // +}; + +// +// +// + +// +// Consolidation Zone ... +struct XConsolidationZone +{ + // + // Props ... + + // + string symbol; // Symbol ... + ENUM_TIMEFRAMES period; // Period ... + + // + double upper; // Upper ... + double lower; // Lower ... + + // + datetime initTime; + int loopback; // Loopback ... + + // + ENUM_X_DIRECTION breakDirection; // Break Direction ... + XOHCL breakerBar; // Breaker Bar ... + + // + // Constructor ... + XConsolidationZone() + { + Clean(); + } + + // + // Tools ... + + /** + * Initialize Zone ... + * + * @param _symbol: String ... + * @param _period: ENUM_TIMEFRAMES member ... + * @param _upper: Double ... + * @param _lower: Double ... + * @param _loopback: Integer ... + * + * @return ( bool ) + */ + bool Init( + string _symbol, + ENUM_TIMEFRAMES _period, + double _upper, + double _lower, + int _loopback // + ) + { + // + bool result = false; + + // + _symbol = NormalizeSymbol(_symbol); + _period = NormalizePeriod(_period); + + // + result = + // + _upper > 0 && + _lower > 0 && + _loopback > 0 + // + ; + if (!result) + { + return result; + } + + // + upper = _upper; + lower = _lower; + symbol = _symbol; + period = _period; + loopback = _loopback; + + // + result = IsValid(); + if (result) + { + initTime = TimeCurrent(); + } + + // + return result; + } + + /** + * Update Breaked State ... + */ + void Update() + { + // + if (!IsValid()) + { + return; + } + + // + if (IsBreaked()) + { + return; + } + + // + XOHCL cBar; + bool isInited = cBar.Init( + symbol, + period, + 0 // + ); + if (!isInited) + { + return; + } + + // + XOHCL pBar; + isInited = cBar.GetPreviousBar(pBar); + if (!isInited) + { + return; + } + + // + // Check Consolidation Hounts ... + bool isHountTop = cBar.high > upper && + cBar.low < upper && + cBar.GetUp() < upper; + bool isHountBottom = cBar.low < lower && + cBar.high > lower && + cBar.GetDown() > lower; + bool isHounted = isHountTop || + isHountBottom; + if (isHounted) + { + // + if (isHountTop) + { + upper = cBar.high; + } + + // + if (isHountBottom) + { + lower = cBar.low; + } + + // + return; + } + + // + // Check Consolidation Breaks ... + bool isBreakTop = (cBar.GetUp() > upper && + cBar.GetDown() < upper) || + (cBar.low > upper && + cBar.high > upper); + bool isBreakBottom = (cBar.GetDown() < lower && + cBar.GetUp() > lower) || + (cBar.high < lower && + cBar.low < lower); + bool isBreaked = isBreakTop || + isBreakBottom; + if (!isBreaked) + { + return; + } + + // + // Calculate Break Direction ... + breakerBar = cBar; + breakDirection = isBreakTop + ? X_DIRECTION_BULLISH + : isBreakBottom + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + } + + /** + * Cleanup ... + */ + void Clean() + { + // + upper = 0; + lower = 0; + loopback = 0; + symbol = NULL; + period = NULL; + initTime = NULL; + breakerBar.Clean(); + breakDirection = X_DIRECTION_NONE; + + // + ZeroMemory(this); + } + + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(symbol) && + IsValid(period) && + upper > 0 && + lower > 0 && + loopback > 0 + // + ; + + // + return result; + } + + /** + * Check Zone is Breaked or not ... + * + * @return ( bool ) + */ + bool IsBreaked() + { + // + bool result = false; + + // + result = breakerBar.IsValid() && + HasDirection(breakDirection); + + // + return result; + } + + /** + * Detect Supply Zone if Exists ... + * + * @return ( bool ) + */ + bool HasSupplyZone( + XCSupplyZone *&zone // + ) + { + // + bool result = false; + + // + result = IsBreaked() && + breakDirection == X_DIRECTION_BEARISH; + if (!result) + { + return result; + } + + // + // Implment Zone Finding ... + int index = breakerBar.Index(); + int hhIDX = iHighest( + symbol, + period, + MODE_HIGH, + loopback, + index // + ); + result = IsValidIndex(hhIDX); + if (!result) + { + return result; + } + + // + XOHCL hhBar; + result = hhBar.Init( + symbol, + period, + hhIDX // + ); + if (!result) + { + return result; + } + + // + zone = new XCSupplyZone(); + result = zone.Init( + hhBar, + loopback // + ); + + // + return result; + } + + /** + * Detect Demand Zone if Exists ... + * + * @return ( bool ) + */ + bool HasDemandZone( + XCDemandZone *&zone // + ) + { + // + bool result = false; + + // + result = IsBreaked() && + breakDirection == X_DIRECTION_BULLISH; + if (!result) + { + return result; + } + + // + // Implment Zone Finding ... + int index = breakerBar.Index(); + int llIDX = iLowest( + symbol, + period, + MODE_LOW, + loopback, + index // + ); + result = IsValidIndex(llIDX); + if (!result) + { + return result; + } + + // + XOHCL llBar; + result = llBar.Init( + symbol, + period, + llIDX // + ); + if (!result) + { + return result; + } + + // + zone = new XCDemandZone(); + result = zone.Init( + llBar, + loopback // + ); + + // + return result; + } + + /** + * Retrieve Start Time ... + * + * @return ( datetime ) + */ + datetime From() + { + // + datetime result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + int startIndex = iBarShift( + symbol, + period, + initTime // + ); + + // + result = iTime( + symbol, + period, + loopback + startIndex // + ); + + // + return result; + } + + /** + * Retrieve Unique Identifier ... + * + * @return ( string ) + */ + string GetTag() + { + // + string result = + // + GetTypeName(this) + "_" + + symbol + "_" + + ToString(period) + "_" + + ToString(upper) + "_" + + ToString(lower) + // + ; + + // + return result; + } + + // +}; + +/** + * Converts a Consolidation Zone ... + * + * @param zone: XConsolidationZone instance Reference ... + * @param dest: XCZone pointer Reference ... + * + * @return ( bool ) + */ +bool ToZone( + XConsolidationZone &zone, + XCZone *&dest // +) +{ + // + bool result = false; + + // + dest = NULL; + + // + result = zone.IsValid(); + if (!result) + { + return result; + } + + // + dest = new XCZone(); + dest.Upper(zone.upper); + dest.Lower(zone.lower); + result = dest.IsValidBoundary(); + + // + return result; +} + +// +// Model Value Changed ... +struct XValueChange +{ + // + // Props ... + double before; // Before Change Value ... + double after; // After Change Value ... + datetime time; // Change Time ... + ENUM_X_DIRECTION dir; // Change Direction ... + + // + // Constructor ... + XValueChange() + { + Clean(); + } + + // + // Tools ... + + /** + * Initialize ... + * + * @param _before: Double, Value Before Change ... + * @param _after: Double, Value After Change ... + * @param _time: Datetime, Change Time ... + * @param _dir: ENUM_X_DIRECTION member, Specified Changed Direction ... + * + * @return ( bool ) + */ + bool Init( + double _before, // Before Change Value ... + double _after, // After Change Value ... + ENUM_X_DIRECTION _dir, // Change Direction ... + datetime _time = NULL // Change Time ... + ) + { + // + bool result = false; + + // + _time = NormalizeTime(_time); + + // + // Validate Inputs ... + result = + // + _after > 0 && + _before > 0 && + IsValid(_time) && + _after != _before && + HasDirection(_dir) + // + ; + if (!result) + { + return result; + } + + // + // Set Validated Values ... + dir = _dir; + time = _time; + after = _after; + before = _before; + + // + result = IsValid(); + + // + return result; + } + + /** + * Cleaning Up ... + */ + void Clean() + { + // + after = 0; + before = 0; + time = NULL; + dir = X_DIRECTION_NONE; + + // + ZeroMemory(this); + } + + /** + * Validate Model ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + after > 0 && + before > 0 && + IsValid(time) && + after != before && + HasDirection(dir) + // + ; + + // + return result; + } + + /** + * Fill Change Bar ... + * + * @param bar: XOHCL instance Reference, holds Change Bar ... + * @param _symbol: String, Specified Symbol ... + * @param _period: ENUM_TIMEFRAMES _period member, Specified Period ... + * + * @return ( bool ) + */ + bool FillBar( + XOHCL &bar, + string _symbol = NULL, + ENUM_TIMEFRAMES _period = NULL // + ) + { + // + bool result = false; + + // + bar.Clean(); + _symbol = NormalizeSymbol(_symbol); + _period = NormalizePeriod(_period); + + // + result = IsValid() && + IsValid(_symbol) && + IsValid(_period); + if (!result) + { + return result; + } + + // + result = bar.Init( + _symbol, + _period, + time // + ); + + // + return result; + } + + // +}; + +// +// Price Zones Model ... +struct XPriceZones +{ + // + XOHCL bar; // if Based On Bar it's Filled ... + double price; // if Based on Price, it's Filled ... + + // + int count; // Exists Zones Count ... + + // + XCFVG *fairValueGap; // Exists Fair Value Gap ... + XCSupplyZone *supplyZone; // Exists Supply Zone ... + XCDemandZone *demandZone; // Exists Demand Zone ... + XCOrderBlock *orderBlock; // Exists Order Block ... + XCSupportZone *supportZone; // Exists Support Zone ... + XCResistanceZone *resistanceZone; // Exists Resistance Zone ...Ù‘ + + // + // Constructor ... + XPriceZones() + { + Clean(); + } + + /** + * Cleanup ... + */ + void Clean() + { + // + bar.Clean(); + price = 0; + + // + supplyZone = NULL; + demandZone = NULL; + orderBlock = NULL; + supportZone = NULL; + fairValueGap = NULL; + resistanceZone = NULL; + + // + ZeroMemory(this); + } + + /** + * Check Zone is Valid ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + (IsBasedOnBar() || + IsBasedOnPrice()) && + IsValidSize(count) + // + ; + + // + return result; + } + + /** + * Check Zones Base on Bar ... + * + * @return ( bool ) + */ + bool IsBasedOnBar() + { + return bar.IsValid(); + } + + /** + * Check Zones Based on Price ... + * + * @return ( bool ) + */ + bool IsBasedOnPrice() + { + return price > 0; + } + + /** + * Check Has Supply Zone ... + * + * @return ( bool ) + */ + bool HasSupplyZone() + { + // + return IsValidSize(count) && + supplyZone != NULL && + supplyZone.IsValid(); + } + + /** + * Check Has Demand Zone ... + * + * @return ( bool ) + */ + bool HasDemandZone() + { + // + return IsValidSize(count) && + demandZone != NULL && + demandZone.IsValid(); + } + + /** + * Check Has OrderBlock ... + * + * @return ( bool ) + */ + bool HasOrderBlock() + { + // + return IsValidSize(count) && + orderBlock != NULL && + orderBlock.IsValid(); + } + + /** + * Check Has Support Zone ... + * + * @return ( bool ) + */ + bool HasSupportZone() + { + // + return IsValidSize(count) && + supportZone != NULL && + supportZone.IsValid(); + } + + /** + * Check Has FairValueGap ... + * + * @return ( bool ) + */ + bool HasFairValueGap() + { + // + return IsValidSize(count) && + fairValueGap != NULL && + fairValueGap.IsValid(); + } + + /** + * Check Has Resistance Zone ... + * + * @return ( bool ) + */ + bool HasResistanceZone() + { + // + return IsValidSize(count) && + resistanceZone != NULL && + resistanceZone.IsValid(); + } + + /** + * Check Zones are Overal Bullish ... + * + * @return ( bool ) + */ + bool IsBullish() + { + // + bool result = false; + + // + result = + // + HasDemandZone() + // + || + // + HasSupportZone() + // + || + // + (HasOrderBlock() && + orderBlock.IsBullish()) + // + || + // + (HasFairValueGap() && + fairValueGap.IsBullish()) + // + ; + + // + return result; + } + + /** + * Check Zones are Overal Bearish ... + * + * @return ( bool ) + */ + bool IsBearish() + { + // + bool result = false; + + // + result = + // + HasSupplyZone() + // + || + // + HasResistanceZone() + // + || + // + (HasOrderBlock() && + orderBlock.IsBearish()) + // + || + // + (HasFairValueGap() && + fairValueGap.IsBearish()) + // + ; + + // + return result; + } + + /** + * Fill Zones Based On required Direction ... + * + * @param dir: ENUM_X_DIRECTION member ... + * + * @return ( int ) + */ + int FillZones( + ENUM_X_DIRECTION dir, + XCZone *&zones[] // + ) + { + // + int result = 0; + + // + Clean(zones); + + // + bool isBullish = IsBullish(dir); + bool isBoth = dir == X_DIRECTION_ALL || + dir == X_DIRECTION_NONE; + + // + if (isBoth || isBullish) + { + // + if (HasSupportZone()) + { + // + Add( + (XCZone *)supportZone, + zones // + ); + } + + // + if (HasDemandZone()) + { + // + Add( + (XCZone *)demandZone, + zones // + ); + } + + // + if (HasOrderBlock() && + orderBlock.IsBullish()) + { + // + Add( + (XCZone *)orderBlock, + zones // + ); + } + + // + if (HasFairValueGap() && + fairValueGap.IsBullish()) + { + // + Add( + (XCZone *)fairValueGap, + zones // + ); + } + } + + // + if (isBoth || !isBullish) + { + // + if (HasResistanceZone()) + { + // + Add( + (XCZone *)resistanceZone, + zones // + ); + } + + // + if (HasSupplyZone()) + { + // + Add( + (XCZone *)supplyZone, + zones // + ); + } + + // + if (HasOrderBlock() && + orderBlock.IsBearish()) + { + // + Add( + (XCZone *)orderBlock, + zones // + ); + } + + // + if (HasFairValueGap() && + fairValueGap.IsBearish()) + { + // + Add( + (XCZone *)fairValueGap, + zones // + ); + } + } + + // s + result = ArraySize(zones); + + // + return result; + } + + /** + * Calculate Boundary of Zones ... + * + * @param dir: ENUM_X_DIRECTION Member, Specified Direction ... + * @param upper: Double ... + * @param lower: Double ... + * + * @return ( bool ) + */ + bool GetBoundary( + ENUM_X_DIRECTION dir, + double &upper, + double &lower // + ) + { + // + bool result = false; + + // + upper = 0; + lower = 0; + + // + XCZone *zones[]; + int mCount = FillZones(dir, zones); + result = IsValidSize(mCount); + if (!result) + { + return result; + } + + // + for (int i = 0; i < mCount; i++) + { + // + XCZone *iZone = zones[i]; + + // + double iUpper = iZone.Upper(); + double iLower = iZone.Lower(); + + // + upper = + upper == 0 + ? iUpper + : iUpper > upper + ? iUpper + : upper; + + // + lower = + lower == 0 + ? iLower + : iLower < lower + ? iLower + : lower; + } + + // + return result; + } + + /** + * Calculate Lifetime of Zones ... + * + * @param dir: ENUM_X_DIRECTION Member, Specified Direction ... + * @param from: DateTime ... + * @param to: DateTime ... + * + * @return ( bool ) + */ + bool GetLifetime( + ENUM_X_DIRECTION dir, + datetime &from, + datetime &to // + ) + { + // + bool result = false; + + // + to = NULL; + from = NULL; + + // + XCZone *zones[]; + int mCount = FillZones(dir, zones); + result = IsValidSize(mCount); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(dir); + bool isAll = dir == X_DIRECTION_NONE || + dir == X_DIRECTION_ALL; + + // + if (isAll || isBullish) + { + // + // Support Zone ... + bool hasSupportZone = HasSupportZone(); + if (hasSupportZone) + { + // + XCSupportZone *zone = supportZone; + + // + from = + !IsValid(from) || + from > zone.From() + ? zone.From() + : from; + + // + to = + !IsValid(to) || + to < zone.To() + ? zone.To() + : from; + } + + // + // Demand Zone ... + bool hasDemandZone = HasDemandZone(); + if (hasDemandZone) + { + // + XCDemandZone *zone = demandZone; + + // + from = + !IsValid(from) || + from > zone.From() + ? zone.From() + : from; + + // + to = + !IsValid(to) || + to < zone.To() + ? zone.To() + : from; + } + + // + // Order Block ... + bool hasOrderBlock = HasOrderBlock() && + orderBlock.IsBullish(); + if (hasOrderBlock) + { + // + XCOrderBlock *zone = orderBlock; + + // + from = + !IsValid(from) || + from > zone.From() + ? zone.From() + : from; + + // + to = + !IsValid(to) || + to < zone.To() + ? zone.To() + : from; + } + + // + // Fair Value Gap ... + bool hasFairValueGap = HasFairValueGap() && + fairValueGap.IsBullish(); + if (hasFairValueGap) + { + // + XCFVG *zone = fairValueGap; + + // + from = + !IsValid(from) || + from > zone.From() + ? zone.From() + : from; + + // + to = + !IsValid(to) || + to < zone.To() + ? zone.To() + : from; + } + } + + // + if (isAll || !isBullish) + { + // + // Resistance Zone ... + bool hasResistanceZone = HasResistanceZone(); + if (hasResistanceZone) + { + // + XCResistanceZone *zone = resistanceZone; + + // + from = + !IsValid(from) || + from > zone.From() + ? zone.From() + : from; + + // + to = + !IsValid(to) || + to < zone.To() + ? zone.To() + : from; + } + + // + // Supply Zone ... + bool hasSupplyZone = HasSupplyZone(); + if (hasSupplyZone) + { + // + XCSupplyZone *zone = supplyZone; + + // + from = + !IsValid(from) || + from > zone.From() + ? zone.From() + : from; + + // + to = + !IsValid(to) || + to < zone.To() + ? zone.To() + : from; + } + + // + // Order Block ... + bool hasOrderBlock = HasOrderBlock() && + orderBlock.IsBearish(); + if (hasOrderBlock) + { + // + XCOrderBlock *zone = orderBlock; + + // + from = + !IsValid(from) || + from > zone.From() + ? zone.From() + : from; + + // + to = + !IsValid(to) || + to < zone.To() + ? zone.To() + : from; + } + + // + // Fair Value Gap ... + bool hasFairValueGap = HasFairValueGap() && + fairValueGap.IsBearish(); + if (hasFairValueGap) + { + // + XCFVG *zone = fairValueGap; + + // + from = + !IsValid(from) || + from > zone.From() + ? zone.From() + : from; + + // + to = + !IsValid(to) || + to < zone.To() + ? zone.To() + : from; + } + } + + // + result = + to > from && + IsValid(to) && + IsValid(from); + + // + return result; + } + + /** + * Calculate Box Model Data ... + * + * @param dir: ENUM_X_DIRECTION Member, Specified Direction ... + * @param upper: Double ... + * @param lower: Double ... + * @param from: DateTime ... + * @param to: DateTime ... + * + * @return ( bool ) + */ + bool GetBoxData( + ENUM_X_DIRECTION dir, + double &upper, + double &lower, + datetime &from, + datetime &to // + ) + { + // + bool result = false; + + // + bool hasBoundary = GetBoundary( + dir, + upper, + lower // + ); + + // + bool hasLifetime = GetLifetime( + dir, + from, + to // + ); + + // + result = + hasBoundary && + hasLifetime; + + // + return result; + } + + // +}; + +// +// Market Strucutre Model ... +struct XMarketStructure +{ + // + string symbol; + ENUM_TIMEFRAMES period; + + // + ENUM_X_DIRECTION bias; + + // + XPVPivotPoint vales[]; + XPriceZones valePriceZones[]; + + // + XPVPivotPoint peaks[]; + XPriceZones peakPriceZones[]; + + // + XOHCL lowestValeBar; + XOHCL lowestValePeakBreakeUpBar; + XOHCL valeAboveLowestValePeakBar; + + // + XOHCL highestPeakBar; + XOHCL peakBelowHighestPeakValeBar; + XOHCL highestPeakValeBreakeDownBar; + + // + XMarketStructure() + { + Clean(); + } + + /** + * Cleanup ... + */ + void Clean() + { + // + symbol = NULL; + period = NULL; + bias = X_DIRECTION_NONE; + + // + Clean(vales); + Clean(peaks); + Clean(valePriceZones); + Clean(peakPriceZones); + + // + lowestValeBar.Clean(); + lowestValePeakBreakeUpBar.Clean(); + valeAboveLowestValePeakBar.Clean(); + + // + highestPeakBar.Clean(); + peakBelowHighestPeakValeBar.Clean(); + highestPeakValeBreakeDownBar.Clean(); + + // + ZeroMemory(this); + } + + /** + * Validate Model ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + IsValid(symbol) && + IsValid(period) && + bias != X_DIRECTION_NONE; + + // + return result; + } + + /** + * Check Bullish Trend ... + * + * @return ( bool ) + */ + bool IsBullish() + { + // + bool result = false; + + // + result = + // + IsValid() && + IsBullish(bias) && + HasChild(peaks) && + HasDirection(bias) && + lowestValeBar.IsValid() && + HasChild(peakPriceZones) && + lowestValePeakBreakeUpBar.IsValid() && + valeAboveLowestValePeakBar.IsValid() + // + ; + + // + return result; + } + + /** + * Check Bearish Trend ... + * + * @return ( bool ) + */ + bool IsBearish() + { + // + bool result = false; + + // + result = + // + IsValid() && + IsBearish(bias) && + HasChild(vales) && + HasDirection(bias) && + highestPeakBar.IsValid() && + HasChild(valePriceZones) && + peakBelowHighestPeakValeBar.IsValid() && + highestPeakValeBreakeDownBar.IsValid() + // + ; + + // + return result; + } + + /** + * Check Has Trend ... + * + * @return ( bool ) + */ + bool HasTrend() + { + // + bool result = false; + + // + result = IsValid() && + (IsBullish() || + IsBearish()); + + // + return result; + } + + // +}; + +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); + + // + ZeroMemory(this); + } + + /** + * 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; + + // + result = ArraySize(supportZones); + + // + return result; + } + + // + int CountResistanceZones() + { + // + int result = 0; + + // + result = ArraySize(resistanceZones); + + // + return result; + } + + // + int CountSupplyZones() + { + // + int result = 0; + + // + result = ArraySize(supplyZones); + + // + return result; + } + + // + int CountDemandZones() + { + // + int result = 0; + + // + result = ArraySize(demandZones); + + // + return result; + } + + // + int CountBullishOrderBlocks() + { + // + int result = 0; + + // + result = ArraySize(bullishOrderBlocks); + + // + return result; + } + + // + int CountBearishOrderBlocks() + { + // + int result = 0; + + // + result = ArraySize(bearishOrderBlocks); + + // + return result; + } + + // + int CountBullishFairValueGaps() + { + // + int result = 0; + + // + result = ArraySize(bullishFairValueGaps); + + // + return result; + } + + // + int CountBearishFairValueGaps() + { + // + int result = 0; + + // + result = ArraySize(bearishFairValueGaps); + + // + return result; + } +}; + +struct XFVGOrderBlock +{ + // + // Props ... + XCOrderBlock *orderBlock; + XCFVG *fairValueGap; + // XStateZones stateZones; + + // + XFVGOrderBlock() + { + Clean(); + } + + /** + * Cleanup Model ... + */ + void Clean() + { + // + orderBlock = NULL; + fairValueGap = NULL; + + // + ZeroMemory(this); + } + + /** + * Validate Model ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + orderBlock != NULL && + fairValueGap != NULL && + // stateZones.IsValid() && + ((orderBlock.IsBullish() && + fairValueGap.IsBullish()) || + ((orderBlock.IsBearish() && + fairValueGap.IsBearish()))) + // + ; + + // + return result; + } + + /** + * Get Model Direction ... + * + * @param dir: ENUM_X_DIRECTION member ... + * + * @return ( bool ) + */ + bool GetDirection( + ENUM_X_DIRECTION &dir // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + dir = orderBlock.IsBullish() + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; + } + + /** + * Retrieve Boundary of Zone ... + * + * @param upper: Upper Boundary ...Ù‘ + * @param lower: Lower Bondary ... + * @return ( bool ) + */ + bool GetBoundary( + double &upper, + double &lower // + ) + { + // + bool result = false; + + // + upper = 0; + lower = 0; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + upper = orderBlock.Upper(); + upper = MathMax(upper, fairValueGap.Upper()); + + // + lower = orderBlock.Lower(); + lower = MathMax(lower, fairValueGap.Lower()); + + // + result = lower > 0 && + upper > 0 && + upper > lower; + + // + return result; + } + + /** + * Check Model is same as another Istance ... + * + * @param value: XFVGOrderBlock instance Reference ... + * + * @return ( bool ) + */ + bool IsSameAs(XFVGOrderBlock &value) + { + // + bool result = false; + + // + result = + IsValid() && + value.IsValid(); + if (!result) + { + return result; + } + + // + ENUM_X_DIRECTION dir; + result = GetDirection(dir); + if (!result) + { + return result; + } + + // + ENUM_X_DIRECTION valueDir; + result = value.GetDirection(valueDir); + if (!result) + { + return result; + } + + // + result = + // + dir == valueDir + // + && + // + orderBlock.From() == value.orderBlock.From() && + orderBlock.Upper() == value.orderBlock.Upper() && + orderBlock.Lower() == value.orderBlock.Lower() + // + && + // + fairValueGap.From() == value.fairValueGap.From() && + fairValueGap.Upper() == value.fairValueGap.Upper() && + fairValueGap.Lower() == value.fairValueGap.Lower() + // + ; + + // + return result; + } + // +}; + +struct XBoxZone +{ + // + // Props ... + string symbol; + ENUM_TIMEFRAMES period; + + // + double upper; + double lower; + + // + datetime from; + datetime to; + + // + string type; + ENUM_X_DIRECTION dir; + + // + // Constructor ... + XBoxZone() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup Model ... + */ + void Clean() + { + // + upper = 0; + lower = 0; + to = NULL; + from = NULL; + symbol = NULL; + period = NULL; + dir = X_DIRECTION_NONE; + + // + ZeroMemory(this); + } + + /** + * Validate Model ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + upper > 0 && + lower > 0 && + from < to && + IsValid(to) && + upper > lower && + IsValid(from) && + IsValid(symbol) && + IsValid(period) + // + ; + + // + return result; + } +}; + +// +// Extensions ... + +/** + * Converts ENUM_XPOI value to String Representation ... + * + * @param value: ENUM_XPOI member ... + * + * @return ( string ) + */ +string ToString(ENUM_XPOIS value) +{ + // + string result = NULL; + + // + switch (value) + { + // + case X_POI_TRADING_DAY: + result = "XTDAY"; + break; + + // + case X_POI_MARKET_SESSION: + result = "XMSESS"; + break; + + // + case X_POI_MOMENTUM_BAR: + result = "XMNTMB"; + break; + + // + case X_POI_REJECTION_BAR: + result = "XRJCTB"; + break; + + // + case X_POI_SWING_HIGH: + result = "XSPH"; + break; + + // + case X_POI_SWING_LOW: + result = "XSPL"; + break; + + // + case X_POI_SUPPORT_ZONE: + result = "XSUP"; + break; + + // + case X_POI_RESISTANCE_ZONE: + result = "XRES"; + break; + + // + case X_POI_SUPPLY_ZONE: + result = "XSUPPLY"; + break; + + // + case X_POI_DEMAND_ZONE: + result = "XDEMAND"; + break; + + // + case X_POI_BULLISH_ORDERBLOCK: + result = "XBULLOB"; + break; + + // + case X_POI_BEARISH_ORDERBLOCK: + result = "XBEAROB"; + break; + + // + case X_POI_BULLISH_FVG: + result = "XBULLFVG"; + break; + + // + case X_POI_BEARISH_FVG: + result = "XBEARFVG"; + break; + + // + case X_POI_TICKS_ZONES: + result = "XTKSZ"; + break; + } + + // + return result; +} + +/** + * Converts ENUM_XSESSION value to String Representation ... + * + * @param value: ENUM_XSESSION member ... + * + * @return ( string ) + */ +string ToString(ENUM_XSESSION value) +{ + // + string result = NULL; + + // + switch (value) + { + // + case X_SYDNEY: + result = "Sydney"; + break; + + // + case X_TOKYO: + result = "Tokyo"; + break; + + // + case X_FRANKFORT: + result = "FrankGurt"; + break; + + // + case X_LONDON: + result = "London"; + break; + + // + case X_NEW_YORK: + result = "NewYork"; + break; + } + + // + return result; +} + +/** + * Generate General Event Messages ... + * + * @param value: ENUM_XPOI_EVENTS member ... + * + * @return ( string ) + */ +string ToString(ENUM_XPOI_EVENTS value) +{ + // + string result = NULL; + + // + switch (value) + { + // + case X_TRADE_DAY_FIRST_BAR: + result = "First Bar of Day"; + break; + + // + case X_TRADE_DAY_LAST_BAR: + result = "Last Bar of Day"; + break; + + // + case X_SESSION_FIRST_BAR: + result = "First Bar of Session"; + break; + + // + case X_SESSION_LAST_BAR: + result = "Last Bar of Session"; + break; + + // + case X_BULLISH_MOMENTUM_BAR_DETECTED: + result = "Bullish Momentum Bar Detected"; + break; + + // + case X_BEARISH_MOMENTUM_BAR_DETECTED: + result = "Bearish Momentum Bar Detected"; + break; + + // + case X_BULLISH_REJECTION_BAR_DETECTED: + result = "Bullish Rejection Bar Detected"; + break; + + // + case X_BEARISH_REJECTION_BAR_DETECTED: + result = "Bearish Rejection Bar Detected"; + break; + + // + case X_SWING_HIGH_DETECTED: + result = "Swing High Detected"; + break; + + // + case X_SWING_LOW_DETECTED: + result = "Swing Low Detected"; + break; + + // + case X_SUPPORT_ZONE_DETECTED: + result = "Support Zone Detected"; + break; + + // + case X_RESISTANCE_ZONE_DETECTED: + result = "Resistance Zone Detected"; + break; + + // + case X_SUPPLY_ZONE_DETECTED: + result = "Supply Zone Detected"; + break; + + // + case X_DEMAND_ZONE_DETECTED: + result = "Demand Zone Detected"; + break; + + // + case X_BULLISH_ORDERBLOCK_DETECTED: + result = "Bullish Order Block Detected"; + break; + + // + case X_BEARISH_ORDERBLOCK_DETECTED: + result = "Bearish Orer Block Detected"; + break; + + // + case X_BULLISH_FVG_DETECTED: + result = "Bullish FVG Detected"; + break; + + // + case X_BEARISH_FVG_DETECTED: + result = "Bearish FVg Detected"; + break; + } + + // + return result; +} + +// +// +// + +/** + * Find Oldest Pivot Index ... + * + * @param pivots: XPVPivot instance ... + * @return ( int ) + */ +int FindOldestPivotIndex( + XPVPivot &pivots[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(pivots); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = pivots[i]; + + // + bool isOldest = true; + for (int j = 0; j < count; j++) + { + // + XPVPivot jPivot = pivots[j]; + + // + isOldest = iPivot.from <= jPivot.from; + if (!isOldest) + { + break; + } + } + + // + if (isOldest) + { + // + result = i; + break; + } + } + + // + return result; +} + +/** + * Sort Pivots Based On From Date ... + * + * @param pivots: XPVPivot instance Collection reference ... + */ +void SortPivots( + XPVPivot &pivots[] // +) +{ + // + XPVPivot tmp[]; + Copy( + pivots, + tmp // + ); + + // + Clean(pivots); + + // + while (ArraySize(tmp) > 0) + { + // + if (ArraySize(tmp) == 1) + { + // + AddRef( + tmp[0], + pivots // + ); + + // + ArrayRemove( + tmp, + 0, + 1); + } + else + { + // + int idx = FindOldestPivotIndex(tmp); + if (IsValidIndex(idx)) + { + // + AddRef( + tmp[idx], + pivots // + ); + + // + ArrayRemove( + tmp, + idx, + 1 // + ); + } + } + } + + // + Clean(tmp); +} + +bool IsPivotBreaked( + XPVPivot &pivot, + XPVPivot &pivots[] // +) +{ + // + bool result = false; + + // + result = pivot.IsValid(); + if (!result) + { + return result; + } + + // + int count = ArraySize(pivots); + result = IsValidSize(pivots); + if (!result) + { + return result; + } + + // + // For Peaks Highs Must not Broked ... + // For Vales Lows Must not Broked ... + bool isPeak = pivot.IsPeak(); + + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = pivots[i]; + + // + result = isPeak + ? iPivot.upper > pivot.upper + : iPivot.lower < pivot.lower; + if (result) + { + break; + } + } + + // + return result; +} + +/** + * Filter Broken Pivots for Detect Order Flow ... + * + * @param pivots: XPVPivot instance Collection reference ... + */ +void FilterBrokenPivots( + XPVPivot &pivots[] // +) +{ + // + XPVPivot tmp[]; + Copy( + pivots, + tmp // + ); + + // + Clean(pivots); + + // + while (ArraySize(tmp) > 0) + { + // + if (ArraySize(tmp) == 1) + { + // + AddRef( + tmp[0], + pivots // + ); + + // + ArrayRemove( + tmp, + 0, + 1 // + ); + } + else + { + // + XPVPivot pivot = tmp[0]; + + // + ArrayRemove( + tmp, + 0, + 1 // + ); + + // + bool isBreaked = IsPivotBreaked( + pivot, + tmp // + ); + if (!isBreaked) + { + // + AddRef( + pivot, + pivots // + ); + } + } + } + + // + Clean(tmp); +} + +/** + * Calculate Order Flow Direction ... + * + * @param orderFlow: XPVPivot instance Collection reference ... + * @param dir: ENUM_X_DIRECTION member reference, Hold's Calculated Direction ... + * + * @return ( bool ) + */ +bool DetectPivotDirection( + XPVPivot &orderFlow[], + ENUM_X_DIRECTION &dir // +) +{ + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + + // + int count = ArraySize(orderFlow); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + // For Bullish Direction all Exists lowers must be Greater or Equal Prev ... + bool isBullish = false; + bool canLookupForBullish = true; + + // + // For Bearish Direction all Exists uppers must be Lesser or Equal Prev ... + bool isBearish = false; + bool canLookupForBearish = true; + + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = orderFlow[i]; + + // + XPVPivot tmp[]; + Copy( + orderFlow, + tmp // + ); + ArrayRemove( + tmp, + 0, + i + 1 // + ); + + // + int tmpCount = ArraySize(tmp); + if (IsValidSize(tmpCount)) + { + // + for (int j = 0; j < tmpCount; j++) + { + // + XPVPivot jPivot = tmp[j]; + + // + // Check Bullish Direction ... + isBullish = + canLookupForBullish && + jPivot.lower >= iPivot.lower; + if (!isBullish) + { + canLookupForBullish = false; + } + + // + // Check Bearish Direction ... + isBearish = + canLookupForBearish && + jPivot.upper <= iPivot.upper; + if (!isBearish) + { + canLookupForBearish = false; + } + + // + if (!canLookupForBullish && + !canLookupForBearish) + { + break; + } + } + } + Clean(tmp); + } + + // + if (isBullish && + !isBearish) + { + dir = X_DIRECTION_BULLISH; + } + else if (isBearish && + !isBullish) + { + dir = X_DIRECTION_BEARISH; + } + + // + result = dir != X_DIRECTION_NONE; + + // + return result; +} + +/** + * Detect all POIs which inside a Pivot ... + * + * @param pivot: XPVPivot instance, Specified Pivot ... + * @param source: XPOIState instance, Reference to Source State ... + * @param state: XPOIState instance, Reference to Detected Pivots ... + * @param lookupSwingHighs: Boolean ... + * @param lookupSwingLows: Boolean ... + * @param lookupSupportZones: Boolean ... + * @param lookupResistanceZones: Boolean ... + * @param lookupSupplyZones: Boolean ... + * @param lookupDemandZones: Boolean ... + * @param lookupBullishOrderBlocks: Boolean ... + * @param lookupBearishOrderBlocks: Boolean ... + * @param lookupBullishFairValueGaps: Boolean ... + * @param lookupBearishFairValueGaps: Boolean ... + * @param lookupBullishRejectionBars: Boolean ... + * @param lookupBearishRejectionBars: Boolean ... + * @param lookupBullishMomentumBars: Boolean ... + * @param lookupBearishMomentumBars: Boolean ... + */ +void DetectPivotPOIs( + XPVPivot &pivot, + XPOIState &source, + XPOIState &state, + bool lookupSwingHighs = true, + bool lookupSwingLows = true, + bool lookupSupportZones = true, + bool lookupResistanceZones = true, + bool lookupSupplyZones = true, + bool lookupDemandZones = true, + bool lookupBullishOrderBlocks = true, + bool lookupBearishOrderBlocks = true, + bool lookupBullishFairValueGaps = true, + bool lookupBearishFairValueGaps = true, + bool lookupBullishRejectionBars = true, + bool lookupBearishRejectionBars = true, + bool lookupBullishMomentumBars = true, + bool lookupBearishMomentumBars = true // +) +{ + // + state.Clean(); + + // + if (!pivot.IsValid()) + { + return; + } + + // + int count = 0; + + // + state.symbol = pivot.symbol; + state.period = pivot.period; + state.time = TimeCurrent(); + + // + // Swings ... + + // + // Swing High ... + if (lookupSwingHighs) + { + // + count = ArraySize(source.swingHighs); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = source.swingHighs[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.high <= pivot.upper; + if (isInside) + { + // + // iSwing.To(pivot.to); + + // + Add( + iSwing, + state.swingHighs // + ); + } + } + } + } + + // + // Swing Low ... + if (lookupSwingLows) + { + // + count = ArraySize(source.swingLows); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = source.swingLows[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.low >= pivot.lower; + if (isInside) + { + // + // iSwing.To(pivot.to); + + // + Add( + iSwing, + state.swingLows // + ); + } + } + } + } + + // + // Support and Resistance Zones ... + + // + // Support Zones ... + if (lookupSupportZones) + { + // + count = ArraySize(source.supportZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iZone = source.supportZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + iZone.To(pivot.to); + + // + Add( + iZone, + state.supportZones // + ); + } + } + } + } + + // + // Resistance Zones ... + if (lookupResistanceZones) + { + // + count = ArraySize(source.resistanceZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iZone = source.resistanceZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + iZone.To(pivot.to); + + // + Add( + iZone, + state.resistanceZones // + ); + } + } + } + } + + // + // Supply and Demand Zones ... + + // + // Supply Zones ... + if (lookupSupplyZones) + { + // + count = ArraySize(source.supplyZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *iZone = source.supplyZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + iZone.To(pivot.to); + + // + Add( + iZone, + state.supplyZones // + ); + } + } + } + } + + // + // Demand Zones ... + if (lookupDemandZones) + { + // + count = ArraySize(source.demandZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone *iZone = source.demandZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + iZone.To(pivot.to); + + // + Add( + iZone, + state.demandZones // + ); + } + } + } + } + + // + // Order Blocks ... + + // + // Bullish Order Blocks ... + if (lookupBullishOrderBlocks) + { + // + count = ArraySize(source.bullishOrderBlocks); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = source.bullishOrderBlocks[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + iZone.To(pivot.to); + + // + Add( + iZone, + state.bullishOrderBlocks // + ); + } + } + } + } + + // + // Bearish Order Blocks ... + if (lookupBearishOrderBlocks) + { + // + count = ArraySize(source.bearishOrderBlocks); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = source.bearishOrderBlocks[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + iZone.To(pivot.to); + + // + Add( + iZone, + state.bearishOrderBlocks // + ); + } + } + } + } + + // + // Fair Value Gaps ... + + // + // Bullish Fair Value Gaps ... + if (lookupBullishFairValueGaps) + { + // + count = ArraySize(source.bullishFairValueGaps); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = source.bullishFairValueGaps[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + iZone.To(pivot.to); + + // + Add( + iZone, + state.bullishFairValueGaps // + ); + } + } + } + } + + // + // Bearish Fair Value Gaps ... + if (lookupBearishFairValueGaps) + { + // + count = ArraySize(source.bearishFairValueGaps); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = source.bearishFairValueGaps[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + iZone.To(pivot.to); + + // + Add( + iZone, + state.bearishFairValueGaps // + ); + } + } + } + } + + // + // Rejection Bars ... + + // + // Bullish Rejection Bars ... + if (lookupBullishRejectionBars) + { + // + count = ArraySize(source.bullishRejectionBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iRejection = source.bullishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.low <= pivot.upper && + iBar.low >= pivot.lower; + if (isInside) + { + // + iRejection.To(pivot.to); + + // + Add( + iRejection, + state.bullishRejectionBars // + ); + } + } + } + } + + // + // Bearish Rejection Bars ... + if (lookupBearishRejectionBars) + { + // + count = ArraySize(source.bearishRejectionBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iRejection = source.bearishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.high <= pivot.upper && + iBar.high >= pivot.lower; + if (isInside) + { + // + iRejection.To(pivot.to); + + // + Add( + iRejection, + state.bearishRejectionBars // + ); + } + } + } + } + + // + // Momentum Bars ... + + // + // Bullish Momentum Bars ... + if (lookupBullishMomentumBars) + { + // + count = ArraySize(source.bullishMomentumBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar *iMomentum = source.bullishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.low <= pivot.upper && + iBar.low >= pivot.lower; + if (isInside) + { + // + iMomentum.To(pivot.to); + + // + Add( + iMomentum, + state.bullishMomentumBars // + ); + } + } + } + } + + // + // Bearish Momenum Bars ... + if (lookupBearishMomentumBars) + { + // + count = ArraySize(source.bearishMomentumBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar *iMomentum = source.bearishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.high <= pivot.upper && + iBar.high >= pivot.lower; + if (isInside) + { + // + iMomentum.To(pivot.to); + + // + Add( + iMomentum, + state.bearishMomentumBars // + ); + } + } + } + } +} + +/** + * Fill Pivot Tick Zone ... + * + * @param pivot: XPVPivot instance Reference ... + */ +void CalculatePivotTickZone( + XPVPivot &pivot, + int ticksLevels, + int ticksRange, + ENUM_TIMEFRAMES _period = NULL // +) +{ + // + string symbol = pivot.symbol; + ENUM_TIMEFRAMES period = IsValid(_period) + ? _period + : pivot.period; + + // + bool isInited = false; + + // + datetime from = pivot.from; + XOHCL iFromBar; + int iFromBarIndex = iBarShift( + symbol, + period, + from // + ); + isInited = iFromBar.Init( + symbol, + period, + iFromBarIndex // + ); + if (!isInited) + { + return; + } + + // + datetime to = pivot.to; + XOHCL iToBar; + int iToBarIndex = iBarShift( + symbol, + period, + to // + ); + isInited = iToBar.Init( + symbol, + period, + iToBarIndex // + ); + if (!isInited) + { + return; + } + + // + if (iFromBarIndex <= iToBarIndex) + { + return; + } + + // + XCTicksZone *iZone; + iZone = new XCTicksZone(); + + // + isInited = ticksLevels > 0 && + ticksRange > 0; + if (!isInited) + { + return; + } + + // + isInited = iZone.Init( + iFromBar, + iToBar // + ); + if (!isInited) + { + return; + } + + // + pivot.state.ticksZone = iZone; +} + +/** + * Filter State based on Pivot ... + * + * @param pivot: XPVPivot instance Reference ... + * @param state: XPOIState instance Reference ... + */ +void FilterPivotState( + XPVPivot &pivot, + XPOIState &state // +) +{ + // + bool isValid = + pivot.IsValid() && + state.IsValid() && + state.HasChild(); + if (!isValid) + { + return; + } + + // + int count = 0; + + // + double upper = pivot.upper; + double lower = pivot.lower; + + // + // + // + + // + // Resistance ... + count = state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + XCResistanceZone *tmp[]; + Copy( + state.resistanceZones, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *item = tmp[i]; + + // + bool isValid = IsPriceInsideZone( + upper, + item // + ); + if (!isValid) + { + // + ArrayRemove( + state.resistanceZones, + i, + 1 // + ); + } + } + + // + Clean(tmp); + } + + // + // Supply ... + count = state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + XCSupplyZone *tmp[]; + Copy( + state.supplyZones, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *item = tmp[i]; + + // + bool isValid = IsPriceInsideZone( + upper, + item // + ); + if (!isValid) + { + // + ArrayRemove( + state.supplyZones, + i, + 1 // + ); + } + } + + // + Clean(tmp); + } + + // + // Bearish Order Block ... + count = state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + XCOrderBlock *tmp[]; + Copy( + state.bearishOrderBlocks, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *item = tmp[i]; + + // + bool isValid = IsPriceInsideZone( + upper, + item // + ); + if (!isValid) + { + // + ArrayRemove( + state.bearishOrderBlocks, + i, + 1 // + ); + } + } + + // + Clean(tmp); + } + + // + // Bearish Fair Value Gap ... + count = state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + XCFVG *tmp[]; + Copy( + state.bearishFairValueGaps, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCFVG *item = tmp[i]; + + // + bool isValid = IsPriceInsideZone( + upper, + item // + ); + if (!isValid) + { + // + ArrayRemove( + state.bearishFairValueGaps, + i, + 1 // + ); + } + } + + // + Clean(tmp); + } + + // + // + // + + // + // Support ... + count = state.CountSupportZones(); + if (IsValidSize(count)) + { + // + XCSupportZone *tmp[]; + Copy( + state.supportZones, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone *item = tmp[i]; + + // + bool isValid = IsPriceInsideZone( + lower, + item // + ); + if (!isValid) + { + // + ArrayRemove( + state.supportZones, + i, + 1 // + ); + } + } + + // + Clean(tmp); + } + + // + // Demand ... + count = state.CountDemandZones(); + if (IsValidSize(count)) + { + // + XCDemandZone *tmp[]; + Copy( + state.demandZones, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone *item = tmp[i]; + + // + bool isValid = IsPriceInsideZone( + lower, + item // + ); + if (!isValid) + { + // + ArrayRemove( + state.demandZones, + i, + 1 // + ); + } + } + + // + Clean(tmp); + } + + // + // Bullish Order Block ... + count = state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + XCOrderBlock *tmp[]; + Copy( + state.bullishOrderBlocks, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *item = tmp[i]; + + // + bool isValid = IsPriceInsideZone( + lower, + item // + ); + if (!isValid) + { + // + ArrayRemove( + state.bullishOrderBlocks, + i, + 1 // + ); + } + } + + // + Clean(tmp); + } + + // + // Bullish Fair Value Gap ... + count = state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + XCFVG *tmp[]; + Copy( + state.bullishFairValueGaps, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCFVG *item = tmp[i]; + + // + bool isValid = IsPriceInsideZone( + lower, + item // + ); + if (!isValid) + { + // + ArrayRemove( + state.bullishFairValueGaps, + i, + 1 // + ); + } + } + + // + Clean(tmp); + } +} + +/** + * Detect Box Date of Specified Pivot ... + */ +bool DetectPivotStateBoxData( + XPVPivot &pivot, + double &peakUpper, + double &peakLower, + datetime &peakFrom, + datetime &peakTo, + double &valeUpper, + double &valeLower, + datetime &valeFrom, + datetime &valeTo // +) +{ + // + bool result = false; + + // + peakUpper = 0; + peakLower = 0; + valeUpper = 0; + valeLower = 0; + + // + peakFrom = NULL; + peakTo = NULL; + valeFrom = NULL; + valeTo = NULL; + + // + result = pivot.IsValid(); + if (!result) + { + return result; + } + + // + int count = 0; + + // + // + // + + // + // Resistance ... + count = pivot.state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + XCResistanceZone *tmp[]; + Copy( + pivot.state.resistanceZones, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *item = tmp[i]; + + // + if (peakUpper == 0 || + peakUpper < item.Upper()) + { + peakUpper = item.Upper(); + } + + // + if (peakLower == 0 || + peakLower > item.Lower()) + { + peakLower = item.Lower(); + } + + // + if (!IsValid(peakFrom) || + peakFrom > item.From()) + { + peakFrom = item.From(); + } + + // + if (!IsValid(peakTo) || + peakTo < item.To()) + { + peakTo = item.To(); + } + } + + // + Clean(tmp); + } + + // + // Supply ... + count = pivot.state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + XCSupplyZone *tmp[]; + Copy( + pivot.state.supplyZones, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *item = tmp[i]; + + // + if (peakUpper == 0 || + peakUpper < item.Upper()) + { + peakUpper = item.Upper(); + } + + // + if (peakLower == 0 || + peakLower > item.Lower()) + { + peakLower = item.Lower(); + } + + // + if (!IsValid(peakFrom) || + peakFrom > item.From()) + { + peakFrom = item.From(); + } + + // + if (!IsValid(peakTo) || + peakTo < item.To()) + { + peakTo = item.To(); + } + } + + // + Clean(tmp); + } + + // + // Bearish Order Block ... + count = pivot.state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + XCOrderBlock *tmp[]; + Copy( + pivot.state.bearishOrderBlocks, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *item = tmp[i]; + + // + if (peakUpper == 0 || + peakUpper < item.Upper()) + { + peakUpper = item.Upper(); + } + + // + if (peakLower == 0 || + peakLower > item.Lower()) + { + peakLower = item.Lower(); + } + + // + if (!IsValid(peakFrom) || + peakFrom > item.From()) + { + peakFrom = item.From(); + } + + // + if (!IsValid(peakTo) || + peakTo < item.To()) + { + peakTo = item.To(); + } + } + + // + Clean(tmp); + } + + // + // Bearish Fair Value Gap ... + count = pivot.state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + XCFVG *tmp[]; + Copy( + pivot.state.bearishFairValueGaps, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCFVG *item = tmp[i]; + + // + if (peakUpper == 0 || + peakUpper < item.Upper()) + { + peakUpper = item.Upper(); + } + + // + if (peakLower == 0 || + peakLower > item.Lower()) + { + peakLower = item.Lower(); + } + + // + if (!IsValid(peakFrom) || + peakFrom > item.From()) + { + peakFrom = item.From(); + } + + // + if (!IsValid(peakTo) || + peakTo < item.To()) + { + peakTo = item.To(); + } + } + + // + Clean(tmp); + } + + // + // + // + + // + // Support ... + count = pivot.state.CountSupportZones(); + if (IsValidSize(count)) + { + // + XCSupportZone *tmp[]; + Copy( + pivot.state.supportZones, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone *item = tmp[i]; + + // + if (valeUpper == 0 || + valeUpper < item.Upper()) + { + valeUpper = item.Upper(); + } + + // + if (valeLower == 0 || + valeLower > item.Lower()) + { + valeLower = item.Lower(); + } + + // + if (!IsValid(valeFrom) || + valeFrom > item.From()) + { + valeFrom = item.From(); + } + + // + if (!IsValid(valeTo) || + valeTo < item.To()) + { + valeTo = item.To(); + } + } + + // + Clean(tmp); + } + + // + // Demand ... + count = pivot.state.CountDemandZones(); + if (IsValidSize(count)) + { + // + XCDemandZone *tmp[]; + Copy( + pivot.state.demandZones, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone *item = tmp[i]; + + // + if (valeUpper == 0 || + valeUpper < item.Upper()) + { + valeUpper = item.Upper(); + } + + // + if (valeLower == 0 || + valeLower > item.Lower()) + { + valeLower = item.Lower(); + } + + // + if (!IsValid(valeFrom) || + valeFrom > item.From()) + { + valeFrom = item.From(); + } + + // + if (!IsValid(valeTo) || + valeTo < item.To()) + { + valeTo = item.To(); + } + } + + // + Clean(tmp); + } + + // + // Bullish Order Block ... + count = pivot.state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + XCOrderBlock *tmp[]; + Copy( + pivot.state.bullishOrderBlocks, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *item = tmp[i]; + + // + if (valeUpper == 0 || + valeUpper < item.Upper()) + { + valeUpper = item.Upper(); + } + + // + if (valeLower == 0 || + valeLower > item.Lower()) + { + valeLower = item.Lower(); + } + + // + if (!IsValid(valeFrom) || + valeFrom > item.From()) + { + valeFrom = item.From(); + } + + // + if (!IsValid(valeTo) || + valeTo < item.To()) + { + valeTo = item.To(); + } + } + + // + Clean(tmp); + } + + // + // Bullish Fair Value Gap ... + count = pivot.state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + XCFVG *tmp[]; + Copy( + pivot.state.bullishFairValueGaps, + tmp // + ); + + // + for (int i = 0; i < count; i++) + { + // + XCFVG *item = tmp[i]; + + // + if (valeUpper == 0 || + valeUpper < item.Upper()) + { + valeUpper = item.Upper(); + } + + // + if (valeLower == 0 || + valeLower > item.Lower()) + { + valeLower = item.Lower(); + } + + // + if (!IsValid(valeFrom) || + valeFrom > item.From()) + { + valeFrom = item.From(); + } + + // + if (!IsValid(valeTo) || + valeTo < item.To()) + { + valeTo = item.To(); + } + } + + // + Clean(tmp); + } + + // + result = peakUpper > 0 && + peakLower > 0 && + valeUpper > 0 && + valeLower > 0 && + IsValid(peakTo) && + IsValid(valeTo) && + IsValid(peakFrom) && + IsValid(valeFrom) && + peakTo > peakFrom && + valeTo > valeFrom && + peakUpper > peakLower && + valeUpper > valeLower; + + // + return result; +} + +/** + * Detect Price Inside Zones ... + * + * @param state: XPOIState instance Reference ... + * @param bar: XOHCL instance Reference ... + * @param hasSupport: Boolean ... + * @param hasResistanceZone: Boolean ... + * @param hasSupplyZone: Boolean ... + * @param hasDemandZone: Boolean ... + * @param hasOrderBlock: Boolean ... + * @param hasFairValueGap: Boolean ... + * @return ( bool ) + */ +bool DetectPriceInsideZones( + XPOIState &state, + XOHCL &bar, + int &zonesCount, + bool &hasSupportZone, + XCSupportZone *&supportZone, + bool &hasResistanceZone, + XCResistanceZone *&resistanceZone, + bool &hasSupplyZone, + XCSupplyZone *&supplyZone, + bool &hasDemandZone, + XCDemandZone *&demandZone, + bool &hasOrderBlock, + XCOrderBlock *&orderBlock, + bool &hasFairValueGap, + XCFVG *&fairValueGap // +) +{ + // + bool result = false; + + // + zonesCount = 0; + + // + hasSupportZone = false; + hasResistanceZone = false; + hasSupplyZone = false; + hasDemandZone = false; + hasOrderBlock = false; + hasFairValueGap = false; + + // + supportZone = NULL; + resistanceZone = NULL; + supplyZone = NULL; + demandZone = NULL; + orderBlock = NULL; + fairValueGap = NULL; + + // + datetime cTime = TimeCurrent(); + + // + result = bar.IsValid() && + state.IsValid() && + state.HasChild(); + if (!result) + { + return result; + } + + // + int count = 0; + + // + // Support Zone ... + count = state.CountSupportZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCSupportZone *iZone = state.supportZones[i]; + + // + bool isValid = IsPriceInsideZone(bar, iZone); + if (isValid) + { + // + supportZone = iZone; + } + } + + // + hasSupportZone = supportZone != NULL && + supportZone.IsValid(); + if (hasSupportZone) + { + // + zonesCount++; + supportZone.To(cTime); + } + } + + // + // Resistance Zone ... + count = state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCResistanceZone *iZone = state.resistanceZones[i]; + + // + bool isValid = IsPriceInsideZone(bar, iZone); + if (isValid) + { + // + resistanceZone = iZone; + } + } + + // + hasResistanceZone = resistanceZone != NULL && + resistanceZone.IsValid(); + if (hasResistanceZone) + { + // + zonesCount++; + resistanceZone.To(cTime); + } + } + + // + // Supply Zone ... + count = state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCSupplyZone *iZone = state.supplyZones[i]; + + // + bool isValid = IsPriceInsideZone(bar, iZone); + if (isValid) + { + // + supplyZone = iZone; + } + } + + // + hasSupplyZone = supplyZone != NULL && + supplyZone.IsValid(); + if (hasSupplyZone) + { + // + zonesCount++; + supplyZone.To(cTime); + } + } + + // + // Demand Zone ... + count = state.CountDemandZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCDemandZone *iZone = state.demandZones[i]; + + // + bool isValid = IsPriceInsideZone(bar, iZone); + if (isValid) + { + // + demandZone = iZone; + } + } + + // + hasDemandZone = demandZone != NULL && + demandZone.IsValid(); + if (hasDemandZone) + { + // + zonesCount++; + demandZone.To(cTime); + } + } + + // + // OrderBlock ... + count = state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCOrderBlock *iZone = state.bullishOrderBlocks[i]; + + // + bool isValid = IsPriceInsideZone(bar, iZone); + if (isValid) + { + // + orderBlock = iZone; + } + } + + // + hasOrderBlock = orderBlock != NULL && + orderBlock.IsValid(); + if (hasOrderBlock) + { + // + zonesCount++; + orderBlock.To(cTime); + } + } + if (!hasOrderBlock) + { + // + count = state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCOrderBlock *iZone = state.bearishOrderBlocks[i]; + + // + bool isValid = IsPriceInsideZone(bar, iZone); + if (isValid) + { + // + orderBlock = iZone; + } + } + + // + hasOrderBlock = orderBlock != NULL && + orderBlock.IsValid(); + if (hasOrderBlock) + { + // + zonesCount++; + orderBlock.To(cTime); + } + } + } + + // + // Fair Value Gap ... + count = state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCFVG *iZone = state.bullishFairValueGaps[i]; + + // + bool isValid = IsPriceInsideZone(bar, iZone); + if (isValid) + { + // + fairValueGap = iZone; + } + } + + // + hasFairValueGap = fairValueGap != NULL && + fairValueGap.IsValid(); + if (hasFairValueGap) + { + // + zonesCount++; + fairValueGap.To(cTime); + } + } + if (!hasFairValueGap) + { + // + count = state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCFVG *iZone = state.bearishFairValueGaps[i]; + + // + bool isValid = IsPriceInsideZone(bar, iZone); + if (isValid) + { + // + fairValueGap = iZone; + } + } + + // + hasFairValueGap = fairValueGap != NULL && + fairValueGap.IsValid(); + if (hasFairValueGap) + { + // + zonesCount++; + fairValueGap.To(cTime); + } + } + } + + // + result = + // + hasSupportZone || + hasResistanceZone || + hasSupplyZone || + hasDemandZone || + hasOrderBlock || + hasFairValueGap + // + ; + + // + return result; +} + +/** + * Detect Price Inside Zones ... + * + * @param state: XPOIState instance Reference ... + * @param price: Double ... + * @param hasSupport: Boolean ... + * @param hasResistanceZone: Boolean ... + * @param hasSupplyZone: Boolean ... + * @param hasDemandZone: Boolean ... + * @param hasOrderBlock: Boolean ... + * @param hasFairValueGap: Boolean ... + * @return ( bool ) + */ +bool DetectPriceInsideZones( + XPOIState &state, + double price, + int &zonesCount, + bool &hasSupportZone, + XCSupportZone *&supportZone, + bool &hasResistanceZone, + XCResistanceZone *&resistanceZone, + bool &hasSupplyZone, + XCSupplyZone *&supplyZone, + bool &hasDemandZone, + XCDemandZone *&demandZone, + bool &hasOrderBlock, + XCOrderBlock *&orderBlock, + bool &hasFairValueGap, + XCFVG *&fairValueGap // +) +{ + // + bool result = false; + + // + zonesCount = 0; + + // + hasSupportZone = false; + hasResistanceZone = false; + hasSupplyZone = false; + hasDemandZone = false; + hasOrderBlock = false; + hasFairValueGap = false; + + // + supportZone = NULL; + resistanceZone = NULL; + supplyZone = NULL; + demandZone = NULL; + orderBlock = NULL; + fairValueGap = NULL; + + // + datetime cTime = TimeCurrent(); + + // + result = price > 0 && + state.IsValid() && + state.HasChild(); + if (!result) + { + return result; + } + + // + int count = 0; + + // + // Support Zone ... + count = state.CountSupportZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCSupportZone *iZone = state.supportZones[i]; + + // + bool isValid = IsPriceInsideZone(price, iZone); + if (isValid) + { + // + supportZone = iZone; + } + } + + // + hasSupportZone = supportZone != NULL && + supportZone.IsValid(); + if (hasSupportZone) + { + // + zonesCount++; + supportZone.To(cTime); + } + } + + // + // Resistance Zone ... + count = state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCResistanceZone *iZone = state.resistanceZones[i]; + + // + bool isValid = IsPriceInsideZone(price, iZone); + if (isValid) + { + // + resistanceZone = iZone; + } + } + + // + hasResistanceZone = resistanceZone != NULL && + resistanceZone.IsValid(); + if (hasResistanceZone) + { + // + zonesCount++; + resistanceZone.To(cTime); + } + } + + // + // Supply Zone ... + count = state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCSupplyZone *iZone = state.supplyZones[i]; + + // + bool isValid = IsPriceInsideZone(price, iZone); + if (isValid) + { + // + supplyZone = iZone; + } + } + + // + hasSupplyZone = supplyZone != NULL && + supplyZone.IsValid(); + if (hasSupplyZone) + { + // + zonesCount++; + supplyZone.To(cTime); + } + } + + // + // Demand Zone ... + count = state.CountDemandZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCDemandZone *iZone = state.demandZones[i]; + + // + bool isValid = IsPriceInsideZone(price, iZone); + if (isValid) + { + // + demandZone = iZone; + } + } + + // + hasDemandZone = demandZone != NULL && + demandZone.IsValid(); + if (hasDemandZone) + { + // + zonesCount++; + demandZone.To(cTime); + } + } + + // + // OrderBlock ... + count = state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCOrderBlock *iZone = state.bullishOrderBlocks[i]; + + // + bool isValid = IsPriceInsideZone(price, iZone); + if (isValid) + { + // + orderBlock = iZone; + } + } + + // + hasOrderBlock = orderBlock != NULL && + orderBlock.IsValid(); + if (hasOrderBlock) + { + // + zonesCount++; + orderBlock.To(cTime); + } + } + if (!hasOrderBlock) + { + // + count = state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCOrderBlock *iZone = state.bearishOrderBlocks[i]; + + // + bool isValid = IsPriceInsideZone(price, iZone); + if (isValid) + { + // + orderBlock = iZone; + } + } + + // + hasOrderBlock = orderBlock != NULL && + orderBlock.IsValid(); + if (hasOrderBlock) + { + // + zonesCount++; + orderBlock.To(cTime); + } + } + } + + // + // Fair Value Gap ... + count = state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCFVG *iZone = state.bullishFairValueGaps[i]; + + // + bool isValid = IsPriceInsideZone(price, iZone); + if (isValid) + { + // + fairValueGap = iZone; + } + } + + // + hasFairValueGap = fairValueGap != NULL && + fairValueGap.IsValid(); + if (hasFairValueGap) + { + // + zonesCount++; + fairValueGap.To(cTime); + } + } + if (!hasFairValueGap) + { + // + count = state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCFVG *iZone = state.bearishFairValueGaps[i]; + + // + bool isValid = IsPriceInsideZone(price, iZone); + if (isValid) + { + // + fairValueGap = iZone; + } + } + + // + hasFairValueGap = fairValueGap != NULL && + fairValueGap.IsValid(); + if (hasFairValueGap) + { + // + zonesCount++; + fairValueGap.To(cTime); + } + } + } + + // + result = + // + hasSupportZone || + hasResistanceZone || + hasSupplyZone || + hasDemandZone || + hasOrderBlock || + hasFairValueGap + // + ; + + // + return result; +} + +bool CalculatePriceInsideZones( + XPriceZones &zone, + XPOIState &state, + double price // +) +{ + // + bool result = false; + + // + zone.Clean(); + + // + int zonesCount = 0; + bool hasSupplyZone = false; + bool hasDemandZone = false; + bool hasOrderBlock = false; + bool hasSupportZone = false; + bool hasFairValueGap = false; + bool hasResistanceZone = false; + + // + result = DetectPriceInsideZones( + state, + price, + zone.count, + hasSupportZone, + zone.supportZone, + hasResistanceZone, + zone.resistanceZone, + hasSupplyZone, + zone.supplyZone, + hasDemandZone, + zone.demandZone, + hasOrderBlock, + zone.orderBlock, + hasFairValueGap, + zone.fairValueGap // + ); + if (!result) + { + return result; + } + + // + zone.price = price; + + // + result = zone.IsValid(); + + // + return result; +} + +bool CalculatePriceInsideZones( + XPriceZones &zone, + XPOIState &state, + XOHCL &bar // +) +{ + // + bool result = false; + + // + zone.Clean(); + + // + int zonesCount = 0; + bool hasSupplyZone = false; + bool hasDemandZone = false; + bool hasOrderBlock = false; + bool hasSupportZone = false; + bool hasFairValueGap = false; + bool hasResistanceZone = false; + + // + result = DetectPriceInsideZones( + state, + bar, + zone.count, + hasSupportZone, + zone.supportZone, + hasResistanceZone, + zone.resistanceZone, + hasSupplyZone, + zone.supplyZone, + hasDemandZone, + zone.demandZone, + hasOrderBlock, + zone.orderBlock, + hasFairValueGap, + zone.fairValueGap // + ); + if (!result) + { + return result; + } + + // + zone.bar = bar; + + // + result = zone.IsValid(); + + // + return result; +} + +/** + * Calculate Zone by Providing Specified Data ... + * + * @param zones: XStateZone instance Reference ... + * @param source: XPOIState instance Reference ... + * @param upper: Double ... + * @param lower: Double ... + * @param from: DateTime ... + * + * @return ( bool ) + */ +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 ... + * + * @param item: XValueChange instance Reference ... + * @param items: XValueChange instance Array Reference ... + * + * @return ( int ) + */ +int AddIfNotExists( + XValueChange &item, + XValueChange &items[] // +) +{ + // + int result = 0; + + // + result = item.IsValid(); + if (!result) + { + return result; + } + + // + bool canAdd = false; + int count = ArraySize(items); + if (!IsValidSize(count)) + { + canAdd = true; + } + else + { + // + XValueChange last; + bool hasItem = GetLastItem( + last, + items // + ); + if (!hasItem) + { + canAdd = true; + } + else + { + // + // Compare Last Item with Current ... + canAdd = item.time > last.time; + } + } + + // + // Add Item if Allowed ... + if (canAdd) + { + // + AddRef( + item, + items // + ); + } + + // + result = ArraySize(items); + + // + return result; +} + +/** + * Combine a Collection of States into dest ... + * + * @param dest: XPOIState instance ... + * @param source: XPOIState Collection ... + */ +void CombineStates( + XPOIState &dest, + XPOIState &source[] // +) +{ + // + dest.Clean(); + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + XPOIState iState = source[i]; + + // + if (dest.ticksZone == NULL) + { + dest.ticksZone = iState.ticksZone; + } + + // + Copy( + iState.swingHighs, + dest.swingHighs, + false // + ); + + // + Copy( + iState.swingLows, + dest.swingLows, + false // + ); + + // + Copy( + iState.bullishMomentumBars, + dest.bullishMomentumBars, + false // + ); + + // + Copy( + iState.bearishMomentumBars, + dest.bearishMomentumBars, + false // + ); + + // + Copy( + iState.bullishRejectionBars, + dest.bullishRejectionBars, + false // + ); + + // + Copy( + iState.bearishRejectionBars, + dest.bearishRejectionBars, + false // + ); + + // + Copy( + iState.supportZones, + dest.supportZones, + false // + ); + + // + Copy( + iState.resistanceZones, + dest.resistanceZones, + false // + ); + + // + Copy( + iState.supplyZones, + dest.supplyZones, + false // + ); + + // + Copy( + iState.demandZones, + dest.demandZones, + false // + ); + + // + Copy( + iState.bullishOrderBlocks, + dest.bullishOrderBlocks, + false // + ); + + // + Copy( + iState.bearishOrderBlocks, + dest.bearishOrderBlocks, + false // + ); + + // + Copy( + iState.bullishFairValueGaps, + dest.bullishFairValueGaps, + false // + ); + + // + Copy( + iState.bearishFairValueGaps, + dest.bearishFairValueGaps, + false // + ); + + // + } +} + +/** + * Check Price Above Specified Zone ... + * + * @param bar: XOHCL instance Reference ... + * + * @return ( bool ) + */ +bool IsPriceAboveZone( + XOHCL &bar, + XCZone *zone // +) +{ + // + bool result = false; + + // + result = + zone != NULL && + bar.IsValid() && + zone.IsValidBoundary(); + if (!result) + { + return result; + } + + // + result = + // + bar.low > zone.Upper() + // + ; + + // + return result; +} + +/** + * Check Price Above Specified Zone ... + * + * @return ( bool ) + */ +bool IsPriceAboveZone( + double price, + XCZone *zone // +) +{ + // + bool result = false; + + // + result = + price > 0 && + zone != NULL && + zone.IsValidBoundary(); + if (!result) + { + return result; + } + + // + result = + // + price > zone.Upper() + // + ; + + // + return result; +} + +/** + * Check Price Below Specified Zone ... + * + * @param bar: XOHCL instance Reference ... + * + * @return ( bool ) + */ +bool IsPriceBelowZone( + XOHCL &bar, + XCZone *zone // +) +{ + // + bool result = false; + + // + result = + zone != NULL && + bar.IsValid() && + zone.IsValidBoundary(); + if (!result) + { + return result; + } + + // + result = + // + bar.high < zone.Lower() + // + ; + + // + return result; +} + +/** + * Check Price Below Specified Zone ... + * + * @return ( bool ) + */ +bool IsPriceBelowZone( + double price, + XCZone *zone // +) +{ + // + bool result = false; + + // + result = + price > 0 && + zone != NULL && + zone.IsValidBoundary(); + if (!result) + { + return result; + } + + // + result = + // + price < zone.Lower() + // + ; + + // + return result; +} + +/** + * Check Price Inside Specified Zone ... + * + * @param bar: XOHCL instance Reference ... + * + * @return ( bool ) + */ +bool IsPriceInsideZone( + XOHCL &bar, + XCZone *zone // +) +{ + // + bool result = false; + + // + result = + zone != NULL && + bar.IsValid() && + zone.IsValidBoundary(); + if (!result) + { + return result; + } + + // + result = + // + bar.low <= zone.Upper() + // + && + // + bar.low >= zone.Lower() + // + ; + + // + return result; +} +bool IsPriceInsideZone( + XOHCL &bar, + double upper, + double lower // +) +{ + // + bool result = false; + + // + result = + upper > 0 && + lower > 0 && + upper > lower && + bar.IsValid(); + if (!result) + { + return result; + } + + // + result = + // + bar.low <= upper + // + && + // + bar.low >= lower + // + ; + + // + return result; +} + +/** + * Check Price Inside Specified Zone ... + * + * @return ( bool ) + */ +bool IsPriceInsideZone( + double price, + XCZone *zone // +) +{ + // + bool result = false; + + // + result = + price > 0 && + zone != NULL && + zone.IsValidBoundary(); + if (!result) + { + return result; + } + + // + result = + // + price <= zone.Upper() + // + && + // + price >= zone.Lower() + // + ; + + // + return result; +} +bool IsPriceInsideZone( + double price, + double upper, + double lower // +) +{ + // + bool result = false; + + // + result = + price > 0 && + upper > 0 && + lower > 0 && + upper > lower; + if (!result) + { + return result; + } + + // + result = + // + price <= upper + // + && + // + price >= lower + // + ; + + // + return result; +} + +/** + * Calculate Target for Specified Direction ... + * + * @param bar: XOHCL instance Reference ... + * @param state: XPOIState instance Reference ... + * @param forDir: ENUM_S_DIRECTION member ... + * + * @return ( double ) + */ +double CalculateTarget( + XOHCL &bar, + XPOIState &state, + ENUM_X_DIRECTION forDir // +) +{ + // + double result = 0; + + // + if (!state.IsValid() || + !state.HasChild() || + !HasDirection(forDir)) + { + return result; + } + + // + XCFVG *iFVG = NULL; + XCOrderBlock *iOB = NULL; + XCSupplyZone *iSupply = NULL; + XCDemandZone *iDemand = NULL; + XCSupportZone *iSupport = NULL; + XCResistanceZone *iResistance = NULL; + + // + bool hasOB = false; + bool hasFVG = false; + bool hasSupply = false; + bool hasDemand = false; + bool hasSupport = false; + bool hasResistance = false; + + // + int count = 0; + + // + if (IsBearish(forDir)) + { + // + // FVG ... + count = state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCFVG *iZone = state.bullishFairValueGaps[i]; + + // + bool isValid = IsPriceAboveZone( + bar, + iZone // + ); + if (isValid) + { + // + iFVG = iZone; + hasFVG = true; + break; + } + } + } + + // + // OB ... + count = state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCOrderBlock *iZone = state.bullishOrderBlocks[i]; + + // + bool isValid = IsPriceAboveZone( + bar, + iZone // + ); + if (isValid) + { + // + iOB = iZone; + hasOB = true; + break; + } + } + } + + // + // SUPPORT ... + count = state.CountSupportZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCSupportZone *iZone = state.supportZones[i]; + + // + bool isValid = IsPriceAboveZone( + bar, + iZone // + ); + if (isValid) + { + // + iSupport = iZone; + hasSupport = true; + break; + } + } + } + + // + // DEMAND ... + count = state.CountDemandZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCDemandZone *iZone = state.demandZones[i]; + + // + bool isValid = IsPriceAboveZone( + bar, + iZone // + ); + if (isValid) + { + // + iDemand = iZone; + hasDemand = true; + break; + } + } + } + + // + // Summary ... + result = + hasFVG + ? iFVG.Upper() + : hasOB + ? iOB.Upper() + : hasSupport + ? iSupport.Upper() + : hasDemand + ? iDemand.Upper() + : 0; + if (hasFVG) + { + result = MathMax(result, iFVG.Upper()); + } + if (hasOB) + { + result = MathMax(result, iOB.Upper()); + } + if (hasSupport) + { + result = MathMax(result, iSupport.Upper()); + } + if (hasDemand) + { + result = MathMax(result, iDemand.Upper()); + } + } + + // + if (IsBullish(forDir)) + { + // + // FVG ... + count = state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCFVG *iZone = state.bearishFairValueGaps[i]; + + // + bool isValid = IsPriceBelowZone( + bar, + iZone // + ); + if (isValid) + { + // + iFVG = iZone; + hasFVG = true; + break; + } + } + } + + // + // OB ... + count = state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCOrderBlock *iZone = state.bearishOrderBlocks[i]; + + // + bool isValid = IsPriceBelowZone( + bar, + iZone // + ); + if (isValid) + { + // + iOB = iZone; + hasOB = true; + break; + } + } + } + + // + // RESISTANCE ... + count = state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCResistanceZone *iZone = state.resistanceZones[i]; + + // + bool isValid = IsPriceBelowZone( + bar, + iZone // + ); + if (isValid) + { + // + iResistance = iZone; + hasResistance = true; + break; + } + } + } + + // + // SUPPLY ... + count = state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCSupplyZone *iZone = state.supplyZones[i]; + + // + bool isValid = IsPriceBelowZone( + bar, + iZone // + ); + if (isValid) + { + // + iSupply = iZone; + hasSupply = true; + break; + } + } + } + + // + // Summary ... + result = + hasFVG + ? iFVG.Lower() + : hasOB + ? iOB.Lower() + : hasSupport + ? iSupport.Lower() + : hasDemand + ? iDemand.Lower() + : 0; + if (hasFVG) + { + result = MathMin(result, iFVG.Lower()); + } + if (hasOB) + { + result = MathMin(result, iOB.Lower()); + } + if (hasSupport) + { + result = MathMin(result, iSupport.Lower()); + } + if (hasDemand) + { + result = MathMin(result, iDemand.Lower()); + } + } + + // + return result; +} + +/** + * Detect Valid Order Blocks ... + * + * @param forDir: ENUM_X_DIRECTION member ... + * @param source: XPOIState instance Reference ... + * + * @return ( int ) + */ +int DetectValidOrderBlocks( + ENUM_X_DIRECTION forDir, + XPOIState &source, + XCOrderBlock *&orderBlocks[] // +) +{ + // + int result = 0; + + // + Clean(orderBlocks); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + HasDirection(forDir) + // + ; + if (!isValid) + { + return result; + } + + // + datetime cTime = TimeCurrent(); + + // + XOHCL cBar; + bool isInited = cBar.Init( + source.symbol, + source.period, + 1 // + ); + if (!isInited) + { + return result; + } + + // + int count = 0; + + // + // Bullish ... + count = source.CountBullishOrderBlocks(); + isValid = IsValidSize(count) && + IsBullish(forDir); + if (isValid) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = source.bullishOrderBlocks[i]; + + // + // Update Order Block Time ... + iOB.To(cTime); + + // + // Check Order Block Validation ... + isValid = IsValid( + forDir, + cBar.symbol, + cBar.period, + iOB.Upper(), + iOB.Lower(), + iOB.From(), + iOB.To() // + ); + if (isValid) + { + // + Add( + iOB, + orderBlocks // + ); + } + } + } + + // + // Bearish ... + count = source.CountBearishOrderBlocks(); + isValid = IsValidSize(count) && + IsBearish(forDir); + if (isValid) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = source.bearishOrderBlocks[i]; + + // + // Update Order Block Time ... + iOB.To(cTime); + + // + // Check Order Block Validation ... + isValid = IsValid( + forDir, + cBar.symbol, + cBar.period, + iOB.Upper(), + iOB.Lower(), + iOB.From(), + iOB.To() // + ); + if (isValid) + { + // + Add( + iOB, + orderBlocks // + ); + } + } + } + + // + result = ArraySize(orderBlocks); + + // + return result; +} + +/** + * Detect Valid Fair Value Gaps ... + * + * @param forDir: ENUM_X_DIRECTION member ... + * @param source: XPOIState instance Reference ... + * + * @return ( int ) + */ +int DetectValidFairValueGaps( + ENUM_X_DIRECTION forDir, + XPOIState &source, + XCFVG *&fairValueGaps[] // +) +{ + // + int result = 0; + + // + Clean(fairValueGaps); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + HasDirection(forDir) + // + ; + if (!isValid) + { + return result; + } + + // + datetime cTime = TimeCurrent(); + + // + XOHCL cBar; + bool isInited = cBar.Init( + source.symbol, + source.period, + 1 // + ); + if (!isInited) + { + return result; + } + + // + int count = 0; + + // + // Bullish ... + count = source.CountBullishFairValueGaps(); + isValid = IsValidSize(count) && + IsBullish(forDir); + if (isValid) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = source.bullishFairValueGaps[i]; + + // + // Update FVG Time ... + iFVG.To(cTime); + + // + // Check FVG Validation ... + isValid = IsValid( + forDir, + cBar.symbol, + cBar.period, + iFVG.Upper(), + iFVG.Lower(), + iFVG.From(), + iFVG.To() // + ); + if (isValid) + { + // + Add( + iFVG, + fairValueGaps // + ); + } + } + } + + // + // Bearish ... + count = source.CountBearishFairValueGaps(); + isValid = IsValidSize(count) && + IsBearish(forDir); + if (isValid) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = source.bearishFairValueGaps[i]; + + // + // Update Order Block Time ... + iFVG.To(cTime); + + // + // Check Order Block Validation ... + isValid = IsValid( + forDir, + cBar.symbol, + cBar.period, + iFVG.Upper(), + iFVG.Lower(), + iFVG.From(), + iFVG.To() // + ); + if (isValid) + { + // + Add( + iFVG, + fairValueGaps // + ); + } + } + } + + // + result = ArraySize(fairValueGaps); + + // + return result; +} + +/** + * Detect Valid Support Zones ... + * + * @param source: XPOIState instance ... + * + * @return ( int ) + */ +int DetectValidSupportZones( + XPOIState &source, + XCOrderBlock *&bullishOrderBlocks[], + XCFVG *&bullishFairValueGaps[], + XCSupportZone *&supportZones[] // +) +{ + // + int result = 0; + + // + Clean(supportZones); + + // + int obsCount = ArraySize(bullishOrderBlocks); + int fvgsCount = ArraySize(bullishFairValueGaps); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + IsValidSize(obsCount + fvgsCount) + // + ; + if (!isValid) + { + return result; + } + + // + int count = source.CountSupportZones(); + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iZone = source.supportZones[i]; + + // + bool isAdded = false; + + // + for (int j = 0; j < obsCount; j++) + { + // + XCOrderBlock *iOB = bullishOrderBlocks[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iOB.Upper(), + iOB.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iOB.Upper(), + iOB.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + supportZones // + ); + + // + isAdded = true; + break; + } + } + + // + if (isAdded) + { + continue; + } + + // + for (int j = 0; j < fvgsCount; j++) + { + // + XCFVG *iFVG = bullishFairValueGaps[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + supportZones // + ); + + // + isAdded = true; + break; + } + } + } + + // + result = ArraySize(supportZones); + + // + return result; +} + +/** + * Detect Valid Resistance Zones ... + * + * @param source: XPOIState instance ... + * + * @return ( int ) + */ +int DetectValidResistanceZones( + XPOIState &source, + XCOrderBlock *&bearishOrderBlocks[], + XCFVG *&bearishFairValueGaps[], + XCResistanceZone *&resistanceZones[] // +) +{ + // + int result = 0; + + // + Clean(resistanceZones); + + // + int obsCount = ArraySize(bearishOrderBlocks); + int fvgsCount = ArraySize(bearishFairValueGaps); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + IsValidSize(obsCount + fvgsCount) + // + ; + if (!isValid) + { + return result; + } + + // + int count = source.CountResistanceZones(); + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iZone = source.resistanceZones[i]; + + // + bool isAdded = false; + + // + for (int j = 0; j < obsCount; j++) + { + // + XCOrderBlock *iOB = bearishOrderBlocks[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iOB.Upper(), + iOB.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iOB.Upper(), + iOB.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + resistanceZones // + ); + + // + isAdded = true; + break; + } + } + + // + if (isAdded) + { + continue; + } + + // + for (int j = 0; j < fvgsCount; j++) + { + // + XCFVG *iFVG = bearishFairValueGaps[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + resistanceZones // + ); + + // + isAdded = true; + break; + } + } + } + + // + result = ArraySize(resistanceZones); + + // + return result; +} + +/** + * Detect Valid Support Zones ... + * + * @param source: XPOIState instance ... + * + * @return ( int ) + */ +int DetectValidDemandZones( + XPOIState &source, + XCOrderBlock *&bullishOrderBlocks[], + XCFVG *&bullishFairValueGaps[], + XCDemandZone *&demandZones[] // +) +{ + // + int result = 0; + + // + Clean(demandZones); + + // + int obsCount = ArraySize(bullishOrderBlocks); + int fvgsCount = ArraySize(bullishFairValueGaps); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + IsValidSize(obsCount + fvgsCount) + // + ; + if (!isValid) + { + return result; + } + + // + int count = source.CountDemandZones(); + for (int i = 0; i < count; i++) + { + // + XCDemandZone *iZone = source.demandZones[i]; + + // + bool isAdded = false; + + // + for (int j = 0; j < obsCount; j++) + { + // + XCOrderBlock *iOB = bullishOrderBlocks[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iOB.Upper(), + iOB.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iOB.Upper(), + iOB.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + demandZones // + ); + + // + isAdded = true; + break; + } + } + + // + if (isAdded) + { + continue; + } + + // + for (int j = 0; j < fvgsCount; j++) + { + // + XCFVG *iFVG = bullishFairValueGaps[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + demandZones // + ); + + // + isAdded = true; + break; + } + } + } + + // + result = ArraySize(demandZones); + + // + return result; +} + +/** + * Detect Valid Resistance Zones ... + * + * @param source: XPOIState instance ... + * + * @return ( int ) + */ +int DetectValidSupplyZones( + XPOIState &source, + XCOrderBlock *&bearishOrderBlocks[], + XCFVG *&bearishFairValueGaps[], + XCSupplyZone *&supplyZones[] // +) +{ + // + int result = 0; + + // + Clean(supplyZones); + + // + int obsCount = ArraySize(bearishOrderBlocks); + int fvgsCount = ArraySize(bearishFairValueGaps); + + // + bool isValid = + // + source.IsValid() && + source.HasChild() && + IsValidSize(obsCount + fvgsCount) + // + ; + if (!isValid) + { + return result; + } + + // + int count = source.CountSupplyZones(); + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *iZone = source.supplyZones[i]; + + // + bool isAdded = false; + + // + for (int j = 0; j < obsCount; j++) + { + // + XCOrderBlock *iOB = bearishOrderBlocks[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iOB.Upper(), + iOB.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iOB.Upper(), + iOB.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + supplyZones // + ); + + // + isAdded = true; + break; + } + } + + // + if (isAdded) + { + continue; + } + + // + for (int j = 0; j < fvgsCount; j++) + { + // + XCFVG *iFVG = bearishFairValueGaps[j]; + + // + bool isValid = + // + IsPriceInsideZone( + iZone.Upper(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + || + // + IsPriceInsideZone( + iZone.Lower(), + iFVG.Upper(), + iFVG.Lower() // + ) + // + ; + if (isValid) + { + // + Add( + iZone, + supplyZones // + ); + + // + isAdded = true; + break; + } + } + } + + // + result = ArraySize(supplyZones); + + // + return result; +} + +/** + * Detect a Zone Breaker Bar ... + * + * @param toBar: XOHCL instance Reference ... + * @param fromBar: XOHCL instance Reference ... + * @param breakerBar: XOHCL instance Reference ... + * @param forDir: ENUM_X_DIRECTION member ... + * @param symbol: String ... + * @param period: ENUM_TIMEFRAMES member ... + * + * @return ( bool ) + */ +bool HasBreakerBar( + XOHCL &toBar, + XOHCL &fromBar, + XOHCL &breakerBar, + ENUM_X_DIRECTION forDir, + string symbol, + ENUM_TIMEFRAMES period, + double upper, + double lower, + datetime from, + datetime to // +) +{ + // + bool result = false; + + // + toBar.Clean(); + fromBar.Clean(); + breakerBar.Clean(); + + // + result = + // + upper > 0 && + lower > 0 && + IsValid(to) && + upper > lower && + IsValid(from) && + IsValid(symbol) && + IsValid(period) && + HasDirection(forDir) + // + ; + if (!result) + { + return result; + } + + // + result = fromBar.Init( + symbol, + period, + from // + ); + if (!result) + { + return result; + } + + // + result = toBar.Init( + symbol, + period, + to // + ); + if (!result) + { + return result; + } + + // + int toIndex = toBar.Index(); + int fromIndex = fromBar.Index(); + + // + // Detect Zone BreakerBar ... + for (int i = fromIndex; i >= toIndex; i--) + { + // + XOHCL iBar; + result = iBar.Init( + symbol, + period, + i // + ); + + // + if (!result) + { + continue; + } + + // + result = + // + IsBullish(forDir) + ? + // + iBar.low < upper && + iBar.high > upper && + iBar.GetUp() > upper + // + : + // + iBar.high > lower && + iBar.low < lower && + iBar.GetDown() < lower + // + ; + if (result) + { + // + breakerBar = iBar; + break; + } + } + + // + result = breakerBar.IsValid(); + + // + return result; +} + +/** + * Validate Specified Order Block ... + * + * @param forDir: ENUM_X_DIRECTION member ... + * @param symbol: String ... + * @param period: ENUM_TIMEFRAMES member ... + * + * @return ( bool ) + */ +bool IsValid( + ENUM_X_DIRECTION forDir, + string symbol, + ENUM_TIMEFRAMES period, + double upper, + double lower, + datetime from, + datetime to, + bool ignoreBreakerBar = false // +) +{ + // + bool result = false; + + // + result = + upper > 0 && + lower > 0 && + IsValid(to) && + upper > lower && + IsValid(from) && + IsValid(symbol) && + IsValid(period) && + HasDirection(forDir) + // + ; + if (!result) + { + return result; + } + + // + XOHCL toBar; + XOHCL fromBar; + XOHCL breakerBar; + + // + if (!ignoreBreakerBar) + { + // + result = HasBreakerBar( + toBar, + fromBar, + breakerBar, + forDir, + symbol, + period, + upper, + lower, + from, + to // + ); + if (!result) + { + return result; + } + } + else + { + // + result = toBar.Init( + symbol, + period, + to // + ); + if (!result) + { + return result; + } + + // + result = fromBar.Init( + symbol, + period, + from // + ); + if (!result) + { + return result; + } + + // + breakerBar = fromBar; + } + + // + int toIndex = toBar.Index(); + int fromIndex = fromBar.Index(); + int breakerIndex = breakerBar.Index(); + + // + bool isBreaked = false; + for (int i = breakerIndex - 1; i >= toIndex; i--) + { + // + XOHCL iBar; + result = iBar.Init( + fromBar.symbol, + fromBar.period, + i // + ); + + // + if (!result) + { + continue; + } + + // + isBreaked = + // + IsBullish(forDir) + // + ? + // + iBar.low < upper + // + : + // + iBar.high > lower + // + ; + if (isBreaked) + { + break; + } + } + + // + result = !isBreaked; + + // + return result; +} + +/** + * Get Oldest Zone ... + * + * @return ( int ) + */ +int GetOldest( + XCZone *&source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XCZone *oldest = NULL; + for (int i = 0; i < count; i++) + { + // + XCZone *iZone = source[i]; + + // + bool canSet = + oldest == NULL || + (oldest != NULL && + oldest.From() > iZone.From()); + if (canSet) + { + // + result = i; + oldest = iZone; + } + } + + // + return result; +} + +/** + * Get Youngest Zone ... + * + * @return ( int ) + */ +int GetYoungest( + XCZone *&source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XCZone *youngest = NULL; + for (int i = 0; i < count; i++) + { + // + XCZone *iZone = source[i]; + + // + bool canSet = + youngest == NULL || + (youngest != NULL && + youngest.From() < iZone.From()); + if (canSet) + { + // + result = i; + youngest = iZone; + } + } + + // + return result; +} + +template +bool ToZone( + T *&source[], + XCZone *&dest[] // +) +{ + // + bool result = false; + + // + Clean(dest); + + // + int count = ArraySize(source); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + T *item = source[i]; + + // + if (item != NULL) + { + // + Add( + (XCZone *)item, + dest // + ); + } + } + + // + int destCount = ArraySize(dest); + result = IsValidSize(destCount); + + // + return result; +} + +// +typedef void (*TOnPOIEvent)(ENUM_XPOI_EVENTS event, + XCBasePOI *param // +); + +// \ No newline at end of file diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 13ecb198..be9d6b51 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -852,6 +852,7 @@ class XCBarZone : public XCZone * @return ( bool ) */ bool IsActivated( + ENUM_X_DIRECTION forDir, XOHCL &activatedBar, ENUM_X_DIRECTION &activatedDir // ) @@ -871,23 +872,29 @@ class XCBarZone : public XCZone } // - // Detect From Bar Index ... - int fromIndex = iBarShift( - GetSymbol(), - GetPeriod(), - From() // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = IsStarted( + forDir, + startedBar, + startedDir // ); - fromIndex--; + result = isStarted; + if (!result) + { + return result; + } // - for (int i = fromIndex; i >= 0; i--) - { - // - if (i == fromIndex) - { - continue; - } + bool isBullish = IsBullish(forDir); + bool isBearish = IsBearish(forDir); + // + int startIndex = startedBar.Index() - 1; + + // + for (int i = startIndex; i >= 0; i--) + { // XOHCL iBar; bool isInited = iBar.Init( @@ -903,8 +910,7 @@ class XCBarZone : public XCZone // XOHCL iPBar; - isInited = iBar - .GetPreviousBar(iPBar); + isInited = iBar.GetPreviousBar(iPBar); result = isInited; if (!result) { @@ -914,16 +920,28 @@ class XCBarZone : public XCZone // bool isActivedFromUpper = // - (iPBar.low > Upper() && - iBar.low <= Upper()) + isBullish && + // + ( + // + (iPBar.low > Upper() && + iBar.low <= Upper()) + // + ) // ; // bool isActivedFromLower = // - (iPBar.high < Lower() && - iBar.high >= Lower()) + isBearish && + // + ( + // + (iPBar.high < Lower() && + iBar.high >= Lower()) + // + ) // ; @@ -944,6 +962,10 @@ class XCBarZone : public XCZone } } + // + result = activatedBar.IsValid() && + HasDirection(activatedDir); + // return result; } @@ -957,6 +979,7 @@ class XCBarZone : public XCZone * @return ( bool ) */ bool IsBreaked( + ENUM_X_DIRECTION forDir, XOHCL &breakerBar, ENUM_X_DIRECTION &breakerDir // ) @@ -969,7 +992,8 @@ class XCBarZone : public XCZone breakerDir = X_DIRECTION_NONE; // - result = IsValid(); + result = IsValid() && + HasDirection(forDir); if (!result) { return result; @@ -979,6 +1003,7 @@ class XCBarZone : public XCZone XOHCL activatedBar; ENUM_X_DIRECTION activatedDir; bool isActivated = IsActivated( + forDir, activatedBar, activatedDir // ); @@ -1051,6 +1076,122 @@ class XCBarZone : public XCZone } } + // + result = breakerBar.IsValid() && + HasDirection(breakerDir); + + // + return result; + } + + /** + * Retrieve Order Zone First Breaker Bar ... + * + * @param breakerBar: XOHCL instance Reference ... + * @param breakerDir: ENUM_X_DIRECTION member ... + * + * @return ( bool ) + */ + bool IsStarted( + ENUM_X_DIRECTION forDir, + XOHCL &startedBar, + ENUM_X_DIRECTION &startedDir // + ) + { + // + bool result = false; + + // + startedBar.Clean(); + startedDir = X_DIRECTION_NONE; + + // + result = IsValid() && + HasDirection(forDir); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(forDir); + bool isBearish = IsBearish(forDir); + + // + // Detect From Bar Index ... + int fromIndex = iBarShift( + GetSymbol(), + GetPeriod(), + From() // + ); + + // + for (int i = fromIndex; i >= 0; i--) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + GetSymbol(), + GetPeriod(), + i // + ); + result = isInited; + if (!result) + { + continue; + } + + // + bool isBreakedFromUpper = + // + isBullish && + // + ( + // + iBar.low > Upper() || + (iBar.low <= Upper() && + iBar.high > Upper()) + // + ) + // + ; + + // + bool isBreakedFromLower = + // + isBearish && + // + ( + // + iBar.low < Lower() || + (iBar.high >= Lower() && + iBar.low < Lower()) + // + ) + // + ; + + // + bool isBreaked = + isBreakedFromUpper || + isBreakedFromLower; + if (isBreaked) + { + // + result = isBreaked; + startedBar = iBar; + startedDir = + isBreakedFromUpper + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + break; + } + } + + // + result = startedBar.IsValid() && + HasDirection(startedDir); + // return result; } @@ -4040,6 +4181,12 @@ struct XPOIState return result; } + // + bool HasSwingHighs() + { + return IsValidSize(CountSwingHighs()); + } + // int CountSwingLows() { @@ -4059,6 +4206,12 @@ struct XPOIState return result; } + // + bool HasSwingLows() + { + return IsValidSize(CountSwingLows()); + } + // int CountBullishMomentumBars() { @@ -4078,6 +4231,12 @@ struct XPOIState return result; } + // + bool HasBullishMomentumBars() + { + return IsValidSize(CountBullishMomentumBars()); + } + // int CountBearishMomentumBars() { @@ -4097,6 +4256,12 @@ struct XPOIState return result; } + // + bool HasBearishMomentumBars() + { + return IsValidSize(CountBearishMomentumBars()); + } + // int CountBullishRejectionBars() { @@ -4116,6 +4281,12 @@ struct XPOIState return result; } + // + bool HasBullishRejectionBars() + { + return IsValidSize(CountBullishRejectionBars()); + } + // int CountBearishRejectionBars() { @@ -4135,6 +4306,12 @@ struct XPOIState return result; } + // + bool HasBearishRejectionBars() + { + return IsValidSize(CountBearishRejectionBars()); + } + // int CountSupportZones() { @@ -4154,6 +4331,12 @@ struct XPOIState return result; } + // + bool HasSupportZones() + { + return IsValidSize(CountSupportZones()); + } + // int CountResistanceZones() { @@ -4173,6 +4356,12 @@ struct XPOIState return result; } + // + bool HasResistanceZones() + { + return IsValidSize(CountResistanceZones()); + } + // int CountSupplyZones() { @@ -4192,6 +4381,12 @@ struct XPOIState return result; } + // + bool HasSupplyZones() + { + return IsValidSize(CountSupplyZones()); + } + // int CountDemandZones() { @@ -4211,6 +4406,12 @@ struct XPOIState return result; } + // + bool HasDemandZones() + { + return IsValidSize(CountDemandZones()); + } + // int CountBullishOrderBlocks() { @@ -4230,6 +4431,12 @@ struct XPOIState return result; } + // + bool HasBullishOrderBlocks() + { + return IsValidSize(CountBullishOrderBlocks()); + } + // int CountBearishOrderBlocks() { @@ -4249,6 +4456,12 @@ struct XPOIState return result; } + // + bool HasBearishOrderBlocks() + { + return IsValidSize(CountBearishOrderBlocks()); + } + // int CountBullishFairValueGaps() { @@ -4268,6 +4481,12 @@ struct XPOIState return result; } + // + bool HasBullishFairValueGaps() + { + return IsValidSize(CountBullishFairValueGaps()); + } + // int CountBearishFairValueGaps() { @@ -4288,567 +4507,14 @@ struct XPOIState } // -}; - -// -// -// - -// -// Pivot Types ... -enum ENUM_XPV_PIVOTS -{ - XPV_NONE, - XPV_PEAK, - XPV_VALE, -}; - -// -// Model a Pivot structure ... -struct XPVPivot -{ - // - string symbol; - ENUM_TIMEFRAMES period; - - // - double upper; - double lower; - - // - datetime from; - datetime to; - - // - int repetition; - - // - ENUM_XPV_PIVOTS type; - - // - // Combined all States ... - XPOIState state; - - // - XPVPivot() + bool HasBearishFairValueGaps() { - Clean(); - } - - // - // Tools ... - - /** - * Cleanup ... - */ - void Clean() - { - // - upper = 0; - lower = 0; - - // - to = NULL; - from = NULL; - symbol = NULL; - period = NULL; - - // - repetition = 0; - - // - type = XPV_NONE; - - // - state.Clean(); - - // - ZeroMemory(this); - } - - /** - * Validation ... - * - * @return ( bool ) - */ - bool IsValid() - { - // - bool result = false; - - // - result = - // - IsValid(to) && - IsValid(from) && - IsValid(symbol) && - IsValid(period) && - repetition > 0 && - type != XPV_NONE && - (upper > 0 || lower > 0) - // - ; - - // - return result; - } - - /** - * Check Pivot is Peak ... - * - * @return ( bool ) - */ - bool IsPeak() - { - // - bool result = false; - - // - result = IsValid() && - type == XPV_PEAK; - - // - return result; - } - - /** - * Check Pivot is Vale ... - * - * @return ( bool ) - */ - bool IsVale() - { - // - bool result = false; - - // - result = IsValid() && - type == XPV_VALE; - - // - return result; - } - - /** - * Calculate Lower for Peaks ... - * - * @return ( double ) - */ - double CalculateLower() - { - // - double result = 0; - - // - if (!IsValid() || - !IsPeak()) - { - return result; - } - - // - int fromIndex = iBarShift( - symbol, - period, - from // - ); - - // - int toIndex = iBarShift( - symbol, - period, - to // - ); - - // - int count = - fromIndex - toIndex; - - // - int llIDX = iLowest( - symbol, - period, - MODE_LOW, - count, - toIndex // - ); - - // - result = - iLow( - symbol, - period, - llIDX // - ); - - // - return result; - } - - /** - * Calculate Upper for Vales ... - * - * @return ( double ) - */ - double CalculateUpper() - { - // - double result = 0; - - // - if (!IsValid() || - !IsVale()) - { - return result; - } - - // - int fromIndex = iBarShift( - symbol, - period, - from // - ); - - // - int toIndex = iBarShift( - symbol, - period, - to // - ); - - // - int count = - fromIndex - toIndex; - - // - int hhIDX = iHighest( - symbol, - period, - MODE_HIGH, - count, - toIndex // - ); - - // - result = - iHigh( - symbol, - period, - hhIDX // - ); - - // - return result; - } - - /** - * Calculate Range of Pivot ... - * - * @return ( double ) - */ - double CalculateRange() - { - // - double result = 0; - - // - if (!IsValid() || - upper <= 0 || - lower <= 0) - { - return result; - } - - // - result = upper - lower; - - // - return result; - } - - /** - * Calculate Middle of Pivot ... - * Used for - * @return ( double ) - */ - double CalculateMid() - { - // - double result = 0; - - // - double range = CalculateRange(); - if (range <= 0) - { - return result; - } - - // - result = lower + (range / 2); - - // - return result; - } - - /** - * Calculate Liquidity Percent for Specified Direction ... - * - * @param forDirection: ENUM_X_DIRECTION member, Specified Liquidity ... - * @param price: Double, Specified Price ... - * - * @return ( double ) - */ - double CalculateLiquidityPercent( - ENUM_X_DIRECTION forDirection, - double price = 0 // - ) - { - // - double result = 0; - - // - if (!IsValid()) - { - return result; - } - - // - result = state - .CalculateLiquidityPercent( - forDirection, - price // - ); - - // - return result; - } - - /** - * Check Price in Premium or not ... - * - * @return ( bool ) - */ - bool IsPriceInPremium() - { - // - bool result = false; - - // - result = IsValid(); - if (!result) - { - return result; - } - - // - double ask = GetAsk(symbol); - double bid = GetBid(symbol); - - // - double mid = CalculateMid(); - - // - result = - // - ask > mid && - bid > mid - // - ; - - // - return result; - } - - /** - * Check Price in Discount or not ... - * - * @return ( bool ) - */ - bool IsPriceInDiscount() - { - // - bool result = false; - - // - result = IsValid(); - if (!result) - { - return result; - } - - // - double ask = GetAsk(symbol); - double bid = GetBid(symbol); - - // - double mid = CalculateMid(); - - // - result = - // - ask > mid && - bid > mid - // - ; - - // - return result; - } - - // - - /** - * Get Unique Identifier ... - * - * @return ( string ) - */ - string GetTag() - { - // - string result = NULL; - - // - if (!IsValid()) - { - return result; - } - - // - string hash = symbol + "_" + - ToString(period) + "_" + - ToString(upper) + "," + - ToString(lower) + "_" + - ToString(from) + "," + - ToString(to); - hash = ToMD5(hash); - - // - string typeStr = - type == XPV_PEAK - ? "Peak" - : "Vale"; - - // - result = - // - "XPV_" + - typeStr + "_" + - symbol + "_" + - ToString(period) + - "_" + hash - // - ; - - // - return result; + return IsValidSize(CountBearishFairValueGaps()); } // }; -// -// Pivots ... -struct XPVPivotPoint -{ - // - // Props ... - double value; - int repetition; - datetime time; - ENUM_XPV_PIVOTS type; - - // - // Constructor ... - XPVPivotPoint() - { - Clean(); - } - - // - // Tools ... - - /** - * Cleanup ... - */ - void Clean() - { - // - value = 0; - time = NULL; - repetition = 0; - type = XPV_NONE; - - // - ZeroMemory(this); - } - - /** - * Validate ... - * - * @return ( bool ) - */ - bool IsValid() - { - // - bool result = false; - - // - result = - // - value > 0 && - IsValid(time) && - repetition > 0 && - type != XPV_NONE - // - ; - - // - return result; - } - - /** - * Check current Pivot Point is Peak or not ... - * - * @return ( bool ) - */ - bool IsPeak() - { - // - bool result = false; - - // - result = IsValid() && - type == XPV_PEAK; - - // - return result; - } - - /** - * Check current Pivot Point is Vale or not ... - * - * @return ( bool ) - */ - bool IsVale() - { - // - bool result = false; - - // - result = IsValid() && - type == XPV_VALE; - - // - return result; - } - - // -}; - -// -// -// - // // Consolidation Zone ... struct XConsolidationZone @@ -5270,1442 +4936,6 @@ struct XConsolidationZone // }; -/** - * Converts a Consolidation Zone ... - * - * @param zone: XConsolidationZone instance Reference ... - * @param dest: XCZone pointer Reference ... - * - * @return ( bool ) - */ -bool ToZone( - XConsolidationZone &zone, - XCZone *&dest // -) -{ - // - bool result = false; - - // - dest = NULL; - - // - result = zone.IsValid(); - if (!result) - { - return result; - } - - // - dest = new XCZone(); - dest.Upper(zone.upper); - dest.Lower(zone.lower); - result = dest.IsValidBoundary(); - - // - return result; -} - -// -// Model Value Changed ... -struct XValueChange -{ - // - // Props ... - double before; // Before Change Value ... - double after; // After Change Value ... - datetime time; // Change Time ... - ENUM_X_DIRECTION dir; // Change Direction ... - - // - // Constructor ... - XValueChange() - { - Clean(); - } - - // - // Tools ... - - /** - * Initialize ... - * - * @param _before: Double, Value Before Change ... - * @param _after: Double, Value After Change ... - * @param _time: Datetime, Change Time ... - * @param _dir: ENUM_X_DIRECTION member, Specified Changed Direction ... - * - * @return ( bool ) - */ - bool Init( - double _before, // Before Change Value ... - double _after, // After Change Value ... - ENUM_X_DIRECTION _dir, // Change Direction ... - datetime _time = NULL // Change Time ... - ) - { - // - bool result = false; - - // - _time = NormalizeTime(_time); - - // - // Validate Inputs ... - result = - // - _after > 0 && - _before > 0 && - IsValid(_time) && - _after != _before && - HasDirection(_dir) - // - ; - if (!result) - { - return result; - } - - // - // Set Validated Values ... - dir = _dir; - time = _time; - after = _after; - before = _before; - - // - result = IsValid(); - - // - return result; - } - - /** - * Cleaning Up ... - */ - void Clean() - { - // - after = 0; - before = 0; - time = NULL; - dir = X_DIRECTION_NONE; - - // - ZeroMemory(this); - } - - /** - * Validate Model ... - * - * @return ( bool ) - */ - bool IsValid() - { - // - bool result = false; - - // - result = - // - after > 0 && - before > 0 && - IsValid(time) && - after != before && - HasDirection(dir) - // - ; - - // - return result; - } - - /** - * Fill Change Bar ... - * - * @param bar: XOHCL instance Reference, holds Change Bar ... - * @param _symbol: String, Specified Symbol ... - * @param _period: ENUM_TIMEFRAMES _period member, Specified Period ... - * - * @return ( bool ) - */ - bool FillBar( - XOHCL &bar, - string _symbol = NULL, - ENUM_TIMEFRAMES _period = NULL // - ) - { - // - bool result = false; - - // - bar.Clean(); - _symbol = NormalizeSymbol(_symbol); - _period = NormalizePeriod(_period); - - // - result = IsValid() && - IsValid(_symbol) && - IsValid(_period); - if (!result) - { - return result; - } - - // - result = bar.Init( - _symbol, - _period, - time // - ); - - // - return result; - } - - // -}; - -// -// Price Zones Model ... -struct XPriceZones -{ - // - XOHCL bar; // if Based On Bar it's Filled ... - double price; // if Based on Price, it's Filled ... - - // - int count; // Exists Zones Count ... - - // - XCFVG *fairValueGap; // Exists Fair Value Gap ... - XCSupplyZone *supplyZone; // Exists Supply Zone ... - XCDemandZone *demandZone; // Exists Demand Zone ... - XCOrderBlock *orderBlock; // Exists Order Block ... - XCSupportZone *supportZone; // Exists Support Zone ... - XCResistanceZone *resistanceZone; // Exists Resistance Zone ...Ù‘ - - // - // Constructor ... - XPriceZones() - { - Clean(); - } - - /** - * Cleanup ... - */ - void Clean() - { - // - bar.Clean(); - price = 0; - - // - supplyZone = NULL; - demandZone = NULL; - orderBlock = NULL; - supportZone = NULL; - fairValueGap = NULL; - resistanceZone = NULL; - - // - ZeroMemory(this); - } - - /** - * Check Zone is Valid ... - * - * @return ( bool ) - */ - bool IsValid() - { - // - bool result = false; - - // - result = - // - (IsBasedOnBar() || - IsBasedOnPrice()) && - IsValidSize(count) - // - ; - - // - return result; - } - - /** - * Check Zones Base on Bar ... - * - * @return ( bool ) - */ - bool IsBasedOnBar() - { - return bar.IsValid(); - } - - /** - * Check Zones Based on Price ... - * - * @return ( bool ) - */ - bool IsBasedOnPrice() - { - return price > 0; - } - - /** - * Check Has Supply Zone ... - * - * @return ( bool ) - */ - bool HasSupplyZone() - { - // - return IsValidSize(count) && - supplyZone != NULL && - supplyZone.IsValid(); - } - - /** - * Check Has Demand Zone ... - * - * @return ( bool ) - */ - bool HasDemandZone() - { - // - return IsValidSize(count) && - demandZone != NULL && - demandZone.IsValid(); - } - - /** - * Check Has OrderBlock ... - * - * @return ( bool ) - */ - bool HasOrderBlock() - { - // - return IsValidSize(count) && - orderBlock != NULL && - orderBlock.IsValid(); - } - - /** - * Check Has Support Zone ... - * - * @return ( bool ) - */ - bool HasSupportZone() - { - // - return IsValidSize(count) && - supportZone != NULL && - supportZone.IsValid(); - } - - /** - * Check Has FairValueGap ... - * - * @return ( bool ) - */ - bool HasFairValueGap() - { - // - return IsValidSize(count) && - fairValueGap != NULL && - fairValueGap.IsValid(); - } - - /** - * Check Has Resistance Zone ... - * - * @return ( bool ) - */ - bool HasResistanceZone() - { - // - return IsValidSize(count) && - resistanceZone != NULL && - resistanceZone.IsValid(); - } - - /** - * Check Zones are Overal Bullish ... - * - * @return ( bool ) - */ - bool IsBullish() - { - // - bool result = false; - - // - result = - // - HasDemandZone() - // - || - // - HasSupportZone() - // - || - // - (HasOrderBlock() && - orderBlock.IsBullish()) - // - || - // - (HasFairValueGap() && - fairValueGap.IsBullish()) - // - ; - - // - return result; - } - - /** - * Check Zones are Overal Bearish ... - * - * @return ( bool ) - */ - bool IsBearish() - { - // - bool result = false; - - // - result = - // - HasSupplyZone() - // - || - // - HasResistanceZone() - // - || - // - (HasOrderBlock() && - orderBlock.IsBearish()) - // - || - // - (HasFairValueGap() && - fairValueGap.IsBearish()) - // - ; - - // - return result; - } - - /** - * Fill Zones Based On required Direction ... - * - * @param dir: ENUM_X_DIRECTION member ... - * - * @return ( int ) - */ - int FillZones( - ENUM_X_DIRECTION dir, - XCZone *&zones[] // - ) - { - // - int result = 0; - - // - Clean(zones); - - // - bool isBullish = IsBullish(dir); - bool isBoth = dir == X_DIRECTION_ALL || - dir == X_DIRECTION_NONE; - - // - if (isBoth || isBullish) - { - // - if (HasSupportZone()) - { - // - Add( - (XCZone *)supportZone, - zones // - ); - } - - // - if (HasDemandZone()) - { - // - Add( - (XCZone *)demandZone, - zones // - ); - } - - // - if (HasOrderBlock() && - orderBlock.IsBullish()) - { - // - Add( - (XCZone *)orderBlock, - zones // - ); - } - - // - if (HasFairValueGap() && - fairValueGap.IsBullish()) - { - // - Add( - (XCZone *)fairValueGap, - zones // - ); - } - } - - // - if (isBoth || !isBullish) - { - // - if (HasResistanceZone()) - { - // - Add( - (XCZone *)resistanceZone, - zones // - ); - } - - // - if (HasSupplyZone()) - { - // - Add( - (XCZone *)supplyZone, - zones // - ); - } - - // - if (HasOrderBlock() && - orderBlock.IsBearish()) - { - // - Add( - (XCZone *)orderBlock, - zones // - ); - } - - // - if (HasFairValueGap() && - fairValueGap.IsBearish()) - { - // - Add( - (XCZone *)fairValueGap, - zones // - ); - } - } - - // s - result = ArraySize(zones); - - // - return result; - } - - /** - * Calculate Boundary of Zones ... - * - * @param dir: ENUM_X_DIRECTION Member, Specified Direction ... - * @param upper: Double ... - * @param lower: Double ... - * - * @return ( bool ) - */ - bool GetBoundary( - ENUM_X_DIRECTION dir, - double &upper, - double &lower // - ) - { - // - bool result = false; - - // - upper = 0; - lower = 0; - - // - XCZone *zones[]; - int mCount = FillZones(dir, zones); - result = IsValidSize(mCount); - if (!result) - { - return result; - } - - // - for (int i = 0; i < mCount; i++) - { - // - XCZone *iZone = zones[i]; - - // - double iUpper = iZone.Upper(); - double iLower = iZone.Lower(); - - // - upper = - upper == 0 - ? iUpper - : iUpper > upper - ? iUpper - : upper; - - // - lower = - lower == 0 - ? iLower - : iLower < lower - ? iLower - : lower; - } - - // - return result; - } - - /** - * Calculate Lifetime of Zones ... - * - * @param dir: ENUM_X_DIRECTION Member, Specified Direction ... - * @param from: DateTime ... - * @param to: DateTime ... - * - * @return ( bool ) - */ - bool GetLifetime( - ENUM_X_DIRECTION dir, - datetime &from, - datetime &to // - ) - { - // - bool result = false; - - // - to = NULL; - from = NULL; - - // - XCZone *zones[]; - int mCount = FillZones(dir, zones); - result = IsValidSize(mCount); - if (!result) - { - return result; - } - - // - bool isBullish = IsBullish(dir); - bool isAll = dir == X_DIRECTION_NONE || - dir == X_DIRECTION_ALL; - - // - if (isAll || isBullish) - { - // - // Support Zone ... - bool hasSupportZone = HasSupportZone(); - if (hasSupportZone) - { - // - XCSupportZone *zone = supportZone; - - // - from = - !IsValid(from) || - from > zone.From() - ? zone.From() - : from; - - // - to = - !IsValid(to) || - to < zone.To() - ? zone.To() - : from; - } - - // - // Demand Zone ... - bool hasDemandZone = HasDemandZone(); - if (hasDemandZone) - { - // - XCDemandZone *zone = demandZone; - - // - from = - !IsValid(from) || - from > zone.From() - ? zone.From() - : from; - - // - to = - !IsValid(to) || - to < zone.To() - ? zone.To() - : from; - } - - // - // Order Block ... - bool hasOrderBlock = HasOrderBlock() && - orderBlock.IsBullish(); - if (hasOrderBlock) - { - // - XCOrderBlock *zone = orderBlock; - - // - from = - !IsValid(from) || - from > zone.From() - ? zone.From() - : from; - - // - to = - !IsValid(to) || - to < zone.To() - ? zone.To() - : from; - } - - // - // Fair Value Gap ... - bool hasFairValueGap = HasFairValueGap() && - fairValueGap.IsBullish(); - if (hasFairValueGap) - { - // - XCFVG *zone = fairValueGap; - - // - from = - !IsValid(from) || - from > zone.From() - ? zone.From() - : from; - - // - to = - !IsValid(to) || - to < zone.To() - ? zone.To() - : from; - } - } - - // - if (isAll || !isBullish) - { - // - // Resistance Zone ... - bool hasResistanceZone = HasResistanceZone(); - if (hasResistanceZone) - { - // - XCResistanceZone *zone = resistanceZone; - - // - from = - !IsValid(from) || - from > zone.From() - ? zone.From() - : from; - - // - to = - !IsValid(to) || - to < zone.To() - ? zone.To() - : from; - } - - // - // Supply Zone ... - bool hasSupplyZone = HasSupplyZone(); - if (hasSupplyZone) - { - // - XCSupplyZone *zone = supplyZone; - - // - from = - !IsValid(from) || - from > zone.From() - ? zone.From() - : from; - - // - to = - !IsValid(to) || - to < zone.To() - ? zone.To() - : from; - } - - // - // Order Block ... - bool hasOrderBlock = HasOrderBlock() && - orderBlock.IsBearish(); - if (hasOrderBlock) - { - // - XCOrderBlock *zone = orderBlock; - - // - from = - !IsValid(from) || - from > zone.From() - ? zone.From() - : from; - - // - to = - !IsValid(to) || - to < zone.To() - ? zone.To() - : from; - } - - // - // Fair Value Gap ... - bool hasFairValueGap = HasFairValueGap() && - fairValueGap.IsBearish(); - if (hasFairValueGap) - { - // - XCFVG *zone = fairValueGap; - - // - from = - !IsValid(from) || - from > zone.From() - ? zone.From() - : from; - - // - to = - !IsValid(to) || - to < zone.To() - ? zone.To() - : from; - } - } - - // - result = - to > from && - IsValid(to) && - IsValid(from); - - // - return result; - } - - /** - * Calculate Box Model Data ... - * - * @param dir: ENUM_X_DIRECTION Member, Specified Direction ... - * @param upper: Double ... - * @param lower: Double ... - * @param from: DateTime ... - * @param to: DateTime ... - * - * @return ( bool ) - */ - bool GetBoxData( - ENUM_X_DIRECTION dir, - double &upper, - double &lower, - datetime &from, - datetime &to // - ) - { - // - bool result = false; - - // - bool hasBoundary = GetBoundary( - dir, - upper, - lower // - ); - - // - bool hasLifetime = GetLifetime( - dir, - from, - to // - ); - - // - result = - hasBoundary && - hasLifetime; - - // - return result; - } - - // -}; - -// -// Market Strucutre Model ... -struct XMarketStructure -{ - // - string symbol; - ENUM_TIMEFRAMES period; - - // - ENUM_X_DIRECTION bias; - - // - XPVPivotPoint vales[]; - XPriceZones valePriceZones[]; - - // - XPVPivotPoint peaks[]; - XPriceZones peakPriceZones[]; - - // - XOHCL lowestValeBar; - XOHCL lowestValePeakBreakeUpBar; - XOHCL valeAboveLowestValePeakBar; - - // - XOHCL highestPeakBar; - XOHCL peakBelowHighestPeakValeBar; - XOHCL highestPeakValeBreakeDownBar; - - // - XMarketStructure() - { - Clean(); - } - - /** - * Cleanup ... - */ - void Clean() - { - // - symbol = NULL; - period = NULL; - bias = X_DIRECTION_NONE; - - // - Clean(vales); - Clean(peaks); - Clean(valePriceZones); - Clean(peakPriceZones); - - // - lowestValeBar.Clean(); - lowestValePeakBreakeUpBar.Clean(); - valeAboveLowestValePeakBar.Clean(); - - // - highestPeakBar.Clean(); - peakBelowHighestPeakValeBar.Clean(); - highestPeakValeBreakeDownBar.Clean(); - - // - ZeroMemory(this); - } - - /** - * Validate Model ... - * - * @return ( bool ) - */ - bool IsValid() - { - // - bool result = false; - - // - result = - IsValid(symbol) && - IsValid(period) && - bias != X_DIRECTION_NONE; - - // - return result; - } - - /** - * Check Bullish Trend ... - * - * @return ( bool ) - */ - bool IsBullish() - { - // - bool result = false; - - // - result = - // - IsValid() && - IsBullish(bias) && - HasChild(peaks) && - HasDirection(bias) && - lowestValeBar.IsValid() && - HasChild(peakPriceZones) && - lowestValePeakBreakeUpBar.IsValid() && - valeAboveLowestValePeakBar.IsValid() - // - ; - - // - return result; - } - - /** - * Check Bearish Trend ... - * - * @return ( bool ) - */ - bool IsBearish() - { - // - bool result = false; - - // - result = - // - IsValid() && - IsBearish(bias) && - HasChild(vales) && - HasDirection(bias) && - highestPeakBar.IsValid() && - HasChild(valePriceZones) && - peakBelowHighestPeakValeBar.IsValid() && - highestPeakValeBreakeDownBar.IsValid() - // - ; - - // - return result; - } - - /** - * Check Has Trend ... - * - * @return ( bool ) - */ - bool HasTrend() - { - // - bool result = false; - - // - result = IsValid() && - (IsBullish() || - IsBearish()); - - // - return result; - } - - // -}; - -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); - - // - ZeroMemory(this); - } - - /** - * 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; - - // - result = ArraySize(supportZones); - - // - return result; - } - - // - int CountResistanceZones() - { - // - int result = 0; - - // - result = ArraySize(resistanceZones); - - // - return result; - } - - // - int CountSupplyZones() - { - // - int result = 0; - - // - result = ArraySize(supplyZones); - - // - return result; - } - - // - int CountDemandZones() - { - // - int result = 0; - - // - result = ArraySize(demandZones); - - // - return result; - } - - // - int CountBullishOrderBlocks() - { - // - int result = 0; - - // - result = ArraySize(bullishOrderBlocks); - - // - return result; - } - - // - int CountBearishOrderBlocks() - { - // - int result = 0; - - // - result = ArraySize(bearishOrderBlocks); - - // - return result; - } - - // - int CountBullishFairValueGaps() - { - // - int result = 0; - - // - result = ArraySize(bullishFairValueGaps); - - // - return result; - } - - // - int CountBearishFairValueGaps() - { - // - int result = 0; - - // - result = ArraySize(bearishFairValueGaps); - - // - return result; - } -}; - -struct XFVGOrderBlock -{ - // - // Props ... - XCOrderBlock *orderBlock; - XCFVG *fairValueGap; - // XStateZones stateZones; - - // - XFVGOrderBlock() - { - Clean(); - } - - /** - * Cleanup Model ... - */ - void Clean() - { - // - orderBlock = NULL; - fairValueGap = NULL; - - // - ZeroMemory(this); - } - - /** - * Validate Model ... - * - * @return ( bool ) - */ - bool IsValid() - { - // - bool result = false; - - // - result = - // - orderBlock != NULL && - fairValueGap != NULL && - // stateZones.IsValid() && - ((orderBlock.IsBullish() && - fairValueGap.IsBullish()) || - ((orderBlock.IsBearish() && - fairValueGap.IsBearish()))) - // - ; - - // - return result; - } - - /** - * Get Model Direction ... - * - * @param dir: ENUM_X_DIRECTION member ... - * - * @return ( bool ) - */ - bool GetDirection( - ENUM_X_DIRECTION &dir // - ) - { - // - bool result = false; - - // - dir = X_DIRECTION_NONE; - - // - result = IsValid(); - if (!result) - { - return result; - } - - // - dir = orderBlock.IsBullish() - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - - // - return result; - } - - /** - * Retrieve Boundary of Zone ... - * - * @param upper: Upper Boundary ...Ù‘ - * @param lower: Lower Bondary ... - * @return ( bool ) - */ - bool GetBoundary( - double &upper, - double &lower // - ) - { - // - bool result = false; - - // - upper = 0; - lower = 0; - - // - result = IsValid(); - if (!result) - { - return result; - } - - // - upper = orderBlock.Upper(); - upper = MathMax(upper, fairValueGap.Upper()); - - // - lower = orderBlock.Lower(); - lower = MathMax(lower, fairValueGap.Lower()); - - // - result = lower > 0 && - upper > 0 && - upper > lower; - - // - return result; - } - - /** - * Check Model is same as another Istance ... - * - * @param value: XFVGOrderBlock instance Reference ... - * - * @return ( bool ) - */ - bool IsSameAs(XFVGOrderBlock &value) - { - // - bool result = false; - - // - result = - IsValid() && - value.IsValid(); - if (!result) - { - return result; - } - - // - ENUM_X_DIRECTION dir; - result = GetDirection(dir); - if (!result) - { - return result; - } - - // - ENUM_X_DIRECTION valueDir; - result = value.GetDirection(valueDir); - if (!result) - { - return result; - } - - // - result = - // - dir == valueDir - // - && - // - orderBlock.From() == value.orderBlock.From() && - orderBlock.Upper() == value.orderBlock.Upper() && - orderBlock.Lower() == value.orderBlock.Lower() - // - && - // - fairValueGap.From() == value.fairValueGap.From() && - fairValueGap.Upper() == value.fairValueGap.Upper() && - fairValueGap.Lower() == value.fairValueGap.Lower() - // - ; - - // - return result; - } - // -}; - struct XBoxZone { // @@ -7039,3132 +5269,6 @@ string ToString(ENUM_XPOI_EVENTS value) // // -/** - * Find Oldest Pivot Index ... - * - * @param pivots: XPVPivot instance ... - * @return ( int ) - */ -int FindOldestPivotIndex( - XPVPivot &pivots[] // -) -{ - // - int result = -1; - - // - int count = ArraySize(pivots); - if (!IsValidSize(count)) - { - return result; - } - - // - for (int i = 0; i < count; i++) - { - // - XPVPivot iPivot = pivots[i]; - - // - bool isOldest = true; - for (int j = 0; j < count; j++) - { - // - XPVPivot jPivot = pivots[j]; - - // - isOldest = iPivot.from <= jPivot.from; - if (!isOldest) - { - break; - } - } - - // - if (isOldest) - { - // - result = i; - break; - } - } - - // - return result; -} - -/** - * Sort Pivots Based On From Date ... - * - * @param pivots: XPVPivot instance Collection reference ... - */ -void SortPivots( - XPVPivot &pivots[] // -) -{ - // - XPVPivot tmp[]; - Copy( - pivots, - tmp // - ); - - // - Clean(pivots); - - // - while (ArraySize(tmp) > 0) - { - // - if (ArraySize(tmp) == 1) - { - // - AddRef( - tmp[0], - pivots // - ); - - // - ArrayRemove( - tmp, - 0, - 1); - } - else - { - // - int idx = FindOldestPivotIndex(tmp); - if (IsValidIndex(idx)) - { - // - AddRef( - tmp[idx], - pivots // - ); - - // - ArrayRemove( - tmp, - idx, - 1 // - ); - } - } - } - - // - Clean(tmp); -} - -bool IsPivotBreaked( - XPVPivot &pivot, - XPVPivot &pivots[] // -) -{ - // - bool result = false; - - // - result = pivot.IsValid(); - if (!result) - { - return result; - } - - // - int count = ArraySize(pivots); - result = IsValidSize(pivots); - if (!result) - { - return result; - } - - // - // For Peaks Highs Must not Broked ... - // For Vales Lows Must not Broked ... - bool isPeak = pivot.IsPeak(); - - // - for (int i = 0; i < count; i++) - { - // - XPVPivot iPivot = pivots[i]; - - // - result = isPeak - ? iPivot.upper > pivot.upper - : iPivot.lower < pivot.lower; - if (result) - { - break; - } - } - - // - return result; -} - -/** - * Filter Broken Pivots for Detect Order Flow ... - * - * @param pivots: XPVPivot instance Collection reference ... - */ -void FilterBrokenPivots( - XPVPivot &pivots[] // -) -{ - // - XPVPivot tmp[]; - Copy( - pivots, - tmp // - ); - - // - Clean(pivots); - - // - while (ArraySize(tmp) > 0) - { - // - if (ArraySize(tmp) == 1) - { - // - AddRef( - tmp[0], - pivots // - ); - - // - ArrayRemove( - tmp, - 0, - 1 // - ); - } - else - { - // - XPVPivot pivot = tmp[0]; - - // - ArrayRemove( - tmp, - 0, - 1 // - ); - - // - bool isBreaked = IsPivotBreaked( - pivot, - tmp // - ); - if (!isBreaked) - { - // - AddRef( - pivot, - pivots // - ); - } - } - } - - // - Clean(tmp); -} - -/** - * Calculate Order Flow Direction ... - * - * @param orderFlow: XPVPivot instance Collection reference ... - * @param dir: ENUM_X_DIRECTION member reference, Hold's Calculated Direction ... - * - * @return ( bool ) - */ -bool DetectPivotDirection( - XPVPivot &orderFlow[], - ENUM_X_DIRECTION &dir // -) -{ - // - bool result = false; - - // - dir = X_DIRECTION_NONE; - - // - int count = ArraySize(orderFlow); - result = IsValidSize(count); - if (!result) - { - return result; - } - - // - // For Bullish Direction all Exists lowers must be Greater or Equal Prev ... - bool isBullish = false; - bool canLookupForBullish = true; - - // - // For Bearish Direction all Exists uppers must be Lesser or Equal Prev ... - bool isBearish = false; - bool canLookupForBearish = true; - - // - for (int i = 0; i < count; i++) - { - // - XPVPivot iPivot = orderFlow[i]; - - // - XPVPivot tmp[]; - Copy( - orderFlow, - tmp // - ); - ArrayRemove( - tmp, - 0, - i + 1 // - ); - - // - int tmpCount = ArraySize(tmp); - if (IsValidSize(tmpCount)) - { - // - for (int j = 0; j < tmpCount; j++) - { - // - XPVPivot jPivot = tmp[j]; - - // - // Check Bullish Direction ... - isBullish = - canLookupForBullish && - jPivot.lower >= iPivot.lower; - if (!isBullish) - { - canLookupForBullish = false; - } - - // - // Check Bearish Direction ... - isBearish = - canLookupForBearish && - jPivot.upper <= iPivot.upper; - if (!isBearish) - { - canLookupForBearish = false; - } - - // - if (!canLookupForBullish && - !canLookupForBearish) - { - break; - } - } - } - Clean(tmp); - } - - // - if (isBullish && - !isBearish) - { - dir = X_DIRECTION_BULLISH; - } - else if (isBearish && - !isBullish) - { - dir = X_DIRECTION_BEARISH; - } - - // - result = dir != X_DIRECTION_NONE; - - // - return result; -} - -/** - * Detect all POIs which inside a Pivot ... - * - * @param pivot: XPVPivot instance, Specified Pivot ... - * @param source: XPOIState instance, Reference to Source State ... - * @param state: XPOIState instance, Reference to Detected Pivots ... - * @param lookupSwingHighs: Boolean ... - * @param lookupSwingLows: Boolean ... - * @param lookupSupportZones: Boolean ... - * @param lookupResistanceZones: Boolean ... - * @param lookupSupplyZones: Boolean ... - * @param lookupDemandZones: Boolean ... - * @param lookupBullishOrderBlocks: Boolean ... - * @param lookupBearishOrderBlocks: Boolean ... - * @param lookupBullishFairValueGaps: Boolean ... - * @param lookupBearishFairValueGaps: Boolean ... - * @param lookupBullishRejectionBars: Boolean ... - * @param lookupBearishRejectionBars: Boolean ... - * @param lookupBullishMomentumBars: Boolean ... - * @param lookupBearishMomentumBars: Boolean ... - */ -void DetectPivotPOIs( - XPVPivot &pivot, - XPOIState &source, - XPOIState &state, - bool lookupSwingHighs = true, - bool lookupSwingLows = true, - bool lookupSupportZones = true, - bool lookupResistanceZones = true, - bool lookupSupplyZones = true, - bool lookupDemandZones = true, - bool lookupBullishOrderBlocks = true, - bool lookupBearishOrderBlocks = true, - bool lookupBullishFairValueGaps = true, - bool lookupBearishFairValueGaps = true, - bool lookupBullishRejectionBars = true, - bool lookupBearishRejectionBars = true, - bool lookupBullishMomentumBars = true, - bool lookupBearishMomentumBars = true // -) -{ - // - state.Clean(); - - // - if (!pivot.IsValid()) - { - return; - } - - // - int count = 0; - - // - state.symbol = pivot.symbol; - state.period = pivot.period; - state.time = TimeCurrent(); - - // - // Swings ... - - // - // Swing High ... - if (lookupSwingHighs) - { - // - count = ArraySize(source.swingHighs); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSwing *iSwing = source.swingHighs[i]; - - // - XOHCL iBar; - bool isFilled = iSwing.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isInside = iBar.high <= pivot.upper; - if (isInside) - { - // - // iSwing.To(pivot.to); - - // - Add( - iSwing, - state.swingHighs // - ); - } - } - } - } - - // - // Swing Low ... - if (lookupSwingLows) - { - // - count = ArraySize(source.swingLows); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSwing *iSwing = source.swingLows[i]; - - // - XOHCL iBar; - bool isFilled = iSwing.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isInside = iBar.low >= pivot.lower; - if (isInside) - { - // - // iSwing.To(pivot.to); - - // - Add( - iSwing, - state.swingLows // - ); - } - } - } - } - - // - // Support and Resistance Zones ... - - // - // Support Zones ... - if (lookupSupportZones) - { - // - count = ArraySize(source.supportZones); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSupportZone *iZone = source.supportZones[i]; - - // - bool isInside = - iZone.Upper() <= pivot.upper && - iZone.Lower() >= pivot.lower; - if (isInside) - { - // - iZone.To(pivot.to); - - // - Add( - iZone, - state.supportZones // - ); - } - } - } - } - - // - // Resistance Zones ... - if (lookupResistanceZones) - { - // - count = ArraySize(source.resistanceZones); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCResistanceZone *iZone = source.resistanceZones[i]; - - // - bool isInside = - iZone.Upper() <= pivot.upper && - iZone.Lower() >= pivot.lower; - if (isInside) - { - // - iZone.To(pivot.to); - - // - Add( - iZone, - state.resistanceZones // - ); - } - } - } - } - - // - // Supply and Demand Zones ... - - // - // Supply Zones ... - if (lookupSupplyZones) - { - // - count = ArraySize(source.supplyZones); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSupplyZone *iZone = source.supplyZones[i]; - - // - bool isInside = - iZone.Upper() <= pivot.upper && - iZone.Lower() >= pivot.lower; - if (isInside) - { - // - iZone.To(pivot.to); - - // - Add( - iZone, - state.supplyZones // - ); - } - } - } - } - - // - // Demand Zones ... - if (lookupDemandZones) - { - // - count = ArraySize(source.demandZones); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCDemandZone *iZone = source.demandZones[i]; - - // - bool isInside = - iZone.Upper() <= pivot.upper && - iZone.Lower() >= pivot.lower; - if (isInside) - { - // - iZone.To(pivot.to); - - // - Add( - iZone, - state.demandZones // - ); - } - } - } - } - - // - // Order Blocks ... - - // - // Bullish Order Blocks ... - if (lookupBullishOrderBlocks) - { - // - count = ArraySize(source.bullishOrderBlocks); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock *iZone = source.bullishOrderBlocks[i]; - - // - bool isInside = - iZone.Upper() <= pivot.upper && - iZone.Lower() >= pivot.lower; - if (isInside) - { - // - iZone.To(pivot.to); - - // - Add( - iZone, - state.bullishOrderBlocks // - ); - } - } - } - } - - // - // Bearish Order Blocks ... - if (lookupBearishOrderBlocks) - { - // - count = ArraySize(source.bearishOrderBlocks); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock *iZone = source.bearishOrderBlocks[i]; - - // - bool isInside = - iZone.Upper() <= pivot.upper && - iZone.Lower() >= pivot.lower; - if (isInside) - { - // - iZone.To(pivot.to); - - // - Add( - iZone, - state.bearishOrderBlocks // - ); - } - } - } - } - - // - // Fair Value Gaps ... - - // - // Bullish Fair Value Gaps ... - if (lookupBullishFairValueGaps) - { - // - count = ArraySize(source.bullishFairValueGaps); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCFVG *iZone = source.bullishFairValueGaps[i]; - - // - bool isInside = - iZone.Upper() <= pivot.upper && - iZone.Lower() >= pivot.lower; - if (isInside) - { - // - iZone.To(pivot.to); - - // - Add( - iZone, - state.bullishFairValueGaps // - ); - } - } - } - } - - // - // Bearish Fair Value Gaps ... - if (lookupBearishFairValueGaps) - { - // - count = ArraySize(source.bearishFairValueGaps); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCFVG *iZone = source.bearishFairValueGaps[i]; - - // - bool isInside = - iZone.Upper() <= pivot.upper && - iZone.Lower() >= pivot.lower; - if (isInside) - { - // - iZone.To(pivot.to); - - // - Add( - iZone, - state.bearishFairValueGaps // - ); - } - } - } - } - - // - // Rejection Bars ... - - // - // Bullish Rejection Bars ... - if (lookupBullishRejectionBars) - { - // - count = ArraySize(source.bullishRejectionBars); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCRejectionBar *iRejection = source.bullishRejectionBars[i]; - - // - XOHCL iBar; - bool isFilled = iRejection.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isInside = iBar.low <= pivot.upper && - iBar.low >= pivot.lower; - if (isInside) - { - // - iRejection.To(pivot.to); - - // - Add( - iRejection, - state.bullishRejectionBars // - ); - } - } - } - } - - // - // Bearish Rejection Bars ... - if (lookupBearishRejectionBars) - { - // - count = ArraySize(source.bearishRejectionBars); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCRejectionBar *iRejection = source.bearishRejectionBars[i]; - - // - XOHCL iBar; - bool isFilled = iRejection.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isInside = iBar.high <= pivot.upper && - iBar.high >= pivot.lower; - if (isInside) - { - // - iRejection.To(pivot.to); - - // - Add( - iRejection, - state.bearishRejectionBars // - ); - } - } - } - } - - // - // Momentum Bars ... - - // - // Bullish Momentum Bars ... - if (lookupBullishMomentumBars) - { - // - count = ArraySize(source.bullishMomentumBars); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCMomentumBar *iMomentum = source.bullishMomentumBars[i]; - - // - XOHCL iBar; - bool isFilled = iMomentum.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isInside = iBar.low <= pivot.upper && - iBar.low >= pivot.lower; - if (isInside) - { - // - iMomentum.To(pivot.to); - - // - Add( - iMomentum, - state.bullishMomentumBars // - ); - } - } - } - } - - // - // Bearish Momenum Bars ... - if (lookupBearishMomentumBars) - { - // - count = ArraySize(source.bearishMomentumBars); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCMomentumBar *iMomentum = source.bearishMomentumBars[i]; - - // - XOHCL iBar; - bool isFilled = iMomentum.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isInside = iBar.high <= pivot.upper && - iBar.high >= pivot.lower; - if (isInside) - { - // - iMomentum.To(pivot.to); - - // - Add( - iMomentum, - state.bearishMomentumBars // - ); - } - } - } - } -} - -/** - * Fill Pivot Tick Zone ... - * - * @param pivot: XPVPivot instance Reference ... - */ -void CalculatePivotTickZone( - XPVPivot &pivot, - int ticksLevels, - int ticksRange, - ENUM_TIMEFRAMES _period = NULL // -) -{ - // - string symbol = pivot.symbol; - ENUM_TIMEFRAMES period = IsValid(_period) - ? _period - : pivot.period; - - // - bool isInited = false; - - // - datetime from = pivot.from; - XOHCL iFromBar; - int iFromBarIndex = iBarShift( - symbol, - period, - from // - ); - isInited = iFromBar.Init( - symbol, - period, - iFromBarIndex // - ); - if (!isInited) - { - return; - } - - // - datetime to = pivot.to; - XOHCL iToBar; - int iToBarIndex = iBarShift( - symbol, - period, - to // - ); - isInited = iToBar.Init( - symbol, - period, - iToBarIndex // - ); - if (!isInited) - { - return; - } - - // - if (iFromBarIndex <= iToBarIndex) - { - return; - } - - // - XCTicksZone *iZone; - iZone = new XCTicksZone(); - - // - isInited = ticksLevels > 0 && - ticksRange > 0; - if (!isInited) - { - return; - } - - // - isInited = iZone.Init( - iFromBar, - iToBar // - ); - if (!isInited) - { - return; - } - - // - pivot.state.ticksZone = iZone; -} - -/** - * Filter State based on Pivot ... - * - * @param pivot: XPVPivot instance Reference ... - * @param state: XPOIState instance Reference ... - */ -void FilterPivotState( - XPVPivot &pivot, - XPOIState &state // -) -{ - // - bool isValid = - pivot.IsValid() && - state.IsValid() && - state.HasChild(); - if (!isValid) - { - return; - } - - // - int count = 0; - - // - double upper = pivot.upper; - double lower = pivot.lower; - - // - // - // - - // - // Resistance ... - count = state.CountResistanceZones(); - if (IsValidSize(count)) - { - // - XCResistanceZone *tmp[]; - Copy( - state.resistanceZones, - tmp // - ); - - // - for (int i = 0; i < count; i++) - { - // - XCResistanceZone *item = tmp[i]; - - // - bool isValid = IsPriceInsideZone( - upper, - item // - ); - if (!isValid) - { - // - ArrayRemove( - state.resistanceZones, - i, - 1 // - ); - } - } - - // - Clean(tmp); - } - - // - // Supply ... - count = state.CountSupplyZones(); - if (IsValidSize(count)) - { - // - XCSupplyZone *tmp[]; - Copy( - state.supplyZones, - tmp // - ); - - // - for (int i = 0; i < count; i++) - { - // - XCSupplyZone *item = tmp[i]; - - // - bool isValid = IsPriceInsideZone( - upper, - item // - ); - if (!isValid) - { - // - ArrayRemove( - state.supplyZones, - i, - 1 // - ); - } - } - - // - Clean(tmp); - } - - // - // Bearish Order Block ... - count = state.CountBearishOrderBlocks(); - if (IsValidSize(count)) - { - // - XCOrderBlock *tmp[]; - Copy( - state.bearishOrderBlocks, - tmp // - ); - - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock *item = tmp[i]; - - // - bool isValid = IsPriceInsideZone( - upper, - item // - ); - if (!isValid) - { - // - ArrayRemove( - state.bearishOrderBlocks, - i, - 1 // - ); - } - } - - // - Clean(tmp); - } - - // - // Bearish Fair Value Gap ... - count = state.CountBearishFairValueGaps(); - if (IsValidSize(count)) - { - // - XCFVG *tmp[]; - Copy( - state.bearishFairValueGaps, - tmp // - ); - - // - for (int i = 0; i < count; i++) - { - // - XCFVG *item = tmp[i]; - - // - bool isValid = IsPriceInsideZone( - upper, - item // - ); - if (!isValid) - { - // - ArrayRemove( - state.bearishFairValueGaps, - i, - 1 // - ); - } - } - - // - Clean(tmp); - } - - // - // - // - - // - // Support ... - count = state.CountSupportZones(); - if (IsValidSize(count)) - { - // - XCSupportZone *tmp[]; - Copy( - state.supportZones, - tmp // - ); - - // - for (int i = 0; i < count; i++) - { - // - XCSupportZone *item = tmp[i]; - - // - bool isValid = IsPriceInsideZone( - lower, - item // - ); - if (!isValid) - { - // - ArrayRemove( - state.supportZones, - i, - 1 // - ); - } - } - - // - Clean(tmp); - } - - // - // Demand ... - count = state.CountDemandZones(); - if (IsValidSize(count)) - { - // - XCDemandZone *tmp[]; - Copy( - state.demandZones, - tmp // - ); - - // - for (int i = 0; i < count; i++) - { - // - XCDemandZone *item = tmp[i]; - - // - bool isValid = IsPriceInsideZone( - lower, - item // - ); - if (!isValid) - { - // - ArrayRemove( - state.demandZones, - i, - 1 // - ); - } - } - - // - Clean(tmp); - } - - // - // Bullish Order Block ... - count = state.CountBullishOrderBlocks(); - if (IsValidSize(count)) - { - // - XCOrderBlock *tmp[]; - Copy( - state.bullishOrderBlocks, - tmp // - ); - - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock *item = tmp[i]; - - // - bool isValid = IsPriceInsideZone( - lower, - item // - ); - if (!isValid) - { - // - ArrayRemove( - state.bullishOrderBlocks, - i, - 1 // - ); - } - } - - // - Clean(tmp); - } - - // - // Bullish Fair Value Gap ... - count = state.CountBullishFairValueGaps(); - if (IsValidSize(count)) - { - // - XCFVG *tmp[]; - Copy( - state.bullishFairValueGaps, - tmp // - ); - - // - for (int i = 0; i < count; i++) - { - // - XCFVG *item = tmp[i]; - - // - bool isValid = IsPriceInsideZone( - lower, - item // - ); - if (!isValid) - { - // - ArrayRemove( - state.bullishFairValueGaps, - i, - 1 // - ); - } - } - - // - Clean(tmp); - } -} - -/** - * Detect Box Date of Specified Pivot ... - */ -bool DetectPivotStateBoxData( - XPVPivot &pivot, - double &peakUpper, - double &peakLower, - datetime &peakFrom, - datetime &peakTo, - double &valeUpper, - double &valeLower, - datetime &valeFrom, - datetime &valeTo // -) -{ - // - bool result = false; - - // - peakUpper = 0; - peakLower = 0; - valeUpper = 0; - valeLower = 0; - - // - peakFrom = NULL; - peakTo = NULL; - valeFrom = NULL; - valeTo = NULL; - - // - result = pivot.IsValid(); - if (!result) - { - return result; - } - - // - int count = 0; - - // - // - // - - // - // Resistance ... - count = pivot.state.CountResistanceZones(); - if (IsValidSize(count)) - { - // - XCResistanceZone *tmp[]; - Copy( - pivot.state.resistanceZones, - tmp // - ); - - // - for (int i = 0; i < count; i++) - { - // - XCResistanceZone *item = tmp[i]; - - // - if (peakUpper == 0 || - peakUpper < item.Upper()) - { - peakUpper = item.Upper(); - } - - // - if (peakLower == 0 || - peakLower > item.Lower()) - { - peakLower = item.Lower(); - } - - // - if (!IsValid(peakFrom) || - peakFrom > item.From()) - { - peakFrom = item.From(); - } - - // - if (!IsValid(peakTo) || - peakTo < item.To()) - { - peakTo = item.To(); - } - } - - // - Clean(tmp); - } - - // - // Supply ... - count = pivot.state.CountSupplyZones(); - if (IsValidSize(count)) - { - // - XCSupplyZone *tmp[]; - Copy( - pivot.state.supplyZones, - tmp // - ); - - // - for (int i = 0; i < count; i++) - { - // - XCSupplyZone *item = tmp[i]; - - // - if (peakUpper == 0 || - peakUpper < item.Upper()) - { - peakUpper = item.Upper(); - } - - // - if (peakLower == 0 || - peakLower > item.Lower()) - { - peakLower = item.Lower(); - } - - // - if (!IsValid(peakFrom) || - peakFrom > item.From()) - { - peakFrom = item.From(); - } - - // - if (!IsValid(peakTo) || - peakTo < item.To()) - { - peakTo = item.To(); - } - } - - // - Clean(tmp); - } - - // - // Bearish Order Block ... - count = pivot.state.CountBearishOrderBlocks(); - if (IsValidSize(count)) - { - // - XCOrderBlock *tmp[]; - Copy( - pivot.state.bearishOrderBlocks, - tmp // - ); - - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock *item = tmp[i]; - - // - if (peakUpper == 0 || - peakUpper < item.Upper()) - { - peakUpper = item.Upper(); - } - - // - if (peakLower == 0 || - peakLower > item.Lower()) - { - peakLower = item.Lower(); - } - - // - if (!IsValid(peakFrom) || - peakFrom > item.From()) - { - peakFrom = item.From(); - } - - // - if (!IsValid(peakTo) || - peakTo < item.To()) - { - peakTo = item.To(); - } - } - - // - Clean(tmp); - } - - // - // Bearish Fair Value Gap ... - count = pivot.state.CountBearishFairValueGaps(); - if (IsValidSize(count)) - { - // - XCFVG *tmp[]; - Copy( - pivot.state.bearishFairValueGaps, - tmp // - ); - - // - for (int i = 0; i < count; i++) - { - // - XCFVG *item = tmp[i]; - - // - if (peakUpper == 0 || - peakUpper < item.Upper()) - { - peakUpper = item.Upper(); - } - - // - if (peakLower == 0 || - peakLower > item.Lower()) - { - peakLower = item.Lower(); - } - - // - if (!IsValid(peakFrom) || - peakFrom > item.From()) - { - peakFrom = item.From(); - } - - // - if (!IsValid(peakTo) || - peakTo < item.To()) - { - peakTo = item.To(); - } - } - - // - Clean(tmp); - } - - // - // - // - - // - // Support ... - count = pivot.state.CountSupportZones(); - if (IsValidSize(count)) - { - // - XCSupportZone *tmp[]; - Copy( - pivot.state.supportZones, - tmp // - ); - - // - for (int i = 0; i < count; i++) - { - // - XCSupportZone *item = tmp[i]; - - // - if (valeUpper == 0 || - valeUpper < item.Upper()) - { - valeUpper = item.Upper(); - } - - // - if (valeLower == 0 || - valeLower > item.Lower()) - { - valeLower = item.Lower(); - } - - // - if (!IsValid(valeFrom) || - valeFrom > item.From()) - { - valeFrom = item.From(); - } - - // - if (!IsValid(valeTo) || - valeTo < item.To()) - { - valeTo = item.To(); - } - } - - // - Clean(tmp); - } - - // - // Demand ... - count = pivot.state.CountDemandZones(); - if (IsValidSize(count)) - { - // - XCDemandZone *tmp[]; - Copy( - pivot.state.demandZones, - tmp // - ); - - // - for (int i = 0; i < count; i++) - { - // - XCDemandZone *item = tmp[i]; - - // - if (valeUpper == 0 || - valeUpper < item.Upper()) - { - valeUpper = item.Upper(); - } - - // - if (valeLower == 0 || - valeLower > item.Lower()) - { - valeLower = item.Lower(); - } - - // - if (!IsValid(valeFrom) || - valeFrom > item.From()) - { - valeFrom = item.From(); - } - - // - if (!IsValid(valeTo) || - valeTo < item.To()) - { - valeTo = item.To(); - } - } - - // - Clean(tmp); - } - - // - // Bullish Order Block ... - count = pivot.state.CountBullishOrderBlocks(); - if (IsValidSize(count)) - { - // - XCOrderBlock *tmp[]; - Copy( - pivot.state.bullishOrderBlocks, - tmp // - ); - - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock *item = tmp[i]; - - // - if (valeUpper == 0 || - valeUpper < item.Upper()) - { - valeUpper = item.Upper(); - } - - // - if (valeLower == 0 || - valeLower > item.Lower()) - { - valeLower = item.Lower(); - } - - // - if (!IsValid(valeFrom) || - valeFrom > item.From()) - { - valeFrom = item.From(); - } - - // - if (!IsValid(valeTo) || - valeTo < item.To()) - { - valeTo = item.To(); - } - } - - // - Clean(tmp); - } - - // - // Bullish Fair Value Gap ... - count = pivot.state.CountBullishFairValueGaps(); - if (IsValidSize(count)) - { - // - XCFVG *tmp[]; - Copy( - pivot.state.bullishFairValueGaps, - tmp // - ); - - // - for (int i = 0; i < count; i++) - { - // - XCFVG *item = tmp[i]; - - // - if (valeUpper == 0 || - valeUpper < item.Upper()) - { - valeUpper = item.Upper(); - } - - // - if (valeLower == 0 || - valeLower > item.Lower()) - { - valeLower = item.Lower(); - } - - // - if (!IsValid(valeFrom) || - valeFrom > item.From()) - { - valeFrom = item.From(); - } - - // - if (!IsValid(valeTo) || - valeTo < item.To()) - { - valeTo = item.To(); - } - } - - // - Clean(tmp); - } - - // - result = peakUpper > 0 && - peakLower > 0 && - valeUpper > 0 && - valeLower > 0 && - IsValid(peakTo) && - IsValid(valeTo) && - IsValid(peakFrom) && - IsValid(valeFrom) && - peakTo > peakFrom && - valeTo > valeFrom && - peakUpper > peakLower && - valeUpper > valeLower; - - // - return result; -} - -/** - * Detect Price Inside Zones ... - * - * @param state: XPOIState instance Reference ... - * @param bar: XOHCL instance Reference ... - * @param hasSupport: Boolean ... - * @param hasResistanceZone: Boolean ... - * @param hasSupplyZone: Boolean ... - * @param hasDemandZone: Boolean ... - * @param hasOrderBlock: Boolean ... - * @param hasFairValueGap: Boolean ... - * @return ( bool ) - */ -bool DetectPriceInsideZones( - XPOIState &state, - XOHCL &bar, - int &zonesCount, - bool &hasSupportZone, - XCSupportZone *&supportZone, - bool &hasResistanceZone, - XCResistanceZone *&resistanceZone, - bool &hasSupplyZone, - XCSupplyZone *&supplyZone, - bool &hasDemandZone, - XCDemandZone *&demandZone, - bool &hasOrderBlock, - XCOrderBlock *&orderBlock, - bool &hasFairValueGap, - XCFVG *&fairValueGap // -) -{ - // - bool result = false; - - // - zonesCount = 0; - - // - hasSupportZone = false; - hasResistanceZone = false; - hasSupplyZone = false; - hasDemandZone = false; - hasOrderBlock = false; - hasFairValueGap = false; - - // - supportZone = NULL; - resistanceZone = NULL; - supplyZone = NULL; - demandZone = NULL; - orderBlock = NULL; - fairValueGap = NULL; - - // - datetime cTime = TimeCurrent(); - - // - result = bar.IsValid() && - state.IsValid() && - state.HasChild(); - if (!result) - { - return result; - } - - // - int count = 0; - - // - // Support Zone ... - count = state.CountSupportZones(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCSupportZone *iZone = state.supportZones[i]; - - // - bool isValid = IsPriceInsideZone(bar, iZone); - if (isValid) - { - // - supportZone = iZone; - } - } - - // - hasSupportZone = supportZone != NULL && - supportZone.IsValid(); - if (hasSupportZone) - { - // - zonesCount++; - supportZone.To(cTime); - } - } - - // - // Resistance Zone ... - count = state.CountResistanceZones(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCResistanceZone *iZone = state.resistanceZones[i]; - - // - bool isValid = IsPriceInsideZone(bar, iZone); - if (isValid) - { - // - resistanceZone = iZone; - } - } - - // - hasResistanceZone = resistanceZone != NULL && - resistanceZone.IsValid(); - if (hasResistanceZone) - { - // - zonesCount++; - resistanceZone.To(cTime); - } - } - - // - // Supply Zone ... - count = state.CountSupplyZones(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCSupplyZone *iZone = state.supplyZones[i]; - - // - bool isValid = IsPriceInsideZone(bar, iZone); - if (isValid) - { - // - supplyZone = iZone; - } - } - - // - hasSupplyZone = supplyZone != NULL && - supplyZone.IsValid(); - if (hasSupplyZone) - { - // - zonesCount++; - supplyZone.To(cTime); - } - } - - // - // Demand Zone ... - count = state.CountDemandZones(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCDemandZone *iZone = state.demandZones[i]; - - // - bool isValid = IsPriceInsideZone(bar, iZone); - if (isValid) - { - // - demandZone = iZone; - } - } - - // - hasDemandZone = demandZone != NULL && - demandZone.IsValid(); - if (hasDemandZone) - { - // - zonesCount++; - demandZone.To(cTime); - } - } - - // - // OrderBlock ... - count = state.CountBullishOrderBlocks(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCOrderBlock *iZone = state.bullishOrderBlocks[i]; - - // - bool isValid = IsPriceInsideZone(bar, iZone); - if (isValid) - { - // - orderBlock = iZone; - } - } - - // - hasOrderBlock = orderBlock != NULL && - orderBlock.IsValid(); - if (hasOrderBlock) - { - // - zonesCount++; - orderBlock.To(cTime); - } - } - if (!hasOrderBlock) - { - // - count = state.CountBearishOrderBlocks(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCOrderBlock *iZone = state.bearishOrderBlocks[i]; - - // - bool isValid = IsPriceInsideZone(bar, iZone); - if (isValid) - { - // - orderBlock = iZone; - } - } - - // - hasOrderBlock = orderBlock != NULL && - orderBlock.IsValid(); - if (hasOrderBlock) - { - // - zonesCount++; - orderBlock.To(cTime); - } - } - } - - // - // Fair Value Gap ... - count = state.CountBullishFairValueGaps(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCFVG *iZone = state.bullishFairValueGaps[i]; - - // - bool isValid = IsPriceInsideZone(bar, iZone); - if (isValid) - { - // - fairValueGap = iZone; - } - } - - // - hasFairValueGap = fairValueGap != NULL && - fairValueGap.IsValid(); - if (hasFairValueGap) - { - // - zonesCount++; - fairValueGap.To(cTime); - } - } - if (!hasFairValueGap) - { - // - count = state.CountBearishFairValueGaps(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCFVG *iZone = state.bearishFairValueGaps[i]; - - // - bool isValid = IsPriceInsideZone(bar, iZone); - if (isValid) - { - // - fairValueGap = iZone; - } - } - - // - hasFairValueGap = fairValueGap != NULL && - fairValueGap.IsValid(); - if (hasFairValueGap) - { - // - zonesCount++; - fairValueGap.To(cTime); - } - } - } - - // - result = - // - hasSupportZone || - hasResistanceZone || - hasSupplyZone || - hasDemandZone || - hasOrderBlock || - hasFairValueGap - // - ; - - // - return result; -} - -/** - * Detect Price Inside Zones ... - * - * @param state: XPOIState instance Reference ... - * @param price: Double ... - * @param hasSupport: Boolean ... - * @param hasResistanceZone: Boolean ... - * @param hasSupplyZone: Boolean ... - * @param hasDemandZone: Boolean ... - * @param hasOrderBlock: Boolean ... - * @param hasFairValueGap: Boolean ... - * @return ( bool ) - */ -bool DetectPriceInsideZones( - XPOIState &state, - double price, - int &zonesCount, - bool &hasSupportZone, - XCSupportZone *&supportZone, - bool &hasResistanceZone, - XCResistanceZone *&resistanceZone, - bool &hasSupplyZone, - XCSupplyZone *&supplyZone, - bool &hasDemandZone, - XCDemandZone *&demandZone, - bool &hasOrderBlock, - XCOrderBlock *&orderBlock, - bool &hasFairValueGap, - XCFVG *&fairValueGap // -) -{ - // - bool result = false; - - // - zonesCount = 0; - - // - hasSupportZone = false; - hasResistanceZone = false; - hasSupplyZone = false; - hasDemandZone = false; - hasOrderBlock = false; - hasFairValueGap = false; - - // - supportZone = NULL; - resistanceZone = NULL; - supplyZone = NULL; - demandZone = NULL; - orderBlock = NULL; - fairValueGap = NULL; - - // - datetime cTime = TimeCurrent(); - - // - result = price > 0 && - state.IsValid() && - state.HasChild(); - if (!result) - { - return result; - } - - // - int count = 0; - - // - // Support Zone ... - count = state.CountSupportZones(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCSupportZone *iZone = state.supportZones[i]; - - // - bool isValid = IsPriceInsideZone(price, iZone); - if (isValid) - { - // - supportZone = iZone; - } - } - - // - hasSupportZone = supportZone != NULL && - supportZone.IsValid(); - if (hasSupportZone) - { - // - zonesCount++; - supportZone.To(cTime); - } - } - - // - // Resistance Zone ... - count = state.CountResistanceZones(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCResistanceZone *iZone = state.resistanceZones[i]; - - // - bool isValid = IsPriceInsideZone(price, iZone); - if (isValid) - { - // - resistanceZone = iZone; - } - } - - // - hasResistanceZone = resistanceZone != NULL && - resistanceZone.IsValid(); - if (hasResistanceZone) - { - // - zonesCount++; - resistanceZone.To(cTime); - } - } - - // - // Supply Zone ... - count = state.CountSupplyZones(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCSupplyZone *iZone = state.supplyZones[i]; - - // - bool isValid = IsPriceInsideZone(price, iZone); - if (isValid) - { - // - supplyZone = iZone; - } - } - - // - hasSupplyZone = supplyZone != NULL && - supplyZone.IsValid(); - if (hasSupplyZone) - { - // - zonesCount++; - supplyZone.To(cTime); - } - } - - // - // Demand Zone ... - count = state.CountDemandZones(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCDemandZone *iZone = state.demandZones[i]; - - // - bool isValid = IsPriceInsideZone(price, iZone); - if (isValid) - { - // - demandZone = iZone; - } - } - - // - hasDemandZone = demandZone != NULL && - demandZone.IsValid(); - if (hasDemandZone) - { - // - zonesCount++; - demandZone.To(cTime); - } - } - - // - // OrderBlock ... - count = state.CountBullishOrderBlocks(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCOrderBlock *iZone = state.bullishOrderBlocks[i]; - - // - bool isValid = IsPriceInsideZone(price, iZone); - if (isValid) - { - // - orderBlock = iZone; - } - } - - // - hasOrderBlock = orderBlock != NULL && - orderBlock.IsValid(); - if (hasOrderBlock) - { - // - zonesCount++; - orderBlock.To(cTime); - } - } - if (!hasOrderBlock) - { - // - count = state.CountBearishOrderBlocks(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCOrderBlock *iZone = state.bearishOrderBlocks[i]; - - // - bool isValid = IsPriceInsideZone(price, iZone); - if (isValid) - { - // - orderBlock = iZone; - } - } - - // - hasOrderBlock = orderBlock != NULL && - orderBlock.IsValid(); - if (hasOrderBlock) - { - // - zonesCount++; - orderBlock.To(cTime); - } - } - } - - // - // Fair Value Gap ... - count = state.CountBullishFairValueGaps(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCFVG *iZone = state.bullishFairValueGaps[i]; - - // - bool isValid = IsPriceInsideZone(price, iZone); - if (isValid) - { - // - fairValueGap = iZone; - } - } - - // - hasFairValueGap = fairValueGap != NULL && - fairValueGap.IsValid(); - if (hasFairValueGap) - { - // - zonesCount++; - fairValueGap.To(cTime); - } - } - if (!hasFairValueGap) - { - // - count = state.CountBearishFairValueGaps(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCFVG *iZone = state.bearishFairValueGaps[i]; - - // - bool isValid = IsPriceInsideZone(price, iZone); - if (isValid) - { - // - fairValueGap = iZone; - } - } - - // - hasFairValueGap = fairValueGap != NULL && - fairValueGap.IsValid(); - if (hasFairValueGap) - { - // - zonesCount++; - fairValueGap.To(cTime); - } - } - } - - // - result = - // - hasSupportZone || - hasResistanceZone || - hasSupplyZone || - hasDemandZone || - hasOrderBlock || - hasFairValueGap - // - ; - - // - return result; -} - -bool CalculatePriceInsideZones( - XPriceZones &zone, - XPOIState &state, - double price // -) -{ - // - bool result = false; - - // - zone.Clean(); - - // - int zonesCount = 0; - bool hasSupplyZone = false; - bool hasDemandZone = false; - bool hasOrderBlock = false; - bool hasSupportZone = false; - bool hasFairValueGap = false; - bool hasResistanceZone = false; - - // - result = DetectPriceInsideZones( - state, - price, - zone.count, - hasSupportZone, - zone.supportZone, - hasResistanceZone, - zone.resistanceZone, - hasSupplyZone, - zone.supplyZone, - hasDemandZone, - zone.demandZone, - hasOrderBlock, - zone.orderBlock, - hasFairValueGap, - zone.fairValueGap // - ); - if (!result) - { - return result; - } - - // - zone.price = price; - - // - result = zone.IsValid(); - - // - return result; -} - -bool CalculatePriceInsideZones( - XPriceZones &zone, - XPOIState &state, - XOHCL &bar // -) -{ - // - bool result = false; - - // - zone.Clean(); - - // - int zonesCount = 0; - bool hasSupplyZone = false; - bool hasDemandZone = false; - bool hasOrderBlock = false; - bool hasSupportZone = false; - bool hasFairValueGap = false; - bool hasResistanceZone = false; - - // - result = DetectPriceInsideZones( - state, - bar, - zone.count, - hasSupportZone, - zone.supportZone, - hasResistanceZone, - zone.resistanceZone, - hasSupplyZone, - zone.supplyZone, - hasDemandZone, - zone.demandZone, - hasOrderBlock, - zone.orderBlock, - hasFairValueGap, - zone.fairValueGap // - ); - if (!result) - { - return result; - } - - // - zone.bar = bar; - - // - result = zone.IsValid(); - - // - return result; -} - -/** - * Calculate Zone by Providing Specified Data ... - * - * @param zones: XStateZone instance Reference ... - * @param source: XPOIState instance Reference ... - * @param upper: Double ... - * @param lower: Double ... - * @param from: DateTime ... - * - * @return ( bool ) - */ -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 ... - * - * @param item: XValueChange instance Reference ... - * @param items: XValueChange instance Array Reference ... - * - * @return ( int ) - */ -int AddIfNotExists( - XValueChange &item, - XValueChange &items[] // -) -{ - // - int result = 0; - - // - result = item.IsValid(); - if (!result) - { - return result; - } - - // - bool canAdd = false; - int count = ArraySize(items); - if (!IsValidSize(count)) - { - canAdd = true; - } - else - { - // - XValueChange last; - bool hasItem = GetLastItem( - last, - items // - ); - if (!hasItem) - { - canAdd = true; - } - else - { - // - // Compare Last Item with Current ... - canAdd = item.time > last.time; - } - } - - // - // Add Item if Allowed ... - if (canAdd) - { - // - AddRef( - item, - items // - ); - } - - // - result = ArraySize(items); - - // - return result; -} - /** * Combine a Collection of States into dest ... * @@ -10586,1415 +5690,388 @@ bool IsPriceInsideZone( return result; } -/** - * Calculate Target for Specified Direction ... - * - * @param bar: XOHCL instance Reference ... - * @param state: XPOIState instance Reference ... - * @param forDir: ENUM_S_DIRECTION member ... - * - * @return ( double ) - */ -double CalculateTarget( - XOHCL &bar, - XPOIState &state, - ENUM_X_DIRECTION forDir // -) -{ - // - double result = 0; - - // - if (!state.IsValid() || - !state.HasChild() || - !HasDirection(forDir)) - { - return result; - } - - // - XCFVG *iFVG = NULL; - XCOrderBlock *iOB = NULL; - XCSupplyZone *iSupply = NULL; - XCDemandZone *iDemand = NULL; - XCSupportZone *iSupport = NULL; - XCResistanceZone *iResistance = NULL; - - // - bool hasOB = false; - bool hasFVG = false; - bool hasSupply = false; - bool hasDemand = false; - bool hasSupport = false; - bool hasResistance = false; - - // - int count = 0; - - // - if (IsBearish(forDir)) - { - // - // FVG ... - count = state.CountBullishFairValueGaps(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCFVG *iZone = state.bullishFairValueGaps[i]; - - // - bool isValid = IsPriceAboveZone( - bar, - iZone // - ); - if (isValid) - { - // - iFVG = iZone; - hasFVG = true; - break; - } - } - } - - // - // OB ... - count = state.CountBullishOrderBlocks(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCOrderBlock *iZone = state.bullishOrderBlocks[i]; - - // - bool isValid = IsPriceAboveZone( - bar, - iZone // - ); - if (isValid) - { - // - iOB = iZone; - hasOB = true; - break; - } - } - } - - // - // SUPPORT ... - count = state.CountSupportZones(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCSupportZone *iZone = state.supportZones[i]; - - // - bool isValid = IsPriceAboveZone( - bar, - iZone // - ); - if (isValid) - { - // - iSupport = iZone; - hasSupport = true; - break; - } - } - } - - // - // DEMAND ... - count = state.CountDemandZones(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCDemandZone *iZone = state.demandZones[i]; - - // - bool isValid = IsPriceAboveZone( - bar, - iZone // - ); - if (isValid) - { - // - iDemand = iZone; - hasDemand = true; - break; - } - } - } - - // - // Summary ... - result = - hasFVG - ? iFVG.Upper() - : hasOB - ? iOB.Upper() - : hasSupport - ? iSupport.Upper() - : hasDemand - ? iDemand.Upper() - : 0; - if (hasFVG) - { - result = MathMax(result, iFVG.Upper()); - } - if (hasOB) - { - result = MathMax(result, iOB.Upper()); - } - if (hasSupport) - { - result = MathMax(result, iSupport.Upper()); - } - if (hasDemand) - { - result = MathMax(result, iDemand.Upper()); - } - } - - // - if (IsBullish(forDir)) - { - // - // FVG ... - count = state.CountBearishFairValueGaps(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCFVG *iZone = state.bearishFairValueGaps[i]; - - // - bool isValid = IsPriceBelowZone( - bar, - iZone // - ); - if (isValid) - { - // - iFVG = iZone; - hasFVG = true; - break; - } - } - } - - // - // OB ... - count = state.CountBearishOrderBlocks(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCOrderBlock *iZone = state.bearishOrderBlocks[i]; - - // - bool isValid = IsPriceBelowZone( - bar, - iZone // - ); - if (isValid) - { - // - iOB = iZone; - hasOB = true; - break; - } - } - } - - // - // RESISTANCE ... - count = state.CountResistanceZones(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCResistanceZone *iZone = state.resistanceZones[i]; - - // - bool isValid = IsPriceBelowZone( - bar, - iZone // - ); - if (isValid) - { - // - iResistance = iZone; - hasResistance = true; - break; - } - } - } - - // - // SUPPLY ... - count = state.CountSupplyZones(); - if (IsValidSize(count)) - { - // - for (int i = count - 1; i >= 0; i--) - { - // - XCSupplyZone *iZone = state.supplyZones[i]; - - // - bool isValid = IsPriceBelowZone( - bar, - iZone // - ); - if (isValid) - { - // - iSupply = iZone; - hasSupply = true; - break; - } - } - } - - // - // Summary ... - result = - hasFVG - ? iFVG.Lower() - : hasOB - ? iOB.Lower() - : hasSupport - ? iSupport.Lower() - : hasDemand - ? iDemand.Lower() - : 0; - if (hasFVG) - { - result = MathMin(result, iFVG.Lower()); - } - if (hasOB) - { - result = MathMin(result, iOB.Lower()); - } - if (hasSupport) - { - result = MathMin(result, iSupport.Lower()); - } - if (hasDemand) - { - result = MathMin(result, iDemand.Lower()); - } - } - - // - return result; -} - -/** - * Detect Valid Order Blocks ... - * - * @param forDir: ENUM_X_DIRECTION member ... - * @param source: XPOIState instance Reference ... - * - * @return ( int ) - */ -int DetectValidOrderBlocks( - ENUM_X_DIRECTION forDir, - XPOIState &source, - XCOrderBlock *&orderBlocks[] // -) -{ - // - int result = 0; - - // - Clean(orderBlocks); - - // - bool isValid = - // - source.IsValid() && - source.HasChild() && - HasDirection(forDir) - // - ; - if (!isValid) - { - return result; - } - - // - datetime cTime = TimeCurrent(); - - // - XOHCL cBar; - bool isInited = cBar.Init( - source.symbol, - source.period, - 1 // - ); - if (!isInited) - { - return result; - } - - // - int count = 0; - - // - // Bullish ... - count = source.CountBullishOrderBlocks(); - isValid = IsValidSize(count) && - IsBullish(forDir); - if (isValid) - { - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock *iOB = source.bullishOrderBlocks[i]; - - // - // Update Order Block Time ... - iOB.To(cTime); - - // - // Check Order Block Validation ... - isValid = IsValid( - forDir, - cBar.symbol, - cBar.period, - iOB.Upper(), - iOB.Lower(), - iOB.From(), - iOB.To() // - ); - if (isValid) - { - // - Add( - iOB, - orderBlocks // - ); - } - } - } - - // - // Bearish ... - count = source.CountBearishOrderBlocks(); - isValid = IsValidSize(count) && - IsBearish(forDir); - if (isValid) - { - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock *iOB = source.bearishOrderBlocks[i]; - - // - // Update Order Block Time ... - iOB.To(cTime); - - // - // Check Order Block Validation ... - isValid = IsValid( - forDir, - cBar.symbol, - cBar.period, - iOB.Upper(), - iOB.Lower(), - iOB.From(), - iOB.To() // - ); - if (isValid) - { - // - Add( - iOB, - orderBlocks // - ); - } - } - } - - // - result = ArraySize(orderBlocks); - - // - return result; -} - -/** - * Detect Valid Fair Value Gaps ... - * - * @param forDir: ENUM_X_DIRECTION member ... - * @param source: XPOIState instance Reference ... - * - * @return ( int ) - */ -int DetectValidFairValueGaps( - ENUM_X_DIRECTION forDir, - XPOIState &source, - XCFVG *&fairValueGaps[] // -) -{ - // - int result = 0; - - // - Clean(fairValueGaps); - - // - bool isValid = - // - source.IsValid() && - source.HasChild() && - HasDirection(forDir) - // - ; - if (!isValid) - { - return result; - } - - // - datetime cTime = TimeCurrent(); - - // - XOHCL cBar; - bool isInited = cBar.Init( - source.symbol, - source.period, - 1 // - ); - if (!isInited) - { - return result; - } - - // - int count = 0; - - // - // Bullish ... - count = source.CountBullishFairValueGaps(); - isValid = IsValidSize(count) && - IsBullish(forDir); - if (isValid) - { - // - for (int i = 0; i < count; i++) - { - // - XCFVG *iFVG = source.bullishFairValueGaps[i]; - - // - // Update FVG Time ... - iFVG.To(cTime); - - // - // Check FVG Validation ... - isValid = IsValid( - forDir, - cBar.symbol, - cBar.period, - iFVG.Upper(), - iFVG.Lower(), - iFVG.From(), - iFVG.To() // - ); - if (isValid) - { - // - Add( - iFVG, - fairValueGaps // - ); - } - } - } - - // - // Bearish ... - count = source.CountBearishFairValueGaps(); - isValid = IsValidSize(count) && - IsBearish(forDir); - if (isValid) - { - // - for (int i = 0; i < count; i++) - { - // - XCFVG *iFVG = source.bearishFairValueGaps[i]; - - // - // Update Order Block Time ... - iFVG.To(cTime); - - // - // Check Order Block Validation ... - isValid = IsValid( - forDir, - cBar.symbol, - cBar.period, - iFVG.Upper(), - iFVG.Lower(), - iFVG.From(), - iFVG.To() // - ); - if (isValid) - { - // - Add( - iFVG, - fairValueGaps // - ); - } - } - } - - // - result = ArraySize(fairValueGaps); - - // - return result; -} - -/** - * Detect Valid Support Zones ... - * - * @param source: XPOIState instance ... - * - * @return ( int ) - */ -int DetectValidSupportZones( - XPOIState &source, - XCOrderBlock *&bullishOrderBlocks[], - XCFVG *&bullishFairValueGaps[], - XCSupportZone *&supportZones[] // -) -{ - // - int result = 0; - - // - Clean(supportZones); - - // - int obsCount = ArraySize(bullishOrderBlocks); - int fvgsCount = ArraySize(bullishFairValueGaps); - - // - bool isValid = - // - source.IsValid() && - source.HasChild() && - IsValidSize(obsCount + fvgsCount) - // - ; - if (!isValid) - { - return result; - } - - // - int count = source.CountSupportZones(); - for (int i = 0; i < count; i++) - { - // - XCSupportZone *iZone = source.supportZones[i]; - - // - bool isAdded = false; - - // - for (int j = 0; j < obsCount; j++) - { - // - XCOrderBlock *iOB = bullishOrderBlocks[j]; - - // - bool isValid = - // - IsPriceInsideZone( - iZone.Upper(), - iOB.Upper(), - iOB.Lower() // - ) - // - || - // - IsPriceInsideZone( - iZone.Lower(), - iOB.Upper(), - iOB.Lower() // - ) - // - ; - if (isValid) - { - // - Add( - iZone, - supportZones // - ); - - // - isAdded = true; - break; - } - } - - // - if (isAdded) - { - continue; - } - - // - for (int j = 0; j < fvgsCount; j++) - { - // - XCFVG *iFVG = bullishFairValueGaps[j]; - - // - bool isValid = - // - IsPriceInsideZone( - iZone.Upper(), - iFVG.Upper(), - iFVG.Lower() // - ) - // - || - // - IsPriceInsideZone( - iZone.Lower(), - iFVG.Upper(), - iFVG.Lower() // - ) - // - ; - if (isValid) - { - // - Add( - iZone, - supportZones // - ); - - // - isAdded = true; - break; - } - } - } - - // - result = ArraySize(supportZones); - - // - return result; -} - -/** - * Detect Valid Resistance Zones ... - * - * @param source: XPOIState instance ... - * - * @return ( int ) - */ -int DetectValidResistanceZones( - XPOIState &source, - XCOrderBlock *&bearishOrderBlocks[], - XCFVG *&bearishFairValueGaps[], - XCResistanceZone *&resistanceZones[] // -) -{ - // - int result = 0; - - // - Clean(resistanceZones); - - // - int obsCount = ArraySize(bearishOrderBlocks); - int fvgsCount = ArraySize(bearishFairValueGaps); - - // - bool isValid = - // - source.IsValid() && - source.HasChild() && - IsValidSize(obsCount + fvgsCount) - // - ; - if (!isValid) - { - return result; - } - - // - int count = source.CountResistanceZones(); - for (int i = 0; i < count; i++) - { - // - XCResistanceZone *iZone = source.resistanceZones[i]; - - // - bool isAdded = false; - - // - for (int j = 0; j < obsCount; j++) - { - // - XCOrderBlock *iOB = bearishOrderBlocks[j]; - - // - bool isValid = - // - IsPriceInsideZone( - iZone.Upper(), - iOB.Upper(), - iOB.Lower() // - ) - // - || - // - IsPriceInsideZone( - iZone.Lower(), - iOB.Upper(), - iOB.Lower() // - ) - // - ; - if (isValid) - { - // - Add( - iZone, - resistanceZones // - ); - - // - isAdded = true; - break; - } - } - - // - if (isAdded) - { - continue; - } - - // - for (int j = 0; j < fvgsCount; j++) - { - // - XCFVG *iFVG = bearishFairValueGaps[j]; - - // - bool isValid = - // - IsPriceInsideZone( - iZone.Upper(), - iFVG.Upper(), - iFVG.Lower() // - ) - // - || - // - IsPriceInsideZone( - iZone.Lower(), - iFVG.Upper(), - iFVG.Lower() // - ) - // - ; - if (isValid) - { - // - Add( - iZone, - resistanceZones // - ); - - // - isAdded = true; - break; - } - } - } - - // - result = ArraySize(resistanceZones); - - // - return result; -} - -/** - * Detect Valid Support Zones ... - * - * @param source: XPOIState instance ... - * - * @return ( int ) - */ -int DetectValidDemandZones( - XPOIState &source, - XCOrderBlock *&bullishOrderBlocks[], - XCFVG *&bullishFairValueGaps[], - XCDemandZone *&demandZones[] // -) -{ - // - int result = 0; - - // - Clean(demandZones); - - // - int obsCount = ArraySize(bullishOrderBlocks); - int fvgsCount = ArraySize(bullishFairValueGaps); - - // - bool isValid = - // - source.IsValid() && - source.HasChild() && - IsValidSize(obsCount + fvgsCount) - // - ; - if (!isValid) - { - return result; - } - - // - int count = source.CountDemandZones(); - for (int i = 0; i < count; i++) - { - // - XCDemandZone *iZone = source.demandZones[i]; - - // - bool isAdded = false; - - // - for (int j = 0; j < obsCount; j++) - { - // - XCOrderBlock *iOB = bullishOrderBlocks[j]; - - // - bool isValid = - // - IsPriceInsideZone( - iZone.Upper(), - iOB.Upper(), - iOB.Lower() // - ) - // - || - // - IsPriceInsideZone( - iZone.Lower(), - iOB.Upper(), - iOB.Lower() // - ) - // - ; - if (isValid) - { - // - Add( - iZone, - demandZones // - ); - - // - isAdded = true; - break; - } - } - - // - if (isAdded) - { - continue; - } - - // - for (int j = 0; j < fvgsCount; j++) - { - // - XCFVG *iFVG = bullishFairValueGaps[j]; - - // - bool isValid = - // - IsPriceInsideZone( - iZone.Upper(), - iFVG.Upper(), - iFVG.Lower() // - ) - // - || - // - IsPriceInsideZone( - iZone.Lower(), - iFVG.Upper(), - iFVG.Lower() // - ) - // - ; - if (isValid) - { - // - Add( - iZone, - demandZones // - ); - - // - isAdded = true; - break; - } - } - } - - // - result = ArraySize(demandZones); - - // - return result; -} - -/** - * Detect Valid Resistance Zones ... - * - * @param source: XPOIState instance ... - * - * @return ( int ) - */ -int DetectValidSupplyZones( - XPOIState &source, - XCOrderBlock *&bearishOrderBlocks[], - XCFVG *&bearishFairValueGaps[], - XCSupplyZone *&supplyZones[] // -) -{ - // - int result = 0; - - // - Clean(supplyZones); - - // - int obsCount = ArraySize(bearishOrderBlocks); - int fvgsCount = ArraySize(bearishFairValueGaps); - - // - bool isValid = - // - source.IsValid() && - source.HasChild() && - IsValidSize(obsCount + fvgsCount) - // - ; - if (!isValid) - { - return result; - } - - // - int count = source.CountSupplyZones(); - for (int i = 0; i < count; i++) - { - // - XCSupplyZone *iZone = source.supplyZones[i]; - - // - bool isAdded = false; - - // - for (int j = 0; j < obsCount; j++) - { - // - XCOrderBlock *iOB = bearishOrderBlocks[j]; - - // - bool isValid = - // - IsPriceInsideZone( - iZone.Upper(), - iOB.Upper(), - iOB.Lower() // - ) - // - || - // - IsPriceInsideZone( - iZone.Lower(), - iOB.Upper(), - iOB.Lower() // - ) - // - ; - if (isValid) - { - // - Add( - iZone, - supplyZones // - ); - - // - isAdded = true; - break; - } - } - - // - if (isAdded) - { - continue; - } - - // - for (int j = 0; j < fvgsCount; j++) - { - // - XCFVG *iFVG = bearishFairValueGaps[j]; - - // - bool isValid = - // - IsPriceInsideZone( - iZone.Upper(), - iFVG.Upper(), - iFVG.Lower() // - ) - // - || - // - IsPriceInsideZone( - iZone.Lower(), - iFVG.Upper(), - iFVG.Lower() // - ) - // - ; - if (isValid) - { - // - Add( - iZone, - supplyZones // - ); - - // - isAdded = true; - break; - } - } - } - - // - result = ArraySize(supplyZones); - - // - return result; -} - -/** - * Detect a Zone Breaker Bar ... - * - * @param toBar: XOHCL instance Reference ... - * @param fromBar: XOHCL instance Reference ... - * @param breakerBar: XOHCL instance Reference ... - * @param forDir: ENUM_X_DIRECTION member ... - * @param symbol: String ... - * @param period: ENUM_TIMEFRAMES member ... - * - * @return ( bool ) - */ -bool HasBreakerBar( - XOHCL &toBar, - XOHCL &fromBar, - XOHCL &breakerBar, - ENUM_X_DIRECTION forDir, - string symbol, - ENUM_TIMEFRAMES period, - double upper, - double lower, - datetime from, - datetime to // +template +bool ToZone( + T *&source[], + XCZone *&dest[] // ) { // bool result = false; // - toBar.Clean(); - fromBar.Clean(); - breakerBar.Clean(); + Clean(dest); // - result = - // - upper > 0 && - lower > 0 && - IsValid(to) && - upper > lower && - IsValid(from) && - IsValid(symbol) && - IsValid(period) && - HasDirection(forDir) - // - ; + int count = ArraySize(source); + result = IsValidSize(count); if (!result) { return result; } // - result = fromBar.Init( - symbol, - period, - from // - ); - if (!result) - { - return result; - } - - // - result = toBar.Init( - symbol, - period, - to // - ); - if (!result) - { - return result; - } - - // - int toIndex = toBar.Index(); - int fromIndex = fromBar.Index(); - - // - // Detect Zone BreakerBar ... - for (int i = fromIndex; i >= toIndex; i--) + for (int i = 0; i < count; i++) { // - XOHCL iBar; - result = iBar.Init( - symbol, - period, - i // - ); + T *item = source[i]; // - if (!result) - { - continue; - } - - // - result = - // - IsBullish(forDir) - ? - // - iBar.low < upper && - iBar.high > upper && - iBar.GetUp() > upper - // - : - // - iBar.high > lower && - iBar.low < lower && - iBar.GetDown() < lower - // - ; - if (result) + if (item != NULL) { // - breakerBar = iBar; - break; + Add( + (XCZone *)item, + dest // + ); } } // - result = breakerBar.IsValid(); + int destCount = ArraySize(dest); + result = IsValidSize(destCount); // return result; } -/** - * Validate Specified Order Block ... - * - * @param forDir: ENUM_X_DIRECTION member ... - * @param symbol: String ... - * @param period: ENUM_TIMEFRAMES member ... - * - * @return ( bool ) - */ -bool IsValid( - ENUM_X_DIRECTION forDir, - string symbol, - ENUM_TIMEFRAMES period, - double upper, - double lower, - datetime from, - datetime to, - bool ignoreBreakerBar = false // +template +bool ToBox( + T *&source[], + XBoxZone &dest[] // ) { // bool result = false; // - result = - upper > 0 && - lower > 0 && - IsValid(to) && - upper > lower && - IsValid(from) && - IsValid(symbol) && - IsValid(period) && - HasDirection(forDir) - // - ; + Clean(dest); + + // + int count = ArraySize(source); + result = IsValidSize(count); if (!result) { return result; } // - XOHCL toBar; - XOHCL fromBar; - XOHCL breakerBar; - - // - if (!ignoreBreakerBar) + for (int i = 0; i < count; i++) { // - result = HasBreakerBar( - toBar, - fromBar, - breakerBar, - forDir, - symbol, - period, - upper, - lower, - from, - to // - ); - if (!result) + T *item = source[i]; + + // + if (item != NULL) { - return result; - } - } - else - { - // - result = toBar.Init( - symbol, - period, - to // - ); - if (!result) - { - return result; - } - - // - result = fromBar.Init( - symbol, - period, - from // - ); - if (!result) - { - return result; - } - - // - breakerBar = fromBar; - } - - // - int toIndex = toBar.Index(); - int fromIndex = fromBar.Index(); - int breakerIndex = breakerBar.Index(); - - // - bool isBreaked = false; - for (int i = breakerIndex - 1; i >= toIndex; i--) - { - // - XOHCL iBar; - result = iBar.Init( - fromBar.symbol, - fromBar.period, - i // - ); - - // - if (!result) - { - continue; - } - - // - isBreaked = // - IsBullish(forDir) - // - ? - // - iBar.low < upper - // - : - // - iBar.high > lower + XBoxZone iBox; + bool hasBox = ToBox( + iBox, + item // + ); + // - ; - if (isBreaked) - { - break; + if (hasBox) + { + // + AddRef( + iBox, + dest // + ); + } } } // - result = !isBreaked; + int destCount = ArraySize(dest); + result = IsValidSize(destCount); + + // + return result; +} + +/** + * Converts a Consolidation Zone ... + * + * @param zone: XConsolidationZone instance Reference ... + * @param dest: XCZone pointer Reference ... + * + * @return ( bool ) + */ +bool ToZone( + XConsolidationZone &zone, + XCZone *&dest // +) +{ + // + bool result = false; + + // + dest = NULL; + + // + result = zone.IsValid(); + if (!result) + { + return result; + } + + // + dest = new XCZone(); + dest.Upper(zone.upper); + dest.Lower(zone.lower); + result = dest.IsValidBoundary(); + + // + return result; +} + +/** + * Converts to XBoxZone ... + * + * @return ( bool ) + */ +bool ToBox( + XBoxZone &box, + XCOrderBlock *item // +) +{ + // + bool result = false; + + // + box.Clean(); + + // + result = item != NULL && + item.IsValid(); + if (!result) + { + return result; + } + + // + box.to = item.To(); + box.from = item.From(); + box.upper = item.Upper(); + box.lower = item.Lower(); + box.symbol = item.GetSymbol(); + box.period = item.GetPeriod(); + box.type = item.TypeAsString(); + box.dir = item.IsBullish() + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + result = box.IsValid(); + + // + return result; +} + +/** + * Converts to XBoxZone ... + * + * @return ( bool ) + */ +bool ToBox( + XBoxZone &box, + XCFVG *item // +) +{ + // + bool result = false; + + // + box.Clean(); + + // + result = item != NULL && + item.IsValid(); + if (!result) + { + return result; + } + + // + box.to = item.To(); + box.from = item.From(); + box.upper = item.Upper(); + box.lower = item.Lower(); + box.symbol = item.GetSymbol(); + box.period = item.GetPeriod(); + box.type = item.TypeAsString(); + box.dir = item.IsBullish() + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + result = box.IsValid(); + + // + return result; +} + +/** + * Converts to XBoxZone ... + * + * @return ( bool ) + */ +bool ToBox( + XBoxZone &box, + XCSupportZone *item // +) +{ + // + bool result = false; + + // + box.Clean(); + + // + result = item != NULL && + item.IsValid(); + if (!result) + { + return result; + } + + // + box.to = item.To(); + box.from = item.From(); + box.upper = item.Upper(); + box.lower = item.Lower(); + box.symbol = item.GetSymbol(); + box.period = item.GetPeriod(); + box.type = item.TypeAsString(); + box.dir = X_DIRECTION_BULLISH; + + // + result = box.IsValid(); + + // + return result; +} + +/** + * Converts to XBoxZone ... + * + * @return ( bool ) + */ +bool ToBox( + XBoxZone &box, + XCResistanceZone *item // +) +{ + // + bool result = false; + + // + box.Clean(); + + // + result = item != NULL && + item.IsValid(); + if (!result) + { + return result; + } + + // + box.to = item.To(); + box.from = item.From(); + box.upper = item.Upper(); + box.lower = item.Lower(); + box.symbol = item.GetSymbol(); + box.period = item.GetPeriod(); + box.type = item.TypeAsString(); + box.dir = X_DIRECTION_BEARISH; + + // + result = box.IsValid(); + + // + return result; +} + +/** + * Converts to XBoxZone ... + * + * @return ( bool ) + */ +bool ToBox( + XBoxZone &box, + XCSupplyZone *item // +) +{ + // + bool result = false; + + // + box.Clean(); + + // + result = item != NULL && + item.IsValid(); + if (!result) + { + return result; + } + + // + box.to = item.To(); + box.from = item.From(); + box.upper = item.Upper(); + box.lower = item.Lower(); + box.symbol = item.GetSymbol(); + box.period = item.GetPeriod(); + box.type = item.TypeAsString(); + box.dir = X_DIRECTION_BEARISH; + + // + result = box.IsValid(); + + // + return result; +} + +/** + * Converts to XBoxZone ... + * + * @return ( bool ) + */ +bool ToBox( + XBoxZone &box, + XCDemandZone *item // +) +{ + // + bool result = false; + + // + box.Clean(); + + // + result = item != NULL && + item.IsValid(); + if (!result) + { + return result; + } + + // + box.to = item.To(); + box.from = item.From(); + box.upper = item.Upper(); + box.lower = item.Lower(); + box.symbol = item.GetSymbol(); + box.period = item.GetPeriod(); + box.type = item.TypeAsString(); + box.dir = X_DIRECTION_BULLISH; + + // + result = box.IsValid(); // return result; @@ -12086,46 +6163,91 @@ int GetYoungest( return result; } -template -bool ToZone( - T *&source[], - XCZone *&dest[] // +/** + * Get Oldest Box Index ... + * + * @param source: XBoxZone instance Reference Collection ... + * + * @return ( int ) + */ +int GetOldest( + XBoxZone &source[] // ) { // - bool result = false; - - // - Clean(dest); + int result = -1; // int count = ArraySize(source); - result = IsValidSize(count); - if (!result) + if (!IsValidSize(count)) { return result; } // + XBoxZone selected; for (int i = 0; i < count; i++) { // - T *item = source[i]; + XBoxZone iBox = source[i]; // - if (item != NULL) + bool canSet = + !selected.IsValid() + ? true + : selected.from > iBox.from; + if (canSet) { // - Add( - (XCZone *)item, - dest // - ); + result = i; + selected = iBox; } } // - int destCount = ArraySize(dest); - result = IsValidSize(destCount); + return result; +} + +/** + * Get Youngest Box Index ... + * + * @param source: XBoxZone instance Reference Collection ... + * + * @return ( int ) + */ +int GetYoungest( + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XBoxZone selected; + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = source[i]; + + // + bool canSet = + !selected.IsValid() + ? true + : selected.from < iBox.from; + if (canSet) + { + // + result = i; + selected = iBox; + } + } // return result; diff --git a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 index 666405e5..c9cc5ee2 100644 --- a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 @@ -376,937 +376,6 @@ class XC121SMCCycleHelper : public XCBase return result; } - /** - * Detect Market Structure Method 2 ... - * - * @param model: XMarketStructure instance Reference ... - * - * @return ( bool ) - */ - bool DetectMarketStructure( - ENUM_X_DIRECTION &dir, - int pivotsCount = 3 // - ) - { - // - bool result = false; - - // - int barIndex = 0; - - // - if (pivotsCount < 3) - { - pivotsCount = 3; - } - - // - dir = X_DIRECTION_NONE; - string symbol = GetSymbol(); - ENUM_TIMEFRAMES period = GetPeriod(); - - // - int hpIndex = -1; - int hpIndexes[]; - double hpValues[]; - - // - int lvIndex = -1; - int lvIndexes[]; - double lvValues[]; - - // - for (int i = 0; i < pivotsCount; i++) - { - // - hpIndex = barIndex; - lvIndex = barIndex; - - // - double lastHP = 0; - double lastLV = 0; - - // - int hpCount = ArraySize(hpIndexes); - int lvCount = ArraySize(lvIndexes); - - // - if (IsValidSize(hpCount)) - { - // - lastHP = hpValues[hpCount - 1]; - hpIndex = hpIndexes[hpCount - 1]; - } - - // - if (IsValidSize(lvCount)) - { - // - lastLV = lvValues[lvCount - 1]; - lvIndex = lvIndexes[lvCount - 1]; - } - - // - if (lastHP == 0) - { - // - lastHP = mX121Helper - .xpvHelper - .GetPeak(hpIndex); - } - - // - if (lastLV == 0) - { - // - lastLV = mX121Helper - .xpvHelper - .GetVale(lvIndex); - } - - // - int highestPeakIndex = -1; - double highesrPeak = - mX121Helper - .xpvHelper - .GetHigherPeak( - highestPeakIndex, - lastHP, - hpIndex // - ); - if (IsValidIndex(highestPeakIndex)) - { - // - Add( - highestPeakIndex, - hpIndexes // - ); - - // - Add( - highesrPeak, - hpValues // - ); - } - - // - int lowestValeIndex = -1; - double lowestVale = - mX121Helper - .xpvHelper - .GetLowerVale( - lowestValeIndex, - lastLV, - lvIndex // - ); - if (IsValidIndex(lowestValeIndex)) - { - // - Add( - lowestValeIndex, - lvIndexes // - ); - - // - Add( - lowestVale, - lvValues // - ); - } - - // - bool canBreak = ArraySize(hpIndexes) >= pivotsCount || - ArraySize(lvIndexes) >= pivotsCount; - if (canBreak) - { - break; - } - } - - // - ArrayReverse(hpValues); - ArrayReverse(hpIndexes); - int countHPs = ArraySize(hpIndexes); - - // - ArrayReverse(lvValues); - ArrayReverse(lvIndexes); - int countLVs = ArraySize(lvIndexes); - - // - bool isValidHPs = countHPs >= pivotsCount; - bool isValidLVs = countLVs >= pivotsCount; - - // - result = isValidHPs || - isValidLVs; - if (!result) - { - return result; - } - - // - if (isValidHPs && isValidLVs) - { - // - hpIndex = hpIndexes[countHPs - 1]; - lvIndex = lvIndexes[countLVs - 1]; - } - - // - dir = - !isValidHPs && isValidLVs - ? X_DIRECTION_BULLISH - : !isValidLVs && isValidHPs - ? X_DIRECTION_BEARISH - : hpIndex < lvIndex - ? X_DIRECTION_BEARISH - : lvIndex < hpIndex - ? X_DIRECTION_BULLISH - : X_DIRECTION_ALL; - - // - return result; - } - - /** - * Detect Order Blocks ... - * - * @return ( bool ) - */ - bool DetectOrderBlocks( - XCOrderBlock *&bullishOrderBlocks[], - XCOrderBlock *&bearishOrderBlocks[] // - ) - { - // - bool result = false; - - // - Clean(bullishOrderBlocks); - Clean(bearishOrderBlocks); - - // - XPOIState state; - mPOIDetector.GetState(state); - bool isValid = state.IsValid() && - state.HasChild(); - if (!isValid) - { - return result; - } - - // - int bullOBsCount = DetectValidOrderBlocks( - X_DIRECTION_BULLISH, - state, - bullishOrderBlocks // - ); - - // - int bearOBsCount = DetectValidOrderBlocks( - X_DIRECTION_BEARISH, - state, - bearishOrderBlocks // - ); - - // - result = IsValidSize(bullOBsCount + - bearOBsCount); - - // - return result; - } - - /** - * Detect Fair Value Gaps ... - * - * @return ( bool ) - */ - bool DetectFairValueGaps( - XCFVG *&bullishFairValueGaps[], - XCFVG *&bearishFairValueGaps[] // - ) - { - // - bool result = false; - - // - Clean(bullishFairValueGaps); - Clean(bearishFairValueGaps); - - // - XPOIState state; - mPOIDetector.GetState(state); - bool isValid = state.IsValid() && - state.HasChild(); - if (!isValid) - { - return result; - } - - // - int bullFVGsCount = DetectValidFairValueGaps( - X_DIRECTION_BULLISH, - state, - bullishFairValueGaps // - ); - - // - int bearFVGsCount = DetectValidFairValueGaps( - X_DIRECTION_BEARISH, - state, - bearishFairValueGaps // - ); - - // - result = IsValidSize(bullFVGsCount + - bearFVGsCount); - - // - return result; - } - - /** - * Detect Support Zones ... - * - * @return ( bool ) - */ - bool DetectSupportZones( - XCOrderBlock *&bullishOrderBlocks[], - XCFVG *&bullishFairValueGaps[], - XCSupportZone *&supportZones[] // - ) - { - // - bool result = false; - - // - Clean(supportZones); - - // - int obsCount = ArraySize(bullishOrderBlocks); - int fvgsCount = ArraySize(bullishFairValueGaps); - - // - XPOIState state; - mPOIDetector.GetState(state); - bool isValid = state.IsValid() && - state.HasChild() && - IsValidSize(obsCount + fvgsCount); - if (!isValid) - { - return result; - } - - // - int supportZonesCount = DetectValidSupportZones( - state, - bullishOrderBlocks, - bullishFairValueGaps, - supportZones // - ); - - // - result = IsValidSize(supportZonesCount); - - // - return result; - } - - /** - * Detect Resistance Zones ... - * - * @return ( bool ) - */ - bool DetectResistanceZones( - XCOrderBlock *&bearishOrderBlocks[], - XCFVG *&bearishFairValueGaps[], - XCResistanceZone *&resistanceZones[] // - ) - { - // - bool result = false; - - // - Clean(resistanceZones); - - // - int obsCount = ArraySize(bearishOrderBlocks); - int fvgsCount = ArraySize(bearishFairValueGaps); - - // - XPOIState state; - mPOIDetector.GetState(state); - bool isValid = state.IsValid() && - state.HasChild() && - IsValidSize(obsCount + fvgsCount); - if (!isValid) - { - return result; - } - - // - int resistanceZonesCount = DetectValidResistanceZones( - state, - bearishOrderBlocks, - bearishFairValueGaps, - resistanceZones // - ); - - // - result = IsValidSize(resistanceZonesCount); - - // - return result; - } - - /** - * Detect Demand Zones ... - * - * @return ( bool ) - */ - bool DetectDemandZones( - XCOrderBlock *&bullishOrderBlocks[], - XCFVG *&bullishFairValueGaps[], - XCDemandZone *&demandZones[] // - ) - { - // - bool result = false; - - // - Clean(demandZones); - - // - int obsCount = ArraySize(bullishOrderBlocks); - int fvgsCount = ArraySize(bullishFairValueGaps); - - // - XPOIState state; - mPOIDetector.GetState(state); - bool isValid = state.IsValid() && - state.HasChild() && - IsValidSize(obsCount + fvgsCount); - if (!isValid) - { - return result; - } - - // - int demandZonesCount = DetectValidDemandZones( - state, - bullishOrderBlocks, - bullishFairValueGaps, - demandZones // - ); - - // - result = IsValidSize(demandZonesCount); - - // - return result; - } - - /** - * Detect Supply Zones ... - * - * @return ( bool ) - */ - bool DetectSupplyZones( - XCOrderBlock *&bearishOrderBlocks[], - XCFVG *&bearishFairValueGaps[], - XCSupplyZone *&supplyZones[] // - ) - { - // - bool result = false; - - // - Clean(supplyZones); - - // - int obsCount = ArraySize(bearishOrderBlocks); - int fvgsCount = ArraySize(bearishFairValueGaps); - - // - XPOIState state; - mPOIDetector.GetState(state); - bool isValid = state.IsValid() && - state.HasChild() && - IsValidSize(obsCount + fvgsCount); - if (!isValid) - { - return result; - } - - // - int supplyZonesCount = DetectValidSupplyZones( - state, - bearishOrderBlocks, - bearishFairValueGaps, - supplyZones // - ); - - // - result = IsValidSize(supplyZonesCount); - - // - return result; - } - - /** - * Count Prev Peak Repetition ... - * - * @param barIndex: Integer ... - * - * @return ( int ) - */ - int CountPrevPeakRepetition( - int barIndex = 0// - ) { - // - int result = 0; - - // - if (barIndex < 0) { - barIndex = 0; - } - - // - int index = barIndex + 1; - double value = mX121Helper.xpvHelper.GetPeak(index); - index++; - - // - bool canContinue = true; - while(canContinue) { - // - double iValue = mX121Helper.xpvHelper.GetPeak(index); - - // - canContinue = iValue == value; - if (canContinue) { - // - index++; - result++; - } - } - - // - return result; - } - - /** - * Count Prev Vale Repetition ... - * - * @param barIndex: Integer ... - * - * @return ( int ) - */ - int CountPrevValeRepetition( - int barIndex = 0// - ) { - // - int result = 0; - - // - if (barIndex < 0) { - barIndex = 0; - } - - // - int index = barIndex + 1; - double value = mX121Helper.xpvHelper.GetVale(index); - index++; - - // - bool canContinue = true; - while(canContinue) { - // - double iValue = mX121Helper.xpvHelper.GetVale(index); - - // - canContinue = iValue == value; - if (canContinue) { - // - index++; - result++; - } - } - - // - return result; - } - - /** - * Get Cycle State and Update it ... - * - * @param state: X121SMCCycleState instance Reference ... - * - * @return ( bool ) - */ - bool GetCycleState(X121SMCCycleState &state) - { - // - bool result = false; - - // - string symbol = GetSymbol(); - ENUM_TIMEFRAMES period = GetPeriod(); - - // - state.symbol = symbol; - state.period = period; - - // - datetime cTime = TimeCurrent(); - - // - // Detect Order Block ... - - // - bool hasBullishOBs = state.HasBullishOBs(); - int bullishOBsCount = state.CountBullishOBs(); - - // - bool hasBearishOBs = state.HasBearishOBs(); - int bearishOBsCount = state.CountBearishOBs(); - - // - bool hasOBs = hasBullishOBs && - hasBearishOBs; - if (!hasOBs) - { - // - XCOrderBlock *bullishOBs[]; - XCOrderBlock *bearishOBs[]; - hasOBs = DetectOrderBlocks( - bullishOBs, - bearishOBs // - ); - - // - if (hasOBs && - !hasBullishOBs) - { - // - Copy( - bullishOBs, - state.bullishOBs // - ); - } - - // - if (hasOBs && - !hasBearishOBs) - { - // - Copy( - bearishOBs, - state.bearishOBs // - ); - } - - // - hasBullishOBs = state.HasBullishOBs(); - bullishOBsCount = state.CountBullishOBs(); - - // - hasBearishOBs = state.HasBearishOBs(); - bearishOBsCount = state.CountBearishOBs(); - } - - // - // Update Order Blocks Time ... - if (hasOBs) - { - // - if (hasBullishOBs) - { - // - for (int i = 0; i < bullishOBsCount; i++) - { - state.bullishOBs[i].To(cTime); - } - } - - // - if (hasBearishOBs) - { - // - for (int i = 0; i < bearishOBsCount; i++) - { - state.bearishOBs[i].To(cTime); - } - } - } - - // - // Detect Fair Value Gap ... - - // - bool hasBullishFVGs = state.HasBullishFVGs(); - int bullishFVGsCount = state.CountBullishFVGs(); - - // - bool hasBearishFVGs = state.HasBearishFVGs(); - int bearishFVGsCount = state.CountBearishFVGs(); - - // - bool hasFVGs = hasBullishFVGs && - hasBearishFVGs; - if (!hasFVGs) - { - // - XCFVG *bullishFVGs[]; - XCFVG *bearishFVGs[]; - hasFVGs = DetectFairValueGaps( - bullishFVGs, - bearishFVGs // - ); - - // - if (hasFVGs && - !hasBullishFVGs) - { - // - Copy( - bullishFVGs, - state.bullishFVGs // - ); - } - - // - if (hasFVGs && - !hasBearishFVGs) - { - // - Copy( - bearishFVGs, - state.bearishFVGs // - ); - } - - // - hasBullishFVGs = state.HasBullishFVGs(); - bullishFVGsCount = state.CountBullishFVGs(); - - // - hasBearishFVGs = state.HasBearishFVGs(); - bearishFVGsCount = state.CountBearishFVGs(); - } - - // - // Update Fair Value Gaps Time ... - if (hasFVGs) - { - // - if (hasBullishFVGs) - { - // - for (int i = 0; i < bullishFVGsCount; i++) - { - state.bullishFVGs[i].To(cTime); - } - } - - // - if (hasBearishFVGs) - { - // - for (int i = 0; i < bearishFVGsCount; i++) - { - state.bearishFVGs[i].To(cTime); - } - } - } - - // - // Detect Support Zones ... - - // - bool hasSupportZones = state.HasSupportZones(); - int supportZonesCount = state.CountSupportZones(); - - // - if (!hasSupportZones) - { - // - XCSupportZone *supportZones[]; - hasSupportZones = DetectSupportZones( - state.bullishOBs, - state.bullishFVGs, - supportZones // - ); - - // - if (hasSupportZones) - { - // - Copy( - supportZones, - state.supportZones // - ); - - // - supportZonesCount = state.CountSupportZones(); - } - } - - // - // Update Support Zones Time ... - if (hasSupportZones) - { - // - for (int i = 0; i < supportZonesCount; i++) - { - state.supportZones[i].To(cTime); - } - } - - // - // Detect Demand Zones ... - - // - bool hasDemandZones = state.HasDemandZones(); - int demandZonesCount = state.CountDemandZones(); - - // - if (!hasDemandZones) - { - // - XCDemandZone *demandZones[]; - hasDemandZones = DetectDemandZones( - state.bullishOBs, - state.bullishFVGs, - demandZones // - ); - - // - if (hasDemandZones) - { - // - Copy( - demandZones, - state.demandZones // - ); - - // - demandZonesCount = state.CountDemandZones(); - } - } - - // - // Update Support Zones Time ... - if (hasDemandZones) - { - // - for (int i = 0; i < demandZonesCount; i++) - { - state.demandZones[i].To(cTime); - } - } - - // - // Detect Resistance Zones ... - - // - bool hasResistanceZones = state.HasResistanceZones(); - int resistanceZonesCount = state.CountResistanceZones(); - - // - if (!hasResistanceZones) - { - // - XCResistanceZone *resistanceZones[]; - hasResistanceZones = DetectResistanceZones( - state.bearishOBs, - state.bearishFVGs, - resistanceZones // - ); - - // - if (hasResistanceZones) - { - // - for (int i = 0; i < ArraySize(resistanceZones); i++) - { - resistanceZones[i].To(cTime); - } - - // - Copy( - resistanceZones, - state.resistanceZones // - ); - - // - resistanceZonesCount = state.CountResistanceZones(); - } - } - - // - // Update Resistance Zones Time ... - if (hasResistanceZones) - { - // - for (int i = 0; i < resistanceZonesCount; i++) - { - state.resistanceZones[i].To(cTime); - } - } - - // - // Detect Supply Zones ... - - // - bool hasSupplyZones = state.HasSupplyZones(); - int supplyZonesCount = state.CountSupplyZones(); - - // - if (!hasSupplyZones) - { - // - XCSupplyZone *supplyZones[]; - hasSupplyZones = DetectSupplyZones( - state.bearishOBs, - state.bearishFVGs, - supplyZones // - ); - - // - if (hasSupplyZones) - { - // - Copy( - supplyZones, - state.supplyZones // - ); - - // - supplyZonesCount = state.CountSupplyZones(); - } - } - - // - // Update Resistance Zones Time ... - if (hasSupplyZones) - { - // - for (int i = 0; i < supplyZonesCount; i++) - { - state.supplyZones[i].To(cTime); - } - } - - // - result = state.IsValid(); - - // - return result; - } - /** * Retrieve Cycle Conditions ... * @@ -1377,306 +446,6 @@ class XC121SMCCycleHelper : public XCBase // // Tools ... - /** - * Draw Cycle State ... - * - * @param state: X121SMCCyleState instance Reference ... - * - * @return ( int ) - */ - int DrawCycleState( - X121SMCCycleState &state, - XCBaseObject *&drawnObjects[], - bool drawOrderBlocks = true, - bool drawFairValueGaps = true, - bool drawSupplyAndDemandZones = false, - bool drawSupportAndResistanceZones = false // - ) - { - // - int result = 0; - - // - // Order Blocks ... - if (drawOrderBlocks) - { - // - // Bullish ... - bool hasBullishOBs = state.HasBullishOBs(); - int bullishOBsCount = state.CountBullishOBs(); - if (hasBullishOBs) - { - // - for (int i = 0; i < bullishOBsCount; i++) - { - // - XCOrderBlock *iOb = state.bullishOBs[i]; - - // - XCBullishOrderBlockObject *iObObj; - bool isCreated = mPOIDrawer - .CreateBullishOrderBlock( - iOb, - iObObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObObj, - drawnObjects // - ); - } - } - } - - // - // Bearish ... - bool hasBearishOBs = state.HasBearishOBs(); - int bearishOBsCount = state.CountBearishOBs(); - if (hasBearishOBs) - { - // - for (int i = 0; i < bearishOBsCount; i++) - { - // - XCOrderBlock *iOb = state.bearishOBs[i]; - - // - XCBearishOrderBlockObject *iObObj; - bool isCreated = mPOIDrawer - .CreateBearishOrderBlock( - iOb, - iObObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObObj, - drawnObjects // - ); - } - } - } - } - - // - // Fair Value Gaps ... - if (drawFairValueGaps) - { - // - // Bullish ... - bool hasBullishFVGs = state.HasBullishFVGs(); - int bullishFVGsCount = state.CountBullishFVGs(); - if (hasBullishFVGs) - { - // - for (int i = 0; i < bullishFVGsCount; i++) - { - // - XCFVG *iFVG = state.bullishFVGs[i]; - - // - XCBullishFairValueGapObject *iFVGObj; - bool isCreated = mPOIDrawer - .CreateBullishFairValueGap( - iFVG, - iFVGObj // - ); - if (isCreated) - { - // - iFVGObj.ZoneColor(clrLime); - - // - Add( - (XCBaseObject *)iFVGObj, - drawnObjects // - ); - } - } - } - - // - // Bearish ... - bool hasBearishFVGs = state.HasBearishFVGs(); - int bearishFVGsCount = state.CountBearishFVGs(); - if (hasBearishFVGs) - { - // - for (int i = 0; i < bearishFVGsCount; i++) - { - // - XCFVG *iFVG = state.bearishFVGs[i]; - - // - XCBearishFairValueGapObject *iFVGObj; - bool isCreated = mPOIDrawer - .CreateBearishFairValueGap( - iFVG, - iFVGObj // - ); - if (isCreated) - { - // - iFVGObj.ZoneColor(clrRed); - - // - Add( - (XCBaseObject *)iFVGObj, - drawnObjects // - ); - } - } - } - } - - // - // Support and Resistance Zones ... - if (drawSupportAndResistanceZones) - { - // - // Support Zones ... - bool hasSupportZones = state.HasSupportZones(); - int supportZonesCount = state.CountSupportZones(); - if (hasSupportZones) - { - // - for (int i = 0; i < supportZonesCount; i++) - { - // - XCSupportZoneObject *iObj; - bool isCreated = mPOIDrawer - .CreateSupportZone( - state.supportZones[i], - iObj // - ); - - // - if (isCreated) - { - // - iObj.ZoneColor(clrDarkSeaGreen); - - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - } - - // - // Resistance Zones ... - bool hasResistanceZones = state.HasResistanceZones(); - int resistanceZonesCount = state.CountResistanceZones(); - if (hasResistanceZones) - { - // - for (int i = 0; i < resistanceZonesCount; i++) - { - // - XCResistanceZoneObject *iObj; - bool isCreated = mPOIDrawer - .CreateResistanceZone( - state.resistanceZones[i], - iObj // - ); - - // - if (isCreated) - { - // - iObj.ZoneColor(clrSaddleBrown); - - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - } - } - - // - // Supply and Demand Zones ... - if (drawSupplyAndDemandZones) - { - // - // Demand Zones ... - bool hasDemandZones = state.HasDemandZones(); - int demandZonesCount = state.CountDemandZones(); - if (hasDemandZones) - { - // - for (int i = 0; i < demandZonesCount; i++) - { - // - XCDemandZoneObject *iObj; - bool isCreated = mPOIDrawer - .CreateDemandZone( - state.demandZones[i], - iObj // - ); - - // - if (isCreated) - { - // - iObj.ZoneColor(clrDarkTurquoise); - - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - } - - // - // Supply Zones ... - bool hasSupplyZones = state.HasSupplyZones(); - int supplyZonesCount = state.CountSupplyZones(); - if (hasSupplyZones) - { - // - for (int i = 0; i < supplyZonesCount; i++) - { - // - XCSupplyZoneObject *iObj; - bool isCreated = mPOIDrawer - .CreateSupplyZone( - state.supplyZones[i], - iObj // - ); - - // - if (isCreated) - { - // - iObj.ZoneColor(clrChocolate); - - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - } - } - - // - result = ArraySize(drawnObjects); - - // - return result; - } - // // Virtuals ... diff --git a/X121SMCEA/Libraries/x-121.smc.guard.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.guard.lib.mq5 index 994ee91d..30a29943 100644 --- a/X121SMCEA/Libraries/x-121.smc.guard.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.guard.lib.mq5 @@ -25,9 +25,6 @@ #include "../Libraries/x-121.smc.lib.mq5" // -XPriceZones x121SMCDecisionPriceZone; -XPriceZones x121SMCAnalysePriceZone; -XPriceZones x121SMCVerificationPriceZone; XConsolidationZone x121SMCConsolidationZone; bool DetectX121SMCGuards( string provider, // Provider ... @@ -151,12 +148,6 @@ bool DetectX121SMCGuards( Clean(ownLongPositions); Clean(ownShortPositions); - // - x121SMCAnalysePriceZone.Clean(); - x121SMCDecisionPriceZone.Clean(); - x121SMCConsolidationZone.Clean(); - x121SMCVerificationPriceZone.Clean(); - // return result; } @@ -349,51 +340,6 @@ bool DetectX121SMCGuards( X121Conditions consolidationXConditions = consolidationConditions.x121Conditions; X121Conditions visionXConditions = visionConditions.x121Conditions; - // - // Trigger ... - ENUM_X_DIRECTION triggerTrendDir; - bool hasTriggerTrend = - triggerCycleHelper - .DetectMarketStructure( - triggerTrendDir // - ); - bool hasTriggerBullishTrend = - hasTriggerTrend && - IsBullish(triggerTrendDir); - bool hasTriggerBearishTrend = - hasTriggerTrend && - IsBearish(triggerTrendDir); - - // - // Decision ... - ENUM_X_DIRECTION decisionTrendDir; - bool hasDecisionTrend = - decisionCycleHelper - .DetectMarketStructure( - decisionTrendDir // - ); - bool hasDecisionBullishTrend = - hasDecisionTrend && - IsBullish(decisionTrendDir); - bool hasDecisionBearishTrend = - hasDecisionTrend && - IsBearish(decisionTrendDir); - - // - // Analyse ... - ENUM_X_DIRECTION analyseTrendDir; - bool hasAnalyseTrend = - analyseCycleHelper - .DetectMarketStructure( - analyseTrendDir // - ); - bool hasAnalyseBullishTrend = - hasAnalyseTrend && - IsBullish(analyseTrendDir); - bool hasAnalyseBearishTrend = - hasAnalyseTrend && - IsBearish(analyseTrendDir); - // // // @@ -470,402 +416,6 @@ bool DetectX121SMCGuards( } } - // - // Detect Price Zones ... - - // - // Decision ... - double decisionPriceZoneUpper = 0; - double decisionPriceZoneLower = 0; - bool isDecisionPriceZoneBearish = false; - bool isDecisionPriceZoneBullish = false; - bool isDecisionPriceZoneValidForPeak = false; - bool isDecisionPriceZoneValidForVale = false; - bool isDecisionPriceZoneLowerRejected = false; - bool isDecisionPriceZoneUpperRejected = false; - bool isDecisionPriceZoneUpperBreakedUp = false; - bool isDecisionPriceZoneLowerBreakedDown = false; - bool hasDecisionPriceZone = x121SMCDecisionPriceZone.IsValid(); - - // - if (!hasDecisionPriceZone) - { - // - hasDecisionPriceZone = CalculatePriceInsideZones( - x121SMCDecisionPriceZone, - decisionState, - cBar // - ); - } - - // - if (hasDecisionPriceZone) - { - // - bool hasBoundary = x121SMCDecisionPriceZone.GetBoundary( - X_DIRECTION_ALL, - decisionPriceZoneUpper, - decisionPriceZoneLower // - ); - - // - isDecisionPriceZoneBearish = x121SMCDecisionPriceZone.IsBearish(); - isDecisionPriceZoneBullish = x121SMCDecisionPriceZone.IsBullish(); - - // - XOHCL iBar; - bool isInited = iBar.Init( - symbol, - decisionXConditions.period, - cIndex // - ); - - // - if (hasBoundary) - { - // - isDecisionPriceZoneValidForPeak = - decisionXConditions.peaksBuffer[1] <= decisionPriceZoneUpper && - decisionXConditions.peaksBuffer[1] >= decisionPriceZoneLower; - - // - isDecisionPriceZoneValidForVale = - decisionXConditions.valesBuffer[1] <= decisionPriceZoneUpper && - decisionXConditions.valesBuffer[1] >= decisionPriceZoneLower; - - // - isDecisionPriceZoneLowerRejected = - isInited && - IsBarReject( - decisionPriceZoneLower, - X_DIRECTION_BULLISH, - iBar // - ); - - // - isDecisionPriceZoneUpperRejected = - isInited && - IsBarReject( - decisionPriceZoneUpper, - X_DIRECTION_BEARISH, - iBar // - ); - - // - isDecisionPriceZoneUpperBreakedUp = - isInited && - IsBarBreak( - decisionPriceZoneUpper, - X_DIRECTION_BULLISH, - iBar // - ); - - // - isDecisionPriceZoneLowerBreakedDown = - isInited && - IsBarBreak( - decisionPriceZoneUpper, - X_DIRECTION_BEARISH, - iBar // - ); - } - - // - // Clear Price Zone ... - bool canReset = - // - (!isInited || - !hasBoundary) - // - || - // - (isInited && - hasBoundary && - (iBar.high < decisionPriceZoneLower || - iBar.low > decisionPriceZoneUpper)) - // - ; - if (canReset) - { - // - x121SMCDecisionPriceZone.Clean(); - - // - decisionPriceZoneUpper = 0; - decisionPriceZoneLower = 0; - isDecisionPriceZoneBearish = false; - isDecisionPriceZoneBullish = false; - isDecisionPriceZoneValidForPeak = false; - isDecisionPriceZoneValidForVale = false; - isDecisionPriceZoneLowerRejected = false; - isDecisionPriceZoneUpperRejected = false; - isDecisionPriceZoneUpperBreakedUp = false; - isDecisionPriceZoneLowerBreakedDown = false; - } - } - - // - // Analyse ... - double analysePriceZoneUpper = 0; - double analysePriceZoneLower = 0; - bool isAnalysePriceZoneBearish = false; - bool isAnalysePriceZoneBullish = false; - bool isAnalysePriceZoneValidForPeak = false; - bool isAnalysePriceZoneValidForVale = false; - bool isAnalysePriceZoneLowerRejected = false; - bool isAnalysePriceZoneUpperRejected = false; - bool isAnalysePriceZoneUpperBreakedUp = false; - bool isAnalysePriceZoneLowerBreakedDown = false; - bool hasAnalysePriceZone = x121SMCAnalysePriceZone.IsValid(); - - // - if (!hasAnalysePriceZone) - { - // - hasAnalysePriceZone = CalculatePriceInsideZones( - x121SMCAnalysePriceZone, - analyseState, - cBar // - ); - } - - // - if (hasAnalysePriceZone) - { - // - bool hasBoundary = x121SMCAnalysePriceZone.GetBoundary( - X_DIRECTION_ALL, - analysePriceZoneUpper, - analysePriceZoneLower // - ); - - // - isAnalysePriceZoneBearish = x121SMCAnalysePriceZone.IsBearish(); - isAnalysePriceZoneBullish = x121SMCAnalysePriceZone.IsBullish(); - - // - XOHCL iBar; - bool isInited = iBar.Init( - symbol, - analyseXConditions.period, - cIndex // - ); - - // - if (hasBoundary) - { - // - isAnalysePriceZoneValidForPeak = - analyseXConditions.peaksBuffer[1] <= analysePriceZoneUpper && - analyseXConditions.peaksBuffer[1] >= analysePriceZoneLower; - - // - isAnalysePriceZoneValidForVale = - analyseXConditions.valesBuffer[1] <= analysePriceZoneUpper && - analyseXConditions.valesBuffer[1] >= analysePriceZoneLower; - - // - isAnalysePriceZoneLowerRejected = - isInited && - IsBarReject( - analysePriceZoneLower, - X_DIRECTION_BULLISH, - iBar // - ); - - // - isAnalysePriceZoneUpperRejected = - isInited && - IsBarReject( - analysePriceZoneUpper, - X_DIRECTION_BEARISH, - iBar // - ); - - // - isAnalysePriceZoneUpperBreakedUp = - isInited && - IsBarBreak( - analysePriceZoneUpper, - X_DIRECTION_BULLISH, - iBar // - ); - - // - isAnalysePriceZoneLowerBreakedDown = - isInited && - IsBarBreak( - analysePriceZoneUpper, - X_DIRECTION_BEARISH, - iBar // - ); - } - - // - // Clear Price Zone ... - bool canReset = - // - (!isInited || - !hasBoundary) - // - || - // - (isInited && - hasBoundary && - (iBar.high < analysePriceZoneLower || - iBar.low > analysePriceZoneUpper)) - // - ; - if (canReset) - { - // - x121SMCAnalysePriceZone.Clean(); - - // - analysePriceZoneUpper = 0; - analysePriceZoneLower = 0; - isAnalysePriceZoneBearish = false; - isAnalysePriceZoneBullish = false; - isAnalysePriceZoneValidForPeak = false; - isAnalysePriceZoneValidForVale = false; - isAnalysePriceZoneLowerRejected = false; - isAnalysePriceZoneUpperRejected = false; - isAnalysePriceZoneUpperBreakedUp = false; - isAnalysePriceZoneLowerBreakedDown = false; - } - } - - // - // Verification ... - double verificationPriceZoneUpper = 0; - double verificationPriceZoneLower = 0; - bool isVerificationPriceZoneBearish = false; - bool isVerificationPriceZoneBullish = false; - bool isVerificationPriceZoneValidForPeak = false; - bool isVerificationPriceZoneValidForVale = false; - bool isVerificationPriceZoneLowerRejected = false; - bool isVerificationPriceZoneUpperRejected = false; - bool isVerificationPriceZoneUpperBreakedUp = false; - bool isVerificationPriceZoneLowerBreakedDown = false; - bool hasVerificationPriceZone = x121SMCVerificationPriceZone.IsValid(); - - // - if (!hasVerificationPriceZone) - { - // - hasVerificationPriceZone = CalculatePriceInsideZones( - x121SMCVerificationPriceZone, - verificationState, - cBar // - ); - } - - // - if (hasVerificationPriceZone) - { - // - bool hasBoundary = x121SMCVerificationPriceZone.GetBoundary( - X_DIRECTION_ALL, - verificationPriceZoneUpper, - verificationPriceZoneLower // - ); - - // - isVerificationPriceZoneBearish = x121SMCVerificationPriceZone.IsBearish(); - isVerificationPriceZoneBullish = x121SMCVerificationPriceZone.IsBullish(); - - // - XOHCL iBar; - bool isInited = iBar.Init( - symbol, - verificationXConditions.period, - cIndex // - ); - - // - if (hasBoundary) - { - // - isVerificationPriceZoneValidForPeak = - verificationXConditions.peaksBuffer[1] <= verificationPriceZoneUpper && - verificationXConditions.peaksBuffer[1] >= verificationPriceZoneLower; - - // - isVerificationPriceZoneValidForVale = - verificationXConditions.valesBuffer[1] <= verificationPriceZoneUpper && - verificationXConditions.valesBuffer[1] >= verificationPriceZoneLower; - - // - isVerificationPriceZoneLowerRejected = - isInited && - IsBarReject( - verificationPriceZoneLower, - X_DIRECTION_BULLISH, - iBar // - ); - - // - isVerificationPriceZoneUpperRejected = - isInited && - IsBarReject( - verificationPriceZoneUpper, - X_DIRECTION_BEARISH, - iBar // - ); - - // - isVerificationPriceZoneUpperBreakedUp = - isInited && - IsBarBreak( - verificationPriceZoneUpper, - X_DIRECTION_BULLISH, - iBar // - ); - - // - isVerificationPriceZoneLowerBreakedDown = - isInited && - IsBarBreak( - verificationPriceZoneUpper, - X_DIRECTION_BEARISH, - iBar // - ); - } - - // - // Clear Price Zone ... - bool canReset = - // - (!isInited || - !hasBoundary) - // - || - // - (isInited && - hasBoundary && - (iBar.high < verificationPriceZoneLower || - iBar.low > verificationPriceZoneUpper)) - // - ; - if (canReset) - { - // - x121SMCVerificationPriceZone.Clean(); - - // - verificationPriceZoneUpper = 0; - verificationPriceZoneLower = 0; - isVerificationPriceZoneBearish = false; - isVerificationPriceZoneBullish = false; - isVerificationPriceZoneValidForPeak = false; - isVerificationPriceZoneValidForVale = false; - isVerificationPriceZoneLowerRejected = false; - isVerificationPriceZoneUpperRejected = false; - isVerificationPriceZoneUpperBreakedUp = false; - isVerificationPriceZoneLowerBreakedDown = false; - } - } - // // Here We Have all Requirements for Guarding Positions ... @@ -906,37 +456,10 @@ bool DetectX121SMCGuards( // isLong ? // - (hasDecisionPriceZone && - isDecisionPriceZoneBearish && - isDecisionPriceZoneValidForPeak) - // - || - // - (hasAnalysePriceZone && - isAnalysePriceZoneBearish && - isAnalysePriceZoneValidForPeak) - // - || - // - (hasVerificationPriceZone && - isVerificationPriceZoneBearish && - isVerificationPriceZoneValidForPeak) + false + // : // - (hasDecisionPriceZone && - isDecisionPriceZoneBullish && - isDecisionPriceZoneValidForVale) - // - || - // - (hasAnalysePriceZone && - isAnalysePriceZoneBullish && - isAnalysePriceZoneValidForVale) - // - || - // - (hasVerificationPriceZone && - isVerificationPriceZoneBullish && - isVerificationPriceZoneValidForVale) + false // ; if (iHasGuard) @@ -969,7 +492,7 @@ bool DetectX121SMCGuards( if (!ignoreCloseLongsOnBearishTrendGuard) { // - bool hasGuard = hasDecisionBearishTrend; + bool hasGuard = false; // hasDecisionBearishTrend; // if (hasGuard) @@ -1016,7 +539,7 @@ bool DetectX121SMCGuards( if (!ignoreCloseShortsOnBullishTrendGuard) { // - bool hasGuard = hasDecisionBullishTrend; + bool hasGuard = false; // hasDecisionBullishTrend; // if (hasGuard) @@ -1100,8 +623,10 @@ bool DetectX121SMCGuards( // bool hasGuard = // - hasAnalyseBearishTrend && - hasDecisionBearishTrend + false + // + // hasAnalyseBearishTrend && + // hasDecisionBearishTrend // ; @@ -1132,8 +657,10 @@ bool DetectX121SMCGuards( // bool hasGuard = // - hasAnalyseBullishTrend && - hasDecisionBullishTrend + false + // + // hasAnalyseBullishTrend && + // hasDecisionBullishTrend // ; @@ -1169,8 +696,10 @@ bool DetectX121SMCGuards( // bool hasGuard = // - hasTriggerBearishTrend || - !hasDecisionBullishTrend + false + // + // hasTriggerBearishTrend || + // !hasDecisionBullishTrend // ; @@ -1211,8 +740,10 @@ bool DetectX121SMCGuards( // bool hasGuard = // - hasTriggerBullishTrend || - !hasDecisionBearishTrend + false + // + // hasTriggerBullishTrend || + // !hasDecisionBearishTrend // ; @@ -1256,7 +787,7 @@ bool DetectX121SMCGuards( if (hasLongs) { // - bool hasTrendGuard = hasDecisionBearishTrend; + bool hasTrendGuard = false; // hasDecisionBearishTrend; // bool hasConsolidationGuard = @@ -1266,24 +797,27 @@ bool DetectX121SMCGuards( // bool hasDecisionPriceZoneGuard = - (hasDecisionPriceZone && - isDecisionPriceZoneBullish && - isDecisionPriceZoneValidForVale && - isDecisionPriceZoneUpperBreakedUp); + false; + // (hasDecisionPriceZone && + // isDecisionPriceZoneBullish && + // isDecisionPriceZoneValidForVale && + // isDecisionPriceZoneUpperBreakedUp); // bool hasAnalysePriceZoneGuard = - (hasAnalysePriceZone && - isAnalysePriceZoneBullish && - isAnalysePriceZoneValidForVale && - isAnalysePriceZoneUpperBreakedUp); + false; + // (hasAnalysePriceZone && + // isAnalysePriceZoneBullish && + // isAnalysePriceZoneValidForVale && + // isAnalysePriceZoneUpperBreakedUp); // bool hasVerificationPriceZoneGuard = - (hasVerificationPriceZone && - isVerificationPriceZoneBullish && - isVerificationPriceZoneValidForVale && - isVerificationPriceZoneUpperBreakedUp); + false; + // (hasVerificationPriceZone && + // isVerificationPriceZoneBullish && + // isVerificationPriceZoneValidForVale && + // isVerificationPriceZoneUpperBreakedUp); // bool hasGuard = @@ -1301,11 +835,11 @@ bool DetectX121SMCGuards( hasConsolidationGuard ? consolidationZoneLower : hasDecisionPriceZoneGuard - ? decisionPriceZoneLower + ? 0 // decisionPriceZoneLower : hasAnalysePriceZoneGuard - ? analysePriceZoneLower + ? 0 // analysePriceZoneLower : hasVerificationPriceZoneGuard - ? verificationPriceZoneLower + ? 0 // verificationPriceZoneLower : 0; // @@ -1378,7 +912,7 @@ bool DetectX121SMCGuards( if (hasShorts) { // - bool hasTrendGuard = hasDecisionBullishTrend; + bool hasTrendGuard = false; // hasDecisionBullishTrend; // bool hasConsolidationGuard = @@ -1388,24 +922,27 @@ bool DetectX121SMCGuards( // bool hasDecisionPriceZoneGuard = - (hasDecisionPriceZone && - isDecisionPriceZoneBearish && - isDecisionPriceZoneValidForPeak && - isDecisionPriceZoneLowerBreakedDown); + false; + // (hasDecisionPriceZone && + // isDecisionPriceZoneBearish && + // isDecisionPriceZoneValidForPeak && + // isDecisionPriceZoneLowerBreakedDown); // bool hasAnalysePriceZoneGuard = - (hasAnalysePriceZone && - isAnalysePriceZoneBearish && - isAnalysePriceZoneValidForPeak && - isAnalysePriceZoneLowerBreakedDown); + false; + // (hasAnalysePriceZone && + // isAnalysePriceZoneBearish && + // isAnalysePriceZoneValidForPeak && + // isAnalysePriceZoneLowerBreakedDown); // bool hasVerificationPriceZoneGuard = - (hasVerificationPriceZone && - isVerificationPriceZoneBearish && - isVerificationPriceZoneValidForPeak && - isVerificationPriceZoneLowerBreakedDown); + false; + // (hasVerificationPriceZone && + // isVerificationPriceZoneBearish && + // isVerificationPriceZoneValidForPeak && + // isVerificationPriceZoneLowerBreakedDown); // bool hasGuard = @@ -1423,11 +960,11 @@ bool DetectX121SMCGuards( hasConsolidationGuard ? consolidationZoneUpper : hasDecisionPriceZoneGuard - ? decisionPriceZoneUpper + ? 0 // decisionPriceZoneUpper : hasAnalysePriceZoneGuard - ? analysePriceZoneUpper + ? 0 // analysePriceZoneUpper : hasVerificationPriceZoneGuard - ? verificationPriceZoneUpper + ? 0 // verificationPriceZoneUpper : 0; // @@ -1507,18 +1044,22 @@ bool DetectX121SMCGuards( // bool hasAnalyseGuard = // - (hasAnalysePriceZone && - isAnalysePriceZoneValidForPeak && - isAnalysePriceZoneUpperRejected) + false + // + // (hasAnalysePriceZone && + // isAnalysePriceZoneValidForPeak && + // isAnalysePriceZoneUpperRejected) // ; // bool hasVerificationGuard = // - (hasVerificationPriceZone && - isVerificationPriceZoneValidForPeak && - isVerificationPriceZoneUpperRejected) + false + // + // (hasVerificationPriceZone && + // isVerificationPriceZoneValidForPeak && + // isVerificationPriceZoneUpperRejected) // ; @@ -1533,9 +1074,9 @@ bool DetectX121SMCGuards( // double guardTP = hasAnalyseGuard - ? analysePriceZoneUpper + ? 0 // analysePriceZoneUpper : hasVerificationGuard - ? verificationPriceZoneUpper + ? 0 // verificationPriceZoneUpper : 0; // @@ -1582,18 +1123,22 @@ bool DetectX121SMCGuards( // bool hasAnalyseGuard = // - (hasAnalysePriceZone && - isAnalysePriceZoneValidForVale && - isAnalysePriceZoneLowerRejected) + false + // + // (hasAnalysePriceZone && + // isAnalysePriceZoneValidForVale && + // isAnalysePriceZoneLowerRejected) // ; // bool hasVerificationGuard = // - (hasVerificationPriceZone && - isVerificationPriceZoneValidForVale && - isVerificationPriceZoneLowerRejected) + false + // + // (hasVerificationPriceZone && + // isVerificationPriceZoneValidForVale && + // isVerificationPriceZoneLowerRejected) // ; @@ -1608,9 +1153,9 @@ bool DetectX121SMCGuards( // double guardTP = hasAnalyseGuard - ? analysePriceZoneLower + ? 0 // analysePriceZoneLower : hasVerificationGuard - ? verificationPriceZoneLower + ? 0 // verificationPriceZoneLower : 0; // @@ -1667,10 +1212,10 @@ bool DetectX121SMCGuards( Clean(ownShortPositions); // - x121SMCAnalysePriceZone.Clean(); - x121SMCDecisionPriceZone.Clean(); - x121SMCConsolidationZone.Clean(); - x121SMCVerificationPriceZone.Clean(); + // x121SMCAnalysePriceZone.Clean(); + // x121SMCDecisionPriceZone.Clean(); + // x121SMCConsolidationZone.Clean(); + // x121SMCVerificationPriceZone.Clean(); // // Release Arrays ... diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index 72234335..5798f7a2 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -37,9 +37,6 @@ const string X121SMCStrategyToken = "X121SMC"; // const string X121SMCXToken = "X121X"; const string X121SMCXOBSToken = "X121XOBS"; -const string X121SMCXHKPVToken = "X121XHKPV"; -const string X121SMCXOBPVToken = "X121XOBPV"; -const string X121SMCXIOBPVToken = "X121XIOBPV"; // // X121 SMC Providers ... @@ -49,9 +46,6 @@ enum ENUM_X_121_SMC_PROVIDERS X_121_SMC_PROVIDER_NONE, X_121_SMC_PROVIDER_X, X_121_SMC_PROVIDER_XOBS, - X_121_SMC_PROVIDER_XHKPV, - X_121_SMC_PROVIDER_XOBPV, - X_121_SMC_PROVIDER_XIOBPV, }; // @@ -627,958 +621,6 @@ struct X121SMCGuard } }; -// -// Model Cycle State ... -struct X121SMCCycleState -{ - // - // Props ... - string symbol; - ENUM_TIMEFRAMES period; - - // - // Bullish ... - XCFVG *bullishFVGs[]; - XCOrderBlock *bullishOBs[]; - XCDemandZone *demandZones[]; - XCSupportZone *supportZones[]; - - // - // Bearish ... - XCFVG *bearishFVGs[]; - XCOrderBlock *bearishOBs[]; - XCSupplyZone *supplyZones[]; - XCResistanceZone *resistanceZones[]; - - // - // Constructor ... - X121SMCCycleState() - { - Clean(); - } - - // - // Tools ... - - /** - * Cleanup Model ... - */ - void Clean() - { - // - symbol = NULL; - period = NULL; - - // - Clean(bullishFVGs); - Clean(bullishOBs); - Clean(demandZones); - Clean(supportZones); - - // - Clean(bearishFVGs); - Clean(bearishOBs); - Clean(supplyZones); - Clean(resistanceZones); - - // - ZeroMemory(this); - } - - /** - * Validate Model ... - * - * @return ( bool ) - */ - bool IsValid() - { - // - bool result = false; - - // - result = - // - IsValid(symbol) && - IsValid(period) && - ( - // - (HasBullishOBs() && - (HasBullishFVGs() || - HasSupportZones() || - HasDemandZones())) - // - || - (HasBearishOBs() && - (HasSupplyZones() || - HasBearishFVGs() || - HasResistanceZones())) - // - ) - // - ; - - // - return result; - } - - // - int CountBullishOBs() - { - return ArraySize(bullishOBs); - } - - // - bool HasBullishOBs() - { - return IsValidSize(CountBullishOBs()); - } - - // - int CountBearishOBs() - { - return ArraySize(bearishOBs); - } - - // - bool HasBearishOBs() - { - return IsValidSize(CountBearishOBs()); - } - - // - int CountSupportZones() - { - return ArraySize(supportZones); - } - - // - bool HasSupportZones() - { - return IsValidSize(CountSupportZones()); - } - - // - int CountResistanceZones() - { - return ArraySize(resistanceZones); - } - - // - bool HasResistanceZones() - { - return IsValidSize(CountResistanceZones()); - } - - // - int CountDemandZones() - { - return ArraySize(demandZones); - } - - // - bool HasDemandZones() - { - return IsValidSize(CountDemandZones()); - } - - // - int CountSupplyZones() - { - return ArraySize(supplyZones); - } - - // - bool HasSupplyZones() - { - return IsValidSize(CountSupplyZones()); - } - - // - int CountBullishFVGs() - { - return ArraySize(bullishFVGs); - } - - // - bool HasBullishFVGs() - { - return IsValidSize(CountBullishFVGs()); - } - - // - int CountBearishFVGs() - { - return ArraySize(bearishFVGs); - } - - // - bool HasBearishFVGs() - { - return IsValidSize(CountBearishFVGs()); - } - - // - bool GetOldestOB( - XCOrderBlock *&orderBlock // - ) - { - // - bool result = false; - - // - orderBlock = NULL; - - // - bool hasBullishOB = HasBullishOBs(); - bool hasBearishOB = HasBearishOBs(); - result = hasBullishOB || - hasBearishOB; - if (!result) - { - return result; - } - - // - int iBullOBIDX = -1; - bool iHasBullOB = false; - XCOrderBlock *iBullOB = NULL; - if (hasBullishOB) - { - // - XCZone* iZones[]; - ToZone( - bullishOBs, - iZones // - ); - - // - iBullOBIDX = GetOldest( - iZones // - ); - - // - iHasBullOB = IsValidIndex(iBullOBIDX); - if (iHasBullOB) - { - iBullOB = bullishOBs[iBullOBIDX]; - } - } - - // - int iBearOBIDX = -1; - bool iHasBearOB = false; - XCOrderBlock *iBearOB = NULL; - if (hasBearishOB) - { - // - XCZone* iZones[]; - ToZone( - bearishOBs, - iZones // - ); - - // - iBearOBIDX = GetOldest( - iZones // - ); - - // - iHasBearOB = IsValidIndex(iBearOBIDX); - if (iHasBearOB) - { - iBearOB = bearishOBs[iBearOBIDX]; - } - } - - // - if (iHasBullOB) - { - orderBlock = iBullOB; - } - - // - if (iHasBearOB) - { - // - bool canSet = orderBlock == NULL || - orderBlock.From() > iBearOB.From(); - if (canSet) - { - orderBlock = iBearOB; - } - } - - // - result = orderBlock != NULL && - orderBlock.IsValid(); - - // - return result; - } - - // - bool GetYoungestOB( - XCOrderBlock *&orderBlock // - ) - { - // - bool result = false; - - // - orderBlock = NULL; - - // - bool hasBullishOB = HasBullishOBs(); - bool hasBearishOB = HasBearishOBs(); - result = hasBullishOB || - hasBearishOB; - if (!result) - { - return result; - } - - // - int iBullOBIDX = -1; - bool iHasBullOB = false; - XCOrderBlock *iBullOB = NULL; - if (hasBullishOB) - { - // - XCZone* iZones[]; - ToZone( - bullishOBs, - iZones // - ); - - // - iBullOBIDX = GetYoungest( - iZones // - ); - - // - iHasBullOB = IsValidIndex(iBullOBIDX); - if (iHasBullOB) - { - iBullOB = bullishOBs[iBullOBIDX]; - } - } - - // - int iBearOBIDX = -1; - bool iHasBearOB = false; - XCOrderBlock *iBearOB = NULL; - if (hasBearishOB) - { - // - XCZone* iZones[]; - ToZone( - bearishOBs, - iZones // - ); - - // - iBearOBIDX = GetYoungest( - iZones // - ); - - // - iHasBearOB = IsValidIndex(iBearOBIDX); - if (iHasBearOB) - { - iBearOB = bearishOBs[iBearOBIDX]; - } - } - - // - if (iHasBullOB) - { - orderBlock = iBullOB; - } - - // - if (iHasBearOB) - { - // - bool canSet = orderBlock == NULL || - orderBlock.From() < iBearOB.From(); - if (canSet) - { - orderBlock = iBearOB; - } - } - - // - result = orderBlock != NULL && - orderBlock.IsValid(); - - // - return result; - } - - // -}; - -/** - * Detect Price inside Box ... - * - * @param box: XBoxZone instance Reference, Founded Price Inside Box ... - * @param orderBlock: XCOrderBlock pointer Reference, Founded Price Inside Order Block ... - * @param xConditions: X121Conditions instance Reference, provides Market Conditions ... - * @param state: X121SMCCycleState instance Reference ... - * - * @return ( bool ) - */ -bool DetectPriceInsideBox( - XBoxZone &box, // Price Inside Bo ... - XCOrderBlock *&orderBlock, // Price Inside Order Block ... - X121Conditions &xConditions, // X121Conditions for Validation ... - X121SMCCycleState &state // Cycle State ... -) -{ - // - bool result = false; - - // - box.Clean(); - - // - string symbol = state.symbol; - ENUM_TIMEFRAMES period = state.period; - - // - box.symbol = symbol; - box.period = period; - - // - result = state.IsValid(); - if (!result) - { - return result; - } - - // - // Detect Price Inside Order Block ... - - // - bool hasBullishOBs = state.HasBullishOBs(); - int bullishOBsCount = state.CountBullishOBs(); - - // - bool hasBearishOBs = state.HasBearishOBs(); - int bearishOBsCount = state.CountBearishOBs(); - - // - bool hasOBs = - // - hasBullishOBs || - hasBearishOBs - // - ; - result = hasOBs; - if (!result) - { - return result; - } - - // - bool hasPriceInsideOB = false; - XCOrderBlock *priceInsideOB = NULL; - ENUM_X_DIRECTION boxDir = X_DIRECTION_NONE; - - // - if (hasBullishOBs && - !hasPriceInsideOB) - { - // - for (int i = 0; i < bullishOBsCount; i++) - { - // - XCOrderBlock *iOb = state.bullishOBs[i]; - - // - bool isInside = IsPriceInsideZone( - xConditions.valesBuffer[1], - (XCZone *)iOb // - ); - if (isInside) - { - // - priceInsideOB = iOb; - hasPriceInsideOB = true; - boxDir = X_DIRECTION_BULLISH; - break; - } - } - } - - // - if (hasBearishOBs && - !hasPriceInsideOB) - { - // - for (int i = 0; i < bearishOBsCount; i++) - { - // - XCOrderBlock *iOb = state.bearishOBs[i]; - - // - bool isInside = IsPriceInsideZone( - xConditions.peaksBuffer[1], - (XCZone *)iOb // - ); - if (isInside) - { - // - priceInsideOB = iOb; - hasPriceInsideOB = true; - boxDir = X_DIRECTION_BEARISH; - break; - } - } - } - - // - if (hasPriceInsideOB) - { - // - orderBlock = priceInsideOB; - boxDir = priceInsideOB.IsBullish() - ? X_DIRECTION_BULLISH - : priceInsideOB.IsBearish() - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; - } - - // - bool hasBullishFVGs = state.HasBullishFVGs(); - bool hasBearishFVGs = state.HasBearishFVGs(); - bool hasDemandZones = state.HasDemandZones(); - bool hasSupplyZones = state.HasSupplyZones(); - bool hasSupportZones = state.HasSupportZones(); - bool hasResistanceZones = state.HasResistanceZones(); - - // - bool hasBullishZones = - // - hasBullishFVGs || - hasDemandZones || - hasSupportZones - // - ; - - // - bool hasBearishZones = - // - hasBearishFVGs || - hasSupplyZones || - hasResistanceZones - // - ; - - // - bool hasPropperZones = - // - IsBullish(boxDir) - ? hasBullishZones - : IsBearish(boxDir) - ? hasBearishZones - : false - // - ; - - // - if (!hasPropperZones && - hasPriceInsideOB) - { - // - // Use Price Inside OB as Box ... - box.dir = boxDir; - box.to = priceInsideOB.To(); - box.from = priceInsideOB.From(); - box.upper = priceInsideOB.Upper(); - box.lower = priceInsideOB.Lower(); - } - else if (hasPropperZones && - hasPriceInsideOB) - { - // - // Detect Validate Zones ... - int count = 0; - XBoxZone boxes[]; - double upper = 0; - double lower = 0; - double price = 0; - datetime to = NULL; - datetime from = NULL; - ENUM_X_DIRECTION dir = X_DIRECTION_NONE; - if (IsBullish(boxDir)) - { - // - double price = xConditions.valesBuffer[1]; - dir = X_DIRECTION_BULLISH; - - // - // Bullish FVG ... - count = state.CountBullishFVGs(); - for (int i = 0; i < count; i++) - { - // - XCFVG *iFVG = state.bullishFVGs[i]; - - // - to = iFVG.To(); - from = iFVG.From(); - upper = iFVG.Upper(); - lower = iFVG.Lower(); - - // - bool isInside = IsPriceInsideZone( - price, - upper, - lower // - ); - if (isInside) - { - // - XBoxZone iBox; - - // - iBox.dir = dir; - iBox.symbol = symbol; - iBox.period = period; - - // - iBox.to = to; - iBox.from = from; - iBox.upper = upper; - iBox.lower = lower; - - // - if (iBox.IsValid()) - { - // - AddRef( - iBox, - boxes // - ); - } - } - } - - // - // Demand Zones ... - count = state.CountDemandZones(); - for (int i = 0; i < count; i++) - { - // - XCDemandZone *iDemand = state.demandZones[i]; - - // - to = iDemand.To(); - from = iDemand.From(); - upper = iDemand.Upper(); - lower = iDemand.Lower(); - - // - bool isInside = IsPriceInsideZone( - price, - upper, - lower // - ); - if (isInside) - { - // - XBoxZone iBox; - - // - iBox.dir = dir; - iBox.symbol = symbol; - iBox.period = period; - - // - iBox.to = to; - iBox.from = from; - iBox.upper = upper; - iBox.lower = lower; - - // - if (iBox.IsValid()) - { - // - AddRef( - iBox, - boxes // - ); - } - } - } - - // - // Support Zones ... - count = state.CountSupportZones(); - for (int i = 0; i < count; i++) - { - // - XCSupportZone *iSupport = state.supportZones[i]; - - // - to = iSupport.To(); - from = iSupport.From(); - upper = iSupport.Upper(); - lower = iSupport.Lower(); - - // - bool isInside = IsPriceInsideZone( - price, - upper, - lower // - ); - if (isInside) - { - // - XBoxZone iBox; - - // - iBox.dir = dir; - iBox.symbol = symbol; - iBox.period = period; - - // - iBox.to = to; - iBox.from = from; - iBox.upper = upper; - iBox.lower = lower; - - // - if (iBox.IsValid()) - { - // - AddRef( - iBox, - boxes // - ); - } - } - } - } - else - { - // - double price = xConditions.peaksBuffer[1]; - dir = X_DIRECTION_BEARISH; - - // - // Bearish FVG ... - count = state.CountBearishFVGs(); - for (int i = 0; i < count; i++) - { - // - XCFVG *iFVG = state.bearishFVGs[i]; - - // - to = iFVG.To(); - from = iFVG.From(); - upper = iFVG.Upper(); - lower = iFVG.Lower(); - - // - bool isInside = IsPriceInsideZone( - price, - upper, - lower // - ); - if (isInside) - { - // - XBoxZone iBox; - - // - iBox.dir = dir; - iBox.symbol = symbol; - iBox.period = period; - - // - iBox.to = to; - iBox.from = from; - iBox.upper = upper; - iBox.lower = lower; - - // - if (iBox.IsValid()) - { - // - AddRef( - iBox, - boxes // - ); - } - } - } - - // - // Supply Zones ... - count = state.CountSupplyZones(); - for (int i = 0; i < count; i++) - { - // - XCSupplyZone *iSupply = state.supplyZones[i]; - - // - to = iSupply.To(); - from = iSupply.From(); - upper = iSupply.Upper(); - lower = iSupply.Lower(); - - // - bool isInside = IsPriceInsideZone( - price, - upper, - lower // - ); - if (isInside) - { - // - XBoxZone iBox; - - // - iBox.dir = dir; - iBox.symbol = symbol; - iBox.period = period; - - // - iBox.to = to; - iBox.from = from; - iBox.upper = upper; - iBox.lower = lower; - - // - if (iBox.IsValid()) - { - // - AddRef( - iBox, - boxes // - ); - } - } - } - - // - // Demand Zones ... - count = state.CountResistanceZones(); - for (int i = 0; i < count; i++) - { - // - XCResistanceZone *iResistance = state.resistanceZones[i]; - - // - to = iResistance.To(); - from = iResistance.From(); - upper = iResistance.Upper(); - lower = iResistance.Lower(); - - // - bool isInside = IsPriceInsideZone( - price, - upper, - lower // - ); - if (isInside) - { - // - XBoxZone iBox; - - // - iBox.dir = dir; - iBox.symbol = symbol; - iBox.period = period; - - // - iBox.to = to; - iBox.from = from; - iBox.upper = upper; - iBox.lower = lower; - - // - if (iBox.IsValid()) - { - // - AddRef( - iBox, - boxes // - ); - } - } - } - } - - // - int boxesCount = ArraySize(boxes); - bool hasBoxes = IsValidSize(boxes); - if (hasBoxes) - { - // - // Filter Boxes ... - for (int i = 0; i < boxesCount; i++) - { - // - XBoxZone iBox = boxes[i]; - - // - // Direction ... - if (!HasDirection(box.dir) || box.dir != iBox.dir) - { - box.dir = iBox.dir; - } - - // - // Upper ... - if (box.upper == 0 || box.upper < iBox.upper) - { - box.upper = iBox.upper; - } - - // - // Lower ... - if (box.lower == 0 || box.lower < iBox.lower) - { - box.lower = iBox.lower; - } - - // - // To ... - if (!IsValid(box.to) || box.to < iBox.to) - { - box.to = iBox.to; - } - - // - // From ... - if (!IsValid(box.from) || box.from > iBox.from) - { - box.from = iBox.from; - } - } - } - else - { - // - // Use Price Inside OB as Box ... - box.dir = boxDir; - box.to = priceInsideOB.To(); - box.from = priceInsideOB.From(); - box.upper = priceInsideOB.Upper(); - box.lower = priceInsideOB.Lower(); - } - } - - // - result = box.IsValid(); - - // - return result; -} - /** * Add Guard to Collection ... * @@ -1675,21 +717,6 @@ string ToString(ENUM_X_121_SMC_PROVIDERS value) case X_121_SMC_PROVIDER_XOBS: result = X121SMCXOBSToken; break; - - // - case X_121_SMC_PROVIDER_XHKPV: - result = X121SMCXHKPVToken; - break; - - // - case X_121_SMC_PROVIDER_XOBPV: - result = X121SMCXOBPVToken; - break; - - // - case X_121_SMC_PROVIDER_XIOBPV: - result = X121SMCXIOBPVToken; - break; } // @@ -1723,18 +750,6 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value) { result = X_121_SMC_PROVIDER_XOBS; } - else if (Contains(X121SMCXHKPVToken, value)) - { - result = X_121_SMC_PROVIDER_XHKPV; - } - else if (Contains(X121SMCXOBPVToken, value)) - { - result = X_121_SMC_PROVIDER_XOBPV; - } - else if (Contains(X121SMCXIOBPVToken, value)) - { - result = X_121_SMC_PROVIDER_XIOBPV; - } // return result; diff --git a/X121SMCEA/Signals/x-121.smc.x.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.x.signal.lib.mq5 index c5bdd020..f40391f8 100644 --- a/X121SMCEA/Signals/x-121.smc.x.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.x.signal.lib.mq5 @@ -54,10 +54,6 @@ struct X121SMCStrategyXSignalConditions double pivot; double point; - // - XCOrderBlock *bullishOBs[]; - XCOrderBlock *bearishOBs[]; - // // Constructor ... X121SMCStrategyXSignalConditions() @@ -180,34 +176,6 @@ struct X121SMCStrategyXSignalConditions point = 0; // - Clean(bullishOBs); - Clean(bearishOBs); - - // - } - - // - int CountBullishOBs() - { - return ArraySize(bullishOBs); - } - - // - bool HasBullishOBs() - { - return IsValidSize(CountBullishOBs()); - } - - // - int CountBearishOBs() - { - return ArraySize(bearishOBs); - } - - // - bool HasBearishOBs() - { - return IsValidSize(CountBearishOBs()); } // @@ -434,69 +402,6 @@ bool DetectX121SMCXSignalSetup( // // Setup Conditions ... - // - // Detect Trend ... - - // - // Consolidation ... - ENUM_X_DIRECTION consolidationTrendDir; - bool hasConsolidationTrend = - consolidationCycleHelper - .DetectMarketStructure( - consolidationTrendDir // - ); - bool hasConsolidationBullishTrend = - hasConsolidationTrend && - IsBullish(consolidationTrendDir); - bool hasConsolidationBearishTrend = - hasConsolidationTrend && - IsBearish(consolidationTrendDir); - - // - // Verification ... - ENUM_X_DIRECTION verificationTrendDir; - bool hasVerificationTrend = - verificationCycleHelper - .DetectMarketStructure( - verificationTrendDir // - ); - bool hasVerificationBullishTrend = - hasVerificationTrend && - IsBullish(verificationTrendDir); - bool hasVerificationBearishTrend = - hasVerificationTrend && - IsBearish(verificationTrendDir); - - // - // Analyse ... - ENUM_X_DIRECTION analyseTrendDir; - bool hasAnalyseTrend = - analyseCycleHelper - .DetectMarketStructure( - analyseTrendDir // - ); - bool hasAnalyseBullishTrend = - hasAnalyseTrend && - IsBullish(analyseTrendDir); - bool hasAnalyseBearishTrend = - hasAnalyseTrend && - IsBearish(analyseTrendDir); - - // - // Decision ... - ENUM_X_DIRECTION decisionTrendDir; - bool hasDecisionTrend = - decisionCycleHelper - .DetectMarketStructure( - decisionTrendDir // - ); - bool hasDecisionBullishTrend = - hasDecisionTrend && - IsBullish(decisionTrendDir); - bool hasDecisionBearishTrend = - hasDecisionTrend && - IsBearish(decisionTrendDir); - // // Detect Bar State ... @@ -714,457 +619,6 @@ bool DetectX121SMCXSignalSetup( // ; - // - // Detect Order Block ... - - // - bool hasBullishOrderBlocks = conditions.HasBullishOBs(); - int bullishOrderBlocksCount = conditions.CountBullishOBs(); - - // - bool hasBearishOrderBlocks = conditions.HasBearishOBs(); - int bearishOrderBlocksCount = conditions.CountBearishOBs(); - - // - bool hasOrderBlocks = hasBullishOrderBlocks && - hasBearishOrderBlocks; - if (!hasOrderBlocks) - { - // - XCOrderBlock *bullishOBs[]; - XCOrderBlock *bearishOBs[]; - bool hasOrderBlocks = visionCycleHelper.DetectOrderBlocks( - bullishOBs, - bearishOBs // - ); - - // - if (!hasBullishOrderBlocks) - { - // - Copy( - bullishOBs, - conditions.bullishOBs // - ); - } - - // - if (!hasBearishOrderBlocks) - { - // - Copy( - bearishOBs, - conditions.bearishOBs // - ); - } - - // - hasBullishOrderBlocks = conditions.HasBullishOBs(); - bullishOrderBlocksCount = conditions.CountBullishOBs(); - - // - hasBearishOrderBlocks = conditions.HasBearishOBs(); - bearishOrderBlocksCount = conditions.CountBearishOBs(); - } - - // - bool hasOldestBullishOB = false; - bool hasYoungestBullishOB = false; - XCOrderBlock *oldestBullishOB = NULL; - XCOrderBlock *youngestBullishOB = NULL; - if (hasBullishOrderBlocks) - { - // - XCZone *zones[]; - bool isConverted = ToZone( - conditions.bullishOBs, - zones // - ); - - // - int oldestIDX = GetOldest(zones); - hasOldestBullishOB = IsValidIndex(oldestIDX); - if (hasOldestBullishOB) - { - oldestBullishOB = conditions.bullishOBs[oldestIDX]; - } - - // - int youngestIDX = GetYoungest(zones); - hasYoungestBullishOB = IsValidIndex(youngestIDX); - if (hasYoungestBullishOB) - { - youngestBullishOB = conditions.bullishOBs[youngestIDX]; - } - } - - // - bool hasOldestBearishOB = false; - bool hasYoungestBearishOB = false; - XCOrderBlock *oldestBearishOB = NULL; - XCOrderBlock *youngestBearishOB = NULL; - if (hasBearishOrderBlocks) - { - // - XCZone *zones[]; - bool isConverted = ToZone( - conditions.bearishOBs, - zones // - ); - - // - int oldestIDX = GetOldest(zones); - hasOldestBearishOB = IsValidIndex(oldestIDX); - if (hasOldestBearishOB) - { - oldestBearishOB = conditions.bearishOBs[oldestIDX]; - } - - // - int youngestIDX = GetYoungest(zones); - hasYoungestBearishOB = IsValidIndex(youngestIDX); - if (hasYoungestBearishOB) - { - youngestBearishOB = conditions.bearishOBs[youngestIDX]; - } - } - - // - bool hasPriceInsideOB = false; - XCOrderBlock *priceInsideOB = NULL; - - // - if (!hasPriceInsideOB && - hasBullishOrderBlocks) - { - // - for (int i = 0; i < bullishOrderBlocksCount; i++) - { - // - XCOrderBlock *iOb = conditions.bullishOBs[i]; - - // - bool isInside = IsPriceInsideZone( - decisionXConditions.valesBuffer[1], - (XCZone *)iOb // - ); - if (isInside) - { - // - hasPriceInsideOB = true; - priceInsideOB = iOb; - break; - } - } - } - - // - if (!hasPriceInsideOB && - hasBearishOrderBlocks) - { - // - for (int i = 0; i < bearishOrderBlocksCount; i++) - { - // - XCOrderBlock *iOb = conditions.bearishOBs[i]; - - // - bool isInside = IsPriceInsideZone( - decisionXConditions.peaksBuffer[1], - (XCZone *)iOb // - ); - if (isInside) - { - // - hasPriceInsideOB = true; - priceInsideOB = iOb; - break; - } - } - } - - // - XStateZones obState; - bool hasOBState = false; - XOHCL priceInsideOBBreakerBar; - if (hasPriceInsideOB) - { - // - XOHCL toBar; - XOHCL fromBar; - ENUM_X_DIRECTION forDir = - priceInsideOB.IsBullish() - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - bool hasBreakerBar = HasBreakerBar( - toBar, - fromBar, - priceInsideOBBreakerBar, - forDir, - priceInsideOB.GetSymbol(), - priceInsideOB.GetPeriod(), - priceInsideOB.Upper(), - priceInsideOB.Lower(), - priceInsideOB.From(), - priceInsideOB.To() // - ); - if (hasBreakerBar) - { - // - CalculateStateZones( - obState, - consolidationState, - priceInsideOB.Upper(), - priceInsideOB.Lower(), - priceInsideOBBreakerBar.time // - ); - } - - // - hasOBState = obState.IsValid(); - } - - // - bool isSameCyclesPeak = - // - triggerXConditions.peaksBuffer[1] == decisionXConditions.peaksBuffer[1] && - decisionXConditions.peaksBuffer[1] == analyseXConditions.peaksBuffer[1] && - analyseXConditions.peaksBuffer[1] == verificationXConditions.peaksBuffer[1] && - verificationXConditions.peaksBuffer[1] == consolidationXConditions.peaksBuffer[1] - // - ; - - // - bool isSameCyclesVale = - // - triggerXConditions.valesBuffer[1] == decisionXConditions.valesBuffer[1] && - decisionXConditions.valesBuffer[1] == analyseXConditions.valesBuffer[1] && - analyseXConditions.valesBuffer[1] == verificationXConditions.valesBuffer[1] && - verificationXConditions.valesBuffer[1] == consolidationXConditions.valesBuffer[1] - // - ; - - // - bool hasSameCyclesPV = - hasOBState && - hasPriceInsideOB && - (isSameCyclesPeak || - isSameCyclesVale); - - // - // DRAW ... - // - - // - XCBaseObject *drawnObjects[]; - - // - if (hasBullishOrderBlocks) - { - // - for (int i = 0; i < bullishOrderBlocksCount; i++) - { - // - XCOrderBlock *iOb = conditions.bullishOBs[i]; - - // - XCBullishOrderBlockObject *iObObj; - bool isCreated = visionCycleHelper - .mPOIDrawer - .CreateBullishOrderBlock( - iOb, - iObObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObObj, - drawnObjects // - ); - } - } - } - - // - if (hasBearishOrderBlocks) - { - // - for (int i = 0; i < bearishOrderBlocksCount; i++) - { - // - XCOrderBlock *iOb = conditions.bearishOBs[i]; - - // - XCBearishOrderBlockObject *iObObj; - bool isCreated = visionCycleHelper - .mPOIDrawer - .CreateBearishOrderBlock( - iOb, - iObObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObObj, - drawnObjects // - ); - } - } - } - - // - // if (hasOldestBullishOB) - // { - // // - // XCBullishOrderBlockObject *iObj; - // bool isCreated = visionCycleHelper - // .mPOIDrawer - // .CreateBullishOrderBlock( - // oldestBullishOB, - // iObj // - // ); - // if (isCreated) - // { - // } - // } - - // // - // if (hasYoungestBullishOB) - // { - // // - // XCBullishOrderBlockObject *iObj; - // bool isCreated = visionCycleHelper - // .mPOIDrawer - // .CreateBullishOrderBlock( - // youngestBullishOB, - // iObj // - // ); - // if (isCreated) - // { - // } - // } - - // // - // if (hasOldestBearishOB) - // { - // // - // XCBearishOrderBlockObject *iObj; - // bool isCreated = visionCycleHelper - // .mPOIDrawer - // .CreateBearishOrderBlock( - // oldestBearishOB, - // iObj // - // ); - // if (isCreated) - // { - // } - // } - - // // - // if (hasYoungestBearishOB) - // { - // // - // XCBearishOrderBlockObject *iObj; - // bool isCreated = visionCycleHelper - // .mPOIDrawer - // .CreateBearishOrderBlock( - // youngestBearishOB, - // iObj // - // ); - // if (isCreated) - // { - // } - // } - - // - if (hasPriceInsideOB) - { - // - bool isBullish = priceInsideOB.IsBullish(); - - // - bool isCreated = false; - XCBaseObject *iObObj = NULL; - if (isBullish) - { - // - XCBullishOrderBlockObject *iObj; - isCreated = visionCycleHelper - .mPOIDrawer - .CreateBullishOrderBlock( - priceInsideOB, - iObj // - ); - - // - if (isCreated) - { - // - iObj.ZoneColor(clrYellow); - iObObj = (XCBaseObject *)iObj; - } - } - else - { - // - XCBearishOrderBlockObject *iObj; - isCreated = visionCycleHelper - .mPOIDrawer - .CreateBearishOrderBlock( - priceInsideOB, - iObj // - ); - - // - if (isCreated) - { - // - iObj.ZoneColor(clrOrangeRed); - iObObj = (XCBaseObject *)iObj; - } - } - - // - if (isCreated) - { - // - Add( - iObObj, - drawnObjects // - ); - } - } - - // - if (hasOBState) - { - // - XCBaseObject *stateObjects[]; - int stateObjectsCount = consolidationCycleHelper - .mPOIDrawer - .DrawStateZones( - obState, - stateObjects // - ); - if (IsValidSize(stateObjectsCount)) - { - // - Copy( - stateObjects, - drawnObjects, - false // - ); - } - } - - // - int drawnCount = ArraySize(drawnObjects); - if (IsValidSize(drawnCount)) - { - } - // // // @@ -1175,42 +629,14 @@ bool DetectX121SMCXSignalSetup( // bool isCondition1Bullish = // - hasSameCyclesPV && - isCBarBullishFormed && - priceInsideOB.IsBullish() && - // - (decisionXConditions.isBreakedUpPrevSar || - decisionXConditions.isBreakedUpPrevStr || - decisionXConditions.isVWapMaxBreakedUp || - decisionXConditions.isBreakedUpPrevCheMax || - decisionXConditions.isBreakedUpPrevAtrLower) && - // - (decisionXConditions.isSarSwitchedToBullish || - decisionXConditions.isStrSwitchedToBullish || - decisionXConditions.isCheSwitchedToBullish || - decisionXConditions.isVWapSwitchedToBullishState || - decisionXConditions.isVWapSwitchedToBullishOrdered) + false // ; // bool isCondition1Bearish = // - hasSameCyclesPV && - isCBarBearishFormed && - priceInsideOB.IsBearish() && - // - (decisionXConditions.isBreakedDownPrevSar || - decisionXConditions.isBreakedDownPrevStr || - decisionXConditions.isVWapMinBreakedDown || - decisionXConditions.isBreakedDownPrevCheMin || - decisionXConditions.isBreakedDownPrevAtrUpper) && - // - (decisionXConditions.isSarSwitchedToBearish || - decisionXConditions.isStrSwitchedToBearish || - decisionXConditions.isCheSwitchedToBearish || - decisionXConditions.isVWapSwitchedToBearishState || - decisionXConditions.isVWapSwitchedToBearishOrdered) + false // ; @@ -1243,8 +669,8 @@ bool DetectX121SMCXSignalSetup( // conditions.pivot = isCondition1Bullish - ? priceInsideOB.Upper() - : priceInsideOB.Lower(); + ? 0 // priceInsideOB.Upper() + : 0; // priceInsideOB.Lower(); } // diff --git a/X121SMCEA/Signals/x-121.smc.xobs.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xobs.signal.lib.mq5 index bf0e592d..6f49f163 100644 --- a/X121SMCEA/Signals/x-121.smc.xobs.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xobs.signal.lib.mq5 @@ -26,6 +26,53 @@ #include "../Libraries/x-121.smc.guard.lib.mq5" #include "../Libraries/x-121.smc.lib.mq5" +// +struct XOBTest +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + XCOrderBlock *ob; + XCFVG *fvg; + + // + datetime fvgActivatedAt; + datetime rewardedAt; + + // + double reward; + + // + // Constructor ... + XOBTest() + { + Clean(); + } + + // + // Tools ... + + // + void Clean() + { + // + ob = NULL; + fvg = NULL; + symbol = NULL; + period = NULL; + rewardedAt = NULL; + fvgActivatedAt = NULL; + + // + reward = 0; + } +}; + // // Definitions ... struct X121SMCStrategyXOBSSignalConditions @@ -56,18 +103,7 @@ struct X121SMCStrategyXOBSSignalConditions // // Extwnsion ... - - // - datetime cOBAt; - XCOrderBlock *cOB; - bool isCOBActivated; - datetime cOBActivatedAt; - - // - datetime aOBAt; - XCOrderBlock *aOB; - bool isAOBActivated; - datetime aOBActivatedAt; + XOBTest obTests[]; // // Constructor ... @@ -191,16 +227,7 @@ struct X121SMCStrategyXOBSSignalConditions point = 0; // - cOB = NULL; - cOBAt = NULL; - cOBActivatedAt = NULL; - isCOBActivated = false; - - // - aOB = NULL; - aOBAt = NULL; - aOBActivatedAt = NULL; - isAOBActivated = false; + Clean(obTests); } // @@ -434,84 +461,6 @@ bool DetectX121SMCXOBSSignalSetup( // // Setup Conditions ... - // - // Detect Trend ... - - // - // Vision ... - ENUM_X_DIRECTION visionTrendDir; - bool hasVisionTrend = - visionCycleHelper - .DetectMarketStructure( - visionTrendDir // - ); - bool hasVisionBullishTrend = - hasVisionTrend && - IsBullish(visionTrendDir); - bool hasVisionBearishTrend = - hasVisionTrend && - IsBearish(visionTrendDir); - - // - // Consolidation ... - ENUM_X_DIRECTION consolidationTrendDir; - bool hasConsolidationTrend = - consolidationCycleHelper - .DetectMarketStructure( - consolidationTrendDir // - ); - bool hasConsolidationBullishTrend = - hasConsolidationTrend && - IsBullish(consolidationTrendDir); - bool hasConsolidationBearishTrend = - hasConsolidationTrend && - IsBearish(consolidationTrendDir); - - // - // Verification ... - ENUM_X_DIRECTION verificationTrendDir; - bool hasVerificationTrend = - verificationCycleHelper - .DetectMarketStructure( - verificationTrendDir // - ); - bool hasVerificationBullishTrend = - hasVerificationTrend && - IsBullish(verificationTrendDir); - bool hasVerificationBearishTrend = - hasVerificationTrend && - IsBearish(verificationTrendDir); - - // - // Analyse ... - ENUM_X_DIRECTION analyseTrendDir; - bool hasAnalyseTrend = - analyseCycleHelper - .DetectMarketStructure( - analyseTrendDir // - ); - bool hasAnalyseBullishTrend = - hasAnalyseTrend && - IsBullish(analyseTrendDir); - bool hasAnalyseBearishTrend = - hasAnalyseTrend && - IsBearish(analyseTrendDir); - - // - // Decision ... - ENUM_X_DIRECTION decisionTrendDir; - bool hasDecisionTrend = - decisionCycleHelper - .DetectMarketStructure( - decisionTrendDir // - ); - bool hasDecisionBullishTrend = - hasDecisionTrend && - IsBullish(decisionTrendDir); - bool hasDecisionBearishTrend = - hasDecisionTrend && - IsBearish(decisionTrendDir); - // // Detect Bar State ... @@ -730,350 +679,36 @@ bool DetectX121SMCXOBSSignalSetup( ; // - // Detect OrderBlocks ... + // Detect Order Flow ... // - bool hasCOB = - conditions.cOB != NULL && - conditions.cOB.IsValid() && - IsValid(conditions.cOBAt); - - // - if (!hasCOB) + // Test Market For Order Flow ... + int obTestsCount = ArraySize(conditions.obTests); + bool isOBTested = obTestsCount == 2; + if (!isOBTested) { // - int poiEvntsCount = ArraySize(consolidationPoiEvents); - bool hasEvent = IsValidSize(poiEvntsCount); - if (hasEvent) + XOBTest test; + bool hasTest = ReTestMarket( + test, + conditions.obTests, + consolidationState, + analyseState, + decisionState, + visionCycleHelper.mPOIDrawer // + ); + if (hasTest) { // - bool hasNewBullOB = Contains( - X_BULLISH_ORDERBLOCK_DETECTED, - consolidationPoiEvents // - ); - - // - bool hasNewBearOB = Contains( - X_BEARISH_ORDERBLOCK_DETECTED, - consolidationPoiEvents // - ); - - // - bool hasNewOB = - hasNewBullOB || - hasNewBearOB; - - // - if (hasNewOB) - { - // - XCOrderBlock *ob = NULL; - if (hasNewBullOB) - { - // - int lastIDX = consolidationState.CountBullishOrderBlocks() - 1; - ob = consolidationState.bullishOrderBlocks[lastIDX]; - - // - // Validate OB ... - } - else if (hasNewBearOB) - { - // - int lastIDX = consolidationState.CountBearishOrderBlocks() - 1; - ob = consolidationState.bearishOrderBlocks[lastIDX]; - - // - // Validate OB ... - } - - // - if (ob != NULL && ob.IsValid()) - { - // - conditions.cOB = ob; - - // - conditions.cOBAt = cTime; - - // - hasCOB = - conditions.cOB != NULL && - conditions.cOB.IsValid() && - IsValid(conditions.cOBAt); - } - } + AddRef( + test, + conditions.obTests); } } // - if (hasCOB) - { - conditions.cOB.To(cTime); - } - - // - bool hasAOB = - conditions.aOB != NULL && - conditions.aOB.IsValid() && - IsValid(conditions.aOBAt); - - // - if (hasCOB && - !hasAOB) - { - // - int poiEvntsCount = ArraySize(analysePoiEvents); - bool hasEvent = IsValidSize(poiEvntsCount); - if (hasEvent) - { - // - bool hasNewBullOB = Contains( - X_BULLISH_ORDERBLOCK_DETECTED, - analysePoiEvents // - ); - - // - bool hasNewBearOB = Contains( - X_BEARISH_ORDERBLOCK_DETECTED, - analysePoiEvents // - ); - - // - bool hasNewOB = - hasNewBullOB || - hasNewBearOB; - - // - if (hasNewOB) - { - // - XCOrderBlock *ob = NULL; - if (hasNewBullOB) - { - // - int lastIDX = analyseState.CountBullishOrderBlocks() - 1; - ob = analyseState.bullishOrderBlocks[lastIDX]; - - // - // Validate OB ... - } - else if (hasNewBearOB) - { - // - int lastIDX = analyseState.CountBearishOrderBlocks() - 1; - ob = analyseState.bearishOrderBlocks[lastIDX]; - - // - // Validate OB ... - } - - // - if (ob != NULL && ob.IsValid()) - { - // - conditions.aOB = ob; - - // - conditions.aOBAt = cTime; - - // - hasAOB = - conditions.aOB != NULL && - conditions.aOB.IsValid() && - IsValid(conditions.aOBAt); - } - } - } - } - - // - if (hasAOB) - { - conditions.aOB.To(cTime); - } - - // - result = hasCOB && - hasAOB; - if (!result) - { - return result; - } - - // - // DRAW ... - // - - // - // Draw Orer Block ... - bool isBullishCOB = conditions.cOB.IsBullish(); - if (isBullishCOB) - { - // - XCBullishOrderBlockObject *iObj; - bool isCreated = consolidationCycleHelper - .mPOIDrawer - .CreateBullishOrderBlock( - conditions.cOB, - iObj // - ); - } - else - { - // - XCBearishOrderBlockObject *iObj; - bool isCreated = consolidationCycleHelper - .mPOIDrawer - .CreateBearishOrderBlock( - conditions.cOB, - iObj // - ); - } - - bool isBullishAOB = conditions.aOB.IsBullish(); - if (isBullishAOB) - { - // - XCBullishOrderBlockObject *iObj; - bool isCreated = analyseCycleHelper - .mPOIDrawer - .CreateBullishOrderBlock( - conditions.aOB, - iObj // - ); - } - else - { - // - XCBearishOrderBlockObject *iObj; - bool isCreated = analyseCycleHelper - .mPOIDrawer - .CreateBearishOrderBlock( - conditions.aOB, - iObj // - ); - } - - // - // Draw From Bar ... - XOHCL cOBFromBar; - bool hasCOBFromBar = cOBFromBar.Init( - conditions.cOB.GetSymbol(), - conditions.cOB.GetPeriod(), - conditions.cOB.From() // - ); - if (hasCOBFromBar) - { - // - XCOHCLObject *barObject; - bool iCreated = consolidationCycleHelper - .mPOIDrawer - .CreateBar( - cOBFromBar, - barObject // - ); - } - - // - // Draw From Bar ... - XOHCL aOBFromBar; - bool hasAOBFromBar = aOBFromBar.Init( - conditions.aOB.GetSymbol(), - conditions.aOB.GetPeriod(), - conditions.aOB.From() // - ); - if (hasAOBFromBar) - { - // - XCOHCLObject *barObject; - bool iCreated = analyseCycleHelper - .mPOIDrawer - .CreateBar( - aOBFromBar, - barObject // - ); - } - - // - // END DRAW ... - // - - // - // Check AOB Activation ... - if (!conditions.isAOBActivated) - { - // - int aPeakRepetition = analyseCycleHelper.CountPrevPeakRepetition(); - int aValeRepetition = analyseCycleHelper.CountPrevValeRepetition(); - - // - bool isActivated = - // - bid >= conditions.aOB.Lower() && - bid <= conditions.aOB.Upper() && - // - cBar.low >= conditions.aOB.Lower() && - cBar.high <= conditions.aOB.Upper() && - // - (conditions.aOB.IsBullish() - ? decisionXConditions.valesBuffer[1] >= conditions.aOB.Lower() && - decisionXConditions.valesBuffer[1] <= conditions.aOB.Upper() - : decisionXConditions.peaksBuffer[1] >= conditions.aOB.Lower() && - decisionXConditions.peaksBuffer[1] <= conditions.aOB.Upper()) - // - ; - - // - if (isActivated) - { - // - conditions.aOBActivatedAt = cTime; - conditions.isAOBActivated = isActivated; - } - } - - // - // Check COB Activation ... - if (!conditions.isCOBActivated) - { - // - int aPeakRepetition = analyseCycleHelper.CountPrevPeakRepetition(); - int aValeRepetition = analyseCycleHelper.CountPrevValeRepetition(); - - // - bool isActivated = - // - bid >= conditions.cOB.Lower() && - bid <= conditions.cOB.Upper() && - // - cBar.low >= conditions.cOB.Lower() && - cBar.high <= conditions.cOB.Upper() && - // - (conditions.cOB.IsBullish() - ? decisionXConditions.valesBuffer[1] >= conditions.cOB.Lower() && - decisionXConditions.valesBuffer[1] <= conditions.cOB.Upper() - : decisionXConditions.peaksBuffer[1] >= conditions.cOB.Lower() && - decisionXConditions.peaksBuffer[1] <= conditions.cOB.Upper()) - // - ; - - // - if (isActivated) - { - // - conditions.cOBActivatedAt = cTime; - conditions.isCOBActivated = isActivated; - } - } - - // - result = conditions.isAOBActivated || - conditions.isCOBActivated; - if (!result) - { - return result; - } + // TODO: + return false; // double upper = 0; @@ -1607,3 +1242,237 @@ int AddX121SMCXOBSConditionsIfNotExists( } // +// +// + +/** + * Retest Market ... + * + * @param test: XOBTest instance Reference, Represet Result Test ... + * @param tests: XOBTest instance Reference Collection, Represet Founded Tests till now ... + * @param htfState: XPOIState instance Reference ... + * @param mtfState: XPOIState instance Reference ... + * @param ttfState: XPOIState instance Reference ... + * + * @return ( bool ) + */ +bool ReTestMarket( + XOBTest &test, + XOBTest &tests[], + XPOIState &htfState, + XPOIState &mtfState, + XPOIState &ttfState, // + // + XCPOIDrawer *drawer + // +) +{ + // + bool result = false; + + // + test.Clean(); + + // + int testsCount = ArraySize(tests); + bool hasTests = IsValidSize(testsCount); + XOBTest lastTest; + if (hasTests) + { + lastTest = tests[testsCount - 1]; + } + + // + // Detect Order Blocks ... + // HTF ... + + // + // Bullish OBs ... + XCOrderBlock *bullOBs[]; + bool hasYoungestBullOB = false; + XCOrderBlock *youngestBullOB = NULL; + int bullOBsCount = ExtractUnActivatedOBs( + htfState.bullishOrderBlocks, + bullOBs // + ); + + // + bool isBullOBsPassed = bullOBsCount >= 1; + if (isBullOBsPassed) + { + // + XBoxZone boxes[]; + int boxesCount = ToBox( + bullOBs, + boxes // + ); + int youngestBoxIDX = GetYoungest(boxes); + hasYoungestBullOB = IsValidIndex(youngestBoxIDX); + if (hasYoungestBullOB) + { + youngestBullOB = bullOBs[youngestBoxIDX]; + } + } + + // + // Bearish OBs ... + XCOrderBlock *bearOBs[]; + bool hasYoungestBearOB = false; + XCOrderBlock *youngestBearOB = NULL; + int bearOBsCount = ExtractUnActivatedOBs( + htfState.bearishOrderBlocks, + bearOBs // + ); + + // + bool isBearOBsPassed = bearOBsCount >= 1; + if (isBearOBsPassed) + { + // + XBoxZone boxes[]; + int boxesCount = ToBox( + bearOBs, + boxes // + ); + int youngestBoxIDX = GetYoungest(boxes); + hasYoungestBearOB = IsValidIndex(youngestBoxIDX); + if (hasYoungestBearOB) + { + youngestBearOB = bearOBs[youngestBoxIDX]; + } + } + + // + result = isBullOBsPassed || + isBearOBsPassed; + if (!result) + { + return result; + } + + // + // DRAW ... + // + + // + XCBaseObject *drawnObjects[]; + + // + if (hasYoungestBullOB) + { + // + XCBullishOrderBlockObject *iObj; + bool isCreated = drawer + .CreateBullishOrderBlock( + youngestBullOB, + iObj // + ); + + // + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + if (hasYoungestBearOB) + { + // + XCBearishOrderBlockObject *iObj; + bool isCreated = drawer + .CreateBearishOrderBlock( + youngestBearOB, + iObj // + ); + + // + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + // END DRAW ... + // + + // + Print("OBs Passed ..."); + + // + return result; +} + +/** + * Extract UnActivated Order Blocks ... + * + * @return ( int ) + */ +int ExtractUnActivatedOBs( + XCOrderBlock *&source[], + XCOrderBlock *&obs[] // +) +{ + // + int result = 0; + + // + Clean(obs); + + // + int count = ArraySize(source); + bool hasOB = IsValidSize(count); + if (!hasOB) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + bool isBullish = source[i].IsBullish(); + ENUM_X_DIRECTION forDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // + // + + // + XOHCL activatedBar; + ENUM_X_DIRECTION activatedDir; + bool isActivated = source[i].IsActivated( + forDir, + activatedBar, + activatedDir // + ); + if (!isActivated) + { + // + Add( + source[i], + obs // + ); + } + } + + // + result = ArraySize(obs); + + // + return result; +} + +// diff --git a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 index aebd7f37..c7f2ed3b 100644 --- a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 @@ -29,9 +29,6 @@ // #include "../Signals/x-121.smc.x.signal.lib.mq5" #include "../Signals/x-121.smc.xobs.signal.lib.mq5" -#include "../Signals/x-121.smc.xhkpv.signal.lib.mq5" -#include "../Signals/x-121.smc.xobpv.signal.lib.mq5" -#include "../Signals/x-121.smc.xiobpv.signal.lib.mq5" // // Definitions ... @@ -47,9 +44,6 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // Props ... bool useXSignal; bool useXOBSSignal; - bool useXHKPVSignal; - bool useXOBPVSignal; - bool useXIOBPVSignal; // // Constructor(s) ... @@ -68,15 +62,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // Deconstructur ... void ~XCX121SMCStrategy() { - // Destroy(); - - // - Clean(mXConditionsCollection); - Clean(mXOBSConditionsCollection); - Clean(mXHKPVConditionsCollection); - Clean(mXOBPVConditionsCollection); - Clean(mXIOBPVConditionsCollection); } // @@ -117,6 +103,10 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy */ void Destroy() override { + // + Clean(mXConditionsCollection); + Clean(mXOBSConditionsCollection); + // ZeroMemory(mTriggerCycleHelper); ZeroMemory(mDecisionCycleHelper); @@ -212,9 +202,6 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // bool hasXSignal = false; bool hasXOBSSignal = false; - bool hasXHKPVSignal = false; - bool hasXOBPVSignal = false; - bool hasXIOBPVSignal = false; // // X Signal ... @@ -234,33 +221,6 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy hasSignal = hasXOBSSignal; } - // - // XHKPV Signal ... - if (useXHKPVSignal && !hasSignal) - { - // - hasXHKPVSignal = DetectXHKPVSignal(conditions); - hasSignal = hasXHKPVSignal; - } - - // - // XOBPV Signal ... - if (useXOBPVSignal && !hasSignal) - { - // - hasXOBPVSignal = DetectXOBPVSignal(conditions); - hasSignal = hasXOBPVSignal; - } - - // - // XIOBPV Signal ... - if (useXIOBPVSignal && !hasSignal) - { - // - hasXIOBPVSignal = DetectXIOBPVSignal(conditions); - hasSignal = hasXIOBPVSignal; - } - // result = hasSignal; if (!result) @@ -450,57 +410,6 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy ); } - // - // XHKPV Guard Detection ... - if (useXHKPVSignal) - { - // - bool hasGuard = DetectX121SMCXHKPVGuards( - guards, - positions, - mTriggerCycleHelper, - mDecisionCycleHelper, - mAnalyseCycleHelper, - mVerificationCycleHelper, - mConsolidationCycleHelper, - mVisionCycleHelper // - ); - } - - // - // XOBPV Guard Detection ... - if (useXOBPVSignal) - { - // - bool hasGuard = DetectX121SMCXOBPVGuards( - guards, - positions, - mTriggerCycleHelper, - mDecisionCycleHelper, - mAnalyseCycleHelper, - mVerificationCycleHelper, - mConsolidationCycleHelper, - mVisionCycleHelper // - ); - } - - // - // XIOBPV Guard Detection ... - if (useXIOBPVSignal) - { - // - bool hasGuard = DetectX121SMCXIOBPVGuards( - guards, - positions, - mTriggerCycleHelper, - mDecisionCycleHelper, - mAnalyseCycleHelper, - mVerificationCycleHelper, - mConsolidationCycleHelper, - mVisionCycleHelper // - ); - } - // count = ArraySize(guards); result = IsValidSize(count); @@ -992,660 +901,6 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy return result; } - // - // XHKPV Signal ... - bool DetectXHKPVSignal( - X121SMCStrategyConditions &conditions // - ) - { - // - bool result = false; - - // - bool isBullish = false; - bool isBearish = false; - - // - int zIndex = 0; - int cIndex = zIndex + 1; - int pIndex = cIndex + 1; - int ppIndex = pIndex + 1; - - // - string symbol = GetSymbol(); - ENUM_TIMEFRAMES period = GetPeriod(); - - // - XOHCL zBar; - result = zBar.Init( - symbol, - period, - zIndex // - ); - if (!result) - { - return result; - } - - // - XOHCL cBar; - result = cBar.Init( - symbol, - period, - cIndex // - ); - if (!result) - { - return result; - } - - // - XOHCL pBar; - result = pBar.Init( - symbol, - period, - pIndex // - ); - if (!result) - { - return result; - } - - // - double cLL = cBar.FindLowest(7, MODE_LOW); - double cHH = cBar.FindHighest(7, MODE_HIGH); - - // - datetime cTime = TimeCurrent(); - - // - ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XHKPV; - string providerStr = ToString(provider); - - // - // Detect Setup Conditions ... - datetime setupTime = mXHKPVConditions.setupTime; - bool isSetuped = mXHKPVConditions.IsSetuped(); - ENUM_X_DIRECTION setupDir = mXHKPVConditions.dir; - if (!isSetuped) - { - // - // Detect Signal Setup ... - isSetuped = DetectX121SMCXHKPVSignalSetup( - symbol, - period, - mXHKPVConditions, - mTriggerCycleHelper, - mDecisionCycleHelper, - mAnalyseCycleHelper, - mVerificationCycleHelper, - mConsolidationCycleHelper, - mVisionCycleHelper // - ); - - // - setupDir = mXHKPVConditions.dir; - setupTime = mXHKPVConditions.setupTime; - - // - if (isSetuped) - { - // - int items = AddX121SMCXHKPVConditionsIfNotExists( - mXHKPVConditions, - mXHKPVConditionsCollection // - ); - - // - mXHKPVConditions.Clean(); - } - } - - // - int conditionsCount = ArraySize(mXHKPVConditionsCollection); - result = IsValidSize(conditionsCount); - if (!result) - { - return result; - } - - // - // Looking For Conditions ... - int selectedIndex = 0; - X121SMCStrategyXHKPVSignalConditions mTmpConditions[]; - Copy( - mXHKPVConditionsCollection, - mTmpConditions // - ); - X121SMCStrategyXHKPVSignalConditions mConditions; - for (int i = 0; i < conditionsCount; i++) - { - // - // Check Triggers ... - bool canTrigger = mTmpConditions[i].CanTrigger(); - datetime triggerTime = mTmpConditions[i].triggerTime; - if (!canTrigger) - { - // - // Detect Signal Trigger ... - canTrigger = DetectX121SMCXHKPVSignalTrigger( - mTmpConditions[i], - symbol, - period, - mTriggerCycleHelper, - mDecisionCycleHelper, - mAnalyseCycleHelper, - mVerificationCycleHelper, - mConsolidationCycleHelper, - mVisionCycleHelper // - ); - - // - result = canTrigger; - if (!result) - { - // - bool isISetuped = mTmpConditions[i].IsSetuped(); - if (!isISetuped) - { - // - ArrayRemove( - mXHKPVConditionsCollection, - i, - 1 // - ); - } - continue; - } - - // - triggerTime = mTmpConditions[i].triggerTime; - } - - // - if (canTrigger) - { - // - selectedIndex = i; - mConditions = mTmpConditions[i]; - break; - } - } - - // - result = IsValid(mConditions.setupTime) && - HasDirection(mConditions.dir); - if (!result) - { - return result; - } - - // - // Remove Selected Index from Main Collection ... - ArrayRemove( - mXHKPVConditionsCollection, - selectedIndex, - 1 // - ); - - // - // Check Signal Direction ... - isBullish = IsBullish(mConditions.dir); - isBearish = IsBearish(mConditions.dir); - result = isBullish || - isBearish; - if (!result) - { - return result; - } - - // - // Issues Signal on Conditions ... - conditions.sl = mConditions.sl; - conditions.provider = providerStr; - conditions.signalDir = mConditions.dir; - conditions.target = mConditions.target; - - // - return result; - } - - // - // XOBPV Signal ... - bool DetectXOBPVSignal( - X121SMCStrategyConditions &conditions // - ) - { - // - bool result = false; - - // - bool isBullish = false; - bool isBearish = false; - - // - int zIndex = 0; - int cIndex = zIndex + 1; - int pIndex = cIndex + 1; - int ppIndex = pIndex + 1; - - // - string symbol = GetSymbol(); - ENUM_TIMEFRAMES period = GetPeriod(); - - // - XOHCL zBar; - result = zBar.Init( - symbol, - period, - zIndex // - ); - if (!result) - { - return result; - } - - // - XOHCL cBar; - result = cBar.Init( - symbol, - period, - cIndex // - ); - if (!result) - { - return result; - } - - // - XOHCL pBar; - result = pBar.Init( - symbol, - period, - pIndex // - ); - if (!result) - { - return result; - } - - // - double cLL = cBar.FindLowest(7, MODE_LOW); - double cHH = cBar.FindHighest(7, MODE_HIGH); - - // - datetime cTime = TimeCurrent(); - - // - ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XOBPV; - string providerStr = ToString(provider); - - // - // Detect Setup Conditions ... - datetime setupTime = mXOBPVConditions.setupTime; - bool isSetuped = mXOBPVConditions.IsSetuped(); - ENUM_X_DIRECTION setupDir = mXOBPVConditions.dir; - if (!isSetuped) - { - // - // Detect Signal Setup ... - isSetuped = DetectX121SMCXOBPVSignalSetup( - symbol, - period, - mXOBPVConditions, - mTriggerCycleHelper, - mDecisionCycleHelper, - mAnalyseCycleHelper, - mVerificationCycleHelper, - mConsolidationCycleHelper, - mVisionCycleHelper // - ); - - // - setupDir = mXOBPVConditions.dir; - setupTime = mXOBPVConditions.setupTime; - - // - if (isSetuped) - { - // - int items = AddX121SMCXOBPVConditionsIfNotExists( - mXOBPVConditions, - mXOBPVConditionsCollection // - ); - - // - mXOBPVConditions.Clean(); - } - } - - // - int conditionsCount = ArraySize(mXOBPVConditionsCollection); - result = IsValidSize(conditionsCount); - if (!result) - { - return result; - } - - // - // Looking For Conditions ... - int selectedIndex = 0; - X121SMCStrategyXOBPVSignalConditions mTmpConditions[]; - Copy( - mXOBPVConditionsCollection, - mTmpConditions // - ); - X121SMCStrategyXOBPVSignalConditions mConditions; - for (int i = 0; i < conditionsCount; i++) - { - // - // Check Triggers ... - bool canTrigger = mTmpConditions[i].CanTrigger(); - datetime triggerTime = mTmpConditions[i].triggerTime; - if (!canTrigger) - { - // - // Detect Signal Trigger ... - canTrigger = DetectX121SMCXOBPVSignalTrigger( - mTmpConditions[i], - symbol, - period, - mTriggerCycleHelper, - mDecisionCycleHelper, - mAnalyseCycleHelper, - mVerificationCycleHelper, - mConsolidationCycleHelper, - mVisionCycleHelper // - ); - - // - result = canTrigger; - if (!result) - { - // - bool isISetuped = mTmpConditions[i].IsSetuped(); - if (!isISetuped) - { - // - ArrayRemove( - mXOBPVConditionsCollection, - i, - 1 // - ); - } - continue; - } - - // - triggerTime = mTmpConditions[i].triggerTime; - } - - // - if (canTrigger) - { - // - selectedIndex = i; - mConditions = mTmpConditions[i]; - break; - } - } - - // - result = IsValid(mConditions.setupTime) && - HasDirection(mConditions.dir); - if (!result) - { - return result; - } - - // - // Remove Selected Index from Main Collection ... - ArrayRemove( - mXOBPVConditionsCollection, - selectedIndex, - 1 // - ); - - // - // Check Signal Direction ... - isBullish = IsBullish(mConditions.dir); - isBearish = IsBearish(mConditions.dir); - result = isBullish || - isBearish; - if (!result) - { - return result; - } - - // - // Issues Signal on Conditions ... - conditions.sl = mConditions.sl; - conditions.provider = providerStr; - conditions.signalDir = mConditions.dir; - conditions.target = mConditions.target; - - // - return result; - } - - // - // XIOBPV Signal ... - bool DetectXIOBPVSignal( - X121SMCStrategyConditions &conditions // - ) - { - // - bool result = false; - - // - bool isBullish = false; - bool isBearish = false; - - // - int zIndex = 0; - int cIndex = zIndex + 1; - int pIndex = cIndex + 1; - int ppIndex = pIndex + 1; - - // - string symbol = GetSymbol(); - ENUM_TIMEFRAMES period = GetPeriod(); - - // - XOHCL zBar; - result = zBar.Init( - symbol, - period, - zIndex // - ); - if (!result) - { - return result; - } - - // - XOHCL cBar; - result = cBar.Init( - symbol, - period, - cIndex // - ); - if (!result) - { - return result; - } - - // - XOHCL pBar; - result = pBar.Init( - symbol, - period, - pIndex // - ); - if (!result) - { - return result; - } - - // - double cLL = cBar.FindLowest(7, MODE_LOW); - double cHH = cBar.FindHighest(7, MODE_HIGH); - - // - datetime cTime = TimeCurrent(); - - // - ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XIOBPV; - string providerStr = ToString(provider); - - // - // Detect Setup Conditions ... - datetime setupTime = mXIOBPVConditions.setupTime; - bool isSetuped = mXIOBPVConditions.IsSetuped(); - ENUM_X_DIRECTION setupDir = mXIOBPVConditions.dir; - if (!isSetuped) - { - // - // Detect Signal Setup ... - isSetuped = DetectX121SMCXIOBPVSignalSetup( - symbol, - period, - mXIOBPVConditions, - mTriggerCycleHelper, - mDecisionCycleHelper, - mAnalyseCycleHelper, - mVerificationCycleHelper, - mConsolidationCycleHelper, - mVisionCycleHelper // - ); - - // - setupDir = mXIOBPVConditions.dir; - setupTime = mXIOBPVConditions.setupTime; - - // - if (isSetuped) - { - // - int items = AddX121SMCXIOBPVConditionsIfNotExists( - mXIOBPVConditions, - mXIOBPVConditionsCollection // - ); - - // - mXIOBPVConditions.Clean(); - } - } - - // - int conditionsCount = ArraySize(mXIOBPVConditionsCollection); - result = IsValidSize(conditionsCount); - if (!result) - { - return result; - } - - // - // Looking For Conditions ... - int selectedIndex = 0; - X121SMCStrategyXIOBPVSignalConditions mTmpConditions[]; - Copy( - mXIOBPVConditionsCollection, - mTmpConditions // - ); - X121SMCStrategyXIOBPVSignalConditions mConditions; - for (int i = 0; i < conditionsCount; i++) - { - // - // Check Triggers ... - bool canTrigger = mTmpConditions[i].CanTrigger(); - datetime triggerTime = mTmpConditions[i].triggerTime; - if (!canTrigger) - { - // - // Detect Signal Trigger ... - canTrigger = DetectX121SMCXIOBPVSignalTrigger( - mTmpConditions[i], - symbol, - period, - mTriggerCycleHelper, - mDecisionCycleHelper, - mAnalyseCycleHelper, - mVerificationCycleHelper, - mConsolidationCycleHelper, - mVisionCycleHelper // - ); - - // - result = canTrigger; - if (!result) - { - // - bool isISetuped = mTmpConditions[i].IsSetuped(); - if (!isISetuped) - { - // - ArrayRemove( - mXIOBPVConditionsCollection, - i, - 1 // - ); - } - continue; - } - - // - triggerTime = mTmpConditions[i].triggerTime; - } - - // - if (canTrigger) - { - // - selectedIndex = i; - mConditions = mTmpConditions[i]; - break; - } - } - - // - result = IsValid(mConditions.setupTime) && - HasDirection(mConditions.dir); - if (!result) - { - return result; - } - - // - // Remove Selected Index from Main Collection ... - ArrayRemove( - mXIOBPVConditionsCollection, - selectedIndex, - 1 // - ); - - // - // Check Signal Direction ... - isBullish = IsBullish(mConditions.dir); - isBearish = IsBearish(mConditions.dir); - result = isBullish || - isBearish; - if (!result) - { - return result; - } - - // - // Issues Signal on Conditions ... - conditions.sl = mConditions.sl; - conditions.provider = providerStr; - conditions.signalDir = mConditions.dir; - conditions.target = mConditions.target; - - // - return result; - } - // // Private ... private: @@ -1663,9 +918,6 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // useXSignal = false; useXOBSSignal = true; - useXHKPVSignal = false; - useXOBPVSignal = false; - useXIOBPVSignal = false; // string symbol = GetSymbol();