iMAOnArray and iEnvelopesOnArray indicator issue

 

Hi

Could someone tell me what is the problem with the following indicator please...? I'm out of ideas.

Problem is with iMAOnArray and iEnvelopesOnArray. Im using this indicator inside an EA using icustom. I dont need to draw this indicator (I can do that manually by combining RSI and MA and combining, williams's percentage with envelopes).

Problem is the following (I think...): the print command inside de second for loop, prints correct when it runs for the first time, but any subsequent calls return zero. (the same with iEnvelopesOnArray if I was to print it...).

Any thoughts? Thank you.

//+------------------------------------------------------------------+
//|                                                 env_rsi_will.mq4 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+

#property indicator_separate_window

#property indicator_buffers 5

//---- indicator buffers
double rsiind[];
double rsiind_temp[];
double ma_rsi[];
double pwind[];
double pwind_temp[];
double envwind_T[];
double envwind_B[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   int    draw_begin;
   string short_name;
//---- drawing settings
   
//---- indicators
   SetIndexShift(0,0);
   SetIndexShift(1,0);
   SetIndexShift(2,0);
   SetIndexShift(3,0);
   SetIndexShift(4,0);
   
   IndicatorShortName("Env_RSI_will");
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
   draw_begin=13;
   //---- indicator buffers mapping
   SetIndexBuffer(0,rsiind);
   SetIndexBuffer(1,ma_rsi);
   SetIndexBuffer(2,pwind);
   SetIndexBuffer(3,envwind_T);
   SetIndexBuffer(4,envwind_B);

   ArraySetAsSeries(rsiind_temp,true);
   ArraySetAsSeries(pwind_temp,true);

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
   int limit;
   //---- check for possible errors
   if(counted_bars<0) return(-1);
   //---- the last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
   
   
   for(int i = 0; i < limit; i++){
      rsiind[i] = iRSI(NULL,0,14,PRICE_CLOSE,i);
      rsiind_temp[i]=rsiind[i];
      pwind[i] = iWPR(NULL,0,21,i);
      pwind_temp[i]=pwind[i];
   }
  
   for(i = 0; i < limit; i++){
      ma_rsi[i] = iMAOnArray(rsiind_temp,limit,7,0,MODE_SMA,i);
      Print("-------------------------",iMAOnArray(rsiind_temp,0,7,0,MODE_SMA,1),"#####################");
      envwind_T[i] = iEnvelopesOnArray(pwind_temp,limit,7,MODE_SMA,0,0.2,MODE_UPPER,i);
      envwind_B[i] = iEnvelopesOnArray(pwind_temp,limit,7,MODE_SMA,0,0.2,MODE_LOWER,i);
   }
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
pduarte:

Hi

Could someone tell me what is the problem with the following indicator please...? I'm out of ideas.

Problem is with iMAOnArray and iEnvelopesOnArray. Im using this indicator inside an EA using icustom. I dont need to draw this indicator (I can do that manually by combining RSI and MA and combining, williams's percentage with envelopes).

Problem is the following (I think...): the print command inside de second for loop, prints correct when it runs for the first time, but any subsequent calls return zero. (the same with iEnvelopesOnArray if I was to print it...).

Any thoughts? Thank you.

After the first run limit is very small, maybe 1 or 0 too tired to check right now . . . so I think that screws up your iMAOnArray(), don't use limit, use 0, meaning the whole array.
 
RaptorUK:
After the first run limit is very small, maybe 1 or 0 too tired to check right now . . . so I think that screws up your iMAOnArray(), don't use limit, use 0, meaning the whole array.


Thanks RaptorUK. Ill give a try later today and let you know. Appreciate your help.
 
iMAOnArray(rsiind_temp,limit,7,0,MODE_SMA,i);

Exactly. limit (Bars-counted_bars) will be 1 or possibly 2 on the first tick of a new bar. Your saying what is the SMA(7) when there is only one value in the array.

You put the real number of values in the array. Or (like this case) for all the values WHOLE_ARRAY


RaptorUK, get some sleep. I'm about to retire and you're FIVE HOURS a head of me.
 
ArraySetAsSeries(rsiind_temp,true);
ArraySetAsSeries(pwind_temp,true);

Just setting those arrays as series isn't going to work you need to make them behave like buffers. Resize them to Bars and reindex them every time a new bar appears like this in start() before the indicator loop.

if(counted_bars < Bars-1) //newbar or newchart detected
 {
 ArraySetAsSeries(myarray,false);  // index array the standard way
 ArrayResize(myarray,Bars);        // resize so any new index is added to high end of array
 ArraySetAsSeries(myarray,true);   // reverse array so new index is the zero
}
 
  1. SDC: Just setting those arrays as series isn't going to work you need to make them behave like buffers...
    Same as my code
    int start(){
       ResizeBuffer(myArray, Bars);
       :
    }
    bool     ResizeBuffer(double& buffer[], int size){ // buffer can be 1D or 2D
       if(ArrayRange(buffer,0) != size){      // ArrayRange allows 1D or 2D arrays
          ArraySetAsSeries(buffer, false);    // Shift values B[2]=B[1]; B[1]=B[0]
          if( !MyArrayResize(buffer, size, "ResizeBuffer") )        return(false);
          ArraySetAsSeries(buffer, true);
       }
       return(true);
    }
    bool     MyArrayResize(double& arr[], int nRows, string msg){
       if(ArrayResize(arr, nRows) >= nRows)   return(true);
       DisableTrading( "ArrayResize("+nRows+") Failed: "+GetLastError() +" "+msg);
       return(false);
    }
    

  2. Why bother, make the last two arrays invisible buffers.
    int init(){
       int    draw_begin;
    :
       SetIndexBuffer(4,envwind_B);
    
       ArraySetAsSeries(rsiind_temp,true);
       ArraySetAsSeries(pwind_temp,true);
    
    int init(){
       IndicatorBuffers(7);             // 5 visible two extra
    :
       SetIndexBuffer(4,envwind_B);
    
    // ArraySetAsSeries(rsiind_temp,true);
    // ArraySetAsSeries(pwind_temp,true);
       SetIndexBuffer(5,rsiind_temp);
       SetIndexBuffer(6,pwind_temp);

 

Thank you so much for your replies. It is working now with SDC and RaptorUK's suggestion.

However, a couple of questions: as I understand, ArraySetAsSeries(myarray, true) changes myarray right? As I don't want rsiind and pwind to be considered as series (they are supposed to be "normal" indicators because I do use them), hence the arrays rsiind_temp and pwind_temp. Right? Or rsiind_temp and pwind_temp are not needed?

As I said, I don't need this indicator to draw anything, because I can do that by using "use previous indicator data" on RSI and Williams percentage. Does this indicator achieve the same?

WHRoeder, interesting suggestion, but unfortunately, I fail to understand your 2nd point. By doing that how do I use MA and Envelopes to use RSI and Williams percentage data?

Again, thanks a lot for your help.

Here's the code now:

//+------------------------------------------------------------------+
//|                                                 env_rsi_will.mq4 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
#property indicator_separate_window

#property indicator_buffers 5

//---- indicator buffers
double rsiind[];
double rsiind_temp[];
double ma_rsi[];
double pwind[];
double pwind_temp[];
double envwind_T[];
double envwind_B[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   
//---- indicators
   SetIndexShift(0,0);
   SetIndexShift(1,0);
   SetIndexShift(2,0);
   SetIndexShift(3,0);
   SetIndexShift(4,0);
   
   IndicatorShortName("Env_RSI_will");
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
   
   //---- indicator buffers mapping
   SetIndexBuffer(0,rsiind);
   SetIndexBuffer(1,ma_rsi);
   SetIndexBuffer(2,pwind);
   SetIndexBuffer(3,envwind_T);
   SetIndexBuffer(4,envwind_B);

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
   int limit;
   //---- check for possible errors
   if(counted_bars<0) return(-1);
   //---- the last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
   
   if(counted_bars < Bars-1) //newbar or newchart
   {
      ArraySetAsSeries(rsiind_temp,false);
      ArrayResize(rsiind_temp,Bars);
      ArraySetAsSeries(rsiind_temp,true);
      ArraySetAsSeries(pwind_temp,false);
      ArrayResize(pwind_temp,Bars);
      ArraySetAsSeries(pwind_temp,true);
   }
   
   for(int i = 0; i < limit; i++){
      rsiind[i] = iRSI(NULL,0,14,PRICE_CLOSE,i);
      rsiind_temp[i]=rsiind[i];
      pwind[i] = iWPR(NULL,0,21,i);
      pwind_temp[i]=pwind[i];
   }
  
   for(i = 0; i < limit; i++){
      ma_rsi[i] = iMAOnArray(rsiind_temp,0,7,0,MODE_SMA,i);
      //Print("-------------------------",iMAOnArray(rsiind_temp,0,7,0,MODE_SMA,1),"#####################");
      envwind_T[i] = iEnvelopesOnArray(pwind_temp,0,7,MODE_SMA,0,0.2,MODE_UPPER,i);
      envwind_B[i] = iEnvelopesOnArray(pwind_temp,0,7,MODE_SMA,0,0.2,MODE_LOWER,i);
   }
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
pduarte: WHRoeder, interesting suggestion, but unfortunately, I fail to understand your 2nd point. By doing that how do I use MA and Envelopes to use RSI and Williams percentage data?
An array must be resized, array elements moved. A buffer does it automatically. Both of the first or buffer, otherwise the onArray() will NOT work. You choose which method, I think #2 is easier.
 
pduarte:

Thank you so much for your replies. It is working now with SDC and RaptorUK's suggestion.

However, a couple of questions: as I understand, ArraySetAsSeries(myarray, true) changes myarray right? As I don't want rsiind and pwind to be considered as series (they are supposed to be "normal" indicators because I do use them), hence the arrays rsiind_temp and pwind_temp. Right? Or rsiind_temp and pwind_temp are not needed?

All drawing buffers set using SetIndexBuffer() are reindexed/resized/setasseries automatically. This has to be done to make the zero index available when new bars form on the chart.

We only have 8 drawing buffers, if we dont want to "waste" any we use regular arrays to accumulate values for iMAOnArray() and other such things that dont need to be drawn. We have to code ourselves to resize and reindex them like I showed you. If we have unused drawing buffers we can use them instead like WHR said (in his option 2) to accumulate the data.. The choice is yours you can do it either way.

Reason: