Z-Score Heikin-Ashi Transformed calculation and ploting problem

 

Hello,
I found an interesting indicator on Trading View - Z-Score Heikin-Ashi Transformed by EliCobra (tradingview.com/script/MFW8vsmU-Z-Score-Heikin-Ashi-Transformed)

I am trying to create it MQL5 and I think I am almost done but at the end of the day it fails. 
Plotting regular HeikinAshi on the window works fine, but when I try to pass it trough Z-Score function I am facing issues. I have no idea how to pass price through that function and get a Z-Score transformed value. 


A snippet of PineScrip function I am referring to:

f_z(float src, simple int len) =>

    (src - ta.sma(src, len)) / ta.stdev(src, len)

method z(bar b, simple int len) =>
    bar x = bar.new(
         f_z(b.o, len),
         f_z(b.h, len),
         f_z(b.l, len),
         f_z(b.c, len))

    x

Where b.o => price of bar open / b.h => price of bar high ect. len => Z-Score length


And mine attempt to recreate it in MQL5:

double f_z(ENUM_APPLIED_PRICE src, int len) {   
    double sma = iMA(_Symbol, PERIOD_CURRENT, len, 0, MODE_SMA, src);
    Print("SMA: ", sma);
    double stdev = iStdDev(_Symbol, PERIOD_CURRENT, len, 0, MODE_SMA, src);
    Print("StdDev: ", stdev);
    double math = (src - sma) / stdev;
    Print("Math: ", math);
    return math;
}

Print for debug 


And the full code here:

//--- indicator settings
#property indicator_separate_window

//#property indicator_minimum -4	
//it should fit in the -4.0 | 4.0 window at the end of the day 
//#property indicator_maximum 4

//#property indicator_level1 -4
//#property indicator_level2 -3
//#property indicator_level3 -2
//#property indicator_level4 0
//#property indicator_level5 2
//#property indicator_level6 3
//#property indicator_level7 4



#property indicator_buffers 8
#property indicator_plots   1
#property indicator_type1   DRAW_COLOR_CANDLES
#property indicator_color1  clrWhite, clrTurquoise
#property indicator_label1  "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close"

//--- indicator buffers
double ExtOBuffer[];
double ExtHBuffer[];
double ExtLBuffer[];
double ExtCBuffer[];

double DevOBuffer[];
double DevHBuffer[];
double DevLBuffer[];
double DevCBuffer[];
double ExtColorBuffer[];

//--- Z-Score length
input int Z_Period = 21;


void OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtOBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(1,ExtHBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,ExtLBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,ExtCBuffer,INDICATOR_CALCULATIONS);
   
   
   SetIndexBuffer(4,DevOBuffer,INDICATOR_DATA);
   SetIndexBuffer(5,DevHBuffer,INDICATOR_DATA);
   SetIndexBuffer(6,DevLBuffer,INDICATOR_DATA);
   SetIndexBuffer(7,DevCBuffer,INDICATOR_DATA);
   
   SetIndexBuffer(8,ExtColorBuffer,INDICATOR_COLOR_INDEX);


   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);

   IndicatorSetString(INDICATOR_SHORTNAME,"Heiken Ashi");

  }
//+------------------------------------------------------------------+
//| Heiken Ashi                                                      |
//+------------------------------------------------------------------+


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 &TickVolume[],
                const long &Volume[],
                const int &Spread[])
  {
   int i,limit;
   if(prev_calculated==0)
     {
      ExtLBuffer[0]=Low[0];
      ExtHBuffer[0]=High[0];
      ExtOBuffer[0]=Open[0];
      ExtCBuffer[0]=Close[0];
      limit=1;
     }
   else
      limit=prev_calculated-1;

//--- main loop
   for(i=limit;i<rates_total && !IsStopped();i++)
     {
      double haOpen=(ExtOBuffer[i-1]+ExtCBuffer[i-1])/2;
      double haClose=(Open[i]+High[i]+Low[i]+Close[i])/4;
      double haHigh=MathMax(High[i],MathMax(haOpen,haClose));
      double haLow=MathMin(Low[i],MathMin(haOpen,haClose));

      ExtOBuffer[i]=haOpen;
      ExtHBuffer[i]=haHigh;
      ExtLBuffer[i]=haLow;
      ExtCBuffer[i]=haClose;

	//Here the regular Heikin Ashi functionality ends


      //Here I am trying to assign new values to new buffers in order to create new Heikin Ashi chart 

      DevOBuffer[i] = f_z(PRICE_OPEN, Z_Period);
      DevHBuffer[i] = f_z(PRICE_HIGH, Z_Period);
      DevLBuffer[i] = f_z(PRICE_LOW, Z_Period);
      DevCBuffer[i] = f_z(PRICE_CLOSE, Z_Period);

      if(haOpen<haClose)
         ExtColorBuffer[i]=0;
      else
         ExtColorBuffer[i]=1;
     }

   return(rates_total);
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+


double f_z(ENUM_APPLIED_PRICE src, int len) {   
    double sma = iMA(_Symbol, PERIOD_CURRENT, len, 0, MODE_SMA, src);
    Print("SMA: ", sma);
    double stdev = iStdDev(_Symbol, PERIOD_CURRENT, len, 0, MODE_SMA, src);
    Print("StdDev: ", stdev);
    double math = (src - sma) / stdev;
    Print("Math: ", math);
    return math;
}




void OnDeinit(const int reason){
   Comment("");
}


I also think the f_z function math is a bit odd because in comparison to TradingView the value difference is pretty big  eg. -0.7 in MT5 to 0.4 in TradingView and that's not because of differences in quotes - those are close to 0.

I am pretty sure I am missing something small here.

I would be extremely grateful for some fresh look at my code and any suggestions. I am loosing my mind because of that issue haha

 
Smerf16:

Hello,
I found an interesting indicator on Trading View - Z-Score Heikin-Ashi Transformed by EliCobra (tradingview.com/script/MFW8vsmU-Z-Score-Heikin-Ashi-Transformed)

I am trying to create it MQL5 and I think I am almost done but at the end of the day it fails. 
Plotting regular HeikinAshi on the window works fine, but when I try to pass it trough Z-Score function I am facing issues. I have no idea how to pass price through that function and get a Z-Score transformed value. 


A snippet of PineScrip function I am referring to:


And mine attempt to recreate it in MQL5:


And the full code here:


I also think the f_z function math is a bit odd because in comparison to TradingView the value difference is pretty big  eg. -0.7 in MT5 to 0.4 in TradingView and that's not because of differences in quotes - those are close to 0.

I am pretty sure I am missing something small here.

I would be extremely grateful for some fresh look at my code and any suggestions. I am loosing my mind because of that issue haha

double f_z(ENUM_APPLIED_PRICE src, int len) {   
    double sma = iMA(_Symbol, PERIOD_CURRENT, len, 0, MODE_SMA, src);
    Print("SMA: ", sma);
    double stdev = iStdDev(_Symbol, PERIOD_CURRENT, len, 0, MODE_SMA, src);
    Print("StdDev: ", stdev);
    double math = (src - sma) / stdev;
    Print("Math: ", math);
    return math;
}

The iMA function is incorrect, and should also be called only once, in the OnInit() function ( iMA - Technical Indicators - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5 )- it returns a handle for use with  CopyBuffer() to read the indicator values. 

Documentation on MQL5: Technical Indicators / iMA
Documentation on MQL5: Technical Indicators / iMA
  • www.mql5.com
The function returns the handle of the Moving Average indicator. It has only one buffer. Parameters symbol [in] The symbol name of the security...
 
ceejay1962 #:

The iMA function is incorrect, and should also be called only once, in the OnInit() function ( iMA - Technical Indicators - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5 )- it returns a handle for use with  CopyBuffer() to read the indicator values. 

You are the king. Thank You, That was it