From 195276c221c2723ca4f13f73d172261e8a450f5c Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Thu, 20 Feb 2025 14:25:32 +0330 Subject: [PATCH] last ... --- Classes/x-saherelm.x-cobject.class.mq5 | 28 + Documents/BKP/xsupdem/tmp.signal.mq5 | 213 + Libraries/x-saherelm.x-poi.extensions.lib.mq5 | 4464 +++++++++++++++++ Libraries/x-saherelm.x-poi.lib.mq5 | 4210 +--------------- X121SMCEA/Libraries/x-121.smc.lib.mq5 | 1 + .../Signals/x-121.smc.xwz.signal.class.mq5 | 1117 ++++- .../Signals/x-121.smc.xwz.signal.lib.mq5 | 1359 +++-- .../Strategy/x-121.smc.strategy.class.mq5 | 7 +- 8 files changed, 6853 insertions(+), 4546 deletions(-) create mode 100644 Libraries/x-saherelm.x-poi.extensions.lib.mq5 diff --git a/Classes/x-saherelm.x-cobject.class.mq5 b/Classes/x-saherelm.x-cobject.class.mq5 index 574fbc43..1edcf174 100644 --- a/Classes/x-saherelm.x-cobject.class.mq5 +++ b/Classes/x-saherelm.x-cobject.class.mq5 @@ -2341,6 +2341,34 @@ class XCOHCLObject : public XCBaseObject mLowShadowRect.Fill(value); } + void BarSpes( + int width = 1, + color clr = clrNONE, + ENUM_LINE_STYLE style = STYLE_SOLID, + bool fill = false // + ) + { + // + BodyWidth(width); + LowShadowWidth(width); + HighShadowWidth(width); + + // + BodyColor(clr); + LowShadowColor(clr); + HighShadowColor(clr); + + // + BodyStyle(style); + LowShadowStyle(style); + HighShadowStyle(style); + + // + BodyFill(fill); + LowShadowFill(fill); + HighShadowFill(fill); + } + // // Virtual ... diff --git a/Documents/BKP/xsupdem/tmp.signal.mq5 b/Documents/BKP/xsupdem/tmp.signal.mq5 index e082256d..175f9260 100644 --- a/Documents/BKP/xsupdem/tmp.signal.mq5 +++ b/Documents/BKP/xsupdem/tmp.signal.mq5 @@ -927,13 +927,226 @@ else if (isPriceRejected) ///////////////////////////////////////////////////////////////////////////////////////////////////// + // + // When FVg is Worked ... + else + { + // + XCFVG *fvgs[]; + if (isBullish) + { + // + Copy( + analyseState.bullishFairValueGaps, + fvgs // + ); + } + else + { + // + Copy( + analyseState.bearishFairValueGaps, + fvgs // + ); + } + + // + // int count = ArraySize(fvgs); + // bool has = IsValidSize(count); + // if (has) + // { + // // + // for (int i = 0; i < count; i++) + // { + // // + // XCBaseObject *iObj; + // bool isCreate = visionCycleHelper + // .mPOIDrawer + // .CreateFairValueGap( + // fvgs[i], + // iObj // + // ); + // } + // } + + // + // Extract UnActivated FVGs ... + int fvgsCount = FilterZones( + // + fvgs, + // + trend, + NULL, // For Period ... + workerBar.time, + // + // Start ... + XZONE_STATE_IGNORED, + true, // Force Body Out ... + // + // Activation ... + XZONE_STATE_FAILED, + false, // Force Body Out ... + // + // Breaktion ... + XZONE_STATE_IGNORED, + false, // Force Body Out ... + // + // Works ... + XZONE_STATE_IGNORED, + false, // Body Out ... + // + true, // Apply Sorting ... + true // Ignore Inside ... + ); + + // + bool has = IsValidSize(fvgsCount); + if (has) + { + // + int youngestIDX = GetYoungest(fvgs); + has = IsValidIndex(youngestIDX); + if (has) + { + // + workingZone + .orderFlow[youngestOBFVGIDX] + .fvg = fvgs[youngestIDX]; + + // + workingZone.UpdateTo(cTime); + + // + XCBaseObject *iFVGObj; + bool isCreated = visionCycleHelper + .mPOIDrawer.CreateFairValueGap( + fvgs[youngestIDX], + iFVGObj // + ); + if (isCreated) + { + Print(""); + } + } + } + } ///////////////////////////////////////////////////////////////////////////////////////////////////// + // + // TODO: Neews to Review ... + else if ( + isOBWorked && + isFVGWorked && + isOBActivated && + isFVGActivated && + fvgActivationBar.time >= obActivationBar.time && + fvgActivationBar.time <= obActivationBar.NextAt() && + obWorkerBar.time > fvgWorkerBar.time) + { + // + XOHCL iBar; + bool isBarPassed = iBar.Init( + symbol, + period, + zIndex // + ); + + // + if (isBarPassed) + { + // + bool isBarInsideFVG = + isBullish + ? ( + // + iBar.low < workingZone.orderFlow[youngestOBFVGIDX].fvg.Upper() && + iBar.high > workingZone.orderFlow[youngestOBFVGIDX].fvg.Lower() && + // + consolidationZBar.low < workingZone.orderFlow[youngestOBFVGIDX].fvg.Upper() + // + ) + : ( + // + iBar.high > workingZone.orderFlow[youngestOBFVGIDX].fvg.Lower() && + iBar.low < workingZone.orderFlow[youngestOBFVGIDX].fvg.Upper() && + // + consolidationZBar.high > workingZone.orderFlow[youngestOBFVGIDX].fvg.Lower() + // + ); + if (isBarInsideFVG) + { + Print(""); + } + } + + // + iBar.Clean(); + } ///////////////////////////////////////////////////////////////////////////////////////////////////// + // + // TODO: + // Remove Drawn Objects ... + + // // + // if (hasNewOB) + // { + // // + // XCBaseObject *iObj; + // bool isCreated = visionCycleHelper + // .mPOIDrawer + // .CreateOrderBlock( + // newOB, + // iObj // + // ); + // Print("New OB"); + // } + + // // + // if (hasNewFVG) + // { + // // + // XCBaseObject *iObj; + // bool isCreated = visionCycleHelper + // .mPOIDrawer + // .CreateFairValueGap( + // newFVG, + // iObj // + // ); + // Print("New FVG"); + // } + + // // + // if (hasNewAnalyseOB) + // { + // // + // XCBaseObject *iObj; + // bool isCreated = analyseCycleHelper + // .mPOIDrawer + // .CreateOrderBlock( + // newAnalyseOB, + // iObj // + // ); + // Print("New OB"); + // } + + // // + // if (hasNewAnalyseFVG) + // { + // // + // XCBaseObject *iObj; + // bool isCreated = analyseCycleHelper + // .mPOIDrawer + // .CreateFairValueGap( + // newAnalyseFVG, + // iObj // + // ); + // Print("New FVG"); + // } + ///////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 new file mode 100644 index 00000000..3fb842bd --- /dev/null +++ b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 @@ -0,0 +1,4464 @@ +/////////////////////////////////////////////////////// +// +// 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 "../Libraries/x-saherelm.x-poi.lib.mq5" + +// +// Extensions ... + +/** + * 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 // + ); + + // + } +} + +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; +} + +template +bool ToBox( + T *&source[], + XBoxZone &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) + { + // + XBoxZone iBox; + bool hasBox = ToBox( + iBox, + item // + ); + + // + if (hasBox) + { + // + AddRef( + iBox, + dest // + ); + } + } + } + + // + int destCount = ArraySize(dest); + result = IsValidSize(destCount); + + // + return result; +} + +template +int GetOldest( + T *&sourec[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XBoxZone boxes[]; + bool isConverted = ToBox( + source, + boxes // + ); + if (!isConverted) + { + return result; + } + + // + int boxesCount = ArraySize(boxes); + + // + if (count != boxesCount) + { + return result; + } + + // + result = GetOldest(boxes); + + // + Clean(boxes); + + // + return result; +} + +template +int GetYoungest( + T *&source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XBoxZone boxes[]; + bool isConverted = ToBox( + source, + boxes // + ); + if (!isConverted) + { + return result; + } + + // + int boxesCount = ArraySize(boxes); + + // + if (count != boxesCount) + { + return result; + } + + // + result = GetYoungest(boxes); + + // + Clean(boxes); + + // + return result; +} + +template +int GetLowest( + T *&source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XBoxZone boxes[]; + bool isConverted = ToBox( + source, + boxes // + ); + if (!isConverted) + { + return result; + } + + // + int boxesCount = ArraySize(boxes); + + // + if (count != boxesCount) + { + return result; + } + + // + result = GetLowest(boxes); + + // + Clean(boxes); + + // + return result; +} + +template +int GetHighest( + T *&source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XBoxZone boxes[]; + bool isConverted = ToBox( + source, + boxes // + ); + if (!isConverted) + { + return result; + } + + // + int boxesCount = ArraySize(boxes); + + // + if (count != boxesCount) + { + return result; + } + + // + result = GetHighest(boxes); + + // + Clean(boxes); + + // + return result; +} + +template +bool IsSame( + T *source, + T *dest // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + XBoxZone destBox; + result = ToBox( + destBox, + dest // + ); + if (!result) + { + return result; + } + + // + result = sourceBox.IsSame(destBox); + + // + return result; +} + +template +bool IsSameDiff( + T *source, + F *dest // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + XBoxZone destBox; + result = ToBox( + destBox, + dest // + ); + if (!result) + { + return result; + } + + // + result = sourceBox.IsSame(destBox); + + // + return result; +} + +template +bool IsBelow( + T *source, + T *dest, + bool ignoreInside = false // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + XBoxZone destBox; + result = ToBox( + destBox, + dest // + ); + if (!result) + { + return result; + } + + // + result = IsBoxBelow( + sourceBox, + destBox, + ignoreInside // + ); + + // + return result; +} + +template +bool IsBelowDiff( + T *source, + F *dest, + bool ignoreInside = false // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + XBoxZone destBox; + result = ToBox( + destBox, + dest // + ); + if (!result) + { + return result; + } + + // + result = IsBoxBelow( + sourceBox, + destBox, + ignoreInside // + ); + + // + return result; +} + +template +bool IsAbove( + T *source, + T *dest, + bool ignoreInside = false // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + XBoxZone destBox; + result = ToBox( + destBox, + dest // + ); + if (!result) + { + return result; + } + + // + result = IsBoxAbove( + sourceBox, + destBox, + ignoreInside // + ); + + // + return result; +} + +template +bool IsAboveDiff( + T *source, + F *dest, + bool ignoreInside = false // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + XBoxZone destBox; + result = ToBox( + destBox, + dest // + ); + if (!result) + { + return result; + } + + // + result = IsBoxAbove( + sourceBox, + destBox, + ignoreInside // + ); + + // + return result; +} + +template +bool IsInside( + T *source, + T *dest // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + XBoxZone destBox; + result = ToBox( + destBox, + dest // + ); + if (!result) + { + return result; + } + + // + result = IsBoxInside( + sourceBox, + destBox // + ); + + // + return result; +} + +template +bool IsInsideDiff( + T *source, + F *dest, + bool forceSideOut = false // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + XBoxZone destBox; + result = ToBox( + destBox, + dest // + ); + if (!result) + { + return result; + } + + // + result = IsBoxInside( + sourceBox, + destBox, + forceSideOut // + ); + + // + return result; +} + +template +bool FindIndex( + int &index, + T *item, + T *&items[] // +) +{ + // + bool result = false; + + // + index = -1; + + // + XBoxZone itemBox; + result = ToBox( + itemBox, + item // + ); + if (!result) + { + return result; + } + + // + XBoxZone itemsBox[]; + result = ToBox( + items, + itemsBox // + ); + if (!result) + { + return result; + } + + // + result = FindBoxIndex( + index, + itemBox, + itemsBox // + ); + + // + return result; +} + +template +bool IsInside( + double value, + T *source // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + result = IsInsideBox( + value, + sourceBox // + ); + + // + return result; +} + +template +bool IsAbove( + double value, + T *source // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + result = IsAboveBox( + value, + sourceBox // + ); + + // + return result; +} + +template +bool IsBelow( + double value, + T *source // +) +{ + // + bool result = false; + + // + XBoxZone sourceBox; + result = ToBox( + sourceBox, + source // + ); + if (!result) + { + return result; + } + + // + result = IsBelowBox( + value, + sourceBox // + ); + + // + return result; +} + +/** + * Find Specified Box Index inside a Collection of Boxes ... + * + * @param box: XBoxZone instance Reference ... + * @param boxes: XBoxZone instance Reference Collection ... + * + * @return ( int ) + */ +bool FindBoxIndex( + int &index, + XBoxZone &box, + XBoxZone &boxes[] // +) +{ + // + bool result = false; + + // + index = -1; + + // + int count = ArraySize(boxes); + result = box.IsValid() && + IsValidSize(count); + if (!result) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = boxes[i]; + + // + bool isSame = box.IsSame(iBox); + if (isSame) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; +} + +/** + * Check Source Box is Below Dest ... + * + * @param source: XBoxZone instance Reference ... + * @param dest: XBoxZone instance Reference ... + * @param ignoreInside: bool ... + * + * @return ( bool ) + */ +bool IsBoxBelow( + XBoxZone &source, + XBoxZone &dest, + bool ignoreInside = false // +) +{ + // + bool result = false; + + // + result = source.IsValid() && + dest.IsValid() && + !source.IsSame(dest); + if (!result) + { + return result; + } + + // + if (!ignoreInside) + { + result = source.upper < dest.lower; + } + else + { + result = (source.upper < dest.lower || + source.upper >= dest.upper) && + source.lower < dest.lower; + } + + // + return result; +} + +/** + * Check Source Box is Above Dest ... + * + * @param source: XBoxZone instance Reference ... + * @param dest: XBoxZone instance Reference ... + * @param ignoreInside: bool ... + * + * @return ( bool ) + */ +bool IsBoxAbove( + XBoxZone &source, + XBoxZone &dest, + bool ignoreInside = false // +) +{ + // + bool result = false; + + // + result = source.IsValid() && + dest.IsValid() && + !source.IsSame(dest); + if (!result) + { + return result; + } + + // + if (!ignoreInside) + { + result = source.lower > dest.upper; + } + else + { + result = (source.lower > dest.upper || + source.lower <= dest.upper) && + source.upper > dest.upper; + } + + // + return result; +} + +/** + * Check Source Box is Inside Dest ... + * + * @param source: XBoxZone instance Reference ... + * @param dest: XBoxZone instance Reference ... + * @param forceSideOut: bool, force check Box has One Side Out ... + * @param ignoreSideOut: bool, Accept if source Box one Side is out of Dest Box ... + * + * @return ( bool ) + */ +bool IsBoxInside( + XBoxZone &source, + XBoxZone &dest, + bool forceSideOut = false, // + bool ignoreSideOut = true // +) +{ + // + bool result = false; + + // + result = source.IsValid() && + dest.IsValid() && + !source.IsSame(dest); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(dest.dir); + + // + if (!forceSideOut) + { + // + if (ignoreSideOut) + { + // + result = source.lower >= dest.lower && + source.upper <= dest.upper; + } + else + { + result = source.lower >= dest.lower || + source.upper <= dest.upper; + } + } + else + { + // + bool hasSideIn = + isBullish + ? source.lower >= dest.lower + : source.upper <= dest.upper; + bool hasSideOut = + isBullish + ? source.upper >= dest.upper + : source.lower <= dest.lower; + result = + hasSideIn && + hasSideOut; + } + + // + return result; +} + +/** + * Check Value is Inside Specified Box ... + * + * @param value: double ... + * @param box: XCBozZone instance Reference ... + * + * @return ( bool ) + */ +bool IsInsideBox( + double value, + XBoxZone &box // +) +{ + // + bool result = false; + + // + result = value > 0 && + box.IsValid() && + value <= box.upper && + value >= box.lower; + + // + return result; +} + +/** + * Check Value is Above Specified Box ... + * + * @param value: double ... + * @param box: XCBozZone instance Reference ... + * + * @return ( bool ) + */ +bool IsAboveBox( + double value, + XBoxZone &box // +) +{ + // + bool result = false; + + // + result = value > 0 && + box.IsValid() && + value > box.upper; + + // + return result; +} + +/** + * Check Value is Below Specified Box ... + * + * @param value: double ... + * @param box: XCBozZone instance Reference ... + * + * @return ( bool ) + */ +bool IsBelowBox( + double value, + XBoxZone &box // +) +{ + // + bool result = false; + + // + result = value > 0 && + box.IsValid() && + value < box.lower; + + // + return result; +} + +/** + * Check a Box is Used or not ... + * + * @param box: XBoxZone instance Reference ... + * @param fromIndex: int ... + * @param toIndex: int + * @param forPeriod: Specified Period ... + * + * @return ( bool ) + */ +bool IsBoxUsed( + XBoxZone &box, + int fromIndex, + int toIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // +) +{ + // + bool result = false; + + // + if (toIndex < 0) + { + toIndex = 0; + } + + // + result = + // + box.IsValid() && + fromIndex > 0 && + fromIndex > toIndex + // + ; + if (!result) + { + return result; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = box.period; + } + + // + ENUM_X_DIRECTION forDir = box.dir; + bool isBullish = IsBullish(forDir); + + // + for (int i = fromIndex; i >= toIndex; i--) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + box.symbol, + forPeriod, + i // + ); + + // + bool isTouched = + isBullish + ? iBar.high > box.lower + : iBar.low < box.upper; + if (!isTouched) + { + continue; + } + + // + iBar.Clean(); + result = false; + break; + } + + // + 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; +} + +/** + * Converts to XBoxZone ... + * + * @return ( bool ) + */ +bool ToBox( + XBoxZone &box, + XConsolidationZone &item // +) +{ + // + bool result = false; + + // + box.Clean(); + + // + result = item.IsValid(); + if (!result) + { + return result; + } + + // + box.upper = item.upper; + box.lower = item.lower; + box.dir = item.breakDir; + box.from = item.initTime; + box.symbol = item.symbol; + box.period = item.period; + box.to = item.breakerBar.time; + box.type = "X_CONSOLIDATION_ZONE"; + + // + result = box.IsValid(); + + // + 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; +} + +/** + * Get Oldest Box Index ... + * + * @param source: XBoxZone instance Reference Collection ... + * + * @return ( int ) + */ +int GetOldest( + 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; +} + +/** + * 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; +} + +/** + * Get Highest Box Index ... + * + * @param source: XBoxZone instance Reference Collection ... + * + * @return ( int ) + */ +int GetHighest( + 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.upper < iBox.upper; + if (canSet) + { + // + result = i; + selected = iBox; + } + } + + // + return result; +} + +/** + * Get Lowest Box Index ... + * + * @param source: XBoxZone instance Reference Collection ... + * + * @return ( int ) + */ +int GetLowest( + 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.lower > iBox.lower; + if (canSet) + { + // + result = i; + selected = iBox; + } + } + + // + selected.Clean(); + + // + return result; +} + +// +template +void SortZones( + T *&source[], + ENUM_X_DIRECTION forDir, + bool ignoreInside = true // +) +{ + // + int idx = -1; + int count = 0; + bool has = false; + + // + has = HasDirection(forDir); + if (!has) + { + return; + } + + // + bool isBullish = IsBullish(forDir); + + // + count = ArraySize(source); + has = IsValidSize(count); + if (!has) + { + return; + } + + // + T *tmpItems[]; + T *last = NULL; + bool hasLast = false; + while (HasChild(source)) + { + // + if (!hasLast) + { + // + idx = GetYoungest(source); + hasLast = IsValidIndex(idx); + if (hasLast) + { + // + last = source[idx]; + ArrayRemove( + source, + idx, + 1 // + ); + + // + Add( + last, + source // + ); + } + + // + count = ArraySize(source); + has = IsValidSize(count); + if (!has) + { + // + ZeroMemory(last); + break; + } + } + if (!hasLast) + { + // + ZeroMemory(last); + break; + } + + // + T *item = NULL; + idx = GetYoungest(source); + has = IsValidIndex(idx); + if (!has) + { + // + ZeroMemory(last); + ZeroMemory(item); + break; + } + item = source[idx]; + ArrayRemove( + source, + idx, + 1 // + ); + + // + bool isAbove = IsAbove( + item, + last, + ignoreInside // + ); + + // + bool isBelow = IsBelow( + item, + last, + ignoreInside // + ); + + // + has = + isBullish + ? isAbove + : isBelow; + if (has) + { + // + Add( + item, + tmpItems // + ); + + // + last = item; + hasLast = item != NULL; + } + } + + // + Clean(source); + Copy( + tmpItems, + source // + ); + + // + Clean(tmpItems); +} + +// +template +int FilterZones( + // + T *&source[], + // + ENUM_X_DIRECTION forDir, + ENUM_TIMEFRAMES forPeriod = NULL, + datetime after = NULL, + // + // Start ... + ENUM_XZONE_STATE startState = XZONE_STATE_PASSED, + bool forceStartedBodyOut = false, + // + // Activation ... + ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED, + bool forceActivatedBodyIn = false, + // + // Breaktion ... + ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED, + bool forceBreakedBodyOut = false, + // + // Works ... + ENUM_XZONE_STATE workState = XZONE_STATE_FAILED, + bool forceWorkedBodyOut = false, + // + bool applySort = false, + // + bool ignoreInside = true + // +) +{ + // + int result = 0; + + // + int idx = -1; + int count = 0; + bool has = false; + + // + has = HasDirection(forDir); + if (!has) + { + return result; + } + + // + bool isBullish = IsBullish(forDir); + + // + count = ArraySize(source); + has = IsValidSize(count); + if (!has) + { + return result; + } + + // + T *tmpZones[]; + XOHCL passedBar; + bool isPassed = false; + for (int i = 0; i < count; i++) + { + // + T *iZone = source[i]; + + // + // Apply after Filter ... + isPassed = + !IsValid(after) + ? true + : iZone.From() >= after; + if (!isPassed) + { + // + ZeroMemory(iZone); + continue; + } + + // + // Check Started State ... + if (startState == XZONE_STATE_PASSED || + startState == XZONE_STATE_FAILED) + { + // + bool isBodyOut = false; + bool isStarted = iZone.IsStarted( + forDir, + passedBar, + isBodyOut, + forPeriod // + ); + + // + bool isPassed = + startState == XZONE_STATE_FAILED + ? !isStarted + : !forceStartedBodyOut + ? isStarted + : isStarted && + isBodyOut; + + // + passedBar.Clean(); + if (!isPassed) + { + continue; + } + } + + // + // Check Activation State ... + if (activeState == XZONE_STATE_PASSED || + activeState == XZONE_STATE_FAILED) + { + // + bool isBodyIn = false; + bool isActivated = iZone.IsActivated( + forDir, + passedBar, + isBodyIn, + forceStartedBodyOut, + forPeriod // + ); + + // + bool isPassed = + activeState == XZONE_STATE_FAILED + ? !isActivated + : !forceActivatedBodyIn + ? isActivated + : isActivated && + isBodyIn; + + // + passedBar.Clean(); + if (!isPassed) + { + continue; + } + } + + // + // Check Break State ... + if (breakState == XZONE_STATE_PASSED || + breakState == XZONE_STATE_FAILED) + { + // + bool isBodyOut = false; + bool isBreaked = iZone.IsBreaked( + forDir, + passedBar, + isBodyOut, + forceStartedBodyOut, + forPeriod // + ); + + // + bool isPassed = + breakState == XZONE_STATE_FAILED + ? !isBreaked + : !forceBreakedBodyOut + ? isBreaked + : isBreaked && + isBodyOut; + + // + passedBar.Clean(); + if (!isPassed) + { + continue; + } + } + + // + // Check Work State ... + if (workState == XZONE_STATE_PASSED || + workState == XZONE_STATE_FAILED) + { + // + bool ignoreActivation = activeState != XZONE_STATE_PASSED; + + // + bool isBodyOut = false; + bool isWorked = iZone.IsWorked( + forDir, + passedBar, + isBodyOut, + ignoreActivation, + forceStartedBodyOut, + forceActivatedBodyIn, + forPeriod // + ); + + // + bool isPassed = + workState == XZONE_STATE_FAILED + ? !isWorked + : !forceWorkedBodyOut + ? isWorked + : isWorked && + isBodyOut; + + // + passedBar.Clean(); + if (!isPassed) + { + continue; + } + } + + // + // Check Filtered Zone Doesn't Exists ... + has = FindIndex( + idx, + iZone, + tmpZones // + ); + if (has) + { + // + ZeroMemory(iZone); + passedBar.Clean(); + continue; + } + + // + Add( + iZone, + tmpZones // + ); + } + + // + Clean(source); + + // + has = HasChild(tmpZones); + if (!has) + { + // + Clean(tmpZones); + passedBar.Clean(); + return result; + } + + // + // Apply Sorting ... + if (applySort) + { + // + T *last = NULL; + bool hasLast = false; + while (HasChild(tmpZones)) + { + // + idx = GetYoungest(tmpZones); + hasLast = IsValidIndex(idx); + if (hasLast) + { + // + last = tmpZones[idx]; + ArrayRemove( + tmpZones, + idx, + 1 // + ); + + // + Add( + last, + source // + ); + } + + // + has = HasChild(tmpZones); + if (!has) + { + break; + } + + // + T *zone = NULL; + bool hasZone = false; + idx = GetYoungest(tmpZones); + hasZone = IsValidIndex(idx); + if (hasZone) + { + // + zone = tmpZones[idx]; + ArrayRemove( + tmpZones, + idx, + 1 // + ); + } + if (!hasZone) + { + // + ZeroMemory(zone); + continue; + } + + // + bool isAbove = IsAbove( + zone, + last, + ignoreInside // + ); + + // + bool isBelow = IsBelow( + zone, + last, + ignoreInside // + ); + + // + isPassed = + isBullish + ? isAbove + : isBelow; + if (!isPassed) + { + // + ZeroMemory(zone); + continue; + } + + // + Add( + zone, + source // + ); + } + } + else + { + // + Copy( + tmpZones, + source // + ); + } + + // + result = ArraySize(source); + + // + return result; +} + +// +// +// + +/** + * Extract XOBFVG Collection of Market ... + * + * @param htfState: Higher Time Frame POI State (Used For Detecting Order Blocks) ... + * @param mtfState: Medium Time Frame POI State (Used For Detecting Fair Value Gaps) ... + * @param stfState: Short Time Frame POI State (Used For Detecting Other POI(s)) ... + * @param dest: Result Collection ... + * @param forDir: Market Direction for Detecting POI(s) ... + * @param forPeriod: Time Frame which Used for Zones actions (NULL for Default) ... + * @param startState: Zones Start State ... + * @param forceStartedBodyOut: Zones Started Bar's Body State ... + * @param activeState: Zones Activation State ... + * @param forceActivatedBodyIn: Zones Activated Bar's Body State ... + * @param breakState: Zones Breaked State ... + * @param forceBreakedBodyOut: Zone Breaker Bar's Body State ... + * @param workState: Zones Worked State ... + * @param forceWorkedBodyOut: Zones Worked Bar's Body State ... + * @param applySort: Specify Applying Sorting on Collections ... + * @param applyFromFilter: Filter Sorted Zones based on Occured Date ... + * @param applyPlaceFilter: Filter Sorted Zones based on Occured Place ... + * @param ignoreInside: Ignore Inside Sides of POI(s) Zones in Related to Order Block ... + * @param applyFromFilterForPOIs: Apply From Filter for Other POI(s) ... + * + * @return ( int ) + */ +int ExtractOBFVGZones( + XPOIState &htfState, + XPOIState &mtfState, + XPOIState &stfState, + XOBFVG &dest[], + // + ENUM_X_DIRECTION forDir, + ENUM_TIMEFRAMES forPeriod = NULL, + // + // Start ... + ENUM_XZONE_STATE startState = XZONE_STATE_PASSED, + bool forceStartedBodyOut = false, + // + // Activation ... + ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED, + bool forceActivatedBodyIn = false, + // + // Breaktion ... + ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED, + bool forceBreakedBodyOut = false, + // + // Works ... + ENUM_XZONE_STATE workState = XZONE_STATE_FAILED, + bool forceWorkedBodyOut = false, + // + bool applySort = true, + bool applyFromFilter = true, + bool applyPlaceFilter = true, + // + bool ignoreInside = true, + // + bool detectInsideOBPOIs = true, + bool detectInsideFVGPOIs = true, + bool applyFromFilterForPOIs = true + // +) +{ + // + int result = 0; + + // + Clean(dest); + + // + bool isValid = + // + htfState.HasChild() && + mtfState.HasChild() && + stfState.HasChild() && + HasDirection(forDir) + // + ; + if (!isValid) + { + return result; + } + + // + // Implement Logic ... + + // + int idx = -1; + int count = 0; + bool has = false; + XCFVG *tmpFVGs[]; + XOBFVG tmpOBFVGs[]; + XCOrderBlock *tmpOBs[]; + XCOrderBlock *tmpWorkingOBs[]; + datetime cTime = TimeCurrent(); + bool isBullish = IsBullish(forDir); + + // + if (isBullish) + { + // + has = htfState.HasBullishOrderBlocks(); + if (has) + { + // + Copy( + htfState.bullishOrderBlocks, + tmpOBs // + ); + + // + has = mtfState.HasBullishFairValueGaps(); + if (has) + { + // + Copy( + mtfState.bullishFairValueGaps, + tmpFVGs // + ); + } + } + } + else + { + // + has = htfState.HasBearishOrderBlocks(); + if (has) + { + // + Copy( + htfState.bearishOrderBlocks, + tmpOBs // + ); + + // + has = mtfState.HasBearishFairValueGaps(); + if (has) + { + // + Copy( + mtfState.bearishFairValueGaps, + tmpFVGs // + ); + } + } + } + + // + count = ArraySize(tmpOBs); + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = tmpOBs[i]; + + // + // Check Started State ... + if (startState == XZONE_STATE_PASSED || + startState == XZONE_STATE_FAILED) + { + // + XOHCL passedBar; + bool isBodyOut = false; + bool isStarted = iOB.IsStarted( + forDir, + passedBar, + isBodyOut, + forPeriod // + ); + + // + bool isPassed = + startState == XZONE_STATE_FAILED + ? !isStarted + : !forceStartedBodyOut + ? isStarted + : isStarted && + isBodyOut; + + // + passedBar.Clean(); + if (!isPassed) + { + continue; + } + } + + // + // Check Activation State ... + if (activeState == XZONE_STATE_PASSED || + activeState == XZONE_STATE_FAILED) + { + // + XOHCL passedBar; + bool isBodyIn = false; + bool isActivated = iOB.IsActivated( + forDir, + passedBar, + isBodyIn, + forceStartedBodyOut, + forPeriod // + ); + + // + bool isPassed = + activeState == XZONE_STATE_FAILED + ? !isActivated + : !forceActivatedBodyIn + ? isActivated + : isActivated && + isBodyIn; + + // + passedBar.Clean(); + if (!isPassed) + { + continue; + } + } + + // + // Check Break State ... + if (breakState == XZONE_STATE_PASSED || + breakState == XZONE_STATE_FAILED) + { + // + XOHCL passedBar; + bool isBodyOut = false; + bool isBreaked = iOB.IsBreaked( + forDir, + passedBar, + isBodyOut, + forceStartedBodyOut, + forPeriod // + ); + + // + bool isPassed = + breakState == XZONE_STATE_FAILED + ? !isBreaked + : !forceBreakedBodyOut + ? isBreaked + : isBreaked && + isBodyOut; + + // + passedBar.Clean(); + if (!isPassed) + { + continue; + } + } + + // + // Check Work State ... + if (workState == XZONE_STATE_PASSED || + workState == XZONE_STATE_FAILED) + { + // + bool ignoreActivation = activeState != XZONE_STATE_PASSED; + + // + XOHCL passedBar; + bool isBodyOut = false; + bool isWorked = iOB.IsWorked( + forDir, + passedBar, + isBodyOut, + ignoreActivation, + forceStartedBodyOut, + forceActivatedBodyIn, + forPeriod // + ); + + // + bool isPassed = + workState == XZONE_STATE_FAILED + ? !isWorked + : !forceWorkedBodyOut + ? isWorked + : isWorked && + isBodyOut; + + // + passedBar.Clean(); + if (!isPassed) + { + continue; + } + } + + // + has = FindIndex( + idx, + iOB, + tmpWorkingOBs // + ); + if (has) + { + // + ZeroMemory(iOB); + continue; + } + + // + Add( + iOB, + tmpWorkingOBs // + ); + } + } + + // + // Clean ... + Clean(tmpOBs); + has = HasChild(tmpWorkingOBs); + if (has) + { + // + Clean(tmpOBs); + Copy( + tmpWorkingOBs, + tmpOBs // + ); + + // + Clean(tmpWorkingOBs); + } + + // + // Sorting ... + if (applySort) + { + // + Clean(tmpWorkingOBs); + has = HasChild(tmpOBs); + count = ArraySize(tmpOBs); + + // + // Sorting Applied Only when there is more than one item ... + if (has && count > 1) + { + // + bool hasLast = false; + XCOrderBlock *last = NULL; + while (HasChild(tmpOBs)) + { + // + // Extract First Last Item ... + if (!hasLast) + { + // + idx = + isBullish + ? GetLowest(tmpOBs) + : GetHighest(tmpOBs); + hasLast = IsValidIndex(idx); + if (hasLast) + { + // + last = tmpOBs[idx]; + ArrayRemove( + tmpOBs, + idx, + 1 // + ); + + // + Add( + last, + tmpWorkingOBs // + ); + } + } + + // + has = false; + XCOrderBlock *iOB = NULL; + idx = + isBullish + ? GetLowest(tmpOBs) + : GetHighest(tmpOBs); + has = IsValidIndex(idx); + if (has) + { + // + iOB = tmpOBs[idx]; + ArrayRemove( + tmpOBs, + idx, + 1 // + ); + } + + // + if (!has) + { + break; + } + + // + // Apply From Filter ... + if (applyFromFilter) + { + // + bool isFromPassed = + hasLast && + last.From() < iOB.From(); + if (!isFromPassed) + { + continue; + } + } + + // + // Apply Place Filter ... + if (applyPlaceFilter) + { + // + bool isAbove = + hasLast && + IsAbove( + iOB, + last, + ignoreInside // + ); + + // + bool isBelow = + hasLast && + IsBelow( + iOB, + last, + ignoreInside // + ); + + // + bool isPlacePassed = + isBullish + ? isAbove + : isBelow; + if (!isPlacePassed) + { + continue; + } + } + + // + last = iOB; + Add( + iOB, + tmpWorkingOBs // + ); + } + + // + if (hasLast && + !HasChild(tmpWorkingOBs)) + { + // + Add( + last, + tmpWorkingOBs // + ); + } + } + else + { + // + Copy( + tmpOBs, + tmpWorkingOBs // + ); + } + + // + if (HasChild(tmpWorkingOBs)) + { + // + Copy( + tmpWorkingOBs, + tmpOBs // + ); + } + // + } + + // + count = ArraySize(tmpOBs); + has = IsValidSize(count); + + // + // Converts to XOBFVG ... + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XOBFVG iOBFVG; + + // + iOBFVG.ob = tmpOBs[i]; + + // + AddRef( + iOBFVG, + tmpOBFVGs // + ); + + // + iOBFVG.Clean(); + } + } + + // + Clean(dest); + Clean(tmpOBs); + Clean(tmpWorkingOBs); + + // + // Here we Going to Complete XOBFVGs ... + has = HasChild(tmpOBFVGs); + if (has && HasChild(tmpFVGs)) + { + // + count = ArraySize(tmpOBFVGs); + for (int i = 0; i < count; i++) + { + // + XOBFVG iOBFVG = tmpOBFVGs[i]; + + // + // Detecting FVG ... + XCFVG *tmpWorkingFVGs[]; + for (int j = 0; j < ArraySize(tmpFVGs); j++) + { + // + XCFVG *jFVG = tmpFVGs[j]; + + // + // Check Start Date ... + bool isFromPassed = jFVG.From() > iOBFVG.ob.From(); + if (!isFromPassed) + { + // + ZeroMemory(jFVG); + continue; + } + + // + // Check Place ... + + // + bool isAbove = IsAboveDiff( + jFVG, + iOBFVG.ob, + ignoreInside // + ); + + // + bool isBelow = IsBelowDiff( + jFVG, + iOBFVG.ob, + ignoreInside // + ); + + // + bool isInside = IsInsideDiff( + jFVG, + iOBFVG.ob, + false // + ); + + // + bool isPlacePassed = + isInside || + (isBullish + ? isAbove + : isBelow); + if (!isPlacePassed) + { + // + ZeroMemory(jFVG); + continue; + } + + // + Add( + jFVG, + tmpWorkingFVGs // + ); + } + + // + int fvgsCount = ArraySize(tmpWorkingFVGs); + has = IsValidSize(fvgsCount); + if (has) + { + // + idx = + isBullish + ? GetLowest(tmpWorkingFVGs) + : GetHighest(tmpWorkingFVGs); + + // + if (IsValidIndex(idx)) + { + // + XCFVG *selectedFVG = tmpWorkingFVGs[idx]; + + // + iOBFVG.fvg = selectedFVG; + + // + bool isExists = FindIndex( + idx, + selectedFVG, + tmpFVGs // + ); + if (isExists) + { + // + ArrayRemove( + tmpFVGs, + idx, + 1 // + ); + } + } + } + Clean(tmpWorkingFVGs); + + // + bool isFVGPassed = iOBFVG.HasFVG(); + if (!isFVGPassed) + { + // + iOBFVG.Clean(); + continue; + } + + // + // Validate Model ... + bool isValid = iOBFVG.IsValid(); + if (!isValid) + { + // + iOBFVG.Clean(); + continue; + } + + // + iOBFVG.UpdateTo(cTime); + + // + AddRef( + iOBFVG, + dest // + ); + + // + iOBFVG.Clean(); + } + + // + Clean(tmpOBFVGs); + } + + // + // Detecting Other POI(s) ... + has = HasChild(dest); + bool canDetectPOIs = + detectInsideOBPOIs || + detectInsideFVGPOIs; + if (has && + canDetectPOIs) + { + // + count = ArraySize(dest); + for (int i = 0; i < count; i++) + { + // + // Supply Zones ... + has = stfState.HasSupplyZones(); + if (has) + { + // + for (int j = 0; j < stfState.CountSupplyZones(); j++) + { + // + bool isInsideOB = IsInsideDiff( + stfState.supplyZones[j], + dest[i].ob // + ); + + // + bool isInsideFVG = IsInsideDiff( + stfState.supplyZones[j], + dest[i].fvg // + ); + + // + bool isInside = isInsideOB || + isInsideFVG; + if (isInside) + { + // + bool isPassed = + detectInsideOBPOIs + ? isInsideOB + : detectInsideFVGPOIs + ? isInsideFVG + : false; + if (isPassed) + { + // + isPassed = + !applyFromFilterForPOIs + ? isPassed + : isInsideOB + ? stfState.supplyZones[j].From() > dest[i].ob.From() + : isInsideFVG + ? stfState.supplyZones[j].From() > dest[i].fvg.From() + : false; + } + + // + if (isPassed) + { + // + Add( + stfState.supplyZones[j], + dest[i].supplyZones // + ); + } + } + } + } + + // + // Demand Zones ... + has = stfState.HasDemandZones(); + if (has) + { + // + for (int j = 0; j < stfState.CountDemandZones(); j++) + { + // + bool isInsideOB = IsInsideDiff( + stfState.demandZones[j], + dest[i].ob // + ); + + // + bool isInsideFVG = IsInsideDiff( + stfState.demandZones[j], + dest[i].fvg // + ); + + // + bool isInside = isInsideOB || + isInsideFVG; + if (isInside) + { + // + bool isPassed = + detectInsideOBPOIs + ? isInsideOB + : detectInsideFVGPOIs + ? isInsideFVG + : false; + if (isPassed) + { + // + isPassed = + !applyFromFilterForPOIs + ? isPassed + : isInsideOB + ? stfState.demandZones[j].From() > dest[i].ob.From() + : isInsideFVG + ? stfState.demandZones[j].From() > dest[i].fvg.From() + : false; + } + + // + if (isPassed) + { + // + Add( + stfState.demandZones[j], + dest[i].demandZones // + ); + } + } + } + } + + // + // Support Zones ... + has = stfState.HasSupportZones(); + if (has) + { + // + for (int j = 0; j < stfState.CountSupportZones(); j++) + { + // + bool isInsideOB = IsInsideDiff( + stfState.supportZones[j], + dest[i].ob // + ); + + // + bool isInsideFVG = IsInsideDiff( + stfState.supportZones[j], + dest[i].fvg // + ); + + // + bool isInside = isInsideOB || + isInsideFVG; + if (isInside) + { + // + bool isPassed = + detectInsideOBPOIs + ? isInsideOB + : detectInsideFVGPOIs + ? isInsideFVG + : false; + if (isPassed) + { + // + isPassed = + !applyFromFilterForPOIs + ? isPassed + : isInsideOB + ? stfState.supportZones[j].From() > dest[i].ob.From() + : isInsideFVG + ? stfState.supportZones[j].From() > dest[i].fvg.From() + : false; + } + + // + if (isPassed) + { + // + Add( + stfState.supportZones[j], + dest[i].supportZones // + ); + } + } + } + } + + // + // Resistance Zones ... + has = stfState.HasResistanceZones(); + if (has) + { + // + for (int j = 0; j < stfState.CountResistanceZones(); j++) + { + // + bool isInsideOB = IsInsideDiff( + stfState.resistanceZones[j], + dest[i].ob // + ); + + // + bool isInsideFVG = IsInsideDiff( + stfState.resistanceZones[j], + dest[i].fvg // + ); + + // + bool isInside = isInsideOB || + isInsideFVG; + if (isInside) + { + // + bool isPassed = + detectInsideOBPOIs + ? isInsideOB + : detectInsideFVGPOIs + ? isInsideFVG + : false; + if (isPassed) + { + // + isPassed = + !applyFromFilterForPOIs + ? isPassed + : isInsideOB + ? stfState.resistanceZones[j].From() > dest[i].ob.From() + : isInsideFVG + ? stfState.resistanceZones[j].From() > dest[i].fvg.From() + : false; + } + + // + if (isPassed) + { + // + Add( + stfState.resistanceZones[j], + dest[i].resistanceZones // + ); + } + } + } + } + } + } + + // + Clean(tmpOBs); + Clean(tmpFVGs); + Clean(tmpOBFVGs); + + // + result = ArraySize(dest); + + // + return result; +} + +/** + * Find Highest Order Block of XOBFVG Collection ... + * + * @param source: XOBFVG Collection ... + * + * @return ( int ) + */ +int GetHighest( + XOBFVG &source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + bool has = IsValidSize(count); + if (!has) + { + return result; + } + + // + XOBFVG item; + for (int i = 0; i < count; i++) + { + // + XOBFVG iOBFVG = source[i]; + + // + bool canSet = + !item.IsValid() + ? true + : item.ob.Upper() < iOBFVG.ob.Upper(); + if (canSet) + { + // + item = iOBFVG; + result = i; + } + + // + iOBFVG.Clean(); + } + + // + item.Clean(); + + // + return result; +} + +/** + * Find Lowest Order Block of XOBFVG Collection ... + * + * @param source: XOBFVG Collection ... + * + * @return ( int ) + */ +int GetLowest( + XOBFVG &source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + bool has = IsValidSize(count); + if (!has) + { + return result; + } + + // + XOBFVG item; + for (int i = 0; i < count; i++) + { + // + XOBFVG iOBFVG = source[i]; + + // + bool canSet = + !item.IsValid() + ? true + : item.ob.Lower() > iOBFVG.ob.Lower(); + if (canSet) + { + // + item = iOBFVG; + result = i; + } + + // + iOBFVG.Clean(); + } + + // + item.Clean(); + + // + return result; +} + +/** + * Find Youngest Order Block of XOBFVG Collection ... + * + * @param source: XOBFVG Collection ... + * + * @return ( int ) + */ +int GetYoungest( + XOBFVG &source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + bool has = IsValidSize(count); + if (!has) + { + return result; + } + + // + XOBFVG item; + for (int i = 0; i < count; i++) + { + // + XOBFVG iOBFVG = source[i]; + + // + bool canSet = + !item.IsValid() + ? true + : item.ob.From() < iOBFVG.ob.From(); + if (canSet) + { + // + item = iOBFVG; + result = i; + } + + // + iOBFVG.Clean(); + } + + // + item.Clean(); + + // + return result; +} + +/** + * Find Oldest Order Block of XOBFVG Collection ... + * + * @param source: XOBFVG Collection ... + * + * @return ( int ) + */ +int GetOldest( + XOBFVG &source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + bool has = IsValidSize(count); + if (!has) + { + return result; + } + + // + XOBFVG item; + for (int i = 0; i < count; i++) + { + // + XOBFVG iOBFVG = source[i]; + + // + bool canSet = + !item.IsValid() + ? true + : item.ob.From() > iOBFVG.ob.From(); + if (canSet) + { + // + item = iOBFVG; + result = i; + } + + // + iOBFVG.Clean(); + } + + // + item.Clean(); + + // + return result; +} + +/** + * Sort XOBFVG Collection based on OB Place ... + * + * @param source: XOBFVG instance Collection ... + * @param forDir: ENUM_X_DIRECTION member ... + * @param ignoreInside: Specified Ignoring price inside in Sorting ... + */ +void Sort( + XOBFVG &source[], + ENUM_X_DIRECTION forDir, + bool ignoreInside = true // +) +{ + // + int idx = -1; + int count = 0; + bool has = false; + + // + has = HasDirection(forDir); + if (!has) + { + return; + } + + // + bool isBullish = IsBullish(forDir); + + // + count = ArraySize(source); + has = IsValidSize(count); + if (!has) + { + return; + } + + // + XOBFVG last; + XOBFVG tmpItems[]; + bool hasLast = false; + while (HasChild(source)) + { + // + if (!hasLast) + { + // + idx = GetYoungest(source); + hasLast = IsValidIndex(idx); + if (hasLast) + { + // + last = source[idx]; + ArrayRemove( + source, + idx, + 1 // + ); + + // + AddRef( + last, + source // + ); + } + + // + count = ArraySize(source); + has = IsValidSize(count); + if (!has) + { + // + last.Clean(); + break; + } + } + if (!hasLast) + { + // + ZeroMemory(last); + break; + } + + // + XOBFVG item; + idx = GetYoungest(source); + has = IsValidIndex(idx); + if (!has) + { + // + item.Clean(); + last.Clean(); + break; + } + item = source[idx]; + ArrayRemove( + source, + idx, + 1 // + ); + + // + bool isAbove = IsAbove( + item.ob, + last.ob, + ignoreInside // + ); + + // + bool isBelow = IsBelow( + item.ob, + last.ob, + ignoreInside // + ); + + // + has = + isBullish + ? isAbove + : isBelow; + if (has) + { + // + AddRef( + item, + tmpItems // + ); + + // + last = item; + hasLast = item.IsValid(); + } + } + + // + Clean(source); + Copy( + tmpItems, + source // + ); + + // + Clean(tmpItems); +} + +// +// +// + +/** + * Check Trading Conditions based on Specified Box ... + * + * @param box: XBoxZone instance Reference, specified Box for Checking Conditions ... + * @param appliedBox: XBoxZone instance Reference, hold's Selected Box inside Parent which trading conditions happens on it ... + * @param swingBar: XOHCL instance Reference, holds Swing Bar if Exists ... + * @param breakerBar: XOHCL instance Reference, holds Breaker Bar if Exists ... + * @param rejectionBar: XOHCL instance Reference, holds Rejection Bar if Exists ... + * @param momentumBar: XOHCL instance Reference, holds Momentum Bar if Exists ... + * @param state: XPOIState instance Reference, provides requirement zone's for check Conditions ... + * @param barIndex: int, Specified Bar Index ... + * @param forPeriod: ENUM_TIMEFRAMES member, Specified Conditions Checking Period ... + * + * @return ( bool ) + */ +bool CheckBoxForTradeConditions( + XBoxZone &box, + XBoxZone &appliedBox, + XOHCL &swingBar, + XOHCL &breakerBar, + XOHCL &rejectionBar, + XOHCL &momentumBar, + XPOIState &state, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // +) +{ + // + bool result = false; + + // + swingBar.Clean(); + appliedBox.Clean(); + breakerBar.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + result = box.IsValid() && + state.IsValid() && + state.HasChild(); + if (!result) + { + return result; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = box.period; + } + + // + string symbol = box.symbol; + datetime cTime = iTime( + symbol, + forPeriod, + barIndex // + ); + + // + ENUM_X_DIRECTION forDir = box.dir; + result = HasDirection(forDir); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(forDir); + + // + int supportsCount = 0; + bool hasSupports = false; + XCSupportZone *supports[]; + + // + int resistancesCount = 0; + bool hasResistances = false; + XCResistanceZone *resistances[]; + + // + XBoxZone supResBoxes[]; + int supresBoxesCount = 0; + bool hasSupResBoxes = false; + + // + int count = 0; + bool has = false; + + // + has = state.HasSupportZones(); + if (has) + { + // + count = state.CountSupportZones(); + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iZone = state.supportZones[i]; + + // + iZone.To(cTime); + + // + XBoxZone iBox; + bool hasBox = ToBox( + iBox, + iZone // + ); + if (!hasBox) + { + // + iBox.Clean(); + continue; + } + + // + // Check From ... + bool isInside = IsBoxInside( + iBox, + box // + ); + if (!isInside) + { + // + iBox.Clean(); + continue; + } + + // + Add( + iZone, + supports // + ); + + // + AddRef( + iBox, + supResBoxes // + ); + + // + iBox.Clean(); + } + + // + supportsCount = ArraySize(supports); + hasSupports = IsValidSize(supportsCount); + + // + supresBoxesCount = ArraySize(supResBoxes); + hasSupResBoxes = IsValidSize(supresBoxesCount); + } + + // + has = state.HasResistanceZones(); + if (has) + { + // + count = state.CountResistanceZones(); + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iZone = state.resistanceZones[i]; + + // + iZone.To(cTime); + + // + XBoxZone iBox; + bool hasBox = ToBox( + iBox, + iZone // + ); + if (!hasBox) + { + // + iBox.Clean(); + continue; + } + + // + // Check From ... + bool isInside = IsBoxInside( + iBox, + box // + ); + if (!isInside) + { + // + iBox.Clean(); + continue; + } + + // + Add( + iZone, + resistances // + ); + + // + AddRef( + iBox, + supResBoxes // + ); + + // + iBox.Clean(); + } + + // + resistancesCount = ArraySize(resistances); + hasResistances = IsValidSize(resistancesCount); + + // + supresBoxesCount = ArraySize(supResBoxes); + hasSupResBoxes = IsValidSize(supresBoxesCount); + } + + // + result = hasSupResBoxes; + if (!result) + { + // + Clean(supports); + Clean(resistances); + Clean(supResBoxes); + + // + return result; + } + + // + // Detect Bars ... + + // + XOHCL zBar; + result = zBar.Init( + symbol, + forPeriod, + barIndex // + ); + if (!result) + { + // + zBar.Clean(); + Clean(supports); + Clean(resistances); + Clean(supResBoxes); + + // + return result; + } + + // + XOHCL cBar; + result = zBar.GetPreviousBar(cBar); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + Clean(supports); + Clean(resistances); + Clean(supResBoxes); + + // + return result; + } + + // + XOHCL pBar; + result = cBar.GetPreviousBar(pBar); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + Clean(supports); + Clean(resistances); + Clean(supResBoxes); + + // + return result; + } + + // + XOHCL ppBar; + result = pBar.GetPreviousBar(ppBar); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + Clean(supports); + Clean(resistances); + Clean(supResBoxes); + + // + return result; + } + // + // Check Conditions ... + + // + // Detect Start Senario ... + + // + double fiboPressureLevel = GetFiboLevelValue(X_FIBO_LEVEL_382); + + // + double fiboUpDown = GetFibonacciLevel( + pBar.high, + pBar.low, + X_FIBO_LEVEL_382, + X_DIRECTION_BEARISH // + ); + double fiboDownUp = GetFibonacciLevel( + pBar.high, + pBar.low, + X_FIBO_LEVEL_382, + X_DIRECTION_BULLISH // + ); + + // + bool hasFiboToUpPressure = + fiboDownUp > 0 && + fiboDownUp <= pBar.GetDown(); + bool hasFiboToDownPressure = + fiboUpDown > 0 && + fiboUpDown >= pBar.GetUp(); + + // + int selectedBoxIDX = -1; + for (int j = 0; j < supresBoxesCount; j++) + { + // + double appliedPrice = + isBullish + ? supResBoxes[j].lower + : supResBoxes[j].upper; + + // + // Check Swing Low ... + bool isSwingLow = + // + pBar.low < ppBar.low && + pBar.low < cBar.low && + zBar.open > pBar.low && + // + appliedPrice > pBar.low && + appliedPrice < pBar.GetDown() + // + ; + bool isPressuredSwingLow = + isSwingLow && + hasFiboToUpPressure; + bool isPressuredStrongSwingLow = + pBar.IsBullish() && + isPressuredSwingLow; + + // + bool isSwingHigh = + // + pBar.high > ppBar.high && + pBar.high > cBar.high && + zBar.open < pBar.high && + // + appliedPrice < pBar.high && + appliedPrice > pBar.GetUp() + // + ; + bool isPressuredSwingHigh = + isSwingHigh && + hasFiboToDownPressure; + bool isPressuredStrongSwingHigh = + pBar.IsBearish() && + isPressuredSwingHigh; + + // + bool hasValidSwing = + isBullish + ? isSwingLow + : isSwingHigh; + bool hasValidPressuredSwing = + isBullish + ? isPressuredSwingLow + : isPressuredSwingHigh; + bool hasValidPressuredStrongSwing = + isBullish + ? isPressuredStrongSwingLow + : isPressuredStrongSwingHigh; + if (hasValidSwing) + { + swingBar = pBar; + } + if (hasValidPressuredSwing) + { + swingBar = pBar; + } + if (hasValidPressuredStrongSwing) + { + swingBar = pBar; + } + + // + bool isCBarBreaked = IsBarBreak( + appliedPrice, + forDir, + cBar // + ); + if (isCBarBreaked) + { + breakerBar = cBar; + } + bool isPBarBreaked = IsBarBreak( + appliedPrice, + forDir, + pBar // + ); + if (!isCBarBreaked && isPBarBreaked) + { + breakerBar = pBar; + } + else + { + isPBarBreaked = false; + } + bool isPPBarBreaked = IsBarBreak( + appliedPrice, + forDir, + ppBar // + ); + if (!isCBarBreaked && + !isPBarBreaked && + isPPBarBreaked) + { + breakerBar = ppBar; + } + else + { + isPPBarBreaked = false; + } + bool isBoxBreaked = isCBarBreaked || + isPBarBreaked || + isPPBarBreaked; + + // + bool isCBarRejected = IsBarReject( + appliedPrice, + forDir, + cBar // + ); + if (isCBarRejected) + { + rejectionBar = cBar; + } + bool isPBarRejected = IsBarReject( + appliedPrice, + forDir, + pBar // + ); + if (!isCBarRejected && isPBarRejected) + { + rejectionBar = pBar; + } + else + { + isPBarRejected = false; + } + bool isPPBarRejected = IsBarReject( + appliedPrice, + forDir, + ppBar // + ); + if (!isCBarRejected && + !isPBarRejected && + isPPBarRejected) + { + rejectionBar = ppBar; + } + else + { + isPPBarRejected = false; + } + bool isBoxRejected = isCBarRejected || + isPBarRejected || + isPPBarRejected; + + // + bool hasRejectionBar = false; + if (isBullish) + { + // + count = state.CountBullishRejectionBars(); + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iZone = state.bullishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + int iBarIndex = iBar.Index(); + + // + hasRejectionBar = + // + (iBarIndex == cBar.Index() || + iBarIndex == pBar.Index()) + // + ; + if (hasRejectionBar) + { + // + if (!rejectionBar.IsValid()) + { + rejectionBar = iBar; + } + + // + break; + } + } + } + else + { + // + count = state.CountBearishRejectionBars(); + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iZone = state.bearishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + int iBarIndex = iBar.Index(); + + // + hasRejectionBar = + // + (iBarIndex == cBar.Index() || + iBarIndex == pBar.Index()) + // + ; + if (hasRejectionBar) + { + // + if (!rejectionBar.IsValid()) + { + rejectionBar = iBar; + } + + // + break; + } + } + } + + // + bool hasMomentumBar = false; + if (isBullish) + { + // + count = state.CountBullishMomentumBars(); + for (int i = 0; i < count; i++) + { + // + XCMomentumBar *iZone = state.bullishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + int iBarIndex = iBar.Index(); + + // + hasMomentumBar = + // + (iBarIndex == cBar.Index() || + iBarIndex == pBar.Index()) + // + ; + if (hasMomentumBar) + { + // + if (!momentumBar.IsValid()) + { + momentumBar = iBar; + } + + // + break; + } + } + } + else + { + // + count = state.CountBearishMomentumBars(); + for (int i = 0; i < count; i++) + { + // + XCMomentumBar *iZone = state.bearishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + int iBarIndex = iBar.Index(); + + // + hasMomentumBar = + // + (iBarIndex == cBar.Index() || + iBarIndex == pBar.Index()) + // + ; + if (hasMomentumBar) + { + // + if (!momentumBar.IsValid()) + { + momentumBar = iBar; + } + + // + break; + } + } + } + + // + bool hasSwing = false; + if (isBullish) + { + // + count = state.CountSwingLows(); + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = state.swingLows[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + int iBarIndex = iBar.Index(); + + // + hasSwing = + // + (iBarIndex == cBar.Index() || + iBarIndex == pBar.Index()) + // + ; + if (hasSwing) + { + // + if (!swingBar.IsValid()) + { + swingBar = iBar; + } + + // + break; + } + } + } + else + { + // + count = state.CountSwingHighs(); + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = state.swingHighs[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + int iBarIndex = iBar.Index(); + + // + hasSwing = + // + (iBarIndex == cBar.Index() || + iBarIndex == pBar.Index()) + // + ; + if (hasSwing) + { + // + if (!swingBar.IsValid()) + { + swingBar = iBar; + } + + // + break; + } + } + } + + // + bool hasRequiredValidations = + // + (hasRejectionBar || + hasMomentumBar) + // + || + // + (hasRejectionBar || + hasSwing) + // + || + // + (hasMomentumBar || + hasSwing) + // + ; + + // + result = + // + (isBoxBreaked && + (hasRequiredValidations || + hasValidPressuredSwing)) + // + || + // + (isBoxRejected && + (hasRequiredValidations || + hasValidPressuredSwing)) + // + ; + if (result) + { + // + selectedBoxIDX = j; + break; + } + } + + // + result = + result && + (isBullish + ? zBar.open > box.upper + : zBar.open < box.lower) && + IsValidIndex(selectedBoxIDX); + if (result) + { + appliedBox = supResBoxes[selectedBoxIDX]; + } + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + Clean(supports); + Clean(resistances); + Clean(supResBoxes); + + // + return result; +} diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 313cb567..a8b4e3e4 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -134,6 +134,256 @@ enum ENUM_XSESSION X_FRANKFORT, }; +/** + * 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; +} + // // Implementation ... @@ -1270,9 +1520,9 @@ class XCBarZone : public XCZone { // result = isBreaked && - isBullish - ? isBreakedFromLower - : isBreakedFromUpper; + (isBullish + ? isBreakedFromLower + : isBreakedFromUpper); if (result) { // @@ -2358,9 +2608,9 @@ class XCTwoBarZone : public XCZone { // result = isBreaked && - isBullish - ? isBreakedFromLower - : isBreakedFromUpper; + (isBullish + ? isBreakedFromLower + : isBreakedFromUpper); if (result) { // @@ -6467,3952 +6717,4 @@ struct XOBFVG } }; -// -// 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; -} - -// -// -// - -/** - * 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 // - ); - - // - } -} - -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; -} - -template -bool ToBox( - T *&source[], - XBoxZone &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) - { - // - XBoxZone iBox; - bool hasBox = ToBox( - iBox, - item // - ); - - // - if (hasBox) - { - // - AddRef( - iBox, - dest // - ); - } - } - } - - // - int destCount = ArraySize(dest); - result = IsValidSize(destCount); - - // - return result; -} - -template -int GetOldest( - T *&sourec[] // -) -{ - // - int result = -1; - - // - int count = ArraySize(source); - if (!IsValidSize(count)) - { - return result; - } - - // - XBoxZone boxes[]; - bool isConverted = ToBox( - source, - boxes // - ); - if (!isConverted) - { - return result; - } - - // - int boxesCount = ArraySize(boxes); - - // - if (count != boxesCount) - { - return result; - } - - // - result = GetOldest(boxes); - - // - Clean(boxes); - - // - return result; -} - -template -int GetYoungest( - T *&source[] // -) -{ - // - int result = -1; - - // - int count = ArraySize(source); - if (!IsValidSize(count)) - { - return result; - } - - // - XBoxZone boxes[]; - bool isConverted = ToBox( - source, - boxes // - ); - if (!isConverted) - { - return result; - } - - // - int boxesCount = ArraySize(boxes); - - // - if (count != boxesCount) - { - return result; - } - - // - result = GetYoungest(boxes); - - // - Clean(boxes); - - // - return result; -} - -template -int GetLowest( - T *&source[] // -) -{ - // - int result = -1; - - // - int count = ArraySize(source); - if (!IsValidSize(count)) - { - return result; - } - - // - XBoxZone boxes[]; - bool isConverted = ToBox( - source, - boxes // - ); - if (!isConverted) - { - return result; - } - - // - int boxesCount = ArraySize(boxes); - - // - if (count != boxesCount) - { - return result; - } - - // - result = GetLowest(boxes); - - // - Clean(boxes); - - // - return result; -} - -template -int GetHighest( - T *&source[] // -) -{ - // - int result = -1; - - // - int count = ArraySize(source); - if (!IsValidSize(count)) - { - return result; - } - - // - XBoxZone boxes[]; - bool isConverted = ToBox( - source, - boxes // - ); - if (!isConverted) - { - return result; - } - - // - int boxesCount = ArraySize(boxes); - - // - if (count != boxesCount) - { - return result; - } - - // - result = GetHighest(boxes); - - // - Clean(boxes); - - // - return result; -} - -template -bool IsSame( - T *source, - T *dest // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - XBoxZone destBox; - result = ToBox( - destBox, - dest // - ); - if (!result) - { - return result; - } - - // - result = sourceBox.IsSame(destBox); - - // - return result; -} - -template -bool IsSameDiff( - T *source, - F *dest // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - XBoxZone destBox; - result = ToBox( - destBox, - dest // - ); - if (!result) - { - return result; - } - - // - result = sourceBox.IsSame(destBox); - - // - return result; -} - -template -bool IsBelow( - T *source, - T *dest, - bool ignoreInside = false // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - XBoxZone destBox; - result = ToBox( - destBox, - dest // - ); - if (!result) - { - return result; - } - - // - result = IsBoxBelow( - sourceBox, - destBox, - ignoreInside // - ); - - // - return result; -} - -template -bool IsBelowDiff( - T *source, - F *dest, - bool ignoreInside = false // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - XBoxZone destBox; - result = ToBox( - destBox, - dest // - ); - if (!result) - { - return result; - } - - // - result = IsBoxBelow( - sourceBox, - destBox, - ignoreInside // - ); - - // - return result; -} - -template -bool IsAbove( - T *source, - T *dest, - bool ignoreInside = false // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - XBoxZone destBox; - result = ToBox( - destBox, - dest // - ); - if (!result) - { - return result; - } - - // - result = IsBoxAbove( - sourceBox, - destBox, - ignoreInside // - ); - - // - return result; -} - -template -bool IsAboveDiff( - T *source, - F *dest, - bool ignoreInside = false // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - XBoxZone destBox; - result = ToBox( - destBox, - dest // - ); - if (!result) - { - return result; - } - - // - result = IsBoxAbove( - sourceBox, - destBox, - ignoreInside // - ); - - // - return result; -} - -template -bool IsInside( - T *source, - T *dest // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - XBoxZone destBox; - result = ToBox( - destBox, - dest // - ); - if (!result) - { - return result; - } - - // - result = IsBoxInside( - sourceBox, - destBox // - ); - - // - return result; -} - -template -bool IsInsideDiff( - T *source, - F *dest, - bool forceSideOut = false // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - XBoxZone destBox; - result = ToBox( - destBox, - dest // - ); - if (!result) - { - return result; - } - - // - result = IsBoxInside( - sourceBox, - destBox, - forceSideOut // - ); - - // - return result; -} - -template -bool FindIndex( - int &index, - T *item, - T *&items[] // -) -{ - // - bool result = false; - - // - index = -1; - - // - XBoxZone itemBox; - result = ToBox( - itemBox, - item // - ); - if (!result) - { - return result; - } - - // - XBoxZone itemsBox[]; - result = ToBox( - items, - itemsBox // - ); - if (!result) - { - return result; - } - - // - result = FindBoxIndex( - index, - itemBox, - itemsBox // - ); - - // - return result; -} - -template -bool IsInside( - double value, - T *source // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - result = IsInsideBox( - value, - sourceBox // - ); - - // - return result; -} - -template -bool IsAbove( - double value, - T *source // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - result = IsAboveBox( - value, - sourceBox // - ); - - // - return result; -} - -template -bool IsBelow( - double value, - T *source // -) -{ - // - bool result = false; - - // - XBoxZone sourceBox; - result = ToBox( - sourceBox, - source // - ); - if (!result) - { - return result; - } - - // - result = IsBelowBox( - value, - sourceBox // - ); - - // - return result; -} - -/** - * Find Specified Box Index inside a Collection of Boxes ... - * - * @param box: XBoxZone instance Reference ... - * @param boxes: XBoxZone instance Reference Collection ... - * - * @return ( int ) - */ -bool FindBoxIndex( - int &index, - XBoxZone &box, - XBoxZone &boxes[] // -) -{ - // - bool result = false; - - // - index = -1; - - // - int count = ArraySize(boxes); - result = box.IsValid() && - IsValidSize(count); - if (!result) - { - return result; - } - - // - for (int i = 0; i < count; i++) - { - // - XBoxZone iBox = boxes[i]; - - // - bool isSame = box.IsSame(iBox); - if (isSame) - { - // - index = i; - break; - } - } - - // - result = IsValidIndex(index); - - // - return result; -} - -/** - * Check Source Box is Below Dest ... - * - * @param source: XBoxZone instance Reference ... - * @param dest: XBoxZone instance Reference ... - * @param ignoreInside: bool ... - * - * @return ( bool ) - */ -bool IsBoxBelow( - XBoxZone &source, - XBoxZone &dest, - bool ignoreInside = false // -) -{ - // - bool result = false; - - // - result = source.IsValid() && - dest.IsValid() && - !source.IsSame(dest); - if (!result) - { - return result; - } - - // - if (!ignoreInside) - { - result = source.upper < dest.lower; - } - else - { - result = (source.upper < dest.lower || - source.upper >= dest.upper) && - source.lower < dest.lower; - } - - // - return result; -} - -/** - * Check Source Box is Above Dest ... - * - * @param source: XBoxZone instance Reference ... - * @param dest: XBoxZone instance Reference ... - * @param ignoreInside: bool ... - * - * @return ( bool ) - */ -bool IsBoxAbove( - XBoxZone &source, - XBoxZone &dest, - bool ignoreInside = false // -) -{ - // - bool result = false; - - // - result = source.IsValid() && - dest.IsValid() && - !source.IsSame(dest); - if (!result) - { - return result; - } - - // - if (!ignoreInside) - { - result = source.lower > dest.upper; - } - else - { - result = (source.lower > dest.upper || - source.lower <= dest.upper) && - source.upper > dest.upper; - } - - // - return result; -} - -/** - * Check Source Box is Inside Dest ... - * - * @param source: XBoxZone instance Reference ... - * @param dest: XBoxZone instance Reference ... - * @param forceSideOut: bool, force check Box has One Side Out ... - * @param ignoreSideOut: bool, Accept if source Box one Side is out of Dest Box ... - * - * @return ( bool ) - */ -bool IsBoxInside( - XBoxZone &source, - XBoxZone &dest, - bool forceSideOut = false, // - bool ignoreSideOut = true // -) -{ - // - bool result = false; - - // - result = source.IsValid() && - dest.IsValid() && - !source.IsSame(dest); - if (!result) - { - return result; - } - - // - bool isBullish = IsBullish(dest.dir); - - // - if (!forceSideOut) - { - // - if (ignoreSideOut) - { - // - result = source.lower >= dest.lower && - source.upper <= dest.upper; - } - else - { - result = source.lower >= dest.lower || - source.upper <= dest.upper; - } - } - else - { - // - bool hasSideIn = - isBullish - ? source.lower >= dest.lower - : source.upper <= dest.upper; - bool hasSideOut = - isBullish - ? source.upper >= dest.upper - : source.lower <= dest.lower; - result = - hasSideIn && - hasSideOut; - } - - // - return result; -} - -/** - * Check Value is Inside Specified Box ... - * - * @param value: double ... - * @param box: XCBozZone instance Reference ... - * - * @return ( bool ) - */ -bool IsInsideBox( - double value, - XBoxZone &box // -) -{ - // - bool result = false; - - // - result = value > 0 && - box.IsValid() && - value <= box.upper && - value >= box.lower; - - // - return result; -} - -/** - * Check Value is Above Specified Box ... - * - * @param value: double ... - * @param box: XCBozZone instance Reference ... - * - * @return ( bool ) - */ -bool IsAboveBox( - double value, - XBoxZone &box // -) -{ - // - bool result = false; - - // - result = value > 0 && - box.IsValid() && - value > box.upper; - - // - return result; -} - -/** - * Check Value is Below Specified Box ... - * - * @param value: double ... - * @param box: XCBozZone instance Reference ... - * - * @return ( bool ) - */ -bool IsBelowBox( - double value, - XBoxZone &box // -) -{ - // - bool result = false; - - // - result = value > 0 && - box.IsValid() && - value < box.lower; - - // - return result; -} - -/** - * Check a Box is Used or not ... - * - * @param box: XBoxZone instance Reference ... - * @param fromIndex: int ... - * @param toIndex: int - * @param forPeriod: Specified Period ... - * - * @return ( bool ) - */ -bool IsBoxUsed( - XBoxZone &box, - int fromIndex, - int toIndex = 0, - ENUM_TIMEFRAMES forPeriod = NULL // -) -{ - // - bool result = false; - - // - if (toIndex < 0) - { - toIndex = 0; - } - - // - result = - // - box.IsValid() && - fromIndex > 0 && - fromIndex > toIndex - // - ; - if (!result) - { - return result; - } - - // - if (!IsValid(forPeriod)) - { - forPeriod = box.period; - } - - // - ENUM_X_DIRECTION forDir = box.dir; - bool isBullish = IsBullish(forDir); - - // - for (int i = fromIndex; i >= toIndex; i--) - { - // - XOHCL iBar; - bool isInited = iBar.Init( - box.symbol, - forPeriod, - i // - ); - - // - bool isTouched = - isBullish - ? iBar.high > box.lower - : iBar.low < box.upper; - if (!isTouched) - { - continue; - } - - // - iBar.Clean(); - result = false; - break; - } - - // - 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; -} - -/** - * Converts to XBoxZone ... - * - * @return ( bool ) - */ -bool ToBox( - XBoxZone &box, - XConsolidationZone &item // -) -{ - // - bool result = false; - - // - box.Clean(); - - // - result = item.IsValid(); - if (!result) - { - return result; - } - - // - box.upper = item.upper; - box.lower = item.lower; - box.dir = item.breakDir; - box.from = item.initTime; - box.symbol = item.symbol; - box.period = item.period; - box.to = item.breakerBar.time; - box.type = "X_CONSOLIDATION_ZONE"; - - // - result = box.IsValid(); - - // - 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; -} - -/** - * Get Oldest Box Index ... - * - * @param source: XBoxZone instance Reference Collection ... - * - * @return ( int ) - */ -int GetOldest( - 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; -} - -/** - * 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; -} - -/** - * Get Highest Box Index ... - * - * @param source: XBoxZone instance Reference Collection ... - * - * @return ( int ) - */ -int GetHighest( - 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.upper < iBox.upper; - if (canSet) - { - // - result = i; - selected = iBox; - } - } - - // - return result; -} - -/** - * Get Lowest Box Index ... - * - * @param source: XBoxZone instance Reference Collection ... - * - * @return ( int ) - */ -int GetLowest( - 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.lower > iBox.lower; - if (canSet) - { - // - result = i; - selected = iBox; - } - } - - // - selected.Clean(); - - // - return result; -} - -// -// -// - -/** - * Extract XOBFVG Collection of Market ... - * - * @param htfState: Higher Time Frame POI State (Used For Detecting Order Blocks) ... - * @param mtfState: Medium Time Frame POI State (Used For Detecting Fair Value Gaps) ... - * @param stfState: Short Time Frame POI State (Used For Detecting Other POI(s)) ... - * @param dest: Result Collection ... - * @param forDir: Market Direction for Detecting POI(s) ... - * @param forPeriod: Time Frame which Used for Zones actions (NULL for Default) ... - * @param startState: Zones Start State ... - * @param forceStartedBodyOut: Zones Started Bar's Body State ... - * @param activeState: Zones Activation State ... - * @param forceActivatedBodyIn: Zones Activated Bar's Body State ... - * @param breakState: Zones Breaked State ... - * @param forceBreakedBodyOut: Zone Breaker Bar's Body State ... - * @param workState: Zones Worked State ... - * @param forceWorkedBodyOut: Zones Worked Bar's Body State ... - * @param applySort: Specify Applying Sorting on Collections ... - * @param applyFromFilter: Filter Sorted Zones based on Occured Date ... - * @param applyPlaceFilter: Filter Sorted Zones based on Occured Place ... - * @param ignoreInside: Ignore Inside Sides of POI(s) Zones in Related to Order Block ... - * @param applyFromFilterForPOIs: Apply From Filter for Other POI(s) ... - * - * @return ( int ) - */ -int ExtractOBFVGZones( - XPOIState &htfState, - XPOIState &mtfState, - XPOIState &stfState, - XOBFVG &dest[], - // - ENUM_X_DIRECTION forDir, - ENUM_TIMEFRAMES forPeriod = NULL, - // - // Start ... - ENUM_XZONE_STATE startState = XZONE_STATE_PASSED, - bool forceStartedBodyOut = false, - // - // Activation ... - ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED, - bool forceActivatedBodyIn = false, - // - // Breaktion ... - ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED, - bool forceBreakedBodyOut = false, - // - // Works ... - ENUM_XZONE_STATE workState = XZONE_STATE_FAILED, - bool forceWorkedBodyOut = false, - // - bool applySort = true, - bool applyFromFilter = true, - bool applyPlaceFilter = true, - // - bool ignoreInside = true, - // - bool detectInsideOBPOIs = true, - bool detectInsideFVGPOIs = true, - bool applyFromFilterForPOIs = true - // -) -{ - // - int result = 0; - - // - Clean(dest); - - // - bool isValid = - // - htfState.HasChild() && - mtfState.HasChild() && - stfState.HasChild() && - HasDirection(forDir) - // - ; - if (!isValid) - { - return result; - } - - // - // Implement Logic ... - - // - int idx = -1; - int count = 0; - bool has = false; - XCFVG *tmpFVGs[]; - XOBFVG tmpOBFVGs[]; - XCOrderBlock *tmpOBs[]; - XCOrderBlock *tmpWorkingOBs[]; - datetime cTime = TimeCurrent(); - bool isBullish = IsBullish(forDir); - - // - if (isBullish) - { - // - has = htfState.HasBullishOrderBlocks(); - if (has) - { - // - Copy( - htfState.bullishOrderBlocks, - tmpOBs // - ); - - // - has = mtfState.HasBullishFairValueGaps(); - if (has) - { - // - Copy( - mtfState.bullishFairValueGaps, - tmpFVGs // - ); - } - } - } - else - { - // - has = htfState.HasBearishOrderBlocks(); - if (has) - { - // - Copy( - htfState.bearishOrderBlocks, - tmpOBs // - ); - - // - has = mtfState.HasBearishFairValueGaps(); - if (has) - { - // - Copy( - mtfState.bearishFairValueGaps, - tmpFVGs // - ); - } - } - } - - // - count = ArraySize(tmpOBs); - has = IsValidSize(count); - if (has) - { - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock *iOB = tmpOBs[i]; - - // - // Check Started State ... - if (startState == XZONE_STATE_PASSED || - startState == XZONE_STATE_FAILED) - { - // - XOHCL passedBar; - bool isBodyOut = false; - bool isStarted = iOB.IsStarted( - forDir, - passedBar, - isBodyOut, - forPeriod // - ); - - // - bool isPassed = - startState == XZONE_STATE_FAILED - ? !isStarted - : !forceStartedBodyOut - ? isStarted - : isStarted && - isBodyOut; - - // - passedBar.Clean(); - if (!isPassed) - { - continue; - } - } - - // - // Check Activation State ... - if (activeState == XZONE_STATE_PASSED || - activeState == XZONE_STATE_FAILED) - { - // - XOHCL passedBar; - bool isBodyIn = false; - bool isActivated = iOB.IsActivated( - forDir, - passedBar, - isBodyIn, - forceStartedBodyOut, - forPeriod // - ); - - // - bool isPassed = - activeState == XZONE_STATE_FAILED - ? !isActivated - : !forceActivatedBodyIn - ? isActivated - : isActivated && - isBodyIn; - - // - passedBar.Clean(); - if (!isPassed) - { - continue; - } - } - - // - // Check Break State ... - if (breakState == XZONE_STATE_PASSED || - breakState == XZONE_STATE_FAILED) - { - // - XOHCL passedBar; - bool isBodyOut = false; - bool isBreaked = iOB.IsBreaked( - forDir, - passedBar, - isBodyOut, - forceStartedBodyOut, - forPeriod // - ); - - // - bool isPassed = - breakState == XZONE_STATE_FAILED - ? !isBreaked - : !forceBreakedBodyOut - ? isBreaked - : isBreaked && - isBodyOut; - - // - passedBar.Clean(); - if (!isPassed) - { - continue; - } - } - - // - // Check Work State ... - if (workState == XZONE_STATE_PASSED || - workState == XZONE_STATE_FAILED) - { - // - bool ignoreActivation = activeState != XZONE_STATE_PASSED; - - // - XOHCL passedBar; - bool isBodyOut = false; - bool isWorked = iOB.IsWorked( - forDir, - passedBar, - isBodyOut, - ignoreActivation, - forceStartedBodyOut, - forceActivatedBodyIn, - forPeriod // - ); - - // - bool isPassed = - workState == XZONE_STATE_FAILED - ? !isWorked - : !forceWorkedBodyOut - ? isWorked - : isWorked && - isBodyOut; - - // - passedBar.Clean(); - if (!isPassed) - { - continue; - } - } - - // - has = FindIndex( - idx, - iOB, - tmpWorkingOBs // - ); - if (has) - { - continue; - } - - // - Add( - iOB, - tmpWorkingOBs // - ); - } - } - - // - // Clean ... - Clean(tmpOBs); - has = HasChild(tmpWorkingOBs); - if (has) - { - // - Clean(tmpOBs); - Copy( - tmpWorkingOBs, - tmpOBs // - ); - - // - Clean(tmpWorkingOBs); - } - - // - // Sorting ... - if (applySort) - { - // - Clean(tmpWorkingOBs); - has = HasChild(tmpOBs); - count = ArraySize(tmpOBs); - - // - // Sorting Applied Only when there is more than one item ... - if (has && count > 1) - { - // - bool hasLast = false; - XCOrderBlock *last = NULL; - while (HasChild(tmpOBs)) - { - // - // Extract First Last Item ... - if (!hasLast) - { - // - idx = - isBullish - ? GetLowest(tmpOBs) - : GetHighest(tmpOBs); - hasLast = IsValidIndex(idx); - if (hasLast) - { - // - last = tmpOBs[idx]; - ArrayRemove( - tmpOBs, - idx, - 1 // - ); - - // - Add( - last, - tmpWorkingOBs // - ); - } - } - - // - has = false; - XCOrderBlock *iOB = NULL; - idx = - isBullish - ? GetLowest(tmpOBs) - : GetHighest(tmpOBs); - has = IsValidIndex(idx); - if (has) - { - // - iOB = tmpOBs[idx]; - ArrayRemove( - tmpOBs, - idx, - 1 // - ); - } - - // - if (!has) - { - break; - } - - // - // Apply From Filter ... - if (applyFromFilter) - { - // - bool isFromPassed = - hasLast && - last.From() < iOB.From(); - if (!isFromPassed) - { - continue; - } - } - - // - // Apply Place Filter ... - if (applyPlaceFilter) - { - // - bool isAbove = - hasLast && - IsAbove( - iOB, - last, - ignoreInside // - ); - - // - bool isBelow = - hasLast && - IsBelow( - iOB, - last, - ignoreInside // - ); - - // - bool isPlacePassed = - isBullish - ? isAbove - : isBelow; - if (!isPlacePassed) - { - continue; - } - } - - // - last = iOB; - Add( - iOB, - tmpWorkingOBs // - ); - } - - // - if (hasLast && - !HasChild(tmpWorkingOBs)) - { - // - Add( - last, - tmpWorkingOBs // - ); - } - } - else - { - // - Copy( - tmpOBs, - tmpWorkingOBs // - ); - } - - // - if (HasChild(tmpWorkingOBs)) - { - // - Copy( - tmpWorkingOBs, - tmpOBs // - ); - } - // - } - - // - count = ArraySize(tmpOBs); - has = IsValidSize(count); - - // - // Converts to XOBFVG ... - if (has) - { - // - for (int i = 0; i < count; i++) - { - // - XOBFVG iOBFVG; - - // - iOBFVG.ob = tmpOBs[i]; - - // - AddRef( - iOBFVG, - tmpOBFVGs // - ); - } - } - - // - Clean(dest); - Clean(tmpOBs); - Clean(tmpWorkingOBs); - - // - // Here we Going to Complete XOBFVGs ... - has = HasChild(tmpOBFVGs); - if (has && HasChild(tmpFVGs)) - { - // - count = ArraySize(tmpOBFVGs); - for (int i = 0; i < count; i++) - { - // - XOBFVG iOBFVG = tmpOBFVGs[i]; - - // - // Detecting FVG ... - XCFVG *tmpWorkingFVGs[]; - for (int j = 0; j < ArraySize(tmpFVGs); j++) - { - // - XCFVG *jFVG = tmpFVGs[j]; - - // - // Check Start Date ... - bool isFromPassed = jFVG.From() > iOBFVG.ob.From(); - if (!isFromPassed) - { - // - ZeroMemory(jFVG); - continue; - } - - // - // Check Place ... - - // - bool isAbove = IsAboveDiff( - jFVG, - iOBFVG.ob, - ignoreInside // - ); - - // - bool isBelow = IsBelowDiff( - jFVG, - iOBFVG.ob, - ignoreInside // - ); - - // - bool isInside = IsInsideDiff( - jFVG, - iOBFVG.ob, - false // - ); - - // - bool isPlacePassed = - isInside || - (isBullish - ? isAbove - : isBelow); - if (!isPlacePassed) - { - // - ZeroMemory(jFVG); - continue; - } - - // - Add( - jFVG, - tmpWorkingFVGs // - ); - } - - // - int fvgsCount = ArraySize(tmpWorkingFVGs); - has = IsValidSize(fvgsCount); - if (has) - { - // - idx = - isBullish - ? GetLowest(tmpWorkingFVGs) - : GetHighest(tmpWorkingFVGs); - - // - if (IsValidIndex(idx)) - { - // - XCFVG *selectedFVG = tmpWorkingFVGs[idx]; - - // - iOBFVG.fvg = selectedFVG; - - // - bool isExists = FindIndex( - idx, - selectedFVG, - tmpFVGs // - ); - if (isExists) - { - // - ArrayRemove( - tmpFVGs, - idx, - 1 // - ); - } - } - } - Clean(tmpWorkingFVGs); - - // - bool isFVGPassed = iOBFVG.HasFVG(); - if (!isFVGPassed) - { - // - iOBFVG.Clean(); - continue; - } - - // - // Validate Model ... - bool isValid = iOBFVG.IsValid(); - if (!isValid) - { - // - iOBFVG.Clean(); - continue; - } - - // - iOBFVG.UpdateTo(cTime); - - // - AddRef( - iOBFVG, - dest // - ); - - // - iOBFVG.Clean(); - } - - // - Clean(tmpOBFVGs); - } - - // - // Detecting Other POI(s) ... - has = HasChild(dest); - bool canDetectPOIs = - detectInsideOBPOIs || - detectInsideFVGPOIs; - if (has && - canDetectPOIs) - { - // - count = ArraySize(dest); - for (int i = 0; i < count; i++) - { - // - // Supply Zones ... - has = stfState.HasSupplyZones(); - if (has) - { - // - for (int j = 0; j < stfState.CountSupplyZones(); j++) - { - // - bool isInsideOB = IsInsideDiff( - stfState.supplyZones[j], - dest[i].ob // - ); - - // - bool isInsideFVG = IsInsideDiff( - stfState.supplyZones[j], - dest[i].fvg // - ); - - // - bool isInside = isInsideOB || - isInsideFVG; - if (isInside) - { - // - bool isPassed = - detectInsideOBPOIs - ? isInsideOB - : detectInsideFVGPOIs - ? isInsideFVG - : false; - if (isPassed) - { - // - isPassed = - !applyFromFilterForPOIs - ? isPassed - : isInsideOB - ? stfState.supplyZones[j].From() > dest[i].ob.From() - : isInsideFVG - ? stfState.supplyZones[j].From() > dest[i].fvg.From() - : false; - } - - // - if (isPassed) - { - // - Add( - stfState.supplyZones[j], - dest[i].supplyZones // - ); - } - } - } - } - - // - // Demand Zones ... - has = stfState.HasDemandZones(); - if (has) - { - // - for (int j = 0; j < stfState.CountDemandZones(); j++) - { - // - bool isInsideOB = IsInsideDiff( - stfState.demandZones[j], - dest[i].ob // - ); - - // - bool isInsideFVG = IsInsideDiff( - stfState.demandZones[j], - dest[i].fvg // - ); - - // - bool isInside = isInsideOB || - isInsideFVG; - if (isInside) - { - // - bool isPassed = - detectInsideOBPOIs - ? isInsideOB - : detectInsideFVGPOIs - ? isInsideFVG - : false; - if (isPassed) - { - // - isPassed = - !applyFromFilterForPOIs - ? isPassed - : isInsideOB - ? stfState.demandZones[j].From() > dest[i].ob.From() - : isInsideFVG - ? stfState.demandZones[j].From() > dest[i].fvg.From() - : false; - } - - // - if (isPassed) - { - // - Add( - stfState.demandZones[j], - dest[i].demandZones // - ); - } - } - } - } - - // - // Support Zones ... - has = stfState.HasSupportZones(); - if (has) - { - // - for (int j = 0; j < stfState.CountSupportZones(); j++) - { - // - bool isInsideOB = IsInsideDiff( - stfState.supportZones[j], - dest[i].ob // - ); - - // - bool isInsideFVG = IsInsideDiff( - stfState.supportZones[j], - dest[i].fvg // - ); - - // - bool isInside = isInsideOB || - isInsideFVG; - if (isInside) - { - // - bool isPassed = - detectInsideOBPOIs - ? isInsideOB - : detectInsideFVGPOIs - ? isInsideFVG - : false; - if (isPassed) - { - // - isPassed = - !applyFromFilterForPOIs - ? isPassed - : isInsideOB - ? stfState.supportZones[j].From() > dest[i].ob.From() - : isInsideFVG - ? stfState.supportZones[j].From() > dest[i].fvg.From() - : false; - } - - // - if (isPassed) - { - // - Add( - stfState.supportZones[j], - dest[i].supportZones // - ); - } - } - } - } - - // - // Resistance Zones ... - has = stfState.HasResistanceZones(); - if (has) - { - // - for (int j = 0; j < stfState.CountResistanceZones(); j++) - { - // - bool isInsideOB = IsInsideDiff( - stfState.resistanceZones[j], - dest[i].ob // - ); - - // - bool isInsideFVG = IsInsideDiff( - stfState.resistanceZones[j], - dest[i].fvg // - ); - - // - bool isInside = isInsideOB || - isInsideFVG; - if (isInside) - { - // - bool isPassed = - detectInsideOBPOIs - ? isInsideOB - : detectInsideFVGPOIs - ? isInsideFVG - : false; - if (isPassed) - { - // - isPassed = - !applyFromFilterForPOIs - ? isPassed - : isInsideOB - ? stfState.resistanceZones[j].From() > dest[i].ob.From() - : isInsideFVG - ? stfState.resistanceZones[j].From() > dest[i].fvg.From() - : false; - } - - // - if (isPassed) - { - // - Add( - stfState.resistanceZones[j], - dest[i].resistanceZones // - ); - } - } - } - } - } - } - - // - Clean(tmpOBs); - Clean(tmpFVGs); - Clean(tmpOBFVGs); - - // - result = ArraySize(dest); - - // - return result; -} - -/** - * Find Highest Order Block of XOBFVG Collection ... - * - * @param source: XOBFVG Collection ... - * - * @return ( int ) - */ -int GetHighest( - XOBFVG &source[] // -) -{ - // - int result = -1; - - // - int count = ArraySize(source); - bool has = IsValidSize(count); - if (!has) - { - return result; - } - - // - XOBFVG item; - for (int i = 0; i < count; i++) - { - // - XOBFVG iOBFVG = source[i]; - - // - bool canSet = - !item.IsValid() - ? true - : item.ob.Upper() < iOBFVG.ob.Upper(); - if (canSet) - { - // - item = iOBFVG; - result = i; - } - - // - iOBFVG.Clean(); - } - - // - item.Clean(); - - // - return result; -} - -/** - * Find Lowest Order Block of XOBFVG Collection ... - * - * @param source: XOBFVG Collection ... - * - * @return ( int ) - */ -int GetLowest( - XOBFVG &source[] // -) -{ - // - int result = -1; - - // - int count = ArraySize(source); - bool has = IsValidSize(count); - if (!has) - { - return result; - } - - // - XOBFVG item; - for (int i = 0; i < count; i++) - { - // - XOBFVG iOBFVG = source[i]; - - // - bool canSet = - !item.IsValid() - ? true - : item.ob.Lower() > iOBFVG.ob.Lower(); - if (canSet) - { - // - item = iOBFVG; - result = i; - } - - // - iOBFVG.Clean(); - } - - // - item.Clean(); - - // - return result; -} - -// -// -// - -/** - * Check Trading Conditions based on Specified Box ... - * - * @param box: XBoxZone instance Reference, specified Box for Checking Conditions ... - * @param appliedBox: XBoxZone instance Reference, hold's Selected Box inside Parent which trading conditions happens on it ... - * @param swingBar: XOHCL instance Reference, holds Swing Bar if Exists ... - * @param breakerBar: XOHCL instance Reference, holds Breaker Bar if Exists ... - * @param rejectionBar: XOHCL instance Reference, holds Rejection Bar if Exists ... - * @param momentumBar: XOHCL instance Reference, holds Momentum Bar if Exists ... - * @param state: XPOIState instance Reference, provides requirement zone's for check Conditions ... - * @param barIndex: int, Specified Bar Index ... - * @param forPeriod: ENUM_TIMEFRAMES member, Specified Conditions Checking Period ... - * - * @return ( bool ) - */ -bool CheckBoxForTradeConditions( - XBoxZone &box, - XBoxZone &appliedBox, - XOHCL &swingBar, - XOHCL &breakerBar, - XOHCL &rejectionBar, - XOHCL &momentumBar, - XPOIState &state, - int barIndex = 0, - ENUM_TIMEFRAMES forPeriod = NULL // -) -{ - // - bool result = false; - - // - swingBar.Clean(); - appliedBox.Clean(); - breakerBar.Clean(); - momentumBar.Clean(); - rejectionBar.Clean(); - - // - if (barIndex < 0) - { - barIndex = 0; - } - - // - result = box.IsValid() && - state.IsValid() && - state.HasChild(); - if (!result) - { - return result; - } - - // - if (!IsValid(forPeriod)) - { - forPeriod = box.period; - } - - // - string symbol = box.symbol; - datetime cTime = iTime( - symbol, - forPeriod, - barIndex // - ); - - // - ENUM_X_DIRECTION forDir = box.dir; - result = HasDirection(forDir); - if (!result) - { - return result; - } - - // - bool isBullish = IsBullish(forDir); - - // - int supportsCount = 0; - bool hasSupports = false; - XCSupportZone *supports[]; - - // - int resistancesCount = 0; - bool hasResistances = false; - XCResistanceZone *resistances[]; - - // - XBoxZone supResBoxes[]; - int supresBoxesCount = 0; - bool hasSupResBoxes = false; - - // - int count = 0; - bool has = false; - - // - has = state.HasSupportZones(); - if (has) - { - // - count = state.CountSupportZones(); - for (int i = 0; i < count; i++) - { - // - XCSupportZone *iZone = state.supportZones[i]; - - // - iZone.To(cTime); - - // - XBoxZone iBox; - bool hasBox = ToBox( - iBox, - iZone // - ); - if (!hasBox) - { - // - iBox.Clean(); - continue; - } - - // - // Check From ... - bool isInside = IsBoxInside( - iBox, - box // - ); - if (!isInside) - { - // - iBox.Clean(); - continue; - } - - // - Add( - iZone, - supports // - ); - - // - AddRef( - iBox, - supResBoxes // - ); - - // - iBox.Clean(); - } - - // - supportsCount = ArraySize(supports); - hasSupports = IsValidSize(supportsCount); - - // - supresBoxesCount = ArraySize(supResBoxes); - hasSupResBoxes = IsValidSize(supresBoxesCount); - } - - // - has = state.HasResistanceZones(); - if (has) - { - // - count = state.CountResistanceZones(); - for (int i = 0; i < count; i++) - { - // - XCResistanceZone *iZone = state.resistanceZones[i]; - - // - iZone.To(cTime); - - // - XBoxZone iBox; - bool hasBox = ToBox( - iBox, - iZone // - ); - if (!hasBox) - { - // - iBox.Clean(); - continue; - } - - // - // Check From ... - bool isInside = IsBoxInside( - iBox, - box // - ); - if (!isInside) - { - // - iBox.Clean(); - continue; - } - - // - Add( - iZone, - resistances // - ); - - // - AddRef( - iBox, - supResBoxes // - ); - - // - iBox.Clean(); - } - - // - resistancesCount = ArraySize(resistances); - hasResistances = IsValidSize(resistancesCount); - - // - supresBoxesCount = ArraySize(supResBoxes); - hasSupResBoxes = IsValidSize(supresBoxesCount); - } - - // - result = hasSupResBoxes; - if (!result) - { - // - Clean(supports); - Clean(resistances); - Clean(supResBoxes); - - // - return result; - } - - // - // Detect Bars ... - - // - XOHCL zBar; - result = zBar.Init( - symbol, - forPeriod, - barIndex // - ); - if (!result) - { - // - zBar.Clean(); - Clean(supports); - Clean(resistances); - Clean(supResBoxes); - - // - return result; - } - - // - XOHCL cBar; - result = zBar.GetPreviousBar(cBar); - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - Clean(supports); - Clean(resistances); - Clean(supResBoxes); - - // - return result; - } - - // - XOHCL pBar; - result = cBar.GetPreviousBar(pBar); - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - Clean(supports); - Clean(resistances); - Clean(supResBoxes); - - // - return result; - } - - // - XOHCL ppBar; - result = pBar.GetPreviousBar(ppBar); - if (!result) - { - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - ppBar.Clean(); - Clean(supports); - Clean(resistances); - Clean(supResBoxes); - - // - return result; - } - // - // Check Conditions ... - - // - // Detect Start Senario ... - - // - double fiboPressureLevel = GetFiboLevelValue(X_FIBO_LEVEL_382); - - // - double fiboUpDown = GetFibonacciLevel( - pBar.high, - pBar.low, - X_FIBO_LEVEL_382, - X_DIRECTION_BEARISH // - ); - double fiboDownUp = GetFibonacciLevel( - pBar.high, - pBar.low, - X_FIBO_LEVEL_382, - X_DIRECTION_BULLISH // - ); - - // - bool hasFiboToUpPressure = - fiboDownUp > 0 && - fiboDownUp <= pBar.GetDown(); - bool hasFiboToDownPressure = - fiboUpDown > 0 && - fiboUpDown >= pBar.GetUp(); - - // - int selectedBoxIDX = -1; - for (int j = 0; j < supresBoxesCount; j++) - { - // - double appliedPrice = - isBullish - ? supResBoxes[j].lower - : supResBoxes[j].upper; - - // - // Check Swing Low ... - bool isSwingLow = - // - pBar.low < ppBar.low && - pBar.low < cBar.low && - zBar.open > pBar.low && - // - appliedPrice > pBar.low && - appliedPrice < pBar.GetDown() - // - ; - bool isPressuredSwingLow = - isSwingLow && - hasFiboToUpPressure; - bool isPressuredStrongSwingLow = - pBar.IsBullish() && - isPressuredSwingLow; - - // - bool isSwingHigh = - // - pBar.high > ppBar.high && - pBar.high > cBar.high && - zBar.open < pBar.high && - // - appliedPrice < pBar.high && - appliedPrice > pBar.GetUp() - // - ; - bool isPressuredSwingHigh = - isSwingHigh && - hasFiboToDownPressure; - bool isPressuredStrongSwingHigh = - pBar.IsBearish() && - isPressuredSwingHigh; - - // - bool hasValidSwing = - isBullish - ? isSwingLow - : isSwingHigh; - bool hasValidPressuredSwing = - isBullish - ? isPressuredSwingLow - : isPressuredSwingHigh; - bool hasValidPressuredStrongSwing = - isBullish - ? isPressuredStrongSwingLow - : isPressuredStrongSwingHigh; - if (hasValidSwing) - { - swingBar = pBar; - } - if (hasValidPressuredSwing) - { - swingBar = pBar; - } - if (hasValidPressuredStrongSwing) - { - swingBar = pBar; - } - - // - bool isCBarBreaked = IsBarBreak( - appliedPrice, - forDir, - cBar // - ); - if (isCBarBreaked) - { - breakerBar = cBar; - } - bool isPBarBreaked = IsBarBreak( - appliedPrice, - forDir, - pBar // - ); - if (!isCBarBreaked && isPBarBreaked) - { - breakerBar = pBar; - } - else - { - isPBarBreaked = false; - } - bool isPPBarBreaked = IsBarBreak( - appliedPrice, - forDir, - ppBar // - ); - if (!isCBarBreaked && - !isPBarBreaked && - isPPBarBreaked) - { - breakerBar = ppBar; - } - else - { - isPPBarBreaked = false; - } - bool isBoxBreaked = isCBarBreaked || - isPBarBreaked || - isPPBarBreaked; - - // - bool isCBarRejected = IsBarReject( - appliedPrice, - forDir, - cBar // - ); - if (isCBarRejected) - { - rejectionBar = cBar; - } - bool isPBarRejected = IsBarReject( - appliedPrice, - forDir, - pBar // - ); - if (!isCBarRejected && isPBarRejected) - { - rejectionBar = pBar; - } - else - { - isPBarRejected = false; - } - bool isPPBarRejected = IsBarReject( - appliedPrice, - forDir, - ppBar // - ); - if (!isCBarRejected && - !isPBarRejected && - isPPBarRejected) - { - rejectionBar = ppBar; - } - else - { - isPPBarRejected = false; - } - bool isBoxRejected = isCBarRejected || - isPBarRejected || - isPPBarRejected; - - // - bool hasRejectionBar = false; - if (isBullish) - { - // - count = state.CountBullishRejectionBars(); - for (int i = 0; i < count; i++) - { - // - XCRejectionBar *iZone = state.bullishRejectionBars[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - int iBarIndex = iBar.Index(); - - // - hasRejectionBar = - // - (iBarIndex == cBar.Index() || - iBarIndex == pBar.Index()) - // - ; - if (hasRejectionBar) - { - // - if (!rejectionBar.IsValid()) - { - rejectionBar = iBar; - } - - // - break; - } - } - } - else - { - // - count = state.CountBearishRejectionBars(); - for (int i = 0; i < count; i++) - { - // - XCRejectionBar *iZone = state.bearishRejectionBars[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - int iBarIndex = iBar.Index(); - - // - hasRejectionBar = - // - (iBarIndex == cBar.Index() || - iBarIndex == pBar.Index()) - // - ; - if (hasRejectionBar) - { - // - if (!rejectionBar.IsValid()) - { - rejectionBar = iBar; - } - - // - break; - } - } - } - - // - bool hasMomentumBar = false; - if (isBullish) - { - // - count = state.CountBullishMomentumBars(); - for (int i = 0; i < count; i++) - { - // - XCMomentumBar *iZone = state.bullishMomentumBars[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - int iBarIndex = iBar.Index(); - - // - hasMomentumBar = - // - (iBarIndex == cBar.Index() || - iBarIndex == pBar.Index()) - // - ; - if (hasMomentumBar) - { - // - if (!momentumBar.IsValid()) - { - momentumBar = iBar; - } - - // - break; - } - } - } - else - { - // - count = state.CountBearishMomentumBars(); - for (int i = 0; i < count; i++) - { - // - XCMomentumBar *iZone = state.bearishMomentumBars[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - int iBarIndex = iBar.Index(); - - // - hasMomentumBar = - // - (iBarIndex == cBar.Index() || - iBarIndex == pBar.Index()) - // - ; - if (hasMomentumBar) - { - // - if (!momentumBar.IsValid()) - { - momentumBar = iBar; - } - - // - break; - } - } - } - - // - bool hasSwing = false; - if (isBullish) - { - // - count = state.CountSwingLows(); - for (int i = 0; i < count; i++) - { - // - XCSwing *iSwing = state.swingLows[i]; - - // - XOHCL iBar; - bool isFilled = iSwing.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - int iBarIndex = iBar.Index(); - - // - hasSwing = - // - (iBarIndex == cBar.Index() || - iBarIndex == pBar.Index()) - // - ; - if (hasSwing) - { - // - if (!swingBar.IsValid()) - { - swingBar = iBar; - } - - // - break; - } - } - } - else - { - // - count = state.CountSwingHighs(); - for (int i = 0; i < count; i++) - { - // - XCSwing *iSwing = state.swingHighs[i]; - - // - XOHCL iBar; - bool isFilled = iSwing.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - int iBarIndex = iBar.Index(); - - // - hasSwing = - // - (iBarIndex == cBar.Index() || - iBarIndex == pBar.Index()) - // - ; - if (hasSwing) - { - // - if (!swingBar.IsValid()) - { - swingBar = iBar; - } - - // - break; - } - } - } - - // - bool hasRequiredValidations = - // - (hasRejectionBar || - hasMomentumBar) - // - || - // - (hasRejectionBar || - hasSwing) - // - || - // - (hasMomentumBar || - hasSwing) - // - ; - - // - result = - // - (isBoxBreaked && - (hasRequiredValidations || - hasValidPressuredSwing)) - // - || - // - (isBoxRejected && - (hasRequiredValidations || - hasValidPressuredSwing)) - // - ; - if (result) - { - // - selectedBoxIDX = j; - break; - } - } - - // - result = - result && - (isBullish - ? zBar.open > box.upper - : zBar.open < box.lower) && - IsValidIndex(selectedBoxIDX); - if (result) - { - appliedBox = supResBoxes[selectedBoxIDX]; - } - - // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - ppBar.Clean(); - Clean(supports); - Clean(resistances); - Clean(supResBoxes); - - // - return result; -} - // \ No newline at end of file diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index d631a4f4..80c31a8e 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -25,6 +25,7 @@ #include "../../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../../Helpers/x-saherelm.x121.helper.mq5" #include "../../Libraries/x-saherelm.common.lib.mq5" +#include "../../Libraries/x-saherelm.x-poi.extensions.lib.mq5" #include "../../Libraries/x-saherelm.x-poi.lib.mq5" #include "../../Libraries/x-saherelm.x-trade.lib.mq5" diff --git a/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 b/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 index fae3b8b3..75885f10 100644 --- a/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 @@ -34,13 +34,22 @@ class XCX121SMCXWZSignalDetector : public XCBase public: // // Props ... + XOBFVG targetZone; + XOBFVG waitingZone; + X121SMCStrategyXWZWorkingZone workingZone; X121SMCStrategyXWZSignalConditions mConditions; X121SMCStrategyXWZSignalConditions mConditionsCollection[]; // // Constructor(s) ... - XCX121SMCXWZSignalDetector() + XCX121SMCXWZSignalDetector( + string _symbol, + ENUM_TIMEFRAMES _period // + ) { + // + symbol = _symbol; + period = _period; Init(); } @@ -58,9 +67,6 @@ class XCX121SMCXWZSignalDetector : public XCBase // // Detect Setup Conditions ... bool DetectSignalSetup( - // - string _symbol, - ENUM_TIMEFRAMES _period, // XC121SMCCycleHelper *decisionCycleHelper, XC121SMCCycleHelper *analyseCycleHelper, @@ -104,10 +110,6 @@ class XCX121SMCXWZSignalDetector : public XCBase // int loopback = 10; - // - string symbol = _symbol; - ENUM_TIMEFRAMES period = _period; - // mConditions.symbol = symbol; mConditions.period = period; @@ -124,12 +126,35 @@ class XCX121SMCXWZSignalDetector : public XCBase double target = 0; double reward = 0; double amountPercent = 0; - ENUM_X_DIRECTION conditionsDir = X_DIRECTION_NONE; ENUM_X121SMC_XWZ_PRIORITY priority = X121SMC_XWZ_PRIORITY_NONE; // // Cycles Conditions ... + // + XOHCL consolidationZBar; + result = consolidationCycleHelper.GetBar( + consolidationZBar, + zIndex // + ); + if (!result) + { + // + consolidationZBar.Clean(); + return result; + } + + // + bool drawBar = true; + if (drawBar) + { + // + DrawBar( + consolidationZBar, + decisionCycleHelper.mPOIDrawer // + ); + } + // // Decision ... ENUM_XPOI_EVENTS decisionPoiEvents[]; @@ -233,12 +258,15 @@ class XCX121SMCXWZSignalDetector : public XCBase // ENUM_X_DIRECTION trend = X_DIRECTION_NONE; - bool hasOrderFlow = mConditions.HasOrderFlow(trend); + bool hasOrderFlow = workingZone.HasOrderFlow(trend); if (!hasOrderFlow) { // - int orderFlowCount = mConditions.DetectOrderFlow( + int orderFlowCount = workingZone.DetectOrderFlow( + symbol, + period, trend, + visionState, consolidationState, analyseState, decisionState // @@ -261,12 +289,35 @@ class XCX121SMCXWZSignalDetector : public XCBase isBullish = IsBullish(trend); isBearish = IsBearish(trend); + // + bool hasPriority = workingZone + .DetectPriority( + priority, + trend, + zIndex, + period // + ); + + // + bool hasRewardAmount = CalculateRiskReward( + priority, + reward, + amountPercent // + ); + // // Has Order Flow ... - mConditions.UpdateTo(cTime); + UpdateTo(cTime); // // TODO: Remove this ... + + // + DrawWorkingZone( + visionCycleHelper.mPOIDrawer // + ); + + // DrawConditions( mConditions, visionCycleHelper.mPOIDrawer // @@ -274,21 +325,40 @@ class XCX121SMCXWZSignalDetector : public XCBase // // Checking Order Flow Break ... - bool isOrderFlowBreaked = mConditions - .IsOrderFlowBreaked( - zIndex, - period // - ); + int breakedIDX = -1; + bool isOrderFlowBreaked = + workingZone.IsOrderFlowBreaked( + breakedIDX, + true, // Force OB Breaked + false, // Force FVG Breaked + zIndex, + period // + ); // // Order Flow Breaked Senario ... if (isOrderFlowBreaked) { // - // TODO: Implement Order Flow Breaker Bar Senario ... + AddRef( + workingZone.orderFlow[breakedIDX], + workingZone.brokenOrderFlow // + ); + + // + Clean(workingZone.orderFlow); + hasOrderFlow = false; + + // + CleanupArray( + workingZone.brokenOrderFlow, + 10 // + ); + + // + // TODO: Here Implement CHOCH Trading Senario ... // - mConditions.Clean(); } result = !isOrderFlowBreaked; if (!result) @@ -301,20 +371,475 @@ class XCX121SMCXWZSignalDetector : public XCBase } // - return false; + // First Check Last Order Flow FVG ... + XOBFVG youngestOrderFlow; + int youngestOBFVGIDX = GetYoungest(workingZone.orderFlow); + bool hasYoungestOBFVG = IsValidIndex(youngestOBFVGIDX); + if (hasYoungestOBFVG) + { + // + youngestOrderFlow = workingZone.orderFlow[youngestOBFVGIDX]; + + // + XOHCL obWorkerBar; + XOHCL obActivationBar; + + // + XOHCL fvgWorkerBar; + XOHCL fvgActivationBar; + + // + bool isOBBodyOut = false; + bool isOBWorked = youngestOrderFlow + .ob + .IsWorked( + trend, + obWorkerBar, + isOBBodyOut, + false // + ); + + // + bool isOBBodyIn = false; + bool isOBActivated = youngestOrderFlow + .ob + .IsActivated( + trend, + obActivationBar, + isOBBodyIn, + false // + ); + + // + bool isFVGBodyOut = false; + bool isFVGWorked = youngestOrderFlow + .fvg + .IsWorked( + trend, + fvgWorkerBar, + isFVGBodyOut, + false // + ); + + // + bool isFVGBodyIn = false; + bool isFVGActivated = youngestOrderFlow + .fvg + .IsActivated( + trend, + fvgActivationBar, + isFVGBodyIn, + false // + ); + + // + if (!isFVGWorked && + isFVGActivated) + { + // + // TODO: Implement Order Flow Side Trading Senario ... + } + + // + fvgWorkerBar.Clean(); + fvgActivationBar.Clean(); + } + + // + // Check New Order Blocks ... + bool hasNewConsolidationBullishOB = Contains( + X_BULLISH_ORDERBLOCK_DETECTED, + consolidationPoiEvents // + ); + bool hasNewConsolidationBearishOB = Contains( + X_BEARISH_ORDERBLOCK_DETECTED, + consolidationPoiEvents // + ); + bool hasNewOB = hasNewConsolidationBullishOB || + hasNewConsolidationBearishOB; + + // + // Check New Fair Value Gaps ... + bool hasNewConsolidationBullishFVG = Contains( + X_BULLISH_FVG_DETECTED, + consolidationPoiEvents // + ); + bool hasNewConsolidationBearishFVG = Contains( + X_BEARISH_FVG_DETECTED, + consolidationPoiEvents // + ); + bool hasNewFVG = hasNewConsolidationBullishFVG || + hasNewConsolidationBearishFVG; + + // + // Check New Order Blocks ... + bool hasNewAnalyseBullishOrderBlock = Contains( + X_BULLISH_ORDERBLOCK_DETECTED, + analysePoiEvents // + ); + bool hasNewAnalyseBearishOrderBlock = Contains( + X_BEARISH_ORDERBLOCK_DETECTED, + analysePoiEvents // + ); + bool hasNewAnalyseOB = hasNewAnalyseBullishOrderBlock || + hasNewAnalyseBearishOrderBlock; + + // + // Check New Fair Value Gaps ... + bool hasNewAnalyseBullishFVG = Contains( + X_BULLISH_FVG_DETECTED, + analysePoiEvents // + ); + bool hasNewAnalyseBearishFVG = Contains( + X_BEARISH_FVG_DETECTED, + analysePoiEvents // + ); + bool hasNewAnalyseFVG = hasNewAnalyseBullishFVG || + hasNewAnalyseBearishFVG; + + // + // Do Order Flow Actions when new Order Blocks + // or FVGs Formed ... + if (hasNewOB || + hasNewFVG || + hasNewAnalyseOB || + hasNewAnalyseFVG) + { + // + XCFVG *newFVG = NULL; + XCOrderBlock *newOB = NULL; + XCFVG *newAnalyseFVG = NULL; + XCOrderBlock *newAnalyseOB = NULL; + + // + bool isValid = false; + bool hasWaitingZone = waitingZone.IsValid(); + + // + int idx = -1; + if (hasNewOB) + { + // + if (hasNewConsolidationBullishOB) + { + // + idx = consolidationState.CountBullishOrderBlocks() - 1; + newOB = consolidationState.bullishOrderBlocks[idx]; + } + else + { + // + idx = consolidationState.CountBearishOrderBlocks() - 1; + newOB = consolidationState.bearishOrderBlocks[idx]; + } + + // + if (hasWaitingZone) + { + } + else + { + // + isValid = + !waitingZone.HasOB() + ? true + : !IsSame( + newOB, + waitingZone.ob // + ); + if (isValid) + { + // + bool isAbove = IsAbove( + newOB, + youngestOrderFlow.ob, + true // Ignore Inside ... + ); + bool isBelow = IsBelow( + newOB, + youngestOrderFlow.ob, + true // Ignore Inside ... + ); + + // + isValid = + isBullish + ? isAbove + : isBelow; + + // + if (isValid) + { + waitingZone.ob = newOB; + } + } + } + } + + // + if (hasNewFVG) + { + // + if (hasNewConsolidationBullishFVG) + { + // + idx = consolidationState.CountBullishFairValueGaps() - 1; + newFVG = consolidationState.bullishFairValueGaps[idx]; + } + else + { + // + idx = consolidationState.CountBearishFairValueGaps() - 1; + newFVG = consolidationState.bearishFairValueGaps[idx]; + } + } + + // + if (hasNewAnalyseOB) + { + // + if (hasNewAnalyseBullishOrderBlock) + { + // + idx = analyseState.CountBullishOrderBlocks() - 1; + newAnalyseOB = analyseState.bullishOrderBlocks[idx]; + } + else + { + // + idx = analyseState.CountBearishOrderBlocks() - 1; + newAnalyseOB = analyseState.bearishOrderBlocks[idx]; + } + } + + // + if (hasNewAnalyseFVG) + { + // + if (hasNewAnalyseBullishFVG) + { + // + idx = analyseState.CountBullishFairValueGaps() - 1; + newAnalyseFVG = analyseState.bullishFairValueGaps[idx]; + } + else + { + // + idx = analyseState.CountBearishFairValueGaps() - 1; + newAnalyseFVG = analyseState.bearishFairValueGaps[idx]; + } + + // + if (hasWaitingZone) + { + } + else + { + // + if (waitingZone.HasOB()) + { + // + XCFVG *tmpFVGs[]; + XCFVG *tmpWorkingFVGs[]; + bool isOBBullish = waitingZone.ob.IsBullish(); + if (isOBBullish) + { + Copy( + analyseState.bullishFairValueGaps, + tmpFVGs // + ); + } + else + { + Copy( + analyseState.bearishFairValueGaps, + tmpFVGs // + ); + } + + // + for (int j = 0; j < ArraySize(tmpFVGs); j++) + { + // + XCFVG *jFVG = tmpFVGs[j]; + + // + // Check Start Date ... + bool isFromPassed = jFVG.From() > waitingZone.ob.From(); + if (!isFromPassed) + { + // + ZeroMemory(jFVG); + continue; + } + + // + // Check Place ... + + // + bool isAbove = IsAboveDiff( + jFVG, + waitingZone.ob, + true // + ); + + // + bool isBelow = IsBelowDiff( + jFVG, + waitingZone.ob, + true // + ); + + // + bool isInside = IsInsideDiff( + jFVG, + waitingZone.ob, + false // + ); + + // + bool isPlacePassed = + isInside || + (isBullish + ? isAbove + : isBelow); + if (!isPlacePassed) + { + // + ZeroMemory(jFVG); + continue; + } + + // + Add( + jFVG, + tmpWorkingFVGs // + ); + } + + // + int fvgsCount = ArraySize(tmpWorkingFVGs); + isValid = IsValidSize(fvgsCount); + if (isValid) + { + // + idx = + isBullish + ? GetLowest(tmpWorkingFVGs) + : GetHighest(tmpWorkingFVGs); + + // + if (IsValidIndex(idx)) + { + // + XCFVG *selectedFVG = tmpWorkingFVGs[idx]; + + // + waitingZone.fvg = selectedFVG; + + // + bool isExists = FindIndex( + idx, + selectedFVG, + tmpFVGs // + ); + if (isExists) + { + // + ArrayRemove( + tmpFVGs, + idx, + 1 // + ); + } + } + } + + // + Clean(tmpFVGs); + Clean(tmpWorkingFVGs); + } + } + } + + // + hasWaitingZone = waitingZone.IsValid(); + if (hasWaitingZone) + { + // + bool isSameDir = waitingZone.GetDirection() == trend; + if (!isSameDir) + { + targetZone = waitingZone; + } + else + { + // + workingZone.AddOrderFlowItem(waitingZone); + mWorkingZoneObjects.Clear(); + + // + // TODO: Remove this ... + DrawWorkingZone( + visionCycleHelper.mPOIDrawer // + ); + } + + // + waitingZone.Clean(); + } + + // + ZeroMemory(newOB); + ZeroMemory(newFVG); + ZeroMemory(newAnalyseOB); + ZeroMemory(newAnalyseFVG); + } + + // + // TODO: Implement Trend Line Trading Senario ... + + // + // TODO: Implement Quarter Line Trading Senario ... + + // + // TODO: Implement Supply and Demand Trading Senario ... + + // + // TODO: Implement Support and Resistance Trading Senario ... + + // + // TODO: these are Trends ... + isBullish = false; + isBearish = false; + + // + bool hasBullishConditions = false; + bool hasBearishConditions = false; + + // + result = + hasBullishConditions || + hasBearishConditions; + + // + // TODO: Implement All Cleanups ... + + // + return result; // // Summarise Conditions ... // // + mConditions.dir = trend; mConditions.pivot = pivot; mConditions.point = point; mConditions.reward = reward; mConditions.target = target; mConditions.setupTime = cTime; mConditions.priority = priority; - mConditions.dir = conditionsDir; mConditions.amountPercent = amountPercent; // @@ -407,10 +932,6 @@ class XCX121SMCXWZSignalDetector : public XCBase // int loopback = 10; - // - string symbol = _symbol; - ENUM_TIMEFRAMES period = _period; - // XOHCL zBar; result = decisionCycleHelper.GetBar( @@ -677,8 +1198,6 @@ class XCX121SMCXWZSignalDetector : public XCBase } // - string symbol = decisionCycleHelper.GetSymbol(); - ENUM_TIMEFRAMES period = decisionCycleHelper.GetPeriod(); string provider = ToString(X_121_SMC_PROVIDER_XWZ); // @@ -1295,10 +1814,6 @@ class XCX121SMCXWZSignalDetector : public XCBase return result; } - // - // - // - // // Add Conditions to Conditions Collection ... int AddConditionsIfNotExists( @@ -1387,200 +1902,68 @@ class XCX121SMCXWZSignalDetector : public XCBase } // - void DrawOrderBlock( - XCOrderBlock *ob, - XCPOIDrawer *drawer // + void DrawBar( + XOHCL &bar, + XCPOIDrawer *drawer, + bool forceClean = true // ) { // - if (ob == NULL || - drawer == NULL) + if (forceClean) + { + mBarObjects.Clear(); + } + + // + if (drawer == NULL || + !bar.IsValid()) { return; } - // // - // ENUM_X_DIRECTION forDir = ob.GetDirection(); - - // // - // color bullishColor = drawer.BarBullishColor(); - // color bearishColor = drawer.BarBearishColor(); - // color forColor = IsBullish(forDir) - // ? bullishColor - // : bearishColor; - - // // - // // Draw Order Block ... - // XCBaseObject *obj; - // bool isCreated = drawer.CreateOrderBlock( - // ob, - // obj // - // ); - // if (isCreated) - // { - // mObjects.Add(obj); - // } - - // // - // ulong chartID = drawer.ChartIdentification(); - // int subWindow = drawer.SubWindowIdentification(); - - // // - // XOHCL startedBar; - // ENUM_X_DIRECTION startedDir; - // bool isStarted = ob.IsStarted( - // forDir, - // startedBar, - // startedDir // - // ); - // if (isStarted) - // { - // // - // datetime to = startedBar.time + (PeriodSeconds(startedBar.period)); - - // // - // XCOHCLObject *obj; - // bool isCreated = drawer.CreateBar( - // startedBar, - // obj, - // to // - // ); - // if (isCreated) - // { - // // - // obj.BodyColor(clrYellow); - // obj.HighShadowColor(clrYellow); - // obj.LowShadowColor(clrYellow); - - // // - // obj.BodyStyle(STYLE_SOLID); - // obj.HighShadowStyle(STYLE_SOLID); - // obj.LowShadowStyle(STYLE_SOLID); - - // // - // mObjects.Add(obj); - // } - - // // - // string startVLineName = "Start_" + ob.GetTag(); - - // // - // CChartObjectVLine *startVLine; - // startVLine = new CChartObjectVLine(); - // isCreated = startVLine.Create( - // chartID, - // startVLineName, - // subWindow, - // startedBar.time // - // ); - // if (isCreated) - // { - // mObjects.Add(startVLine); - // } - // } - } - - // - void DrawFairValueGap( - XCFVG *fvg, - XCPOIDrawer *drawer // - ) - { // - if (fvg == NULL || - drawer == NULL) + bool isBullish = bar.IsBullish(); + + // + int widthBar = 2; + bool fillShadowsBar = true; + ENUM_LINE_STYLE styleBar = STYLE_SOLID; + color clrBar = + isBullish + ? clrAqua + : clrMagenta; + + // + datetime to = bar.NextAt(); + + // + XCOHCLObject *iObj; + bool isCreated = drawer + .CreateBar( + bar, + iObj, + to // + ); + if (isCreated) { - return; + // + iObj.BarSpes( + widthBar, + clrBar, + styleBar // + ); + + // + iObj.LowShadowFill(fillShadowsBar); + iObj.HighShadowFill(fillShadowsBar); + + // + mBarObjects.Add(iObj); } - - // // - // ENUM_X_DIRECTION forDir = fvg.GetDirection(); - - // // - // color bullishColor = drawer.BarBullishColor(); - // color bearishColor = drawer.BarBearishColor(); - // color forColor = IsBullish(forDir) - // ? bullishColor - // : bearishColor; - - // // - // // Draw Order Block ... - // XCBaseObject *obj; - // bool isCreated = drawer.CreateFairValueGap( - // fvg, - // obj // - // ); - // if (isCreated) - // { - // mObjects.Add(obj); - // } - - // // - // ulong chartID = drawer.ChartIdentification(); - // int subWindow = drawer.SubWindowIdentification(); - - // // - // XOHCL startedBar; - // ENUM_X_DIRECTION startedDir; - // bool isStarted = fvg.IsStarted( - // forDir, - // startedBar, - // startedDir // - // ); - // if (isStarted) - // { - // // - // datetime to = startedBar.time + (PeriodSeconds(startedBar.period)); - - // // - // XCOHCLObject *obj; - // bool isCreated = drawer.CreateBar( - // startedBar, - // obj, - // to // - // ); - // if (isCreated) - // { - // // - // obj.BodyColor(clrYellow); - // obj.HighShadowColor(clrYellow); - // obj.LowShadowColor(clrYellow); - - // // - // obj.BodyStyle(STYLE_SOLID); - // obj.HighShadowStyle(STYLE_SOLID); - // obj.LowShadowStyle(STYLE_SOLID); - - // // - // mObjects.Add(obj); - // } - - // // - // string startVLineName = "Start_" + fvg.GetTag(); - - // // - // CChartObjectVLine *startVLine; - // startVLine = new CChartObjectVLine(); - // isCreated = startVLine.Create( - // chartID, - // startVLineName, - // subWindow, - // startedBar.time // - // ); - // if (isCreated) - // { - // // - // startVLine.Color(forColor); - - // // - // mObjects.Add(startVLine); - // } - // } } // - void DrawConditions( - X121SMCStrategyXWZSignalConditions &conditions, + void DrawWorkingZone( XCPOIDrawer *drawer, bool drawTrendLine = true, bool forceClean = false // @@ -1595,7 +1978,7 @@ class XCX121SMCXWZSignalDetector : public XCBase // if (forceClean) { - mObjects.Clear(); + mWorkingZoneObjects.Clear(); } // @@ -1610,19 +1993,211 @@ class XCX121SMCXWZSignalDetector : public XCBase color bearishColor = drawer.BarBearishColor(); // + // Supply Zone ... + has = workingZone.HasSupplyZone(); + if (has) + { + // + XCSupplyZoneObject *iObj; + isCreated = drawer.CreateSupplyZone( + workingZone.supplyZone, + iObj // + ); + + // + if (isCreated) + { + mWorkingZoneObjects.Add(iObj); + } + } + + // + // Demand Zone ... + has = workingZone.HasDemandZone(); + if (has) + { + // + XCDemandZoneObject *iObj; + isCreated = drawer.CreateDemandZone( + workingZone.demandZone, + iObj // + ); + + // + if (isCreated) + { + mWorkingZoneObjects.Add(iObj); + } + } + + // + // Quarters ... + has = workingZone.IsValid(); + if (has) + { + // + double zoneUpper = workingZone.supplyZone.Upper(); + double upper = workingZone.supplyZone.Lower(); + + // + double lower = workingZone.demandZone.Upper(); + double zoneLower = workingZone.demandZone.Lower(); + + // + string prefix = "X121WZone_" + workingZone.symbol + "_" + ToString(workingZone.period); + + // + // Zone Upper ... + CChartObjectHLine *zoneUpperLine; + zoneUpperLine = new CChartObjectHLine(); + isCreated = zoneUpperLine.Create( + chartID, + prefix + "_ZoneTop", + subWindow, + zoneUpper // + ); + if (isCreated) + { + // + zoneUpperLine.Color(clrRed); + + // + mWorkingZoneObjects.Add(zoneUpperLine); + } + + // + // Zone Lower ... + CChartObjectHLine *zoneLowerLine; + zoneLowerLine = new CChartObjectHLine(); + isCreated = zoneLowerLine.Create( + chartID, + prefix + "_ZoneDown", + subWindow, + zoneLower // + ); + if (isCreated) + { + // + zoneLowerLine.Color(clrRed); + + // + mWorkingZoneObjects.Add(zoneLowerLine); + } + + // + // Upper ... + CChartObjectHLine *upperLine; + upperLine = new CChartObjectHLine(); + isCreated = upperLine.Create( + chartID, + prefix + "_Upper", + subWindow, + upper // + ); + if (isCreated) + { + // + upperLine.Color(clrLime); + + // + mWorkingZoneObjects.Add(upperLine); + } + + // + // Lower ... + CChartObjectHLine *lowerLine; + lowerLine = new CChartObjectHLine(); + isCreated = lowerLine.Create( + chartID, + prefix + "_Lower", + subWindow, + lower // + ); + if (isCreated) + { + // + lowerLine.Color(clrLime); + + // + mWorkingZoneObjects.Add(lowerLine); + } + + // + // Quarters ... + + // + // Quarter 1 ... + CChartObjectHLine *q1Line; + q1Line = new CChartObjectHLine(); + isCreated = q1Line.Create( + chartID, + prefix + "_Q1", + subWindow, + workingZone.quarter1 // + ); + if (isCreated) + { + // + q1Line.Color(clrYellow); + + // + mWorkingZoneObjects.Add(q1Line); + } + + // + // Quarter 2 ... + CChartObjectHLine *q2Line; + q2Line = new CChartObjectHLine(); + isCreated = q2Line.Create( + chartID, + prefix + "_Q2", + subWindow, + workingZone.quarter2 // + ); + if (isCreated) + { + // + q2Line.Color(clrYellow); + + // + mWorkingZoneObjects.Add(q2Line); + } + + // + // Quarter 3 ... + CChartObjectHLine *q3Line; + q3Line = new CChartObjectHLine(); + isCreated = q3Line.Create( + chartID, + prefix + "_Q3", + subWindow, + workingZone.quarter3 // + ); + if (isCreated) + { + // + q3Line.Color(clrYellow); + + // + mWorkingZoneObjects.Add(q3Line); + } + } + + // + // Draw Order Flow ... ENUM_X_DIRECTION trend; - has = conditions.HasOrderFlow(trend); + has = workingZone.HasOrderFlow(trend); if (has) { // bool isBullish = IsBullish(trend); // - count = conditions.CountOrderFlow(); + count = workingZone.CountOrderFlow(); for (int i = 0; i < count; i++) { // - XOBFVG iOBFVG = conditions.orderFlow[i]; + XOBFVG iOBFVG = workingZone.orderFlow[i]; // XCBaseObject *drawnObjects[]; @@ -1641,16 +2216,17 @@ class XCX121SMCXWZSignalDetector : public XCBase ); if (IsValidSize(drawnObjectsCount)) { - AddDrawnObjects(drawnObjects); + AddDrawnWorkingZoneObjects(drawnObjects); } } // + // Draw Trend Line ... if (drawTrendLine) { // XOBFVGPivot pivots[]; - count = conditions.GetSwings(pivots); + count = workingZone.GetSwings(pivots); has = count >= 2; if (has) { @@ -1730,10 +2306,10 @@ class XCX121SMCXWZSignalDetector : public XCBase // string trendName = ToString(trend) + "_" + "XTRNDL_" + - ToString(conditions.period) + "_" + + ToString(period) + "_" + ToString(price1) + "_" + - ToString(price2) + "_" + - ToMD5(ToString(time1)); + ToString(price2) + "_"; + // + ToMD5(ToString(time1)); // CChartObjectTrend *mTrend; @@ -1757,10 +2333,59 @@ class XCX121SMCXWZSignalDetector : public XCBase mTrend.RayRight(true); // - mObjects.Add(mTrend); + mWorkingZoneObjects.Add(mTrend); } } } + + // + // Draw Target Zone ... + has = targetZone.IsValid(); + if (has) + { + // + XCBaseObject *drawnObjects[]; + int drawnObjectsCount = drawer + .DrawOBFVG( + // + targetZone, + drawnObjects, + // + true, // Draw Order Block ... + true, // Draw Fair Value Gap ... + false, // Draw Supply Zones ... + false, // Draw Demand Zones ... + false, // Draw Support Zones ... + false // Draw Resistance Zones ... + ); + if (IsValidSize(drawnObjectsCount)) + { + AddDrawnWorkingZoneObjects(drawnObjects); + } + } + } + + // + } + + // + void DrawConditions( + X121SMCStrategyXWZSignalConditions &conditions, + XCPOIDrawer *drawer, + bool drawTrendLine = true, + bool forceClean = false // + ) + { + // + if (drawer == NULL) + { + return; + } + + // + if (forceClean) + { + mObjects.Clear(); } } @@ -1772,7 +2397,11 @@ class XCX121SMCXWZSignalDetector : public XCBase private: // // Props ... + string symbol; + ENUM_TIMEFRAMES period; CArrayObj mObjects; + CArrayObj mBarObjects; + CArrayObj mWorkingZoneObjects; /** * Initialize ... @@ -1787,9 +2416,33 @@ class XCX121SMCXWZSignalDetector : public XCBase void DeInit() { // - RemoveDraws(); mConditions.Clean(); + workingZone.Clean(); Clean(mConditionsCollection); + + // + mObjects.Clear(); + mBarObjects.Clear(); + mWorkingZoneObjects.Clear(); + } + + /** + * Update To Time of Exists Components ... + * + * @param value: updated time ... + */ + void UpdateTo( + datetime value = NULL // + ) + { + // + value = NormalizeTime(value); + + // + targetZone.UpdateTo(value); + workingZone.UpdateTo(value); + mConditions.UpdateTo(value); + waitingZone.UpdateTo(value); } // @@ -1885,6 +2538,24 @@ class XCX121SMCXWZSignalDetector : public XCBase } } + // + void AddDrawnWorkingZoneObjects(XCBaseObject *&objects[]) + { + // + int count = ArraySize(objects); + bool has = IsValidSize(count); + if (!has) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + mWorkingZoneObjects.Add(objects[i]); + } + } + // }; diff --git a/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 index fbda0524..1a35449d 100644 --- a/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 @@ -37,6 +37,999 @@ enum ENUM_X121SMC_XWZ_PRIORITY X121SMC_XWZ_PRIORITY_STRONG_HIGH, }; +// +struct X121SMCStrategyXWZWorkingZone +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + XCSupplyZone *supplyZone; + XCDemandZone *demandZone; + + // + double quarter1; + double quarter2; + double quarter3; + + // + XOBFVG orderFlow[]; + XOBFVGPivot swings[]; + XOBFVG brokenOrderFlow[]; + CChartObjectTrend *orderFlowTrend; + + // + // Constructor ... + X121SMCStrategyXWZWorkingZone() + { + Clean(); + } + + // + // Tools ... + + // + void Clean() + { + // + quarter1 = 0; + quarter2 = 0; + quarter3 = 0; + + // + symbol = NULL; + period = NULL; + + // + Clean(orderFlow); + Clean(brokenOrderFlow); + + // + Clean(swings); + ZeroMemory(supplyZone); + ZeroMemory(demandZone); + + // + if (orderFlowTrend != NULL) + { + orderFlowTrend.Delete(); + } + ZeroMemory(orderFlowTrend); + + // + ZeroMemory(this); + } + + // + bool IsValid() + { + // + bool result = false; + + // + result = + // + quarter1 > 0 && + quarter2 > 0 && + quarter3 > 0 && + HasSupplyZone() && + HasDemandZone() && + quarter1 > quarter2 && + quarter2 > quarter3 + // + ; + + // + return result; + } + + // + bool HasSupplyZone() + { + return supplyZone != NULL && + supplyZone.IsValid(); + } + + // + bool HasDemandZone() + { + return demandZone != NULL && + demandZone.IsValid(); + } + + // + // + // + + // + bool HasOrderFlow() + { + // + bool result = false; + + // + result = IsValid() && + HasChild(orderFlow); + + // + return result; + } + + // + bool HasOrderFlow( + ENUM_X_DIRECTION &orderFlowDir // + ) + { + // + bool result = false; + + // + result = IsValid() && + HasChild(orderFlow); + if (result) + { + orderFlowDir = orderFlow[0].GetDirection(); + } + + // + return result; + } + + // + int CountOrderFlow() + { + return ArraySize(orderFlow); + } + + // + int GetSwings( + XOBFVGPivot &pivots[] // + ) + { + // + int result = 0; + + // + Clean(pivots); + + // + int count = 0; + bool has = false; + + // + has = HasOrderFlow(); + if (!has) + { + return result; + } + + // + count = CountOrderFlow(); + for (int i = 0; i < count; i++) + { + // + XOBFVGPivot iPivots[]; + int iPivotsCount = orderFlow[i] + .GetSwings(iPivots); + bool hasPivots = IsValidSize(iPivotsCount); + if (hasPivots) + { + // + Copy( + iPivots, + pivots, + false // + ); + } + + // + Clean(iPivots); + } + + // + result = ArraySize(pivots); + + // + return result; + } + + // + double GetOrderFlowTrendLinePrice( + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + double result = 0; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + if (!IsValid() || + !HasOrderFlow() || + orderFlowTrend == NULL) + { + return result; + } + + // + datetime time = iTime( + symbol, + forPeriod, + barIndex // + ); + + // + result = ObjectGetValueByTime( + orderFlowTrend.ChartId(), + orderFlowTrend.Name(), + time // + ); + + // + return result; + } + + // + int DetectOrderFlow( + string forSymbol, + ENUM_TIMEFRAMES forPeriod, + ENUM_X_DIRECTION &orderFlowDir, + XPOIState <fState, + XPOIState &htfState, + XPOIState &mtfState, + XPOIState &stfState // + ) + { + // + int result = 0; + + // + Clean(orderFlow); + orderFlowDir = X_DIRECTION_NONE; + + // + bool isValid = + // + IsValid(forSymbol) && + IsValid(forPeriod) && + ltfState.HasChild() && + htfState.HasChild() && + mtfState.HasChild() && + stfState.HasChild() + // + ; + if (!isValid) + { + return result; + } + + // + // Find Working Zone ... + bool hasWorkingZone = IsValid(); + if (!hasWorkingZone) + { + // + symbol = forSymbol; + period = forPeriod; + + // + int idx = -1; + bool has = false; + + // + has = ltfState.HasSupplyZones(); + if (has) + { + // + idx = GetHighest(ltfState.supplyZones); + if (IsValidIndex(idx)) + { + supplyZone = ltfState.supplyZones[idx]; + } + } + + // + has = ltfState.HasDemandZones(); + if (has) + { + // + idx = GetLowest(ltfState.demandZones); + if (IsValidIndex(idx)) + { + demandZone = ltfState.demandZones[idx]; + } + } + + // + hasWorkingZone = HasSupplyZone() && + HasDemandZone(); + if (hasWorkingZone) + { + // + double upper = supplyZone.Lower(); + double lower = demandZone.Upper(); + + // + double delta = ((upper - lower) / 100) * 25; + + // + quarter1 = upper - (1 * delta); + quarter2 = upper - (2 * delta); + quarter3 = upper - (3 * delta); + + // + hasWorkingZone = IsValid(); + } + } + + // + if (!hasWorkingZone) + { + return result; + } + + // + // Bullish OBFVGs ... + XOBFVG bullOBFVGs[]; + int bullOBFVGsCount = ExtractOBFVGZones( + htfState, + mtfState, + stfState, + bullOBFVGs, + X_DIRECTION_BULLISH, + NULL, // For Period ... + // + // Start ... + XZONE_STATE_PASSED, + true, // Force Body Out ... + // + // Activation ... + XZONE_STATE_PASSED, + true, // Force Body In ... + // + // Breaktion ... + XZONE_STATE_FAILED, + false, // Force Body In ... + // + // Works ... + XZONE_STATE_PASSED, + true, // Force Body Out ... + // + true, // Apply Sort ... + true, // From Filter ... + true, // Place Filter ... + // + true, // Ignore Inside in Place Filter ... + // + true, // Detect Inside OB POI(s) ... + true, // Detect Inside FVG POI(s) ... + true // Apply From Filter to Selected POI(s) ... + ); + bool hasBullOBFVGs = IsValidSize(bullOBFVGsCount); + + // + // Bearish OBFVGs ... + XOBFVG bearOBFVGs[]; + int bearOBFVGsCount = ExtractOBFVGZones( + htfState, + mtfState, + stfState, + bearOBFVGs, + X_DIRECTION_BEARISH, + NULL, // For Period ... + // + // Start ... + XZONE_STATE_PASSED, + true, // Force Body Out ... + // + // Activation ... + XZONE_STATE_PASSED, + true, // Force Body In ... + // + // Breaktion ... + XZONE_STATE_FAILED, + false, // Force Body In ... + // + // Works ... + XZONE_STATE_PASSED, + true, // Force Body Out ... + // + true, // Apply Sort ... + true, // From Filter ... + true, // Place Filter ... + // + true, // Ignore Inside in Place Filter ... + // + true, // Detect Inside OB POI(s) ... + true, // Detect Inside FVG POI(s) ... + true // Apply From Filter to Selected POI(s) ... + ); + bool hasBearOBFVGs = IsValidSize(bearOBFVGsCount); + + // + XOBFVG lastBroken; + bool hasBroken = false; + int idx = GetYoungest(brokenOrderFlow); + if (IsValidIndex(idx)) + { + // + lastBroken = brokenOrderFlow[idx]; + hasBroken = lastBroken.IsValid(); + } + + // + bool hasOrderFlow = hasBearOBFVGs || + hasBullOBFVGs; + if (hasOrderFlow) + { + // + // Vlidate ... + isValid = + // + (hasBullOBFVGs && + !hasBearOBFVGs && + bullOBFVGsCount >= 1) + // + || + // + (hasBearOBFVGs && + !hasBullOBFVGs && + bearOBFVGsCount >= 1) + // + ; + + // + if (isValid) + { + // + if (hasBullOBFVGs) + { + // + Copy( + bullOBFVGs, + orderFlow // + ); + } + else if (hasBearOBFVGs) + { + // + Copy( + bearOBFVGs, + orderFlow // + ); + } + + // + orderFlowDir = + hasBullOBFVGs + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + bool isPlacePassed = true; + if (hasBroken) + { + // + bool isBullish = IsBullish(orderFlowDir); + + // + idx = GetYoungest(orderFlow); + bool hasYounget = IsValidIndex(idx); + + // + isPlacePassed = + ArraySize(orderFlow) > 1 + ? true + : isBullish + ? (IsAbove( + orderFlow[idx].ob, + lastBroken.ob, + true // Ignore Inside ... + )) + : (IsBelow( + orderFlow[idx].ob, + lastBroken.ob, + true // Ignore Inside + )); + + // + Clean(brokenOrderFlow); + AddRef( + orderFlow[idx], + brokenOrderFlow // + ); + } + + // + if (!isPlacePassed) + { + // + Clean(orderFlow); + orderFlowDir = X_DIRECTION_NONE; + } + + // + result = ArraySize(orderFlow); + } + } + + // + Clean(bullOBFVGs); + Clean(bearOBFVGs); + + // + lastBroken.Clean(); + + // + if (IsValidSize(result)) + { + // + int count = GetSwings(swings); + bool has = count >= 2; + bool isBullish = IsBullish(orderFlowDir); + if (has) + { + // + // Get Max / Min ... + double max = 0; + double min = 0; + datetime maxAt = NULL; + datetime minAt = NULL; + for (int i = 0; i < count; i++) + { + // + XOBFVGPivot iPivot = swings[i]; + + // + if (!iPivot.IsValid()) + { + // + iPivot.Clean(); + continue; + } + + // + // Min ... + bool canSetMin = + min == 0 + ? true + : min > iPivot.value; + if (canSetMin) + { + // + minAt = iPivot.at; + min = iPivot.value; + } + + // + // Max ... + bool canSetMax = + max == 0 + ? true + : max < iPivot.value; + if (canSetMax) + { + // + maxAt = iPivot.at; + max = iPivot.value; + } + + // + iPivot.Clean(); + } + + // + double price1 = + isBullish + ? min + : max; + double price2 = + isBullish + ? max + : min; + datetime time1 = + isBullish + ? minAt + : maxAt; + datetime time2 = + isBullish + ? maxAt + : minAt; + + // + color clrTrend = clrNONE; + + // + string trendName = + "XORDFLW" + ToString(orderFlowDir) + "_" + "XTRNDL_" + + ToString(period) + "_" + + ToString(price1) + "_" + + ToString(price2) + "_"; + + // + orderFlowTrend = new CChartObjectTrend(); + has = orderFlowTrend.Create( + 0, + trendName, + 0, + time1, + price1, + time2, + price2 // + ); + + // + if (has) + { + // + orderFlowTrend.Width(1); + orderFlowTrend.Color(clrTrend); + orderFlowTrend.RayRight(true); + } + } + } + + // + return result; + } + + // + void AddOrderFlowItem( + XOBFVG &orderItem // + ) + { + // + ENUM_X_DIRECTION trend; + if (!HasOrderFlow(trend)) + { + return; + } + + // + bool isSameDir = orderItem + .GetDirection() == trend; + if (!isSameDir) + { + return; + } + + // + bool isBullish = IsBullish(trend); + + // + AddRef( + orderItem, + orderFlow // + ); + + // + Sort( + orderFlow, + trend, + true // Ignore Inside ... + ); + } + + // + bool IsOrderFlowBreaked( + int &breakedIndex, + bool forceOBBreake = false, + bool forceFVGBreake = false, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + breakedIndex = -1; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + ENUM_X_DIRECTION orderFlowDir; + result = HasOrderFlow(orderFlowDir); + if (!result) + { + return result; + } + + // + XOHCL bar; + result = bar.Init( + symbol, + forPeriod, + barIndex // + ); + if (!result) + { + // + bar.Clean(); + return result; + } + + // + bool isBullish = IsBullish(orderFlowDir); + + // + int idx = + isBullish + ? GetHighest(orderFlow) + : GetLowest(orderFlow); + result = IsValidIndex(idx); + if (!result) + { + // + bar.Clean(); + return result; + } + + // + XOHCL obBreakerBar; + bool isOBBodyOut = false; + bool isOBBreaked = orderFlow[idx].ob.IsBreaked( + orderFlowDir, + obBreakerBar, + isOBBodyOut, + false, // Ignore Start ... + false, // Started Bar Body Out ... + forPeriod // + ); + + // + if (!isOBBreaked) + { + obBreakerBar.Clean(); + } + + // + XOHCL fvgBreakerBar; + bool isFVGBodyOut = false; + bool isFVGBreaked = orderFlow[idx].fvg.IsBreaked( + orderFlowDir, + fvgBreakerBar, + isFVGBodyOut, + false, // Ignore Start ... + true, // Started Bar Body Out ... + forPeriod // + ); + + // + if (!isFVGBreaked) + { + fvgBreakerBar.Clean(); + } + + // + isOBBreaked = + obBreakerBar.IsValid(); + + // + isFVGBreaked = + fvgBreakerBar.IsValid(); + + // + if ((forceOBBreake && forceFVGBreake) || + (!forceOBBreake && !forceFVGBreake)) + { + // + result = isOBBreaked || + isFVGBreaked; + } + else if (forceOBBreake) + { + result = isOBBreaked; + } + else if (forceFVGBreake) + { + result = isFVGBreaked; + } + + // + if (result) + { + breakedIndex = idx; + } + + // + bar.Clean(); + obBreakerBar.Clean(); + fvgBreakerBar.Clean(); + + // + return result; + } + + // + bool DetectPriority( + ENUM_X121SMC_XWZ_PRIORITY &priority, + ENUM_X_DIRECTION forDir, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + priority = X121SMC_XWZ_PRIORITY_NONE; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + result = IsValid() && + HasDirection(forDir); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(forDir); + + // + XOHCL bar; + result = bar.Init( + symbol, + forPeriod, + barIndex // + ); + if (!result) + { + // + bar.Clean(); + return result; + } + + // + if (bar.high < supplyZone.Upper() && + bar.low > supplyZone.Lower()) + { + // + priority = + isBullish + ? X121SMC_XWZ_PRIORITY_NONE + : X121SMC_XWZ_PRIORITY_STRONG_HIGH; + } + else if (bar.high < supplyZone.Lower() && + bar.low > quarter1) + { + // + priority = + isBullish + ? X121SMC_XWZ_PRIORITY_WEAK + : X121SMC_XWZ_PRIORITY_HIGH; + } + else if (bar.high < quarter1 && + bar.low > quarter2) + { + // + priority = + isBullish + ? X121SMC_XWZ_PRIORITY_LOW + : X121SMC_XWZ_PRIORITY_REGULAR; + } + else if (bar.high < quarter2 && + bar.low > quarter3) + { + // + priority = + isBullish + ? X121SMC_XWZ_PRIORITY_REGULAR + : X121SMC_XWZ_PRIORITY_LOW; + } + else if (bar.high < quarter3 && + bar.low > demandZone.Upper()) + { + // + priority = + isBullish + ? X121SMC_XWZ_PRIORITY_HIGH + : X121SMC_XWZ_PRIORITY_WEAK; + } + else if (bar.high < demandZone.Upper() && + bar.low > demandZone.Lower()) + { + // + priority = + isBullish + ? X121SMC_XWZ_PRIORITY_STRONG_HIGH + : X121SMC_XWZ_PRIORITY_NONE; + } + + // + result = priority != X121SMC_XWZ_PRIORITY_NONE && + priority != X121SMC_XWZ_PRIORITY_WEAK; + + // + bar.Clean(); + + // + return result; + } + + // + // + // + + // + void UpdateTo(datetime value = NULL) + { + // + value = NormalizeTime(value); + + // + int count = 0; + bool has = false; + + // + has = HasSupplyZone(); + if (has) + { + supplyZone.To(value); + } + + // + has = HasDemandZone(); + if (has) + { + demandZone.To(value); + } + + // + // Order Flow ... + ENUM_X_DIRECTION orderFlowDir; + has = HasOrderFlow(orderFlowDir); + if (has) + { + // + count = CountOrderFlow(); + for (int i = 0; i < count; i++) + { + orderFlow[i].UpdateTo(value); + } + } + + // + } +}; + // // Definitions ... struct X121SMCStrategyXWZSignalConditions @@ -70,9 +1063,6 @@ struct X121SMCStrategyXWZSignalConditions // ENUM_X121SMC_XWZ_PRIORITY priority; - // - XOBFVG orderFlow[]; - // // Constructor ... X121SMCStrategyXWZSignalConditions() @@ -198,106 +1188,12 @@ struct X121SMCStrategyXWZSignalConditions target = 0; reward = 0; amountPercent = 0; - - // - // startZone.Clean(); - Clean(orderFlow); } // // // - // - bool HasOrderFlow() - { - // - bool result = false; - - // - result = HasChild(orderFlow); - - // - return result; - } - - // - bool HasOrderFlow( - ENUM_X_DIRECTION &orderFlowDir // - ) - { - // - bool result = false; - - // - result = HasChild(orderFlow); - if (result) - { - orderFlowDir = orderFlow[0].GetDirection(); - } - - // - return result; - } - - // - int CountOrderFlow() - { - return ArraySize(orderFlow); - } - - // - int GetSwings( - XOBFVGPivot &pivots[] // - ) - { - // - int result = 0; - - // - Clean(pivots); - - // - int count = 0; - bool has = false; - - // - has = HasOrderFlow(); - if (!has) - { - return result; - } - - // - count = CountOrderFlow(); - for (int i = 0; i < count; i++) - { - // - XOBFVGPivot iPivots[]; - int iPivotsCount = orderFlow[i] - .GetSwings(iPivots); - bool hasPivots = IsValidSize(iPivotsCount); - if (hasPivots) - { - // - Copy( - iPivots, - pivots, - false // - ); - } - - // - Clean(iPivots); - } - - // - result = ArraySize(pivots); - - // - return result; - } - // void UpdateTo(datetime value = NULL) { @@ -307,275 +1203,6 @@ struct X121SMCStrategyXWZSignalConditions // int count = 0; bool has = false; - - // - // Order Flow ... - ENUM_X_DIRECTION orderFlowDir; - has = HasOrderFlow(orderFlowDir); - if (has) - { - // - count = CountOrderFlow(); - for (int i = 0; i < count; i++) - { - orderFlow[i].UpdateTo(value); - } - } - } - - // - // - // - - // - int DetectOrderFlow( - ENUM_X_DIRECTION &orderFlowDir, - XPOIState &htfState, - XPOIState &mtfState, - XPOIState &stfState // - ) - { - // - int result = 0; - - // - Clean(orderFlow); - orderFlowDir = X_DIRECTION_NONE; - - // - bool isValid = - // - IsValid(symbol) && - IsValid(period) && - htfState.HasChild() && - mtfState.HasChild() && - stfState.HasChild() - // - ; - if (!isValid) - { - return result; - } - - // - // Bullish OBFVGs ... - XOBFVG bullOBFVGs[]; - int bullOBFVGsCount = ExtractOBFVGZones( - htfState, - mtfState, - stfState, - bullOBFVGs, - X_DIRECTION_BULLISH, - NULL, // For Period ... - // - // Start ... - XZONE_STATE_PASSED, - true, // Force Body Out ... - // - // Activation ... - XZONE_STATE_PASSED, - true, // Force Body In ... - // - // Breaktion ... - XZONE_STATE_FAILED, - false, // Force Body In ... - // - // Works ... - XZONE_STATE_PASSED, - true, // Force Body Out ... - // - true, // Apply Sort ... - true, // From Filter ... - true, // Place Filter ... - // - true, // Ignore Inside in Place Filter ... - // - true, // Detect Inside OB POI(s) ... - true, // Detect Inside FVG POI(s) ... - true // Apply From Filter to Selected POI(s) ... - ); - bool hasBullOBFVGs = IsValidSize(bullOBFVGsCount); - - // - // Bearish OBFVGs ... - XOBFVG bearOBFVGs[]; - int bearOBFVGsCount = ExtractOBFVGZones( - htfState, - mtfState, - stfState, - bearOBFVGs, - X_DIRECTION_BEARISH, - NULL, // For Period ... - // - // Start ... - XZONE_STATE_PASSED, - true, // Force Body Out ... - // - // Activation ... - XZONE_STATE_PASSED, - true, // Force Body In ... - // - // Breaktion ... - XZONE_STATE_FAILED, - false, // Force Body In ... - // - // Works ... - XZONE_STATE_PASSED, - true, // Force Body Out ... - // - true, // Apply Sort ... - true, // From Filter ... - true, // Place Filter ... - // - true, // Ignore Inside in Place Filter ... - // - true, // Detect Inside OB POI(s) ... - true, // Detect Inside FVG POI(s) ... - true // Apply From Filter to Selected POI(s) ... - ); - bool hasBearOBFVGs = IsValidSize(bearOBFVGsCount); - - // - bool hasOrderFlow = hasBearOBFVGs || - hasBullOBFVGs; - if (hasOrderFlow) - { - // - // Vlidate ... - bool isValid = - // - (hasBullOBFVGs && - !hasBearOBFVGs && - bullOBFVGsCount >= 1) - // - || - // - (hasBearOBFVGs && - !hasBullOBFVGs && - bearOBFVGsCount >= 1) - // - ; - - // - if (isValid) - { - // - if (hasBullOBFVGs) - { - // - Copy( - bullOBFVGs, - orderFlow // - ); - } - else if (hasBearOBFVGs) - { - // - Copy( - bearOBFVGs, - orderFlow // - ); - } - - // - orderFlowDir = - hasBullOBFVGs - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - - // - result = ArraySize(orderFlow); - } - } - - // - Clean(bullOBFVGs); - Clean(bearOBFVGs); - - // - return result; - } - - // - bool IsOrderFlowBreaked( - int barIndex = 0, - ENUM_TIMEFRAMES forPeriod = NULL // - ) - { - // - bool result = false; - - // - if (barIndex < 0) - { - barIndex = 0; - } - - // - if (!IsValid(forPeriod)) - { - forPeriod = period; - } - - // - ENUM_X_DIRECTION orderFlowDir; - result = HasOrderFlow(orderFlowDir); - if (!result) - { - return result; - } - - // - XOHCL bar; - result = bar.Init( - symbol, - forPeriod, - barIndex // - ); - if (!result) - { - // - bar.Clean(); - return result; - } - - // - bool isBullish = IsBullish(orderFlowDir); - - // - int idx = - isBullish - ? GetHighest(orderFlow) - : GetLowest(orderFlow); - result = IsValidIndex(idx); - if (!result) - { - // - bar.Clean(); - return result; - } - - // - XOHCL breakerBar; - bool isBodyOut = false; - result = orderFlow[idx].ob.IsBreaked( - orderFlowDir, - breakerBar, - isBodyOut, - false, // Ignore Start ... - true, // Started Bar Body Out ... - forPeriod // - ); - - // - result = breakerBar.Index() == bar.Index() + 1; - - // - bar.Clean(); - breakerBar.Clean(); - - // - return result; } // diff --git a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 index 18c4daba..61a05b35 100644 --- a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 @@ -58,7 +58,10 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy InitialHelpers(); // - mXWZSignalDetector = new XCX121SMCXWZSignalDetector(); + mXWZSignalDetector = new XCX121SMCXWZSignalDetector( + _symbol, + _period // + ); } // @@ -582,8 +585,6 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // // Detect Signal Setup ... isSetuped = mXWZSignalDetector.DetectSignalSetup( - symbol, - period, mDecisionCycleHelper, mAnalyseCycleHelper, mConsolidationCycleHelper,