//+------------------------------------------------------------------+ //| Swing Indicator.mq4 | //| Copyright 2022, Filip Valkovic | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2022, Filip Valkovic" #property link "https://www.mql5.com/en/users/f4ge113/seller" #property description "Order your EA/tool at https://www.fiverr.com/xraiderstudios" #property version "1.20" #property strict #property indicator_chart_window #property indicator_buffers 2 #property indicator_plots 2 //--- plot top #property indicator_label1 "top" #property indicator_type1 DRAW_ARROW #property indicator_color1 clrWhite #property indicator_style1 STYLE_SOLID #property indicator_width1 4 //--- plot bot #property indicator_label2 "bot" #property indicator_type2 DRAW_ARROW #property indicator_color2 clrWhite #property indicator_style2 STYLE_SOLID #property indicator_width2 4 //--- input parameters input int iindex=25; //barsback input int pips=80; // Signal_Points_offset //input bool notify=false; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ datetime lastalert=TimeCurrent(); //--- indicator buffers double topBuffer[]; double botBuffer[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,topBuffer); SetIndexBuffer(1,botBuffer); //--- setting a code from the Wingdings charset as the property of PLOT_ARROW SetIndexArrow(0,159); SetIndexArrow(1,159); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[]) { //--- /* int index = iindex/2; int lookleft=index; int lookright=index; int mb=lookleft+lookright+1;*/ int i=rates_total-prev_calculated-1+iindex; if(i>=rates_total-1) i=rates_total-iindex-1; if(i<0) i=0; for(; i>=0 && !IsStopped(); i--) { if(i+(iindex*2) - 1>rates_total-1) continue; bool swing_high = false; bool swing_low = false; swing_detection(high,low,iindex,swing_high,swing_low,i); if(swing_high) { topBuffer[i+iindex]=high[i+iindex]+pips*Point; } if(swing_low) { botBuffer[i+iindex]=low[i+iindex]-pips*Point; } /* int hindex=LocalExtremeBar(high,low,mb,i-lookleft,1); int lindex=LocalExtremeBar(high,low,mb,i-lookleft,-1); if(high[i]==high[hindex] && topBuffer[i+1]==EMPTY_VALUE) { topBuffer[i]=high[hindex]+pips*Point; if(notify && lastalert swing_point_high) { swing_high= false; break; } } // Have to do checks before pivot and after seperately because we can get // two highs of the same value in a row. Notice the > and >= difference if(i > index) { if(high[i+pos] >= swing_point_high) { swing_high = false; break; } } } for(int i = 0; i < sstart; i++) { swing_low = true; if(i < index) { if(low[i+pos] < swing_point_low) { swing_low= false; break; } } // Have to do checks before pivot and after seperately because we can get // two highs of the same value in a row. Notice the > and >= difference if(i > index) { if(low[i+pos] <= swing_point_low) { swing_low = false; break; } } } return swing_high+swing_low; } //+------------------------------------------------------------------+ int LocalExtremeBar(const double &hi[],const double &lo[],int length, int start, double d) // d=direction= +1 HIGH or -1 LOW { if(d > 0) return(LocalExtremeArray(hi, length, start, d)); return(LocalExtremeArray(lo, length, start, d)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int LocalExtremeArray(const double &arr[], int length, int iStart, double d) { while(true) { int iPrev = iStart; iStart = ArrayExtrema(arr, length, iStart, d); if(iStart == iPrev) return iStart; } //NOTREACHED } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int ArrayExtrema(double const &arr[], int length, int iStart, double d) { int iExtreme = iStart; double value = arr[iExtreme]; int iLimit = MathMin(iStart + length, ArraySize(arr)); for(iStart++; iStart= 0.) { iExtreme = iStart; value = arr[iExtreme]; } // largest index (>=) return iExtreme; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+