/** * Calculate Target for Specified Direction ... * * @param bar: XOHCL instance Reference ... * @param state: XPOIState instance Reference ... * @param forDir: ENUM_S_DIRECTION member ... * * @return ( double ) */ double CalculateTarget( XOHCL &bar, XPOIState &state, ENUM_X_DIRECTION forDir // ) { // double result = 0; // if (!state.IsValid() || !state.HasChild() || !HasDirection(forDir)) { return result; } // XCFVG *iFVG = NULL; XCOrderBlock *iOB = NULL; XCSupplyZone *iSupply = NULL; XCDemandZone *iDemand = NULL; XCSupportZone *iSupport = NULL; XCResistanceZone *iResistance = NULL; // bool hasOB = false; bool hasFVG = false; bool hasSupply = false; bool hasDemand = false; bool hasSupport = false; bool hasResistance = false; // int count = 0; // if (IsBearish(forDir)) { // // FVG ... count = state.CountBullishFairValueGaps(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCFVG *iZone = state.bullishFairValueGaps[i]; // bool isValid = IsPriceAboveZone( bar, iZone // ); if (isValid) { // iFVG = iZone; hasFVG = true; break; } } } // // OB ... count = state.CountBullishOrderBlocks(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCOrderBlock *iZone = state.bullishOrderBlocks[i]; // bool isValid = IsPriceAboveZone( bar, iZone // ); if (isValid) { // iOB = iZone; hasOB = true; break; } } } // // SUPPORT ... count = state.CountSupportZones(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCSupportZone *iZone = state.supportZones[i]; // bool isValid = IsPriceAboveZone( bar, iZone // ); if (isValid) { // iSupport = iZone; hasSupport = true; break; } } } // // DEMAND ... count = state.CountDemandZones(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCDemandZone *iZone = state.demandZones[i]; // bool isValid = IsPriceAboveZone( bar, iZone // ); if (isValid) { // iDemand = iZone; hasDemand = true; break; } } } // // Summary ... result = hasFVG ? iFVG.Upper() : hasOB ? iOB.Upper() : hasSupport ? iSupport.Upper() : hasDemand ? iDemand.Upper() : 0; if (hasFVG) { result = MathMax(result, iFVG.Upper()); } if (hasOB) { result = MathMax(result, iOB.Upper()); } if (hasSupport) { result = MathMax(result, iSupport.Upper()); } if (hasDemand) { result = MathMax(result, iDemand.Upper()); } } // if (IsBullish(forDir)) { // // FVG ... count = state.CountBearishFairValueGaps(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCFVG *iZone = state.bearishFairValueGaps[i]; // bool isValid = IsPriceBelowZone( bar, iZone // ); if (isValid) { // iFVG = iZone; hasFVG = true; break; } } } // // OB ... count = state.CountBearishOrderBlocks(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCOrderBlock *iZone = state.bearishOrderBlocks[i]; // bool isValid = IsPriceBelowZone( bar, iZone // ); if (isValid) { // iOB = iZone; hasOB = true; break; } } } // // RESISTANCE ... count = state.CountResistanceZones(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCResistanceZone *iZone = state.resistanceZones[i]; // bool isValid = IsPriceBelowZone( bar, iZone // ); if (isValid) { // iResistance = iZone; hasResistance = true; break; } } } // // SUPPLY ... count = state.CountSupplyZones(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCSupplyZone *iZone = state.supplyZones[i]; // bool isValid = IsPriceBelowZone( bar, iZone // ); if (isValid) { // iSupply = iZone; hasSupply = true; break; } } } // // Summary ... result = hasFVG ? iFVG.Lower() : hasOB ? iOB.Lower() : hasSupport ? iSupport.Lower() : hasDemand ? iDemand.Lower() : 0; if (hasFVG) { result = MathMin(result, iFVG.Lower()); } if (hasOB) { result = MathMin(result, iOB.Lower()); } if (hasSupport) { result = MathMin(result, iSupport.Lower()); } if (hasDemand) { result = MathMin(result, iDemand.Lower()); } } // return result; } /** * Detect Valid Order Blocks ... * * @param forDir: ENUM_X_DIRECTION member ... * @param source: XPOIState instance Reference ... * * @return ( int ) */ int DetectValidOrderBlocks( ENUM_X_DIRECTION forDir, XPOIState &source, XCOrderBlock *&orderBlocks[] // ) { // int result = 0; // Clean(orderBlocks); // bool isValid = // source.IsValid() && source.HasChild() && HasDirection(forDir) // ; if (!isValid) { return result; } // datetime cTime = TimeCurrent(); // XOHCL cBar; bool isInited = cBar.Init( source.symbol, source.period, 1 // ); if (!isInited) { return result; } // int count = 0; // // Bullish ... count = source.CountBullishOrderBlocks(); isValid = IsValidSize(count) && IsBullish(forDir); if (isValid) { // for (int i = 0; i < count; i++) { // XCOrderBlock *iOB = source.bullishOrderBlocks[i]; // // Update Order Block Time ... iOB.To(cTime); // // Check Order Block Validation ... isValid = IsValid( forDir, cBar.symbol, cBar.period, iOB.Upper(), iOB.Lower(), iOB.From(), iOB.To() // ); if (isValid) { // Add( iOB, orderBlocks // ); } } } // // Bearish ... count = source.CountBearishOrderBlocks(); isValid = IsValidSize(count) && IsBearish(forDir); if (isValid) { // for (int i = 0; i < count; i++) { // XCOrderBlock *iOB = source.bearishOrderBlocks[i]; // // Update Order Block Time ... iOB.To(cTime); // // Check Order Block Validation ... isValid = IsValid( forDir, cBar.symbol, cBar.period, iOB.Upper(), iOB.Lower(), iOB.From(), iOB.To() // ); if (isValid) { // Add( iOB, orderBlocks // ); } } } // result = ArraySize(orderBlocks); // return result; } /** * Detect Valid Fair Value Gaps ... * * @param forDir: ENUM_X_DIRECTION member ... * @param source: XPOIState instance Reference ... * * @return ( int ) */ int DetectValidFairValueGaps( ENUM_X_DIRECTION forDir, XPOIState &source, XCFVG *&fairValueGaps[] // ) { // int result = 0; // Clean(fairValueGaps); // bool isValid = // source.IsValid() && source.HasChild() && HasDirection(forDir) // ; if (!isValid) { return result; } // datetime cTime = TimeCurrent(); // XOHCL cBar; bool isInited = cBar.Init( source.symbol, source.period, 1 // ); if (!isInited) { return result; } // int count = 0; // // Bullish ... count = source.CountBullishFairValueGaps(); isValid = IsValidSize(count) && IsBullish(forDir); if (isValid) { // for (int i = 0; i < count; i++) { // XCFVG *iFVG = source.bullishFairValueGaps[i]; // // Update FVG Time ... iFVG.To(cTime); // // Check FVG Validation ... isValid = IsValid( forDir, cBar.symbol, cBar.period, iFVG.Upper(), iFVG.Lower(), iFVG.From(), iFVG.To() // ); if (isValid) { // Add( iFVG, fairValueGaps // ); } } } // // Bearish ... count = source.CountBearishFairValueGaps(); isValid = IsValidSize(count) && IsBearish(forDir); if (isValid) { // for (int i = 0; i < count; i++) { // XCFVG *iFVG = source.bearishFairValueGaps[i]; // // Update Order Block Time ... iFVG.To(cTime); // // Check Order Block Validation ... isValid = IsValid( forDir, cBar.symbol, cBar.period, iFVG.Upper(), iFVG.Lower(), iFVG.From(), iFVG.To() // ); if (isValid) { // Add( iFVG, fairValueGaps // ); } } } // result = ArraySize(fairValueGaps); // return result; } /** * Detect Valid Support Zones ... * * @param source: XPOIState instance ... * * @return ( int ) */ int DetectValidSupportZones( XPOIState &source, XCOrderBlock *&bullishOrderBlocks[], XCFVG *&bullishFairValueGaps[], XCSupportZone *&supportZones[] // ) { // int result = 0; // Clean(supportZones); // int obsCount = ArraySize(bullishOrderBlocks); int fvgsCount = ArraySize(bullishFairValueGaps); // bool isValid = // source.IsValid() && source.HasChild() && IsValidSize(obsCount + fvgsCount) // ; if (!isValid) { return result; } // int count = source.CountSupportZones(); for (int i = 0; i < count; i++) { // XCSupportZone *iZone = source.supportZones[i]; // bool isAdded = false; // for (int j = 0; j < obsCount; j++) { // XCOrderBlock *iOB = bullishOrderBlocks[j]; // bool isValid = // IsPriceInsideZone( iZone.Upper(), iOB.Upper(), iOB.Lower() // ) // || // IsPriceInsideZone( iZone.Lower(), iOB.Upper(), iOB.Lower() // ) // ; if (isValid) { // Add( iZone, supportZones // ); // isAdded = true; break; } } // if (isAdded) { continue; } // for (int j = 0; j < fvgsCount; j++) { // XCFVG *iFVG = bullishFairValueGaps[j]; // bool isValid = // IsPriceInsideZone( iZone.Upper(), iFVG.Upper(), iFVG.Lower() // ) // || // IsPriceInsideZone( iZone.Lower(), iFVG.Upper(), iFVG.Lower() // ) // ; if (isValid) { // Add( iZone, supportZones // ); // isAdded = true; break; } } } // result = ArraySize(supportZones); // return result; } /** * Detect Valid Resistance Zones ... * * @param source: XPOIState instance ... * * @return ( int ) */ int DetectValidResistanceZones( XPOIState &source, XCOrderBlock *&bearishOrderBlocks[], XCFVG *&bearishFairValueGaps[], XCResistanceZone *&resistanceZones[] // ) { // int result = 0; // Clean(resistanceZones); // int obsCount = ArraySize(bearishOrderBlocks); int fvgsCount = ArraySize(bearishFairValueGaps); // bool isValid = // source.IsValid() && source.HasChild() && IsValidSize(obsCount + fvgsCount) // ; if (!isValid) { return result; } // int count = source.CountResistanceZones(); for (int i = 0; i < count; i++) { // XCResistanceZone *iZone = source.resistanceZones[i]; // bool isAdded = false; // for (int j = 0; j < obsCount; j++) { // XCOrderBlock *iOB = bearishOrderBlocks[j]; // bool isValid = // IsPriceInsideZone( iZone.Upper(), iOB.Upper(), iOB.Lower() // ) // || // IsPriceInsideZone( iZone.Lower(), iOB.Upper(), iOB.Lower() // ) // ; if (isValid) { // Add( iZone, resistanceZones // ); // isAdded = true; break; } } // if (isAdded) { continue; } // for (int j = 0; j < fvgsCount; j++) { // XCFVG *iFVG = bearishFairValueGaps[j]; // bool isValid = // IsPriceInsideZone( iZone.Upper(), iFVG.Upper(), iFVG.Lower() // ) // || // IsPriceInsideZone( iZone.Lower(), iFVG.Upper(), iFVG.Lower() // ) // ; if (isValid) { // Add( iZone, resistanceZones // ); // isAdded = true; break; } } } // result = ArraySize(resistanceZones); // return result; } /** * Detect Valid Support Zones ... * * @param source: XPOIState instance ... * * @return ( int ) */ int DetectValidDemandZones( XPOIState &source, XCOrderBlock *&bullishOrderBlocks[], XCFVG *&bullishFairValueGaps[], XCDemandZone *&demandZones[] // ) { // int result = 0; // Clean(demandZones); // int obsCount = ArraySize(bullishOrderBlocks); int fvgsCount = ArraySize(bullishFairValueGaps); // bool isValid = // source.IsValid() && source.HasChild() && IsValidSize(obsCount + fvgsCount) // ; if (!isValid) { return result; } // int count = source.CountDemandZones(); for (int i = 0; i < count; i++) { // XCDemandZone *iZone = source.demandZones[i]; // bool isAdded = false; // for (int j = 0; j < obsCount; j++) { // XCOrderBlock *iOB = bullishOrderBlocks[j]; // bool isValid = // IsPriceInsideZone( iZone.Upper(), iOB.Upper(), iOB.Lower() // ) // || // IsPriceInsideZone( iZone.Lower(), iOB.Upper(), iOB.Lower() // ) // ; if (isValid) { // Add( iZone, demandZones // ); // isAdded = true; break; } } // if (isAdded) { continue; } // for (int j = 0; j < fvgsCount; j++) { // XCFVG *iFVG = bullishFairValueGaps[j]; // bool isValid = // IsPriceInsideZone( iZone.Upper(), iFVG.Upper(), iFVG.Lower() // ) // || // IsPriceInsideZone( iZone.Lower(), iFVG.Upper(), iFVG.Lower() // ) // ; if (isValid) { // Add( iZone, demandZones // ); // isAdded = true; break; } } } // result = ArraySize(demandZones); // return result; } /** * Detect Valid Resistance Zones ... * * @param source: XPOIState instance ... * * @return ( int ) */ int DetectValidSupplyZones( XPOIState &source, XCOrderBlock *&bearishOrderBlocks[], XCFVG *&bearishFairValueGaps[], XCSupplyZone *&supplyZones[] // ) { // int result = 0; // Clean(supplyZones); // int obsCount = ArraySize(bearishOrderBlocks); int fvgsCount = ArraySize(bearishFairValueGaps); // bool isValid = // source.IsValid() && source.HasChild() && IsValidSize(obsCount + fvgsCount) // ; if (!isValid) { return result; } // int count = source.CountSupplyZones(); for (int i = 0; i < count; i++) { // XCSupplyZone *iZone = source.supplyZones[i]; // bool isAdded = false; // for (int j = 0; j < obsCount; j++) { // XCOrderBlock *iOB = bearishOrderBlocks[j]; // bool isValid = // IsPriceInsideZone( iZone.Upper(), iOB.Upper(), iOB.Lower() // ) // || // IsPriceInsideZone( iZone.Lower(), iOB.Upper(), iOB.Lower() // ) // ; if (isValid) { // Add( iZone, supplyZones // ); // isAdded = true; break; } } // if (isAdded) { continue; } // for (int j = 0; j < fvgsCount; j++) { // XCFVG *iFVG = bearishFairValueGaps[j]; // bool isValid = // IsPriceInsideZone( iZone.Upper(), iFVG.Upper(), iFVG.Lower() // ) // || // IsPriceInsideZone( iZone.Lower(), iFVG.Upper(), iFVG.Lower() // ) // ; if (isValid) { // Add( iZone, supplyZones // ); // isAdded = true; break; } } } // result = ArraySize(supplyZones); // return result; } /** * Detect a Zone Breaker Bar ... * * @param toBar: XOHCL instance Reference ... * @param fromBar: XOHCL instance Reference ... * @param breakerBar: XOHCL instance Reference ... * @param forDir: ENUM_X_DIRECTION member ... * @param symbol: String ... * @param period: ENUM_TIMEFRAMES member ... * * @return ( bool ) */ bool HasBreakerBar( XOHCL &toBar, XOHCL &fromBar, XOHCL &breakerBar, ENUM_X_DIRECTION forDir, string symbol, ENUM_TIMEFRAMES period, double upper, double lower, datetime from, datetime to // ) { // bool result = false; // toBar.Clean(); fromBar.Clean(); breakerBar.Clean(); // result = // upper > 0 && lower > 0 && IsValid(to) && upper > lower && IsValid(from) && IsValid(symbol) && IsValid(period) && HasDirection(forDir) // ; if (!result) { return result; } // result = fromBar.Init( symbol, period, from // ); if (!result) { return result; } // result = toBar.Init( symbol, period, to // ); if (!result) { return result; } // int toIndex = toBar.Index(); int fromIndex = fromBar.Index(); // // Detect Zone BreakerBar ... for (int i = fromIndex; i >= toIndex; i--) { // XOHCL iBar; result = iBar.Init( symbol, period, i // ); // if (!result) { continue; } // result = // IsBullish(forDir) ? // iBar.low < upper && iBar.high > upper && iBar.GetUp() > upper // : // iBar.high > lower && iBar.low < lower && iBar.GetDown() < lower // ; if (result) { // breakerBar = iBar; break; } } // result = breakerBar.IsValid(); // return result; } /** * Validate Specified Order Block ... * * @param forDir: ENUM_X_DIRECTION member ... * @param symbol: String ... * @param period: ENUM_TIMEFRAMES member ... * * @return ( bool ) */ bool IsValid( ENUM_X_DIRECTION forDir, string symbol, ENUM_TIMEFRAMES period, double upper, double lower, datetime from, datetime to, bool ignoreBreakerBar = false // ) { // bool result = false; // result = upper > 0 && lower > 0 && IsValid(to) && upper > lower && IsValid(from) && IsValid(symbol) && IsValid(period) && HasDirection(forDir) // ; if (!result) { return result; } // XOHCL toBar; XOHCL fromBar; XOHCL breakerBar; // if (!ignoreBreakerBar) { // result = HasBreakerBar( toBar, fromBar, breakerBar, forDir, symbol, period, upper, lower, from, to // ); if (!result) { return result; } } else { // result = toBar.Init( symbol, period, to // ); if (!result) { return result; } // result = fromBar.Init( symbol, period, from // ); if (!result) { return result; } // breakerBar = fromBar; } // int toIndex = toBar.Index(); int fromIndex = fromBar.Index(); int breakerIndex = breakerBar.Index(); // bool isBreaked = false; for (int i = breakerIndex - 1; i >= toIndex; i--) { // XOHCL iBar; result = iBar.Init( fromBar.symbol, fromBar.period, i // ); // if (!result) { continue; } // isBreaked = // IsBullish(forDir) // ? // iBar.low < upper // : // iBar.high > lower // ; if (isBreaked) { break; } } // result = !isBreaked; // return result; } /** * Get Oldest Zone ... * * @return ( int ) */ int GetOldest( XCZone *&source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XCZone *oldest = NULL; for (int i = 0; i < count; i++) { // XCZone *iZone = source[i]; // bool canSet = oldest == NULL || (oldest != NULL && oldest.From() > iZone.From()); if (canSet) { // result = i; oldest = iZone; } } // return result; } /** * Get Youngest Zone ... * * @return ( int ) */ int GetYoungest( XCZone *&source[] // ) { // int result = -1; // int count = ArraySize(source); if (!IsValidSize(count)) { return result; } // XCZone *youngest = NULL; for (int i = 0; i < count; i++) { // XCZone *iZone = source[i]; // bool canSet = youngest == NULL || (youngest != NULL && youngest.From() < iZone.From()); if (canSet) { // result = i; youngest = iZone; } } // return result; } template bool ToZone( T *&source[], XCZone *&dest[] // ) { // bool result = false; // Clean(dest); // int count = ArraySize(source); result = IsValidSize(count); if (!result) { return result; } // for (int i = 0; i < count; i++) { // T *item = source[i]; // if (item != NULL) { // Add( (XCZone *)item, dest // ); } } // int destCount = ArraySize(dest); result = IsValidSize(destCount); // return result; } ///////////////////////////////////////////////////////////////////// /** * Find Oldest Pivot Index ... * * @param pivots: XPVPivot instance ... * @return ( int ) */ int FindOldestPivotIndex( XPVPivot &pivots[] // ) { // int result = -1; // int count = ArraySize(pivots); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // XPVPivot iPivot = pivots[i]; // bool isOldest = true; for (int j = 0; j < count; j++) { // XPVPivot jPivot = pivots[j]; // isOldest = iPivot.from <= jPivot.from; if (!isOldest) { break; } } // if (isOldest) { // result = i; break; } } // return result; } /** * Sort Pivots Based On From Date ... * * @param pivots: XPVPivot instance Collection reference ... */ void SortPivots( XPVPivot &pivots[] // ) { // XPVPivot tmp[]; Copy( pivots, tmp // ); // Clean(pivots); // while (ArraySize(tmp) > 0) { // if (ArraySize(tmp) == 1) { // AddRef( tmp[0], pivots // ); // ArrayRemove( tmp, 0, 1); } else { // int idx = FindOldestPivotIndex(tmp); if (IsValidIndex(idx)) { // AddRef( tmp[idx], pivots // ); // ArrayRemove( tmp, idx, 1 // ); } } } // Clean(tmp); } bool IsPivotBreaked( XPVPivot &pivot, XPVPivot &pivots[] // ) { // bool result = false; // result = pivot.IsValid(); if (!result) { return result; } // int count = ArraySize(pivots); result = IsValidSize(pivots); if (!result) { return result; } // // For Peaks Highs Must not Broked ... // For Vales Lows Must not Broked ... bool isPeak = pivot.IsPeak(); // for (int i = 0; i < count; i++) { // XPVPivot iPivot = pivots[i]; // result = isPeak ? iPivot.upper > pivot.upper : iPivot.lower < pivot.lower; if (result) { break; } } // return result; } /** * Filter Broken Pivots for Detect Order Flow ... * * @param pivots: XPVPivot instance Collection reference ... */ void FilterBrokenPivots( XPVPivot &pivots[] // ) { // XPVPivot tmp[]; Copy( pivots, tmp // ); // Clean(pivots); // while (ArraySize(tmp) > 0) { // if (ArraySize(tmp) == 1) { // AddRef( tmp[0], pivots // ); // ArrayRemove( tmp, 0, 1 // ); } else { // XPVPivot pivot = tmp[0]; // ArrayRemove( tmp, 0, 1 // ); // bool isBreaked = IsPivotBreaked( pivot, tmp // ); if (!isBreaked) { // AddRef( pivot, pivots // ); } } } // Clean(tmp); } /** * Calculate Order Flow Direction ... * * @param orderFlow: XPVPivot instance Collection reference ... * @param dir: ENUM_X_DIRECTION member reference, Hold's Calculated Direction ... * * @return ( bool ) */ bool DetectPivotDirection( XPVPivot &orderFlow[], ENUM_X_DIRECTION &dir // ) { // bool result = false; // dir = X_DIRECTION_NONE; // int count = ArraySize(orderFlow); result = IsValidSize(count); if (!result) { return result; } // // For Bullish Direction all Exists lowers must be Greater or Equal Prev ... bool isBullish = false; bool canLookupForBullish = true; // // For Bearish Direction all Exists uppers must be Lesser or Equal Prev ... bool isBearish = false; bool canLookupForBearish = true; // for (int i = 0; i < count; i++) { // XPVPivot iPivot = orderFlow[i]; // XPVPivot tmp[]; Copy( orderFlow, tmp // ); ArrayRemove( tmp, 0, i + 1 // ); // int tmpCount = ArraySize(tmp); if (IsValidSize(tmpCount)) { // for (int j = 0; j < tmpCount; j++) { // XPVPivot jPivot = tmp[j]; // // Check Bullish Direction ... isBullish = canLookupForBullish && jPivot.lower >= iPivot.lower; if (!isBullish) { canLookupForBullish = false; } // // Check Bearish Direction ... isBearish = canLookupForBearish && jPivot.upper <= iPivot.upper; if (!isBearish) { canLookupForBearish = false; } // if (!canLookupForBullish && !canLookupForBearish) { break; } } } Clean(tmp); } // if (isBullish && !isBearish) { dir = X_DIRECTION_BULLISH; } else if (isBearish && !isBullish) { dir = X_DIRECTION_BEARISH; } // result = dir != X_DIRECTION_NONE; // return result; } /** * Detect all POIs which inside a Pivot ... * * @param pivot: XPVPivot instance, Specified Pivot ... * @param source: XPOIState instance, Reference to Source State ... * @param state: XPOIState instance, Reference to Detected Pivots ... * @param lookupSwingHighs: Boolean ... * @param lookupSwingLows: Boolean ... * @param lookupSupportZones: Boolean ... * @param lookupResistanceZones: Boolean ... * @param lookupSupplyZones: Boolean ... * @param lookupDemandZones: Boolean ... * @param lookupBullishOrderBlocks: Boolean ... * @param lookupBearishOrderBlocks: Boolean ... * @param lookupBullishFairValueGaps: Boolean ... * @param lookupBearishFairValueGaps: Boolean ... * @param lookupBullishRejectionBars: Boolean ... * @param lookupBearishRejectionBars: Boolean ... * @param lookupBullishMomentumBars: Boolean ... * @param lookupBearishMomentumBars: Boolean ... */ void DetectPivotPOIs( XPVPivot &pivot, XPOIState &source, XPOIState &state, bool lookupSwingHighs = true, bool lookupSwingLows = true, bool lookupSupportZones = true, bool lookupResistanceZones = true, bool lookupSupplyZones = true, bool lookupDemandZones = true, bool lookupBullishOrderBlocks = true, bool lookupBearishOrderBlocks = true, bool lookupBullishFairValueGaps = true, bool lookupBearishFairValueGaps = true, bool lookupBullishRejectionBars = true, bool lookupBearishRejectionBars = true, bool lookupBullishMomentumBars = true, bool lookupBearishMomentumBars = true // ) { // state.Clean(); // if (!pivot.IsValid()) { return; } // int count = 0; // state.symbol = pivot.symbol; state.period = pivot.period; state.time = TimeCurrent(); // // Swings ... // // Swing High ... if (lookupSwingHighs) { // count = ArraySize(source.swingHighs); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCSwing *iSwing = source.swingHighs[i]; // XOHCL iBar; bool isFilled = iSwing.FillBar(iBar); if (!isFilled) { continue; } // bool isInside = iBar.high <= pivot.upper; if (isInside) { // // iSwing.To(pivot.to); // Add( iSwing, state.swingHighs // ); } } } } // // Swing Low ... if (lookupSwingLows) { // count = ArraySize(source.swingLows); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCSwing *iSwing = source.swingLows[i]; // XOHCL iBar; bool isFilled = iSwing.FillBar(iBar); if (!isFilled) { continue; } // bool isInside = iBar.low >= pivot.lower; if (isInside) { // // iSwing.To(pivot.to); // Add( iSwing, state.swingLows // ); } } } } // // Support and Resistance Zones ... // // Support Zones ... if (lookupSupportZones) { // count = ArraySize(source.supportZones); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCSupportZone *iZone = source.supportZones[i]; // bool isInside = iZone.Upper() <= pivot.upper && iZone.Lower() >= pivot.lower; if (isInside) { // iZone.To(pivot.to); // Add( iZone, state.supportZones // ); } } } } // // Resistance Zones ... if (lookupResistanceZones) { // count = ArraySize(source.resistanceZones); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCResistanceZone *iZone = source.resistanceZones[i]; // bool isInside = iZone.Upper() <= pivot.upper && iZone.Lower() >= pivot.lower; if (isInside) { // iZone.To(pivot.to); // Add( iZone, state.resistanceZones // ); } } } } // // Supply and Demand Zones ... // // Supply Zones ... if (lookupSupplyZones) { // count = ArraySize(source.supplyZones); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCSupplyZone *iZone = source.supplyZones[i]; // bool isInside = iZone.Upper() <= pivot.upper && iZone.Lower() >= pivot.lower; if (isInside) { // iZone.To(pivot.to); // Add( iZone, state.supplyZones // ); } } } } // // Demand Zones ... if (lookupDemandZones) { // count = ArraySize(source.demandZones); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCDemandZone *iZone = source.demandZones[i]; // bool isInside = iZone.Upper() <= pivot.upper && iZone.Lower() >= pivot.lower; if (isInside) { // iZone.To(pivot.to); // Add( iZone, state.demandZones // ); } } } } // // Order Blocks ... // // Bullish Order Blocks ... if (lookupBullishOrderBlocks) { // count = ArraySize(source.bullishOrderBlocks); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCOrderBlock *iZone = source.bullishOrderBlocks[i]; // bool isInside = iZone.Upper() <= pivot.upper && iZone.Lower() >= pivot.lower; if (isInside) { // iZone.To(pivot.to); // Add( iZone, state.bullishOrderBlocks // ); } } } } // // Bearish Order Blocks ... if (lookupBearishOrderBlocks) { // count = ArraySize(source.bearishOrderBlocks); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCOrderBlock *iZone = source.bearishOrderBlocks[i]; // bool isInside = iZone.Upper() <= pivot.upper && iZone.Lower() >= pivot.lower; if (isInside) { // iZone.To(pivot.to); // Add( iZone, state.bearishOrderBlocks // ); } } } } // // Fair Value Gaps ... // // Bullish Fair Value Gaps ... if (lookupBullishFairValueGaps) { // count = ArraySize(source.bullishFairValueGaps); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCFVG *iZone = source.bullishFairValueGaps[i]; // bool isInside = iZone.Upper() <= pivot.upper && iZone.Lower() >= pivot.lower; if (isInside) { // iZone.To(pivot.to); // Add( iZone, state.bullishFairValueGaps // ); } } } } // // Bearish Fair Value Gaps ... if (lookupBearishFairValueGaps) { // count = ArraySize(source.bearishFairValueGaps); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCFVG *iZone = source.bearishFairValueGaps[i]; // bool isInside = iZone.Upper() <= pivot.upper && iZone.Lower() >= pivot.lower; if (isInside) { // iZone.To(pivot.to); // Add( iZone, state.bearishFairValueGaps // ); } } } } // // Rejection Bars ... // // Bullish Rejection Bars ... if (lookupBullishRejectionBars) { // count = ArraySize(source.bullishRejectionBars); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCRejectionBar *iRejection = source.bullishRejectionBars[i]; // XOHCL iBar; bool isFilled = iRejection.FillBar(iBar); if (!isFilled) { continue; } // bool isInside = iBar.low <= pivot.upper && iBar.low >= pivot.lower; if (isInside) { // iRejection.To(pivot.to); // Add( iRejection, state.bullishRejectionBars // ); } } } } // // Bearish Rejection Bars ... if (lookupBearishRejectionBars) { // count = ArraySize(source.bearishRejectionBars); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCRejectionBar *iRejection = source.bearishRejectionBars[i]; // XOHCL iBar; bool isFilled = iRejection.FillBar(iBar); if (!isFilled) { continue; } // bool isInside = iBar.high <= pivot.upper && iBar.high >= pivot.lower; if (isInside) { // iRejection.To(pivot.to); // Add( iRejection, state.bearishRejectionBars // ); } } } } // // Momentum Bars ... // // Bullish Momentum Bars ... if (lookupBullishMomentumBars) { // count = ArraySize(source.bullishMomentumBars); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCMomentumBar *iMomentum = source.bullishMomentumBars[i]; // XOHCL iBar; bool isFilled = iMomentum.FillBar(iBar); if (!isFilled) { continue; } // bool isInside = iBar.low <= pivot.upper && iBar.low >= pivot.lower; if (isInside) { // iMomentum.To(pivot.to); // Add( iMomentum, state.bullishMomentumBars // ); } } } } // // Bearish Momenum Bars ... if (lookupBearishMomentumBars) { // count = ArraySize(source.bearishMomentumBars); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCMomentumBar *iMomentum = source.bearishMomentumBars[i]; // XOHCL iBar; bool isFilled = iMomentum.FillBar(iBar); if (!isFilled) { continue; } // bool isInside = iBar.high <= pivot.upper && iBar.high >= pivot.lower; if (isInside) { // iMomentum.To(pivot.to); // Add( iMomentum, state.bearishMomentumBars // ); } } } } } /** * Fill Pivot Tick Zone ... * * @param pivot: XPVPivot instance Reference ... */ void CalculatePivotTickZone( XPVPivot &pivot, int ticksLevels, int ticksRange, ENUM_TIMEFRAMES _period = NULL // ) { // string symbol = pivot.symbol; ENUM_TIMEFRAMES period = IsValid(_period) ? _period : pivot.period; // bool isInited = false; // datetime from = pivot.from; XOHCL iFromBar; int iFromBarIndex = iBarShift( symbol, period, from // ); isInited = iFromBar.Init( symbol, period, iFromBarIndex // ); if (!isInited) { return; } // datetime to = pivot.to; XOHCL iToBar; int iToBarIndex = iBarShift( symbol, period, to // ); isInited = iToBar.Init( symbol, period, iToBarIndex // ); if (!isInited) { return; } // if (iFromBarIndex <= iToBarIndex) { return; } // XCTicksZone *iZone; iZone = new XCTicksZone(); // isInited = ticksLevels > 0 && ticksRange > 0; if (!isInited) { return; } // isInited = iZone.Init( iFromBar, iToBar // ); if (!isInited) { return; } // pivot.state.ticksZone = iZone; } /** * Filter State based on Pivot ... * * @param pivot: XPVPivot instance Reference ... * @param state: XPOIState instance Reference ... */ void FilterPivotState( XPVPivot &pivot, XPOIState &state // ) { // bool isValid = pivot.IsValid() && state.IsValid() && state.HasChild(); if (!isValid) { return; } // int count = 0; // double upper = pivot.upper; double lower = pivot.lower; // // // // // Resistance ... count = state.CountResistanceZones(); if (IsValidSize(count)) { // XCResistanceZone *tmp[]; Copy( state.resistanceZones, tmp // ); // for (int i = 0; i < count; i++) { // XCResistanceZone *item = tmp[i]; // bool isValid = IsPriceInsideZone( upper, item // ); if (!isValid) { // ArrayRemove( state.resistanceZones, i, 1 // ); } } // Clean(tmp); } // // Supply ... count = state.CountSupplyZones(); if (IsValidSize(count)) { // XCSupplyZone *tmp[]; Copy( state.supplyZones, tmp // ); // for (int i = 0; i < count; i++) { // XCSupplyZone *item = tmp[i]; // bool isValid = IsPriceInsideZone( upper, item // ); if (!isValid) { // ArrayRemove( state.supplyZones, i, 1 // ); } } // Clean(tmp); } // // Bearish Order Block ... count = state.CountBearishOrderBlocks(); if (IsValidSize(count)) { // XCOrderBlock *tmp[]; Copy( state.bearishOrderBlocks, tmp // ); // for (int i = 0; i < count; i++) { // XCOrderBlock *item = tmp[i]; // bool isValid = IsPriceInsideZone( upper, item // ); if (!isValid) { // ArrayRemove( state.bearishOrderBlocks, i, 1 // ); } } // Clean(tmp); } // // Bearish Fair Value Gap ... count = state.CountBearishFairValueGaps(); if (IsValidSize(count)) { // XCFVG *tmp[]; Copy( state.bearishFairValueGaps, tmp // ); // for (int i = 0; i < count; i++) { // XCFVG *item = tmp[i]; // bool isValid = IsPriceInsideZone( upper, item // ); if (!isValid) { // ArrayRemove( state.bearishFairValueGaps, i, 1 // ); } } // Clean(tmp); } // // // // // Support ... count = state.CountSupportZones(); if (IsValidSize(count)) { // XCSupportZone *tmp[]; Copy( state.supportZones, tmp // ); // for (int i = 0; i < count; i++) { // XCSupportZone *item = tmp[i]; // bool isValid = IsPriceInsideZone( lower, item // ); if (!isValid) { // ArrayRemove( state.supportZones, i, 1 // ); } } // Clean(tmp); } // // Demand ... count = state.CountDemandZones(); if (IsValidSize(count)) { // XCDemandZone *tmp[]; Copy( state.demandZones, tmp // ); // for (int i = 0; i < count; i++) { // XCDemandZone *item = tmp[i]; // bool isValid = IsPriceInsideZone( lower, item // ); if (!isValid) { // ArrayRemove( state.demandZones, i, 1 // ); } } // Clean(tmp); } // // Bullish Order Block ... count = state.CountBullishOrderBlocks(); if (IsValidSize(count)) { // XCOrderBlock *tmp[]; Copy( state.bullishOrderBlocks, tmp // ); // for (int i = 0; i < count; i++) { // XCOrderBlock *item = tmp[i]; // bool isValid = IsPriceInsideZone( lower, item // ); if (!isValid) { // ArrayRemove( state.bullishOrderBlocks, i, 1 // ); } } // Clean(tmp); } // // Bullish Fair Value Gap ... count = state.CountBullishFairValueGaps(); if (IsValidSize(count)) { // XCFVG *tmp[]; Copy( state.bullishFairValueGaps, tmp // ); // for (int i = 0; i < count; i++) { // XCFVG *item = tmp[i]; // bool isValid = IsPriceInsideZone( lower, item // ); if (!isValid) { // ArrayRemove( state.bullishFairValueGaps, i, 1 // ); } } // Clean(tmp); } } /** * Detect Box Date of Specified Pivot ... */ bool DetectPivotStateBoxData( XPVPivot &pivot, double &peakUpper, double &peakLower, datetime &peakFrom, datetime &peakTo, double &valeUpper, double &valeLower, datetime &valeFrom, datetime &valeTo // ) { // bool result = false; // peakUpper = 0; peakLower = 0; valeUpper = 0; valeLower = 0; // peakFrom = NULL; peakTo = NULL; valeFrom = NULL; valeTo = NULL; // result = pivot.IsValid(); if (!result) { return result; } // int count = 0; // // // // // Resistance ... count = pivot.state.CountResistanceZones(); if (IsValidSize(count)) { // XCResistanceZone *tmp[]; Copy( pivot.state.resistanceZones, tmp // ); // for (int i = 0; i < count; i++) { // XCResistanceZone *item = tmp[i]; // if (peakUpper == 0 || peakUpper < item.Upper()) { peakUpper = item.Upper(); } // if (peakLower == 0 || peakLower > item.Lower()) { peakLower = item.Lower(); } // if (!IsValid(peakFrom) || peakFrom > item.From()) { peakFrom = item.From(); } // if (!IsValid(peakTo) || peakTo < item.To()) { peakTo = item.To(); } } // Clean(tmp); } // // Supply ... count = pivot.state.CountSupplyZones(); if (IsValidSize(count)) { // XCSupplyZone *tmp[]; Copy( pivot.state.supplyZones, tmp // ); // for (int i = 0; i < count; i++) { // XCSupplyZone *item = tmp[i]; // if (peakUpper == 0 || peakUpper < item.Upper()) { peakUpper = item.Upper(); } // if (peakLower == 0 || peakLower > item.Lower()) { peakLower = item.Lower(); } // if (!IsValid(peakFrom) || peakFrom > item.From()) { peakFrom = item.From(); } // if (!IsValid(peakTo) || peakTo < item.To()) { peakTo = item.To(); } } // Clean(tmp); } // // Bearish Order Block ... count = pivot.state.CountBearishOrderBlocks(); if (IsValidSize(count)) { // XCOrderBlock *tmp[]; Copy( pivot.state.bearishOrderBlocks, tmp // ); // for (int i = 0; i < count; i++) { // XCOrderBlock *item = tmp[i]; // if (peakUpper == 0 || peakUpper < item.Upper()) { peakUpper = item.Upper(); } // if (peakLower == 0 || peakLower > item.Lower()) { peakLower = item.Lower(); } // if (!IsValid(peakFrom) || peakFrom > item.From()) { peakFrom = item.From(); } // if (!IsValid(peakTo) || peakTo < item.To()) { peakTo = item.To(); } } // Clean(tmp); } // // Bearish Fair Value Gap ... count = pivot.state.CountBearishFairValueGaps(); if (IsValidSize(count)) { // XCFVG *tmp[]; Copy( pivot.state.bearishFairValueGaps, tmp // ); // for (int i = 0; i < count; i++) { // XCFVG *item = tmp[i]; // if (peakUpper == 0 || peakUpper < item.Upper()) { peakUpper = item.Upper(); } // if (peakLower == 0 || peakLower > item.Lower()) { peakLower = item.Lower(); } // if (!IsValid(peakFrom) || peakFrom > item.From()) { peakFrom = item.From(); } // if (!IsValid(peakTo) || peakTo < item.To()) { peakTo = item.To(); } } // Clean(tmp); } // // // // // Support ... count = pivot.state.CountSupportZones(); if (IsValidSize(count)) { // XCSupportZone *tmp[]; Copy( pivot.state.supportZones, tmp // ); // for (int i = 0; i < count; i++) { // XCSupportZone *item = tmp[i]; // if (valeUpper == 0 || valeUpper < item.Upper()) { valeUpper = item.Upper(); } // if (valeLower == 0 || valeLower > item.Lower()) { valeLower = item.Lower(); } // if (!IsValid(valeFrom) || valeFrom > item.From()) { valeFrom = item.From(); } // if (!IsValid(valeTo) || valeTo < item.To()) { valeTo = item.To(); } } // Clean(tmp); } // // Demand ... count = pivot.state.CountDemandZones(); if (IsValidSize(count)) { // XCDemandZone *tmp[]; Copy( pivot.state.demandZones, tmp // ); // for (int i = 0; i < count; i++) { // XCDemandZone *item = tmp[i]; // if (valeUpper == 0 || valeUpper < item.Upper()) { valeUpper = item.Upper(); } // if (valeLower == 0 || valeLower > item.Lower()) { valeLower = item.Lower(); } // if (!IsValid(valeFrom) || valeFrom > item.From()) { valeFrom = item.From(); } // if (!IsValid(valeTo) || valeTo < item.To()) { valeTo = item.To(); } } // Clean(tmp); } // // Bullish Order Block ... count = pivot.state.CountBullishOrderBlocks(); if (IsValidSize(count)) { // XCOrderBlock *tmp[]; Copy( pivot.state.bullishOrderBlocks, tmp // ); // for (int i = 0; i < count; i++) { // XCOrderBlock *item = tmp[i]; // if (valeUpper == 0 || valeUpper < item.Upper()) { valeUpper = item.Upper(); } // if (valeLower == 0 || valeLower > item.Lower()) { valeLower = item.Lower(); } // if (!IsValid(valeFrom) || valeFrom > item.From()) { valeFrom = item.From(); } // if (!IsValid(valeTo) || valeTo < item.To()) { valeTo = item.To(); } } // Clean(tmp); } // // Bullish Fair Value Gap ... count = pivot.state.CountBullishFairValueGaps(); if (IsValidSize(count)) { // XCFVG *tmp[]; Copy( pivot.state.bullishFairValueGaps, tmp // ); // for (int i = 0; i < count; i++) { // XCFVG *item = tmp[i]; // if (valeUpper == 0 || valeUpper < item.Upper()) { valeUpper = item.Upper(); } // if (valeLower == 0 || valeLower > item.Lower()) { valeLower = item.Lower(); } // if (!IsValid(valeFrom) || valeFrom > item.From()) { valeFrom = item.From(); } // if (!IsValid(valeTo) || valeTo < item.To()) { valeTo = item.To(); } } // Clean(tmp); } // result = peakUpper > 0 && peakLower > 0 && valeUpper > 0 && valeLower > 0 && IsValid(peakTo) && IsValid(valeTo) && IsValid(peakFrom) && IsValid(valeFrom) && peakTo > peakFrom && valeTo > valeFrom && peakUpper > peakLower && valeUpper > valeLower; // return result; } /** * Detect Price Inside Zones ... * * @param state: XPOIState instance Reference ... * @param bar: XOHCL instance Reference ... * @param hasSupport: Boolean ... * @param hasResistanceZone: Boolean ... * @param hasSupplyZone: Boolean ... * @param hasDemandZone: Boolean ... * @param hasOrderBlock: Boolean ... * @param hasFairValueGap: Boolean ... * @return ( bool ) */ bool DetectPriceInsideZones( XPOIState &state, XOHCL &bar, int &zonesCount, bool &hasSupportZone, XCSupportZone *&supportZone, bool &hasResistanceZone, XCResistanceZone *&resistanceZone, bool &hasSupplyZone, XCSupplyZone *&supplyZone, bool &hasDemandZone, XCDemandZone *&demandZone, bool &hasOrderBlock, XCOrderBlock *&orderBlock, bool &hasFairValueGap, XCFVG *&fairValueGap // ) { // bool result = false; // zonesCount = 0; // hasSupportZone = false; hasResistanceZone = false; hasSupplyZone = false; hasDemandZone = false; hasOrderBlock = false; hasFairValueGap = false; // supportZone = NULL; resistanceZone = NULL; supplyZone = NULL; demandZone = NULL; orderBlock = NULL; fairValueGap = NULL; // datetime cTime = TimeCurrent(); // result = bar.IsValid() && state.IsValid() && state.HasChild(); if (!result) { return result; } // int count = 0; // // Support Zone ... count = state.CountSupportZones(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCSupportZone *iZone = state.supportZones[i]; // bool isValid = IsPriceInsideZone(bar, iZone); if (isValid) { // supportZone = iZone; } } // hasSupportZone = supportZone != NULL && supportZone.IsValid(); if (hasSupportZone) { // zonesCount++; supportZone.To(cTime); } } // // Resistance Zone ... count = state.CountResistanceZones(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCResistanceZone *iZone = state.resistanceZones[i]; // bool isValid = IsPriceInsideZone(bar, iZone); if (isValid) { // resistanceZone = iZone; } } // hasResistanceZone = resistanceZone != NULL && resistanceZone.IsValid(); if (hasResistanceZone) { // zonesCount++; resistanceZone.To(cTime); } } // // Supply Zone ... count = state.CountSupplyZones(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCSupplyZone *iZone = state.supplyZones[i]; // bool isValid = IsPriceInsideZone(bar, iZone); if (isValid) { // supplyZone = iZone; } } // hasSupplyZone = supplyZone != NULL && supplyZone.IsValid(); if (hasSupplyZone) { // zonesCount++; supplyZone.To(cTime); } } // // Demand Zone ... count = state.CountDemandZones(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCDemandZone *iZone = state.demandZones[i]; // bool isValid = IsPriceInsideZone(bar, iZone); if (isValid) { // demandZone = iZone; } } // hasDemandZone = demandZone != NULL && demandZone.IsValid(); if (hasDemandZone) { // zonesCount++; demandZone.To(cTime); } } // // OrderBlock ... count = state.CountBullishOrderBlocks(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCOrderBlock *iZone = state.bullishOrderBlocks[i]; // bool isValid = IsPriceInsideZone(bar, iZone); if (isValid) { // orderBlock = iZone; } } // hasOrderBlock = orderBlock != NULL && orderBlock.IsValid(); if (hasOrderBlock) { // zonesCount++; orderBlock.To(cTime); } } if (!hasOrderBlock) { // count = state.CountBearishOrderBlocks(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCOrderBlock *iZone = state.bearishOrderBlocks[i]; // bool isValid = IsPriceInsideZone(bar, iZone); if (isValid) { // orderBlock = iZone; } } // hasOrderBlock = orderBlock != NULL && orderBlock.IsValid(); if (hasOrderBlock) { // zonesCount++; orderBlock.To(cTime); } } } // // Fair Value Gap ... count = state.CountBullishFairValueGaps(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCFVG *iZone = state.bullishFairValueGaps[i]; // bool isValid = IsPriceInsideZone(bar, iZone); if (isValid) { // fairValueGap = iZone; } } // hasFairValueGap = fairValueGap != NULL && fairValueGap.IsValid(); if (hasFairValueGap) { // zonesCount++; fairValueGap.To(cTime); } } if (!hasFairValueGap) { // count = state.CountBearishFairValueGaps(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCFVG *iZone = state.bearishFairValueGaps[i]; // bool isValid = IsPriceInsideZone(bar, iZone); if (isValid) { // fairValueGap = iZone; } } // hasFairValueGap = fairValueGap != NULL && fairValueGap.IsValid(); if (hasFairValueGap) { // zonesCount++; fairValueGap.To(cTime); } } } // result = // hasSupportZone || hasResistanceZone || hasSupplyZone || hasDemandZone || hasOrderBlock || hasFairValueGap // ; // return result; } /** * Detect Price Inside Zones ... * * @param state: XPOIState instance Reference ... * @param price: Double ... * @param hasSupport: Boolean ... * @param hasResistanceZone: Boolean ... * @param hasSupplyZone: Boolean ... * @param hasDemandZone: Boolean ... * @param hasOrderBlock: Boolean ... * @param hasFairValueGap: Boolean ... * @return ( bool ) */ bool DetectPriceInsideZones( XPOIState &state, double price, int &zonesCount, bool &hasSupportZone, XCSupportZone *&supportZone, bool &hasResistanceZone, XCResistanceZone *&resistanceZone, bool &hasSupplyZone, XCSupplyZone *&supplyZone, bool &hasDemandZone, XCDemandZone *&demandZone, bool &hasOrderBlock, XCOrderBlock *&orderBlock, bool &hasFairValueGap, XCFVG *&fairValueGap // ) { // bool result = false; // zonesCount = 0; // hasSupportZone = false; hasResistanceZone = false; hasSupplyZone = false; hasDemandZone = false; hasOrderBlock = false; hasFairValueGap = false; // supportZone = NULL; resistanceZone = NULL; supplyZone = NULL; demandZone = NULL; orderBlock = NULL; fairValueGap = NULL; // datetime cTime = TimeCurrent(); // result = price > 0 && state.IsValid() && state.HasChild(); if (!result) { return result; } // int count = 0; // // Support Zone ... count = state.CountSupportZones(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCSupportZone *iZone = state.supportZones[i]; // bool isValid = IsPriceInsideZone(price, iZone); if (isValid) { // supportZone = iZone; } } // hasSupportZone = supportZone != NULL && supportZone.IsValid(); if (hasSupportZone) { // zonesCount++; supportZone.To(cTime); } } // // Resistance Zone ... count = state.CountResistanceZones(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCResistanceZone *iZone = state.resistanceZones[i]; // bool isValid = IsPriceInsideZone(price, iZone); if (isValid) { // resistanceZone = iZone; } } // hasResistanceZone = resistanceZone != NULL && resistanceZone.IsValid(); if (hasResistanceZone) { // zonesCount++; resistanceZone.To(cTime); } } // // Supply Zone ... count = state.CountSupplyZones(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCSupplyZone *iZone = state.supplyZones[i]; // bool isValid = IsPriceInsideZone(price, iZone); if (isValid) { // supplyZone = iZone; } } // hasSupplyZone = supplyZone != NULL && supplyZone.IsValid(); if (hasSupplyZone) { // zonesCount++; supplyZone.To(cTime); } } // // Demand Zone ... count = state.CountDemandZones(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCDemandZone *iZone = state.demandZones[i]; // bool isValid = IsPriceInsideZone(price, iZone); if (isValid) { // demandZone = iZone; } } // hasDemandZone = demandZone != NULL && demandZone.IsValid(); if (hasDemandZone) { // zonesCount++; demandZone.To(cTime); } } // // OrderBlock ... count = state.CountBullishOrderBlocks(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCOrderBlock *iZone = state.bullishOrderBlocks[i]; // bool isValid = IsPriceInsideZone(price, iZone); if (isValid) { // orderBlock = iZone; } } // hasOrderBlock = orderBlock != NULL && orderBlock.IsValid(); if (hasOrderBlock) { // zonesCount++; orderBlock.To(cTime); } } if (!hasOrderBlock) { // count = state.CountBearishOrderBlocks(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCOrderBlock *iZone = state.bearishOrderBlocks[i]; // bool isValid = IsPriceInsideZone(price, iZone); if (isValid) { // orderBlock = iZone; } } // hasOrderBlock = orderBlock != NULL && orderBlock.IsValid(); if (hasOrderBlock) { // zonesCount++; orderBlock.To(cTime); } } } // // Fair Value Gap ... count = state.CountBullishFairValueGaps(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCFVG *iZone = state.bullishFairValueGaps[i]; // bool isValid = IsPriceInsideZone(price, iZone); if (isValid) { // fairValueGap = iZone; } } // hasFairValueGap = fairValueGap != NULL && fairValueGap.IsValid(); if (hasFairValueGap) { // zonesCount++; fairValueGap.To(cTime); } } if (!hasFairValueGap) { // count = state.CountBearishFairValueGaps(); if (IsValidSize(count)) { // for (int i = count - 1; i >= 0; i--) { // XCFVG *iZone = state.bearishFairValueGaps[i]; // bool isValid = IsPriceInsideZone(price, iZone); if (isValid) { // fairValueGap = iZone; } } // hasFairValueGap = fairValueGap != NULL && fairValueGap.IsValid(); if (hasFairValueGap) { // zonesCount++; fairValueGap.To(cTime); } } } // result = // hasSupportZone || hasResistanceZone || hasSupplyZone || hasDemandZone || hasOrderBlock || hasFairValueGap // ; // return result; } bool CalculatePriceInsideZones( XPriceZones &zone, XPOIState &state, double price // ) { // bool result = false; // zone.Clean(); // int zonesCount = 0; bool hasSupplyZone = false; bool hasDemandZone = false; bool hasOrderBlock = false; bool hasSupportZone = false; bool hasFairValueGap = false; bool hasResistanceZone = false; // result = DetectPriceInsideZones( state, price, zone.count, hasSupportZone, zone.supportZone, hasResistanceZone, zone.resistanceZone, hasSupplyZone, zone.supplyZone, hasDemandZone, zone.demandZone, hasOrderBlock, zone.orderBlock, hasFairValueGap, zone.fairValueGap // ); if (!result) { return result; } // zone.price = price; // result = zone.IsValid(); // return result; } bool CalculatePriceInsideZones( XPriceZones &zone, XPOIState &state, XOHCL &bar // ) { // bool result = false; // zone.Clean(); // int zonesCount = 0; bool hasSupplyZone = false; bool hasDemandZone = false; bool hasOrderBlock = false; bool hasSupportZone = false; bool hasFairValueGap = false; bool hasResistanceZone = false; // result = DetectPriceInsideZones( state, bar, zone.count, hasSupportZone, zone.supportZone, hasResistanceZone, zone.resistanceZone, hasSupplyZone, zone.supplyZone, hasDemandZone, zone.demandZone, hasOrderBlock, zone.orderBlock, hasFairValueGap, zone.fairValueGap // ); if (!result) { return result; } // zone.bar = bar; // result = zone.IsValid(); // return result; } /** * Calculate Zone by Providing Specified Data ... * * @param zones: XStateZone instance Reference ... * @param source: XPOIState instance Reference ... * @param upper: Double ... * @param lower: Double ... * @param from: DateTime ... * * @return ( bool ) */ bool CalculateStateZones( XStateZones &zones, XPOIState &source, double upper, double lower, datetime from // ) { // bool result = false; // zones.Clean(); // datetime cTime = TimeCurrent(); // result = // upper > 0 && lower > 0 && upper > lower && IsValid(from) && source.IsValid() && source.HasChild() // ; if (!result) { return result; } // int count = 0; // // Support ... count = source.CountSupportZones(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCSupportZone *iZone = source.supportZones[i]; // double iUpper = iZone.Upper(); double iLower = iZone.Lower(); datetime iFrom = iZone.From(); // bool isAbove = iUpper > upper && iLower <= upper; // bool isInside = iUpper <= upper && iLower >= lower; // bool isBelow = iUpper >= lower && iLower < lower; // bool isValid = // iFrom > from && (isAbove || isBelow || isInside) // ; if (isValid) { // iZone.To(cTime); Add( iZone, zones.supportZones // ); } } } // // Resistance ... count = source.CountResistanceZones(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCResistanceZone *iZone = source.resistanceZones[i]; // double iUpper = iZone.Upper(); double iLower = iZone.Lower(); datetime iFrom = iZone.From(); // bool isAbove = iUpper > upper && iLower <= upper; // bool isInside = iUpper <= upper && iLower >= lower; // bool isBelow = iUpper >= lower && iLower < lower; // bool isValid = // iFrom > from && (isAbove || isBelow || isInside) // ; if (isValid) { // iZone.To(cTime); Add( iZone, zones.resistanceZones // ); } } } // // Supply ... count = source.CountSupplyZones(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCSupplyZone *iZone = source.supplyZones[i]; // double iUpper = iZone.Upper(); double iLower = iZone.Lower(); datetime iFrom = iZone.From(); // bool isAbove = iUpper > upper && iLower <= upper; // bool isInside = iUpper <= upper && iLower >= lower; // bool isBelow = iUpper >= lower && iLower < lower; // bool isValid = // iFrom > from && (isAbove || isBelow || isInside) // ; if (isValid) { // iZone.To(cTime); Add( iZone, zones.supplyZones // ); } } } // // Demand ... count = source.CountDemandZones(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCDemandZone *iZone = source.demandZones[i]; // double iUpper = iZone.Upper(); double iLower = iZone.Lower(); datetime iFrom = iZone.From(); // bool isAbove = iUpper > upper && iLower <= upper; // bool isInside = iUpper <= upper && iLower >= lower; // bool isBelow = iUpper >= lower && iLower < lower; // bool isValid = // iFrom > from && (isAbove || isBelow || isInside) // ; if (isValid) { // iZone.To(cTime); Add( iZone, zones.demandZones // ); } } } // // Bullish OrderBlocks ... count = source.CountBullishOrderBlocks(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCOrderBlock *iZone = source.bullishOrderBlocks[i]; // double iUpper = iZone.Upper(); double iLower = iZone.Lower(); datetime iFrom = iZone.From(); // bool isAbove = iUpper > upper && iLower <= upper; // bool isInside = iUpper <= upper && iLower >= lower; // bool isBelow = iUpper >= lower && iLower < lower; // bool isValid = // iFrom > from && (isAbove || isBelow || isInside) // ; if (isValid) { // iZone.To(cTime); Add( iZone, zones.bullishOrderBlocks // ); } } } // // Bearish OrderBlocks ... count = source.CountBearishOrderBlocks(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCOrderBlock *iZone = source.bearishOrderBlocks[i]; // double iUpper = iZone.Upper(); double iLower = iZone.Lower(); datetime iFrom = iZone.From(); // bool isAbove = iUpper > upper && iLower <= upper; // bool isInside = iUpper <= upper && iLower >= lower; // bool isBelow = iUpper >= lower && iLower < lower; // bool isValid = // iFrom > from && (isAbove || isBelow || isInside) // ; if (isValid) { // iZone.To(cTime); Add( iZone, zones.bearishOrderBlocks // ); } } } // // Bullish FairValueGaps ... count = source.CountBullishFairValueGaps(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCFVG *iZone = source.bullishFairValueGaps[i]; // double iUpper = iZone.Upper(); double iLower = iZone.Lower(); datetime iFrom = iZone.From(); // bool isAbove = iUpper > upper && iLower <= upper; // bool isInside = iUpper <= upper && iLower >= lower; // bool isBelow = iUpper >= lower && iLower < lower; // bool isValid = // iFrom > from && (isAbove || isBelow || isInside) // ; if (isValid) { // iZone.To(cTime); Add( iZone, zones.bullishFairValueGaps // ); } } } // // Bearish FairValueGaps ... count = source.CountBearishFairValueGaps(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCFVG *iZone = source.bearishFairValueGaps[i]; // double iUpper = iZone.Upper(); double iLower = iZone.Lower(); datetime iFrom = iZone.From(); // bool isAbove = iUpper > upper && iLower <= upper; // bool isInside = iUpper <= upper && iLower >= lower; // bool isBelow = iUpper >= lower && iLower < lower; // bool isValid = // iFrom > from && (isAbove || isBelow || isInside) // ; if (isValid) { // iZone.To(cTime); Add( iZone, zones.bearishFairValueGaps // ); } } } // result = zones.IsValid(); // return result; } /** * Add Value Change instance to Exists Collection if it's not Exists ... * * @param item: XValueChange instance Reference ... * @param items: XValueChange instance Array Reference ... * * @return ( int ) */ int AddIfNotExists( XValueChange &item, XValueChange &items[] // ) { // int result = 0; // result = item.IsValid(); if (!result) { return result; } // bool canAdd = false; int count = ArraySize(items); if (!IsValidSize(count)) { canAdd = true; } else { // XValueChange last; bool hasItem = GetLastItem( last, items // ); if (!hasItem) { canAdd = true; } else { // // Compare Last Item with Current ... canAdd = item.time > last.time; } } // // Add Item if Allowed ... if (canAdd) { // AddRef( item, items // ); } // result = ArraySize(items); // return result; } ///////////////////////////////////////////////////////////////////////// // // // // // Pivot Types ... enum ENUM_XPV_PIVOTS { XPV_NONE, XPV_PEAK, XPV_VALE, }; // // Model a Pivot structure ... struct XPVPivot { // string symbol; ENUM_TIMEFRAMES period; // double upper; double lower; // datetime from; datetime to; // int repetition; // ENUM_XPV_PIVOTS type; // // Combined all States ... XPOIState state; // XPVPivot() { Clean(); } // // Tools ... /** * Cleanup ... */ void Clean() { // upper = 0; lower = 0; // to = NULL; from = NULL; symbol = NULL; period = NULL; // repetition = 0; // type = XPV_NONE; // state.Clean(); // ZeroMemory(this); } /** * Validation ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = // IsValid(to) && IsValid(from) && IsValid(symbol) && IsValid(period) && repetition > 0 && type != XPV_NONE && (upper > 0 || lower > 0) // ; // return result; } /** * Check Pivot is Peak ... * * @return ( bool ) */ bool IsPeak() { // bool result = false; // result = IsValid() && type == XPV_PEAK; // return result; } /** * Check Pivot is Vale ... * * @return ( bool ) */ bool IsVale() { // bool result = false; // result = IsValid() && type == XPV_VALE; // return result; } /** * Calculate Lower for Peaks ... * * @return ( double ) */ double CalculateLower() { // double result = 0; // if (!IsValid() || !IsPeak()) { return result; } // int fromIndex = iBarShift( symbol, period, from // ); // int toIndex = iBarShift( symbol, period, to // ); // int count = fromIndex - toIndex; // int llIDX = iLowest( symbol, period, MODE_LOW, count, toIndex // ); // result = iLow( symbol, period, llIDX // ); // return result; } /** * Calculate Upper for Vales ... * * @return ( double ) */ double CalculateUpper() { // double result = 0; // if (!IsValid() || !IsVale()) { return result; } // int fromIndex = iBarShift( symbol, period, from // ); // int toIndex = iBarShift( symbol, period, to // ); // int count = fromIndex - toIndex; // int hhIDX = iHighest( symbol, period, MODE_HIGH, count, toIndex // ); // result = iHigh( symbol, period, hhIDX // ); // return result; } /** * Calculate Range of Pivot ... * * @return ( double ) */ double CalculateRange() { // double result = 0; // if (!IsValid() || upper <= 0 || lower <= 0) { return result; } // result = upper - lower; // return result; } /** * Calculate Middle of Pivot ... * Used for * @return ( double ) */ double CalculateMid() { // double result = 0; // double range = CalculateRange(); if (range <= 0) { return result; } // result = lower + (range / 2); // return result; } /** * Calculate Liquidity Percent for Specified Direction ... * * @param forDirection: ENUM_X_DIRECTION member, Specified Liquidity ... * @param price: Double, Specified Price ... * * @return ( double ) */ double CalculateLiquidityPercent( ENUM_X_DIRECTION forDirection, double price = 0 // ) { // double result = 0; // if (!IsValid()) { return result; } // result = state .CalculateLiquidityPercent( forDirection, price // ); // return result; } /** * Check Price in Premium or not ... * * @return ( bool ) */ bool IsPriceInPremium() { // bool result = false; // result = IsValid(); if (!result) { return result; } // double ask = GetAsk(symbol); double bid = GetBid(symbol); // double mid = CalculateMid(); // result = // ask > mid && bid > mid // ; // return result; } /** * Check Price in Discount or not ... * * @return ( bool ) */ bool IsPriceInDiscount() { // bool result = false; // result = IsValid(); if (!result) { return result; } // double ask = GetAsk(symbol); double bid = GetBid(symbol); // double mid = CalculateMid(); // result = // ask > mid && bid > mid // ; // return result; } // /** * Get Unique Identifier ... * * @return ( string ) */ string GetTag() { // string result = NULL; // if (!IsValid()) { return result; } // string hash = symbol + "_" + ToString(period) + "_" + ToString(upper) + "," + ToString(lower) + "_" + ToString(from) + "," + ToString(to); hash = ToMD5(hash); // string typeStr = type == XPV_PEAK ? "Peak" : "Vale"; // result = // "XPV_" + typeStr + "_" + symbol + "_" + ToString(period) + "_" + hash // ; // return result; } // }; // // Pivots ... struct XPVPivotPoint { // // Props ... double value; int repetition; datetime time; ENUM_XPV_PIVOTS type; // // Constructor ... XPVPivotPoint() { Clean(); } // // Tools ... /** * Cleanup ... */ void Clean() { // value = 0; time = NULL; repetition = 0; type = XPV_NONE; // ZeroMemory(this); } /** * Validate ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = // value > 0 && IsValid(time) && repetition > 0 && type != XPV_NONE // ; // return result; } /** * Check current Pivot Point is Peak or not ... * * @return ( bool ) */ bool IsPeak() { // bool result = false; // result = IsValid() && type == XPV_PEAK; // return result; } /** * Check current Pivot Point is Vale or not ... * * @return ( bool ) */ bool IsVale() { // bool result = false; // result = IsValid() && type == XPV_VALE; // return result; } // }; // // // // // Model Value Changed ... struct XValueChange { // // Props ... double before; // Before Change Value ... double after; // After Change Value ... datetime time; // Change Time ... ENUM_X_DIRECTION dir; // Change Direction ... // // Constructor ... XValueChange() { Clean(); } // // Tools ... /** * Initialize ... * * @param _before: Double, Value Before Change ... * @param _after: Double, Value After Change ... * @param _time: Datetime, Change Time ... * @param _dir: ENUM_X_DIRECTION member, Specified Changed Direction ... * * @return ( bool ) */ bool Init( double _before, // Before Change Value ... double _after, // After Change Value ... ENUM_X_DIRECTION _dir, // Change Direction ... datetime _time = NULL // Change Time ... ) { // bool result = false; // _time = NormalizeTime(_time); // // Validate Inputs ... result = // _after > 0 && _before > 0 && IsValid(_time) && _after != _before && HasDirection(_dir) // ; if (!result) { return result; } // // Set Validated Values ... dir = _dir; time = _time; after = _after; before = _before; // result = IsValid(); // return result; } /** * Cleaning Up ... */ void Clean() { // after = 0; before = 0; time = NULL; dir = X_DIRECTION_NONE; // ZeroMemory(this); } /** * Validate Model ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = // after > 0 && before > 0 && IsValid(time) && after != before && HasDirection(dir) // ; // return result; } /** * Fill Change Bar ... * * @param bar: XOHCL instance Reference, holds Change Bar ... * @param _symbol: String, Specified Symbol ... * @param _period: ENUM_TIMEFRAMES _period member, Specified Period ... * * @return ( bool ) */ bool FillBar( XOHCL &bar, string _symbol = NULL, ENUM_TIMEFRAMES _period = NULL // ) { // bool result = false; // bar.Clean(); _symbol = NormalizeSymbol(_symbol); _period = NormalizePeriod(_period); // result = IsValid() && IsValid(_symbol) && IsValid(_period); if (!result) { return result; } // result = bar.Init( _symbol, _period, time // ); // return result; } // }; // // Price Zones Model ... struct XPriceZones { // XOHCL bar; // if Based On Bar it's Filled ... double price; // if Based on Price, it's Filled ... // int count; // Exists Zones Count ... // XCFVG *fairValueGap; // Exists Fair Value Gap ... XCSupplyZone *supplyZone; // Exists Supply Zone ... XCDemandZone *demandZone; // Exists Demand Zone ... XCOrderBlock *orderBlock; // Exists Order Block ... XCSupportZone *supportZone; // Exists Support Zone ... XCResistanceZone *resistanceZone; // Exists Resistance Zone ...ّ // // Constructor ... XPriceZones() { Clean(); } /** * Cleanup ... */ void Clean() { // bar.Clean(); price = 0; // supplyZone = NULL; demandZone = NULL; orderBlock = NULL; supportZone = NULL; fairValueGap = NULL; resistanceZone = NULL; // ZeroMemory(this); } /** * Check Zone is Valid ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = // (IsBasedOnBar() || IsBasedOnPrice()) && IsValidSize(count) // ; // return result; } /** * Check Zones Base on Bar ... * * @return ( bool ) */ bool IsBasedOnBar() { return bar.IsValid(); } /** * Check Zones Based on Price ... * * @return ( bool ) */ bool IsBasedOnPrice() { return price > 0; } /** * Check Has Supply Zone ... * * @return ( bool ) */ bool HasSupplyZone() { // return IsValidSize(count) && supplyZone != NULL && supplyZone.IsValid(); } /** * Check Has Demand Zone ... * * @return ( bool ) */ bool HasDemandZone() { // return IsValidSize(count) && demandZone != NULL && demandZone.IsValid(); } /** * Check Has OrderBlock ... * * @return ( bool ) */ bool HasOrderBlock() { // return IsValidSize(count) && orderBlock != NULL && orderBlock.IsValid(); } /** * Check Has Support Zone ... * * @return ( bool ) */ bool HasSupportZone() { // return IsValidSize(count) && supportZone != NULL && supportZone.IsValid(); } /** * Check Has FairValueGap ... * * @return ( bool ) */ bool HasFairValueGap() { // return IsValidSize(count) && fairValueGap != NULL && fairValueGap.IsValid(); } /** * Check Has Resistance Zone ... * * @return ( bool ) */ bool HasResistanceZone() { // return IsValidSize(count) && resistanceZone != NULL && resistanceZone.IsValid(); } /** * Check Zones are Overal Bullish ... * * @return ( bool ) */ bool IsBullish() { // bool result = false; // result = // HasDemandZone() // || // HasSupportZone() // || // (HasOrderBlock() && orderBlock.IsBullish()) // || // (HasFairValueGap() && fairValueGap.IsBullish()) // ; // return result; } /** * Check Zones are Overal Bearish ... * * @return ( bool ) */ bool IsBearish() { // bool result = false; // result = // HasSupplyZone() // || // HasResistanceZone() // || // (HasOrderBlock() && orderBlock.IsBearish()) // || // (HasFairValueGap() && fairValueGap.IsBearish()) // ; // return result; } /** * Fill Zones Based On required Direction ... * * @param dir: ENUM_X_DIRECTION member ... * * @return ( int ) */ int FillZones( ENUM_X_DIRECTION dir, XCZone *&zones[] // ) { // int result = 0; // Clean(zones); // bool isBullish = IsBullish(dir); bool isBoth = dir == X_DIRECTION_ALL || dir == X_DIRECTION_NONE; // if (isBoth || isBullish) { // if (HasSupportZone()) { // Add( (XCZone *)supportZone, zones // ); } // if (HasDemandZone()) { // Add( (XCZone *)demandZone, zones // ); } // if (HasOrderBlock() && orderBlock.IsBullish()) { // Add( (XCZone *)orderBlock, zones // ); } // if (HasFairValueGap() && fairValueGap.IsBullish()) { // Add( (XCZone *)fairValueGap, zones // ); } } // if (isBoth || !isBullish) { // if (HasResistanceZone()) { // Add( (XCZone *)resistanceZone, zones // ); } // if (HasSupplyZone()) { // Add( (XCZone *)supplyZone, zones // ); } // if (HasOrderBlock() && orderBlock.IsBearish()) { // Add( (XCZone *)orderBlock, zones // ); } // if (HasFairValueGap() && fairValueGap.IsBearish()) { // Add( (XCZone *)fairValueGap, zones // ); } } // s result = ArraySize(zones); // return result; } /** * Calculate Boundary of Zones ... * * @param dir: ENUM_X_DIRECTION Member, Specified Direction ... * @param upper: Double ... * @param lower: Double ... * * @return ( bool ) */ bool GetBoundary( ENUM_X_DIRECTION dir, double &upper, double &lower // ) { // bool result = false; // upper = 0; lower = 0; // XCZone *zones[]; int mCount = FillZones(dir, zones); result = IsValidSize(mCount); if (!result) { return result; } // for (int i = 0; i < mCount; i++) { // XCZone *iZone = zones[i]; // double iUpper = iZone.Upper(); double iLower = iZone.Lower(); // upper = upper == 0 ? iUpper : iUpper > upper ? iUpper : upper; // lower = lower == 0 ? iLower : iLower < lower ? iLower : lower; } // return result; } /** * Calculate Lifetime of Zones ... * * @param dir: ENUM_X_DIRECTION Member, Specified Direction ... * @param from: DateTime ... * @param to: DateTime ... * * @return ( bool ) */ bool GetLifetime( ENUM_X_DIRECTION dir, datetime &from, datetime &to // ) { // bool result = false; // to = NULL; from = NULL; // XCZone *zones[]; int mCount = FillZones(dir, zones); result = IsValidSize(mCount); if (!result) { return result; } // bool isBullish = IsBullish(dir); bool isAll = dir == X_DIRECTION_NONE || dir == X_DIRECTION_ALL; // if (isAll || isBullish) { // // Support Zone ... bool hasSupportZone = HasSupportZone(); if (hasSupportZone) { // XCSupportZone *zone = supportZone; // from = !IsValid(from) || from > zone.From() ? zone.From() : from; // to = !IsValid(to) || to < zone.To() ? zone.To() : from; } // // Demand Zone ... bool hasDemandZone = HasDemandZone(); if (hasDemandZone) { // XCDemandZone *zone = demandZone; // from = !IsValid(from) || from > zone.From() ? zone.From() : from; // to = !IsValid(to) || to < zone.To() ? zone.To() : from; } // // Order Block ... bool hasOrderBlock = HasOrderBlock() && orderBlock.IsBullish(); if (hasOrderBlock) { // XCOrderBlock *zone = orderBlock; // from = !IsValid(from) || from > zone.From() ? zone.From() : from; // to = !IsValid(to) || to < zone.To() ? zone.To() : from; } // // Fair Value Gap ... bool hasFairValueGap = HasFairValueGap() && fairValueGap.IsBullish(); if (hasFairValueGap) { // XCFVG *zone = fairValueGap; // from = !IsValid(from) || from > zone.From() ? zone.From() : from; // to = !IsValid(to) || to < zone.To() ? zone.To() : from; } } // if (isAll || !isBullish) { // // Resistance Zone ... bool hasResistanceZone = HasResistanceZone(); if (hasResistanceZone) { // XCResistanceZone *zone = resistanceZone; // from = !IsValid(from) || from > zone.From() ? zone.From() : from; // to = !IsValid(to) || to < zone.To() ? zone.To() : from; } // // Supply Zone ... bool hasSupplyZone = HasSupplyZone(); if (hasSupplyZone) { // XCSupplyZone *zone = supplyZone; // from = !IsValid(from) || from > zone.From() ? zone.From() : from; // to = !IsValid(to) || to < zone.To() ? zone.To() : from; } // // Order Block ... bool hasOrderBlock = HasOrderBlock() && orderBlock.IsBearish(); if (hasOrderBlock) { // XCOrderBlock *zone = orderBlock; // from = !IsValid(from) || from > zone.From() ? zone.From() : from; // to = !IsValid(to) || to < zone.To() ? zone.To() : from; } // // Fair Value Gap ... bool hasFairValueGap = HasFairValueGap() && fairValueGap.IsBearish(); if (hasFairValueGap) { // XCFVG *zone = fairValueGap; // from = !IsValid(from) || from > zone.From() ? zone.From() : from; // to = !IsValid(to) || to < zone.To() ? zone.To() : from; } } // result = to > from && IsValid(to) && IsValid(from); // return result; } /** * Calculate Box Model Data ... * * @param dir: ENUM_X_DIRECTION Member, Specified Direction ... * @param upper: Double ... * @param lower: Double ... * @param from: DateTime ... * @param to: DateTime ... * * @return ( bool ) */ bool GetBoxData( ENUM_X_DIRECTION dir, double &upper, double &lower, datetime &from, datetime &to // ) { // bool result = false; // bool hasBoundary = GetBoundary( dir, upper, lower // ); // bool hasLifetime = GetLifetime( dir, from, to // ); // result = hasBoundary && hasLifetime; // return result; } // }; // // Market Strucutre Model ... struct XMarketStructure { // string symbol; ENUM_TIMEFRAMES period; // ENUM_X_DIRECTION bias; // XPVPivotPoint vales[]; XPriceZones valePriceZones[]; // XPVPivotPoint peaks[]; XPriceZones peakPriceZones[]; // XOHCL lowestValeBar; XOHCL lowestValePeakBreakeUpBar; XOHCL valeAboveLowestValePeakBar; // XOHCL highestPeakBar; XOHCL peakBelowHighestPeakValeBar; XOHCL highestPeakValeBreakeDownBar; // XMarketStructure() { Clean(); } /** * Cleanup ... */ void Clean() { // symbol = NULL; period = NULL; bias = X_DIRECTION_NONE; // Clean(vales); Clean(peaks); Clean(valePriceZones); Clean(peakPriceZones); // lowestValeBar.Clean(); lowestValePeakBreakeUpBar.Clean(); valeAboveLowestValePeakBar.Clean(); // highestPeakBar.Clean(); peakBelowHighestPeakValeBar.Clean(); highestPeakValeBreakeDownBar.Clean(); // ZeroMemory(this); } /** * Validate Model ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = IsValid(symbol) && IsValid(period) && bias != X_DIRECTION_NONE; // return result; } /** * Check Bullish Trend ... * * @return ( bool ) */ bool IsBullish() { // bool result = false; // result = // IsValid() && IsBullish(bias) && HasChild(peaks) && HasDirection(bias) && lowestValeBar.IsValid() && HasChild(peakPriceZones) && lowestValePeakBreakeUpBar.IsValid() && valeAboveLowestValePeakBar.IsValid() // ; // return result; } /** * Check Bearish Trend ... * * @return ( bool ) */ bool IsBearish() { // bool result = false; // result = // IsValid() && IsBearish(bias) && HasChild(vales) && HasDirection(bias) && highestPeakBar.IsValid() && HasChild(valePriceZones) && peakBelowHighestPeakValeBar.IsValid() && highestPeakValeBreakeDownBar.IsValid() // ; // return result; } /** * Check Has Trend ... * * @return ( bool ) */ bool HasTrend() { // bool result = false; // result = IsValid() && (IsBullish() || IsBearish()); // return result; } // }; struct XStateZones { // XCSupportZone *supportZones[]; // Holds Founded Support Zones ... XCResistanceZone *resistanceZones[]; // Holds Founded Resistance Zones ... XCSupplyZone *supplyZones[]; // Holds Founded Supply Zones ... XCDemandZone *demandZones[]; // Holds Founded Demand Zones ... XCOrderBlock *bullishOrderBlocks[]; // Holds Founded Bullish Order Blocks ... XCOrderBlock *bearishOrderBlocks[]; // Holds Founded Bearish Order Blocks ... XCFVG *bullishFairValueGaps[]; // Holds Founded Bullish Fair Value Gaps ... XCFVG *bearishFairValueGaps[]; // Holds Founded Bearish Fair Value Gaps ... // XStateZones() { Clean(); } /** * Cleaning Model ... */ void Clean() { // Clean(supportZones); Clean(resistanceZones); Clean(supplyZones); Clean(demandZones); Clean(bullishOrderBlocks); Clean(bearishOrderBlocks); Clean(bullishFairValueGaps); Clean(bearishFairValueGaps); // ZeroMemory(this); } /** * Validate Model ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = // IsValidSize(CountSupportZones()) || IsValidSize(CountResistanceZones()) || IsValidSize(CountSupplyZones()) || IsValidSize(CountDemandZones()) || IsValidSize(CountBullishOrderBlocks()) || IsValidSize(CountBearishOrderBlocks()) || IsValidSize(CountBullishFairValueGaps()) || IsValidSize(CountBearishFairValueGaps()) // ; // return result; } // // Tools ... // int CountSupportZones() { // int result = 0; // result = ArraySize(supportZones); // return result; } // int CountResistanceZones() { // int result = 0; // result = ArraySize(resistanceZones); // return result; } // int CountSupplyZones() { // int result = 0; // result = ArraySize(supplyZones); // return result; } // int CountDemandZones() { // int result = 0; // result = ArraySize(demandZones); // return result; } // int CountBullishOrderBlocks() { // int result = 0; // result = ArraySize(bullishOrderBlocks); // return result; } // int CountBearishOrderBlocks() { // int result = 0; // result = ArraySize(bearishOrderBlocks); // return result; } // int CountBullishFairValueGaps() { // int result = 0; // result = ArraySize(bullishFairValueGaps); // return result; } // int CountBearishFairValueGaps() { // int result = 0; // result = ArraySize(bearishFairValueGaps); // return result; } }; struct XFVGOrderBlock { // // Props ... XCOrderBlock *orderBlock; XCFVG *fairValueGap; // XStateZones stateZones; // XFVGOrderBlock() { Clean(); } /** * Cleanup Model ... */ void Clean() { // orderBlock = NULL; fairValueGap = NULL; // ZeroMemory(this); } /** * Validate Model ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = // orderBlock != NULL && fairValueGap != NULL && // stateZones.IsValid() && ((orderBlock.IsBullish() && fairValueGap.IsBullish()) || ((orderBlock.IsBearish() && fairValueGap.IsBearish()))) // ; // return result; } /** * Get Model Direction ... * * @param dir: ENUM_X_DIRECTION member ... * * @return ( bool ) */ bool GetDirection( ENUM_X_DIRECTION &dir // ) { // bool result = false; // dir = X_DIRECTION_NONE; // result = IsValid(); if (!result) { return result; } // dir = orderBlock.IsBullish() ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // return result; } /** * Retrieve Boundary of Zone ... * * @param upper: Upper Boundary ...ّ * @param lower: Lower Bondary ... * @return ( bool ) */ bool GetBoundary( double &upper, double &lower // ) { // bool result = false; // upper = 0; lower = 0; // result = IsValid(); if (!result) { return result; } // upper = orderBlock.Upper(); upper = MathMax(upper, fairValueGap.Upper()); // lower = orderBlock.Lower(); lower = MathMax(lower, fairValueGap.Lower()); // result = lower > 0 && upper > 0 && upper > lower; // return result; } /** * Check Model is same as another Istance ... * * @param value: XFVGOrderBlock instance Reference ... * * @return ( bool ) */ bool IsSameAs(XFVGOrderBlock &value) { // bool result = false; // result = IsValid() && value.IsValid(); if (!result) { return result; } // ENUM_X_DIRECTION dir; result = GetDirection(dir); if (!result) { return result; } // ENUM_X_DIRECTION valueDir; result = value.GetDirection(valueDir); if (!result) { return result; } // result = // dir == valueDir // && // orderBlock.From() == value.orderBlock.From() && orderBlock.Upper() == value.orderBlock.Upper() && orderBlock.Lower() == value.orderBlock.Lower() // && // fairValueGap.From() == value.fairValueGap.From() && fairValueGap.Upper() == value.fairValueGap.Upper() && fairValueGap.Lower() == value.fairValueGap.Lower() // ; // return result; } // }; // // // // // XPVPivot Object ... class XCXPVPivotObject : public XCBaseObject { // public: // /** * Creator ... * * @param chart_id: Long, Specified Chart ID ... * @param window: Integer, Specified Chart Window ID ... * @param pivot: XPVPivot instance ... * @param prefix: String ... * * @return ( bool ) */ bool Create( long chart_id, int window, XPVPivot &pivot, string prefix = NULL // ) { // bool result = false; // result = pivot.IsValid(); if (!result) { return result; } // string name = pivot.GetTag(); if (IsValid(prefix)) { name = prefix + "_" + name; } // result = mRect.Create( chart_id, name, window, pivot.from, pivot.upper, pivot.to, pivot.lower // ); // if (result) { ObjName(name); } // string mTrendName = "MID_" + name; double mid = pivot.CalculateMid(); result = mTrend.Create( chart_id, mTrendName, window, pivot.from, mid, pivot.to, mid // ); if (!result) { // mRect.Delete(); mRect.Detach(); } // return result; } // // Getter(s) / Setter(s) ... /** * Set Pivot Width ... * * @param value: Integer ... */ void PivotWidth(int value) { // if (value < 1) { value = 1; } // mRect.Width(value); mTrend.Width(value); } /** * Set Pivot Color ... * * @param value: Color ... */ void PivotColor(color value) { // mRect.Color(value); mTrend.Color(value); } /** * Set Pivot Style ... * * @param value: ENUM_LINE_STYLE member ... */ void PivotStyle(ENUM_LINE_STYLE value) { // mRect.Style(value); mTrend.Style(value); } /** * Set Pivot Fill ... * * @param value: Boolean ... */ void PivotFill(bool value) { mRect.Fill(value); } // // Virtual ... /** * Retrieve Object Type ... * * @return ( ENUM_XCHARTOBJECTS ) */ virtual ENUM_XCHARTOBJECTS Type() { return X_XPVPIVOT_OBJ; } // private: // // // Props ... CChartObjectRectangle mRect; CChartObjectTrend mTrend; }; // // // /** * Draw Specified State Zone ... * * @param source: XStateZones instance Reference ... * * @return ( int ) */ int DrawStateZones( XStateZones &source, XCBaseObject *&drawnObjects[] // ) { // int result = 0; // Clean(drawnObjects); // if (!source.IsValid()) { return result; } // // SupportZones ... int count = source.CountSupportZones(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCSupportZone *iZone = source.supportZones[i]; XCSupportZoneObject *iObj; // bool isCreated = CreateSupportZone( iZone, iObj // ); if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } } // // ResistanceZones ... count = source.CountResistanceZones(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCResistanceZone *iZone = source.resistanceZones[i]; XCResistanceZoneObject *iObj; // bool isCreated = CreateResistanceZone( iZone, iObj // ); if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } } // // SupplyZones ... count = source.CountSupplyZones(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCSupplyZone *iZone = source.supplyZones[i]; XCSupplyZoneObject *iObj; // bool isCreated = CreateSupplyZone( iZone, iObj // ); if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } } // // DemandZones ... count = source.CountDemandZones(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCDemandZone *iZone = source.demandZones[i]; XCDemandZoneObject *iObj; // bool isCreated = CreateDemandZone( iZone, iObj // ); if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } } // // BullishOrderBlocks ... count = source.CountBullishOrderBlocks(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCOrderBlock *iZone = source.bullishOrderBlocks[i]; XCBullishOrderBlockObject *iObj; // bool isCreated = CreateBullishOrderBlock( iZone, iObj // ); if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } } // // BearishOrderBlocks ... count = source.CountBearishOrderBlocks(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCOrderBlock *iZone = source.bearishOrderBlocks[i]; XCBearishOrderBlockObject *iObj; // bool isCreated = CreateBearishOrderBlock( iZone, iObj // ); if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } } // // BullishFairValueGaps ... count = source.CountBullishFairValueGaps(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCFVG *iZone = source.bullishFairValueGaps[i]; XCBullishFairValueGapObject *iObj; // bool isCreated = CreateBullishFairValueGap( iZone, iObj // ); if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } } // // BearishFairValueGaps ... count = source.CountBearishFairValueGaps(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XCFVG *iZone = source.bearishFairValueGaps[i]; XCBearishFairValueGapObject *iObj; // bool isCreated = CreateBearishFairValueGap( iZone, iObj // ); if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } } // result = ArraySize(drawnObjects); // return result; } /** * Draw Specified Market Structure ... * * @param model: XMarketStructure instance Reference ... * * @return ( int ) */ int DrawMarketStructure( XMarketStructure &model, XCBaseObject *&drawnObjects[] // ) { // int result = 0; // Clean(drawnObjects); // datetime cTime = TimeCurrent(); // bool isValid = model.IsValid(); if (!isValid) { return result; } // if (model.lowestValeBar.IsValid()) { // XCOHCLObject *iObj; bool isCreated = CreateBar( model.lowestValeBar, iObj, cTime // ); // if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } // if (model.lowestValePeakBreakeUpBar.IsValid()) { // XCOHCLObject *iObj; bool isCreated = CreateBar( model.lowestValePeakBreakeUpBar, iObj, cTime // ); // if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } // if (model.valeAboveLowestValePeakBar.IsValid()) { // XCOHCLObject *iObj; bool isCreated = CreateBar( model.valeAboveLowestValePeakBar, iObj, cTime // ); // if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } // if (model.highestPeakBar.IsValid()) { // XCOHCLObject *iObj; bool isCreated = CreateBar( model.highestPeakBar, iObj, cTime // ); // if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } // if (model.peakBelowHighestPeakValeBar.IsValid()) { // XCOHCLObject *iObj; bool isCreated = CreateBar( model.peakBelowHighestPeakValeBar, iObj, cTime // ); // if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } // if (model.highestPeakValeBreakeDownBar.IsValid()) { // XCOHCLObject *iObj; bool isCreated = CreateBar( model.highestPeakValeBreakeDownBar, iObj, cTime // ); // if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } // if (HasChild(model.valePriceZones)) { // int count = ArraySize(model.valePriceZones); for (int i = 0; i < count; i++) { // XPriceZones ipZone = model.valePriceZones[i]; // XCBaseObject *ipObjects[]; int ipDrawnObjects = DrawPriceZone( ipZone, ipObjects, model.bias // ); if (IsValidSize(ipObjects)) { // Copy( ipObjects, drawnObjects, false // ); } } } // if (HasChild(model.peakPriceZones)) { // int count = ArraySize(model.peakPriceZones); for (int i = 0; i < count; i++) { // XPriceZones ipZone = model.peakPriceZones[i]; // XCBaseObject *ipObjects[]; int ipDrawnObjects = DrawPriceZone( ipZone, ipObjects, model.bias // ); if (IsValidSize(ipObjects)) { // Copy( ipObjects, drawnObjects, false // ); } } } // result = ArraySize(drawnObjects); // return result; } // // // /** * Draw Specific Pivot ... * * @param pivot: XPVPivot instance Reference ... * @param drawState: Boolean ... * @param drawTicksZone: Boolean ... * @param ignoreSwingHighs: Boolean ... * @param ignoreSwingLows: Boolean ... * @param ignoreSupportZones: Boolean ... * @param ignoreResistanceZones: Boolean ... * @param ignoreSupplyZones: Boolean ... * @param ignoreDemandZones: Boolean ... * @param ignoreBullishOrderBlocks: Boolean ... * @param ignoreBearishOrderBlocks: Boolean ... * @param ignoreBullishFairValueGaps: Boolean ... * @param ignoreBearishFairValueGaps: Boolean ... * @param ignoreBullishRejectionBars: Boolean ... * @param ignoreBearishRejectionBars: Boolean ... * @param ignoreBullishMomentumBars: Boolean ... * @param ignoreBearishMomentumBars: Boolean ... */ int DrawPivot( XPVPivot &pivot, XCBaseObject *&drawnObjects[], bool drawState = false, bool drawStateAsBox = false, bool drawTicksZone = false, bool ignoreSwingHighs = false, bool ignoreSwingLows = false, bool ignoreSupportZones = false, bool ignoreResistanceZones = false, bool ignoreSupplyZones = false, bool ignoreDemandZones = false, bool ignoreBullishOrderBlocks = false, bool ignoreBearishOrderBlocks = false, bool ignoreBullishFairValueGaps = false, bool ignoreBearishFairValueGaps = false, bool ignoreBullishRejectionBars = false, bool ignoreBearishRejectionBars = false, bool ignoreBullishMomentumBars = false, bool ignoreBearishMomentumBars = false // ) { // int result = 0; // Clean(drawnObjects); // if (!pivot.IsValid()) { return result; } // string prefix = Prefix(); long chartID = ChartIdentification(); int window = SubWindowIdentification(); // // Draw Pivot it self ... XCXPVPivotObject *iPivotObj; iPivotObj = new XCXPVPivotObject(); bool isCreated = iPivotObj.Create( chartID, window, pivot, prefix // ); if (!isCreated) { return result; } // color clrPivotColor = pivot.IsPeak() ? clrAqua : clrMagenta; iPivotObj.PivotColor(clrPivotColor); iPivotObj.PivotWidth(2); // Add( (XCBaseObject *)iPivotObj, drawnObjects // ); // result = ArraySize(drawnObjects); // if (!drawState) { return result; } // if (!pivot.state.IsValid()) { return result; } // XCBaseObject *stateObjects[]; int stateCount = 0; // if (!drawStateAsBox) { // stateCount = DrawState( pivot.state, stateObjects, drawTicksZone, ignoreSwingHighs, ignoreSwingLows, ignoreSupportZones, ignoreResistanceZones, ignoreSupplyZones, ignoreDemandZones, ignoreBullishOrderBlocks, ignoreBearishOrderBlocks, ignoreBullishFairValueGaps, ignoreBearishFairValueGaps, ignoreBullishRejectionBars, ignoreBearishRejectionBars, ignoreBullishMomentumBars, ignoreBearishMomentumBars // ); } else { // double peakUpper = 0; double peakLower = 0; double valeUpper = 0; double valeLower = 0; // datetime peakTo = NULL; datetime valeTo = NULL; datetime peakFrom = NULL; datetime valeFrom = NULL; // bool hasBoxData = DetectPivotStateBoxData( pivot, peakUpper, peakLower, peakFrom, peakTo, valeUpper, valeLower, valeFrom, valeTo // ); // if (hasBoxData) { // XCBoxObject *peakBox; bool isCreated = CreateBox( peakBox, peakUpper, peakLower, peakFrom, peakTo, clrMagenta, 1, false, STYLE_DASHDOT // ); if (isCreated) { // Add( (XCBaseObject *)peakBox, stateObjects // ); } // XCBoxObject *valeBox; isCreated = CreateBox( valeBox, valeUpper, valeLower, valeFrom, valeTo, clrAqua, 1, false, STYLE_DASHDOT // ); if (isCreated) { // Add( (XCBaseObject *)valeBox, stateObjects // ); } } } // if (IsValidSize(stateCount)) { // Copy( stateObjects, drawnObjects, false // Doesn't Clean ... ); // Clean(stateObjects); } // result = ArraySize(drawnObjects); // return result; } /** * Draw Specified XFVGOrderBlock Object ... * * @param models: XFVGOrderBlock instance Reference ... * * @return ( int ) */ int DrawFVGOrderBlock( XFVGOrderBlock &model, XCBaseObject *&drawnObjects[] // ) { // int result = 0; // Clean(drawnObjects); // if (!model.IsValid()) { return result; } // ENUM_X_DIRECTION iDir; result = model.GetDirection(iDir); if (!result) { return result; } // bool isBullish = IsBullish(iDir); if (isBullish) { // // Order Block ... XCBullishOrderBlockObject *iOBObj; bool isCreated = CreateBullishOrderBlock( model.orderBlock, iOBObj // ); if (isCreated) { // Add( (XCBaseObject *)iOBObj, drawnObjects // ); } // // FVG ... XCBullishFairValueGapObject *iFVGObj; isCreated = CreateBullishFairValueGap( model.fairValueGap, iFVGObj // ); if (isCreated) { // Add( (XCBaseObject *)iOBObj, drawnObjects // ); } } else { // // Order Block ... XCBearishOrderBlockObject *iOBObj; bool isCreated = CreateBearishOrderBlock( model.orderBlock, iOBObj // ); if (isCreated) { // Add( (XCBaseObject *)iOBObj, drawnObjects // ); } // // FVG ... XCBearishFairValueGapObject *iFVGObj; isCreated = CreateBearishFairValueGap( model.fairValueGap, iFVGObj // ); if (isCreated) { // Add( (XCBaseObject *)iFVGObj, drawnObjects // ); } } // result = ArraySize(drawnObjects); // return result; } // // // /** * Draw Price Zone ... * * @param zone: XPriceZones instance Reference ... * @param forDir: ENUM_X_DIRECTION member ... * * @return ( int ) */ int DrawPriceZone( XPriceZones &zone, XCBaseObject *&drawnObjects[], ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, bool onlyBoundary = false // ) { // int result = 0; // Clean(drawnObjects); // if (!zone.IsValid()) { return result; } // bool isBullish = IsBullish(forDir); bool isBearish = IsBearish(forDir); bool isAll = forDir == X_DIRECTION_ALL || forDir == X_DIRECTION_NONE; // if (isAll || isBullish) { // if (onlyBoundary) { // double upper = 0; double lower = 0; datetime to = NULL; datetime from = NULL; // bool isRetrieved = zone.GetBoxData( X_DIRECTION_NONE, upper, lower, from, to // ); if (isRetrieved) { // color clr = isBullish ? BarBullishColor() : isBearish ? BarBearishColor() : clrGray; XCBoxObject *iObj; result = CreateBox( iObj, upper, lower, from, to, clr, 1, false, STYLE_DOT // ); if (result) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } } else { // // Support Zone ... if (zone.HasSupportZone()) { // XCSupportZoneObject *iObj; bool isCreated = CreateSupportZone( zone.supportZone, iObj // ); if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } // // Demand Zone ... if (zone.HasDemandZone()) { // XCDemandZoneObject *iObj; bool isCreated = CreateDemandZone( zone.demandZone, iObj // ); if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } // // OrderBlock ... if (zone.HasOrderBlock() && zone.orderBlock.IsBullish()) { // XCBullishOrderBlockObject *iObj; bool isCreated = CreateBullishOrderBlock( zone.orderBlock, iObj // ); if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } // // FairValueGap ... if (zone.HasFairValueGap() && zone.fairValueGap.IsBullish()) { // XCBullishFairValueGapObject *iObj; bool isCreated = CreateBullishFairValueGap( zone.fairValueGap, iObj // ); if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } } } // if (isAll || isBearish) { // if (onlyBoundary) { // double upper = 0; double lower = 0; datetime to = NULL; datetime from = NULL; // bool isRetrieved = zone.GetBoxData( X_DIRECTION_NONE, upper, lower, from, to // ); if (isRetrieved) { // color clr = isBullish ? BarBullishColor() : isBearish ? BarBearishColor() : clrGray; XCBoxObject *iObj; result = CreateBox( iObj, upper, lower, from, to, clr, 1, false, STYLE_DOT // ); if (result) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } } else { // // Resistance Zone ... if (zone.HasResistanceZone()) { // XCResistanceZoneObject *iObj; bool isCreated = CreateResistanceZone( zone.resistanceZone, iObj // ); if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } // // Supply Zone ... if (zone.HasSupplyZone()) { // XCSupplyZoneObject *iObj; bool isCreated = CreateSupplyZone( zone.supplyZone, iObj // ); if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } // // OrderBlock ... if (zone.HasOrderBlock() && zone.orderBlock.IsBearish()) { // XCBearishOrderBlockObject *iObj; bool isCreated = CreateBearishOrderBlock( zone.orderBlock, iObj // ); if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } // // FairValueGap ... if (zone.HasFairValueGap() && zone.fairValueGap.IsBearish()) { // XCBearishFairValueGapObject *iObj; bool isCreated = CreateBearishFairValueGap( zone.fairValueGap, iObj // ); if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } } } // result = ArraySize(drawnObjects); // return result; } // // //