array out of range ... and doesn't paint. why?

 

Hi, I have this ... but don't manage to make it work. what's wrong? what am I missing?


array out of range when testing...


#property  indicator_separate_window
#property  indicator_buffers 3
#property  indicator_plots   1
#property  indicator_type1   DRAW_LINE
#property  indicator_color1  clrRed
#property  indicator_style1  STYLE_SOLID
#property  indicator_label1  "TII"

input int AMper= 5;
input int AMshift=3;
input ENUM_TIMEFRAMES AMtimeframe = PERIOD_CURRENT;

double ITT_[],UP[],DOWN[];
int hMA;
int totalBars = Bars(_Symbol, _Period);



//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   IndicatorSetString(INDICATOR_SHORTNAME, "ITT");

   ArrayInitialize(ITT_, 0.0);
   ArrayInitialize(UP, 0.0);
   ArrayInitialize(DOWN, 0.0);

   ArrayResize(ITT_, totalBars);
   ArrayResize(UP, totalBars);
   ArrayResize(DOWN, totalBars);

   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, AMper);
   PlotIndexSetInteger(0, PLOT_LINE_STYLE, STYLE_SOLID);
   PlotIndexSetInteger(0, PLOT_LINE_WIDTH, 1);
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, clrRed);
   IndicatorSetInteger(INDICATOR_DIGITS, 3);
//--- indicator buffers mapping

   SetIndexBuffer(0, ITT_, INDICATOR_DATA);
   SetIndexBuffer(1, UP, INDICATOR_CALCULATIONS);
   SetIndexBuffer(2, DOWN, INDICATOR_CALCULATIONS);
   
   hMA = iMA(_Symbol,PERIOD_CURRENT,AMper,AMshift,MODE_SMA,PRICE_CLOSE);

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//---

   int i;
   double itt[];

   CopyBuffer(hMA, 0, 0, 2, itt);

   ArraySetAsSeries(itt, true);

   for(i = prev_calculated; i < rates_total; i++)
     {
      if(price[i]>itt[i])
        {
         UP[i]=price[i]-itt[i];

        }
      else
        {
         if(price[i]<itt[i])
            DOWN[i]=itt[i]-price[i];

        }

      ITT_[i]=100*(UP[i]/(UP[i]+DOWN[i]));
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   IndicatorRelease(hMA);
  }
//+------------------------------------------------------------------+
 
Javier Santiago Gaston De Iriarte Cabrera:

Hi, I have this ... but don't manage to make it work. what's wrong? what am I missing?


U should probably copy the values to the itt array with this instead:

CopyBuffer(hMA, 0, 0, rates_total, itt);

 
phade #:
U should probably copy the values to the itt array with this instead:

CopyBuffer(hMA, 0, 0, rates_total, itt);

Still array out of range when testing...

 
I'm going to take a look later as I like problem solving.
In the meantime someone else might take a look, but it's a Sunday so they might be away ;)
 
Javier Santiago Gaston De Iriarte Cabrera:
   CopyBuffer(hMA, 0, 0, 2, itt);

Two things stand out at first glance:

1. Read the documentation to this:

CopyBuffer(hMA, 0, 0, 2, itt);


And you are assuming:

rates_total == totalBars

which is rarely the case, and if, it wont stay that way consistently. - Additionally, I suggest to replace totalBars with rates_total.

But actually it would be better to completley spare these lines:

   ArrayResize(ITT_, totalBars);
   ArrayResize(UP, totalBars);
   ArrayResize(DOWN, totalBars);

And you dont want this:

ArraySetAsSeries(itt, true);


Or you want it on all arrays, else you have one reverse array in your data.

As an idea, try something like this for your buffer calls:

   CopyBuffer(hMA, 0, time[prev_calculated], time[rates_total - 1], itt);

But if you are doing such, watch your indexing, as they are not synched to the other buffers. - You will need to track an offset. - As said read the docs around CopyBuffer and Timeseries access.... It is important to understand how it works.


EDIT:

I just saw, you are using the alternate function siganture for OnCalculate(), you will need to figure out the indexing for the function call:

you cannot use this function call:

CopyBuffer(hMA, 0, time[prev_calculated], time[rates_total - 1], itt);
 
Dominik Christian Egert #:

Two things stand out at first glance:

1. Read the documentation to this:


And you are assuming:

which is rarely the case, and if, it wont stay that way consistently. - Additionally, I suggest to replace totalBars with rates_total.

But actually it would be better to completley spare these lines:

And you dont want this:


Or you want it on all arrays, else you have one reverse array in your data.

As an idea, try something like this for your buffer calls:

But if you are doing such, watch your indexing, as they are not synched to the other buffers. - You will need to track an offset. - As said read the docs around CopyBuffer and Timeseries access.... It is important to understand how it works.


EDIT:

I just saw, you are using the alternate function siganture for OnCalculate(), you will need to figure out the indexing for the function call:

you cannot use this function call:

thanks for responding.

1) why should I use coppybuffer like that?

int  CopyBuffer(
   int       indicator_handle,     // indicator handle
   int       buffer_num,           // indicator buffer number
   int       start_pos,            // start position
   int       count,                // amount to copy
   double    buffer[]              // target array to copy
   );
CopyBuffer(hMA, 0, 0, rates_total, itt);

2) total bars is 

int totalBars = Bars(_Symbol, _Period);

but you are correct, looks better if I use rates_total, but rates_total is in OnCalculate, and ArrayResize is OnInit

3) Spare RatesResize with what? or should I delet it?

 
Javier Santiago Gaston De Iriarte Cabrera #:

thanks for responding.

1) why should I use coppybuffer like that?

2) total bars is 

but you are correct, looks better if I use rates_total, but rates_total is in OnCalculate, and ArrayResize is OnInit

3) Spare RatesResize with what? or should I delet it?

Then how do I do it? just whant to creat a simple Indicator out of another one ... can't find the simple way.

 
Javier Santiago Gaston De Iriarte Cabrera #:

Then how do I do it? just whant to creat a simple Indicator out of another one ... can't find the simple way.

ok, problem solved ... I used this article

How to Write an Indicator on the Basis of Another Indicator
How to Write an Indicator on the Basis of Another Indicator
  • www.mql5.com
In MQL5 you can write an indicator both from a scratch and on the basis of another already existing indicator, in-built in the client terminal or a custom one. And here you also have two ways - to improve an indicator by adding new calculations and graphical styles to it , or to use an indicator in-built in the client terminal or a custom one via the iCustom() or IndicatorCreate() functions.
 
Javier Santiago Gaston De Iriarte Cabrera #:

ok, problem solved ... I used this article

Thanks for sharing, I find the documentation to be lacking clarity on a lot of things
 
Javier Santiago Gaston De Iriarte Cabrera #:

thanks for responding.

1) why should I use coppybuffer like that?

2) total bars is 

but you are correct, looks better if I use rates_total, but rates_total is in OnCalculate, and ArrayResize is OnInit

3) Spare RatesResize with what? or should I delet it?

For completeness:

1) You queried only a few values by CopyBuffer, so the resulting array is only the size of your query... You cannot use the prev_calculated < rates_total indexing on that array. Because indexing values will be out of bound.

2) You should never use any Chart related data before receiving a tick. The chart might not be ready. You will get false data.

When using an array with PlotIndexSetBuffer, you transmit control to the terminal. The array will be managed for you, you do not need to take care of it, except for storing the data inside.

Yes, rates_total is available only in OnCalculate() this statement was on purpose, because it would have forced you to put the code there. And by doing so, you would have avoided any invalid calls to functions that might give false data. OnCalculate will be called as the chart us ready and data is made available.