/** * Detect Price Consolidation ... * * @param bar: XOHCL instance Reference, Start Bar ... * @param loopback: Integer, Consolidation Length Finder ... * @param consolidationRange: Integer, Consolidation Range Finder ... * @param upper: Double Reference ... * @param lower: Double Reference ... * @param upperAppliedTo: ENUM_APPLIED_PRICE member, Upper Price ... * @param lowerAppliedTo: ENUM_APPLIED_PRICE member, Lower Price ... * * @return ( bool ) */ bool IsConsolidate( XOHCL &bar, double &upper, double &lower, int loopback = 30, int consolidationRange = 50, ENUM_APPLIED_PRICE upperAppliedTo = PRICE_HIGH, ENUM_APPLIED_PRICE lowerAppliedTo = PRICE_LOW // ) { // bool result = false; // upper = 0; lower = 0; // if (loopback < 7) { loopback = 7; } // result = bar.IsValid(); if (!result) { return result; } // double points = GetPoints(bar.symbol); int index = bar.Index(); // double upperPrice[]; int upperPriceCount = FillPrice( upperPrice, upperAppliedTo, bar.symbol, bar.period, index, loopback // ); // double lowerPrice[]; int lowerPriceCount = FillPrice( lowerPrice, lowerAppliedTo, bar.symbol, bar.period, index, loopback // ); // result = upperPriceCount == lowerPriceCount && lowerPriceCount == loopback; if (!result) { return result; } // upper = upperPrice[ArrayMaximum(upperPrice)]; lower = lowerPrice[ArrayMinimum(lowerPrice)]; // double range = upper - lower; result = range <= consolidationRange * points; // return result; } bool HasConsolidationZone( XOHCL &bar, XConsolidationZone &zone, int minLoopback = 3, double range = 50, ENUM_APPLIED_PRICE upperAppliedTo = PRICE_HIGH, ENUM_APPLIED_PRICE lowerAppliedTo = PRICE_LOW // ) { // bool result = false; // zone.Clean(); // result = bar.IsValid() && minLoopback > 0 && range > 0; if (!result) { return result; } // double points = GetPoints(bar.symbol); int index = bar.Index() + 1; int length = minLoopback; // double upperPrice[]; int upperPriceCount = FillPrice( upperPrice, upperAppliedTo, bar.symbol, bar.period, index, length // ); // double lowerPrice[]; int lowerPriceCount = FillPrice( lowerPrice, lowerAppliedTo, bar.symbol, bar.period, index, length // ); // result = upperPriceCount == lowerPriceCount && lowerPriceCount == length; if (!result) { // Clean(upperPrice); Clean(lowerPrice); // return result; } // double upper = upperPrice[ArrayMaximum(upperPrice)]; double lower = lowerPrice[ArrayMinimum(lowerPrice)]; // bool isBullishBreake = bar.low > lower && bar.high > upper && bar.GetUp() > upper; bool isBearishBreake = bar.high < upper && bar.low < lower && bar.GetDown() < lower; result = isBullishBreake || isBearishBreake; if (!result) { // Clean(upperPrice); Clean(lowerPrice); // return result; } // double delta = upper - lower; result = delta <= range * points; if (!result) { // Clean(upperPrice); Clean(lowerPrice); // return result; } // while (delta <= range * points) { // length++; // upperPriceCount = FillPrice( upperPrice, upperAppliedTo, bar.symbol, bar.period, index, length // ); // lowerPriceCount = FillPrice( lowerPrice, lowerAppliedTo, bar.symbol, bar.period, index, length // ); // bool isValid = upperPriceCount == lowerPriceCount && lowerPriceCount == length; if (!isValid) { break; } // double iUpper = upperPrice[ArrayMaximum(upperPrice)]; double iLower = lowerPrice[ArrayMinimum(lowerPrice)]; // delta = iUpper - iLower; if (delta <= range * points) { // upper = iUpper; lower = iLower; } } // Clean(upperPrice); Clean(lowerPrice); // // Filling Zone ... zone.upper = upper; zone.lower = lower; zone.symbol = bar.symbol; zone.period = bar.period; zone.to = iTime( bar.symbol, bar.period, bar.Index() + 1 // ); zone.from = iTime( bar.symbol, bar.period, bar.Index() + length // ); zone.dir = isBullishBreake ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // result = zone.IsValid(); if (!result) { zone.Clean(); } // return result; } // // Commons ... /** * Check Specified Bar's Range is Extended or not ... * * @param bar: XOHCL instance, Specified Bar ... * @param loopback: Integer, Loopback Length ... * * @return ( bool ) */ bool HasExtendedRange( XOHCL &bar, int loopback = 3 // ) { // bool result = false; // if (loopback < 3) { loopback = 3; } // result = bar.IsValid(); if (!result) { return result; } // int index = bar.Index(); int start = index + 1; int end = start + loopback; int count = end - start; result = count >= 1; if (!result) { return result; } // double sum = 0; XOHCL iBar = bar; for (int i = start; i < end; i++) { // bool isRetrieved = iBar.GetPreviousBar(iBar); if (!isRetrieved) { continue; } // sum += iBar.GetRange(); } // result = sum > 0; if (!result) { return result; } // double avg = sum / count; // result = bar.GetRange() >= avg; // return result; } /** * Check Specified Bar's Body is Extended or not ... * * @param bar: XOHCL instance, Specified Bar ... * @param loopback: Integer, Loopback Length ... * * @return ( bool ) */ bool HasExtendedBody( XOHCL &bar, int loopback = 3 // ) { // bool result = false; // if (loopback < 3) { loopback = 3; } // result = bar.IsValid(); if (!result) { return result; } // int index = bar.Index(); int start = index + 1; int end = start + loopback; int count = end - start; result = count >= 1; if (!result) { return result; } // double sum = 0; XOHCL iBar = bar; for (int i = start; i < end; i++) { // bool isRetrieved = iBar.GetPreviousBar(iBar); if (!isRetrieved) { continue; } // sum += iBar.GetBody(); } // result = sum > 0; if (!result) { return result; } // double avg = sum / count; // result = bar.GetBody() >= avg; // return result; } /** * Check Specified Bar's Body and Range is Extended or not ... * * @param bar: XOHCL instance, Specified Bar ... * @param loopback: Integer, Loopback Length ... * * @return ( bool ) */ bool IsExtended( XOHCL &bar, int loopback = 3 // ) { // bool result = false; // bool hasExtendedBody = HasExtendedBody(bar, loopback); bool hasExtendedRange = HasExtendedRange(bar, loopback); result = hasExtendedBody && hasExtendedRange; // return result; } /** * Check Specified Bar is Swing High or not ... * * @param bar: XOHCL instnce ... * @param range: Integer, Specified Range ... * * @return ( bool ) */ bool IsSwingHigh( XOHCL &bar, int range = 2 // ) { // bool result = false; // if (range < 1) { range = 1; } // result = bar.IsValid(); if (!result) { return result; } // int index = bar.Index(); result = range > 0 && index >= range; if (!result) { return result; } // string symbol = bar.symbol; ENUM_TIMEFRAMES period = bar.period; // for (int i = 1; i <= range; i++) { // // Prev Bar ... XOHCL iPrevBar; result = iPrevBar.Init( symbol, period, index + i // ); if (!result) { break; } // // Next Bar ... XOHCL iNextBar; result = iNextBar.Init( symbol, period, index - i // ); if (!result) { break; } // result = bar.high >= iPrevBar.high && bar.high >= iNextBar.high; if (!result) { break; } } // return result; } /** * Check Specified Bar is Swing Low or not ... * * @param bar: XOHCL instnce ... * @param range: Integer, Specified Range ... * * @return ( bool ) */ bool IsSwingLow( XOHCL &bar, int range = 2 // ) { // bool result = false; // if (range < 1) { range = 1; } // result = bar.IsValid(); if (!result) { return result; } // int index = bar.Index(); result = range > 0 && index >= range; if (!result) { return result; } // string symbol = bar.symbol; ENUM_TIMEFRAMES period = bar.period; // for (int i = 1; i <= range; i++) { // // Prev Bar ... XOHCL iPrevBar; result = iPrevBar.Init( symbol, period, index + i // ); if (!result) { break; } // // Next Bar ... XOHCL iNextBar; result = iNextBar.Init( symbol, period, index - i // ); if (!result) { break; } // result = bar.low <= iPrevBar.low && bar.low <= iNextBar.low; if (!result) { break; } } // return result; } /** * Check Specified Bar is Swing or not ... * * @param bar: XOHCL instnce ... * @param dir: ENUM_X_DIRECTION member ... * @param range: Integer, Specified Range ... * * @return ( bool ) */ bool IsSwing( XOHCL &bar, ENUM_X_DIRECTION &dir, int range = 2 // ) { // bool result = false; // dir = X_DIRECTION_NONE; // bool isSwingLow = IsSwingLow(bar, range); bool isSwingHigh = IsSwingHigh(bar, range); // result = isSwingLow || isSwingHigh; if (result) { // if (isSwingLow) { dir = X_DIRECTION_BULLISH; } else { dir = X_DIRECTION_BEARISH; } } // return result; } /** * Check a Bar is Momentum Bar or not ... * * @param bar: XOHCL instance ... * @param dir: ENUM_X_DIRECTION member ... * @param extend: Integer ... * @param bodyPercent: Double ... * * @return ( bool ) */ bool IsMomentumBar( XOHCL &bar, ENUM_X_DIRECTION &dir, int extend = 1, double bodyPercent = 70 // ) { // bool result = false; // if (extend < 0) { extend = 0; } // if (bodyPercent < 50) { bodyPercent = 50; } // dir = X_DIRECTION_NONE; // result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // if (extend > 0) { // result = IsExtended( bar, extend // ); // if (!result) { return result; } } // double body = bar.GetBody(); double rp = GetBarRangePercent(bar); // result = body >= rp * bodyPercent; // if (result) { // dir = bar.IsBullish() ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; } // return result; } /** * Check a Bar is Rejection Bar or not ... * * @param bar: XOHCL instance ... * @param dir: ENUM_X_DIRECTION member ... * @param extend: Integer ... * @param shadowPercent: Double ... * * @return ( bool ) */ bool IsRejectionBar( XOHCL &bar, ENUM_X_DIRECTION &dir, int extend = 1, double shadowPercent = 60 // ) { // bool result = false; // if (extend < 0) { extend = 0; } // if (shadowPercent < 50) { shadowPercent = 50; } // dir = X_DIRECTION_NONE; // result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // if (extend > 0) { // result = IsExtended( bar, extend // ); // if (!result) { return result; } } // double body = bar.GetBody(); double range = bar.GetRange(); double shadows = bar.GetShadows(); double lowShadow = bar.GetLowShadow(); double highShadow = bar.GetHighShadow(); double rp = GetBarRangePercent(bar); // result = shadows >= rp * shadowPercent; // if (result) { // dir = lowShadow > highShadow ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; } // return result; } /** * Check Specified Bar is Engulfing Bar or not ... * * @param bar: XOHCL instance ... * @param dir: ENUM_X_DIRECTION member ... * @param extend: Integer ... * @param bodyPercent: Double ... * * @return ( bool ) */ bool IsEngulfBar( XOHCL &bar, ENUM_X_DIRECTION &dir, int extend = 1, double bodyPercent = 60 // ) { // bool result = false; // if (extend < 0) { extend = 0; } // if (bodyPercent < 50) { bodyPercent = 50; } // dir = X_DIRECTION_NONE; // result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // // Previous Bar ... XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { return result; } // if (extend > 0) { // result = IsExtended( pBar, extend // ); // if (!result) { return result; } } // // Check Engulfig ... result = bar.GetUp() > pBar.GetUp() && bar.GetDown() < pBar.GetDown(); if (!result) { return result; } // // Check Engulfing Direction ... bool isBullishEngulfed = pBar.IsBearish() && bar.IsBullish(); bool isBearishEngulfed = pBar.IsBullish() && bar.IsBearish(); // result = isBullishEngulfed || isBearishEngulfed; if (!result) { return result; } // dir = isBullishEngulfed ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // return result; } /** * Check Specified Bar is Pin Bar or not ... * * @param bar: XOHCL instance ... * @param dir: ENUM_X_DIRECTION member ... * @param extend: Integer ... * @param shadowPercent: Double ... * @param bodyPercent: Double ... * * @return ( bool ) */ bool IsPinBar( XOHCL &bar, ENUM_X_DIRECTION &dir, int extend = 1, double shadowPercent = 65, double bodyPercent = 25 // ) { // bool result = false; // dir = X_DIRECTION_NONE; // result = bar.IsValid() && bar.Index() > 0 && bodyPercent > 0 && shadowPercent > 0 && bodyPercent < shadowPercent; if (!result) { return result; } // // Chack Range Extends ... if (extend > 0) { // result = HasExtendedRange( bar, extend // ); if (!result) { return result; } } // // Check Body ... double rangePercent = GetBarRangePercent(bar); result = rangePercent > 0; if (!result) { return result; } // double body = bar.GetBody(); double highShadow = bar.GetHighShadow(); double lowShadow = bar.GetLowShadow(); // // Check Body ... result = body / rangePercent >= bodyPercent; if (!result) { return result; } // bool isPassedHighShadow = highShadow / rangePercent >= shadowPercent; bool isPassedLowShadow = lowShadow / rangePercent >= shadowPercent; result = isPassedLowShadow || isPassedHighShadow; if (!result) { return result; } // dir = isPassedLowShadow ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // return result; } /** * Decision Bar (Pin, Momentum or Rejection) ... * * @param bar: XOHCL instance ... * @param dir: ENUM_X_DIRECTION member ... * @param extend: Integer ... * @param shadowForPinAndRejectionBarPercent: Double ... * @param bodyForPinBarPercent: Double ... * @param bodyForEngulfBarPercent: Double ... * @param bodyForMomentumBarPercent: Double ... * * @return ( bool ) */ bool IsDecisionBar( XOHCL &bar, ENUM_X_DIRECTION &dir, int extend = 1, double shadowForPinAndRejectionBarPercent = 65, double bodyForPinBarPercent = 25, double bodyForEngulfBarPercent = 65, double bodyForMomentumBarPercent = 70 // ) { // bool result = false; // dir = X_DIRECTION_NONE; // result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // // Pin Bar ... ENUM_X_DIRECTION pinDir; bool isPiBar = IsPinBar( bar, pinDir, extend, shadowForPinAndRejectionBarPercent, bodyForPinBarPercent // ); // // Engulfing Bar ... ENUM_X_DIRECTION engulfDir; bool isEngulfBar = IsEngulfBar( bar, engulfDir, extend, bodyForEngulfBarPercent // ); // // Momentum Bar ... ENUM_X_DIRECTION momentumDir; bool isMomentumBar = IsMomentumBar( bar, momentumDir, extend, bodyForMomentumBarPercent // ); // // Rejection Bar ... ENUM_X_DIRECTION rejectionDir; bool isRejectionBar = IsRejectionBar( bar, rejectionDir, extend, shadowForPinAndRejectionBarPercent // ); // result = isPiBar || isEngulfBar || isMomentumBar || isRejectionBar; if (result) { // if (isPiBar) { dir = pinDir; } else if (isEngulfBar) { dir = engulfDir; } else if (isMomentumBar) { dir = momentumDir; } else { dir = rejectionDir; } } // result = IsBullish(dir) || IsBearish(dir); // return result; } // // Support and Resistance Zones ... /** * Check a Bar is Support Bar or not ... * * @param bar: XOHCL instance ... * @param range: Integer, Specified Verifiation Range ... * * @return ( bool ) */ bool IsSupport( XOHCL &bar, int range = 21 // ) { // bool result = false; // if (range < 2) { range = 2; } // result = bar.IsValid(); if (!result) { return result; } // int index = bar.Index(); result = range > 0 && index >= range; if (!result) { return result; } // string symbol = bar.symbol; ENUM_TIMEFRAMES period = bar.period; // for (int i = 1; i <= range; i++) { // int prevIDX = index + i; int nextIDX = index - 1; // // Prev Bar ... XOHCL iPrevBar; result = iPrevBar.Init( symbol, period, prevIDX // ); if (!result) { break; } // // Next Bar ... XOHCL iNextBar; result = iNextBar.Init( symbol, period, nextIDX // ); if (!result) { break; } // result = bar.low <= iPrevBar.low && bar.low <= iNextBar.low; if (!result) { break; } } // return result; } /** * Check a Bar Has Support or not ... * * @param bar: XOHCL instance ... * @param supportBar: XOHCL instance Specified Support Bar ... * @param rage: int, * @return ( bool ) */ bool HasSupport( XOHCL &bar, XOHCL &supportBar, int range = 21 // ) { // bool result = false; // result = bar.IsValid(); if (!result) { return result; } // int barIndex = bar.Index() + range; result = IsValidIndex(barIndex); if (!result) { // supportBar.Clean(); return result; } result = supportBar.Init( bar.symbol, bar.period, barIndex // ); // result = supportBar.low < supportBar.GetDown(); if (!result) { // supportBar.Clean(); return result; } // double selectedValue = supportBar.GetDown(); // int llIDX = bar.FindLowestIndex(range - 1, MODE_LOW); result = IsValidIndex(llIDX); if (!result) { // supportBar.Clean(); return result; } // double llValue = iLow( bar.symbol, bar.period, llIDX // ); // result = llValue >= selectedValue; if (!result) { // supportBar.Clean(); return result; } // result = supportBar.IsValid(); // return result; } /** * Check a Bar is Resistance Bar or not ... * * @param bar: XOHCL instance ... * @param range: Integer, Specified Verifiation Range ... * * @return ( bool ) */ bool IsResistance( XOHCL &bar, int range = 21 // ) { // bool result = false; // if (range < 2) { range = 2; } // result = bar.IsValid(); if (!result) { return result; } // int index = bar.Index(); result = range > 0 && index >= range; if (!result) { return result; } // string symbol = bar.symbol; ENUM_TIMEFRAMES period = bar.period; // for (int i = 1; i <= range; i++) { // int prevIDX = index + i; int nextIDX = index - 1; // // Prev Bar ... XOHCL iPrevBar; result = iPrevBar.Init( symbol, period, prevIDX // ); if (!result) { break; } // // Next Bar ... XOHCL iNextBar; result = iNextBar.Init( symbol, period, nextIDX // ); if (!result) { break; } // result = bar.high >= iPrevBar.high && bar.high >= iNextBar.high; if (!result) { break; } } // return result; } /** * Check a Bar Has Resistance or not ... * * @param bar: XOHCL instance ... * @param resistanceBar: XOHCL instance Specified Resistance Bar ... * @param rage: int, * @return ( bool ) */ bool HasResistance( XOHCL &bar, XOHCL &resistanceBar, int range = 21 // ) { // bool result = false; // result = bar.IsValid(); if (!result) { return result; } // int barIndex = bar.Index() + range; result = IsValidIndex(barIndex); if (!result) { // resistanceBar.Clean(); return result; } result = resistanceBar.Init( bar.symbol, bar.period, barIndex // ); // result = resistanceBar.low < resistanceBar.GetDown(); if (!result) { // resistanceBar.Clean(); return result; } // double selectedValue = resistanceBar.GetUp(); // int hhIDX = bar.FindHighestIndex(range - 1, MODE_HIGH); result = IsValidIndex(hhIDX); if (!result) { // resistanceBar.Clean(); return result; } // double hhValue = iHigh( bar.symbol, bar.period, hhIDX // ); // result = hhValue >= selectedValue; if (!result) { // resistanceBar.Clean(); return result; } // result = resistanceBar.IsValid(); // return result; } // // Order Blocks ... /** * Detect an Order Block Based on Given Bar ... * * @param bar: XOHCL instance, Specified Start Bar ... * @param ob: XOHCL instance, Fill it if Order Block Found ... * @param dir: ENUM_X_DIRECTION member, Specified Founded Order Block Direction ... * @param sameBars: Integer, Specified Min Same Bars for Detecting Order Block ... * * @return ( bool ) */ bool HasOrderBlock( XOHCL &bar, XOHCL &ob, ENUM_X_DIRECTION &dir, int sameBars = 3 // ) { // bool result = false; // ob.Clean(); dir = X_DIRECTION_NONE; // if (sameBars < 1) { sameBars = 1; } // result = bar.IsValid(); if (!result) { return result; } // int index = 0; result = HasSameBars( bar, dir, index, sameBars // ); if (!result) { return result; } // int obIndex = index + 1; result = ob.Init( bar.symbol, bar.period, obIndex // ); if (!result) { return result; } // return result; } // // Fair Value Gaps ... /** * Detect a Fair Value Gap Based on Given Bar ... * * @param bar: XOHCL instance, Specified Start Bar ... * @param dir: ENUM_X_DIRECTION member, Specified Founded Order Block Direction ... * @param sameBars: Integer, Specified Min Same Bars for Detecting Order Block ... * * @return ( bool ) */ bool HasFairValueGap( XOHCL &bar, XOHCL &prevBar, XOHCL &nextBar, ENUM_X_DIRECTION &dir, int sameBars = 3 // ) { // bool result = false; // prevBar.Clean(); nextBar.Clean(); dir = X_DIRECTION_NONE; // if (sameBars < 1) { sameBars = 1; } // result = bar.IsValid(); if (!result) { return result; } // int index = 0; result = HasSameBars( bar, dir, index, sameBars // ); if (!result) { return result; } // bool isBullish = IsBullish(dir); // int to = bar.Index(); int from = index > (to + sameBars) ? to + sameBars : index; for (int i = from; i > to; i--) { // result = prevBar.Init( bar.symbol, bar.period, i // ); if (!result) { break; } // result = nextBar.Init( bar.symbol, bar.period, i - 2 // ); if (!result) { break; } // result = isBullish ? prevBar.high < nextBar.low : prevBar.low > nextBar.high; if (result) { break; } } // if (!result) { // prevBar.Clean(); nextBar.Clean(); dir = X_DIRECTION_NONE; } // return result; } // // Bar CHOCH ... /** * Check Specified Bar Has PullBack or not ... * * @param dir: ENUM_X_DIRECTION member, Specified Direction ... * @param bar: XOHCL instance, Speciied Bar ... * @param loopback: Integer, loopback Length ... * @param forceBody: Boolean, Specified Choch Happens only by Bar's Body ... * * @return ( bool ) */ bool HasPullBack( ENUM_X_DIRECTION &dir, XOHCL &bar, int loopback = 3, bool forceBody = false // ) { // bool result = false; // dir = X_DIRECTION_NONE; // if (loopback < 1) { loopback = 1; } // result = bar.IsValid(); if (!result) { return result; } // string symbol = bar.symbol; ENUM_TIMEFRAMES period = bar.period; // // Calculate Loopback Data ... int index = -1; int start = -1; int end = -1; int count = -1; result = CalculateLoopBackData( index, start, end, count, bar, loopback // ); if (!result) { return result; } // // Calculate Loopback HH and LL Data ... int hhIDX = -1; double hh = -1; int llIDX = -1; double ll = -1; result = CalculateLoopbackHLData( hhIDX, hh, llIDX, ll, bar, loopback // ); if (!result) { return result; } // bool isBullishDirection = bar.high > hh && bar.low > ll; bool isBearishDirection = bar.high < hh && bar.low < ll; result = isBullishDirection || isBearishDirection; if (!result) { return result; } // if (forceBody) { // isBullishDirection = bar.GetUp() > hh && bar.GetDown() > ll; isBearishDirection = bar.GetUp() < hh && bar.GetDown() < ll; result = isBullishDirection || isBearishDirection; if (!result) { return result; } } // // Check Bar's Direction in related to CHOCH Direction ... result = isBullishDirection ? bar.IsBullish() : bar.IsBearish(); if (!result) { return result; } // // Set Direction ... dir = isBullishDirection ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // // Check Loopback End Bar ... XOHCL endBar; result = endBar.Init( symbol, period, end - 1 // ); if (!result) { return result; } // // End Bar Must be InDirect by Specified Bar ... result = isBullishDirection ? endBar.IsBearish() : endBar.IsBullish(); // // Check Loopback for Directional Bars ... // return result; } // // Tools ... // bool IsStrong( XOHCL &bar, double percent = 50 // Percent of Body ) { // bool result = false; // result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // result = (bar.GetRange() * percent) / 100 <= bar.GetBody(); // return result; } // bool HasStrongLowShadow( XOHCL &bar, double percent = 50, // Percent of Body int __loopback = 2, double _sharpRatio = 2.5 // ) { // bool result = false; // result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // result = (bar.GetRange() * percent) / 100 <= bar.GetLowShadow(); if (!result) { return result; } // if (__loopback < 0) { __loopback = 2; } // if (_sharpRatio < 0) { _sharpRatio = 2.5; } // result = bar.Index() > __loopback; if (!result) { return result; } // // Get Highest High and Lowest Low in loopback Range ... int startIndex = bar.Index() - __loopback; int endIndex = bar.Index() + __loopback; int requiredBars = MathAbs(endIndex - startIndex); // // Highs ... double highs[]; int copiedHighs = CopyHigh( bar.symbol, bar.period, startIndex, requiredBars, highs // ); // result = copiedHighs == requiredBars; if (!result) { return result; } // int highestHighIDX = ArrayMaximum(highs); result = IsValidIndex(highestHighIDX); if (!result) { return result; } // double highestHigh = highs[highestHighIDX]; // // Lows ... double lows[]; int copiedLows = CopyLow( bar.symbol, bar.period, startIndex, requiredBars, lows // ); // result = copiedLows == requiredBars; if (!result) { return result; } // int lowestLowIDX = ArrayMinimum(lows); result = IsValidIndex(lowestLowIDX); if (!result) { return result; } // double lowestLow = lows[lowestLowIDX]; // result = bar.low == lowestLow && highestHigh > bar.high; if (!result) { return result; } // // Try to Validate Sharp Ratio ... // Clean(highs); Clean(lows); // // Left Side ... startIndex = bar.Index() + 1; endIndex = startIndex + (__loopback / 2) - 1; requiredBars = MathAbs(endIndex - startIndex); // copiedHighs = CopyHigh( bar.symbol, bar.period, startIndex, requiredBars, highs // ); result = copiedHighs == requiredBars; if (!result) { return result; } // highestHighIDX = ArrayMaximum(highs); result = IsValidIndex(highestHighIDX); if (!result) { return result; } // highestHigh = highs[highestHighIDX]; // copiedLows = CopyLow( bar.symbol, bar.period, startIndex, requiredBars, lows // ); result = copiedLows == requiredBars; if (!result) { return result; } // lowestLowIDX = ArrayMinimum(lows); result = IsValidIndex(lowestLowIDX); if (!result) { return result; } // lowestLow = lows[lowestLowIDX]; // double leftDiff = highestHigh - lowestLow; // Clean(highs); Clean(lows); // // Right Side ... startIndex = bar.Index() - 1; endIndex = startIndex - (__loopback / 2) + 1; requiredBars = MathAbs(endIndex - startIndex); // copiedHighs = CopyHigh( bar.symbol, bar.period, startIndex, requiredBars, highs // ); result = copiedHighs == requiredBars; if (!result) { return result; } // highestHighIDX = ArrayMaximum(highs); result = IsValidIndex(highestHighIDX); if (!result) { return result; } // highestHigh = highs[highestHighIDX]; // copiedLows = CopyLow( bar.symbol, bar.period, startIndex, requiredBars, lows // ); result = copiedLows == requiredBars; if (!result) { return result; } // lowestLowIDX = ArrayMinimum(lows); result = IsValidIndex(lowestLowIDX); if (!result) { return result; } // lowestLow = lows[lowestLowIDX]; // double rightDiff = highestHigh - lowestLow; double diff = MathMax(leftDiff, rightDiff); result = bar.GetLowShadow() >= (diff / 100) * _sharpRatio; // return result; } // bool HasStrongHighShadow( XOHCL &bar, double percent = 50, // Percent of Body int __loopback = 2, double _sharpRatio = 2.5 // ) { // bool result = false; // result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // result = (bar.GetRange() * percent) / 100 <= bar.GetHighShadow(); if (!result) { return result; } // if (__loopback < 0) { __loopback = 2; } // if (_sharpRatio < 0) { _sharpRatio = 2.5; } // result = bar.Index() > __loopback; if (!result) { return result; } // // Get Highest High and Lowest Low in loopback Range ... int startIndex = bar.Index() - __loopback; int endIndex = bar.Index() + __loopback; int requiredBars = MathAbs(endIndex - startIndex); // // Highs ... double highs[]; int copiedHighs = CopyHigh( bar.symbol, bar.period, startIndex, requiredBars, highs // ); // result = copiedHighs == requiredBars; if (!result) { return result; } // int highestHighIDX = ArrayMaximum(highs); result = IsValidIndex(highestHighIDX); if (!result) { return result; } // double highestHigh = highs[highestHighIDX]; // // Lows ... double lows[]; int copiedLows = CopyLow( bar.symbol, bar.period, startIndex, requiredBars, lows // ); // result = copiedLows == requiredBars; if (!result) { return result; } // int lowestLowIDX = ArrayMinimum(lows); result = IsValidIndex(lowestLowIDX); if (!result) { return result; } // double lowestLow = lows[lowestLowIDX]; // result = bar.high == highestHigh && lowestLow < bar.low; if (!result) { return result; } // // Try to Validate Sharp Ratio ... // Clean(highs); Clean(lows); // // Left Side ... startIndex = bar.Index() + 1; endIndex = startIndex + (__loopback / 2) - 1; requiredBars = MathAbs(endIndex - startIndex); // copiedHighs = CopyHigh( bar.symbol, bar.period, startIndex, requiredBars, highs // ); result = copiedHighs == requiredBars; if (!result) { return result; } // highestHighIDX = ArrayMaximum(highs); result = IsValidIndex(highestHighIDX); if (!result) { return result; } // highestHigh = highs[highestHighIDX]; // copiedLows = CopyLow( bar.symbol, bar.period, startIndex, requiredBars, lows // ); result = copiedLows == requiredBars; if (!result) { return result; } // lowestLowIDX = ArrayMinimum(lows); result = IsValidIndex(lowestLowIDX); if (!result) { return result; } // lowestLow = lows[lowestLowIDX]; // double leftDiff = highestHigh - lowestLow; // Clean(highs); Clean(lows); // // Right Side ... startIndex = bar.Index() - 1; endIndex = startIndex - (__loopback / 2) + 1; requiredBars = MathAbs(endIndex - startIndex); // copiedHighs = CopyHigh( bar.symbol, bar.period, startIndex, requiredBars, highs // ); result = copiedHighs == requiredBars; if (!result) { return result; } // highestHighIDX = ArrayMaximum(highs); result = IsValidIndex(highestHighIDX); if (!result) { return result; } // highestHigh = highs[highestHighIDX]; // copiedLows = CopyLow( bar.symbol, bar.period, startIndex, requiredBars, lows // ); result = copiedLows == requiredBars; if (!result) { return result; } // lowestLowIDX = ArrayMinimum(lows); result = IsValidIndex(lowestLowIDX); if (!result) { return result; } // lowestLow = lows[lowestLowIDX]; // double rightDiff = highestHigh - lowestLow; double diff = MathMax(leftDiff, rightDiff); result = bar.GetHighShadow() >= (diff / 100) * _sharpRatio; // return result; } // bool IsStrongBullish( XOHCL &bar, double percent = 50 // Percent of Body ) { // bool result = false; // result = bar.IsValid() && bar.IsBullish() && IsStrong(bar, percent); // return result; } // bool IsStrongBearish( XOHCL &bar, double percent = 50 // Percent of Body ) { // bool result = false; // result = bar.IsValid() && bar.IsBearish() && IsStrong(bar, percent); // return result; } // bool IsSharpBullish( XOHCL &bar, int __loopback = 2, double _sharpRatio = 2.5 // ) { // bool result = false; // result = bar.IsValid(); if (!result) { return result; } // if (__loopback < 0) { __loopback = 2; } // if (_sharpRatio < 0) { _sharpRatio = 2.5; } // int hIDX = bar.FindHighestIndex( __loopback, MODE_HIGH // ); int lIDX = bar.FindLowestIndex( __loopback, MODE_LOW // ); // result = // hIDX >= 0 && lIDX >= 0 && MathAbs(hIDX - bar.Index()) < 2 // ; // if (!result) { return result; } // XOHCL hBar; result = hBar.Init( bar.symbol, bar.period, hIDX // ); if (!result) { return result; } // XOHCL lBar; result = lBar.Init( bar.symbol, bar.period, lIDX // ); if (!result) { return result; } // double lhDif = hBar.high - lBar.low; // int hhIDX = hBar.FindHighestIndex( __loopback, MODE_HIGH // ); // int llIDX = lBar.FindLowestIndex( __loopback, MODE_LOW // ); // XOHCL hhBar; result = hhBar.Init( bar.symbol, bar.period, hhIDX + hIDX // ); if (!result) { return result; } // XOHCL llBar; result = llBar.Init( bar.symbol, bar.period, llIDX + lIDX // ); if (!result) { return result; } // double llhhDif = hhBar.high - llBar.low; // result = // lBar.low > llBar.low && hBar.high > hhBar.high && lhDif >= llhhDif * _sharpRatio // ; // return result; } // bool IsSharpBearish( XOHCL &bar, int __loopback = 2, double _sharpRatio = 2.5 // ) { // bool result = false; // result = bar.IsValid(); if (!result) { return result; } // if (__loopback < 0) { __loopback = 2; } // if (_sharpRatio < 0) { _sharpRatio = 2.5; } // int hIDX = bar.FindHighestIndex( __loopback, MODE_HIGH // ); int lIDX = bar.FindLowestIndex( __loopback, MODE_LOW // ); // result = // hIDX >= 0 && lIDX >= 0 && MathAbs(hIDX - bar.Index()) < 2 // ; // if (!result) { return result; } // XOHCL hBar; result = hBar.Init( bar.symbol, bar.period, hIDX // ); if (!result) { return result; } // XOHCL lBar; result = lBar.Init( bar.symbol, bar.period, lIDX // ); if (!result) { return result; } // double lhDif = hBar.high - lBar.low; // int hhIDX = hBar.FindHighestIndex( __loopback, MODE_HIGH // ); // int llIDX = lBar.FindLowestIndex( __loopback, MODE_LOW // ); // XOHCL hhBar; result = hhBar.Init( bar.symbol, bar.period, hhIDX + hIDX // ); if (!result) { return result; } // XOHCL llBar; result = llBar.Init( bar.symbol, bar.period, llIDX + lIDX // ); if (!result) { return result; } // double llhhDif = hhBar.high - llBar.low; // result = // lBar.low < llBar.low && hBar.high < hhBar.high && lhDif >= llhhDif * _sharpRatio // ; // return result; } // // // // // Retrieve Bullish Pressure ... double GetBullishPressure( XOHCL &bar, int __loopback = 7 // ) { // double result = 0; // if (!bar.IsValid()) { return result; } // XOHCL bars[]; int barsCount = GetBars( bars, bar.symbol, bar.period, bar.Index(), __loopback // ); if (!IsValidSize(barsCount)) { return result; } // for (int i = 0; i < barsCount; i++) { result += bars[i].GetLowShadow(); } // return result; } // // Retrieve Bearish Pressure ... double GetBearishPressure( XOHCL &bar, int __loopback = 7 // ) { // double result = 0; // if (!bar.IsValid()) { return result; } // XOHCL bars[]; int barsCount = GetBars( bars, bar.symbol, bar.period, bar.Index(), __loopback // ); if (!IsValidSize(barsCount)) { return result; } // for (int i = 0; i < barsCount; i++) { result += bars[i].GetHighShadow(); } // return result; } // bool HasBullishPressure( XOHCL &bar, int __loopback = 7 // ) { // bool result = false; // if (__loopback < 0) { __loopback = 7; } // result = bar.IsValid(); if (!result) { return result; } // double bullishPressure = GetBullishPressure(bar, __loopback); double bearishPressure = GetBearishPressure(bar, __loopback); // result = // bullishPressure > 0 && bearishPressure >= 0 && bullishPressure > bearishPressure // ; // return result; } // bool HasBearishPressure( XOHCL &bar, int __loopback = 7 // ) { // bool result = false; // if (__loopback < 0) { __loopback = 7; } // result = bar.IsValid(); if (!result) { return result; } // double bullishPressure = GetBullishPressure(bar, __loopback); double bearishPressure = GetBearishPressure(bar, __loopback); // result = // bearishPressure > 0 && bullishPressure >= 0 && bearishPressure > bullishPressure // ; // return result; } // // Retrieve Bullish Power ... double GetBullishPower( XOHCL &bar, int __loopback = 7 // ) { // double result = 0; // if (!bar.IsValid()) { return result; } // XOHCL bars[]; int barsCount = GetBars( bars, bar.symbol, bar.period, bar.Index(), __loopback // ); if (!IsValidSize(barsCount)) { return result; } // for (int i = 0; i < barsCount; i++) { // if (bars[i].IsBullish()) { result += bars[i].GetBody(); } } // return result; } // // Retrieve Bearish Pressure ... double GetBearishPower( XOHCL &bar, int __loopback = 7 // ) { // double result = 0; // if (!bar.IsValid()) { return result; } // XOHCL bars[]; int barsCount = GetBars( bars, bar.symbol, bar.period, bar.Index(), __loopback // ); if (!IsValidSize(barsCount)) { return result; } // for (int i = 0; i < barsCount; i++) { // if (bars[i].IsBearish()) { result += bars[i].GetBody(); } } // return result; } // bool HasBullishPower( XOHCL &bar, int __loopback = 7 // ) { // bool result = false; // if (__loopback < 0) { __loopback = 7; } // result = bar.IsValid(); if (!result) { return result; } // double bullishPressure = GetBullishPower(bar, __loopback); double bearishPressure = GetBearishPower(bar, __loopback); // result = // bullishPressure > 0 && bearishPressure >= 0 && bullishPressure > bearishPressure // ; // return result; } // bool HasBearishPower( XOHCL &bar, int __loopback = 7 // ) { // bool result = false; // if (__loopback < 0) { __loopback = 7; } // result = bar.IsValid(); if (!result) { return result; } // double bullishPressure = GetBullishPower(bar, __loopback); double bearishPressure = GetBearishPower(bar, __loopback); // result = // bearishPressure > 0 && bullishPressure >= 0 && bearishPressure > bullishPressure // ; // return result; } // // Decisions ... // // Candlestic Patterns ... // // Check Doji ... bool IsDoji( XOHCL &bar // ) { // bool result = false; // // Validate Content and Ignore 0 Bar // since it is not Completed ... result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // result = bar.open == bar.close; // return result; } // // Check Hammer ... bool IsHammer( XOHCL &bar, double _upShadowFactor = 0.1, double _downShadowFactor = 0.6, bool applyFib382Check = true, bool applyPrevShadowCheck = true // ) { // bool result = false; // // Validate Content and Ignore 0 Bar // since it is not Completed ... result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // if (_upShadowFactor < 0) { _upShadowFactor = 0.1; } // if (_downShadowFactor < 0) { _upShadowFactor = 0.6; } // double range = bar.GetRange(); // // Check Upper Shadow Must be 0 or Under 10% ... double upShadow = bar.GetHighShadow(); result = upShadow < range * _upShadowFactor; if (!result) { return result; } // // Check Down Shadow Must at least 60% ... double downShadow = bar.GetLowShadow(); result = downShadow > range * _downShadowFactor; if (!result) { return result; } // // Check Fib 382 ... if (result && applyFib382Check) { // double fib382 = GetFibonacciLevel( bar.high, bar.low, 0.382, -1 // ); result = bar.GetDown() > fib382; } // // Check Shadow Based on Prev Bar ... if (result && applyPrevShadowCheck) { // XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { return result; } // result = bar.low < pBar.low; } // return result; } // // Check Sgooting Star ... // Reversal Hammer ... bool IsShootingStar( XOHCL &bar, double _upShadowFactor = 0.6, double _downShadowFactor = 0.1, bool applyFib382Check = true, bool applyPrevShadowCheck = true // ) { // bool result = false; // // Validate Content and Ignore 0 Bar // since it is not Completed ... result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // if (_upShadowFactor < 0) { _upShadowFactor = 0.6; } // if (_downShadowFactor < 0) { _upShadowFactor = 0.1; } // double range = bar.GetRange(); // // Check Upper Shadow Must be 0 or Under 10% ... double upShadow = bar.GetHighShadow(); result = upShadow > range * _upShadowFactor; if (!result) { return result; } // // Check Down Shadow Must at least 60% ... double downShadow = bar.GetLowShadow(); result = downShadow < range * _downShadowFactor; if (!result) { return result; } // // Check Fib 382 ... if (result && applyFib382Check) { // double fib382 = GetFibonacciLevel( bar.high, bar.low, 0.382, 1 // ); result = bar.GetUp() < fib382; } // // Check Shadow Based on Prev Bar ... if (result && applyPrevShadowCheck) { // XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { return result; } // result = bar.high > pBar.high; } // return result; } // // Check Bullish Engulfing ... bool IsBullishEngulfing( XOHCL &bar, double _engulfBarBodyFactor = 0.7 // ) { // bool result = false; // // Validate Content and Ignore 0 Bar // since it is not Completed ... result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // if (_engulfBarBodyFactor < 0) { _engulfBarBodyFactor = 0.7; } // // Check Bar Is Bullish ... result = bar.IsBullish(); if (!result) { return result; } // // Retrieve Previous Bar ... XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { return result; } // double range = bar.GetRange(); double body = bar.GetBody(); // // Check Prev Bar Must Bearish ... result = pBar.IsBearish(); if (!result) { return result; } // // Check Shadows Engulf Prev Bar ... result = // bar.high > pBar.high && bar.low <= pBar.low // ; if (!result) { return result; } // // Check Engulfed Bar Must Inside Engulfer Body ... result = // bar.GetUp() > pBar.GetUp() && bar.GetDown() < pBar.GetDown() // ; if (!result) { return result; } // // Check Body of Engulfing Bar ... if (result && _engulfBarBodyFactor > 0) { result = body >= range * _engulfBarBodyFactor; } // return result; } // // Check Bearish Engulfing ... bool IsBearishEngulfing( XOHCL &bar, double _engulfBarBodyFactor = 0.7 // ) { // bool result = false; // // Validate Content and Ignore 0 Bar // since it is not Completed ... result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // if (_engulfBarBodyFactor < 0) { _engulfBarBodyFactor = 0.7; } // // Check Bar Is Bearish ... result = bar.IsBearish(); if (!result) { return result; } // // Retrieve Previous Bar ... XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { return result; } // double range = bar.GetRange(); double body = bar.GetBody(); // // Check Prev Bar Must Bullish ... result = pBar.IsBullish(); if (!result) { return result; } // // Check Shadows Engulf Prev Bar ... result = bar.high >= pBar.high && bar.low < pBar.low; if (!result) { return result; } // // Check Engulfed Bar Must Inside Engulfer Body ... result = // bar.GetUp() > pBar.GetUp() && bar.GetDown() < pBar.GetDown() // ; if (!result) { return result; } // // Check Body of Engulfing Bar ... if (result && _engulfBarBodyFactor > 0) { result = body >= range * _engulfBarBodyFactor; } // return result; } // // Check Morning Star Pattern ... bool IsMorningStar( XOHCL &bar, double _middleRangeFactor = 0.3, double _startBodyFactor = 0.6, bool forceCheckMiddleBarDirection = true, bool forceCheckStartBody = true // ) { // bool result = false; // // Validate Content and Ignore 0 Bar // since it is not Completed ... result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // if (_middleRangeFactor < 0) { _middleRangeFactor = 0.3; } // if (_startBodyFactor < 0) { _startBodyFactor = 0.6; } // // Current Bar Must be Bullish ... result = bar.IsBullish(); if (!result) { return result; } // // Retrieve Previous Bar ... XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { return result; } // // Prev Bar must be Bearish ... if (result && forceCheckMiddleBarDirection) { // result = pBar.IsBearish(); if (!result) { return result; } } // // Retrieve Previous Bar of Prev Bar ... XOHCL ppBar; result = pBar.GetPreviousBar(ppBar); if (!result) { return result; } // // Prev Of Prev Bar Must be Bearish ... result = ppBar.IsBearish(); if (!result) { return result; } // double range = bar.GetRange(); double pRange = pBar.GetRange(); double ppRange = ppBar.GetRange(); // // Middle Bar must be Smaller than Ratio of other ... result = // pRange < range * _middleRangeFactor && pRange < ppRange * _middleRangeFactor // ; if (!result) { return result; } // if (result && forceCheckStartBody) { // result = ppBar.GetBody() > ppRange * _startBodyFactor; if (!result) { return result; } } // return result; } // // Check Evening Star Pattern ... bool IsEveningStar( XOHCL &bar, double _middleRangeFactor = 0.3, double _startBodyFactor = 0.6, bool forceCheckMiddleBarDirection = true, bool forceCheckStartBody = true // ) { // bool result = false; // // Validate Content and Ignore 0 Bar // since it is not Completed ... result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // if (_middleRangeFactor < 0) { _middleRangeFactor = 0.3; } // if (_startBodyFactor < 0) { _startBodyFactor = 0.6; } // // Current Bar Must be Bearish ... result = bar.IsBearish(); if (!result) { return result; } // // Retrieve Previous Bar ... XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { return result; } // // Prev Bar must be Bullish ... if (result && forceCheckMiddleBarDirection) { // result = pBar.IsBullish(); if (!result) { return result; } } // // Retrieve Previous Bar of Prev Bar ... XOHCL ppBar; result = pBar.GetPreviousBar(ppBar); if (!result) { return result; } // // Prev Of Prev Bar Must be Bullish ... result = ppBar.IsBullish(); if (!result) { return result; } // double range = bar.GetRange(); double pRange = pBar.GetRange(); double ppRange = ppBar.GetRange(); // // Middle Bar must be Smaller than Ratio of other ... result = // pRange < range * _middleRangeFactor && pRange < ppRange * _middleRangeFactor // ; if (!result) { return result; } // if (result && forceCheckStartBody) { // result = ppBar.GetBody() > ppRange * _startBodyFactor; if (!result) { return result; } } // return result; } // // Bullish Marubozu ... bool IsBullishMarubozu(XOHCL &bar) { // bool result = false; // result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // result = bar.IsBullish(); if (!result) { return result; } // result = // bar.GetUp() == bar.high && bar.GetDown() == bar.low // ; // return result; } // // Bearish Marubozu ... bool IsBearishMarubozu(XOHCL &bar) { // bool result = false; // result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // result = bar.IsBearish(); if (!result) { return result; } // result = // bar.GetUp() == bar.high && bar.GetDown() == bar.low // ; // return result; } // // Contextual Patterns ... // // Check Swing High ... bool IsBarSwingHigh(XOHCL &bar) { // bool result = false; // // Validate Content and Ignore 0 Bar // since it is not Completed ... result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // // Current Bar Must be Bearish ... result = bar.IsBearish(); if (!result) { return result; } // // Retrieve Prev Bar ... XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { return result; } // // Prev Bar Must be Bullish ... result = pBar.IsBullish(); if (!result) { return result; } // // Retrieve Prev of Prev Bar ... XOHCL ppBar; result = pBar.GetPreviousBar(ppBar); if (!result) { return result; } // // Prev of Prev Bar Must be Bullish ... result = ppBar.IsBullish(); if (!result) { return result; } // // Check All Highs ... result = // bar.high < pBar.high && pBar.high > ppBar.high // ; // return result; } // // Find Simple 3 Candle Based Swing High ... bool IsSimpleSwingHigh( XOHCL &bar, double thresholdInPoint = 1 // ) { // bool result = false; // int index = bar.Index(); result = index > 0; if (!result) { return result; } // XOHCL nextBar; result = bar.GetNextBar(nextBar); if (!result) { return result; } // XOHCL prevBar; result = bar.GetPreviousBar(prevBar); if (!result) { return result; } // double point = GetPoints(bar.symbol); double requiredOffset = point * thresholdInPoint; // result = bar.high > nextBar.high && bar.high > prevBar.high && (thresholdInPoint <= 0 ? true : MathAbs( MathMax( nextBar.high, prevBar.high) - bar.high) >= requiredOffset); // return result; } // // Find Last Swing High ... bool FindLastSwingHigh( XOHCL &bar, XOHCL &swing // ) { // bool result = false; // swing.Clean(); // result = bar.IsValid(); if (!result) { return result; } // int totalBars = iBars( bar.symbol, bar.period // ); int maxAllowed = MathMin(100, (totalBars / 100)); // int idx = bar.Index(); for (int i = idx; i <= idx + maxAllowed; i++) { // swing.Clean(); result = swing.Init( bar.symbol, bar.period, i // ); if (!result) { // swing.Clean(); break; } // result = IsBarSwingHigh(swing); if (result) { break; } } // return result; } // // Check Swing Low ... bool IsBarSwingLow(XOHCL &bar) { // bool result = false; // // Validate Content and Ignore 0 Bar // since it is not Completed ... result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // // Current Bar Must be Bullish ... result = bar.IsBullish(); if (!result) { return result; } // // Retrieve Prev Bar ... XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { return result; } // // Prev Bar Must be Bearish ... result = pBar.IsBearish(); if (!result) { return result; } // // Retrieve Prev of Prev Bar ... XOHCL ppBar; result = pBar.GetPreviousBar(ppBar); if (!result) { return result; } // // Prev of Prev Bar Must be Bearish ... result = ppBar.IsBearish(); if (!result) { return result; } // // Check All Lows ... result = // bar.low > pBar.low && pBar.low < ppBar.low // ; // return result; } // // Find Simple 3 Candle Based Swing Low ... bool IsSimpleSwingLow( XOHCL &bar, double thresholdInPoint = 1 // ) { // bool result = false; // int index = bar.Index(); result = index > 0; if (!result) { return result; } // XOHCL nextBar; result = bar.GetNextBar(nextBar); if (!result) { return result; } // XOHCL prevBar; result = bar.GetPreviousBar(prevBar); if (!result) { return result; } // double point = GetPoints(bar.symbol); double requiredOffset = point * thresholdInPoint; // result = bar.low < nextBar.low && bar.low < prevBar.low && (thresholdInPoint <= 0 ? true : MathAbs( MathMax( nextBar.low, prevBar.low) - bar.low) >= requiredOffset); // return result; } // // Find Last Swing Low ... bool FindLastSwingLow( XOHCL &bar, XOHCL &swing // ) { // bool result = false; // swing.Clean(); // result = bar.IsValid(); if (!result) { return result; } // int totalBars = iBars( bar.symbol, bar.period // ); int maxAllowed = MathMin(100, (totalBars / 100)); // int idx = bar.Index(); for (int i = idx; i <= idx + maxAllowed; i++) { // swing.Clean(); result = swing.Init( bar.symbol, bar.period, i // ); if (!result) { // swing.Clean(); break; } // result = IsBarSwingLow(swing); if (result) { break; } } // return result; } // // Check Bullish FVG ... bool HasBullishFVG( XOHCL &bar, double &upper, double &lower, datetime &start, datetime &end, bool forceMiddleBarCheck = true, bool forceCheckLastBarDirection = false // ) { // bool result = false; // upper = 0; lower = 0; // end = NULL; start = NULL; // // Validate Content and Ignore 0 Bar // since it is not Completed ... result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // // Current Bar Must be Bullish ... result = !forceCheckLastBarDirection ? true : bar.IsBullish(); if (!result) { return result; } // // Retrieve Prev Bar ... XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { return result; } // // Prev Bar Must be Bullish ... result = pBar.IsBullish(); if (!result) { return result; } // // Retrieve Prev of Prev Bar ... XOHCL ppBar; result = pBar.GetPreviousBar(ppBar); if (!result) { return result; } // // Prev of Prev Bar Must be Bullish ... result = ppBar.IsBullish(); if (!result) { return result; } // // Other Conditions ... result = // bar.low > ppBar.high // ; // // Check Middle Bar Range ... if (result && forceMiddleBarCheck) { // result = // pBar.high > bar.low && pBar.low < ppBar.high // ; // if (!result) { return result; } } // if (result) { // end = bar.time; upper = bar.low; lower = ppBar.high; start = ppBar.time; } // return result; } // // Check Bearish FVG ... bool HasBearishFVG( XOHCL &bar, double &upper, double &lower, datetime &start, datetime &end, bool forceMiddleBarCheck = true, bool forceCheckLastBarDirection = false // ) { // bool result = false; // upper = 0; lower = 0; // end = NULL; start = NULL; // // Validate Content and Ignore 0 Bar // since it is not Completed ... result = bar.IsValid() && bar.Index() > 0; if (!result) { return result; } // // Current Bar Must be Bearish ... result = !forceCheckLastBarDirection ? true : bar.IsBullish(); if (!result) { return result; } // // Retrieve Prev Bar ... XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { return result; } // // Prev Bar Must be Bearish ... result = pBar.IsBearish(); if (!result) { return result; } // // Retrieve Prev of Prev Bar ... XOHCL ppBar; result = pBar.GetPreviousBar(ppBar); if (!result) { return result; } // // Prev of Prev Bar Must be Bearish ... result = ppBar.IsBearish(); if (!result) { return result; } // // Other Conditions ... result = // bar.high < ppBar.low // ; // // Check Middle Bar Range ... if (result && forceMiddleBarCheck) { // result = // pBar.high > bar.low && pBar.low < ppBar.high // ; // if (!result) { return result; } } // if (result) { // end = bar.time; lower = bar.high; upper = ppBar.low; start = ppBar.time; } // return result; } // // Find Support ... bool HasSupport( XOHCL &bar, XOHCL &dest, ENUM_X_PRICE type = X_PRICE_CLOSE, int _loopback = 21, int tries = 100 // ) { // bool result = false; // dest.Clean(); // if (_loopback < 0) { _loopback = 21; } // if (tries < 0) { tries = 100; } // result = bar.IsValid(); if (!result) { return result; } // double price = bar.GetPrice(type); // for (int i = 1; i < tries; i++) { // int _length = _loopback * i; // int lowestIDX = bar.FindLowestIndex( _length, MODE_LOW // ); result = IsValidIndex(lowestIDX); if (!result) { break; } // XOHCL iLBar; result = iLBar.Init( bar.symbol, bar.period, lowestIDX // ); if (!result) { break; } // result = // price > iLBar.high // ; if (result) { // dest = iLBar; break; } } // result = dest.IsValid(); // return result; } // // Find Resistance ... bool HasResistance( XOHCL &bar, XOHCL &dest, ENUM_X_PRICE type = X_PRICE_CLOSE, int _loopback = 21, int tries = 100 // ) { // bool result = false; // dest.Clean(); // if (_loopback < 0) { _loopback = 21; } // if (tries < 0) { tries = 100; } // result = bar.IsValid(); if (!result) { return result; } // double price = bar.GetPrice(type); // for (int i = 1; i < tries; i++) { // int _length = _loopback * i; // int highestIDX = bar.FindHighestIndex( _length, MODE_LOW // ); result = IsValidIndex(highestIDX); if (!result) { break; } // XOHCL iHBar; result = iHBar.Init( bar.symbol, bar.period, highestIDX // ); if (!result) { break; } // result = // price < iHBar.high // ; if (result) { // dest = iHBar; break; } } // result = dest.IsValid(); // return result; } // // Trend Detection ... // // Find Bullish Trend ... bool HasBullishTrend( XOHCL &bar, XOHCL &highSwingBars[], XOHCL &lowSwingBars[], bool forceMethod2 = false, int _loopback = 3, int tries = 3, ENUM_X_PRICE type = X_PRICE_CLOSE // ) { // bool result = false; // Clean(lowSwingBars); Clean(highSwingBars); // result = bar.IsValid(); if (!result) { return result; } // double price = bar.GetPrice(type); // int lastIDX = bar.Index(); double lastH = 0; double lastL = 0; for (int i = 1; i < tries + 1; i++) { // // Use Regular Method ... if (!forceMethod2) { // int iHIDX = FindSwing( bar.symbol, bar.period, X_SWING_HIGH, _loopback, lastIDX // ); result = IsValidIndex(iHIDX); if (!result) { break; } // XOHCL iHBar; result = iHBar.Init( bar.symbol, bar.period, iHIDX // ); if (!result) { break; } // double iH = iHBar.high; bool isIHAccepted = // iH > 0 && ( // lastH == 0 ? true : iH < lastH // ) // ; if (isIHAccepted) { // AddRef( iHBar, highSwingBars // ); // lastH = iH; lastIDX = iHIDX; } // int iLIDX = FindSwing( bar.symbol, bar.period, X_SWING_LOW, _loopback, lastIDX // ); result = IsValidIndex(iLIDX); if (!result) { break; } // XOHCL iLBar; result = iLBar.Init( bar.symbol, bar.period, iLIDX // ); if (!result) { break; } // double iL = iLBar.low; bool isILAccepted = // iL > 0 && ( // lastL == 0 ? true : iL < lastL // ) // ; if (isILAccepted) { // AddRef( iLBar, lowSwingBars // ); // lastL = iL; lastIDX = iLIDX; } } // // Use Other MEthod ... else { // int _length = i * _loopback; int start = // i == 1 ? 1 : _length - _loopback // ; // int iHIDX = iHighest( bar.symbol, bar.period, MODE_HIGH, _loopback, start // ); result = IsValidIndex(iHIDX); if (!result) { break; } // XOHCL iHBar; result = iHBar.Init( bar.symbol, bar.period, iHIDX // ); if (!result) { break; } // double iH = iHBar.high; bool isIHAccepted = // iH > 0 && ( // lastH == 0 ? true : iH < lastH // ) // ; if (isIHAccepted) { // AddRef( iHBar, highSwingBars // ); // lastH = iH; lastIDX = iHIDX; } // int iLIDX = iLowest( bar.symbol, bar.period, MODE_LOW, _loopback, start // ); result = IsValidIndex(iLIDX); if (!result) { break; } // XOHCL iLBar; result = iLBar.Init( bar.symbol, bar.period, iLIDX // ); if (!result) { break; } // double iL = iLBar.low; bool isILAccepted = // iL > 0 && ( // lastL == 0 ? true : iL < lastL // ) // ; if (isILAccepted) { // AddRef( iLBar, lowSwingBars // ); // lastL = iL; lastIDX = iLIDX; } } } // if (result) { // result = // ArraySize(lowSwingBars) == tries && ArraySize(highSwingBars) == tries // ; } // if (!result) { // Clean(lowSwingBars); Clean(highSwingBars); } // return result; } // // Find Bearish Trend ... bool HasBearishTrend( XOHCL &bar, XOHCL &highSwingBars[], XOHCL &lowSwingBars[], bool forceMethod2 = false, int _loopback = 3, int tries = 3, ENUM_X_PRICE type = X_PRICE_CLOSE // ) { // bool result = false; // Clean(lowSwingBars); Clean(highSwingBars); // result = bar.IsValid(); if (!result) { return result; } // double price = bar.GetPrice(type); // int lastIDX = bar.Index(); double lastH = 0; double lastL = 0; for (int i = 1; i < tries + 1; i++) { // // Use Regular Method ... if (!forceMethod2) { // int iHIDX = FindSwing( bar.symbol, bar.period, X_SWING_HIGH, _loopback, lastIDX // ); result = IsValidIndex(iHIDX); if (!result) { break; } // XOHCL iHBar; result = iHBar.Init( bar.symbol, bar.period, iHIDX // ); if (!result) { break; } // double iH = iHBar.high; bool isIHAccepted = // iH > 0 && ( // lastH == 0 ? true : iH > lastH // ) // ; if (isIHAccepted) { // AddRef( iHBar, highSwingBars // ); // lastH = iH; lastIDX = iHIDX; } // int iLIDX = FindSwing( bar.symbol, bar.period, X_SWING_LOW, _loopback, lastIDX // ); result = IsValidIndex(iLIDX); if (!result) { break; } // XOHCL iLBar; result = iLBar.Init( bar.symbol, bar.period, iLIDX // ); if (!result) { break; } // double iL = iLBar.low; bool isILAccepted = // iL > 0 && ( // lastL == 0 ? true : iL > lastL // ) // ; if (isILAccepted) { // AddRef( iLBar, lowSwingBars // ); // lastL = iL; lastIDX = iLIDX; } } // // Use Other MEthod ... else { // int _length = i * _loopback; int start = // i == 1 ? 1 : _length - _loopback // ; // int iHIDX = iHighest( bar.symbol, bar.period, MODE_HIGH, _loopback, start // ); result = IsValidIndex(iHIDX); if (!result) { break; } // XOHCL iHBar; result = iHBar.Init( bar.symbol, bar.period, iHIDX // ); if (!result) { break; } // double iH = iHBar.high; bool isIHAccepted = // iH > 0 && ( // lastH == 0 ? true : iH > lastH // ) // ; if (isIHAccepted) { // AddRef( iHBar, highSwingBars // ); // lastH = iH; lastIDX = iHIDX; } // int iLIDX = iLowest( bar.symbol, bar.period, MODE_LOW, _loopback, start // ); result = IsValidIndex(iLIDX); if (!result) { break; } // XOHCL iLBar; result = iLBar.Init( bar.symbol, bar.period, iLIDX // ); if (!result) { break; } // double iL = iLBar.low; bool isILAccepted = // iL > 0 && ( // lastL == 0 ? true : iL > lastL // ) // ; if (isILAccepted) { // AddRef( iLBar, lowSwingBars // ); // lastL = iL; lastIDX = iLIDX; } } } // if (result) { // result = // ArraySize(lowSwingBars) == tries && ArraySize(highSwingBars) == tries // ; } // if (!result) { // Clean(lowSwingBars); Clean(highSwingBars); } // return result; } // // Order Blocks ... // // Find Bullish Order Block ... bool HasBullishOrderBlock( XOHCL &bar, XOHCL &orderBlock, int _minimumSameBars = 4 // ) { // bool result = false; // orderBlock.Clean(); // result = bar.IsValid(); if (!result) { return result; } // if (_minimumSameBars < 0) { _minimumSameBars = 4; } // XOHCL cBar; int founded = 0; int cIDX = bar.Index(); bool isEnough = false; while (!isEnough) { // result = cBar.Init( bar.symbol, bar.period, cIDX // ); if (!result) { break; } // result = cBar.IsBullish(); if (!result && cBar.IsBearish()) { break; } // cIDX++; founded++; } // // Here we have to check founded and if it's fill // our requirements ... // cIDX is Order Block Index ... result = // cBar.IsValid() && bar.high > cBar.high && founded >= _minimumSameBars // ; if (!result) { return result; } // result = orderBlock.Init( bar.symbol, bar.period, cIDX // ); if (!result) { // orderBlock.Clean(); return result; } // return result; } // // Find Bearish Order Block ... bool HasBearishOrderBlock( XOHCL &bar, XOHCL &orderBlock, int _minimumSameBars = 4 // ) { // bool result = false; // orderBlock.Clean(); // result = bar.IsValid(); if (!result) { return result; } // if (_minimumSameBars < 0) { _minimumSameBars = 4; } // XOHCL cBar; int founded = 0; int cIDX = bar.Index(); bool isEnough = false; while (!isEnough) { // bool isInited = cBar.Init( bar.symbol, bar.period, cIDX // ); // result = cBar.IsBearish(); if (!result && cBar.IsBullish()) { break; } // cIDX++; founded++; } // // Here we have to check founded and if it's fill // our requirements ... // cIDX is Order Block Index ... result = // cBar.IsValid() && bar.high < cBar.low && founded >= _minimumSameBars // ; if (!result) { return result; } // result = orderBlock.Init( bar.symbol, bar.period, cIDX // ); if (!result) { // orderBlock.Clean(); return result; } // return result; }