XBoxZone iPeak; XBoxZone iVale; XBoxZone iOBBull; XBoxZone iOBBear; XBoxZone iMTBull; XBoxZone iMTBear; // iPeak.Clean(); iVale.Clean(); iOBBull.Clean(); iOBBear.Clean(); iMTBull.Clean(); iMTBear.Clean(); // // Select MT Block ... // if (result) // { // // // // New MT Pivot Detected ... // if (detector.newMTBullishPivotDetected) // { // // // idx = GetYoungest(detector.mtBullishPivots); // if (IsValidIndex(idx)) // { // iMTBull = detector.mtBullishPivots[idx]; // } // } // else if (detector.newMTBearishPivotDetected) // { // // // idx = GetYoungest(detector.mtBearishPivots); // if (IsValidIndex(idx)) // { // iMTBear = detector.mtBearishPivots[idx]; // } // } // // // // Draw MT ... // // // // Bullish ... // has = iMTBull.IsValid(); // if (has) // { // // // iMTBull.to = conditions.bars[zIDX].time; // // // XCBoxObject *iObj; // has = drawer // .drawer // .DrawBox( // iMTBull, // iObj // // ); // if (has) // { // drawer.ApplyMTBullishPivotStyle(iObj); // } // } // // // // Bearish ... // has = iMTBear.IsValid(); // if (has) // { // // // iMTBear.to = conditions.bars[zIDX].time; // // // XCBoxObject *iObj; // has = drawer // .drawer // .DrawBox( // iMTBear, // iObj // // ); // if (has) // { // drawer.ApplyMTBearishPivotStyle(iObj); // } // } // } // // Select Peak and Vale ... // this used to Signalling Better ... // if (result) // { // // // // Select Peak ... // idx = GetLowest( // conditions.bars[cIDX], // detector.peakPivots // // ); // if (IsValidIndex(idx)) // { // // // iPeak = detector.peakPivots[idx]; // iPeak.to = conditions.bars[zIDX].time; // } // // // // Select Vale ... // idx = GetHighest( // conditions.bars[cIDX], // detector.valePivots // // ); // if (IsValidIndex(idx)) // { // // // iVale = detector.valePivots[idx]; // iVale.to = conditions.bars[zIDX].time; // } // // // // Checkig Result ... // result = // iPeak.IsValid() && // iVale.IsValid(); // // // // Draw Peak and Vales ... // if (result) // { // // // // Object Definitions ... // XCBoxObject *iObj; // // // // Draw Peak ... // has = drawer // .drawer // .DrawBox( // iPeak, // iObj // // ); // if (has) // { // drawer.ApplyPeakPivotStyle(iObj); // } // ZeroMemory(iObj); // // // // Draw Vale ... // has = drawer // .drawer // .DrawBox( // iVale, // iObj // // ); // if (has) // { // drawer.ApplyValePivotStyle(iObj); // } // ZeroMemory(iObj); // } // } // // // // We Have to Detect Youngest Order Block ... // // or Mitigation Block ... // if (isCond1Bullish) // { // // // // // // OB ... // // idx = GetYoungest(detector.obBullishPivots); // // has = IsValidIndex(idx); // // if (has) // // { // // iOB = detector.obBullishPivots[idx]; // // } // // // // MT ... // idx = GetYoungest(detector.mtBullishPivots); // has = IsValidIndex(idx); // if (has) // { // iOB = detector.mtBullishPivots[idx]; // } // } // else if (isCond1Bearish) // { // // // // OB // // idx = GetYoungest(detector.obBearishPivots); // // has = IsValidIndex(idx); // // if (has) // // { // // iOB = detector.obBearishPivots[idx]; // // } // // // // MT // idx = GetYoungest(detector.mtBearishPivots); // has = IsValidIndex(idx); // if (has) // { // iMT = detector.mtBearishPivots[idx]; // } // } // // // // Now we can Do some Verifications Using these ... // result = // isCond1Bullish // ? iMT.IsBullish() // : iMT.IsBearish(); // if (!result) // { // // // isCond1Bullish = false; // isCond1Bearish = false; // } // // All Requirements based on Cond 1 ... /////////////////////////////////////////////////////////////// // XOHCL pBar; has = bar.GetPreviousBar(pBar); if (has) { // ENUM_X_DIRECTION seqDir; // bool isSeqBreaked = barAnalyser .IsSeqBreak( pBar, seqDir // ); bool isBullishSeqBreaked = isSeqBreaked && IsBullish(seqDir); bool isBearishSeqBreaked = isSeqBreaked && IsBearish(seqDir); // if (isSeqBreaked) { Print("Detect Sequence Breaker Bar ..."); } } pBar.Clean(); /////////////////////////////////////////////////////////////// /** * Detect Spike ... * * @param bar: XOHCL instance reference, Start Bar ... * @param dir: ENUM_X_DIRECTION member, Event Direction ... * @param type: ENUM_X_PRICE member, Price Type ... * @param forcBodyInRange: bool, Use Body in Range Detection ... * @param rangeExtendMultiplier: double, a Multiplier for Checking Price Range ... * @param sameBars: int, Specified How Many Same Bars Required for an Spike ... * * @return ( bool ) */ bool IsSpike( XOHCL &bar, ENUM_X_DIRECTION &dir, int &rootIDX, ENUM_X_PRICE type = X_PRICE_CLOSE, bool forcBodyInRange = true, double rangeExtendMultiplier = 2.0, int sameBars = 3 // ) { // bool result = false; // dir = X_DIRECTION_NONE; sameBars = NormalizeInt(sameBars, 2); // result = IsValid(type) && bar.IsValid(); if (!result) { return result; } // // First We Have to Has a Big Change ... int sharpRootIDX = -1; result = IsSharp( bar, dir, sharpRootIDX, type, forcBodyInRange, rangeExtendMultiplier // ); if (!result) { return result; } // // Check Has Same Bars ... int sameBarsIndex = -1; ENUM_X_DIRECTION sameBarsDir; result = HasSameBars( bar, sameBarsDir, sameBarsIndex, sameBars // ); if (!result) { return result; } // // Check Same Bars Direction sames To Price Change ... result = sameBarsDir == dir; if (!result) { return result; } // rootIDX = sharpRootIDX; // return result; } /** * Check a Bar is Support Bar or not ... * * @param bar: XOHCL instance ... * @param supportBar: XOHCL instance, Provides Fouded Support Bar ... * @param range: Integer, Specified Verifiation Range ... * * @return ( bool ) */ bool HasSupport( XOHCL &bar, XOHCL &supportBar, int range = 21 // ) { // bool result = false; // result = bar.IsValid(); if (!result) { return result; } // int supportIDX = bar.Index() + range; result = supportBar.Init( bar.symbol, bar.period, supportIDX // ); if (!result) { // supportBar.Clean(); return result; } // result = bar.low > supportBar.low; if (!result) { // supportBar.Clean(); return result; } // // Validate Point ... for (int i = 1; i < range; i++) { // XOHCL iPBar; XOHCL iNBar; bool iHas = false; // iHas = iPBar.Init( bar.symbol, bar.period, supportIDX + i // ); result = iHas; if (!result) { break; } // iHas = iNBar.Init( bar.symbol, bar.period, supportIDX - i // ); result = iHas; if (!result) { break; } // result = supportBar.low < iPBar.low && supportBar.low < iNBar.low; if (!result) { break; } } // return result; } /** * Check a Bar is Resistance Bar or not ... * * @param bar: XOHCL instance ... * @param resistanceBar: XOHCL instance, Provides Fouded Support Bar ... * @param range: Integer, Specified Verifiation Range ... * * @return ( bool ) */ bool HasResistance( XOHCL &bar, XOHCL &resistanceBar, int range = 21 // ) { // bool result = false; // result = bar.IsValid(); if (!result) { return result; } // int resistanceIDX = bar.Index() + range; result = resistanceBar.Init( bar.symbol, bar.period, resistanceIDX // ); if (!result) { // resistanceBar.Clean(); return result; } // result = bar.high < resistanceBar.high; if (!result) { // resistanceBar.Clean(); return result; } // // Validate Point ... for (int i = 1; i < range; i++) { // XOHCL iPBar; XOHCL iNBar; bool iHas = false; // iHas = iPBar.Init( bar.symbol, bar.period, resistanceIDX + i // ); result = iHas; if (!result) { break; } // iHas = iNBar.Init( bar.symbol, bar.period, resistanceIDX - i // ); result = iHas; if (!result) { break; } // result = resistanceBar.high > iPBar.high && resistanceBar.high > iNBar.high; if (!result) { break; } } // return result; } /** * Detect a Fair Value Gap Based on Given Bar ... * * @param bar: XOHCL instance, Specified Start Bar ... * @param fromBar: XOHCL instance, Provides Start Bar of FVG ... * @param toBar: XOHCL instance, Provides End Bar of FVG ... * @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 &fromBar, XOHCL &toBar, ENUM_X_DIRECTION &dir, int sameBars = 3 // ) { // bool result = false; // toBar.Clean(); fromBar.Clean(); dir = X_DIRECTION_NONE; sameBars = NormalizeInt(sameBars, 1); // result = bar.IsValid(); if (!result) { // toBar.Clean(); fromBar.Clean(); 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 = fromBar.Init( bar.symbol, bar.period, i // ); if (!result) { break; } // result = toBar.Init( bar.symbol, bar.period, i - 2 // ); if (!result) { break; } // result = isBullish ? fromBar.high < toBar.low : fromBar.low > toBar.high; if (result) { break; } } // if (!result) { // toBar.Clean(); fromBar.Clean(); dir = X_DIRECTION_NONE; } // return result; } /** * 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 forceSpike = true, bool forceFairValueGap = true, bool forceSupportResistance = true // ) { // bool result = false; // ob.Clean(); dir = X_DIRECTION_NONE; sameBars = NormalizeInt(sameBars, 1); // result = bar.IsValid(); if (!result) { return result; } // XOHCL sBar; if (bar.Index() == 0) { // result = bar.GetPreviousBar(sBar); if (!result) { // sBar.Clean(); return result; } } else { sBar = bar; } // // First Step We Have to Check Same Bars ... int spikeRootIDX = -1; int sameBarsIndex = -1; result = HasSameBars( bar, dir, sameBarsIndex, sameBars // ); if (!result) { // ob.Clean(); return result; } // // Must an Spike Happens ... if (forceSpike) { // ENUM_X_DIRECTION spikeDir; result = IsSpike( bar, spikeDir, spikeRootIDX, // Spike Root Index ... X_PRICE_CLOSE, // Price Type ... true, // Force Body ... 1.5, // Range Extend Multiplier ... sameBars // ); result = result && dir == spikeDir; if (!result) { // ob.Clean(); return result; } } // // Select OB Candidate Bars ... XOHCL sameBar; XOHCL rootBar; XOHCL rootPBar; result = sameBar.Init( bar.symbol, bar.period, sameBarsIndex + 1 // ); if (!result) { // sBar.Clean(); sameBar.Clean(); return result; } result = rootBar.Init( bar.symbol, bar.period, spikeRootIDX // ); if (!result) { // sBar.Clean(); rootBar.Clean(); sameBar.Clean(); return result; } result = rootBar.GetPreviousBar(rootPBar); if (!result) { // sBar.Clean(); rootBar.Clean(); sameBar.Clean(); rootPBar.Clean(); return result; } // // Select ob Bar ... if (rootBar.GetDirection() == Opposit(dir)) { ob = rootBar; } else if (rootPBar.GetDirection() == Opposit(dir)) { ob = rootPBar; } else if (sameBar.GetDirection() == Opposit(dir)) { ob = sameBar; } else { ob.Clean(); } // // Select Order Block Bar ... result = ob.IsValid(); ENUM_X_DIRECTION obDir = ob.GetDirection(); result = result && dir == Opposit(obDir); if (!result) { // sBar.Clean(); rootBar.Clean(); sameBar.Clean(); rootPBar.Clean(); // return result; } // // if Bullish OB => Supports ... // if Bearish OB => Resistance ... if (forceSupportResistance) { // XOHCL supResBar; // // Check Support ... bool isSupport = HasSupport( ob, supResBar // ); // // Check Resistance ... bool isResistance = HasResistance( ob, supResBar // ); // supResBar.Clean(); // result = result && (IsBullish(dir) ? isSupport : isResistance); // if (!result) { // ob.Clean(); sBar.Clean(); rootBar.Clean(); sameBar.Clean(); rootPBar.Clean(); // return result; } } // // Force Check Fair ValueGaps ... if (forceFairValueGap) { // XOHCL toBar; XOHCL fromBar; ENUM_X_DIRECTION fvgDir; bool isFVG = HasFairValueGap( bar, fromBar, toBar, fvgDir, sameBars // ); // result = isFVG && result && dir == fvgDir; // toBar.Clean(); fromBar.Clean(); } // // Cleanup Resource ... // sBar.Clean(); rootBar.Clean(); sameBar.Clean(); rootPBar.Clean(); // return result; } /** * Check a Bar has Consolidation Zone or not ... * * @param bar: XOHCL instance, Specified Start Bar ... * @param zone: XConsolidationZone instance, consolidation Zone Object ... * @param minLoopback: int, min Allowed Lopback for Consolidating ... * @param range: double, Consolidation Range ... * @param upperAppliedTo: ENUM_X_PRICE member, Upper Selection Price ... * @param lowerAppliedTo: ENUM_X_PRICE member, Lower Selection Price ... * * @return ( bool ) */ bool HasConsolidationZone( XOHCL &bar, XConsolidationZone &zone, int minLoopback = 7, double range = 50, ENUM_X_PRICE upperAppliedTo = X_PRICE_HIGH, ENUM_X_PRICE lowerAppliedTo = X_PRICE_LOW // ) { // bool result = false; // zone.Clean(); range = NormalizeDouble(range, 50); minLoopback = NormalizeInt(minLoopback, 7); // result = bar.IsValid(); if (!result) { return result; } // double points = GetPoints(bar.symbol); int index = bar.Index() + 1; int length = minLoopback; // double upperPrice[]; int upperPriceCount = FillPrice( upperPrice, bar, length, upperAppliedTo // ); // double lowerPrice[]; int lowerPriceCount = FillPrice( lowerPrice, bar, length, lowerAppliedTo // ); // 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, bar, length, upperAppliedTo // ); // lowerPriceCount = FillPrice( lowerPrice, bar, length, lowerAppliedTo // ); // 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; } /////////////////////////////////////////////////////////////////// // // DOJI ... bool isDoji = IsDoji( bar, iDir // ); bool isBullishDoji = isDoji && IsBullish(iDir); bool isBearishDoji = isDoji && IsBearish(iDir); // // SWING ... bool isSwing = IsSwing( bar, iDir // ); bool isBullishSwing = isSwing && IsBullish(iDir); bool isBearishSwing = isSwing && IsBearish(iDir); // // HAMMER ... bool isHammer = IsHammer( bar, iDir // ); bool isBullishHammer = isHammer && IsBullish(iDir); bool isBearishHammer = isHammer && IsBearish(iDir); // // ENGULF ... bool isEngulfed = IsEngulfed( bar, iDir // ); bool isBullishEngulfed = isEngulfed && IsBullish(iDir); bool isBearishEngulfed = isEngulfed && IsBearish(iDir); // // REJECTED ... bool isRejected = IsRejected( bar, iDir // ); bool isBullishRejected = isRejected && IsBullish(iDir); bool isBearishRejected = isRejected && IsBearish(iDir); // // MOMENTUM ... bool isMomentum = IsMomentum( bar, iDir // ); bool isBullishMomentum = isMomentum && IsBullish(iDir); bool isBearishMomentum = isMomentum && IsBearish(iDir); // // Summarize Conditions ... // bool isBullishOr = isBullishDoji || isBullishSwing || isBullishHammer || isBullishEngulfed || isBullishRejected || isBullishMomentum; // bool isBearishOr = isBearishDoji || isBearishSwing || isBearishHammer || isBearishEngulfed || isBearishRejected || isBearishMomentum; // bool isBullish = isBullishOr && !isBearishOr; // bool isBearish = !isBullishOr && isBearishOr; /////////////////////////////////////////////////////////////////// bool IsVPattern( XOHCL &bar, ENUM_X_DIRECTION &dir, ENUM_X_PRICE pType = X_PRICE_CLOSE, int loopback = 3 // ) { // bool result = false; // // Normalize Args ... dir = X_DIRECTION_NONE; loopback = NormalizeInt(loopback, 3); // // Loopback Must an Odd Number ... // here we Validate and Normalize it ... double iLoopbackCheck = ((double)(loopback - 1)) / 2; if (iLoopbackCheck != 0) { loopback++; } // // Validate Args ... result = bar.IsValid() && IsValid(pType); if (!result) { return result; } // XOHCL iBar; int index = -1; XOHCL iSwingBar; double prices[]; bool has = false; double iPrice = 0; int pricesCount = 0; int swingBarIDX = -1; int loopbackHalf = 0; bool isBullish = false; bool isBearish = false; bool hasBullishSeq = false; bool hasBearishSeq = false; // if (result) { // // Retrieve Price Type Collection ... index = bar.Index(); pricesCount = FillPrice( prices, bar, loopback, pType // ); result = pricesCount == loopback; if (result) { // loopbackHalf = (loopback - 1) / 2; swingBarIDX = index + loopbackHalf + 1; has = IsValidIndex(swingBarIDX); // // Check for Bullish and Bearish ... if (has) { // hasBullishSeq = true; hasBearishSeq = true; iPrice = prices[swingBarIDX]; for (int i = 0; i < loopbackHalf - 1; i++) { // // Side Values ... // // Prev ... double iPPrice = prices[swingBarIDX + i]; double iP2Price = prices[swingBarIDX + i + 1]; // // Next ... double iNPrice = prices[swingBarIDX - i]; double iN2Price = prices[swingBarIDX - i - 1]; // if (hasBullishSeq) { // // For Bullish Seq ... // Prevs Must: iPPrice < iP2Price // Nexts Must: iNPrice < iN2Price hasBullishSeq = iPrice < iPPrice && iPrice < iNPrice && iPPrice <= iP2Price && iNPrice <= iN2Price; } // if (hasBearishSeq) { // // For Bearish Seq ... // Prevs Must: iPPrice > iP2Price // Nexts Must: iNPrice > iN2Price hasBearishSeq = iPrice > iPPrice && iPrice > iNPrice && iPPrice >= iP2Price && iNPrice >= iN2Price; } // if (!hasBullishSeq && !hasBearishSeq) { break; } } } // result = has && (hasBullishSeq || hasBearishSeq); } } // // Here we Make Sure the Propper Sequence is Exists ... if (result) { // // Try to Check onther Conditions ... has = iSwingBar.Init( bar.symbol, bar.period, swingBarIDX // ); // if (has) { // // Draw Requirement to Now ... string iName = "S_1"; datetime iTime = iSwingBar.time; // CChartObjectVLine *iObj = new CChartObjectVLine(); has = iObj.Create( 0, iName, 0, iTime // ); // iName = "SP_1"; iTime = GetBarTime( bar.symbol, bar.period, swingBarIDX + loopbackHalf); CChartObjectVLine *iObj1 = new CChartObjectVLine(); has = iObj1.Create( 0, iName, 0, iTime // ); // Print("Salam ..."); } } // // Summarize Result ... result = isBullish || isBearish; if (result) { // dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; } // // Cleanup Resource ... iBar.Clean(); iSwingBar.Clean(); // return result; } ///////////////////////////////////////////////////////////////////