Is there similare MT5 version?
Alberto Tortella #:
Is there similare MT5 version?
version for mt5:Is there similare MT5 version?
#property copyright "Evgeniy Chumakov | © Copyright 2026" #property description "A modification of the ZigZag indicator, where the reversal moment is determined not by a fixed percentage, but by reaching a specified ratio of the current price to the last local extremum." #property version "1.0" #property link "https://www.mql5.com/ru/users/jack857752" #property indicator_chart_window #property indicator_buffers 7 #property indicator_plots 2 #property indicator_label1 "High Extremum" #property indicator_type1 DRAW_ZIGZAG #property indicator_color1 clrYellow #property indicator_width1 2 #property indicator_label2 "Low Extremum" #property indicator_type2 DRAW_ZIGZAG #property indicator_color2 clrYellow #property indicator_width2 2 input double StepRatio = 1.005; // Step Ratio input int LineWidth = 2; // Line Width input color LineColor = clrYellow; // Color double ArrayHighZZ[]; // High Extremum ZZ double ArrayLowZZ[]; // Low Extremum ZZ double ArrayTypeZZ[]; // ZigZag direction buffer double ArrayHighBarZZ[]; // ZigZag maximum bar location double ArrayLowBarZZ[]; // ZigZag minimum bar location double ArrayHighLast[]; // Last maximum value double ArrayLowLast[]; // Last minimum value //+------------------------------------------------------------------+ int OnInit() { ArraySetAsSeries(ArrayHighZZ, true); ArraySetAsSeries(ArrayLowZZ, true); ArraySetAsSeries(ArrayTypeZZ, true); ArraySetAsSeries(ArrayHighBarZZ, true); ArraySetAsSeries(ArrayLowBarZZ, true); ArraySetAsSeries(ArrayHighLast, true); ArraySetAsSeries(ArrayLowLast, true); // Set buffers for drawing SetIndexBuffer(0, ArrayHighZZ, INDICATOR_DATA); SetIndexBuffer(1, ArrayLowZZ, INDICATOR_DATA); // Set buffers for calculations SetIndexBuffer(2, ArrayTypeZZ, INDICATOR_CALCULATIONS); SetIndexBuffer(3, ArrayHighBarZZ, INDICATOR_CALCULATIONS); SetIndexBuffer(4, ArrayLowBarZZ, INDICATOR_CALCULATIONS); SetIndexBuffer(5, ArrayHighLast, INDICATOR_CALCULATIONS); SetIndexBuffer(6, ArrayLowLast, INDICATOR_CALCULATIONS); // Initialize plot properties PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_ZIGZAG); PlotIndexSetInteger(0, PLOT_LINE_STYLE, STYLE_SOLID); PlotIndexSetInteger(0, PLOT_LINE_WIDTH, LineWidth); PlotIndexSetInteger(0, PLOT_LINE_COLOR, LineColor); PlotIndexSetInteger(0, PLOT_SHOW_DATA, true); PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_ZIGZAG); PlotIndexSetInteger(1, PLOT_LINE_STYLE, STYLE_SOLID); PlotIndexSetInteger(1, PLOT_LINE_WIDTH, LineWidth); PlotIndexSetInteger(1, PLOT_LINE_COLOR, LineColor); PlotIndexSetInteger(1, PLOT_SHOW_DATA, true); IndicatorSetInteger(INDICATOR_DIGITS, _Digits); IndicatorSetString(INDICATOR_SHORTNAME, "RatioZigZag"); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { // Checking for the minimum number of bars to calculate if(rates_total < 3) return(0); // Set arrays as timeseries ArraySetAsSeries(high, true); ArraySetAsSeries(low, true); int start; if(prev_calculated == 0) { // Full recalculation ArrayInitialize(ArrayHighZZ, EMPTY_VALUE); ArrayInitialize(ArrayLowZZ, EMPTY_VALUE); ArrayInitialize(ArrayTypeZZ, EMPTY_VALUE); ArrayInitialize(ArrayHighBarZZ, 0); ArrayInitialize(ArrayLowBarZZ, 0); ArrayInitialize(ArrayHighLast, 0.0); ArrayInitialize(ArrayLowLast, 0.0); start = rates_total - 3; // Calculate starting extremes int init_index = CalcStartingExtremes(rates_total - 1, high, low); if(init_index > 0) start = init_index - 1; } else { // Calculate only new bars start = prev_calculated - 1; if(start < 0) start = 0; } // Calculating the indicator for(int i = start; i >= 0; i--) { if(i + 1 >= rates_total) continue; if(ArrayTypeZZ[i + 1] != EMPTY_VALUE) { if(ArrayTypeZZ[i + 1] > 0) Calculate_High_Extremum(i, high, low); else if(ArrayTypeZZ[i + 1] < 0) Calculate_Low_Extremum(i, high, low); } } return(rates_total); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Calculation High Extremum | //+------------------------------------------------------------------+ void Calculate_High_Extremum(const int index, const double &high[], const double &low[]) { double PriceHigh = high[index]; // Current maximum price value double PriceLow = low[index]; // Current minimum price value bool EventHigh = false; // High point ZZ update event bool EventLow = false; // Low point ZZ update event double MinZZParametr = MathLog(PriceLow) - MathLog(ArrayHighLast[index + 1]); // Updating and redrawing the maximum extremum if(PriceHigh > ArrayHighLast[index + 1]) { EventHigh = true; ArrayTypeZZ[index] = 1; // Clear previous high point if(ArrayHighBarZZ[index + 1] < ArraySize(ArrayHighZZ)) ArrayHighZZ[(int)ArrayHighBarZZ[index + 1]] = EMPTY_VALUE; // Set new high point ArrayHighZZ[index] = PriceHigh; ArrayHighBarZZ[index] = index; ArrayLowBarZZ[index] = ArrayLowBarZZ[index + 1]; ArrayHighLast[index] = PriceHigh; ArrayLowLast[index] = ArrayLowLast[index + 1]; } // Creating and drawing the minimum extremum if(MinZZParametr <= -MathLog(StepRatio) && !EventHigh) { EventLow = true; ArrayTypeZZ[index] = -1; // Set low point ArrayLowZZ[index] = PriceLow; ArrayLowLast[index] = PriceLow; ArrayHighLast[index] = ArrayHighLast[index + 1]; ArrayHighBarZZ[index] = ArrayHighBarZZ[index + 1]; ArrayLowBarZZ[index] = index; } // No events for forming extremes. Copying past data. if(!EventHigh && !EventLow) { ArrayTypeZZ[index] = ArrayTypeZZ[index + 1]; ArrayHighBarZZ[index] = ArrayHighBarZZ[index + 1]; ArrayLowBarZZ[index] = ArrayLowBarZZ[index + 1]; ArrayHighLast[index] = ArrayHighLast[index + 1]; ArrayLowLast[index] = ArrayLowLast[index + 1]; } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Calculation Low Extremum | //+------------------------------------------------------------------+ void Calculate_Low_Extremum(const int index, const double &high[], const double &low[]) { double PriceHigh = high[index]; // Current maximum price value double PriceLow = low[index]; // Current minimum price value bool EventLow = false; // Low point ZZ update event bool EventHigh = false; // High point ZZ update event double MaxZZParametr = MathLog(PriceHigh) - MathLog(ArrayLowLast[index + 1]); // Updating and redrawing the minimum extremum if(PriceLow < ArrayLowLast[index + 1]) { EventLow = true; ArrayTypeZZ[index] = -1; // Clear previous low point if(ArrayLowBarZZ[index + 1] < ArraySize(ArrayLowZZ)) ArrayLowZZ[(int)ArrayLowBarZZ[index + 1]] = EMPTY_VALUE; // Set new low point ArrayLowZZ[index] = PriceLow; ArrayLowBarZZ[index] = index; ArrayHighBarZZ[index] = ArrayHighBarZZ[index + 1]; ArrayHighLast[index] = ArrayHighLast[index + 1]; ArrayLowLast[index] = PriceLow; } // Creating and drawing the maximum extremum if(MaxZZParametr >= MathLog(StepRatio) && !EventLow) { EventHigh = true; ArrayTypeZZ[index] = 1; // Set high point ArrayHighZZ[index] = PriceHigh; ArrayHighLast[index] = PriceHigh; ArrayLowLast[index] = ArrayLowLast[index + 1]; ArrayHighBarZZ[index] = index; ArrayLowBarZZ[index] = ArrayLowBarZZ[index + 1]; } // No events for forming extremes. Copying past data. if(!EventHigh && !EventLow) { ArrayTypeZZ[index] = ArrayTypeZZ[index + 1]; ArrayHighBarZZ[index] = ArrayHighBarZZ[index + 1]; ArrayLowBarZZ[index] = ArrayLowBarZZ[index + 1]; ArrayHighLast[index] = ArrayHighLast[index + 1]; ArrayLowLast[index] = ArrayLowLast[index + 1]; } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Calculation Of Starting Extremes | //+------------------------------------------------------------------+ int CalcStartingExtremes(const int index, const double &high[], const double &low[]) { int init_index = 0; for(int period = 2; period < index; period++) { int period_start = index - period; // Measurement start position int MaxBar = -1; double max_val = -DBL_MAX; for(int j = period_start; j < period_start + period; j++) { if(high[j] > max_val) { max_val = high[j]; MaxBar = j; } } int MinBar = -1; double min_val = DBL_MAX; for(int j = period_start; j < period_start + period; j++) { if(low[j] < min_val) { min_val = low[j]; MinBar = j; } } double Max_Price = high[MaxBar]; // The value of the maximum price on the measured interval. double Min_Price = low[MinBar]; // The value of the minimum price on the measured interval. double MaxZZParametr = MathLog(Max_Price) - MathLog(Min_Price); double MinZZParametr = MathLog(Min_Price) - MathLog(Max_Price); // Formation of the maximum extremum if(MaxBar != MinBar && MaxBar < MinBar && MaxZZParametr >= MathLog(StepRatio)) { ArrayTypeZZ[period_start] = 1; ArrayHighZZ[MaxBar] = Max_Price; ArrayLowZZ[MinBar] = Min_Price; ArrayHighBarZZ[period_start] = MaxBar; ArrayLowBarZZ[period_start] = MinBar; ArrayHighLast[period_start] = Max_Price; ArrayLowLast[period_start] = Min_Price; init_index = period_start; break; } // Formation of a minimum extremum if(MaxBar != MinBar && MinBar < MaxBar && MinZZParametr <= -MathLog(StepRatio)) { ArrayTypeZZ[period_start] = -1; ArrayHighZZ[MaxBar] = Max_Price; ArrayLowZZ[MinBar] = Min_Price; ArrayHighBarZZ[period_start] = MaxBar; ArrayLowBarZZ[period_start] = MinBar; ArrayHighLast[period_start] = Max_Price; ArrayLowLast[period_start] = Min_Price; init_index = period_start; break; } } return(init_index); } //+------------------------------------------------------------------+
Thank you very much!
I just tried the indicator but when I loaded it on a graph the plaform crashed...
What does this indicator do different to normal ZigZag? I can spot the difference in plotting, I just don't see any use-case and why should it be used over common zigzag? Is it a baseline for some specific strategy?
Shadoba #:
What does this indicator do different to normal ZigZag? I can spot the difference in plotting, I just don't see any use-case and why should it be used over common zigzag? Is it a baseline for some specific strategy?
It differs from a regular zigzag in that it uses a different calculation. The indicator is similar to other indicators in terms of how to use it.
What does this indicator do different to normal ZigZag? I can spot the difference in plotting, I just don't see any use-case and why should it be used over common zigzag? Is it a baseline for some specific strategy?
Thank you very much!
You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
RatioZigZag:
A modification of the ZigZag indicator, where the reversal moment is determined by a specified coefficient.
Author: Evgeniy Chumakov