Need more than 8 buffers in my Custom Indicator!!! How can I get this done?

 
Here's the problem...
I'm trying to build a custom indicator. I am using the Heiken Ashi indicator but it already uses up 8 buffers. I would like to put arrows on the chart where a potential trade signal will be how do I achieve this?
I've tried creating a separate CI altogether and using iCustom to grab the necessary data from the 1st indicator....but the problem is the data necessary for me to place arrows is not contained in any of the 8 buffers being used in indicator 1!

I've been at it for almost 5 hours now....I'm stumped!
Any tips?
 
Create more than 1 indicator.
Combine them together.
 
Tenners:
Here's the problem...
I'm trying to build a custom indicator. I am using the Heiken Ashi indicator but it already uses up 8 buffers. I would like to put arrows on the chart where a potential trade signal will be how do I achieve this?
I've tried creating a separate CI altogether and using iCustom to grab the necessary data from the 1st indicator....but the problem is the data necessary for me to place arrows is not contained in any of the 8 buffers being used in indicator 1!

I've been at it for almost 5 hours now....I'm stumped!
Any tips?


If it's only arrows, you don't need a buffer to draw them, do you ?

but I would probably go with 2 indicators as well

 
Tenners - not knowing the source you are using but below are some ideas which may be of use now or in future apps
(edit: ooops, course forgot to say that the 4 extra buffers you re-jig as described below now allows you to declare 4 additional buffers as indicator buffers to hold eg, your arrows, so that can get via iCustom() )
.
1. what source file using? so many different one around...
2. what value do you have on this line? #property indicator_buffers value
3. what value is on this line? IndicatorBuffers(value)
eg: if #property indicator_buffers 4 and IndicatorBuffers(8) then 4 extra buffers are allowed to be used as non displayed calculation buffers.
.
These extra index buffers can instead be:
1. declared as normal eg: double fred1[],fred2[][...];
2. inside start() at top eg:
if(sbFirstCall) {
  sbFirstCall = false;
  ArrayResize(fred1,Bars);
  ArraySetAsSeries(fred1,true);
  
  ArrayResize(fred2,Bars);              
  ArraySetAsSeries(fred2,true);          

  ArrayResize(fredn,Bars);
  ArraySetAsSeries(fredn,true);
}

This is enough to allow following indicator code to do whatever as if nothing had changed, using fred1,.. as normal.
The once off/first time of resizing to Bars elements can be whatever you think the indicator actually needs to plot on chart ie, many indicators use all the Bars but never need more than a handfull...
The setAsSeries reverses the indexing sense of the array so it's identical to the normal IndicatorBuffers.
.
hth
 
fbj:
Tenners - not knowing the source you are using but below are some ideas which may be of use now or in future apps
(edit: ooops, course forgot to say that the 4 extra buffers you re-jig as described below now allows you to declare 4 additional buffers as indicator buffers to hold eg, your arrows, so that can get via iCustom() )
.
1. what source file using? so many different one around...
2. what value do you have on this line? #property indicator_buffers value
3. what value is on this line? IndicatorBuffers(value)
eg: if #property indicator_buffers 4 and IndicatorBuffers(8) then 4 extra buffers are allowed to be used as non displayed calculation buffers.
.
These extra index buffers can instead be:
1. declared as normal eg: double fred1[],fred2[][...];
2. inside start() at top eg:
This is enough to allow following indicator code to do whatever as if nothing had changed, using fred1,.. as normal.
The once off/first time of resizing to Bars elements can be whatever you think the indicator actually needs to plot on chart ie, many indicators use all the Bars but never need more than a handfull...
The setAsSeries reverses the indexing sense of the array so it's identical to the normal IndicatorBuffers.
.
hth


Thanks for all responses!

@fbj that was pretty informative...

I already had #property indicator_buffers 4 & IndicatorBuffers(8)......but I wasn't aware of the second implementation of adding the "extra" buffers....

I am using the Heiken Ashi Smoothed code found in the "codebase" section of this site (codebase.mql4.com).....

Again, thanks for the tip...I will try to implement it and let you know my result.


T.

 
fbj:
Tenners - not knowing the source you are using but below are some ideas which may be of use now or in future apps
(edit: ooops, course forgot to say that the 4 extra buffers you re-jig as described below now allows you to declare 4 additional buffers as indicator buffers to hold eg, your arrows, so that can get via iCustom() )
.
1. what source file using? so many different one around...
2. what value do you have on this line? #property indicator_buffers value
3. what value is on this line? IndicatorBuffers(value)
eg: if #property indicator_buffers 4 and IndicatorBuffers(8) then 4 extra buffers are allowed to be used as non displayed calculation buffers.
.
These extra index buffers can instead be:
1. declared as normal eg: double fred1[],fred2[][...];
2. inside start() at top eg:
This is enough to allow following indicator code to do whatever as if nothing had changed, using fred1,.. as normal.
The once off/first time of resizing to Bars elements can be whatever you think the indicator actually needs to plot on chart ie, many indicators use all the Bars but never need more than a handfull...
The setAsSeries reverses the indexing sense of the array so it's identical to the normal IndicatorBuffers.
.
hth


Oh...one more thing...will those "extra" buffers have indexes/indicies that increase?

I mean when I call iCustom...will I refer to the buffer index(8), (9), (10) and (11)?

 
You can not get the extra buffers via iCustom. put the temporary/non-displayed calculations in the extra buffers.
Also you can optimized the buffers. Any past calculated values that are never referred to, do not need to be saved in a buffer. Look at each non-display buffer. If you never see a reference of (i+x) then just use a temporary.
 
Tenners:

Oh...one more thing...will those "extra" buffers have indexes/indicies that increase?

I mean when I call iCustom...will I refer to the buffer index(8), (9), (10) and (11)?




I tried that but I guess iCustom doesn't allow you to reference any buffer index that is greater than 7.
So here's the current set up....

The Heiken Ashi needs 8 buffers/arrays. 4 for display and 4 for calculation. It was using buffers 1 through 8....but I need two buffers for "arrows" so that I can pass them to another indicator that will then display them.
So I used the method described above by fbj to do this...However, in order to get the buffer values for my arrow arrays I had to rearrange the order of the buffers and use the method fbj described to create the 4 arrays that the Heiken Ashi uses only for calculations.

I can now obtain values for my arrows...but my heiken ashi is messed up....

Please see the following....

Heiken Ashi Indicator:
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Red
#property indicator_color2 Lime
#property indicator_color3 Red
#property indicator_color4 Lime
//#property indicator_color5 Yellow
//---- parameters
extern int MaMetod =2;
extern int MaPeriod=6;
extern int MaMetod2 =3;
extern int MaPeriod2=2;
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
double arrowUp[],arrowDn[],signal[];
double ExtMapBuffer5[];
double ExtMapBuffer6[];
double ExtMapBuffer7[];
double ExtMapBuffer8[];
//----
int ExtCountedBars=0;
int firstStart = true;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//|------------------------------------------------------------------|
int init()
  {
//---- indicators
   IndicatorBuffers(8);
   SetIndexStyle(0,DRAW_HISTOGRAM, 0, 1, Red);
   SetIndexBuffer(0, ExtMapBuffer1);
   SetIndexStyle(1,DRAW_HISTOGRAM, 0, 1, Lime);
   SetIndexBuffer(1, ExtMapBuffer2);
   SetIndexStyle(2,DRAW_HISTOGRAM, 0, 3, Red);
   SetIndexBuffer(2, ExtMapBuffer3);
   SetIndexStyle(3,DRAW_HISTOGRAM, 0, 3, Lime);
   SetIndexBuffer(3, ExtMapBuffer4);
    SetIndexBuffer(4,arrowUp);
    SetIndexStyle(4,DRAW_ARROW);
    SetIndexArrow(4,233); //241 option for different arrow head
    SetIndexBuffer(5,arrowDn);
    SetIndexStyle(5,DRAW_ARROW);
    SetIndexArrow(5,234); //242 option for different arrow head      
//----
   SetIndexDrawBegin(0,5);
//---- indicator buffers mapping
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexBuffer(1,ExtMapBuffer2);
   SetIndexBuffer(2,ExtMapBuffer3);
   SetIndexBuffer(3,ExtMapBuffer4);
   SetIndexBuffer(4,arrowUp);
   SetIndexBuffer(5,arrowDn);
   SetIndexBuffer(6,signal); 

   /*SetIndexBuffer(4,ExtMapBuffer5);
   SetIndexBuffer(5,ExtMapBuffer6);
   SetIndexBuffer(6,ExtMapBuffer7);
   SetIndexBuffer(7,ExtMapBuffer8);*/
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- TODO: add your code here
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
//---- Add extra buffers
if(firstStart == true)
{
   ArrayResize(ExtMapBuffer5,Bars);
   ArraySetAsSeries(ExtMapBuffer5,true);     //The setAsSeries reverses the indexing sense of the array so it's identical to the normal IndicatorBuffers.

   ArrayResize(ExtMapBuffer6,Bars);              
   ArraySetAsSeries(ExtMapBuffer5,true);          

   ArrayResize(ExtMapBuffer7,Bars);
   ArraySetAsSeries(ExtMapBuffer7,true);

   ArrayResize(ExtMapBuffer8,Bars);
   ArraySetAsSeries(ExtMapBuffer8,true);
   
   firstStart = false;
}


   double maOpen, maClose, maLow, maHigh;
   double haOpen, haHigh, haLow, haClose;
   if(Bars<=10) return(0);
   ExtCountedBars=IndicatorCounted();
//---- check for possible errors
   if (ExtCountedBars<0) return(-1);
//---- last counted bar will be recounted
   if (ExtCountedBars>0) ExtCountedBars--;
   int pos=Bars-ExtCountedBars-1;
   while(pos>=0)
     {
      maOpen=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_OPEN,pos);
      maClose=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_CLOSE,pos);
      maLow=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_LOW,pos);
      maHigh=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_HIGH,pos);
//----
      haOpen=(ExtMapBuffer5[pos+1]+ExtMapBuffer6[pos+1])/2;
      haClose=(maOpen+maHigh+maLow+maClose)/4;
      haHigh=MathMax(maHigh, MathMax(haOpen, haClose));
      haLow=MathMin(maLow, MathMin(haOpen, haClose));
      arrowUp[pos]= 0;
      arrowDn[pos]= 0;
      signal[pos]=0;
      if (haOpen<haClose)
        {
         ExtMapBuffer7[pos]=haLow;
         ExtMapBuffer8[pos]=haHigh;
         arrowUp[pos]= haLow - 10 * MarketInfo(Symbol(),MODE_POINT);
         arrowDn[pos]= 0;
         signal[pos]=1;
        }
      else
        {
         ExtMapBuffer7[pos]=haHigh;
         ExtMapBuffer8[pos]=haLow;
         arrowUp[pos]= 0;
         arrowDn[pos]= haHigh + 10 * MarketInfo(Symbol(),MODE_POINT);
         signal[pos]=-1;
        }
      ExtMapBuffer5[pos]=haOpen;
      ExtMapBuffer6[pos]=haClose;
      pos--;
     }
   int i;
   for(i=0; i<Bars; i++) ExtMapBuffer1[i]=iMAOnArray(ExtMapBuffer7,Bars,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<Bars; i++) ExtMapBuffer2[i]=iMAOnArray(ExtMapBuffer8,Bars,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<Bars; i++) ExtMapBuffer3[i]=iMAOnArray(ExtMapBuffer5,Bars,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<Bars; i++) ExtMapBuffer4[i]=iMAOnArray(ExtMapBuffer6,Bars,MaPeriod2,0,MaMetod2,i);
//----
   return(0);
  }
//+------------------------------------------------------------------+

Now the code for the 2nd indicator that will use the arrow values:

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Lime
#property indicator_color2 Red

#property indicator_width1 1
#property indicator_width2 1

extern string ___Heiken_Ashi_Smoothed___;
extern int MaM1 = 2;
extern int MaP1 = 6;     
extern int MaM2 = 3;
extern int MaP2 = 2;

//---- buffers
double arrowUpImg[];
double arrowDnImg[];
double signal[];

int arrowPos;
int ExtCountedBars=0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//|------------------------------------------------------------------|
int init()
  {
   arrowPos = ipm(Period());
//---- indicators
//----   
//---- indicator buffers mapping
    SetIndexBuffer(1,arrowUpImg);
    SetIndexStyle(1,DRAW_ARROW);
    SetIndexArrow(1,233); //241 option for different arrow head
    SetIndexBuffer(2,arrowDnImg);
    SetIndexStyle(2,DRAW_ARROW);
    SetIndexArrow(2,234); //242 option for different arrow head   
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- TODO: add your code here
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   //double haOpen, haHigh, haLow, haClose;
   //double emb1,emb2,emb3,emb4,emb5,emb6,emb7,emb8;                  //external map buffers from Heiken_Ashi_Smoothed indicator
   int myBars = 1000; //used for testing ******
   
   if(Bars<=10) return(0);
   ExtCountedBars=IndicatorCounted();
//---- check for possible errors
   if (ExtCountedBars<0) return(-1);
//---- last counted bar will be recounted
   if (ExtCountedBars>0) ExtCountedBars--;
   int pos=Bars-ExtCountedBars-1;
   while(pos>=0)
     {
     int ppos = pos;
     signal[ppos] = iCustom(NULL,0,"Heiken_Ashi_Smoothed",MaM1,MaP1,MaM2,MaP2,6,0);

      if( signal[ppos] > 0 ){
         arrowUpImg[ppos] = iCustom(NULL,0,"Heiken_Ashi_Smoothed",MaM1,MaP1,MaM2,MaP2,4,0);
         arrowDnImg[ppos] = 0;
         Print("************************** Buy **************************");
      }
      else if ( signal[ppos] < 0 ){
         arrowUpImg[ppos] = 0;
         arrowDnImg[ppos] = iCustom(NULL,0,"Heiken_Ashi_Smoothed",MaM1,MaP1,MaM2,MaP2,5,0);
         Print("************************** Sell **************************");
      }
      else if ( signal[ppos] == 0 ){
         arrowUpImg[ppos] = 0; 
         arrowDnImg[ppos] = 0;
         Print("************************** No Signal **************************");
      }
           pos--;
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+

//--- Functions -----------------------------------------------------------------------
//+------------------------------------------------------------------+
//| Time Frame Dependent Arrow Placement                             |
//+------------------------------------------------------------------+
  
int ipm(double p)      //indicatorPositionMultiplier
{
   if (p == PERIOD_M1 ) return (5);
   if (p == PERIOD_M5 ) return (5);
   if (p == PERIOD_M15) return (5);
   if (p == PERIOD_M30) return (20);
   if (p == PERIOD_H1 ) return (20);
   if (p == PERIOD_H4 ) return (30);
   if (p == PERIOD_D1 ) return (75);
   if (p == PERIOD_W1 ) return (120);
   if (p == PERIOD_MN1) return (200);
}

But the result for my Heiken Ashi now looks messed up....




And so....I remain stumped.....
Any more ideas?

thanks,
T.
 
Please state exactly what you 'need' from the HA indicator.
Your second version has been recoded before you know what you are doing is correct. Now, you have your recoding + your 'need' - this is imho dangerous since you have no benchmark to test mods against (ie, the original code without the 'need' coded in. All the recoding masks whats going on by introducing more potential non-working issues which deviate from the original working code base.
.
ie, is it that you want an UP or DN signal in 'your' calling code?
.
IF that is all THEN the proposed mods I suggested will work.
 
fbj:
Please state exactly what you 'need' from the HA indicator.
Your second version has been recoded before you know what you are doing is correct. Now, you have your recoding + your 'need' - this is imho dangerous since you have no benchmark to test mods against (ie, the original code without the 'need' coded in. All the recoding masks whats going on by introducing more potential non-working issues which deviate from the original working code base.
.
ie, is it that you want an UP or DN signal in 'your' calling code?
.
IF that is all THEN the proposed mods I suggested will work.


Hi fbj,

sorry about that...but I still do have the unchanged original code....see here:

//+------------------------------------------------------------------+
//|                                         Heiken Ashi Smoothed.mq4 |
//|                                                                  |
//|                                                      mod by Raff |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Forex-TSD.com "
#property link      "https://www.forex-tsd.com/"
//----
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Red
#property indicator_color2 Lime
#property indicator_color3 Red
#property indicator_color4 Lime
//---- parameters
extern int MaMetod =2;
extern int MaPeriod=6;
extern int MaMetod2 =3;
extern int MaPeriod2=2;
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
double ExtMapBuffer5[];
double ExtMapBuffer6[];
double ExtMapBuffer7[];
double ExtMapBuffer8[];
//----
int ExtCountedBars=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//|------------------------------------------------------------------|
int init()
  {
//---- indicators
   IndicatorBuffers(8);
   SetIndexStyle(0,DRAW_HISTOGRAM, 0, 1, Red);
   SetIndexBuffer(0, ExtMapBuffer1);
   SetIndexStyle(1,DRAW_HISTOGRAM, 0, 1, Lime);
   SetIndexBuffer(1, ExtMapBuffer2);
   SetIndexStyle(2,DRAW_HISTOGRAM, 0, 3, Red);
   SetIndexBuffer(2, ExtMapBuffer3);
   SetIndexStyle(3,DRAW_HISTOGRAM, 0, 3, Lime);
   SetIndexBuffer(3, ExtMapBuffer4);
//----
   SetIndexDrawBegin(0,5);
//---- indicator buffers mapping
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexBuffer(1,ExtMapBuffer2);
   SetIndexBuffer(2,ExtMapBuffer3);
   SetIndexBuffer(3,ExtMapBuffer4);
   SetIndexBuffer(4,ExtMapBuffer5);
   SetIndexBuffer(5,ExtMapBuffer6);
   SetIndexBuffer(6,ExtMapBuffer7);
   SetIndexBuffer(7,ExtMapBuffer8);
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- TODO: add your code here
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   double maOpen, maClose, maLow, maHigh;
   double haOpen, haHigh, haLow, haClose;
   if(Bars<=10) return(0);
   ExtCountedBars=IndicatorCounted();
//---- check for possible errors
   if (ExtCountedBars<0) return(-1);
//---- last counted bar will be recounted
   if (ExtCountedBars>0) ExtCountedBars--;
   int pos=Bars-ExtCountedBars-1;
   while(pos>=0)
     {
      maOpen=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_OPEN,pos);
      maClose=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_CLOSE,pos);
      maLow=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_LOW,pos);
      maHigh=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_HIGH,pos);
//----
      haOpen=(ExtMapBuffer5[pos+1]+ExtMapBuffer6[pos+1])/2; //???????
      haClose=(maOpen+maHigh+maLow+maClose)/4;
      haHigh=MathMax(maHigh, MathMax(haOpen, haClose));
      haLow=MathMin(maLow, MathMin(haOpen, haClose));
      if (haOpen<haClose)
        {
         ExtMapBuffer7[pos]=haLow;
         ExtMapBuffer8[pos]=haHigh;
        }
      else
        {
         ExtMapBuffer7[pos]=haHigh;
         ExtMapBuffer8[pos]=haLow;
        }
      ExtMapBuffer5[pos]=haOpen;
      ExtMapBuffer6[pos]=haClose;
      pos--;
     }
   int i;
   for(i=0; i<Bars; i++) ExtMapBuffer1[i]=iMAOnArray(ExtMapBuffer7,Bars,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<Bars; i++) ExtMapBuffer2[i]=iMAOnArray(ExtMapBuffer8,Bars,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<Bars; i++) ExtMapBuffer3[i]=iMAOnArray(ExtMapBuffer5,Bars,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<Bars; i++) ExtMapBuffer4[i]=iMAOnArray(ExtMapBuffer6,Bars,MaPeriod2,0,MaMetod2,i);
//----
   return(0);
  }
//+------------------------------------------------------------------+


The first problem here is I don't really follow the line I marked with "???????" marks...
Not really clear how the ExtMapBuffer5 and ExtMapBuffer6 can be used to calculate haOpen when they haven't even been set at yet.

Secondly....as you see from the original code....if I want to use 2 new buffers arrowUp and arrowDn to "draw" arrows on the chart...they will have to be in the buffer index range from 0 - 7.....this means I would have to use the method you described to create at least 2 of the ExtMapBuffers that are only used for calculation...namely.....ExtMapBuffer 5,6,7 and 8

Am I right?
 
I mean....wouldn't I have to do this even if I wanted to use iCustom in another indicator to get the values of the arrow buffers???


Reason: