Could you please help me convert this pine script to mql4? Some of this like NZ function is very complex to me.
- ATR like trading view in MT5
- need Help to Convert Pine Script into MQL4 language
- need help to convert pine script indicator to MQL4
double atr = 0.1 * NormalizeDouble(iATR(NULL, 0, 2, 1), Digits);
double atr_ma = iMA(NULL, 0, 20, 0, MODE_EMA, PRICE_CLOSE, 1);
double m = (High[1] + Low[1]) / 2;
Here you go
#property strict #property indicator_separate_window #property indicator_buffers 4 #property indicator_plots 1 //--- plot Label1 #property indicator_label1 "formula" #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 input int atr_period=2;//Atr Period input int atr_ema_period=20;//Ema Atr Period //--- indicator buffers double formula[],atr[],atrEma[],m[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int deflekt=0; int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,formula); SetIndexBuffer(1,atr);SetIndexStyle(1,DRAW_NONE,EMPTY,EMPTY,clrNONE); SetIndexBuffer(2,atrEma);SetIndexStyle(2,DRAW_NONE,EMPTY,EMPTY,clrNONE); SetIndexBuffer(3,m);SetIndexStyle(3,DRAW_NONE,EMPTY,EMPTY,clrNONE); deflekt=(int)MathMax(atr_ema_period,atr_period); //--- return(INIT_SUCCEEDED); } void reset(){ ArrayFill(formula,0,ArraySize(formula),0.0); ArrayFill(atr,0,ArraySize(atr),0.0); } //+------------------------------------------------------------------+ //| 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 calcs=rates_total-prev_calculated; int from=calcs; int bottom=rates_total-deflekt*2; if(from>deflekt){ reset(); from=bottom; } for(int i=from;i>=0;i--) { //atr = 0.1 * nz(ta.atr(2)[1], ta.atr(2)) /* if Not A Number it is replaced with the current atr otherwise use the previous atr But we have taken care of that by starting after 2 times the deflekt value so its hard to get an empty value so , just get the atr */ atr[i]=0.1*iATR(_Symbol,_Period,atr_period,i); //atr_ma = ta.ema(atr, 20) /* we are using an ema on the atr buffer , we need to start when we have atr_ema_period amount of atr stored so : */ if(i<=(bottom-atr_ema_period)){ atrEma[i]=maOnArray(atr,i,atr_ema_period,ma_ema,true,(bottom-atr_ema_period)-i,atrEma[i+1]); } //m = (ta.highest(2) + ta.lowest(2)) / 2 /* the highest and lowest of the 2 last bars by 2 */ m[i]=(MathMax(High[i],High[i+1])+MathMin(Low[i],Low[i+1]))/2.0; //what you want to plot was not clear but these are the calcuations for the components. //if you want to use them in a formula use the [i] index alongside them //example : formula[i]=m[i]*atrEma[i]*atr[i];//this is an example i don't know what you wanted to do with these buffers } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ /* ma of array */ enum ma_method{ ma_sma=0,//sma ma_ema=1,//ema ma_smma=2,//smma ma_lwma=3//lwma }; double maOnArray(const double &which_array[], int where,//start from where int period, ma_method mode, bool is_series, int calc_index,//this measures which calculation this is starting from 0 double previous_ma){//and this receives the previous value double result=0.0; //starting point int from=0; int step=0; int until=where; if(!is_series){ from=where-period+1; step=1; } else{ from=where+period-1; step=-1; } if(until>=0&&until<ArraySize(which_array)&&from>=0&&from<ArraySize(which_array)){ //sma or first ema or first smma if(mode==ma_sma||(mode==ma_ema&&calc_index==0)||(mode==ma_smma&&calc_index==0)){ int i=from-step; while(i!=until) { i+=step; result+=which_array[i]; } result/=((double)period); } //ema non first else if(mode==ma_ema){ double w=2.00/((double)period+1.0); result=which_array[until]*w+previous_ma*(1-w); } //smma non first else if(mode==ma_smma){ result=((previous_ma*((double)period))-previous_ma+which_array[until])/((double)period); } //lwma else if(mode==ma_lwma){ int i=from-step; double divider=0.0; int weight=0.0; while(i!=until) { i+=step; weight+=1.0; result+=which_array[i]*weight; divider+=weight; } result/=divider; } } return(result); }
it's great Lorentzos! Can I msg you privately?
this is the whole calculations: (for your question that what i want to do with this)
it's great Lorentzos! Can I msg you privately?
this is the whole calculations: (for your question that what i want to do with this)
i see , what is src ?
Edit : i assume it can only be price so here goes :
#property copyright "GO TO DISCUSSION" #property link "https://www.mql5.com/en/forum/439178" #property strict #property indicator_separate_window #property indicator_buffers 4 #property indicator_plots 1 //--- plot Label1 #property indicator_label1 "formula" #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 input int atr_period=2;//Atr Period input int atr_ema_period=20;//Ema Atr Period input double f=0.1;//coefficient input ENUM_APPLIED_PRICE source_price=PRICE_CLOSE;//source price //--- indicator buffers double formula[],atr[],atrEma[],m[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int deflekt=0; int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,formula); SetIndexBuffer(1,atr);SetIndexStyle(1,DRAW_NONE,EMPTY,EMPTY,clrNONE); SetIndexBuffer(2,atrEma);SetIndexStyle(2,DRAW_NONE,EMPTY,EMPTY,clrNONE); SetIndexBuffer(3,m);SetIndexStyle(3,DRAW_NONE,EMPTY,EMPTY,clrNONE); deflekt=(int)MathMax(atr_ema_period,atr_period); //--- return(INIT_SUCCEEDED); } void reset(){ ArrayFill(formula,0,ArraySize(formula),0.0); ArrayFill(atr,0,ArraySize(atr),0.0); } //+------------------------------------------------------------------+ //| 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 calcs=rates_total-prev_calculated; int from=calcs; int bottom=rates_total-deflekt*2; if(from>deflekt){ reset(); from=bottom; } for(int i=from;i>=0;i--) { //atr = 0.1 * nz(ta.atr(2)[1], ta.atr(2)) /* if Not A Number it is replaced with the current atr otherwise use the previous atr But we have taken care of that by starting after 2 times the deflekt value so its hard to get an empty value so , just get the atr */ atr[i]=f*iATR(_Symbol,_Period,atr_period,i); //atr_ma = ta.ema(atr, 20) /* we are using an ema on the atr buffer , we need to start when we have atr_ema_period amount of atr stored so : */ if(i<=(bottom-atr_ema_period)){ atrEma[i]=maOnArray(atr,i,atr_ema_period,ma_ema,true,(bottom-atr_ema_period)-i,atrEma[i+1]); } //m = (ta.highest(2) + ta.lowest(2)) / 2 /* the highest and lowest of the 2 last bars by 2 */ m[i]=(MathMax(High[i],High[i+1])+MathMin(Low[i],Low[i+1]))/2.0; //what you want to plot was not clear but these are the calcuations for the components. //if you want to use them in a formula use the [i] index alongside them //example : //formula[i]=m[i]*atrEma[i]*atr[i];//this is an example i don't know what you wanted to do with these buffers double src=get_price(Open[i],High[i],Low[i],Close[i],source_price); formula[i]=(src>m[i]+2.0*atr[i])?m[i]+atr[i]:(src<m[i]-2.0*atr[i])?m[i]-atr[i]:m[i]; } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //get price double get_price(double o,double h,double l,double c,ENUM_APPLIED_PRICE _src_price){ if(_src_price==PRICE_CLOSE){return(c);} else if(_src_price==PRICE_HIGH){return(h);} else if(_src_price==PRICE_LOW){return(l);} else if(_src_price==PRICE_MEDIAN){return((h+l)/2.00);} else if(_src_price==PRICE_OPEN){return(o);} else if(_src_price==PRICE_TYPICAL){return((h+l+c)/3.0);} else if(_src_price==PRICE_WEIGHTED){return((h+l+c+c)/4.0);} return(0.0); } /* ma of array */ enum ma_method{ ma_sma=0,//sma ma_ema=1,//ema ma_smma=2,//smma ma_lwma=3//lwma }; double maOnArray(const double &which_array[], int where,//start from where int period, ma_method mode, bool is_series, int calc_index,//this measures which calculation this is starting from 0 double previous_ma){//and this receives the previous value double result=0.0; //starting point int from=0; int step=0; int until=where; if(!is_series){ from=where-period+1; step=1; } else{ from=where+period-1; step=-1; } if(until>=0&&until<ArraySize(which_array)&&from>=0&&from<ArraySize(which_array)){ //sma or first ema or first smma if(mode==ma_sma||(mode==ma_ema&&calc_index==0)||(mode==ma_smma&&calc_index==0)){ int i=from-step; while(i!=until) { i+=step; result+=which_array[i]; } result/=((double)period); } //ema non first else if(mode==ma_ema){ double w=2.00/((double)period+1.0); result=which_array[until]*w+previous_ma*(1-w); } //smma non first else if(mode==ma_smma){ result=((previous_ma*((double)period))-previous_ma+which_array[until])/((double)period); } //lwma else if(mode==ma_lwma){ int i=from-step; double divider=0.0; int weight=0.0; while(i!=until) { i+=step; weight+=1.0; result+=which_array[i]*weight; divider+=weight; } result/=divider; } } return(result); }
We can make it a little more difficult😄
Once upon a time, I converted the indicator from pinescript to MT4. I'm not good at formulas for calculating technical indicators. Therefore, I did as written in the documentation of the pinescript. As a result, the ATR values did not match the values of the built-in atr in MT4:
Most likely, a different averaging is used in MT4
In the end, this
ta.atr
is what I turned into this😄
#property strict #property indicator_separate_window #property indicator_buffers 1 #property indicator_label1 "pine_atr" #property indicator_type1 DRAW_LINE #property indicator_color1 clrDodgerBlue input int inpAtrLength = 14; // Length double tr[]; double atr[]; int OnInit() { IndicatorShortName(StringFormat("pine_atr(%i)", inpAtrLength)); int buffersNumber = 2; IndicatorBuffers(buffersNumber); SetIndexBuffer(0, atr); SetIndexBuffer(1, tr); for(int i = 0; i < buffersNumber; i++) SetIndexEmptyValue(i, EMPTY_VALUE); 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[]) { pine_buffer_tr(tr, high, low, close, rates_total, prev_calculated); pine_buffer_atr(inpAtrLength, atr, tr, rates_total, prev_calculated); return(rates_total); } void pine_buffer_atr(int period, double &buffer[], const double &tr_data[], int rates_total, int prev_calculated) // Different from the built-in MT4 ATR. Most likely, a different averaging is used in MT4 { pine_buffer_rma(buffer, tr_data, period, rates_total, prev_calculated, 1); } void pine_buffer_rma(double &buffer[], const double &source[], int period, int rates_total, int prev_calculated, int sourceBeginOffset = 0) { for(int i = bufferCalculFrom(rates_total, prev_calculated, period, sourceBeginOffset); i >= 0; i--) buffer[i] = pine_rma(source, period, i, buffer[i+1]); } double pine_rma(const double &source[], int length, int bar, double prevValue = EMPTY_VALUE) { double alpha = 1.0 / length; return(prevValue == EMPTY_VALUE ? pine_sma(source, length, bar) : alpha * source[bar] + (1.0 - alpha) * prevValue); } double pine_sma(const double &source[], int period, int bar) { double sum = 0.0; for(int i = 0; i <= period - 1; i++) sum += source[bar + i] / period; return(sum); } void pine_buffer_tr(double &buffer[], const double &high[], const double &low[], const double &close[], int rates_total, int prev_calculated) { for(int i = bufferCalculFrom(rates_total, prev_calculated, 2, 0); i >= 0; i--) buffer[i] = pine_tr(high[i], low[i], close[i + 1]); } double pine_tr(double high, double low, double prevClose) { return(MathMax(high - low, MathMax(MathAbs(high - prevClose), MathAbs(low - prevClose)))); } int bufferCalculFrom(int rates_total, int prev_calculated, int period, int sourceBeginOffset) { int notCalculated = rates_total - prev_calculated; int lastIndex = rates_total - 1; return((notCalculated == 0 || notCalculated == 1) ? notCalculated : (lastIndex - (period - 1)) - sourceBeginOffset); }
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use