You have to check for zero divide errors.
//+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, 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[]) { //--- int begin=!prev_calculated?rates_total-BBandPeriod-1:rates_total-prev_calculated; double bandsUpper,bandsLower; //--- for(int i=begin;i>=0;i--) { bandsUpper=iBands(NULL,PERIOD_CURRENT,BBandPeriod,2,0,PRICE_CLOSE,MODE_UPPER,i); bandsLower=iBands(NULL,PERIOD_CURRENT,BBandPeriod,2,0,PRICE_CLOSE,MODE_LOWER,i); BBandsWidthBuffer[i]=(bandsLower)?(bandsUpper-bandsLower)/bandsLower:BBandsWidthBuffer[i+1]; } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+
Thank you very much Ernst for shedding on light on me as a newbie in mql4 programming.
Mind if I ask about the topic of how to normalize data given by iBands(upper) - iBands(lower) so that a peak will correspond to 100% and a trough to 0%?
Or is it easier to program code to detect a peak/trough formed and turning around by level / tangent/ gradient?
Thank you very much Ernst for shedding on light on me as a newbie in mql4 programming.
Mind if I ask about the topic of how to normalize data given by iBands(upper) - iBands(lower) so that a peak will correspond to 100% and a trough to 0%?
Or is it easier to program code to detect a peak/trough formed and turning around by level / tangent/ gradient?
You're welcome. The easiest way would probably be to apply RSI.
//--- indicator buffers double RSIBuffer[]; double BBandsWidthBuffer[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,RSIBuffer); IndicatorBuffers(2); SetIndexBuffer(1,BBandsWidthBuffer); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, 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[]) { //--- int begin=!prev_calculated?rates_total-BBandPeriod-1:rates_total-prev_calculated; double bandsUpper,bandsLower; //--- for(int i=begin;i>=0;i--) { bandsUpper=iBands(NULL,PERIOD_CURRENT,BBandPeriod,2,0,PRICE_CLOSE,MODE_UPPER,i); bandsLower=iBands(NULL,PERIOD_CURRENT,BBandPeriod,2,0,PRICE_CLOSE,MODE_LOWER,i); BBandsWidthBuffer[i]=(bandsLower)?(bandsUpper-bandsLower)/bandsLower:BBandsWidthBuffer[i+1]; } //--- begin=!prev_calculated?rates_total-BBandPeriod*2-2:rates_total-prev_calculated; //--- for(int i=begin;i>=0;i--) RSIBuffer[i]=iRSIOnArray(BBandsWidthBuffer,0,BBandPeriod,i); //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+
You're welcome. The easiest way would probably be to apply RSI.
RSIBuffer on BBandsWidthBuffer did not quite work. The value grows eventually quite large and offers not much of useful indication.
I have found another thread about calculating the slope/angle of price/indicator at
https://www.mql5.com/en/forum/155802
- 2015.06.06
- www.mql5.com
- 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 could not get bbwidthBuffer[i] drawn by the terminal. It would show a blank indicator window beneath the price chart. What is wrong with my coding?