/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Seriallize Library // --------------------------------------- // Name: XPOILib // Description: All models related to POIs ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2025, SaherElm IT Center" #property link "https://www.saherelm.ir" #property version "1.00" #property strict // // Imports ... #include "../Libraries/x-saherelm.common.lib.mq5" #include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5" #include "../Libraries/x-saherelm.x-poi.lib.mq5" /** * Model Specified Pivots Analysis ... **/ struct XPivotAnalysis { // // Props ... string name; // Name ... string symbol; // Symbol ... datetime time; // Time ... XPivot pivots[]; // Pivots ... ENUM_TIMEFRAMES period; // Period ... // // Linear Regression Parameters ... double peakSlope; double valeSlope; double peakIntercept; double valeIntercept; // // Analysed Results ... // // Directions ... ENUM_X_DIRECTION dir; // Trending Direction ... ENUM_X_DIRECTION peakDir; ENUM_X_DIRECTION valeDir; // // Predicted Values ... double peakTo; double valeTo; double peakFrom; double valeFrom; // // Time Analysis ... datetime toTime; datetime fromTime; // // Support and Resistances ... double minorSupport; double majorSupport; double minorResistance; double majorResistance; // // Constructor ... XPivotAnalysis() { Clean(); } // // Tools ... // // Cleaners ... /** * Cleanup Model ... */ void Clean() { // time = NULL; name = NULL; symbol = NULL; period = NULL; SpecifiedClean(pivots); // CleanAnalysis(); CleanLinearRegressionParameters(); // ZeroMemory(this); } /** * Clean Analysis Props ... */ void CleanAnalysis() { // toTime = NULL; fromTime = NULL; peakTo = EMPTY_VALUE; valeTo = EMPTY_VALUE; peakFrom = EMPTY_VALUE; valeFrom = EMPTY_VALUE; dir = X_DIRECTION_NONE; peakDir = X_DIRECTION_NONE; valeDir = X_DIRECTION_NONE; minorSupport = EMPTY_VALUE; majorSupport = EMPTY_VALUE; minorResistance = EMPTY_VALUE; majorResistance = EMPTY_VALUE; } /** * Clean Linear Regression Parameters ... */ void CleanLinearRegressionParameters() { // peakSlope = EMPTY_VALUE; valeSlope = EMPTY_VALUE; peakIntercept = EMPTY_VALUE; valeIntercept = EMPTY_VALUE; } // // Initializer / Actions (s) ... /** * Initialize Model ... * * @param _name: Name ... * @param _symbol: Symbol ... * @param _period: Period ... * @param _pivots: Provided Pivots ... * * @return ( bool ) */ bool Init( string _name, string _symbol, ENUM_TIMEFRAMES _period, XPivot &_pivots[] // ) { // bool result = false; // // Validate Args ... result = HasChild(_pivots) && IsSpecifiedValid(_name) && IsSpecifiedValid(_symbol) && IsSpecifiedValid(_period); if (!result) { // Clean(); return result; } // name = _name; symbol = _symbol; period = _period; Copy( _pivots, pivots // ); time = TimeCurrent(); // result = IsValid(); if (!result) { Clean(); } // // Do Calculations if Model is Valid ... if (result) { Update(); } // return result; } /** * Fully Update Analysis based on Pivots ... */ void Update() { // bool has = false; // // Prepare ... CleanAnalysis(); CleanLinearRegressionParameters(); // // Validate ... has = IsValid() && HasPivots(); if (!has) { return; } // // Calculate Linear Regression Parameters ... has = CalculateLinearRegressionParameters(); if (!has) { return; } // // Analyse ... has = Analyse(); if (!has) { return; } } /** * Fully Update Analysis based on Pivots ... * * @param _pivots: new Pivots Collection for Update ... */ void Update(XPivot &_pivots[]) { // bool has = IsValid() && HasChild(_pivots); if (!has) { return; } // SpecifiedClean(pivots); Copy( _pivots, pivots // ); // Update(); } /** * Re Analyse Pivots ... * * @return ( bool ) */ bool Analyse() { // bool result = false; // // Prepare ... CleanAnalysis(); // // Validate ... result = IsValid() && HasPivots() && HasLinearRegressionParameters(); if (!result) { return result; } // // Do Analyse ... // bool has = false; // // Specified To and From Time ... // // To Time ... int toIDX = GetYoungest(pivots); if (IsValidIndex(toIDX)) { // toTime = pivots[toIDX].time; toIDX = GetBarIndex( symbol, period, toTime // ); } // // From Time ... int fromIDX = GetOldest(pivots); if (IsValidIndex(fromIDX)) { // fromTime = pivots[fromIDX].time; fromIDX = GetBarIndex( symbol, period, fromTime // ); } // // Validate To From times ... result = IsValidIndex(toIDX) && IsValidIndex(fromIDX) && IsSpecifiedValid(toTime) && IsSpecifiedValid(fromTime); if (!result) { return result; } // // Predict Values ... // // Peaks ... // // Check Slope and Intercept Exists ... has = NotEmpty(peakSlope) && NotEmpty(peakIntercept); if (has) { // // To ... peakTo = PredictValue( peakSlope, peakIntercept, toIDX // ); // // From ... peakFrom = PredictValue( peakSlope, peakIntercept, fromIDX // ); } // // Vales ... // // Check Slope and Intercept Exists ... has = NotEmpty(valeSlope) && NotEmpty(valeIntercept); if (has) { // // To ... valeTo = PredictValue( valeSlope, valeIntercept, toIDX // ); // // From ... valeFrom = PredictValue( valeSlope, valeIntercept, fromIDX // ); } // // Check Directions ... // // Peak ... has = IsPeakAnalysed(); if (has) { // peakDir = peakFrom < peakTo ? X_DIRECTION_BULLISH : peakFrom > peakTo ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; } // // Vale ... has = IsValeAnalysed(); if (has) { // valeDir = valeFrom < valeTo ? X_DIRECTION_BULLISH : valeFrom > valeTo ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; } // // Check For Strong Type Trending ... has = IsPeakAnalysed() && IsValeAnalysed() && peakDir == valeDir; if (has) { dir = peakDir; } // // Calculate Support and Resistances ... // // Support ... ExtractSupport( minorSupport, majorSupport, pivots // ); // // Resistance ... ExtractResistances( minorResistance, majorResistance, pivots // ); // result = IsAnalysed(); // // Cleanup Resources ... // return result; } /** * Re Calculate Linear Regression Parameters ... * * @return ( bool ) */ bool CalculateLinearRegressionParameters() { // bool result = false; // // Prepare ... CleanLinearRegressionParameters(); // // Validate ... result = IsValid() && HasPivots(); if (!result) { return result; } // // Make a Copy of Pivots ... XPivot tmpPivots[]; Copy( pivots, tmpPivots // ); // // Sort Pivots ... Sort( tmpPivots, X_SORT_BY_DATE, X_DIRECTION_BEARISH // ); // // Do Calculations ... // double yData[]; double xData[]; bool has = false; // // Peaks ... // XPivot peaks[]; int peaksCount = ExtractPivots( peaks, tmpPivots, X_PIVOT_TYPE_PEAK // ); has = IsValidSize(peaksCount); if (has) { // // Extract X and Y axis Data ... ExtractPivotsData( xData, yData, peaks // ); // // Calculating Slope and Intercept ... has = ArraySize(xData) >= 2 && ArraySize(yData) >= 2; if (has) { // CalculateSlopeAndIntercept( peakSlope, peakIntercept, xData, yData // ); } } // // Vales ... // XPivot vales[]; int valesCount = ExtractPivots( vales, tmpPivots, X_PIVOT_TYPE_VALE // ); has = IsValidSize(valesCount); if (has) { // // Extract X and Y axis Data ... ExtractPivotsData( xData, yData, vales // ); // // Calculating Slope and Intercept ... has = ArraySize(xData) >= 2 && ArraySize(yData) >= 2; if (has) { // CalculateSlopeAndIntercept( valeSlope, valeIntercept, xData, yData // ); } } // // Validate Result ... result = IsValid() && HasLinearRegressionParameters(); // // Cleanup Resources ... SpecifiedClean(yData); SpecifiedClean(xData); SpecifiedClean(peaks); SpecifiedClean(vales); SpecifiedClean(tmpPivots); // return result; } // // Validator / Checker (s) ... /** * Validate Model ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = HasPivots() && IsSpecifiedValid(time) && IsSpecifiedValid(symbol) && IsSpecifiedValid(period); // return result; } /** * Check Model has Pivots or not ... * * @return ( bool ) */ bool HasPivots() { // bool result = false; // result = HasChild(pivots); // return result; } /** * Check Model is Analysed or not ... * * @return ( bool ) */ bool IsAnalysed() { // bool result = false; // result = IsPeakAnalysed() || IsValeAnalysed(); // return result; } /** * Check Peak Analysed or not ... * * @return ( bool ) */ bool IsPeakAnalysed() { // bool result = false; // result = IsValid() && HasLinearRegressionParameters() && ( // NotEmpty(peakTo) && NotEmpty(peakFrom) && // HasDirection(peakDir) && IsSpecifiedValid(toTime) && IsSpecifiedValid(fromTime) // ); // return result; } /** * Check Vale Analysed or not ... * * @return ( bool ) */ bool IsValeAnalysed() { // bool result = false; // result = IsValid() && HasLinearRegressionParameters() && ( // NotEmpty(valeTo) && NotEmpty(valeFrom) && // HasDirection(valeDir) && IsSpecifiedValid(toTime) && IsSpecifiedValid(fromTime) // ); // return result; } /** * Check Models Linear Regression Parameters Calculated or not ... * * @return ( bool ) */ bool HasLinearRegressionParameters() { // bool result = false; // result = (NotEmpty(peakSlope) && NotEmpty(peakIntercept)) || (NotEmpty(valeSlope) || NotEmpty(valeIntercept)); // return result; } /** * Check Analysis Has Trend or not ... * * @return ( bool ) */ bool HasTrend() { // bool result = false; // result = IsAnalysed() && HasDirection(dir); // return result; } /** * Check Analysis Has Bullish Trend or not ... * * @return ( bool ) */ bool HasBullishTrend() { // bool result = false; // result = HasTrend() && IsSpecifiedBullish(dir); // return result; } /** * Check Analysis Has Bearish Trend or not ... * * @return ( bool ) */ bool HasBearishTrend() { // bool result = false; // result = HasTrend() && IsSpecifiedBearish(dir); // return result; } /** * Check Market Has Support ... * * @return ( bool ) */ bool HasSupport() { // bool result = false; // result = IsValid() && HasPivots() && IsAnalysed() && NotEmpty(minorSupport) && NotEmpty(majorSupport); // return result; } /** * Check Market Has Resistance ... * * @return ( bool ) */ bool HasResistance() { // bool result = false; // result = IsValid() && HasPivots() && IsAnalysed() && NotEmpty(minorResistance) && NotEmpty(majorResistance); // return result; } // // Pivots ... /** * Extract all Peaks from Exists Pivots ... * * @param dest: a Collection refrence to Hold Extracted Pivots ... * * @return ( int ) */ int ExtractPeaks(XPivot &dest[]) { // int result = -1; // // Prepare ... SpecifiedClean(dest); // // Do Extraction ... result = ExtractPivots( dest, pivots, X_PIVOT_TYPE_PEAK // ); // return result; } /** * Extract all Vales from Exists Pivots ... * * @param dest: a Collection refrence to Hold Extracted Pivots ... * * @return ( int ) */ int ExtractVales(XPivot &dest[]) { // int result = -1; // // Prepare ... SpecifiedClean(dest); // // Do Extraction ... result = ExtractPivots( dest, pivots, X_PIVOT_TYPE_VALE // ); // return result; } /** * Sort Pivots ... * * @param sortBy: ENUM_X_SORT_BY, Specified Sort Param ... * @param sortDir: ENUM_X_DIRECTION, Specified Sort Direction ... */ void SortPivots( ENUM_X_SORT_BY sortBy, ENUM_X_DIRECTION sortDir // ) { // // Validate ... bool has = IsValid() && HasPivots(); if (!has) { return; } // // Apply Sorting ... Sort( pivots, sortBy, sortDir // ); } // // Boxing Tools ... /** * Generate Support Box if Has Strong Supports ... * * @param box: a refrence XBoxZone to holds Generated result ... * * @return ( bool ) */ bool HasSupportBox(XBoxZone &box) { // bool result = false; // // Prepare ... box.Clean(); // // Validate ... result = IsValid() && IsAnalysed(); if (!result) { return result; } // box.to = toTime; box.symbol = symbol; box.period = period; box.from = fromTime; // box.upper = minorSupport; box.lower = majorSupport; box.dir = X_DIRECTION_BULLISH; box.type = GetTag() + "_Support"; // result = box.IsValid(); if (!result) { box.Clean(); } // return result; } /** * Generate Resistance Box if Has Strong Resistance ... * * @param box: a refrence XBoxZone to holds Generated result ... * * @return ( bool ) */ bool HasResistanceBox(XBoxZone &box) { // bool result = false; // // Prepare ... box.Clean(); // // Validate ... result = IsValid() && IsAnalysed(); if (!result) { return result; } // box.to = toTime; box.symbol = symbol; box.period = period; box.from = fromTime; // box.upper = majorResistance; box.lower = minorResistance; box.dir = X_DIRECTION_BEARISH; box.type = GetTag() + "_Resistance"; // result = box.IsValid(); if (!result) { box.Clean(); } // return result; } // // Detecting ... /** * Check Two Model is Same or not ... * * @param item: Specified Model for Compare ... * * @return ( bool ) */ bool IsSameAs(XPivotAnalysis &item) { // bool result = false; // result = IsValid() && item.IsValid() && IsSameMarketAs(item) && name == item.name && time == item.time; // return result; } /** * Check Two Model Has Same Symbol or not ... * * @param item: Specified Model for Compare ... * * @return ( bool ) */ bool IsSameSymbolAs(XPivotAnalysis &item) { // bool result = false; // result = IsValid() && item.IsValid() && symbol == item.symbol; // return result; } /** * Check Two Model Has Same Period or not ... * * @param item: Specified Model for Compare ... * * @return ( bool ) */ bool IsSamePeriodAs(XPivotAnalysis &item) { // bool result = false; // result = IsValid() && item.IsValid() && period == item.period; // return result; } /** * Check Two Model Has Same Symbol/Period or not ... * * @param item: Specified Model for Compare ... * * @return ( bool ) */ bool IsSameMarketAs(XPivotAnalysis &item) { // bool result = false; // result = IsValid() && item.IsValid() && IsSameSymbolAs(item) && IsSamePeriodAs(item); // return result; } // // Logging ... /** * Extract Specified Token of Struct ... * * @return ( string ) */ string GetTag() { return name + GetToken(this); } /** * Represent an String Unique Identifier for Chart Objects ... * * @return ( string ) */ string GetObjectID() { // string result = ""; // if (!IsValid()) { return result; } // result = GetTag() + "_" + symbol + "_" + ToXString(period); // return result; } /** * Represent an String Unique Identifier for Upper Trend Chart Objects ... * * @return ( string ) */ string GetUpperObjectID() { // string result = ""; // if (!IsValid()) { return result; } // result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_UPPER"; // return result; } /** * Represent an String Unique Identifier for Lower Trend Chart Objects ... * * @return ( string ) */ string GetLowerObjectID() { // string result = ""; // if (!IsValid()) { return result; } // result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_LOWER"; // return result; } /** * Represent an String Unique Identifier for Support Box Chart Objects ... * * @return ( string ) */ string GetSupportBoxObjectID() { // string result = ""; // if (!IsValid()) { return result; } // result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_SUPPORT"; // return result; } /** * Represent an String Unique Identifier for Resistance BOX Chart Objects ... * * @return ( string ) */ string GetResistanceBoxObjectID() { // string result = ""; // if (!IsValid()) { return result; } // result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_RESISTANCE"; // return result; } /** * Represent as String ... * * @param spacer: string, How to Represent Spaces ... * * @return ( string ) */ string GetMessage(string spacer = NULL) { // string result = ""; // // Normalize Spacer ... if (!IsSpecifiedValid(spacer)) { spacer = " "; } // // Validate ... if (!IsValid()) { return result; } // result = "==========================" + spacer + GetTag() + ":" + spacer + "==========================" + spacer + "Symbol: " + symbol + spacer + "Period: " + ToXString(period) + spacer + (!HasTrend() ? "" : "Direction: " + ToXString(dir) + spacer) + "Time: " + ToXString(time) + spacer; // return result; } // }; /** * a Model to Describe Specified Bar Pattern's Analysis ... **/ struct XPatternAnalysis { // // Props ... XOHCL bar; // Specified Bar ... XBoxZone ob; // OrderBlock if Exists ... XBoxZone fvg; // Fair Value Gap if Exists ... datetime time; // Analysis Time ... XOHCL flagSwing; // Flag Patterns Swing Bar if Exists ... XBoxZone support; // Bar's Support if Exists ... XBoxZone resistance; // Bar's Resistance if Exists ... ENUM_X_BAR_PATTERN patterns[]; // All Bars Exists Patterns ... ENUM_X_DIRECTION patternsDir[]; // Each Exists Patterns Directions ... // // Constructor ... XPatternAnalysis() { Clean(); } // // Tools ... /** * Cleanup Model ... */ void Clean() { // ob.Clean(); bar.Clean(); fvg.Clean(); time = NULL; support.Clean(); XClean(patterns); flagSwing.Clean(); resistance.Clean(); XClean(patternsDir); // ZeroMemory(this); } /** * Validate Model ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = bar.IsValid() && IsXValid(time); // return result; } // // Pattern Actions ... /** * Count Directional Patterns ... * * @param forDir: ENUM_X_DIRECTION, Specified Direction ... * * @return ( int ) */ int Count( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // int result = 0; // // Validate ... bool has = IsValid() && HasChild(patternsDir); if (!has) { return result; } // int count = ArraySize(patternsDir); if (!HasDirection(forDir)) { // result = count; return result; } // for (int i = 0; i < count; i++) { // has = forDir == patternsDir[i]; if (has) { result++; } } // return result; } // // Detectors ... bool IsHigh() { // bool result = false; // result = HasPattern(X_BAR_PATTERN_HIGH); // return result; } bool IsLow() { // bool result = false; // result = HasPattern(X_BAR_PATTERN_LOW); // return result; } bool IsSupport() { // bool result = false; // result = HasPattern( X_BAR_PATTERN_SUPPORT // ); // return result; } bool IsResistance() { // bool result = false; // result = HasPattern(X_BAR_PATTERN_RESISTANCE); // return result; } bool IsMomentum( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_MOMENTUM, forDir // ); // return result; } bool IsEngulfed( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_ENGULFED, forDir // ); // return result; } bool IsTrueGaped( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_TRUE_GAPED, forDir // ); // return result; } bool IsPinned( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_PINNED, forDir // ); // return result; } bool IsStar( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_STAR, forDir // ); // return result; } bool IsPiercing( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_PIERCING, forDir // ); // return result; } bool IsRising( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_RISING, forDir // ); // return result; } bool IsFlag( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_FLAG, forDir // ); // return result; } bool IsSignalKey( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_SIGNALKEY, forDir // ); // return result; } bool IsOB( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_OB, forDir // ); // return result; } bool IsFVG( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = HasPattern( X_BAR_PATTERN_FVG, forDir // ); // return result; } // // Getters ... bool GetLow( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_LOW; ENUM_X_DIRECTION _patternDir = X_DIRECTION_BULLISH; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetHigh( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_HIGH; ENUM_X_DIRECTION _patternDir = X_DIRECTION_BEARISH; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetSupport( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_SUPPORT; ENUM_X_DIRECTION _patternDir = X_DIRECTION_BULLISH; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetResistance( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_RESISTANCE; ENUM_X_DIRECTION _patternDir = X_DIRECTION_BEARISH; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetOB( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_OB; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetFVG( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_FVG; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetMomentum( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_MOMENTUM; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetEngulfed( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_ENGULFED; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetPinned( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_PINNED; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetTrueGaped( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_TRUE_GAPED; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetStar( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_STAR; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetFlag( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_FLAG; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetRising( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_RISING; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetPiercing( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_PIERCING; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } bool GetSignalKey( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // ENUM_X_BAR_PATTERN _pattern = X_BAR_PATTERN_SIGNALKEY; // return GetPattern( _bar, _pivot, _zone, _pattern, _patternDir // ); } // // Common Tools ... /** * Add Specified Patterns to Model ... * * @param pattern: ENUM_X_BAR_PATTERN, Specified Pattern ... * @param patternDir: ENUM_X_DIRECTION, Specified Pattern Direction ... */ void AddPattern( ENUM_X_BAR_PATTERN pattern, ENUM_X_DIRECTION patternDir // ) { // bool has = IsXValid(pattern) && HasDirection(patternDir); if (!has) { return; } // Add( pattern, patterns // ); // Add( patternDir, patternsDir // ); } /** * Check Model Has Specified Pattern or not ... * * @param pattern: ENUM_X_BAR_PATTERN, Specified Pattern ... * @param patternDir: ENUM_X_DIRECTION, Specified Pattern Direction ... * * @return ( bool ) */ bool HasPattern( ENUM_X_BAR_PATTERN pattern, ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // bool result = false; // result = IsValid(); if (!result) { return result; } // result = Contains( pattern, patterns // ); if (!result) { return result; } // if (HasDirection(forDir)) { // int idx = FindIndex( pattern, patterns // ); result = IsValidIndex(idx) && forDir == patternsDir[idx]; } // return result; } /** * Get Specified Pattern if Exists ... * * @param _bar: XOHCL, Patterns Bar ... * @param _pivot: XPivot, Patterns Pivot ... * @param _zone: XBoxZone, Patterns Box ... * @param _pattern: ENUM_X_BAR_PATTERN, Specified Pattern ... * @param _patternDir: ENUM_X_DIRECTION, Specified Pattern Direction ... * @param _peakPriceType: ENUM_X_PRICE, Specified Peak Price Type ... * @param _valePriceType: ENUM_X_PRICE, Specified Vale Price Type ... * @param _toTime: datetime, Specified Time to Update Pivot and Zones ... * * @return ( bool ) */ bool GetPattern( XOHCL &_bar, XPivot &_pivot, XBoxZone &_zone, ENUM_X_BAR_PATTERN _pattern, ENUM_X_DIRECTION _patternDir = X_DIRECTION_NONE, ENUM_X_PRICE _peakPriceType = X_PRICE_HIGH, ENUM_X_PRICE _valePriceType = X_PRICE_LOW, datetime _toTime = NULL // ) { // bool result = false; // // Prepare ... _bar.Clean(); _zone.Clean(); _pivot.Clean(); // // Normalize ... if (!IsXValid(_peakPriceType)) { _peakPriceType = X_PRICE_HIGH; } if (!IsXValid(_valePriceType)) { _valePriceType = X_PRICE_LOW; } _toTime = NormalizeTime(_toTime); // // Validate ... result = IsValid() && HasChild(patterns) && IsXValid(_peakPriceType) && IsXValid(_valePriceType) && HasPattern(_pattern, _patternDir); if (!result) { return result; } // // Find Pattern Index ... int index = FindIndex(_pattern, patterns); result = IsValidIndex(index); if (!result) { return result; } // // Fill Common Patterns Data ... _bar = bar; result = ToPivot( _bar, _pivot, _patternDir, _pattern, _peakPriceType, _valePriceType // ); result = result && ToBox( _bar, _zone, _patternDir, _pattern, _peakPriceType, _valePriceType // ); if (result) { _zone.to = _toTime; } // // Use Custom Data if Pattern Staisfied ... if (result) { // // OB ... if (_pattern == X_BAR_PATTERN_OB) { // _bar.Clean(); _zone.Clean(); _pivot.Clean(); // // Result Preparation ... result = ob.IsValid() && ob.dir == _patternDir; if (result) { // _zone = ob; result = _zone.FromBar(_bar); if (result) { // result = ToPivot( _bar, _pivot, _patternDir, _pattern, _peakPriceType, _valePriceType // ); } } } // // FVG ... else if (_pattern == X_BAR_PATTERN_FVG) { // _bar.Clean(); _zone.Clean(); _pivot.Clean(); // // Result Preparation ... result = fvg.IsValid() && fvg.dir == _patternDir; if (result) { // _zone = fvg; result = _zone.FromBar(_bar); if (result) { // result = ToPivot( _bar, _pivot, _patternDir, _pattern, _peakPriceType, _valePriceType // ); } } } // // Support ... else if (_pattern == X_BAR_PATTERN_SUPPORT) { // _bar.Clean(); _zone.Clean(); _pivot.Clean(); // // Result Preparation ... result = support.IsValid(); if (result) { // _zone = support; result = _zone.AtBar(_bar); if (result) { // result = ToPivot( _bar, _pivot, _patternDir, _pattern, _peakPriceType, _valePriceType // ); } } } // // Resistance ... else if (_pattern == X_BAR_PATTERN_RESISTANCE) { // _bar.Clean(); _zone.Clean(); _pivot.Clean(); // // Result Preparation ... result = resistance.IsValid(); if (result) { // _zone = resistance; result = _zone.AtBar(_bar); if (result) { // result = ToPivot( _bar, _pivot, _patternDir, _pattern, _peakPriceType, _valePriceType // ); } } } } // // Cleanup Resources ... if (!result) { // _bar.Clean(); _zone.Clean(); _pivot.Clean(); } // return result; } /** * Extract All Exists Patterns Pivots ... * * @param dest: XPivot, collection reference to holds Extracted Patterns ... * @param forDir: ENUM_X_DIRECTION, Specified Direction of Extractions ... * * @return ( int ) */ int GetPatterns( XPivot &dest[], ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // int result = 0; // // Prepare ... XClean(dest); // // Validate ... bool has = IsValid() && HasChild(patterns); if (!has) { return result; } // // Do ... XOHCL iBar; XPivot iPivot; XBoxZone iZone; int count = ArraySize(patterns); for (int i = 0; i < count; i++) { // has = GetPattern(iBar, iPivot, iZone, patterns[i], forDir); if (has) { AddIfNotExists(iPivot, dest); } } // result = ArraySize(dest); // // Cleanup ... iBar.Clean(); iZone.Clean(); iPivot.Clean(); // return result; } // }; struct XPatternAnalysisConfig { // // Props ... // // PV ... int pvValidationLength; ENUM_X_PRICE peakPriceType; ENUM_X_PRICE valePriceType; // // Momentum ... int momentumBarValidationLength; double momentumBarApprovedMultiplier; // // TrueGap ... double trueGapApprovedStrength; // // Pin ... double pinBarShadowApprovedMultiplier; double pinBarRangeMultiplier; bool pinBarForceDirection; // // Flag ... int flagPatternPullbackLength; // // FVG ... bool fvgForceType; // // OB ... bool obForceTwoBar; // // Support and Resistance ... int supportAndResistanceValidationLength; int supportAndResistanceLoopbackLength; // ENUM_X_DIRECTION allowedDirs[]; ENUM_X_BAR_PATTERN allowedPatterns[]; // // Constructor ... XPatternAnalysisConfig() { Clean(); } // // Tools ... /** * Cleanup ... */ void Clean() { // // PV ... pvValidationLength = 0; peakPriceType = X_PRICE_NONE; valePriceType = X_PRICE_NONE; // // Momentum ... momentumBarValidationLength = 0; momentumBarApprovedMultiplier = 0; // // TrueGap ... trueGapApprovedStrength = 0; // // Pin ... pinBarShadowApprovedMultiplier = 0; pinBarRangeMultiplier = 0; pinBarForceDirection = false; // // Flag ... flagPatternPullbackLength = 0; // // FVG ... fvgForceType = false; // // OB ... obForceTwoBar = false; // // Support and Resistance ... supportAndResistanceValidationLength = 0; supportAndResistanceLoopbackLength = 0; // XClean(allowedDirs); XClean(allowedPatterns); // ZeroMemory(this); } /** * Default Configurations ... */ void Default() { // // PV ... pvValidationLength = 5; peakPriceType = X_PRICE_HIGH; valePriceType = X_PRICE_LOW; // // Momentum ... momentumBarValidationLength = 3; momentumBarApprovedMultiplier = 3; // // TrueGap ... trueGapApprovedStrength = 1; // // Pin ... pinBarShadowApprovedMultiplier = 3; pinBarRangeMultiplier = 4; pinBarForceDirection = false; // // Flag ... flagPatternPullbackLength = 3; // // FVG ... fvgForceType = false; // // OB ... obForceTwoBar = false; // // Support and Resistance ... supportAndResistanceValidationLength = 21; supportAndResistanceLoopbackLength = 50; } // // Permissions ... /** * Check Specified Patterns Detection is Allowed or not ... * * @param pattern: ENUM_X_BAR_PATTERN, Specified Pattern to Detect ... * @param patternDir: ENUM_X_DIRECTION, which Pattern Direction to Detect ... * * @return ( bool ) */ bool CanDetect( ENUM_X_BAR_PATTERN pattern, ENUM_X_DIRECTION patternDir = X_DIRECTION_NONE // ) { // bool result = false; // // Validate Pattern and // Check Pattern Exists ... result = IsXValid(pattern) && HasChild(allowedPatterns) && Contains(pattern, allowedPatterns); if (!result) { return result; } // // Now Check Direction ... int index = FindIndex(pattern, allowedPatterns); result = IsValidIndex(index) && HasChild(allowedDirs) && (!HasDirection(patternDir) ? !HasDirection(allowedDirs[index]) : (!HasDirection(allowedDirs[index]) || patternDir == allowedDirs[index])); // return result; } // // Collection Manipulations ... /** * Remove all Allowed Patterns and Directions ... */ void CleanPatterns() { // XClean(allowedDirs); XClean(allowedPatterns); } /** * Full Detect Patterns ... * * @param forDir: ENUM_X_DIRECTION, which Pattern Direction to Detect ... */ void FullPattern( ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // ) { // int count = GetAllBarPatters(allowedPatterns); for (int i = 0; i < count; i++) { // Add( forDir, allowedDirs // ); } } /** * Add Specified Pattern to Detecte ... * * @param pattern: ENUM_X_BAR_PATTERN, Specified Pattern to Detect ... * @param patternDir: ENUM_X_DIRECTION, which Pattern Direction to Detect ... */ void AddPattern( ENUM_X_BAR_PATTERN pattern, ENUM_X_DIRECTION patternDir = X_DIRECTION_NONE // ) { // bool has = IsXValid(pattern); if (!has) { return; } // Add( pattern, allowedPatterns // ); // Add( patternDir, allowedDirs // ); } // }; // // Anaysis Draw Config Models ... struct XPivotAnalysisDrawConfig { // // Props ... // // Drawing Flags ... bool drawSupport; bool drawResistance; // bool drawPeakTrend; bool drawValeTrend; bool rayLeftTrends; bool rayRightTrends; // bool drawPivots; // // Drawing Configs ... XPOIDrawConfig drawConfig; // // Constructor ... XPivotAnalysisDrawConfig() { Clean(); } // // Tools ... /** * This function fulfills the will of the developer */ void Clean() { // // Drawing Flags ... // drawPivots = false; drawSupport = false; drawPeakTrend = false; drawValeTrend = false; rayLeftTrends = false; rayRightTrends = false; drawResistance = false; // // Drawing Configs ... drawConfig.Clean(); // ZeroMemory(this); } /** * Default Configurations ... */ void Default() { // // Drawing Flags ... // drawPivots = false; drawSupport = true; drawPeakTrend = false; drawValeTrend = false; rayLeftTrends = true; rayRightTrends = true; drawResistance = true; // // Drawing Configs ... drawConfig.Default(); } /** * No Draw Abilioty ... */ void Off() { // drawPivots = false; drawSupport = false; drawPeakTrend = false; drawValeTrend = false; drawResistance = false; } /** * Full Draw Abilioty ... */ void Full() { // drawPivots = true; drawSupport = true; drawPeakTrend = true; drawValeTrend = true; drawResistance = true; } // }; struct XPatternAnalysisDrawConfig { // // Props ... // // Patterns ... // ENUM_X_BAR_PATTERN allowedDraws[]; // Allowed Draw Patterns ENUM_X_BAR_PATTERN allowedDrawZones[]; // Allowed Draw Pattern Zones ENUM_X_BAR_PATTERN allowedDrawPivots[]; // Allowed Draw Pattern Pivots // XPOIDrawConfig drawConfig; // // Constructor ... XPatternAnalysisDrawConfig() { Clean(); } // // Tools ... /** * Cleanup ... */ void Clean() { // // Drawing Configs ... drawConfig.Clean(); // XClean(allowedDraws); XClean(allowedDrawZones); XClean(allowedDrawPivots); } /** * Default Drawing Config ... */ void Default() { // // Drawing Configs ... drawConfig.Default(); // Full(); // // Remove Unused From Zones ... Remove(X_BAR_PATTERN_PINNED, allowedDrawZones); Remove(X_BAR_PATTERN_MOMENTUM, allowedDrawZones); Remove(X_BAR_PATTERN_ENGULFED, allowedDrawZones); Remove(X_BAR_PATTERN_TRUE_GAPED, allowedDrawZones); // // Remove Unused From Pivots ... Remove(X_BAR_PATTERN_OB, allowedDrawPivots); Remove(X_BAR_PATTERN_FVG, allowedDrawPivots); Remove(X_BAR_PATTERN_SUPPORT, allowedDrawPivots); Remove(X_BAR_PATTERN_RESISTANCE, allowedDrawPivots); } /** * No Draw Abilioty ... */ void Off() { // XClean(allowedDraws); XClean(allowedDrawZones); XClean(allowedDrawPivots); } /** * Full Draw Abilioty ... */ void Full() { // GetAllBarPatters(allowedDraws); GetAllBarPatters(allowedDrawZones); GetAllBarPatters(allowedDrawPivots); } // // Checkers ... /** * Check Can Draw Specified Pattern ... * * @param pattern: ENUM_X_BAR_PATTERN, Specified Pattern ... * * @return ( bool ) */ bool CanDraw(ENUM_X_BAR_PATTERN pattern) { // bool result = false; // result = HasChild(allowedDraws) && Contains(pattern, allowedDraws); // return result; } /** * Check Can Draw Specified Pattern's Zone ... * * @param pattern: ENUM_X_BAR_PATTERN, Specified Pattern ... * * @return ( bool ) */ bool CanDrawZone(ENUM_X_BAR_PATTERN pattern) { // bool result = false; // result = CanDraw(pattern) && HasChild(allowedDrawZones) && Contains(pattern, allowedDrawZones); // return result; } /** * Check Can Draw Specified Pattern's Pivot ... * * @param pattern: ENUM_X_BAR_PATTERN, Specified Pattern ... * * @return ( bool ) */ bool CanDrawPivot(ENUM_X_BAR_PATTERN pattern) { // bool result = false; // result = CanDraw(pattern) && HasChild(allowedDrawPivots) && Contains(pattern, allowedDrawPivots); // return result; } }; // // Extensions ... bool FindByTime( int &index, datetime time, XPatternAnalysis &source[] // ) { // bool result = false; // // Prepare ... index = -1; // // Validate ... result = IsXValid(time) && HasChild(source); if (!result) { return result; } // // Do ... int count = ArraySize(source); for (int i = 0; i < count; i++) { // result = source[i].bar.time == time; if (result) { // index = i; break; } } // result = IsValidIndex(index); // return result; } //