//+------------------------------------------------------------------+ //| 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 "../Libraries/x-saherelm.common.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; input int mExtendFutureLength = 100; // Bars to extend trendlines into the future // // 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[]; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // // Initialize Bar Tracker ... mBarTracker.Init( _Symbol, _Period // ); // double xData[]; double yData[]; int xDataCount = CollectData( xData, yData // ); // // 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 = ReadZigZagValues(); if (readedZigZagsCount <= 0) { return; } ProcessZigZagsPeaksAndVales(); CalculateZigZagLinearRegressionParameters(); DrawZigZagPredictedTrendLines(); // // Process ZigZag Values ... Print(""); // } //+------------------------------------------------------------------+ // int CollectData( double &xData[], double &yData[], int barIndex = 0 // ) { // int result = false; // SpecifiedClean(xData); SpecifiedClean(yData); // barIndex = NormalizeInt(barIndex, 0); // int start = barIndex; int end = start + mLoopbackLength; for (int i = start; i < end; i++) { // double iY = GetAppliedPrice( _Symbol, _Period, i // ); // datetime iTime = iTime( _Symbol, _Period, i // ); double iX = i + 1; // (double)TimeToSeconds(iTime); // Add( iX, xData // ); // Add( iY, yData // ); } // result = ArraySize(xData); // return result; } // 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); // return result; } // void ProcessZigZagsPeaksAndVales() { // // Here we Parse ZigZag Values to Detect Peak or Vale ... // // 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(); } // // 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 iZigZagIDX = -1; 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 // ); } } // // TODO: // - [] Add Support for Reading Specified Number of Swings instead of Specified Loopback ... } // void CalculateZigZagLinearRegressionParameters() { // // Peaks ... CalculateSlopeAndIntercept( mPeakSlope, mPeakIntercept, mZigZagPeakIndexes, mZigZagPeaks // ); // // Vales ... CalculateSlopeAndIntercept( mValeSlope, mValeIntercept, mZigZagValeIndexes, mZigZagVales // ); } // void DrawZigZagPredictedTrendLines() { // // This Variables are Same in Peaks and Vales ... // // TODO: // - [] Add Support for Extending Lines betwen Oldest and Youngest Pivots ... // - [] Add Support for Styling Lines ... // // FromTime ... datetime fromTime = iTime( _Symbol, _Period, mLoopbackLength - 1 // ); int fromIDX = iBarShift( _Symbol, _Period, fromTime // ); // // To Time ... // this time Calculated using From Time and mExtendFutureLength ... datetime toTime = fromTime + (mExtendFutureLength * PeriodSeconds(_Period)); int toIDX = iBarShift( _Symbol, _Period, toTime // ); // // Predict Values ... // // Peak ... double mPeakTo = PredictValue( mPeakSlope, mPeakIntercept, toIDX // ); double mPeakFrom = PredictValue( mPeakSlope, mPeakIntercept, fromIDX // ); // // Vale ... double mValeTo = PredictValue( mValeSlope, mValeIntercept, toIDX // ); double mValeFrom = PredictValue( mValeSlope, mValeIntercept, fromIDX // ); // // Draw Predicted Lines ... // 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, fromTime, mPeakFrom, toTime, mPeakTo // ); if (isCreated) { // // Apply Styles ... // mUpperTrend.Width(2); mUpperTrend.RayRight(true); mUpperTrend.Color(clrAqua); } // // Vale ... // // Cleanup Lower Object ... if (mLowerTrend != NULL) { // mLowerTrend.Delete(); mLowerTrend.Detach(); delete mLowerTrend; ZeroMemory(mLowerTrend); } // mLowerTrend = new CChartObjectTrend(); isCreated = mLowerTrend.Create( ChartID(), "LowerTrend", 0, fromTime, mValeFrom, toTime, mValeTo // ); if (isCreated) { // // Apply Styles ... // mLowerTrend.Width(2); mLowerTrend.RayRight(true); mLowerTrend.Color(clrMagenta); } } //