as far as my issue goes, I'm trying to calculate the ATR of MACD, the only number I need is the last ATR of MACD for period of 14 bars.
I tried this code but it's not working (the code does not draw any line for ATR[0]):
void CalculateIndicator(int countedBars) { for(int i=countedBars; i>=0; i--) { CalculateMACD(i); CatchBullishDivergence(i+2,countedBars); CatchBearishDivergence(i+2,countedBars); } } 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 counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; int limit=Bars-counted_bars; if(counted_bars==0) limit-=1+MathMax(i_fastEMA,i_slowEMA); CalculateIndicator(limit); int i; limit = 0; if(prev_calculated==0) { ExtTRBuffer[0]=0.0; ExtATRBuffer[0]=0.0; //--- filling out the array of True Range values for each period for(i=1; i<rates_total; i++) ExtTRBuffer[i]=MathMax(ArrayMaximum(MACDLineBuffer, 14, i),MACDLineBuffer[i-1])-MathMin(ArrayMinimum(MACDLineBuffer, 14, i),MACDLineBuffer[i-1]); //--- first AtrPeriod values of the indicator are not calculated double firstValue=0.0; for(i=1; i<=InpAtrPeriod; i++) { ExtATRBuffer[i]=0.0; firstValue+=ExtTRBuffer[i]; } //--- calculating the first value of the indicator firstValue/=InpAtrPeriod; ExtATRBuffer[InpAtrPeriod]=firstValue; limit=InpAtrPeriod+1; } else limit=prev_calculated-1; //--- the main loop of calculations for(i=limit; i<rates_total; i++) { ExtTRBuffer[i]=MathMax(ArrayMaximum(MACDLineBuffer, 14, i),MACDLineBuffer[i-1])-MathMin(ArrayMinimum(MACDLineBuffer, 14, i),MACDLineBuffer[i-1]); ExtATRBuffer[i]=ExtATRBuffer[i-1]+(ExtTRBuffer[i]-ExtTRBuffer[i-InpAtrPeriod])/InpAtrPeriod; } int indicatorWindow=WindowFind(indicatorName); if(indicatorWindow<0) return; string label="MACD_TEST"; ObjectDelete(label); ObjectCreate(label,OBJ_TREND,indicatorWindow,Time[0] + PeriodSeconds(PERIOD_CURRENT),ExtATRBuffer[0],Time[0] + 25 * PeriodSeconds(PERIOD_CURRENT),ExtATRBuffer[0],0,0); ObjectSet(label,OBJPROP_RAY,0); ObjectSet(label,OBJPROP_COLOR,clrChartreuse); ObjectSet(label,OBJPROP_STYLE,STYLE_DOT); ObjectSet(label,OBJPROP_HIDDEN,true); ObjectSet(label,OBJPROP_XOFFSET, 15); return(rates_total); } void CalculateMACD(int i) { MACDLineBuffer[i]=iMACD(NULL,0,i_fastEMA,i_slowEMA,i_signalMA,PRICE_CLOSE,MODE_MAIN,i); ExtSignalBuffer[i]=iMAOnArray(MACDLineBuffer,Bars,i_signalMA,0,MODE_SMA,i); ExtHistoryBuffer[i]=MACDLineBuffer[i] - ExtSignalBuffer[i]; MACDDiv[i]=MACDLineBuffer[i]; }
Can anyone help me find what is the problem here?
OK, made some progress.
Not sure why it's not working on the last stage. first the whole code :
//+------------------------------------------------------------------+ //| Custom MACD.mq4 | //| Copyright 2005-2014, MetaQuotes Software Corp. | //| http://www.mql4.com | //+------------------------------------------------------------------+ #property copyright "2005-2014, Traderset." #property link "http://www.traderset.ir" #property description "MACD + Divergence" #property strict //--- indicator settings #property indicator_separate_window #property indicator_buffers 8 //#property indicator_buffers 7 #property indicator_color4 clrLimeGreen #property indicator_color5 clrRed #property indicator_width1 1 #property indicator_width2 1 #property indicator_width3 1 #property indicator_width4 2 #property indicator_width5 2 #include <MovingAverages.mqh> #define arrowsDisplacement 0.0001 //--- indicator parameters extern int i_fastEMA=12; //Fast EMA Period extern int i_slowEMA=26; //Slow EMA Period extern int i_signalMA=9; //Signal SMA Period extern int InpAtrPeriod=14; //ATR Period extern color ColorBull = clrChartreuse; //Bullish Divergence Color extern color ColorBear = clrChocolate; //Bearish Divergence Color extern color MACDLineColor = clrTurquoise; //MACD Line Color extern color SignalLineColor = clrMagenta; //Signal Line Color extern color HistogramColor = clrMediumBlue; //Histogram Color extern color ATRColor = clrYellow; //ATR Band Color extern color ATR15Color = clrMaroon; //Upped ATR*1.5 Color extern color ATR15NColor = clrDarkGreen; //Lower ATR*1.5 Color extern bool displayAlert=false; //Display Alerts extern bool English=true; //Use English for Alert extern bool DrawPriceLines=true; //Draw Price Line extern bool DrawArrows=true; //Draw Divergence Arrows extern bool drawDivergenceLines=true; //Draw Divergence Lines //--- indicator buffers double MACDLineBuffer[]; double ExtSignalBuffer[]; double ExtHistoryBuffer[]; double bullishDivergence[]; double bearishDivergence[]; double MACDDiv[]; double ExtATRBuffer[]; double ExtTRBuffer[]; static datetime lastAlertTime; static string indicatorName; static bool b_first=true; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit(void) { IndicatorDigits(Digits+2); //--- drawing settings SetIndexDrawBegin(1,i_signalMA); //--- indicator buffers mapping SetIndexBuffer(0,ExtHistoryBuffer); SetIndexStyle(0,DRAW_HISTOGRAM, STYLE_SOLID,1, HistogramColor); SetIndexLabel(0,"Histogram"); SetIndexBuffer(1,ExtSignalBuffer); SetIndexStyle(1,DRAW_LINE, STYLE_SOLID,1, SignalLineColor); SetIndexLabel(1,"Signal"); SetIndexBuffer(2,MACDLineBuffer); SetIndexStyle(2,DRAW_LINE, STYLE_SOLID,1, MACDLineColor); SetIndexLabel(2,"MACD"); SetIndexBuffer(3,bullishDivergence); SetIndexStyle(3,DRAW_ARROW,STYLE_SOLID,0); SetIndexLabel(3,"Bullish"); SetIndexBuffer(4,bearishDivergence); SetIndexStyle(4,DRAW_ARROW,STYLE_SOLID,0); SetIndexLabel(4,"Bearish"); SetIndexBuffer(5,MACDDiv); SetIndexStyle(5,DRAW_NONE); SetIndexBuffer(6,ExtATRBuffer); SetIndexStyle(6,DRAW_NONE); SetIndexBuffer(7,ExtTRBuffer); SetIndexStyle(7,DRAW_NONE); //SetIndexBuffer(6,ExtTRBuffer); //SetIndexStyle(6,DRAW_NONE); SetIndexArrow(1,233); SetIndexArrow(2,234); //--- name for DataWindow and indicator subwindow label IndicatorShortName("MACD - ATR - RSI"); indicatorName=("MACD - ATR - RSI"); //--- check for input parameters if(i_fastEMA<=1 || i_slowEMA<=1 || i_signalMA<=1 || i_fastEMA>=i_slowEMA || InpAtrPeriod <= 0) { Print("Wrong input parameters"); return(INIT_FAILED); } //--- initialization done return(INIT_SUCCEEDED); } int deinit() { //---- for(int i=ObjectsTotal()-1; i>=0; i--) { string label=ObjectName(i); if(StringSubstr(label,0,19)!="MACD_DivergenceLine" && StringSubstr(label,0,10)!="MACD_LEVEL") continue; ObjectDelete(label); } return(0); } 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 counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; int limit=Bars-counted_bars; if(counted_bars==0) limit-=1+MathMax(i_fastEMA,i_slowEMA); CalculateIndicator(limit); //ArraySetAsSeries(ExtTRBuffer, false); //ArraySetAsSeries(ExtATRBuffer, false); ExponentialMAOnBuffer(rates_total,prev_calculated,0,2 * InpAtrPeriod - 1,ExtTRBuffer,ExtATRBuffer); //SimpleMAOnBuffer(rates_total,prev_calculated,0,InpAtrPeriod,ExtTRBuffer,ExtATRBuffer); //Print(ExtATRBuffer[0]); int indicatorWindow=WindowFind(indicatorName); if(indicatorWindow<0) return(rates_total); string label; label="MACD_LEVEL_TR_UP"; ObjectDelete(label); ObjectCreate(label,OBJ_TREND,indicatorWindow,Time[0] + 11 * PeriodSeconds(PERIOD_CURRENT),ExtTRBuffer[0],Time[0] + 25 * PeriodSeconds(PERIOD_CURRENT),ExtTRBuffer[0],0,0); ObjectSet(label,OBJPROP_RAY,0); ObjectSet(label,OBJPROP_COLOR,ATRColor); ObjectSet(label,OBJPROP_STYLE,STYLE_DOT); ObjectSet(label,OBJPROP_HIDDEN,true); ObjectSet(label,OBJPROP_XOFFSET, 15); ObjectSet(label,OBJPROP_SELECTABLE,false); ObjectSet(label,OBJPROP_SELECTED,false); label="MACD_LEVEL_TR15_UP"; ObjectDelete(label); ObjectCreate(label,OBJ_TREND,indicatorWindow,Time[0] + 11 * PeriodSeconds(PERIOD_CURRENT),ExtTRBuffer[0] * 1.5,Time[0] + 25 * PeriodSeconds(PERIOD_CURRENT),ExtTRBuffer[0] * 1.5,0,0); ObjectSet(label,OBJPROP_RAY,0); ObjectSet(label,OBJPROP_COLOR,ATR15Color); ObjectSet(label,OBJPROP_STYLE,STYLE_DOT); ObjectSet(label,OBJPROP_HIDDEN,true); ObjectSet(label,OBJPROP_XOFFSET, 15); ObjectSet(label,OBJPROP_SELECTABLE,false); ObjectSet(label,OBJPROP_SELECTED,false); label="MACD_LEVEL_TR_DN"; ObjectDelete(label); ObjectCreate(label,OBJ_TREND,indicatorWindow,Time[0] + 11 * PeriodSeconds(PERIOD_CURRENT),-ExtTRBuffer[0],Time[0] + 25 * PeriodSeconds(PERIOD_CURRENT),-ExtTRBuffer[0],0,0); ObjectSet(label,OBJPROP_RAY,0); ObjectSet(label,OBJPROP_COLOR,ATRColor); ObjectSet(label,OBJPROP_STYLE,STYLE_DOT); ObjectSet(label,OBJPROP_HIDDEN,true); ObjectSet(label,OBJPROP_XOFFSET, 15); ObjectSet(label,OBJPROP_SELECTABLE,false); ObjectSet(label,OBJPROP_SELECTED,false); label="MACD_LEVEL_TR15_DN"; ObjectDelete(label); ObjectCreate(label,OBJ_TREND,indicatorWindow,Time[0] + 11 * PeriodSeconds(PERIOD_CURRENT),-ExtTRBuffer[0] * 1.5,Time[0] + 25 * PeriodSeconds(PERIOD_CURRENT),-ExtTRBuffer[0] * 1.5,0,0); ObjectSet(label,OBJPROP_RAY,0); ObjectSet(label,OBJPROP_COLOR,ATR15NColor); ObjectSet(label,OBJPROP_STYLE,STYLE_DOT); ObjectSet(label,OBJPROP_HIDDEN,true); ObjectSet(label,OBJPROP_XOFFSET, 15); ObjectSet(label,OBJPROP_SELECTABLE,false); ObjectSet(label,OBJPROP_SELECTED,false); label="MACD_LEVEL_SIGNAL"; ObjectDelete(label); ObjectCreate(label,OBJ_TREND,indicatorWindow,Time[0] + PeriodSeconds(PERIOD_CURRENT),ExtSignalBuffer[0],Time[0] + 10 * PeriodSeconds(PERIOD_CURRENT),ExtSignalBuffer[0],0,0); ObjectSet(label,OBJPROP_RAY,0); ObjectSet(label,OBJPROP_COLOR,SignalLineColor); ObjectSet(label,OBJPROP_STYLE,STYLE_DOT); ObjectSet(label,OBJPROP_HIDDEN,true); ObjectSet(label,OBJPROP_XOFFSET, 15); ObjectSet(label,OBJPROP_SELECTABLE,false); ObjectSet(label,OBJPROP_SELECTED,false); label="MACD_LEVEL_MACD"; ObjectDelete(label); ObjectCreate(label,OBJ_TREND,indicatorWindow,Time[0] + PeriodSeconds(PERIOD_CURRENT),MACDLineBuffer[0],Time[0] + 10 * PeriodSeconds(PERIOD_CURRENT),MACDLineBuffer[0],0,0); ObjectSet(label,OBJPROP_RAY,0); ObjectSet(label,OBJPROP_COLOR,MACDLineColor); ObjectSet(label,OBJPROP_STYLE,STYLE_DOT); ObjectSet(label,OBJPROP_HIDDEN,true); ObjectSet(label,OBJPROP_XOFFSET, 15); ObjectSet(label,OBJPROP_SELECTABLE,false); ObjectSet(label,OBJPROP_SELECTED,false); return(rates_total); } void CalculateIndicator(int countedBars) { for(int i=countedBars; i>=0; i--) { CalculateMACD(i); CatchBullishDivergence(i+2,countedBars); CatchBearishDivergence(i+2,countedBars); int minIndex = ArrayMinimum(MACDLineBuffer, InpAtrPeriod, i); int maxIndex = ArrayMaximum(MACDLineBuffer, InpAtrPeriod, i); if (i != 0) { ExtTRBuffer[i] = MathMax(MACDLineBuffer[maxIndex] - MACDLineBuffer[minIndex], MathAbs(MACDLineBuffer[maxIndex] - MACDLineBuffer[i - 1])); ExtTRBuffer[i] = MathMax(ExtTRBuffer[i], MathAbs(MACDLineBuffer[minIndex] - MACDLineBuffer[i - 1])); } else { ExtTRBuffer[i] = MathMax(MACDLineBuffer[maxIndex] - MACDLineBuffer[minIndex], MACDLineBuffer[maxIndex]); ExtTRBuffer[i] = MathMax(ExtTRBuffer[i], MACDLineBuffer[minIndex]); } } } void CalculateMACD(int i) { MACDLineBuffer[i]=iMACD(NULL,0,i_fastEMA,i_slowEMA,i_signalMA,PRICE_CLOSE,MODE_MAIN,i); ExtSignalBuffer[i]=iMAOnArray(MACDLineBuffer,Bars,i_signalMA,0,MODE_SMA,i); ExtHistoryBuffer[i]=MACDLineBuffer[i] - ExtSignalBuffer[i]; MACDDiv[i]=MACDLineBuffer[i]; } void CatchBullishDivergence(int shift,int maxind) { if(IsIndicatorTrough(shift)==false) return; int currentTrough=shift; int lastTrough=GetIndicatorLastTrough(shift,maxind); if(currentTrough==-1) return; if(lastTrough==-1) return; if(MACDDiv[currentTrough]>MACDDiv[lastTrough] && Low[currentTrough]<Low[lastTrough]) { bullishDivergence[currentTrough]=MACDDiv[currentTrough]; if(drawDivergenceLines==true) { DrawPriceTrendLine(Time[currentTrough],Time[lastTrough],Low[currentTrough], Low[lastTrough],Green,STYLE_SOLID); DrawIndicatorTrendLine(Time[currentTrough],Time[lastTrough],MACDDiv[currentTrough], MACDDiv[lastTrough],Green,STYLE_SOLID,drawDivergenceLines); } if(displayAlert==true) DisplayAlert("Classical bullish divergence on: ",currentTrough); } if(MACDDiv[currentTrough]<MACDDiv[lastTrough] && Low[currentTrough]>Low[lastTrough]) { bullishDivergence[currentTrough]=MACDDiv[currentTrough]; if(drawDivergenceLines==true) { DrawPriceTrendLine(Time[currentTrough],Time[lastTrough],Low[currentTrough], Low[lastTrough],Green,STYLE_DOT); DrawIndicatorTrendLine(Time[currentTrough],Time[lastTrough],MACDDiv[currentTrough], MACDDiv[lastTrough],Green,STYLE_DOT,drawDivergenceLines); } if(displayAlert==true) DisplayAlert("Reverse bullish divergence on: ",currentTrough); } } void CatchBearishDivergence(int shift,int maxind) { if(IsIndicatorPeak(shift)==false) return; int currentPeak=shift; int lastPeak=GetIndicatorLastPeak(shift,maxind); if(currentPeak==-1) return; if(lastPeak==-1) return; if(MACDDiv[currentPeak]<MACDDiv[lastPeak] && High[currentPeak]>High[lastPeak]) { bearishDivergence[currentPeak]=MACDDiv[currentPeak]; if(drawDivergenceLines==true) { DrawPriceTrendLine(Time[currentPeak],Time[lastPeak],High[currentPeak], High[lastPeak],Red,STYLE_SOLID); DrawIndicatorTrendLine(Time[currentPeak],Time[lastPeak],MACDDiv[currentPeak], MACDDiv[lastPeak],Red,STYLE_SOLID,drawDivergenceLines); } if(displayAlert==true) DisplayAlert("Classical bearish divergence on: ",currentPeak); } if(MACDDiv[currentPeak]>MACDDiv[lastPeak] && High[currentPeak]<High[lastPeak]) { bearishDivergence[currentPeak]=MACDDiv[currentPeak]; if(drawDivergenceLines==true) { DrawPriceTrendLine(Time[currentPeak],Time[lastPeak],High[currentPeak], High[lastPeak],Red,STYLE_DOT); DrawIndicatorTrendLine(Time[currentPeak],Time[lastPeak],MACDDiv[currentPeak], MACDDiv[lastPeak],Red,STYLE_DOT,drawDivergenceLines); } if(displayAlert==true) DisplayAlert("Reverse bearish divergence on: ",currentPeak); } } bool IsIndicatorPeak(int shift) { if(MACDDiv[shift]>=MACDDiv[shift+1] && MACDDiv[shift]>MACDDiv[shift+2] && MACDDiv[shift]>MACDDiv[shift-1]) return(true); else return(false); } bool IsIndicatorTrough(int shift) { if(MACDDiv[shift]<=MACDDiv[shift+1] && MACDDiv[shift]<MACDDiv[shift+2] && MACDDiv[shift]<MACDDiv[shift-1]) return(true); else return(false); } int GetIndicatorLastPeak(int shift,int maxind) { for(int i=shift+5; i<maxind-2; i++) { if(MACDLineBuffer[i] >= MACDLineBuffer[i+1] && MACDLineBuffer[i] >= MACDLineBuffer[i+2] && MACDLineBuffer[i] >= MACDLineBuffer[i-1] && MACDLineBuffer[i] >= MACDLineBuffer[i-2]) { for(int j=i; j<maxind-2; j++) { if(MACDDiv[j] >= MACDDiv[j+1] && MACDDiv[j] > MACDDiv[j+2] && MACDDiv[j] >= MACDDiv[j-1] && MACDDiv[j] > MACDDiv[j-2]) return(j); } } } return(-1); } int GetIndicatorLastTrough(int shift,int maxind) { for(int i=shift+5; i<maxind-2; i++) { if(MACDLineBuffer[i] <= MACDLineBuffer[i+1] && MACDLineBuffer[i] <= MACDLineBuffer[i+2] && MACDLineBuffer[i] <= MACDLineBuffer[i-1] && MACDLineBuffer[i] <= MACDLineBuffer[i-2]) { for(int j=i; j<maxind-2; j++) { if(MACDDiv[j] <= MACDDiv[j+1] && MACDDiv[j] < MACDDiv[j+2] && MACDDiv[j] <= MACDDiv[j-1] && MACDDiv[j] < MACDDiv[j-2]) return(j); } } } return(-1); } void DisplayAlert(string message,int shift) { if(shift<=2 && Time[shift]!=lastAlertTime) { lastAlertTime=Time[shift]; Alert(message,Symbol()," , ",s_GetPeriod(Period())); } } void DrawPriceTrendLine(datetime x1,datetime x2,double y1, double y2,color lineColor,double style) { string label="MACD_DivergenceLine.0# "+DoubleToStr(x1,0); ObjectDelete(label); ObjectCreate(label,OBJ_TREND,0,x1,y1,x2,y2,0,0); ObjectSet(label,OBJPROP_RAY,0); ObjectSet(label,OBJPROP_COLOR,lineColor); ObjectSet(label,OBJPROP_STYLE,style); ObjectSet(label,OBJPROP_HIDDEN,true); ObjectSet(label,OBJPROP_SELECTABLE,false); ObjectSet(label,OBJPROP_SELECTED,false); } void DrawIndicatorTrendLine(datetime x1,datetime x2,double y1, double y2,color lineColor,double style,bool ibullishDivergence) { int indicatorWindow=WindowFind(indicatorName); if(indicatorWindow<0) return; string label="MACD_DivergenceLine - "+DoubleToStr(x1,0); ObjectDelete(label); ObjectCreate(label,OBJ_TREND,indicatorWindow,x1,y1,x2,y2,0,0); ObjectSet(label,OBJPROP_RAY,0); ObjectSet(label,OBJPROP_COLOR,lineColor); ObjectSet(label,OBJPROP_STYLE,style); ObjectSet(label,OBJPROP_HIDDEN,true); ObjectSet(label,OBJPROP_SELECTABLE,false); ObjectSet(label,OBJPROP_SELECTED,false); } string s_isMACD() { for(int j=1; j<=24; j++) { for(int i=1; i<=44; i++) { for(int k=1; k<=24; k++) { if(WindowFind("MACD("+DoubleToStr(j,0)+","+DoubleToStr(i,0)+"," +DoubleToStr(k,0)+")")!=-1) return(DoubleToStr(j,0)+","+DoubleToStr(i,0) +","+DoubleToStr(k,0)); } } } return ""; } string s_GetPer(string s_stRoka,string s_razD,int i_pozPer) { string s_vrPer = s_stRoka + s_razD; string s_mnk1S = "", s_mnk1; int i_mnk = 0; for(int j = 0; j <= StringLen(s_vrPer)-1;j++) { s_mnk1=StringSubstr(s_vrPer,j,1); if(s_mnk1==s_razD) { i_mnk++; if(i_mnk<i_pozPer) s_mnk1S=""; } else { s_mnk1S=s_mnk1S+s_mnk1; } if(i_mnk==i_pozPer) return(s_mnk1S); } return ""; } string s_GetPeriod(int i_per) { switch(i_per) { case 1: return("M1 "); case 5: return("M5 "); case 15: return("M15"); case 30: return("M30"); case 60: return("H1 "); case 240: return("H4 "); case 1440: return("D1 "); case 10080: return("W1 "); case 43200: return("MN1"); } return ""; }
Now the problem, I am calculating the true range successfully. for ATR we need to get the RMA average (original formule) with is ..> rma(x, period) = ema(x, 2 * period -1)
Now, as you see, i'm trying to get the ema on this line of code here :
ExponentialMAOnBuffer(rates_total,prev_calculated,0,2 * InpAtrPeriod - 1,ExtTRBuffer,ExtATRBuffer);
At the next line I had a print command to get the result of last ExtATRBuffer that is calculated, funny thing : when all the numbers move between 40 to 0, how the hell the EMA result is billion?
2019.10.06 10:41:22.944 MACD BTCUSD,M1: 1861152497.823013
this makes no sense, can anyone help and tell me what did i do wrong?
PLEASE

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hi
I need someone to write two functions in mql4, they should take in a 1D array (for example let's say the values calculated for MACD), one function should calculate the RMA for the array and return the result array buffer, the other should do the same but for ATR.
I'm fairly new to mql4 and no matter how much i looked around, i can't figure these two, I know that I need RMA to calculate the ATR, so these two functions should work hand in hand, I prefer to have each calculation separated in a function so that I can keep a reference of them and use them in future.
Honestly, I'm well familiar with pinescript in tradingview and lack of many functions availability for things other than just the price series is hitting me hard in mql :( would be nice if someone sit and write a whole library of base functions like calculating macd, tsi, rma, atr, wma, ema and sma from array and not serries, I think mql has some internal headers for the sma and ema and wma, but for others i couldn't find anything.
thanks