/** * Leg Pattern Detection ... * * @param bar: XOHCL, reference to Specified Bar ... * @param zone: XBoxZone, reference to Holds Detection Zone ... * @param validationLength: int, leg minimum Validation Length ... * @param loopback: int, Max Allowed Loopback Length ... * * @return ( bool ) */ bool IsLegPattern( XOHCL &bar, XLeg &leg, int validationLength = 3, int loopback = 10 // ) { // bool result = false; // // Prepare ... leg.Clean(); // // Normalize ... loopback = NormalizeInt(loopback, 5); // // Validate ... result = bar.IsValid(); if (!result) { return result; } // // Prepare Patterns Analysis Config ... XPatternAnalysisConfig iPatternsConfig; iPatternsConfig.Default(); iPatternsConfig.CleanPatterns(); iPatternsConfig.AddPattern(X_BAR_PATTERN_LOW); iPatternsConfig.AddPattern(X_BAR_PATTERN_HIGH); iPatternsConfig.AddPattern(X_BAR_PATTERN_FLAG); iPatternsConfig.AddPattern(X_BAR_PATTERN_STAR); iPatternsConfig.AddPattern(X_BAR_PATTERN_RISING); iPatternsConfig.AddPattern(X_BAR_PATTERN_PIERCING); iPatternsConfig.AddPattern(X_BAR_PATTERN_ENGULFED); iPatternsConfig.AddPattern(X_BAR_PATTERN_MOMENTUM); iPatternsConfig.AddPattern(X_BAR_PATTERN_SIGNALKEY); iPatternsConfig.AddPattern(X_BAR_PATTERN_TRUE_GAPED); // XOHCL iBar; XOHCL pBar; XOHCL iZBar; XBoxZone zone; XBoxZone iZone; XBoxZone jZone; bool has = false; XBoxZone supports[]; XOHCL bullishBars[]; XOHCL bearishBars[]; XBoxZone bullishFVGs[]; XBoxZone bearishFVGs[]; bool isBullish = false; bool isBearish = false; XBoxZone resistances[]; double bullishPower = 0; double bearishPower = 0; int bullishBarsCount = 0; int bearishBarsCount = 0; int barIndex = bar.Index(); int start = barIndex + 1; XPatternAnalysis iPattern; int end = start + loopback; XPatternAnalysis patterns[]; int bullishPatternsCount = 0; int bearishPatternsCount = 0; int sequentialsBullishBarsCount = 0; int sequentialsBearishBarsCount = 0; ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; // for (int i = end; i >= start; i--) { // // Initialize Indexed Bar ... iBar.Clean(); pBar.Clean(); result = bar.BarAt(i, iBar); result = result && iBar.GetPreviousBar(pBar); if (!result) { break; } // // Fill Bar Direction ... isBullish = iBar.IsBullish(); isBearish = iBar.IsBearish(); // // Directional ... // if (isBullish) { // bullishBarsCount++; // bullishPower += iBar.GetBody(); bullishPower += iBar.GetLowShadow(); bullishPower -= iBar.GetHighShadow(); // AddIfNotExists(iBar, bullishBars); } // if (isBearish) { // bearishBarsCount++; // bearishPower += iBar.GetBody(); bearishPower -= iBar.GetLowShadow(); bearishPower += iBar.GetHighShadow(); // AddIfNotExists(iBar, bearishBars); } // // Sequentail .... // // Bullish ... if (isBullish) { // if (pBar.IsBullish()) { sequentialsBullishBarsCount++; } else if (pBar.IsBearish()) { sequentialsBullishBarsCount = 0; } } // // Bearish ... if (isBearish) { // if (pBar.IsBearish()) { sequentialsBearishBarsCount++; } else if (pBar.IsBullish()) { sequentialsBearishBarsCount = 0; } } // // Detect Patterns ... iPattern.Clean(); has = AnalyseBarPatterns(iBar, iPattern, iPatternsConfig); if (has) { // AddRef(iPattern, patterns); // bullishPatternsCount += iPattern.Count(X_DIRECTION_BULLISH); bearishPatternsCount += iPattern.Count(X_DIRECTION_BEARISH); } // // FVG Detection ... CleanDirection(iDir); has = HasFVG(iBar, iDir, iZone); if (has) { // if (iZone.IsBullish()) { AddIfNotExists(iZone, bullishFVGs); } else { AddIfNotExists(iZone, bearishFVGs); } } // // Support / Resistance Detection ... has = HasSupportResistance( iBar, iZone, jZone, 5 // ); if (has) { // if (iZone.IsValid()) { AddIfNotExists(iZone, supports); } // if (jZone.IsValid()) { AddIfNotExists(jZone, resistances); } } } // // Summarizing ... // // Detect Direction ... zone.Clean(); isBullish = false; isBearish = false; CleanDirection(iDir); // isBullish = // bullishPower > 0 && bullishBarsCount > 0 && bullishPatternsCount > 0 && sequentialsBullishBarsCount > 0 && // bullishPower > bearishPower && bullishBarsCount > bearishBarsCount && bullishPatternsCount > bearishPatternsCount && sequentialsBullishBarsCount > sequentialsBearishBarsCount // ; // isBearish = // bearishPower > 0 && bearishBarsCount > 0 && bearishPatternsCount > 0 && sequentialsBearishBarsCount > 0 && // bearishPower > bullishPower && bearishBarsCount > bullishBarsCount && bearishPatternsCount > bullishPatternsCount && sequentialsBearishBarsCount > sequentialsBullishBarsCount // ; // // Validate ... result = (isBullish && !isBearish) || (isBearish && !isBullish); // // PRICE Types ... ENUM_X_PRICE lowerPriceType = X_PRICE_LOW; ENUM_X_PRICE upperPriceType = X_PRICE_HIGH; // // Prepare Zone ... if (result) { // zone.at = bar.time; zone.to = bar.time; zone.period = bar.period; zone.symbol = bar.symbol; // zone.type = ToXString(X_BAR_PATTERN_LEG); zone.dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // int idx = -1; if (isBullish) { idx = GetOldest(bullishBars); } else { idx = GetOldest(bearishBars); } // result = IsValidIndex(idx); if (result) { // iZBar.Clean(); if (isBullish) { iZBar = bullishBars[idx]; } else { iZBar = bearishBars[idx]; } // zone.from = iZBar.time; // iZBar.Clean(); } // if (isBullish) { // // Prepare Upper and Lower ... // // Upper ... idx = GetHighestBarPrice(bullishBars, upperPriceType); if (IsValidIndex(idx)) { zone.upper = bullishBars[idx].GetPrice(upperPriceType); } // // Lower ... idx = GetLowestBarPrice(bullishBars, upperPriceType); if (IsValidIndex(idx)) { zone.lower = bullishBars[idx].GetPrice(lowerPriceType); } } else { // // Prepare Upper and Lower ... // // Upper ... idx = GetHighestBarPrice(bearishBars, upperPriceType); if (IsValidIndex(idx)) { zone.upper = bearishBars[idx].GetPrice(upperPriceType); } // // Lower ... idx = GetLowestBarPrice(bearishBars, upperPriceType); if (IsValidIndex(idx)) { zone.lower = bearishBars[idx].GetPrice(lowerPriceType); } } // result = zone.IsValid(); } // // Prepare XLeg ... if (result) { // leg.dir = zone.dir; leg.time = zone.from; leg.upper = zone.upper; leg.lower = zone.lower; leg.symbol = zone.symbol; leg.period = zone.period; Copy(patterns, leg.patterns); Copy(supports, leg.supports); Copy(bullishBars, leg.bullishBars); Copy(bearishBars, leg.bearishBars); Copy(resistances, leg.resistances); Copy(bullishFVGs, leg.bullishFVGs); Copy(bearishFVGs, leg.bearishFVGs); leg.sequentialBullishBars = sequentialsBullishBarsCount; leg.sequentialBearishBars = sequentialsBearishBarsCount; // result = leg.IsValid(); } // // Cleanup ... if (!result) { zone.Clean(); } iBar.Clean(); pBar.Clean(); zone.Clean(); iZBar.Clean(); iZone.Clean(); jZone.Clean(); iPattern.Clean(); XClean(supports); XClean(patterns); XClean(bullishBars); XClean(bearishBars); XClean(bullishFVGs); XClean(bearishFVGs); XClean(resistances); // return result; } bool IsLegPattern1( XOHCL &bar, XLeg &leg, int validationLength = 5, int loopback = 500 // ) { // bool result = false; // // Prepare ... leg.Clean(); // // Normalize ... loopback = NormalizeInt(loopback, 50); validationLength = NormalizeInt(validationLength, 3); // // Validate ... result = bar.IsValid() && fimaParser.IsValid(); if (!result) { return result; } // int idx = bar.Index(); while (idx < bar.Index() + loopback) { // } // return result; } ////////////////////////////////////////////////// // // Leg ... XLeg leg; // Exists Leg ... bool drawLeg; // Draw Leg ... bool manageLegs; // bool HasLeg() { return leg.IsValid(); } // bool ValidateLeg(XOHCL &bar) { // bool result = false; // result = HasLeg() && bar.IsValid(); if (!result) { return result; } // result = leg.IsBullish() ? bar.low > leg.lower : leg.IsBearish() ? bar.high < leg.upper : false; // return result; } // void DrawLeg() { // if (!drawLeg) { return; } // if (!HasLeg()) { return; } // // Update to Times ... leg.UpdateTimes(); // // Draw Leg Box ... XBoxZone legZone; leg.ToBox(legZone); if (legZone.IsValid()) { // legZone.to = TimeCurrent(); poiDrawer.DrawZone(legZone, structureDrawConfig.drawConfig); } // // Draw Legs Other Stufs ... return; // // FVGs ... poiDrawer.DrawZones(leg.bullishFVGs, structureDrawConfig.drawConfig); poiDrawer.DrawZones(leg.bearishFVGs, structureDrawConfig.drawConfig); // // Support and Resistances ... poiDrawer.DrawZones(leg.supports, structureDrawConfig.drawConfig); poiDrawer.DrawZones(leg.resistances, structureDrawConfig.drawConfig); // // Patterns ... poiDrawer.DrawPatternAnalysises(leg.patterns, structureDrawConfig.barAnalysisDrawConfig); } // void ManageLeg(XOHCL &bar) { // // Validate Exists ... if (HasLeg()) { // if (!ValidateLeg(bar)) { // // Invalidate XLeg ... leg.Clean(); } } // // Detect New ... if (!HasLeg()) { poiDetector.IsLegPattern(bar, leg); } // // Update Exists ... if (HasLeg()) { // // Update to Times ... leg.UpdateTimes(); // DrawLeg(); } } // // // ManageLeg(bar); // // Checking For Leg Pattern ... bool hasLeg = poiDetector.IsLegPattern( pBar, _leg, 3, 10 // ); if (hasLeg) { hasLeg = _leg.ToBox(legZone); } bool hasBullishLeg = hasLeg && _leg.IsBullish(); bool hasBearishLeg = hasLeg && _leg.IsBearish(); // // // int CollectPivots( XPivot &pivots[], int barIndex = 0, int loopback = 500 // ) { // int result = 0; // // Prepare ... XClean(pivots); // // Normalize ... loopback = NormalizeInt(loopback, 50); barIndex = NormalizeBarIndex(barIndex); // // Validate ... bool has = IsValid(); if (!has) { return result; } // has = false; XOHCL tmpBar; XPivot tmpPivot; double tmpValue; datetime tmpTime; bool isBullish = false; bool isBearish = false; string tmpSymbol = symbol; ENUM_TIMEFRAMES tmpPeriod = period; ENUM_X_DIRECTION tmpDir = X_DIRECTION_NONE; for (int i = barIndex; i < barIndex + loopback; i++) { // tmpBar.Clean(); tmpPivot.Clean(); // has = tmpBar.Init(tmpSymbol, tmpPeriod, i); if (!has) { continue; } // // XSAR ... isBullish = IsSARSwitchedToBullish(i); isBearish = IsSARSwitchedToBearish(i); has = isBullish || isBearish; if (has) { } // // XMA Fast / Slow ... // // States ... isBullish = IsMASlowSwitchedToBullish(i); isBearish = IsMASlowSwitchedToBearish(i); has = isBullish || isBearish; if (has) { } // // Crossed Fast Slow ... isBullish = IsMAFastCrossedOverSlow(i); isBearish = IsMAFastCrossedUnderSlow(i); has = isBullish || isBearish; if (has) { } // // Crossed Last ... isBullish = IsMASlowCrossedOverLast(i); isBearish = IsMASlowCrossedUnderLast(i); has = isBullish || isBearish; if (has) { } // // XHK ... isBullish = IsHKSwitchedToBullish(i); isBearish = IsHKSwitchedToBearish(i); has = isBullish || isBearish; if (has) { } } // result = ArraySize(pivots); // return result; } // // // /** * an strucutre to Model Specified Leg Pattern ... **/ struct XLeg { // // Props ... // datetime time; string symbol; ENUM_X_DIRECTION dir; ENUM_TIMEFRAMES period; // double upper; double lower; // XOHCL bullishBars[]; XOHCL bearishBars[]; // XBoxZone supports[]; XBoxZone resistances[]; // XBoxZone bullishFVGs[]; XBoxZone bearishFVGs[]; // XPatternAnalysis patterns[]; // int sequentialBullishBars; int sequentialBearishBars; // // Constructor ... // // Tools ... /** * Cleanup ... */ void Clean() { // time = NULL; symbol = NULL; period = NULL; dir = X_DIRECTION_NONE; // upper = 0; lower = 0; sequentialBullishBars = 0; sequentialBearishBars = 0; // XClean(patterns); XClean(supports); XClean(bullishBars); XClean(bearishBars); XClean(resistances); XClean(bullishFVGs); XClean(bearishFVGs); } /** * Validate ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = IsXValid(time) && IsXValid(symbol) && IsXValid(period) && HasDirection(dir) && NotEmptyZero(upper) && NotEmptyZero(lower) && upper > lower; // return result; } /** * Check is Bullish ... * * @return ( bool ) */ bool IsBullish() { return IsValid() && IsXBullish(dir); } /** * Check is Bearish ... * * @return ( bool ) */ bool IsBearish() { return IsValid() && IsXBearish(dir); } /** * Converts a Leg to XBoxZone ... * * @param zone: XBoxZone, reference to holds Converted ... * * @return ( bool ) */ bool ToBox(XBoxZone &zone) { // bool result = false; // // Prepare ... zone.Clean(); // // Validate ... result = IsValid(); if (!result) { return result; } // zone.at = time; zone.dir = dir; zone.from = time; zone.upper = upper; zone.lower = lower; zone.symbol = symbol; zone.period = period; zone.to = TimeCurrent(); zone.type = ToXString(X_BAR_PATTERN_LEG); // result = zone.IsValid(); // // Cleanup ... if (!result) { zone.Clean(); } // return result; } /** * Update Times of Collections ... * * @param value: datetime, Specified Time ... */ void UpdateTimes(datetime value = NULL) { // // Normalize ... value = NormalizeTime(value); // // Validate ... if (!IsValid()) { return; } // UpdateToTime(supports, value); UpdateToTime(resistances, value); UpdateToTime(bullishFVGs, value); UpdateToTime(bearishFVGs, value); } // };