Could you please help me convert this pine script to mql4? Some of this like NZ function is very complex to me.

 
atr = 0.1 * nz(ta.atr(2)[1], ta.atr(2))
atr_ma = ta.ema(atr, 20)
m = (ta.highest(2) + ta.lowest(2)) / 2
 
Help with what? You stated a want, show your try
 
Runny Picasso:
atr = 0.1 * nz(ta.atr(2)[1], ta.atr(2))
atr_ma = ta.ema(atr, 20)
m = (ta.highest(2) + ta.lowest(2)) / 2

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;

 
Runny Picasso:
atr = 0.1 * nz(ta.atr(2)[1], ta.atr(2))
atr_ma = ta.ema(atr, 20)
m = (ta.highest(2) + ta.lowest(2)) / 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);
}
 
Daniel Cioca #:

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;


Thank you Daniel!

 
Lorentzos Roussos #:

Here you go 

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)



// Calculations
atr = f * nz(ta.atr(p2)[1], ta.atr(p2))
atr_ma = ta.ema(atr, 20)
m = (ta.highest(p1) + ta.lowest(p1)) / 2
trend = m
trend := src > nz(trend[1], m) + 2 * atr ? nz(trend[1], m) + atr : src < nz(trend[1], m) - 2 * atr ? nz(trend[1], m) - atr : nz(trend[1], m)
 
Runny Picasso #:

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)



// Calculations
atr = f * nz(ta.atr(p2)[1], ta.atr(p2))
atr_ma = ta.ema(atr, 20)
m = (ta.highest(p1) + ta.lowest(p1)) / 2
trend = m
trend := src > nz(trend[1], m) + 2 * atr ? nz(trend[1], m) + atr : src < nz(trend[1], m) - 2 * atr ? nz(trend[1], m) - atr : nz(trend[1], m)

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);
}
 
Lorentzos Roussos #:

i see , what is src ? 

Edit : i assume it can only be price so here goes : 

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

 
Vladislav Boyko #:

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);
  }
 
Lorentzos Roussos #:

i see , what is src ? 

Edit : i assume it can only be price so here goes : 

I'm not asking you to change your code. I just told my story of acquaintance with the ATR 😄

 
Ridouan Tarnich #:
No

This is not an example of how to do it. It's just my funny story :)

Reason: