Combine them together.
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
(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
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.
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)?
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.
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)?
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.
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.
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?

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
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?