How to calculate an indicator for Max number of Bars

 

Hello my friends,

I want to build an indicator that show the close for the last X number of candles only. Therefore, I wrote the attached indicator.

//+------------------------------------------------------------------+
//|                                           Close Oscillator I.mq4 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window

extern int MaxCandles = 10; // Max Candles to draw

//--- right input parameters flag
bool          ExtParameters=false;

double zxc[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
IndicatorBuffers(1);
SetIndexBuffer(0,zxc);
SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,1,clrRed);

IndicatorShortName("TDO");
SetIndexLabel(0,"TDO");

if(MaxCandles <2)
 {
Print("Candles should be more than 1");
ExtParameters=false;
return(INIT_FAILED);
 }
else
ExtParameters=true;
//---
return(INIT_SUCCEEDED); 
  }
//+------------------------------------------------------------------+
//| 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 limit= MaxCandles - prev_calculated ;
if(prev_calculated==0)limit--;
else  limit++;
//---
for(int i=limit; i>=0 && !IsStopped(); i--)
  {
zxc[i] = iClose(NULL,PERIOD_CURRENT,i);
  }
//---
   return(MaxCandles);
  }
  

The problem is that when I close MT4 and reopen it the indicator appear like in the next chart.


Could you help me to find what is wrong with this code.

 
Muhammad Elbermawi:

Hello my friends,

I want to build an indicator that show the close for the last X number of candles only. Therefore, I wrote the attached indicator.

The problem is that when I close MT4 and reopen it the indicator appear like in the next chart.


Could you help me to find what is wrong with this code.

You could try something like this. A little old fashion way but it should work:

   int limit=IndicatorCounted(); 
   //---- check for possible errors
   if (limit<0) return(-1);
   //---- last counted bar will be recounted
   if (limit>0) limit--;
   int pos=Bars-limit-1;
   if(pos>Bars-1) pos=Bars-1;
   if(pos>MaxCandles) pos=MaxCandles;

// Iterate from past to present
   for(int i = pos; i >= 1; i--)
   {
     //your code here
   }
 
Jan Flodin:

You could try something like this. A little old fashion way but it should work:

Thanks for your help. I tried the code but it didn't help to solve the problem.


 
Jan Flodin: You could try something like this. A little old fashion way but it should work:
 int limit=IndicatorCounted(); 
  1. You should stop using the old IndicatorCounted and start using the new Event Handling Functions - Functions - Language Basics - MQL4 Reference
  2. See How to do your lookbacks correctly.


Muhammad Elbermawi:

I want to build an indicator that show the close for the last X number of candles only. Therefore, I wrote the attached indicator.

The problem is that when I close MT4 and reopen it the indicator appear like in the next chart.

  1. Why do you want to do that? Just process all bars and be done.
    1. Your initial loop processes [MaxCandles-1 .. 1]. After that it processes the previous candle a second time. drop the limit++.
    2. No need for the if(previous if you adjust your return value.
                How to do your lookbacks correctly.
    3. You said "show .. the last X..." After the first run you will be adding additional bars but never remove old ones.

  2. zxc[i] = iClose(NULL,PERIOD_CURRENT,i);
    No such function in MT5. Why did you post your MT4 question in the Root / MT5 Indicators section instead of the MQL4 section, (bottom of the Root page?)
              General rules and best pratices of the Forum. - General - MQL5 programming forum
    Next time post in the correct place. The moderators will likely move this thread there soon.

  3. IndicatorBuffers(1);
    This is used to specify the total number of buffers, not the number of visible buffers. Delete it and add the appropriate #property.

 
whroeder1:
  1. You should stop using the old IndicatorCounted and start using the new Event Handling Functions - Functions - Language Basics - MQL4 Reference
  2. See How to do your lookbacks correctly.


  1. Why do you want to do that? Just process all bars and be done.
  2. No such function in MT5. Why did you post your MT4 question in the Root / MT5 Indicators section instead of the MQL4 section, (bottom of the Root page?)
              General rules and best pratices of the Forum. - General - MQL5 programming forum
    Next time post in the correct place. The moderators will likely move this thread there soon.

  3. This is used to specify the total number of buffers, not the number of visible buffers. Delete it and add the appropriate #property.

1. I can't see your answer helpful.

2. If moderator want to transfer the thread they will do it.

3. Buffers used in calculation and visible buffers are the same and this is not my main problem here.

 
Muhammad Elbermawi:

Hello my friends,

I want to build an indicator that show the close for the last X number of candles only. Therefore, I wrote the attached indicator.

The problem is that when I close MT4 and reopen it the indicator appear like in the next chart.


Could you help me to find what is wrong with this code.

Maybe I've just misunderstood you but try this updated code. I hope it does what you want.

//+------------------------------------------------------------------+
//|                                           Close Oscillator I.mq4 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window

extern int MaxCandles = 10; // Max Candles to draw

//--- right input parameters flag
bool          ExtParameters=false;

double zxc[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   IndicatorBuffers(1);
   SetIndexBuffer(0,zxc);
   SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,1,clrRed);
   SetIndexEmptyValue(0,0.0);
   IndicatorDigits(_Digits);
   IndicatorShortName("TDO");
   SetIndexLabel(0,"TDO");
   
   if(MaxCandles <2)
     {
      Print("Candles should be more than 1");
      ExtParameters=false;
      return(INIT_PARAMETERS_INCORRECT);
     }
   else ExtParameters=true;
//---
   return(INIT_SUCCEEDED); 
  }
//+------------------------------------------------------------------+
//| 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 limit;
   if(prev_calculated==0) limit=rates_total;
   else limit=(rates_total-prev_calculated)>MaxCandles?(rates_total-prev_calculated+2):(MaxCandles+2);
//---
   for(int i=0;i<limit && !IsStopped();i++) zxc[i]=i>MaxCandles?0.0:close[i];
//---
   return(rates_total);
  }
 
Petr Nosek:
Maybe I've just misunderstood you but try this updated code. I hope it does what you want.
Thanks for your help Petr. The market is close now that is why I will have to wait until its open next week to test your code.
 

Muhammad Elbermawi:
Thanks for your help Petr. The market is close now that is why I will have to wait until its open next week to test your code.

You are welcome. I've updated a little bit my code so improve its efficient (close[] instead of iClose()). Let me know when you try it.

 
Muhammad Elbermawi:

3. Buffers used in calculation and visible buffers are the same and this is not my main problem here.

No they are not. You have ZERO visible buffers (no #property indicator_buffers) Therefor that may be your "main problem."

 
whroeder1:

No they are not. You have ZERO visible buffers (no #property indicator_buffers) Therefor that may be your "main problem."

You are wrong in my opinion. But maybe I've missed something. Could you, please, explain me what difference (in my above code) would be if I had used #property indicator_buffers. I think there isn't any difference. And I don't believe that is Muhammad's "main problem".
 
Petr Nosek:

Maybe I've just misunderstood you but try this updated code. I hope it does what you want.

Thanks a lot Petr, this code do the job. I hope you can explain this lines in more details.

//---
   int limit;
   if(prev_calculated==0) limit=rates_total;
   else limit=(rates_total-prev_calculated)>MaxCandles?(rates_total-prev_calculated+2):(MaxCandles+2);
//---
   for(int i=0;i<limit && !IsStopped();i++) zxc[i]=i>MaxCandles?0.0:close[i];


Thanks

Reason: