diff --git a/Documents/BKP/ZigZagLinearRegression/TestRegresser.mq5 b/Documents/BKP/ZigZagLinearRegression/TestRegresser.mq5 index 0a6a63a4..6b54b003 100644 --- a/Documents/BKP/ZigZagLinearRegression/TestRegresser.mq5 +++ b/Documents/BKP/ZigZagLinearRegression/TestRegresser.mq5 @@ -618,7 +618,7 @@ void ProcessZigZagsSupportsAnsResistances() tmpValue = mMajorResistance; mMajorResistance = iValue; } - else + elsetmp { // // Check Minor Resistance ... diff --git a/Libraries/x-saherelm.x-enums.lib.mq5 b/Libraries/x-saherelm.x-enums.lib.mq5 index 34803914..68dbd1f9 100644 --- a/Libraries/x-saherelm.x-enums.lib.mq5 +++ b/Libraries/x-saherelm.x-enums.lib.mq5 @@ -1275,4 +1275,91 @@ string ToString(ENUM_X_MA_METHOD value) // END Ma Methods ... // +// +// START XPivots ... +// + +// +enum ENUM_X_PIVOT_TYPE +{ + X_PIVOT_TYPE_NONE = 0, // None + X_PIVOT_TYPE_PEAK = 1, // PEAK + X_PIVOT_TYPE_VALE = 2, // VALE +}; + +/** + * Validate ... + * + * @param value: ENUM_X_PIVOT_TYPE ... + * + * @return ( bool ) + */ +bool IsXValid(ENUM_X_PIVOT_TYPE value) +{ + // + bool result = false; + + // + result = value != X_PIVOT_TYPE_NONE; + + // + return result; +} + +/** + * Check Specified Type of Pivot is Peak or not ... + * + * @param value: ENUM_X_PIVOT_TYPE, Specified Type ... + * + * @return ( bool ) + */ +bool IsXPeak(ENUM_X_PIVOT_TYPE value) +{ + // + bool result = false; + + // + result = IsXValid(value) && + value == X_PIVOT_TYPE_PEAK; + + // + return result; +} + +/** + * Check Specified Type of Pivot is Vale or not ... + * + * @param value: ENUM_X_PIVOT_TYPE, Specified Type ... + * + * @return ( bool ) + */ +bool IsXVale(ENUM_X_PIVOT_TYPE value) +{ + // + bool result = false; + + // + result = IsXValid(value) && + value == X_PIVOT_TYPE_VALE; + + // + return result; +} + +/** + * Represent Specified ZigZag Point Type as String ... + * + * @param value: ENUM_X_PIVOT_TYPE ... + * + * @return ( string ) + */ +string ToXString(ENUM_X_PIVOT_TYPE value) +{ + return EnumToString(value); +} + +// +// END XPivots ... +// + // \ No newline at end of file diff --git a/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 b/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 new file mode 100644 index 00000000..1c8ff0ae --- /dev/null +++ b/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 @@ -0,0 +1,1086 @@ +/////////////////////////////////////////////////////// +// +// 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 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; + 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 _symbol: Symbol ... + * @param _period: Period ... + * @param _pivots: Provided Pivots ... + * + * @return ( bool ) + */ + bool Init( + string _symbol, + ENUM_TIMEFRAMES _period, + XPivot &_pivots[] // + ) + { + // + bool result = false; + + // + // Validate Args ... + result = + HasChild(_pivots) && + IsSpecifiedValid(_symbol) && + IsSpecifiedValid(_period); + if (!result) + { + // + Clean(); + return result; + } + + // + 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 ... + 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 ... + 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 // + ); + } + + // + // Detecting ... + + /** + * Check Two Model is Same or not ... + * + * @param item: Specified Model for Compare ... + * + * @return ( bool ) + */ + bool IsSameAs(XPivot &item) + { + // + bool result = false; + + // + result = IsValid() && + item.IsValid() && + IsSameMarketAs(item) && + time == item.time; + + // + return result; + } + + /** + * Check Two Model Has Same Symbol or not ... + * + * @param item: Specified Model for Compare ... + * + * @return ( bool ) + */ + bool IsSameSymbolAs(XPivot &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(XPivot &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(XPivot &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 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) + "_" + ToXString(TimeToSeconds(time)); + + // + 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; + } + + // +}; + +// \ No newline at end of file diff --git a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 index 5318ee47..90944d7e 100644 --- a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 @@ -26,10 +26,13 @@ // // Extensions ... +//+------------------------------------------------------------------+ +//| Oldest Detection | +//+------------------------------------------------------------------+ /** - * Get Oldest Box Index ... + * Get Oldest Index of Specified Collection ... * - * @param source: XBoxZone instance Reference Collection ... + * @param source: Specified Collection ... * * @return ( int ) */ @@ -76,7 +79,16 @@ int GetOldest( // return result; } -int GetOldest( + +/** + * Get Oldest Index of Specified Collection ... + * + * @param bar: XOHCL, Specified Bar ... + * @param source: Specified Collection ... + * + * @return ( int ) + */ +int GetOldestByBar( XOHCL &bar, XBoxZone &source[] // ) @@ -139,9 +151,83 @@ int GetOldest( } /** - * Get Youngest Box Index ... + * Get Oldest Index of Specified Collection ... * - * @param source: XBoxZone instance Reference Collection ... + * @param source: Specified Collection ... + * @param type: ENUM_X_PIVOT_TYPE, Specified Points Type ... + * + * @return ( int ) + */ +int GetOldest( + XPivot &source[], + ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE // +) +{ + // + int result = -1; + + // + // Validate ... + if (!HasChild(source)) + { + return result; + } + + // + bool has = false; + XPivot iPoint; + int count = ArraySize(source); + for (int i = 0; i < count; i++) + { + // + // Passed Type ... + has = !IsXValid(type) + ? true + : type == source[i].type; + + // + // Check Can Assign ... + has = + has && + (!iPoint.IsValid() || + (iPoint.IsValid() && + source[i].GetAge() > iPoint.GetAge())); + if (has) + { + // + result = i; + iPoint = source[i]; + } + } + + // + // Validate Result ... + has = + iPoint.IsValid() && + IsValidIndex(result); + if (!has) + { + // + result = -1; + iPoint.Clean(); + return result; + } + + // + iPoint.Clean(); + + // + return result; +} +//+------------------------------------------------------------------+ + +//+------------------------------------------------------------------+ +//| Youngest Detection | +//+------------------------------------------------------------------+ +/** + * Get Youngest Index of Specified Collection ... + * + * @param source: Specified Collection ... * * @return ( int ) */ @@ -188,7 +274,16 @@ int GetYoungest( // return result; } -int GetYoungest( + +/** + * Get Youngest Index of Specified Collection ... + * + * @param bar: XOHCL, Specified Bar ... + * @param source: Specified Collection ... + * + * @return ( int ) + */ +int GetYoungestByBar( XOHCL &bar, XBoxZone &source[] // ) @@ -251,9 +346,83 @@ int GetYoungest( } /** - * Get Highest Box Index ... + * Get Youngest Index of Specified Collection ... * - * @param source: XBoxZone instance Reference Collection ... + * @param source: Specified Collection ... + * @param type: ENUM_X_PIVOT_TYPE, Specified Points Type ... + * + * @return ( int ) + */ +int GetYoungest( + XPivot &source[], + ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE // +) +{ + // + int result = -1; + + // + // Validate ... + if (!HasChild(source)) + { + return result; + } + + // + bool has = false; + XPivot iPoint; + int count = ArraySize(source); + for (int i = 0; i < count; i++) + { + // + // Passed Type ... + has = !IsXValid(type) + ? true + : type == source[i].type; + + // + // Check Can Assign ... + has = + has && + (!iPoint.IsValid() || + (iPoint.IsValid() && + source[i].GetAge() < iPoint.GetAge())); + if (has) + { + // + result = i; + iPoint = source[i]; + } + } + + // + // Validate Result ... + has = + iPoint.IsValid() && + IsValidIndex(result); + if (!has) + { + // + result = -1; + iPoint.Clean(); + return result; + } + + // + iPoint.Clean(); + + // + return result; +} +//+------------------------------------------------------------------+ + +//+------------------------------------------------------------------+ +//| Highest Detection | +//+------------------------------------------------------------------+ +/** + * Get Highest Index of Specified Collection ... + * + * @param source: Specified Collection ... * * @return ( int ) */ @@ -300,7 +469,16 @@ int GetHighest( // return result; } -int GetHighest( + +/** + * Get Highest Index of Specified Collection ... + * + * @param bar: XOHCL, Specified Bar ... + * @param source: Specified Collection ... + * + * @return ( int ) + */ +int GetHighestByBar( XOHCL &bar, XBoxZone &source[] // ) @@ -363,9 +541,83 @@ int GetHighest( } /** - * Get Lowest Box Index ... + * Get Highest Index of Specified Collection ... * - * @param source: XBoxZone instance Reference Collection ... + * @param source: Specified Collection ... + * @param type: ENUM_X_PIVOT_TYPE, Specified Points Type ... + * + * @return ( int ) + */ +int GetHighest( + XPivot &source[], + ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE // +) +{ + // + int result = -1; + + // + // Validate ... + if (!HasChild(source)) + { + return result; + } + + // + bool has = false; + XPivot iPoint; + int count = ArraySize(source); + for (int i = 0; i < count; i++) + { + // + // Passed Type ... + has = !IsXValid(type) + ? true + : type == source[i].type; + + // + // Check Can Assign ... + has = + has && + (!iPoint.IsValid() || + (iPoint.IsValid() && + source[i].value > iPoint.value)); + if (has) + { + // + result = i; + iPoint = source[i]; + } + } + + // + // Validate Result ... + has = + iPoint.IsValid() && + IsValidIndex(result); + if (!has) + { + // + result = -1; + iPoint.Clean(); + return result; + } + + // + iPoint.Clean(); + + // + return result; +} +//+------------------------------------------------------------------+ + +//+------------------------------------------------------------------+ +//| Loest Detection | +//+------------------------------------------------------------------+ +/** + * Get Lowest Index of Specified Collection ... + * + * @param source: Specified Collection ... * * @return ( int ) */ @@ -412,7 +664,16 @@ int GetLowest( // return result; } -int GetLowest( + +/** + * Get Lowest Index of Specified Collection ... + * + * @param bar: XOHCL, Specified Bar ... + * @param source: Specified Collection ... + * + * @return ( int ) + */ +int GetLowestByBar( XOHCL &bar, XBoxZone &source[] // ) @@ -475,60 +736,610 @@ int GetLowest( } /** - * Find Specified Box Index inside a Collection of Boxes ... + * Get Lowest Index of Specified Collection ... * - * @param box: XBoxZone instance Reference ... - * @param boxes: XBoxZone instance Reference Collection ... + * @param source: Specified Collection ... + * @param type: ENUM_X_PIVOT_TYPE, Specified Points Type ... * * @return ( int ) */ -bool FindIndex( - int &index, - XBoxZone &item, - XBoxZone &items[] // +int GetLowest( + XPivot &items[], + ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE // ) { // - bool result = false; + int result = -1; // - index = -1; - - // - int count = ArraySize(items); - result = item.IsValid() && - IsValidSize(count); - if (!result) + // Validate ... + if (!HasChild(items)) { return result; } // + bool has = false; + XPivot iPoint; + int count = ArraySize(items); for (int i = 0; i < count; i++) { // - XBoxZone iBox = items[i]; + // Passed Type ... + has = !IsXValid(type) + ? true + : type == items[i].type; // - bool isSame = item.IsSameAs(iBox); - if (isSame) + // Check Can Assign ... + has = + has && + (!iPoint.IsValid() || + (iPoint.IsValid() && + items[i].value < iPoint.value)); + if (has) { // - index = i; - break; + result = i; + iPoint = items[i]; } } // - result = IsValidIndex(index); + // Validate Result ... + has = + iPoint.IsValid() && + IsValidIndex(result); + if (!has) + { + // + result = -1; + iPoint.Clean(); + return result; + } + + // + iPoint.Clean(); // return result; } +//+------------------------------------------------------------------+ + +//+------------------------------------------------------------------+ +//| Sort | +//+------------------------------------------------------------------+ + +/** + * Allowed Sort Param ... + **/ +enum ENUM_X_SORT_BY +{ + X_SORT_BY_NONE = 0, // None + X_SORT_BY_DATE = 1, // by Date + X_SORT_BY_VALUE = 2, // by Date +}; + +/** + * Check Specified Sort By Validation ... + * + * @param value: ENUM_X_SORT_BY, value to Validate ... + * + * @return ( bool ) + */ +bool IsXValid(ENUM_X_SORT_BY value) +{ + return value != X_SORT_BY_NONE; +} + +/** + * Select Specified Index of a Collection by Sort Params ... + * + * @param source: Collection for Search ... + * @param sortBy: ENUM_X_SORT_BY, Specified Sort Param ... + * @param sortDir: ENUM_X_DIRECTION, Specified Sort Direction ... + * + * @return ( int ) + */ +template +int SelectItemForSorting( + T &source[], + ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE, + ENUM_X_DIRECTION sortDir = X_DIRECTION_BULLISH // +) +{ + // + int result = -1; + + // + // Validate ... + if (!HasChild(source) || + !IsXValid(sortBy) || + !HasDirection(sortDir)) + { + return result; + } + + // + // Sort By Date ... + if (sortBy == X_SORT_BY_DATE) + { + // + // Select Based on Sorting Direction ... + + // + // form Oldest to Youngest ... + if (sortDir == X_DIRECTION_BULLISH) + { + result = GetOldest(source); + } + // + // form Youngest to Oldest ... + else if (sortDir == X_DIRECTION_BEARISH) + { + result = GetYoungest(source); + } + // + // Not Valid ... + else + { + result = -1; + } + } + // + // Sort By Value ... + else if (sortBy == X_SORT_BY_VALUE) + { + // + // form Lowst to Highest ... + if (sortDir == X_DIRECTION_BULLISH) + { + result = GetLowest(source); + } + // + // form Highest to Lowest ... + else if (sortDir == X_DIRECTION_BEARISH) + { + result = GetHighest(source); + } + // + // Not Valid ... + else + { + result = -1; + } + } + // + // Not Valid ... + else + { + result = -1; + } + + // + return result; +} + +/** + * Apply Sort on Specified Collection ... + * + * @param source: Collection Reference to Sort ... + * @param sortBy: ENUM_X_SORT_BY, Specified Sort Param ... + * @param sortDir: ENUM_X_DIRECTION, Specified Sort Direction ... + * @param maxAllowed: int, Max Allowed Collection Size ... + */ +template +void Sort( + T &source[], + ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE, + ENUM_X_DIRECTION sortDir = X_DIRECTION_BULLISH, + int maxAllowed = 0 // +) +{ + // + int idx = -1; + bool has = false; + + // + // Validate ... + has = + IsXValid(sortBy) && + HasChild(source) && + HasDirection(sortDir); + if (!has) + { + return; + } + + // + // Copy source for Manipulating ... + T tmps[]; + Copy( + source, + tmps // + ); + + // + // Clean Source Collection for Adding Sorted Items ... + Clean(source); + + // + // Loop Through Temp Collection Has Child ... + while (HasChild(tmps)) + { + // + // Select Based on Sorting Parameter ... + idx = SelectItemForSorting( + tmps, + sortBy, + sortDir // + ); + + // + // Validate Detected Index ... + has = IsValidIndex(idx); + if (!has) + { + break; + } + + // + // Add Detected Indexed Item to Source ... + AddRef( + tmps[idx], + source // + ); + + // + // Remove Item From Temp Collection ... + ArrayRemove( + tmps, + idx, + 1 // + ); + } + + // + // Cleanup Collection if Max Items Reached ... + if (maxAllowed > 0) + { + // + CleanupArray( + source, + maxAllowed // + ); + } + + // + // Cleanup Resources ... + SpecifiedClean(tmps); +} +//+------------------------------------------------------------------+ + +//+------------------------------------------------------------------+ +//| Extraction | +//+------------------------------------------------------------------+ +/** + * Extract Specific Types of Pivots From a Collection ... + * + * @param dest: reference Collection to Hold result ... + * @param source: Collection to Find Type Specific items ... + * @param _type: Specified item Type ... + * + * @return ( int ) + */ +int ExtractPivots( + XPivot &dest[], + XPivot &source[], + ENUM_X_PIVOT_TYPE _type // +) +{ + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(dest); + + // + // Validate ... + int count = ArraySize(source); + bool has = + IsXValid(_type) && + IsValidSize(count); + if (!has) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + // Check Type Passing ... + has = _type == source[i].type; + if (!has) + { + continue; + } + + // + AddIfNotExists( + source[i], + dest // + ); + } + + // + result = ArraySize(dest); + + // + return result; +} + +/** + * Extract Pivots Data for Linear Regression Calculations ... + * + * @param xData: refrence Collection to Holds X-Axis Data ... + * @param yData: refrence Collection to Holds Y-Axis Data ... + * @param source: pivots Collection for Extraction ... + * + * @return ( int ) + */ +int ExtractPivotsData( + double &xData[], + double &yData[], + XPivot &source[] // +) +{ + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(xData); + SpecifiedClean(yData); + + // + // Validate ... + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + double iX = EMPTY_VALUE; + double iY = EMPTY_VALUE; + for (int i = 0; i < count; i++) + { + // + iX = i + 1; + iY = source[i].value; + + // + Add( + iX, + xData // + ); + + // + Add( + iY, + yData // + ); + } + + // + result = MathMin(ArraySize(xData), ArraySize(yData)); + + // + return result; +} +//+------------------------------------------------------------------+ + +//+------------------------------------------------------------------+ +//| Support and Resistance | +//+------------------------------------------------------------------+ +/** + * Extract Support Levels of Pivots Collection ... + * + * @param _minor: refrence to Holds Minor Level ... + * @param _major: refrence to Holds Major Level ... + * @param source: Collection of Pivots ... + * + * @return ( bool ) + */ +bool ExtractSupport( + double &_minor, + double &_major, + XPivot &source[] // +) +{ + // + bool result = false; + + // + // Prepare ... + _minor = EMPTY_VALUE; + _major = EMPTY_VALUE; + + // + // Validate ... + int count = ArraySize(source); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + bool has = false; + double tmp = EMPTY_VALUE; + double iValue = EMPTY_VALUE; + for (int i = 0; i < count; i++) + { + // + // Check Type ... + has = source[i].IsVale(); + if (!has) + { + continue; + } + + // + // Reading Value ... + iValue = source[i].value; + + // + // Check Can Change Major ... + has = !NotEmpty(_major) || + _major > iValue; + if (has) + { + // + tmp = _major; + _major = iValue; + } + // + // Check Can Change Minor ... + else + { + // + // Change Minor ... + has = !NotEmpty(tmp) || + tmp > iValue; + if (has) + { + tmp = iValue; + } + } + } + + // + // Last Update of Minore Minor ... + has = NotEmpty(tmp); + if (has) + { + _minor = tmp; + } + + // + result = NotEmpty(_major) || + NotEmpty(_minor); + + // + return result; +} + +/** + * Extract Resistance Levels of Pivots Collection ... + * + * @param _minor: refrence to Holds Minor Level ... + * @param _major: refrence to Holds Major Level ... + * @param source: Collection of Pivots ... + * + * @return ( bool ) + */ +bool ExtractResistances( + double &_minor, + double &_major, + XPivot &source[] // +) +{ + // + bool result = false; + + // + // Prepare ... + _minor = EMPTY_VALUE; + _major = EMPTY_VALUE; + + // + // Validate ... + int count = ArraySize(source); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + bool has = false; + double tmp = EMPTY_VALUE; + double iValue = EMPTY_VALUE; + for (int i = 0; i < count; i++) + { + // + // Check Type ... + has = source[i].IsPeak(); + if (!has) + { + continue; + } + + // + // Reading Value ... + iValue = source[i].value; + + // + // Check Can Change Major ... + has = !NotEmpty(_major) || + _major < iValue; + if (has) + { + // + tmp = _major; + _major = iValue; + } + // + // Check Can Change Minor ... + else + { + // + // Change Minor ... + has = !NotEmpty(tmp) || + tmp < iValue; + if (has) + { + tmp = iValue; + } + } + } + + // + // Last Update of Minore Minor ... + has = NotEmpty(tmp); + if (has) + { + _minor = tmp; + } + + // + result = NotEmpty(_major) || + NotEmpty(_minor); + + // + return result; +} +//+------------------------------------------------------------------+ + +//+------------------------------------------------------------------+ +//| Find Index | +//+------------------------------------------------------------------+ +/** + * Find Specified Item index in a Collection ... + * + * @param index: int, reference to Hold Index if Exists ... + * @param item: Specified item to Detect ... + * @param source: Collection to Search for item ... + * + * @return ( bool ) + */ bool FindIndex( int &index, - XDirectionShift &item, - XDirectionShift &items[] // + XBoxZone &item, + XBoxZone &source[] // ) { // @@ -538,7 +1349,7 @@ bool FindIndex( index = -1; // - int count = ArraySize(items); + int count = ArraySize(source); result = item.IsValid() && IsValidSize(count); if (!result) @@ -550,10 +1361,7 @@ bool FindIndex( for (int i = 0; i < count; i++) { // - XDirectionShift iItem = items[i]; - - // - bool isSame = item.IsSameAs(iItem); + bool isSame = item.IsSameAs(source[i]); if (isSame) { // @@ -570,11 +1378,168 @@ bool FindIndex( } /** - * Remove Specified Box from Collection ... + * Find Specified Item index in a Collection ... + * + * @param index: int, reference to Hold Index if Exists ... + * @param item: Specified item to Detect ... + * @param source: Collection to Search for item ... + * + * @return ( bool ) + */ +bool FindIndex( + int &index, + XPivot &item, + XPivot &source[] // +) +{ + // + bool result = false; + + // + index = -1; + + // + int count = ArraySize(source); + result = item.IsValid() && + IsValidSize(count); + if (!result) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + bool isSame = item.IsSameAs(source[i]); + if (isSame) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; +} + +/** + * Find Specified Item index in a Collection ... + * + * @param index: int, reference to Hold Index if Exists ... + * @param item: Specified item to Detect ... + * @param source: Collection to Search for item ... + * + * @return ( bool ) + */ +bool FindIndex( + int &index, + XDirectionShift &item, + XDirectionShift &source[] // +) +{ + // + bool result = false; + + // + index = -1; + + // + int count = ArraySize(source); + result = item.IsValid() && + IsValidSize(count); + if (!result) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + bool isSame = item.IsSameAs(source[i]); + if (isSame) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; +} +//+------------------------------------------------------------------+ + +//+------------------------------------------------------------------+ +//| Remove | +//+------------------------------------------------------------------+ +/** + * Remove Specified Item from a Collection ... + * + * @param item: Specified Item ... + * @param source: Specified Collection for Remove item from it ... + * + * @return ( bool ) + */ +bool Remove( + XPivot &item, + XPivot &source[] // +) +{ + // + bool result = false; + + // + result = + item.IsValid() && + HasChild(source); + if (!result) + { + return result; + } + + // + int idx = -1; + result = FindIndex( + idx, + item, + source // + ); + if (!result) + { + return result; + } + + // + result = ArrayRemove( + source, + idx, + 1 // + ); + + // + return result; +} + +/** + * Remove Specified Item from a Collection ... + * + * @param item: Specified Item ... + * @param source: Specified Collection for Remove item from it ... + * + * @return ( bool ) */ bool Remove( XBoxZone &item, - XBoxZone &items[] // + XBoxZone &source[] // ) { // @@ -583,7 +1548,7 @@ bool Remove( // result = item.IsValid() && - HasChild(items); + HasChild(source); if (!result) { return result; @@ -594,7 +1559,7 @@ bool Remove( result = FindIndex( idx, item, - items // + source // ); if (!result) { @@ -603,46 +1568,7 @@ bool Remove( // result = ArrayRemove( - items, - idx, - 1 // - ); - - // - return result; -} -bool Remove( - XDirectionShift &item, - XDirectionShift &items[] // -) -{ - // - bool result = false; - - // - result = - item.IsValid() && - HasChild(items); - if (!result) - { - return result; - } - - // - int idx = -1; - result = FindIndex( - idx, - item, - items // - ); - if (!result) - { - return result; - } - - // - result = ArrayRemove( - items, + source, idx, 1 // ); @@ -652,7 +1578,60 @@ bool Remove( } /** - * Remove Specified Box from Collection ... + * Remove Specified Item from a Collection ... + * + * @param item: Specified Item ... + * @param source: Specified Collection for Remove item from it ... + * + * @return ( bool ) + */ +bool Remove( + XDirectionShift &item, + XDirectionShift &source[] // +) +{ + // + bool result = false; + + // + result = + item.IsValid() && + HasChild(source); + if (!result) + { + return result; + } + + // + int idx = -1; + result = FindIndex( + idx, + item, + source // + ); + if (!result) + { + return result; + } + + // + result = ArrayRemove( + source, + idx, + 1 // + ); + + // + return result; +} + +/** + * Remove Specified items from a Collection ... + * + * @param items: Specified Items to Remove ... + * @param sources: Sepcified Collection for Removing items from it ... + * + * @return ( int ) */ int Removes( XBoxZone &items[], @@ -671,11 +1650,13 @@ int Removes( } // + int idx = -1; + has = false; int count = ArraySize(items); for (int i = 0; i < count; i++) { // - int idx = -1; + // Detect Item Index in Collection ... has = FindIndex( idx, items[i], @@ -684,6 +1665,7 @@ int Removes( if (has) { // + // Remove Detected Index from Collection ... has = ArrayRemove( sources, idx, @@ -693,6 +1675,8 @@ int Removes( // if (has) { + // + // Count Removed Items ... result++; } } @@ -701,6 +1685,76 @@ int Removes( // return result; } + +/** + * Remove Specified items from a Collection ... + * + * @param items: Specified Items to Remove ... + * @param sources: Sepcified Collection for Removing items from it ... + * + * @return ( int ) + */ +int Removes( + XPivot &items[], + XPivot &sources[] // +) +{ + // + int result = 0; + + // + bool has = HasChild(items) && + HasChild(sources); + if (!has) + { + return result; + } + + // + int idx = -1; + has = false; + int count = ArraySize(items); + for (int i = 0; i < count; i++) + { + // + // Detect Item Index in Collection ... + has = FindIndex( + idx, + items[i], + sources // + ); + if (has) + { + // + // Remove Detected Index from Collection ... + has = ArrayRemove( + sources, + idx, + 1 // + ); + + // + if (has) + { + // + // Count Removed Items ... + result++; + } + } + } + + // + return result; +} + +/** + * Remove Specified items from a Collection ... + * + * @param items: Specified Items to Remove ... + * @param sources: Sepcified Collection for Removing items from it ... + * + * @return ( int ) + */ int Removes( XDirectionShift &items[], XDirectionShift &sources[] // @@ -718,11 +1772,13 @@ int Removes( } // + int idx = -1; + has = false; int count = ArraySize(items); for (int i = 0; i < count; i++) { // - int idx = -1; + // Detect Item Index in Collection ... has = FindIndex( idx, items[i], @@ -731,6 +1787,7 @@ int Removes( if (has) { // + // Remove Detected Index from Collection ... has = ArrayRemove( sources, idx, @@ -740,6 +1797,8 @@ int Removes( // if (has) { + // + // Count Removed Items ... result++; } } @@ -748,12 +1807,16 @@ int Removes( // return result; } +//+------------------------------------------------------------------+ +//+------------------------------------------------------------------+ +//| Add If Not Exists | +//+------------------------------------------------------------------+ /** - * Add items reference into source Collection only if it's not Exists ...alignas + * Add Specified Item to Specified Collection, if not Exists ... * - * @param item: XBoxZone instance Reference, Specified Item to Add ... - * @param sources: XBoxZone instance Reference Collection, Source Items Collection ... + * @param item: Item to Add ... + * @param sources: Collection to Add item ... * @param maxAllowed: int, Max Allowed Collection Size ... * * @return ( bool ) @@ -761,7 +1824,7 @@ int Removes( bool AddIfNotExists( XBoxZone &item, XBoxZone &sources[], - int maxAllowed = 50 // + int maxAllowed = 0 // ) { // @@ -791,62 +1854,13 @@ bool AddIfNotExists( // AddRef( - item, - sources //; - ); - - // - if (result && - maxAllowed > 0) - { - // - CleanupArray( - sources, - maxAllowed // - ); - } - - // - return result; -} -bool AddIfNotExists( - XDirectionShift &item, - XDirectionShift &sources[], - int maxAllowed = 50 // -) -{ - // - bool result = false; - - // - // Validate Args ... - result = item.IsValid(); - if (!result) - { - return result; - } - - // - // Check Item Exists or not ... - int idx = -1; - bool isExists = FindIndex( - idx, item, sources // ); - result = !isExists; - if (!result) - { - return result; - } - - // - AddRef( - item, - sources //; - ); // + // Handle Cleanup Collection + // if Max Reached ... if (result && maxAllowed > 0) { @@ -862,49 +1876,54 @@ bool AddIfNotExists( } /** - * Add items Collection reference Members into source Collection only if it's not Exists ...alignas + * Add Specified Item to Specified Collection, if not Exists ... * - * @param items: XBoxZone instance Reference Collection, Specified Items to Add ... - * @param sources: XBoxZone instance Reference Collection, Source Items Collection ... + * @param item: Item to Add ... + * @param sources: Collection to Add item ... * @param maxAllowed: int, Max Allowed Collection Size ... * - * @return ( int ) + * @return ( bool ) */ -int AddIfNotExists( - XBoxZone &items[], - XBoxZone &sources[], - int maxAllowed = 50 // +bool AddIfNotExists( + XPivot &item, + XPivot &sources[], + int maxAllowed = 0 // ) { // - int result = 0; + bool result = false; // - bool has = HasChild(items); - if (!has) + // Validate Args ... + result = item.IsValid(); + if (!result) { return result; } // - int before = ArraySize(sources); - - // - int count = ArraySize(items); - for (int i = 0; i < count; i++) + // Check Item Exists or not ... + int idx = -1; + bool isExists = FindIndex( + idx, + item, + sources // + ); + result = !isExists; + if (!result) { - // - has = AddIfNotExists( - items[i], - sources // - ); + return result; } // - int after = ArraySize(sources); + AddRef( + item, + sources // + ); // - result = after > before; + // Handle Cleanup Collection + // if Max Reached ... if (result && maxAllowed > 0) { @@ -918,41 +1937,56 @@ int AddIfNotExists( // return result; } -int AddIfNotExists( - XDirectionShift &items[], + +/** + * Add Specified Item to Specified Collection, if not Exists ... + * + * @param item: Item to Add ... + * @param sources: Collection to Add item ... + * @param maxAllowed: int, Max Allowed Collection Size ... + * + * @return ( bool ) + */ +bool AddIfNotExists( + XDirectionShift &item, XDirectionShift &sources[], - int maxAllowed = 50 // + int maxAllowed = 0 // ) { // - int result = 0; + bool result = false; // - bool has = HasChild(items); - if (!has) + // Validate Args ... + result = item.IsValid(); + if (!result) { return result; } // - int before = ArraySize(sources); - - // - int count = ArraySize(items); - for (int i = 0; i < count; i++) + // Check Item Exists or not ... + int idx = -1; + bool isExists = FindIndex( + idx, + item, + sources // + ); + result = !isExists; + if (!result) { - // - has = AddIfNotExists( - items[i], - sources // - ); + return result; } // - int after = ArraySize(sources); + AddRef( + item, + sources // + ); // - result = after > before; + // Handle Cleanup Collection + // if Max Reached ... if (result && maxAllowed > 0) { @@ -966,11 +2000,16 @@ int AddIfNotExists( // return result; } +//+------------------------------------------------------------------+ // // // +//+------------------------------------------------------------------+ +//| Other Extensions | +//+------------------------------------------------------------------+ + /** * Validate Boxes ... * @param box: XBoxZone instance reference for Validate ... @@ -1359,5 +2398,6 @@ bool ToResistanceBox( // return result; } +//+------------------------------------------------------------------+ // \ No newline at end of file diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 77140d21..3bd30193 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -14,7 +14,7 @@ // // Global Properties ... #property library -#property copyright "Copyright `023, SaherElm IT Center" +#property copyright "Copyright 2023, SaherElm IT Center" #property link "https://www.saherelm.ir" #property version "1.00" #property strict @@ -22,12 +22,536 @@ // // Imports ... #include "../Classes/x-saherelm.base.class.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" #include // // Definitions ... -// +/** + * Represent a Pivot ... + **/ +struct XPivot +{ + // + // Props ... + double value; // Value + datetime time; // Time + string symbol; // Symbol + ENUM_X_DIRECTION dir; // Direction + ENUM_TIMEFRAMES period; // Period + ENUM_X_PIVOT_TYPE type; // Type + + // + // Constructor ... + XPivot() + { + Clean(); + } + + // + // Init ... + + /** + * Initialize Structure ... + * + * @param _value: double, value of point ... + * @param _time: datetime, time of point ... + * @param _symbol: string, Symbol ... + * @param _dir: ENUM_X_DIRECTION, direction of point ... + * @param _period: ENUM_TIMEFRAMES, period ... + * @param _type: ENUM_X_PIVOT_TYPE, point type ... + * + * @return ( bool ) + */ + bool Init( + double _value, + datetime _time, + string _symbol, + ENUM_X_DIRECTION _dir, + ENUM_TIMEFRAMES _period, + ENUM_X_PIVOT_TYPE _type // + ) + { + // + bool result = false; + + // + dir = _dir; + time = _time; + type = _type; + value = _value; + symbol = _symbol; + period = _period; + + // + result = IsValid(); + if (!result) + { + Clean(); + } + + // + return result; + } + + // + // Tools ... + + /** + * Cleanup Model ... + */ + void Clean() + { + // + value = 0; + time = NULL; + symbol = NULL; + period = NULL; + dir = X_DIRECTION_NONE; + type = X_PIVOT_TYPE_NONE; + + // + ZeroMemory(this); + } + + /** + * Validate Model ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + value > 0 && + IsXValid(type) && + HasDirection(dir) && + IsSpecifiedValid(time) && + IsSpecifiedValid(symbol) && + IsSpecifiedValid(period); + + // + return result; + } + + /** + * Check Model is Peak or not ... + * + * @return ( bool ) + */ + bool IsPeak() + { + // + bool result = false; + + // + result = + IsValid() && + IsXPeak(type); + + // + return result; + } + + /** + * Check Model is Vale or not ... + * + * @return ( bool ) + */ + bool IsVale() + { + // + bool result = false; + + // + result = + IsValid() && + IsXVale(type); + + // + return result; + } + + /** + * Check Point is Bullish or not ... + * + * @return ( bool ) + */ + bool IsBullish() + { + // + bool result = false; + + // + result = IsValid() && + IsSpecifiedBullish(dir); + + // + return result; + } + + /** + * Check Point is Bearish or not ... + * + * @return ( bool ) + */ + bool IsBearish() + { + // + bool result = false; + + // + result = IsValid() && + IsSpecifiedBearish(dir); + + // + return result; + } + + /** + * Check two Struct are Same or not ... + * + * @param item: XPivot ... + * + * @return ( bool ) + */ + bool IsSameAs(XPivot &item) + { + // + bool result = false; + + // + result = + IsValid() && + item.IsValid() && + dir == item.dir && + type == item.type && + time == item.time && + value == item.value && + symbol == item.symbol && + period == item.period; + + // + return result; + } + + /** + * Check Structure Exists in Specified Collection or not ... + * + * @param items: XPivot, reference Array ... + * @param index: int, reference to Holds Founded Index ... + * + * @return ( bool ) + */ + bool IsExists( + XPivot &items[], + int &index // + ) + { + // + bool result = false; + + // + // Prepare ... + index = -1; + + // + // Validate ... + result = + IsValid() && + HasChild(items); + if (!result) + { + return result; + } + + // + int count = ArraySize(items); + for (int i = 0; i < count; i++) + { + // + result = IsSameAs(items[i]); + if (result) + { + // + index = i; + + // + break; + } + } + + // + result = + result && + IsValidIndex(index); + + // + return result; + } + + /** + * Add Structure to Specified Collection only if not Exists ... + * + * @param items: XPivot, reference Array ... + */ + void AddIfNotExists(XPivot &items[]) + { + // + // Validate ... + if (!IsValid()) + { + return; + } + + // + if (!HasChild(items)) + { + // + AddRef( + this, + items // + ); + + // + return; + } + + // + int index = -1; + bool isExists = IsExists(items, index); + if (!isExists) + { + // + AddRef( + this, + items // + ); + } + } + + /** + * Calculate Pivot Age ... + * + * @return ( int ) + */ + int GetAge() + { + // + int result = -1; + + // + if (!IsValid()) + { + return result; + } + + // + result = GetBarIndex( + symbol, + period, + time // + ); + + // + return result; + } + + /** + * Check to model Has Same Symbol ... + * + * @param item: XPivot, dest model for Checking ... + * + * @return ( bool ) + */ + bool IsSameSymbolAs(XPivot &item) + { + // + bool result = false; + + // + result = + IsValid() && + item.IsValid() && + symbol == item.symbol; + + // + return result; + } + + /** + * Check to model Has Same Period ... + * + * @param item: XPivot, dest model for Checking ... + * + * @return ( bool ) + */ + bool IsSamePeriodAs(XPivot &item) + { + // + bool result = false; + + // + result = + IsValid() && + item.IsValid() && + period == item.period; + + // + return result; + } + + /** + * Check to model Has Same Symbol/Period ... + * + * @param item: XPivot, dest model for Checking ... + * + * @return ( bool ) + */ + bool IsSameMarketAs(XPivot &item) + { + // + bool result = false; + + // + result = + IsValid() && + item.IsValid() && + IsSameSymbolAs(item) && + IsSamePeriodAs(item); + + // + return result; + } + + /** + * Check to model Has Same Type ... + * + * @param item: XPivot, dest model for Checking ... + * + * @return ( bool ) + */ + bool IsSameTypeAs(XPivot &item) + { + // + bool result = false; + + // + result = + IsValid() && + item.IsValid() && + type == item.type; + + // + return result; + } + + /** + * Check to model Has Same Direction ... + * + * @param item: XPivot, dest model for Checking ... + * + * @return ( bool ) + */ + bool IsSameDirectionAs(XPivot &item) + { + // + bool result = false; + + // + result = + IsValid() && + item.IsValid() && + dir == item.dir; + + // + return result; + } + + // + // Logging Tools ... + + /** + * Extract Specified Token of Struct ... + * + * @return ( string ) + */ + string GetTag() + { + return 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) + "_" + ToXString(dir) + "_" + ToXString(type) + "_" + ToXString(TimeToSeconds(time)); + + // + return result; + } + + /** + * Represent a Point 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 = + ToXString(dir) + spacer + GetTag() + ":" + spacer + + "Symbol: " + symbol + spacer + + "Period: " + ToXString(period) + spacer + + "Type: " + ToXString(type) + spacer + + "Direction: " + ToXString(dir) + spacer + + "Value: " + ToXString(value) + spacer + + "Time: " + ToXString(time) + spacer; + + // + return result; + } +}; + +/** + * Model a Box ... + **/ struct XBoxZone { // @@ -564,7 +1088,9 @@ struct XBoxZone } }; -// +/** + * Model a Direction Shift ... + **/ struct XDirectionShift { // diff --git a/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 b/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 index 87c6ba2d..280f1b00 100644 --- a/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 +++ b/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 @@ -32,535 +32,15 @@ // Enumerations ... // -// ZigZag Point Type ... -enum ENUM_X_ZIGZAG_POINT_TYPE -{ - X_ZIGZAG_PIVOT_TYPE_NONE = 0, // None - X_ZIGZAG_PIVOT_TYPE_PEAK = 1, // PEAK - X_ZIGZAG_PIVOT_TYPE_VALE = 2, // VALE -}; - -/** - * Validate ... - * - * @param value: ENUM_X_ZIGZAG_POINT_TYPE ... - * - * @return ( bool ) - */ -bool IsXValid(ENUM_X_ZIGZAG_POINT_TYPE value) -{ - // - bool result = false; - - // - result = value != X_ZIGZAG_PIVOT_TYPE_NONE; - - // - return result; -} - -/** - * Represent Specified ZigZag Point Type as String ... - * - * @param value: ENUM_X_ZIGZAG_POINT_TYPE ... - * - * @return ( string ) - */ -string ToXString(ENUM_X_ZIGZAG_POINT_TYPE value) -{ - return EnumToString(value); -} +// Point Type ... // // Structs ... -/** - * Specified ZigZag Point ... - **/ -struct XZigZagPivot -{ - // - // Props ... - double value; // Value - datetime time; // Time - string symbol; // Symbol - ENUM_X_DIRECTION dir; // Direction - ENUM_TIMEFRAMES period; // Period - ENUM_X_ZIGZAG_POINT_TYPE type; // Type - - // - // Constructor ... - XZigZagPivot() - { - Clean(); - } - - // - // Init ... - - /** - * Initialize Structure ... - * - * @param _value: double, value of point ... - * @param _time: datetime, time of point ... - * @param _symbol: string, Symbol ... - * @param _dir: ENUM_X_DIRECTION, direction of point ... - * @param _period: ENUM_TIMEFRAMES, period ... - * @param _type: ENUM_X_ZIGZAG_POINT_TYPE, point type ... - * - * @return ( bool ) - */ - bool Init( - double _value, - datetime _time, - string _symbol, - ENUM_X_DIRECTION _dir, - ENUM_TIMEFRAMES _period, - ENUM_X_ZIGZAG_POINT_TYPE _type // - ) - { - // - bool result = false; - - // - dir = _dir; - time = _time; - type = _type; - value = _value; - symbol = _symbol; - period = _period; - - // - result = IsValid(); - if (!result) - { - Clean(); - } - - // - return result; - } - - // - // Tools ... - - /** - * Cleanup Model ... - */ - void Clean() - { - // - value = 0; - time = NULL; - symbol = NULL; - period = NULL; - dir = X_DIRECTION_NONE; - type = X_ZIGZAG_PIVOT_TYPE_NONE; - - // - ZeroMemory(this); - } - - /** - * Validate Model ... - * - * @return ( bool ) - */ - bool IsValid() - { - // - bool result = false; - - // - result = - value > 0 && - IsXValid(type) && - HasDirection(dir) && - IsSpecifiedValid(time) && - IsSpecifiedValid(symbol) && - IsSpecifiedValid(period); - - // - return result; - } - - /** - * Check Point is Bullish or not ... - * - * @return ( bool ) - */ - bool IsBullish() - { - // - bool result = false; - - // - result = IsValid() && - IsSpecifiedBullish(dir); - - // - return result; - } - - /** - * Check Point is Bearish or not ... - * - * @return ( bool ) - */ - bool IsBearish() - { - // - bool result = false; - - // - result = IsValid() && - IsSpecifiedBearish(dir); - - // - return result; - } - - /** - * Check two Struct are Same or not ... - * - * @param item: XZigZagPivot ... - * - * @return ( bool ) - */ - bool IsSameAs(XZigZagPivot &item) - { - // - bool result = false; - - // - result = - IsValid() && - item.IsValid() && - dir == item.dir && - type == item.type && - time == item.time && - value == item.value && - symbol == item.symbol && - period == item.period; - - // - return result; - } - - /** - * Check Structure Exists in Specified Collection or not ... - * - * @param items: XZigZagPivot, reference Array ... - * @param index: int, reference to Holds Founded Index ... - * - * @return ( bool ) - */ - bool IsExists( - XZigZagPivot &items[], - int &index // - ) - { - // - bool result = false; - - // - // Prepare ... - index = -1; - - // - // Validate ... - result = - IsValid() && - HasChild(items); - if (!result) - { - return result; - } - - // - int count = ArraySize(items); - for (int i = 0; i < count; i++) - { - // - result = IsSameAs(items[i]); - if (result) - { - // - index = i; - - // - break; - } - } - - // - result = - result && - IsValidIndex(index); - - // - return result; - } - - /** - * Add Structure to Specified Collection only if not Exists ... - * - * @param items: XZigZagPivot, reference Array ... - */ - void AddIfNotExists(XZigZagPivot &items[]) - { - // - // Validate ... - if (!IsValid()) - { - return; - } - - // - if (!HasChild(items)) - { - // - AddRef( - this, - items // - ); - - // - return; - } - - // - int index = -1; - bool isExists = IsExists(items, index); - if (!isExists) - { - // - AddRef( - this, - items // - ); - } - } - - /** - * Calculate Pivot Age ... - * - * @return ( int ) - */ - int GetAge() - { - // - int result = -1; - - // - if (!IsValid()) - { - return result; - } - - // - result = GetBarIndex( - symbol, - period, - time // - ); - - // - return result; - } - - /** - * Check to model Has Same Symbol ... - * - * @param item: XZigZagXZigZagPivotAXZigZagPivotnalysis, dest model for Checking ... - * - * @return ( bool ) - */ - bool IsSameSymbolAs(XZigZagPivot &item) - { - // - bool result = false; - - // - result = - IsValid() && - item.IsValid() && - symbol == item.symbol; - - // - return result; - } - - /** - * Check to model Has Same Period ... - * - * @param item: XZigZagPivot, dest model for Checking ... - * - * @return ( bool ) - */ - bool IsSamePeriodAs(XZigZagPivot &item) - { - // - bool result = false; - - // - result = - IsValid() && - item.IsValid() && - period == item.period; - - // - return result; - } - - /** - * Check to model Has Same Symbol/Period ... - * - * @param item: XZigZagPivot, dest model for Checking ... - * - * @return ( bool ) - */ - bool IsSameMarketAs(XZigZagPivot &item) - { - // - bool result = false; - - // - result = - IsValid() && - item.IsValid() && - IsSameSymbolAs(item) && - IsSamePeriodAs(item); - - // - return result; - } - - /** - * Check to model Has Same Type ... - * - * @param item: XZigZagPivot, dest model for Checking ... - * - * @return ( bool ) - */ - bool IsSameTypeAs(XZigZagPivot &item) - { - // - bool result = false; - - // - result = - IsValid() && - item.IsValid() && - type == item.type; - - // - return result; - } - - /** - * Check to model Has Same Direction ... - * - * @param item: XZigZagPivot, dest model for Checking ... - * - * @return ( bool ) - */ - bool IsSameDirectionAs(XZigZagPivot &item) - { - // - bool result = false; - - // - result = - IsValid() && - item.IsValid() && - dir == item.dir; - - // - return result; - } - - // - // Logging Tools ... - - /** - * Extract Specified Token of Struct ... - * - * @return ( string ) - */ - string GetTag() - { - return 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) + "_" + ToXString(dir) + "_" + ToXString(type) + "_" + ToXString(TimeToSeconds(time)); - - // - return result; - } - - /** - * Represent a Point 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 = - ToXString(dir) + spacer + GetTag() + ":" + spacer + - "Symbol: " + symbol + spacer + - "Period: " + ToXString(period) + spacer + - "Type: " + ToXString(type) + spacer + - "Direction: " + ToXString(dir) + spacer + - "Value: " + ToXString(value) + spacer + - "Time: " + ToXString(time) + spacer; - - // - return result; - } -}; - /** * Specified ZigZag based Market Analysis ... **/ -struct XZigZagAnalysis +struct XFIMAAnalysis { // // Props ... @@ -633,9 +113,9 @@ struct XZigZagAnalysis Copy(_pivots, pivots); // - int oldestPeakIdx = GetOldest(pivots, X_ZIGZAG_PIVOT_TYPE_PEAK); + int oldestPeakIdx = GetOldest(pivots, X_PIVOT_TYPE_PEAK); int oldestValeIdx = GetOldest(pivots, X_ZIGZAG_PIVOT_TYPE_VALE); - int youngestPeakIdx = GetYoungest(pivots, X_ZIGZAG_PIVOT_TYPE_PEAK); + int youngestPeakIdx = GetYoungest(pivots, X_PIVOT_TYPE_PEAK); int youngestValeIdx = GetYoungest(pivots, X_ZIGZAG_PIVOT_TYPE_VALE); // @@ -674,7 +154,7 @@ struct XZigZagAnalysis peakSlope, peakIntercept, pivots, - X_ZIGZAG_PIVOT_TYPE_PEAK // + X_PIVOT_TYPE_PEAK // ); if (!result) { @@ -1127,12 +607,12 @@ struct XZigZagAnalysis /** * Get Highest Specified Pivot ... * - * @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Pivot Type ... + * @param type: ENUM_X_PIVOT_TYPE, Specified Pivot Type ... * * @return ( int ) */ int GetHighestPivot( - ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // + ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE // ) { // @@ -1187,12 +667,12 @@ struct XZigZagAnalysis /** * Get Lowest Specified Pivot ... * - * @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Pivot Type ... + * @param type: ENUM_X_PIVOT_TYPE, Specified Pivot Type ... * * @return ( int ) */ int GetLowestPivot( - ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // + ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE // ) { // @@ -1247,12 +727,12 @@ struct XZigZagAnalysis /** * Get Oldest Specified Pivot ... * - * @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Pivot Type ... + * @param type: ENUM_X_PIVOT_TYPE, Specified Pivot Type ... * * @return ( int ) */ int GetOldestPivot( - ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // + ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE // ) { // @@ -1307,12 +787,12 @@ struct XZigZagAnalysis /** * Get Youngest Specified Pivot ... * - * @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Pivot Type ... + * @param type: ENUM_X_PIVOT_TYPE, Specified Pivot Type ... * * @return ( int ) */ int GetYoungestPivot( - ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // + ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE // ) { // @@ -1370,14 +850,14 @@ struct XZigZagAnalysis * * @param recent: XZigZagPivot, Collection reference as result ... * @param numberOfRequiredPivots: int, required number of Pivots ... - * @param type: ENUM_X_ZIGZAG_POINT_TYPE, type of Pivot ... + * @param type: ENUM_X_PIVOT_TYPE, type of Pivot ... * * @return ( int ) */ int GetRecentPivots( XZigZagPivot &recent[], int numberOfRequiredPivots = 2, - ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // + ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE // ) { // @@ -1527,7 +1007,7 @@ class XCZigZagAnalysisObject : public XCBaseObject int count = model.GetRecentPivots( rPeaks, numberOfPivots, - X_ZIGZAG_PIVOT_TYPE_PEAK // + X_PIVOT_TYPE_PEAK // ); // @@ -1814,407 +1294,13 @@ class XCZigZagAnalysisObject : public XCBaseObject // // Extensions ... -/** - * Get Highest ZigZagPoint Index in Specified Collection ... - * - * @param items: XZigZagPivot, Specified Points Collection to Search ... - * @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Points Type ... - * - * @return ( int ) - */ -int GetHighest( - XZigZagPivot &items[], - ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // -) -{ - // - int result = -1; - // - // Validate ... - if (!HasChild(items)) - { - return result; - } - - // - bool has = false; - XZigZagPivot iPoint; - int count = ArraySize(items); - for (int i = 0; i < count; i++) - { - // - // Passed Type ... - has = !IsXValid(type) - ? true - : type == items[i].type; - - // - // Check Can Assign ... - has = - has && - (!iPoint.IsValid() || - (iPoint.IsValid() && - items[i].value > iPoint.value)); - if (has) - { - // - result = i; - iPoint = items[i]; - } - } - - // - // Validate Result ... - has = - iPoint.IsValid() && - IsValidIndex(result); - if (!has) - { - // - result = -1; - iPoint.Clean(); - return result; - } - - // - iPoint.Clean(); - - // - return result; -} - -/** - * Get Lowest ZigZagPoint Index in Specified Collection ... - * - * @param items: XZigZagPivot, Specified Points Collection to Search ... - * @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Points Type ... - * - * @return ( int ) - */ -int GetLowest( - XZigZagPivot &items[], - ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // -) -{ - // - int result = -1; - - // - // Validate ... - if (!HasChild(items)) - { - return result; - } - - // - bool has = false; - XZigZagPivot iPoint; - int count = ArraySize(items); - for (int i = 0; i < count; i++) - { - // - // Passed Type ... - has = !IsXValid(type) - ? true - : type == items[i].type; - - // - // Check Can Assign ... - has = - has && - (!iPoint.IsValid() || - (iPoint.IsValid() && - items[i].value < iPoint.value)); - if (has) - { - // - result = i; - iPoint = items[i]; - } - } - - // - // Validate Result ... - has = - iPoint.IsValid() && - IsValidIndex(result); - if (!has) - { - // - result = -1; - iPoint.Clean(); - return result; - } - - // - iPoint.Clean(); - - // - return result; -} - -/** - * Get Oldest ZigZagPoint Index in Specified Collection ... - * - * @param items: XZigZagPivot, Specified Points Collection to Search ... - * @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Points Type ... - * - * @return ( int ) - */ -int GetOldest( - XZigZagPivot &items[], - ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // -) -{ - // - int result = -1; - - // - // Validate ... - if (!HasChild(items)) - { - return result; - } - - // - bool has = false; - XZigZagPivot iPoint; - int count = ArraySize(items); - for (int i = 0; i < count; i++) - { - // - // Passed Type ... - has = !IsXValid(type) - ? true - : type == items[i].type; - - // - // Check Can Assign ... - has = - has && - (!iPoint.IsValid() || - (iPoint.IsValid() && - items[i].GetAge() > iPoint.GetAge())); - if (has) - { - // - result = i; - iPoint = items[i]; - } - } - - // - // Validate Result ... - has = - iPoint.IsValid() && - IsValidIndex(result); - if (!has) - { - // - result = -1; - iPoint.Clean(); - return result; - } - - // - iPoint.Clean(); - - // - return result; -} - -/** - * Get Youngest ZigZagPoint Index in Specified Collection ... - * - * @param items: XZigZagPivot, Specified Points Collection to Search ... - * @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Points Type ... - * - * @return ( int ) - */ -int GetYoungest( - XZigZagPivot &items[], - ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // -) -{ - // - int result = -1; - - // - // Validate ... - if (!HasChild(items)) - { - return result; - } - - // - bool has = false; - XZigZagPivot iPoint; - int count = ArraySize(items); - for (int i = 0; i < count; i++) - { - // - // Passed Type ... - has = !IsXValid(type) - ? true - : type == items[i].type; - - // - // Check Can Assign ... - has = - has && - (!iPoint.IsValid() || - (iPoint.IsValid() && - items[i].GetAge() < iPoint.GetAge())); - if (has) - { - // - result = i; - iPoint = items[i]; - } - } - - // - // Validate Result ... - has = - iPoint.IsValid() && - IsValidIndex(result); - if (!has) - { - // - result = -1; - iPoint.Clean(); - return result; - } - - // - iPoint.Clean(); - - // - return result; -} - -/** - * Get Recent Number of Specified Type of Pivots ... - * - * @param source: XZigZagPivot, Collection reference as Data Source ... - * @param recent: XZigZagPivot, Collection reference as result ... - * @param numberRequiredItems: int, required number of Pivots ... - * @param type: ENUM_X_ZIGZAG_POINT_TYPE, type of Pivot ... - * - * @return ( int ) - */ -int GetRecent( - XZigZagPivot &source[], - XZigZagPivot &recent[], - int numberRequiredItems = 2, - ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // -) -{ - // - int result = 0; - - // - int idx = -1; - bool has = false; - - // - // Prepare ... - SpecifiedClean(recent); - - // - // Normalize ... - numberRequiredItems = NormalizeInt(numberRequiredItems, 1); - - // - result = ArraySize(recent); - - // - XZigZagPivot tmp[]; - Copy( - source, - tmp // - ); - - // - // Looping to Detect Recent Pivots ... - XZigZagPivot iPoint; - while (ArraySize(tmp) > 0 && - ArraySize(recent) < numberRequiredItems) - { - // - // Find Youngest of Type Index ... - idx = GetYoungest( - tmp, - type // - ); - has = IsValidIndex(idx); - if (!has) - { - continue; - } - - // - // Extract Item ... - iPoint = tmp[idx]; - - // - // Remove Item ... - ArrayRemove( - tmp, - idx, - 1 // - ); - - // - // Validate Item and Add it to Recent ... - has = iPoint.IsValid(); - if (has) - { - // - AddRef( - iPoint, - recent // - ); - } - - // - // Check For Breaking Loop ... - - // - // If Detect Recent is Passed ... - has = ArraySize(recent) == numberRequiredItems; - if (has) - { - break; - } - - // - // If not anymore items ... - has = ArraySize(tmp) > 0; - if (!has) - { - break; - } - } - - // - result = ArraySize(recent); - - // - // Cleanup Resources ... - iPoint.Clean(); - SpecifiedClean(tmp); - - // - return result; -} bool CalculateZigZagLinearRegression( double &_slope, double &_intercept, XZigZagPivot &_pivots[], - ENUM_X_ZIGZAG_POINT_TYPE _type // + ENUM_X_PIVOT_TYPE _type // ) { // @@ -2311,4 +1397,5 @@ bool CalculateZigZagLinearRegression( // return result; } + // \ No newline at end of file