How to get custom timeframe indicators working on MT5

 
I have this indicator on trading view that I'm trying to replicate on MT5 but it's like a dead end.

The trading view indicator works by plotting ALMA on the current timeframe and then going 8x the current timeframe to get the ALT ALMA values on the new obtained timeframe.

I'm super close (I think) on the MT5 side but they are not matching no matter what I do, here's the code for both platforms.

SO for M5 timeframe, the TradingView code goes to 8x5 = 40.

TradingView: 

mult   = input.int(8, "TF Multiplier")
len    = input.int(2, "ALMA Length")
sigma  = input.int(5)
offset = input.float(0.85)

// BASE ALMA
closeMA = ta.alma(close, len, offset, sigma)
openMA  = ta.alma(open,  len, offset, sigma)

// ALT TIMEFRAME
tf = str.tostring(timeframe.multiplier * mult)

//label.new(bar_index, high, tf)

closeAlt = request.security(syminfo.tickerid, tf, closeMA, lookahead=barmerge.lookahead_on)
openAlt  = request.security(syminfo.tickerid, tf, openMA,  lookahead=barmerge.lookahead_on)

// PREVIOUS VALUES
closeAltPrev = closeAlt[1]
openAltPrev  = openAlt[1]

// CROSS DETECTION
leTrigger = closeAlt > openAlt and closeAltPrev <= openAltPrev
seTrigger = closeAlt < openAlt and closeAltPrev >= openAltPrev

// STATE MACHINE
var float condition = 0

if leTrigger and condition[1] <= 0
    condition := 1
else if seTrigger and condition[1] >= 0
    condition := -1

longE  = leTrigger and condition[1] <= 0 and condition == 1
shortE = seTrigger and condition[1] >= 0 and condition == -1

// SIGNAL LABELS
plotshape(longE,  style=shape.labelup,   location=location.belowbar, color=color.green, text="BUY")
plotshape(shortE, style=shape.labeldown, location=location.abovebar, color=color.red,   text="SELL")


MT5: 

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   4

#property indicator_label1 "ALMA Close (LTF)"
#property indicator_type1  DRAW_LINE
#property indicator_color1 clrOrange
#property indicator_width1 2

#property indicator_label2 "ALMA Open (LTF)"
#property indicator_type2  DRAW_LINE
#property indicator_color2 clrDodgerBlue
#property indicator_width2 2

#property indicator_label3 "closeAlt (HTF ALMA)"
#property indicator_type3  DRAW_LINE
#property indicator_color3 clrLime
#property indicator_width3 3

#property indicator_label4 "openAlt (HTF ALMA)"
#property indicator_type4  DRAW_LINE
#property indicator_color4 clrRed
#property indicator_width4 3

input int    Length        = 2;
input double Offset        = 0.85;
input double Sigma         = 5;
input int    TF_Multiplier = 8;

double AlmaClose[];
double AlmaOpen[];
double closeAltBuf[];
double openAltBuf[];
double Weights[];

void ComputeWeights()
{
   ArrayResize(Weights, Length);
   double m   = Offset * (Length - 1);
   double s   = (double)Length / Sigma;
   double wsum = 0;
   for(int i = 0; i < Length; i++)
   {
      Weights[i] = MathExp(-((i - m)*(i - m)) / (2.0*s*s));
      wsum += Weights[i];
   }
   for(int i = 0; i < Length; i++)
      Weights[i] /= wsum;
}

double ALMAonArray(const double &arr[], int newestIdx)
{
   if(newestIdx < Length - 1) return EMPTY_VALUE;
   double sum = 0;
   for(int i = 0; i < Length; i++)
      sum += arr[newestIdx - i] * Weights[Length - 1 - i];
   return sum;
}

int OnInit()
{
   SetIndexBuffer(0, AlmaClose);
   SetIndexBuffer(1, AlmaOpen);
   SetIndexBuffer(2, closeAltBuf);
   SetIndexBuffer(3, openAltBuf);
   ComputeWeights();
   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[])
{
   if(rates_total < Length) return 0;

   int ltfStart = (prev_calculated < Length) ? Length - 1 : prev_calculated;
   for(int bar = ltfStart; bar < rates_total; bar++)
   {
      AlmaClose[bar] = ALMAonArray(close, bar);
      AlmaOpen[bar]  = ALMAonArray(open,  bar);
   }

   int blockId[];
   ArrayResize(blockId, rates_total);

   {
      int globalBlock = 0; 
      int posInBlock  = 0;   
      datetime lastDay = 0;

      for(int bar = 0; bar < rates_total; bar++)
      {
         MqlDateTime dt;
         TimeToStruct(time[bar], dt);
         datetime thisDay = (datetime)(time[bar] - dt.hour*3600 - dt.min*60 - dt.sec);

         if(thisDay != lastDay)
         {
            if(bar > 0) globalBlock++;
            posInBlock = 0;
            lastDay    = thisDay;
         }
         else if(posInBlock == TF_Multiplier)
         {
            globalBlock++;
            posInBlock = 0;
         }

         blockId[bar] = globalBlock;
         posInBlock++;
      }
   }

   int maxBlock = blockId[rates_total - 1];
   int blockFirst[];
   int blockLast[];
   ArrayResize(blockFirst, maxBlock + 1);
   ArrayResize(blockLast,  maxBlock + 1);
   ArrayInitialize(blockFirst, -1);
   ArrayInitialize(blockLast,  -1);

   for(int bar = 0; bar < rates_total; bar++)
   {
      int b = blockId[bar];
      if(blockFirst[b] < 0) blockFirst[b] = bar;
      blockLast[b] = bar;
   }

   double htfClose[];
   double htfOpen[];
   ArrayResize(htfClose, maxBlock + 1);
   ArrayResize(htfOpen,  maxBlock + 1);

   for(int b = 0; b <= maxBlock; b++)
   {
      if(blockFirst[b] < 0) { htfClose[b] = 0; htfOpen[b] = 0; continue; }
      
      htfClose[b] = (blockLast[b] >= Length-1)  ? AlmaClose[blockLast[b]]  : 0;
      
      htfOpen[b]  = (blockFirst[b] >= Length-1) ? AlmaOpen[blockFirst[b]]  : 0;
   }

   double htfCloseALMA[];
   double htfOpenALMA[];
   ArrayResize(htfCloseALMA, maxBlock + 1);
   ArrayResize(htfOpenALMA,  maxBlock + 1);
   ArrayInitialize(htfCloseALMA, EMPTY_VALUE);
   ArrayInitialize(htfOpenALMA,  EMPTY_VALUE);

   for(int b = Length - 1; b <= maxBlock; b++)
   {
      htfCloseALMA[b] = ALMAonArray(htfClose, b);
      htfOpenALMA[b]  = ALMAonArray(htfOpen,  b);
   }

   for(int bar = 0; bar < rates_total; bar++)
{
   int b = blockId[bar];
   
   int posInBlock = bar - blockFirst[b];
    
   int lookupBlock = (posInBlock >= TF_Multiplier / 2) ? b : b - 1;

   if(lookupBlock < Length - 1 || lookupBlock < 0)
   {
      closeAltBuf[bar] = 0;
      openAltBuf[bar]  = 0;
   }
   else
   {
      closeAltBuf[bar] = (htfCloseALMA[lookupBlock] != EMPTY_VALUE) ? htfCloseALMA[lookupBlock] : 0;
      openAltBuf[bar]  = (htfOpenALMA[lookupBlock]  != EMPTY_VALUE) ? htfOpenALMA[lookupBlock]  : 0;
   }
}

   return rates_total;
}
 
Vaibhav Vishwakarma:
I have this indicator on trading view that I'm trying to replicate on MT5 but it's like a dead end.

The trading view indicator works by plotting ALMA on the current timeframe and then going 8x the current timeframe to get the ALT ALMA values on the new obtained timeframe.

I'm super close (I think) on the MT5 side but they are not matching no matter what I do, here's the code for both platforms.

SO for M5 timeframe, the TradingView code goes to 8x5 = 40.

TradingView: 


MT5: 

Generate the Custom Symbol/chart:

Code Base

Period Converter Mod

Aleksandr Slavskii, 2025.07.13 12:13

An analogue of Period Converter in MT4

And then apply the indicator to the Custom Symbol/chart:

Forum on trading, automated trading systems and testing trading strategies

Indicators: ALMA(Arnaud Legoux Moving Average)

xtemer, 2021.04.03 04:58

The indicator doesn't work, there is compile error: 'iTime' - override system function alma_v2.mq5 209 10

I think this function should be removed as current version of MQL5 already has built-in iTime function.

datetime iTime(string symbol,ENUM_TIMEFRAMES TF,int index)

{

   if(index < 0) return(-1);

   static datetime timearray[];

   if(CopyTime(symbol,TF,index,1,timearray) > 0) return(timearray[0]); else return(-1);

}


Attached the fixed mq5 file (note: you have to click "Go to discussion" link to see the attachment)


 
Ryan L Johnson #:

Generate the Custom Symbol/chart:

And then apply the indicator to the Custom Symbol/chart:


ALMA works perfectly but I still can't get the custom timeframe part going,

I got very close but still not matching tradingview.

here is the latest code: 

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   4

#property indicator_label1 "ALMA Close (LTF)"
#property indicator_type1  DRAW_LINE
#property indicator_color1 clrOrange
#property indicator_width1 2

#property indicator_label2 "ALMA Open (LTF)"
#property indicator_type2  DRAW_LINE
#property indicator_color2 clrDodgerBlue
#property indicator_width2 2

#property indicator_label3 "closeAlt (HTF ALMA)"
#property indicator_type3  DRAW_LINE
#property indicator_color3 clrLime
#property indicator_width3 3

#property indicator_label4 "openAlt (HTF ALMA)"
#property indicator_type4  DRAW_LINE
#property indicator_color4 clrRed
#property indicator_width4 3

input int    Length        = 2;
input double Offset        = 0.85;
input double Sigma         = 5;
input int    TF_Multiplier = 8;

double AlmaClose[];
double AlmaOpen[];
double closeAltBuf[];
double openAltBuf[];
double Weights[];

void ComputeWeights()
{
   ArrayResize(Weights, Length);

   double m   = Offset * (Length - 1);
   double s   = (double)Length / Sigma;
   double wsum = 0;

   for(int i = 0; i < Length; i++)
   {
      Weights[i] = MathExp(-((i - m)*(i - m)) / (2*s*s));
      wsum += Weights[i];
   }

   for(int i = 0; i < Length; i++)
      Weights[i] /= wsum;
}

double ALMAonArray(const double &arr[], int newestIdx)
{
   if(newestIdx < Length - 1)
      return EMPTY_VALUE;

   double sum = 0;

   for(int i = 0; i < Length; i++)
      sum += arr[newestIdx - i] * Weights[Length - 1 - i];

   return sum;
}

int OnInit()
{
   SetIndexBuffer(0, AlmaClose);
   SetIndexBuffer(1, AlmaOpen);
   SetIndexBuffer(2, closeAltBuf);
   SetIndexBuffer(3, openAltBuf);

   ArrayInitialize(closeAltBuf, EMPTY_VALUE);
   ArrayInitialize(openAltBuf,  EMPTY_VALUE);

   ComputeWeights();

   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[])
{
   if(rates_total < Length)
      return 0;

   int start = (prev_calculated < Length) ? Length - 1 : prev_calculated;

   // Calculate LTF ALMA
   for(int bar = start; bar < rates_total; bar++)
   {
      AlmaClose[bar] = ALMAonArray(close, bar);
      AlmaOpen[bar]  = ALMAonArray(open,  bar);
   }

   // Build synthetic 8x blocks
   int blockId[];
   ArrayResize(blockId, rates_total);

   int block = 0;
   int pos   = 0;

   for(int bar = 0; bar < rates_total; bar++)
   {
      blockId[bar] = block;

      pos++;

      if(pos == TF_Multiplier)
      {
         block++;
         pos = 0;
      }
   }

   int maxBlock = blockId[rates_total - 1];

   int blockFirst[];
   int blockLast[];

   ArrayResize(blockFirst, maxBlock + 1);
   ArrayResize(blockLast,  maxBlock + 1);

   ArrayInitialize(blockFirst, -1);
   ArrayInitialize(blockLast,  -1);

   for(int bar = 0; bar < rates_total; bar++)
   {
      int b = blockId[bar];

      if(blockFirst[b] == -1)
         blockFirst[b] = bar;

      blockLast[b] = bar;
   }

   // Sample HTF values directly from LTF ALMA
   double htfCloseAlt[];
   double htfOpenAlt[];

   ArrayResize(htfCloseAlt, maxBlock + 1);
   ArrayResize(htfOpenAlt,  maxBlock + 1);

   for(int b = 0; b <= maxBlock; b++)
   {
      if(blockLast[b] >= Length - 1)
         htfCloseAlt[b] = AlmaClose[blockLast[b]];
      else
         htfCloseAlt[b] = EMPTY_VALUE;

      if(blockFirst[b] >= Length - 1)
         htfOpenAlt[b]  = AlmaOpen[blockFirst[b]];
      else
         htfOpenAlt[b]  = EMPTY_VALUE;
   }

   // Project HTF values back to LTF bars
   for(int bar = 0; bar < rates_total; bar++)
   {
      int b = blockId[bar];

      if(b >= 0 && b <= maxBlock)
      {
         closeAltBuf[bar] = htfCloseAlt[b];
         openAltBuf[bar]  = htfOpenAlt[b];
      }
      else
      {
         closeAltBuf[bar] = EMPTY_VALUE;
         openAltBuf[bar]  = EMPTY_VALUE;
      }
   }

   return rates_total;
}