From 0e21425cefed1434f5c3b34dec2890ac8037f9fa Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Wed, 24 Sep 2025 07:45:03 +0330 Subject: [PATCH] remove test materials ... --- Experts/TestRegresser.mq5 | 1108 ------------------------------------- Indicators/ZigZag.mq5 | Bin 18826 -> 0 bytes 2 files changed, 1108 deletions(-) delete mode 100644 Experts/TestRegresser.mq5 delete mode 100644 Indicators/ZigZag.mq5 diff --git a/Experts/TestRegresser.mq5 b/Experts/TestRegresser.mq5 deleted file mode 100644 index cd880162..00000000 --- a/Experts/TestRegresser.mq5 +++ /dev/null @@ -1,1108 +0,0 @@ -//+------------------------------------------------------------------+ -//| TestRegresser.mq5 | -//| SaherElm IT Center | -//| https://www.saherelm.ir | -//+------------------------------------------------------------------+ -#property copyright "SaherElm IT Center" -#property link "https://www.saherelm.ir" -#property version "1.00" - -// -// Imports ... -#include "../Classes/x-saherelm.x-cobject.class.mq5" -#include "../Libraries/x-saherelm.common.lib.mq5" -#include "../Libraries/x-saherelm.x-poi.lib.mq5" -#include - -// -// Inputs ... - -// -// Calculation ... -input int zigzagDepth = 12; // Depth -input int zigzagDeviation = 5; // Deviation -input int zigzagBackStep = 3; // Back Step -input int mLoopbackLength = 200; // Loopback Length for Calculation -input int mRequiredPivots = 50; // Required Peaks for Calculation (0 > use loopback ) - -// -// Variables ... - -// -double mZigZagBuffer[]; // ZigZag Values Buffer ... -XBarTracker mBarTracker; // Bar Tracker ... -bool mZigZagPivotIsPeaks[]; // Check ZigZag Pivot Peak or Vale ... -double mZigZagPivotPrices[]; // ZigZag Pivot Prices ... -double mZigZagPivotIndexes[]; // ZigZag Pivot Indexes ... -datetime mZigZagPivotTimes[]; // ZigZag Pivot Times ... -CChartObjectTrend *mUpperTrend; // Trend Line Upper ... -CChartObjectTrend *mLowerTrend; // Trend Line Lower ... -int mZigZagHandler = INVALID_HANDLE; // ZigZag Indicator Handler ... - -// -double mPeakSlope; -double mPeakIntercept; -double mZigZagPeaks[]; -double mZigZagPeakIndexes[]; -datetime mZigZagPeakTimes[]; - -// -double mValeSlope; -double mValeIntercept; -double mZigZagVales[]; -double mZigZagValeIndexes[]; -datetime mZigZagValeTimes[]; - -// -datetime mToTime; -datetime mFromTime; - -// -// Predictions ... - -// -double mPeakTo; -double mValeTo; -double mPeakFrom; -double mValeFrom; - -// -ENUM_X_DIRECTION mUpperTrendDir; -ENUM_X_DIRECTION mLowerTrendDir; - -// -// Support and Resistances ... - -// -XBoxZone mSupportBox; -double mMinorSupport; -double mMajorSupport; -XCBoxObject *mSupportObj; - -// -XBoxZone mResistanceBox; -double mMinorResistance; -double mMajorResistance; -XCBoxObject *mResistanceObj; - -//+------------------------------------------------------------------+ -//| Expert initialization function | -//+------------------------------------------------------------------+ -int OnInit() -{ - // - // Initialize Bar Tracker ... - mBarTracker.Init( - _Symbol, - _Period // - ); - - // - // Initialize ZigZag Handler ... - mZigZagHandler = iCustom( - _Symbol, - _Period, - "ZigZag", - zigzagDepth, - zigzagDeviation, - zigzagBackStep // - ); - if (mZigZagHandler == INVALID_HANDLE) - { - Print("Error creating ZigZag handle"); - return (INIT_FAILED); - } - - // - return (INIT_SUCCEEDED); -} -//+------------------------------------------------------------------+ -//| Expert deinitialization function | -//+------------------------------------------------------------------+ -void OnDeinit(const int reason) -{ - // - IndicatorRelease(mZigZagHandler); -} -//+------------------------------------------------------------------+ -//| Expert tick function | -//+------------------------------------------------------------------+ -void OnTick() -{ - // - if (!mBarTracker.IsNewBar()) - { - return; - } - - // - int readedZigZagsCount = 0; - bool readZigZagsBasedOnPivots = mRequiredPivots > 0; - - // - // Reading ZigZag Values Based on Loopback Length ... - if (!readZigZagsBasedOnPivots) - { - readedZigZagsCount = ReadZigZagValues(); - } - // - // Reading ZigZag Pivots based on required Pivots ... - else - { - // - readedZigZagsCount = ReadingZigZagPivots( - 0, // BarIndex ... - mRequiredPivots + 1, // Required Pivots ... - 1500 // Max Allowed Loopback Length ... - ); - } - - // - // Validate Reading Succeed ... - if (readedZigZagsCount <= 0) - { - return; - } - - // - // Try to Detect ZigZag Peaks and Vales ... - ProcessZigZagsPeaksAndVales(); - - // - // Try to Calculate ZigZag Supports and Resistances ... - ProcessZigZagsSupportsAnsResistances(); - - // - // Try to Calculate Peaks and Vales Linear Regression Based - // Slope and Intercept (s) and also Detect From and To Times then - // Predict Peaks and Vales Values for them then ... - // Prepare Support and Resistance Boxes based on Calculated Support - // and Resistances ... - if (!CalculateZigZagLinearRegressionParameters()) - { - return; - } - - // - // Draw Peaks and Vales Based Trend Lines ... - DrawAnalysis(); - - // - // Process ZigZag Values ... - Print(""); - - // -} -//+------------------------------------------------------------------+ - -// -int ReadZigZagValues(int barIndex = 0) -{ - // - int result = 0; - - // - // Normalize ... - barIndex = NormalizeInt(barIndex, 0); - - // - // Validate ... - if (mZigZagHandler == INVALID_HANDLE) - { - return result; - } - - // - // Copy ZigZag Values to Buffers ... - result = CopyBuffer(mZigZagHandler, MAIN_LINE, 0, mLoopbackLength, mZigZagBuffer); - - // - // Set ZigZag Buffers as Series ... - ArraySetAsSeries(mZigZagBuffer, true); - - // - if (result <= 0) - { - return result; - } - - // - // Filling ZigZag Pivots ... - - // - // Clean Buffers ... - SpecifiedClean(mZigZagPivotTimes); - SpecifiedClean(mZigZagPivotPrices); - SpecifiedClean(mZigZagPivotIsPeaks); - SpecifiedClean(mZigZagPivotIndexes); - - // - // Looping Through ZigZag Buffers ... - XOHCL iBar; - bool has = false; - double iZigZag = 0; - bool isIZigZagPeak = false; - int count = ArraySize(mZigZagBuffer); - for (int i = 0; i < count; i++) - { - // - // Reading ZigZag Value ... - iZigZag = mZigZagBuffer[i]; - - // - // Validate ZigZag Values ... - if (!NotEmptyZero(iZigZag)) - { - continue; - } - - // - // Check ZigZag Value Is Peak or Vale ... - - // - // Initialize iBar ... - has = iBar.Init( - _Symbol, - _Period, - i // - ); - - // - // Validate Bar and also Exclude Most Recent Swing ... - if (!has || iBar.Index() == 0) - { - // - iBar.Clean(); - continue; - } - - // - isIZigZagPeak = iZigZag == iBar.high; - - // - // Filling Buffers ... - Add( - iBar.time, - mZigZagPivotTimes // - ); - Add( - iZigZag, - mZigZagPivotPrices // - ); - Add( - isIZigZagPeak, - mZigZagPivotIsPeaks // - ); - Add( - (double)iBar.Index(), - mZigZagPivotIndexes // - ); - - // - // Cleanup Resources ... - iBar.Clean(); - } - - // - return result; -} - -// -int ReadingZigZagPivots( - int barIndex = 0, - int requiredPivots = 15, - int maxAllowedLoopback = 1500 // -) -{ - // - int result = 0; - - // - // Cleanup Resources ... - SpecifiedClean(mZigZagPivotTimes); - SpecifiedClean(mZigZagPivotPrices); - SpecifiedClean(mZigZagPivotIsPeaks); - SpecifiedClean(mZigZagPivotIndexes); - - // - // Normalize ... - barIndex = NormalizeInt(barIndex, 0); - requiredPivots = NormalizeInt(requiredPivots, 2); - maxAllowedLoopback = NormalizeInt(maxAllowedLoopback, 100); - - // - XOHCL iBar; - bool has = false; - double iZigZag = 0; - bool isPeak = false; - int idx = barIndex - 1; - double tmpZigZagBuffer[]; - int maxAllowed = barIndex + maxAllowedLoopback; - while (idx < maxAllowed && - ArraySize(mZigZagPivotPrices) < requiredPivots) - { - // - idx++; - - // - // Initializing Bar ... - has = iBar.Init( - _Symbol, - _Period, - idx // - ); - if (!has) - { - continue; - } - - // - // Reading ZigZag Value ... - if (CopyBuffer(mZigZagHandler, MAIN_LINE, idx, 1, tmpZigZagBuffer) < 1) - { - // - iBar.Clean(); - continue; - } - - // - // Read ZigZag Value and Validate it ... - iZigZag = tmpZigZagBuffer[0]; - has = NotEmptyZero(iZigZag); - if (!has) - { - // - iBar.Clean(); - SpecifiedClean(tmpZigZagBuffer); - - // - continue; - } - - // - isPeak = iZigZag == iBar.high; - - // - // Validate ZigZag Value for Ignore Zero ... - if (iBar.Index() == barIndex) - { - // - iBar.Clean(); - SpecifiedClean(tmpZigZagBuffer); - - // - continue; - } - - // - // Filling Pivots ... - - // - Add( - iZigZag, - mZigZagPivotPrices // - ); - - // - Add( - isPeak, - mZigZagPivotIsPeaks // - ); - - // - Add( - iBar.time, - mZigZagPivotTimes // - ); - - // - Add( - (double)iBar.Index(), - mZigZagPivotIndexes // - ); - - // - // Cleanup Resources ... - iBar.Clean(); - SpecifiedClean(tmpZigZagBuffer); - - // - // Check Can Break Loop ... - has = idx >= maxAllowed || - ArraySize(mZigZagPivotPrices) == requiredPivots; - if (has) - { - break; - } - } - - // - // Cleanup Resources ... - SpecifiedClean(tmpZigZagBuffer); - - // - result = ArraySize(mZigZagPivotPrices); - - // - return result; -} - -// -void ProcessZigZagsPeaksAndVales() -{ - // - // Here we Parse ZigZag Values to Detect Peak or Vale ... - - // - int count = 0; - bool has = false; - - // - // Extract mZigZag Peaks and Vales ... - SpecifiedClean(mZigZagPeaks); - SpecifiedClean(mZigZagVales); - SpecifiedClean(mZigZagPeakTimes); - SpecifiedClean(mZigZagValeTimes); - SpecifiedClean(mZigZagPeakIndexes); - SpecifiedClean(mZigZagValeIndexes); - count = ArraySize(mZigZagPivotPrices); - has = IsValidSize(count); - if (!has) - { - return; - } - - // - double iZigZag = 0; - double iZigZagIDX = -1; - bool isIZigZagPeak = false; - datetime iZigZagTime = NULL; - for (int i = 0; i < count; i++) - { - // - // Reading Required Values ... - iZigZag = mZigZagPivotPrices[i]; - iZigZagTime = mZigZagPivotTimes[i]; - iZigZagIDX = mZigZagPivotIndexes[i]; - isIZigZagPeak = mZigZagPivotIsPeaks[i]; - - // - if (isIZigZagPeak) - { - // - Add( - iZigZag, - mZigZagPeaks // - ); - - // - Add( - iZigZagTime, - mZigZagPeakTimes // - ); - - // - Add( - iZigZagIDX, - mZigZagPeakIndexes // - ); - } - else - { - // - Add( - iZigZag, - mZigZagVales // - ); - - // - Add( - iZigZagTime, - mZigZagValeTimes // - ); - - // - Add( - iZigZagIDX, - mZigZagValeIndexes // - ); - } - } -} - -// -void ProcessZigZagsSupportsAnsResistances() -{ - // - int count = 0; - bool has = false; - double iValue = EMPTY_VALUE; - double tmpValue = EMPTY_VALUE; - - // - // Support ... - // Supports Calculated based on Vales ... - - // - tmpValue = EMPTY_VALUE; - mMinorSupport = EMPTY_VALUE; - mMajorSupport = EMPTY_VALUE; - count = ArraySize(mZigZagVales); - has = IsValidSize(count); - if (has) - { - // - for (int i = 0; i < count; i++) - { - // - // Reading Indexed Value ... - iValue = mZigZagVales[i]; - - // - // Check Can Change Major Support ... - has = !NotEmpty(mMajorSupport) || - mMajorSupport > iValue; - if (has) - { - // - tmpValue = mMajorSupport; - mMajorSupport = iValue; - } - else - { - // - // Check Minor Support ... - has = !NotEmpty(tmpValue) || - tmpValue > iValue; - if (has) - { - tmpValue = iValue; - } - } - } - - // - has = NotEmpty(tmpValue); - if (has) - { - mMinorSupport = tmpValue; - } - } - - // - // Resistance ... - // Resistances Calculated based on Peaks ... - - // - tmpValue = EMPTY_VALUE; - mMinorResistance = EMPTY_VALUE; - mMajorResistance = EMPTY_VALUE; - count = ArraySize(mZigZagPeaks); - has = IsValidSize(count); - if (has) - { - // - for (int i = 0; i < count; i++) - { - // - // Reading Indexed Value ... - iValue = mZigZagPeaks[i]; - - // - // Check Can Change Major Resistance ... - has = !NotEmpty(mMajorResistance) || - mMajorResistance < iValue; - if (has) - { - // - tmpValue = mMajorResistance; - mMajorResistance = iValue; - } - else - { - // - // Check Minor Resistance ... - has = !NotEmpty(tmpValue) || - tmpValue < iValue; - if (has) - { - tmpValue = iValue; - } - } - } - - // - has = NotEmpty(tmpValue); - if (has) - { - mMinorResistance = tmpValue; - } - } -} - -// -bool CalculateZigZagLinearRegressionParameters() -{ - // - bool result = false; - mUpperTrendDir = X_DIRECTION_NONE; - mLowerTrendDir = X_DIRECTION_NONE; - - // - // Peaks ... - CalculateSlopeAndIntercept( - mPeakSlope, - mPeakIntercept, - mZigZagPeakIndexes, - mZigZagPeaks // - ); - - // - // Vales ... - CalculateSlopeAndIntercept( - mValeSlope, - mValeIntercept, - mZigZagValeIndexes, - mZigZagVales // - ); - - // - result = - (NotEmpty(mPeakSlope) && - NotEmpty(mPeakIntercept)) || - (NotEmpty(mValeSlope) && - NotEmpty(mValeIntercept)); - if (!result) - { - return result; - } - - // - // Detect Oldest and Youngest Time of Pivots ... - - // - int idx = -1; - bool has = false; - - // - // Oldest ... - has = FindOldestIndex( - idx, - mZigZagPivotTimes // - ); - if (has) - { - mFromTime = mZigZagPivotTimes[idx]; - } - - // - // Youngest ... - has = FindYoungesttIndex( - idx, - mZigZagPivotTimes // - ); - if (has) - { - mToTime = mZigZagPivotTimes[idx]; - } - - // - // Validate Extracted Times ... - result = - IsSpecifiedValid(mToTime) && - IsSpecifiedValid(mFromTime); - if (!result) - { - return result; - } - - // - // Detect Extracted Times Bar Indexes ... - - // - int mToIDX = iBarShift( - _Symbol, - _Period, - mToTime // - ); - int mFromIDX = iBarShift( - _Symbol, - _Period, - mFromTime // - ); - - // - // Validate Detected Bar Indexes ... - result = - IsValidIndex(mToIDX) && - IsValidIndex(mFromIDX); - if (!result) - { - return result; - } - - // - // Calculate Predictions ... - - // - // Peak ... - mPeakTo = PredictValue( - mPeakSlope, - mPeakIntercept, - mToIDX // - ); - mPeakFrom = PredictValue( - mPeakSlope, - mPeakIntercept, - mFromIDX // - ); - - // - // Vale ... - mValeTo = PredictValue( - mValeSlope, - mValeIntercept, - mToIDX // - ); - mValeFrom = PredictValue( - mValeSlope, - mValeIntercept, - mFromIDX // - ); - - // - mUpperTrendDir = - mPeakFrom < mPeakTo - ? X_DIRECTION_BULLISH - : mPeakFrom > mPeakTo - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; - mLowerTrendDir = - mValeFrom < mValeTo - ? X_DIRECTION_BULLISH - : mValeFrom > mValeTo - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; - - // - // Prepare Support and Resistance Boxes ... - - // - // Support ... - - // - mSupportBox.Clean(); - has = NotEmptyZero(mMinorSupport) && - NotEmptyZero(mMajorSupport); - if (has) - { - // - mSupportBox.to = mToTime; - mSupportBox.from = mFromTime; - mSupportBox.symbol = _Symbol; - mSupportBox.period = _Period; - mSupportBox.type = "Support"; - mSupportBox.upper = mMinorSupport; - mSupportBox.lower = mMajorSupport; - mSupportBox.dir = X_DIRECTION_BULLISH; - } - - // - // Resistance ... - - // - mResistanceBox.Clean(); - has = NotEmptyZero(mMinorResistance) && - NotEmptyZero(mMajorResistance); - if (has) - { - // - mResistanceBox.to = mToTime; - mResistanceBox.from = mFromTime; - mResistanceBox.symbol = _Symbol; - mResistanceBox.period = _Period; - mResistanceBox.type = "Resistance"; - mResistanceBox.upper = mMajorResistance; - mResistanceBox.lower = mMinorResistance; - mResistanceBox.dir = X_DIRECTION_BEARISH; - } - - // - result = - mSupportBox.IsValid() || - mResistanceBox.IsValid(); - - // - return result; -} - -// -void DrawAnalysis() -{ - // - bool isCreated = false; - - // - // Peak ... - - // - // Cleanup Upper Object ... - if (mUpperTrend != NULL) - { - // - mUpperTrend.Delete(); - mUpperTrend.Detach(); - delete mUpperTrend; - ZeroMemory(mUpperTrend); - } - - // - mUpperTrend = new CChartObjectTrend(); - isCreated = mUpperTrend.Create( - ChartID(), - "UpperTrend", - 0, - mFromTime, - mPeakFrom, - mToTime, - mPeakTo // - ); - if (isCreated) - { - // - // Apply Styles ... - - // - color upperColor = - IsSpecifiedBullish(mUpperTrendDir) - ? clrAqua - : IsSpecifiedBearish(mUpperTrendDir) - ? clrMagenta - : clrGray; // Neutural ... - - // - mUpperTrend.Width(2); - mUpperTrend.RayRight(true); - mUpperTrend.Color(upperColor); - } - - // - // Vale ... - - // - // Cleanup Lower Object ... - if (mLowerTrend != NULL) - { - // - mLowerTrend.Delete(); - mLowerTrend.Detach(); - delete mLowerTrend; - ZeroMemory(mLowerTrend); - } - - // - mLowerTrend = new CChartObjectTrend(); - isCreated = mLowerTrend.Create( - ChartID(), - "LowerTrend", - 0, - mFromTime, - mValeFrom, - mToTime, - mValeTo // - ); - if (isCreated) - { - // - // Apply Styles ... - - // - color lowerColor = - IsSpecifiedBullish(mLowerTrendDir) - ? clrAqua - : IsSpecifiedBearish(mLowerTrendDir) - ? clrMagenta - : clrGray; // Neutural ... - - // - mLowerTrend.Width(2); - mLowerTrend.RayRight(true); - mLowerTrend.Color(lowerColor); - } - - // - // Support ... - - // - // Cleanup Support Object ... - if (mSupportObj != NULL) - { - // - mSupportObj.Delete(); - mSupportObj.Detach(); - delete mSupportObj; - ZeroMemory(mSupportObj); - } - - // - isCreated = mSupportBox.IsValid(); - if (isCreated) - { - // - datetime to = TimeCurrent(); - mSupportObj = new XCBoxObject(); - isCreated = mSupportObj.Create( - ChartID(), - 0, - "Support", - mSupportBox.upper, - mSupportBox.lower, - mSupportBox.from, - to // - ); - if (isCreated) - { - // - // Apply Style ... - mSupportObj.BoxWidth(2); - mSupportObj.BoxColor(clrAqua); - } - } - - // - // Resistance ... - - // - // Cleanup Resistance Object ... - if (mResistanceObj != NULL) - { - // - mResistanceObj.Delete(); - mResistanceObj.Detach(); - delete mResistanceObj; - ZeroMemory(mResistanceObj); - } - - // - isCreated = mResistanceBox.IsValid(); - if (isCreated) - { - // - datetime to = TimeCurrent(); - mResistanceObj = new XCBoxObject(); - isCreated = mResistanceObj.Create( - ChartID(), - 0, - "Resistance", - mResistanceBox.upper, - mResistanceBox.lower, - mResistanceBox.from, - to // - ); - if (isCreated) - { - // - // Apply Style ... - mResistanceObj.BoxWidth(2); - mResistanceObj.BoxColor(clrMagenta); - } - } -} - -// -int FindOldestIndex( - int &index, - datetime ×[] // -) -{ - // - bool result = false; - - // - // Prepare ... - index = -1; - - // - // Validate ... - if (!HasChild(times)) - { - return result; - } - - // - bool has = false; - datetime tmpTime = NULL; - for (int i = 0; i < ArraySize(times); i++) - { - // - has = - !IsSpecifiedValid(tmpTime) - ? true - : tmpTime > times[i]; - if (has) - { - // - index = i; - tmpTime = times[i]; - } - } - - // - // Validate result ... - result = - IsValidIndex(index) && - IsSpecifiedValid(tmpTime); - - // - return result; -} - -// -int FindYoungesttIndex( - int &index, - datetime ×[] // -) -{ - // - bool result = false; - - // - // Prepare ... - index = -1; - - // - // Validate ... - if (!HasChild(times)) - { - return result; - } - - // - bool has = false; - datetime tmpTime = NULL; - for (int i = 0; i < ArraySize(times); i++) - { - // - has = - !IsSpecifiedValid(tmpTime) - ? true - : tmpTime < times[i]; - if (has) - { - // - index = i; - tmpTime = times[i]; - } - } - - // - // Validate result ... - result = - IsValidIndex(index) && - IsSpecifiedValid(tmpTime); - - // - return result; -} - -// \ No newline at end of file diff --git a/Indicators/ZigZag.mq5 b/Indicators/ZigZag.mq5 deleted file mode 100644 index 3863bd7aff92ac295fcb08c7843b2df30f7bb69e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18826 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 rW081Y<7(H}ZvNLlZU_&