///////////////////////////////////////////////////////////////// // // SaherElm IT Center ZigZag Indicator // ------------------------------------------------------------- // this indicator provides signals for Main strategy ... // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // //////////////////////////////////////////////////////////////// // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm ZigZag Indicator" #property strict // // START Inputs ... // input int depth = 12; // Depth input int deviation = 5; // Deviation input int backStep = 3; // BackStep // // END Inputs ... // // // START Global Definitions: Variables, Properties and etc ... // // // Includes our shared library ... #include "../Libraries/x-saherelm.lib.mq4" // // here we specify logging enabled or not ... bool enableLogging = true; // // this is a Tag which attached to our Logger ... string logTag = "XS_ZG"; // #property indicator_chart_window // #property indicator_buffers 1 // #property indicator_width1 1 #property indicator_color1 clrAqua // #property indicator_type1 DRAW_SECTION // #property indicator_style1 STYLE_SOLID // // // #property indicator_width2 1 // #property indicator_color2 clrNONE // #property indicator_type2 DRAW_NONE // #property indicator_style2 STYLE_SOLID // // // #property indicator_width3 1 // #property indicator_color3 clrNONE // #property indicator_type3 DRAW_NONE // #property indicator_style3 STYLE_SOLID // // Buffers ... // #define zigzagBufferIndex 0 #define highBufferIndex 1 #define lowBufferIndex 2 // #define ziggyBufferIndex 3 // double zigzagBuffer[]; double highBuffer[]; double lowBuffer[]; // double ziggyBuffer[]; // // recounting's depth of extremums ... int level=3; // // END Global Definitions: Variables, Properties and etc ... // // // Start Event Handlers ... // // // Initialization ... int OnInit() { // // Initialize what we want ... // // Validating Input Parameters ... if ( depth <= 0 || backStep < 0 || deviation < 0 || backStep >= depth ) { return INIT_PARAMETERS_INCORRECT; } // // Set Index Buffers of ZigZag ... IndicatorBuffers(3); // // ZigZag Buffer ... SetIndexBuffer(zigzagBufferIndex, zigzagBuffer); SetIndexStyle(zigzagBufferIndex, DRAW_SECTION); SetIndexLabel(zigzagBufferIndex, "ZigZag"); // // High Buffer ... SetIndexBuffer(highBufferIndex, highBuffer); SetIndexLabel(highBufferIndex, ""); // // Low Buffer ... SetIndexBuffer(lowBufferIndex, lowBuffer); SetIndexLabel(lowBufferIndex, ""); // // Ziggy Buffer ... // SetIndexBuffer(ziggyBufferIndex, ziggyBuffer); // SetIndexLabel(ziggyBufferIndex, ""); // return(INIT_SUCCEEDED); } // // Do Calculation ... 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[] ) { // // this counts Available Bars ... int limit; // int maxLength = MathMax(depth, backStep); int i; int counterZ; int back; int pos; // int lastlowpos = 0; int lasthighpos = 0; int whatlookfor = 0; // double extremum; // double curlow = 0.0; double curhigh = 0.0; double lasthigh = 0.0; double lastlow = 0.0; // // input variable, we return 0 means nothing passed ... if (rates_total < maxLength) { return 0; } // // first calculations ... if (prev_calculated == 0) { limit = InitializeBuffers(); } else { // // find first extremum in the depth ExtLevel or 100 last bars ... i = counterZ = 0; while(counterZ < level && i < 100) { // if(zigzagBuffer[i] != 0.0) { counterZ++; } // i++; } // // no extremum found - recounting all from begin ... if(counterZ == 0) { limit = InitializeBuffers(); } else { // // set start position to found extremum position ... limit = i-1; // //--- what kind of extremum? if(lowBuffer[i] != 0.0) { // // low extremum ... curlow = lowBuffer[i]; // // will look for the next high extremum ... whatlookfor=1; } else { // // high extremum ... curhigh = highBuffer[i]; // // will look for the next low extremum ... whatlookfor=-1; } // // clear the rest data ... for(i = limit - 1; i >= 0; i--) { // lowBuffer[i]=0.0; highBuffer[i]=0.0; zigzagBuffer[i]=0.0; } } } // // Main Calculation Loop ... for (i = limit; i >= 0; i--) { // // find lowest low in depth of bars ... extremum = low[ iLowest( _Symbol, _Period, MODE_LOW, depth, i ) ]; // // this lowest has been found previously ... if (extremum == lastlow) { extremum = 0.0; } else { // // new last low ... lastlow=extremum; // // discard extremum if current low is too high ... if(low[i] - extremum > deviation * _Point) { extremum=0.0; } else { // // clear previous extremums in backstep bars ... for(back = 1; back <= backStep; back++) { // pos = i + back; // if(lowBuffer[pos] != 0 && lowBuffer[pos] > extremum) { lowBuffer[pos] = 0.0; } } } } // // found extremum is current low ... if (low[i] == extremum) { lowBuffer[i] = extremum; } else { lowBuffer[i] = 0.0; } // // find highest high in depth of bars ... extremum = high[ iHighest( _Symbol, _Period, MODE_HIGH, depth, i ) ]; // // this highest has been found previously ... if (extremum == lasthigh) { extremum = 0.0; } else { // // new last high ... lasthigh=extremum; // // discard extremum if current high is too low ... if (extremum - high[i] > deviation * Point) { extremum = 0.0; } else { // // clear previous extremums in backstep bars ... for(back = 1; back <= backStep; back++) { // pos = i + back; // if (highBuffer[pos] != 0 && highBuffer[pos] < extremum) { highBuffer[pos] = 0.0; } } } } // // found extremum is current high ... if (high[i] == extremum) { highBuffer[i] = extremum; } else { highBuffer[i] = 0.0; } } // // final cutting ... if( whatlookfor == 0) { // lastlow = 0.0; lasthigh = 0.0; } else { // lastlow = curlow; lasthigh = curhigh; } // for(i = limit; i >= 0; i--) { switch(whatlookfor) { // // look for peak or lawn ... case 0: // if (lastlow == 0.0 && lasthigh == 0.0) { if(highBuffer[i]!=0.0) { // lasthigh = High[i]; lasthighpos = i; whatlookfor = -1; // zigzagBuffer[i] = lasthigh; } // if(lowBuffer[i] != 0.0) { // lastlow = Low[i]; lastlowpos = i; whatlookfor = 1; // zigzagBuffer[i] = lastlow; } } break; // // look for peak ... case 1: // if ( lowBuffer[i] != 0.0 && lowBuffer[i] < lastlow && highBuffer[i] == 0.0 ) { // zigzagBuffer[lastlowpos] = 0.0; lastlowpos = i; lastlow = lowBuffer[i]; zigzagBuffer[i] = lastlow; } // if(highBuffer[i] != 0.0 && lowBuffer[i] == 0.0) { // lasthigh = highBuffer[i]; lasthighpos = i; zigzagBuffer[i] = lasthigh; // whatlookfor=-1; } break; // // look for lawn ... case -1: // if( highBuffer[i] != 0.0 && highBuffer[i] > lasthigh && lowBuffer[i] == 0.0 ) { // zigzagBuffer[lasthighpos] = 0.0; lasthighpos = i; lasthigh = highBuffer[i]; zigzagBuffer[i] = lasthigh; } // if( lowBuffer[i] !=0.0 && highBuffer[i] == 0.0 ) { // lastlow = lowBuffer[i]; lastlowpos = i; zigzagBuffer[i] = lastlow; whatlookfor=1; } break; } } // // Done ... return rates_total; } // // De Initialization ... void OnDeinit(const int reason) { // // RemoveDraws(signalPrefix); ChartRedraw(0); } // // END Event Handlers ... // // // START Functions ... // int InitializeBuffers() { // ArrayInitialize(lowBuffer,0.0); ArrayInitialize(highBuffer, 0.0); ArrayInitialize(zigzagBuffer, 0.0); // //--- first counting position return(Bars - depth); } // // END Functions ... //