Hello everyone!
How can I add signal/buffer to this indicator to open and exit trades? I tried to add another buffer and read it, but I get numbers like "2.3454682334345 e-308" or just 0.
Perhaps you could post the code where you've made the changes? That way people here will be better able to help...
Perhaps you could post the code where you've made the changes? That way people here will be better able to help...
Hi Seng,
Sure...But I didn't change much of it. I will put it in yellow background for easier understanding. This is the full code, which can be found in the codebase.
My idea was to add a buffer that can give me a signal when the indicator generates signals. I also ran the indicator in backtest mode to see how many signals the indicator gives itself in 3 years (used the daily chart) and surprisingly it gave like 3-4 signals.
Any idea why?
//+------------------------------------------------------------------+ //| Waddah_Attar_Explosion.mq4 | //| Copyright © 2006, Eng. Waddah Attar | //| waddahattar@hotmail.com | //+------------------------------------------------------------------+ #property copyright "Copyright © 2006, Eng. Waddah Attar" #property link "waddahattar@hotmail.com" //---- indicator version #property version "1.00" //---- drawing the indicator in a separate window #property indicator_separate_window //---- number of indicator buffers 4 #property indicator_buffers 5 //---- only three plots are used #property indicator_plots 3 //+-----------------------------------+ //| Indicator drawing parameters | //+-----------------------------------+ //---- drawing the indicator as a three-color histogram #property indicator_type1 DRAW_COLOR_HISTOGRAM //---- Gray, Lime and Magenta colors are used for the three-color histogram #property indicator_color1 clrGray,clrLime,clrRed //---- indicator line is a solid one #property indicator_style1 STYLE_SOLID //---- indicator line width is equal to 2 #property indicator_width1 2 //---- displaying the indicator label #property indicator_label1 "MACD" //---- drawing the indicator as a line #property indicator_type2 DRAW_LINE //---- use blue color for the line #property indicator_color2 Blue //---- indicator line is a solid curve #property indicator_style2 STYLE_SOLID //---- indicator line width is equal to 2 #property indicator_width2 2 //---- displaying the signal line label #property indicator_label2 "Signal Line" //---- drawing the indicator as a line #property indicator_type3 DRAW_LINE //---- use red color for the line #property indicator_color3 clrGold //---- the indicator line is a dash-dotted curve #property indicator_style3 STYLE_DASHDOTDOT //---- indicator line width is equal to 1 #property indicator_width3 1 //---- displaying the signal line #property indicator_label3 "DeadZonePip Level" #property indicator_minimum 0.0 //+------------------------------------+ //| Indicator input parameters | //+------------------------------------+ input int Fast_MA = 20; // Period of the fast MACD moving average input int Slow_MA = 40; // Period of the slow MACD moving average input int BBPeriod=20; // Bollinger period input double BBDeviation=2.0; // Number of Bollinger deviations input int Sensetive=150; input int DeadZonePip=400; input int ExplosionPower=15; input int TrendPower=150; input bool AlertWindow=false; input int AlertCount=2; input bool AlertLong=false; input bool AlertShort=false; input bool AlertExitLong=false; input bool AlertExitShort=false; //+-----------------------------------+ //---- declaration of the integer variables for the start of data calculation int min_rates_total; //---- declaration of integer variables for the indicators handles int MACD_Handle,BB_Handle; //---- declaration of global variables double bask,bbid; int LastTime1,LastTime2,LastTime3,LastTime4,Status,PrevStatus; //---- declaration of dynamic arrays that //---- will be used as indicator buffers double IndBuffer1[],ColorIndBuffer1[],IndBuffer2[],IndBuffer3[]; double signalTrades[]; //+------------------------------------------------------------------+ //| MACD indicator initialization function | //+------------------------------------------------------------------+ void OnInit() { //---- initialization of variables of the start of data calculation min_rates_total=BBPeriod+1; //---- initialization of variables LastTime1=1; LastTime2=1; LastTime3=1; LastTime4=1; Status=0; PrevStatus=-1; //---- getting handle of the iMACD indicator MACD_Handle=iMACD(NULL,0,Fast_MA,Slow_MA,9,PRICE_CLOSE); if(MACD_Handle==INVALID_HANDLE)Print(" Failed to get handle of the iMACD indicator"); //---- getting handle of the iBands indicator BB_Handle=iBands(NULL,0,BBPeriod,0,BBDeviation,PRICE_CLOSE); if(BB_Handle==INVALID_HANDLE)Print(" Failed to get handle of the iBands indicator"); //---- set IndBuffer1[] dynamic array as an indicator buffer SetIndexBuffer(0,IndBuffer1,INDICATOR_DATA); //---- performing the shift of the beginning of the indicator drawing PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,min_rates_total); //---- setting the indicator values that won't be visible on a chart PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0); //---- indexing the elements in buffers as timeseries ArraySetAsSeries(IndBuffer1,true); //---- set ColorIndBuffer1[] as a colored index buffer SetIndexBuffer(1,ColorIndBuffer1,INDICATOR_COLOR_INDEX); //---- performing the shift of the beginning of the indicator drawing PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,min_rates_total); //---- indexing the elements in buffers as timeseries ArraySetAsSeries(ColorIndBuffer1,true); //---- set IndBuffer2[] as an indicator buffer SetIndexBuffer(2,IndBuffer2,INDICATOR_DATA); //---- performing the shift of the beginning of the indicator drawing PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,min_rates_total); //---- setting the indicator values that won't be visible on a chart PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,0.0); //---- indexing the elements in buffers as timeseries ArraySetAsSeries(IndBuffer2,true); //---- set IndBuffer3[] as an indicator buffer SetIndexBuffer(3,IndBuffer3,INDICATOR_DATA); //---- performing the shift of the beginning of the indicator drawing PlotIndexSetInteger(3,PLOT_DRAW_BEGIN,min_rates_total); //---- setting the indicator values that won't be visible on a chart PlotIndexSetDouble(3,PLOT_EMPTY_VALUE,0.0); //---- indexing the elements in buffers as timeseries ArraySetAsSeries(IndBuffer3,true); SetIndexBuffer(4,signalTrades); ArraySetAsSeries(signalTrades,true); //---- creating a name for displaying in a separate sub-window and in a tooltip IndicatorSetString(INDICATOR_SHORTNAME,"Waddah Attar Explosion"); //---- determination of accuracy of displaying the indicator values IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1); //---- initialization end } //+------------------------------------------------------------------+ //| MACD iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, // number of bars in history at the current tick const int prev_calculated, // number of bars calculated at previous call 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[]) { //---- checking the number of bars to be enough for the calculation if(BarsCalculated(MACD_Handle)<rates_total || BarsCalculated(BB_Handle)<rates_total || rates_total<min_rates_total) return(0); //---- declarations of local variables int limit,to_copy,bar; double MACD[],BandsUp[],BandsDn[]; double Trend1,Trend2,Explo1,Explo2,Dead; double pwrt,pwre,Ask,Bid; string SirName; //---- indexing elements in arrays as timeseries ArraySetAsSeries(spread,true); ArraySetAsSeries(close,true); ArraySetAsSeries(MACD,true); ArraySetAsSeries(BandsUp,true); ArraySetAsSeries(BandsDn,true); //---- calculation of the 'first' starting index for the bars recalculation loop if(prev_calculated>rates_total || prev_calculated<=0) // checking for the first start of the indicator calculation { limit=rates_total-min_rates_total-1; // starting index for calculation of all bars } else { limit=rates_total-prev_calculated; // starting index for calculation of new bars } to_copy=limit+2; //--- copy newly appeared data in the arrays if(CopyBuffer(BB_Handle,1,0,to_copy,BandsUp)<=0) return(0); if(CopyBuffer(BB_Handle,2,0,to_copy,BandsDn)<=0) return(0); to_copy+=2; if(CopyBuffer(MACD_Handle,0,0,to_copy,MACD)<=0) return(0); //---- main indicator calculation loop for(bar=limit; bar>=0; bar--) { Trend1=(MACD[bar] - MACD[bar+1])*Sensetive; Trend2=(MACD[bar+2] - MACD[bar+3])*Sensetive; Explo1=BandsUp[bar] - BandsDn[bar]; Explo2=BandsUp[bar+1] - BandsDn[bar+1]; Dead=_Point*DeadZonePip; IndBuffer1[bar]=MathAbs(Trend1); Bid=close[bar]; Ask=Bid+spread[bar]; if(Trend1>0) ColorIndBuffer1[bar]=1; if(Trend1<0) ColorIndBuffer1[bar]=2; IndBuffer2[bar]=Explo1; IndBuffer3[bar]=Dead; if(bar==0) { if(Trend1>0 && Trend1>Explo1 && Trend1>Dead && Explo1>Dead && Explo1>Explo2 && Trend1>Trend2 && LastTime1<AlertCount && AlertLong==true && Ask!=bask) { pwrt=100*(Trend1 - Trend2)/Trend1; pwre=100*(Explo1 - Explo2)/Explo1; bask=Ask; if(pwre>=ExplosionPower && pwrt>=TrendPower) { signalTrades[0]=1.0; SirName=""; StringConcatenate(SirName,LastTime1,"- ",Symbol()," - BUY "," (", DoubleToString(bask,_Digits),") Trend PWR ", DoubleToString(pwrt,0)," - Exp PWR ",DoubleToString(pwre,0)); if(AlertWindow==true) Alert(SirName); else Print(SirName); LastTime1++; } Status=1; } if(Trend1<0 && MathAbs(Trend1)>Explo1 && MathAbs(Trend1)>Dead && Explo1>Dead && Explo1>Explo2 && MathAbs(Trend1)>MathAbs(Trend2) && LastTime2<AlertCount && AlertShort==true && Bid!=bbid) { pwrt=100*(MathAbs(Trend1) - MathAbs(Trend2))/MathAbs(Trend1); pwre=100*(Explo1 - Explo2)/Explo1; bbid=Bid; if(pwre>=ExplosionPower && pwrt>=TrendPower) { signalTrades[0]=2.0; SirName=""; StringConcatenate(SirName,LastTime2,"- ",Symbol()," - Sell "," (", DoubleToString(bask,_Digits),") Trend PWR ", DoubleToString(pwrt,0)," - Exp PWR ",DoubleToString(pwre,0)); if(AlertWindow==true) Alert(SirName); else Print(SirName); LastTime2++; } Status=2; } if(Trend1>0 && Trend1<Explo1 && Trend1<Trend2 && Trend2>Explo2 && Trend1>Dead && Explo1>Dead && LastTime3<=AlertCount && AlertExitLong==true && Bid!=bbid) { bbid=Bid; SirName=""; StringConcatenate(SirName,LastTime3,"- ",Symbol()," - Exit BUY "," ",DoubleToString(bbid,_Digits)); signalTrades[0]=-1.0; if(AlertWindow==true) Alert(SirName); else Print(SirName); Status=3; LastTime3++; } if(Trend1<0 && MathAbs(Trend1)<Explo1 && MathAbs(Trend1)<MathAbs(Trend2) && MathAbs(Trend2)>Explo2 && Trend1>Dead && Explo1>Dead && LastTime4<=AlertCount && AlertExitShort==true && Ask!=bask) { bask=Ask; SirName=""; StringConcatenate(SirName,LastTime4,"- ",Symbol()," - Exit SELL "," ",DoubleToString(bask,_Digits)); signalTrades[0]=-2.0; if(AlertWindow==true) Alert(SirName); else Print(SirName); Status=4; LastTime4++; } PrevStatus=Status; } if(Status!=PrevStatus) { LastTime1=1; LastTime2=1; LastTime3=1; LastTime4=1; } } //---- return(rates_total); } //+------------------------------------------------------------------+
Hi Seng,
Sure...But I didn't change much of it. I will put it in yellow background for easier understanding. This is the full code, which can be found in the codebase.
My idea was to add a buffer that can give me a signal when the indicator generates signals. I also ran the indicator in backtest mode to see how many signals the indicator gives itself in 3 years (used the daily chart) and surprisingly it gave like 3-4 signals.
Any idea why?
Ok, I did some tests, and found that
SetIndexBuffer(4,signalTrades); ArraySetAsSeries(signalTrades,true);
should be changed to:
SetIndexBuffer(4,signalTrades,INDICATOR_CALCULATIONS); PlotIndexSetInteger(4,PLOT_SHOW_DATA,false); ArraySetAsSeries(signalTrades,true);
before I'm able to retrieve the values of signalTrades in my test EA.
Next, I realised I need to set these flags to true for signalTrades to be filled:
input bool AlertLong=true; input bool AlertShort=true; input bool AlertExitLong=true; input bool AlertExitShort=true;
Lastly, you're right that signals are rare, but you can lower the values of DeadZonePip, ExplosionPower and TrendPower to get more signals.
Ok, I did some tests, and found that
should be changed to:
before I'm able to retrieve the values of signalTrades in my test EA.
Next, I realised I need to set these flags to true for signalTrades to be filled:
Lastly, you're right that signals are rare, but you can lower the values of DeadZonePip, ExplosionPower and TrendPower to get more signals.
Thank you Seng!
It worked in someway, but for some reason if I run a backtest from, lets say 2011 up to now, I get like 2-3 signals.
Then if I run the same test but this time from 2019 up to now, I get only 2 signals.
This happens even if I try backtesting the pure indicator. I'm backtesting in OHLC mode to save some time.
This is how I'm getting the signal from the buffer.
int wae() { CopyBuffer(wHandle,4,0,1,wSignal2); //signal buffer if(wSignal2[0]==1) return 1; //buy if(wSignal2[0]==2) return 2; //sell if(wSignal2[0]==-1) return -1; //exit buy if(wSignal2[0]==-2) return -2; //exit sell return 0; }
I also changed the default parameters to some lower ones that can give me more signals, but it does not seems to work in backtest.
Its like in backtest, when it gives the first signal, it remains "trapped" in some point. I checked the code of the indicator, but couldn't figure it out.
Any idea why this happens?
In fact, I don't know if the indicator is ment to give signals everytime the bars goes over the line, but I would like to use this like a volume indicator/exit indicator (I think its designed for volume, but honstly I think it shows entry points and exits pretty well)
How can I incorporate this into an EA? Maybe just putting the logic of the indicator as a function?
Thank you Seng!
It worked in someway, but for some reason if I run a backtest from, lets say 2011 up to now, I get like 2-3 signals.
Then if I run the same test but this time from 2019 up to now, I get only 2 signals.
This happens even if I try backtesting the pure indicator. I'm backtesting in OHLC mode to save some time.
This is how I'm getting the signal from the buffer.
I also changed the default parameters to some lower ones that can give me more signals, but it does not seems to work in backtest.
Its like in backtest, when it gives the first signal, it remains "trapped" in some point. I checked the code of the indicator, but couldn't figure it out.
Any idea why this happens?
You're right. The problem lies with these status flags:
int LastTime1,LastTime2,LastTime3,LastTime4,Status,PrevStatus;
Looking at the code, I seriously think that they were not being set/reset properly. E.g. "PrevStatus=Status;" must not be called right after the 4 big 'ifs' that checks the open/close conditions. So that is likely the direction you should head towards in checking through the execution.
In fact, I don't know if the indicator is ment to give signals everytime the bars goes over the line, but I would like to use this like a volume indicator/exit indicator (I think its designed for volume, but honstly I think it shows entry points and exits pretty well)
How can I incorporate this into an EA? Maybe just putting the logic of the indicator as a function?
It can be done, just remove all indicator-specific lines and group the remaining lines into a function in your EA. May not be necessary to debug the status flags issues if you're going to EA path, because in EA, you'll have access to other means to check order/trade status.
It can be done, just remove all indicator-specific lines and group the remaining lines into a function in your EA. May not be necessary to debug the status flags issues if you're going to EA path, because in EA, you'll have access to other means to check order/trade status.
Hmm I see...so the status thing is messing around.
What do you think of this? All buffer arrays are set as series.
I want to use this indicator as exit indicator, but it seems that it can be a good entry/volume indicator too. Thoughts?
int wae() { CopyBuffer(macdHandle,0,0,6,macd); CopyBuffer(bbHandle,1,0,6,bbUp); CopyBuffer(bbHandle,2,0,6,bbDown); double Trend1=(macd[0]-macd[1])*Sensetive; double Trend2=(macd[2] - macd[3])*Sensetive; double Explo1=bbUp[0] - bbDown[0]; double Explo2=bbUp[1] - bbDown[1]; Ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK); Bid=SymbolInfoDouble(Symbol(),SYMBOL_BID); double pwrt,pwre; double Dead=_Point*DeadZonePip; int retVal=0; if(Trend1>0 && Trend1>Explo1 && Trend1>Dead && Explo1>Dead && Explo1>Explo2 && Trend1>Trend2 && Ask!=bask) { pwrt=100*(Trend1 - Trend2)/Trend1; pwre=100*(Explo1 - Explo2)/Explo1; bask=Ask; if(pwre>=ExplosionPower && pwrt>=TrendPower) { retVal=1;//BUY } } if(Trend1<0 && MathAbs(Trend1)>Explo1 && MathAbs(Trend1)>Dead && Explo1>Dead && Explo1>Explo2 && MathAbs(Trend1)>MathAbs(Trend2) && Bid!=bbid) { pwrt=100*(MathAbs(Trend1) - MathAbs(Trend2))/MathAbs(Trend1); pwre=100*(Explo1 - Explo2)/Explo1; bbid=Bid; if(pwre>=ExplosionPower && pwrt>=TrendPower) { retVal=2;//SELL } } if(Trend1>0 && Trend1<Explo1 && Trend1<Trend2 && Trend2>Explo2 && Trend1>Dead && Explo1>Dead && Bid!=bbid) { bbid=Bid; retVal=-1;//Exit BUY } if(Trend1<0 && MathAbs(Trend1)<Explo1 && MathAbs(Trend1)<MathAbs(Trend2) && MathAbs(Trend2)>Explo2 && Trend1>Dead && Explo1>Dead && Ask!=bask) { bask=Ask; retVal=-2;//Exit SELL } return retVal; }
Hmm I see...so the status thing is messing around.
What do you think of this? All buffer arrays are set as series.
I want to use this indicator as exit indicator, but it seems that it can be a good entry/volume indicator too. Thoughts?
I think you're almost done :). Here're my thoughts:
- Consider looking from bar 1 onwards, not 0... because 0 refers to the current bar, and will still change before the the next bar. So i would change all my references to macd, bbup, bbdown to use their indexes from 1 onwards.
- I won't call wae every tick. instead, i'll keep track of the latest bar start time, to make sure that i call wae only when the bar changes.
static datetime latestbartime = 0; if (latestbartime<iTime(NULL,0,0)) { // call wae latestbartime = iTime(NULL,0,0); }
- There is probably no need for bbid and bask anymore.
I think you're almost done :). Here're my thoughts:
- Consider looking from bar 1 onwards, not 0... because 0 refers to the current bar, and will still change before the the next bar. So i would change all my references to macd, bbup, bbdown to use their indexes from 1 onwards.
- I won't call wae every tick. instead, i'll keep track of the latest bar start time, to make sure that i call wae only when the bar changes.
- There is probably no need for bbid and bask anymore.
Like this?
int wae() { CopyBuffer(macdHandle,0,0,6,macd); CopyBuffer(bbHandle,1,0,6,bbUp); CopyBuffer(bbHandle,2,0,6,bbDown); double Trend1=(macd[1]-macd[2])*Sensetive; double Trend2=(macd[3] - macd[4])*Sensetive; double Explo1=bbUp[1] - bbDown[1]; double Explo2=bbUp[2] - bbDown[2]; //Ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK); //Bid=SymbolInfoDouble(Symbol(),SYMBOL_BID); double pwrt,pwre; double Dead=_Point*DeadZonePip; int retVal=0; if(Trend1>0 && Trend1>Explo1 && Trend1>Dead && Explo1>Dead && Explo1>Explo2 && Trend1>Trend2 && /*Ask!=bask*/) { pwrt=100*(Trend1 - Trend2)/Trend1; pwre=100*(Explo1 - Explo2)/Explo1; //bask=Ask; if(pwre>=ExplosionPower && pwrt>=TrendPower) { retVal=1;//BUY } } if(Trend1<0 && MathAbs(Trend1)>Explo1 && MathAbs(Trend1)>Dead && Explo1>Dead && Explo1>Explo2 && MathAbs(Trend1)>MathAbs(Trend2) /*&& Bid!=bbid*/) { pwrt=100*(MathAbs(Trend1) - MathAbs(Trend2))/MathAbs(Trend1); pwre=100*(Explo1 - Explo2)/Explo1; //bbid=Bid; if(pwre>=ExplosionPower && pwrt>=TrendPower) { retVal=2;//SELL } } if(Trend1>0 && Trend1<Explo1 && Trend1<Trend2 && Trend2>Explo2 && Trend1>Dead && Explo1>Dead /*&& Bid!=bbid*/) { //bbid=Bid; retVal=-1;//Exit BUY } if(Trend1<0 && MathAbs(Trend1)<Explo1 && MathAbs(Trend1)<MathAbs(Trend2) && MathAbs(Trend2)>Explo2 && Trend1>Dead && Explo1>Dead /*&& Ask!=bask*/) { //bask=Ask; retVal=-2;//Exit SELL } return retVal; }
I used the part that I posted in the last post and got this results, lol:
It seems that, for some reason I have a valid setup to enter, but at the same time it gets wiped out because of wae. Maybe because I was using the current bar 0?
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hello everyone!
How can I add signal/buffer to this indicator to open and exit trades? I tried to add another buffer and read it, but I get numbers like "2.3454682334345 e-308" or just 0.