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 3863bd7a..00000000 Binary files a/Indicators/ZigZag.mq5 and /dev/null differ