How to check 3 RSI values against the Bollinger Bands?

喜夏-厌秋 提交于 2019-12-10 12:06:46

问题


There are Bollinger Bands with three RSI running in the basement.

I want to do a check on the signal in such a way that when 3 RSI struck the zone of the upper Bbands, there was a signal down and vice versa:

int start(){
   double ma, stdev;
   int i, limit, count=IndicatorCounted();

   if(count<0) return(0);
   limit=Bars-count;  
   if(limit>1) limit=Bars-1;

    for(i=limit; i>=0; i--) {
        RSI[i] =iRSI(Symbol(),Period(),rsi_period,  PRICE_CLOSE,i);
        RSI2[i]=iRSI(Symbol(),Period(),rsi_period_2,PRICE_CLOSE,i);
        RSI3[i]=iRSI(Symbol(),Period(),rsi_period_3,PRICE_CLOSE,i);
        }

    for(i=limit; i>=0; i--) {
        ma=iMAOnArray(RSI3,0,bb_period,0,0,i); // midle line
        stdev=iStdDevOnArray(RSI3,0,bb_period,0,0,i); // dev
        BBUP[i]=ma+bb_dev*stdev; // up line
        BBDOWN[i]=ma-bb_dev*stdev; // down line
        UP[i]=0;
        DOWN[i]=0;
        }

    if(limit<Bars-1) limit++;

    for(i=limit; i>0; i--) {          
        if(RSI[i] <= BBDOWN[i] && RSI[i+1] > BBDOWN[i+1] && RSI2[i] <= BBDOWN[i] && RSI2[i+1] > BBDOWN[i+1] && RSI3[i] <= BBDOWN[i] && RSI3[i+1] > BBDOWN[i+1]){
           DOWN[i] = iLow(_Symbol, _Period, i);
           }
        if(RSI[i] >= BBUP[i] && RSI[i+1] < BBUP[i+1] &&W RSI2[i] >= BBUP[i] && RSI2[i+1] < BBUP[i+1] && RSI3[i] >= BBUP[i] && RSI3[i+1] < BBUP[i+1]){
           UP[i]= iHigh(_Symbol, _Period, i);
           }
    }

The whole problem is that I have very crooked signals.

Appear where they should not be, and there is no where to be.


回答1:


THE BEST PRACTICE:


Step 0: Let's first agree in written WHAT is the actual TARGET:

If the TARGET is to compute & paint on GUI the Bollinger Bands on RSI3[] values, the best way to do this is to use:

UPPER[i] = iBandsOnArray( RSI3,                       // ArrayAsSeries[]
                          array_calculation_depth,    // reduce overheads
                          BB_MA_period,               // BBands period
                          BB_StDev_MUL,               // how many sigmas
                          BB_Zero_Shift,              // #DEFINE BB_Zero_Shift 0
                          MODE_UPPER,                 // BBands upper line
                          i                           // shifting operator[i]
                          );

This way one may efficiently produce each of the { MODE_UPPER | MODE_MAIN | MODE_LOWER } Bollinger Bands lines here, consistently generated over dimension-less RSI3[] data, thus protecting the sense of any additive operations in signal-composition(s) with other, dimension-less data, as in { RSI2[], RSI[] }.


Step 1: visually check the lines to validate any signal-conditions:

Given the GUI shows lines accordingly, one may try to compose signal-conditions. The "hot"-bar [0] is a live-bar, where novice may encounter tricking signalling situations, if not handled with due professional care.


Step 2: implement signal-conditions in code:

Only after Step 0) & 1) took place and both meet one's own prior expectations, any code starts to make sense to get built.




回答2:


From MQL4 docs https://docs.mql4.com/indicators/imaonarray

Unlike iMA(...), the iMAOnArray() function does not take data by symbol name, timeframe, the applied price. The price data must be previously prepared. The indicator is calculated from left to right. To access to the array elements as to a series array (i.e., from right to left), one has to use the ArraySetAsSeries() function.

RSI3 is currently orientated right to left (0 is most recent time point, limit is furthest element). Same issue with iStdDevOnArray()

Fix those issues and it should work as you want. Whether there is any value in drawing Bollinger bands on RSI is another matter


Update

The function ArraySetAsSeries() can be used to swap the array between left-to-right and right-to-left

When you first initialise the RSI arrays ( in the OnInit() ) tell MetaTrader Terminal that they are timeseries.

ArraySetAsSeries(RSI1,True);
ArraySetAsSeries(RSI2,True);
ArraySetAsSeries(RSI3,True);

Then in main body, add ArraySetAsSeries(RSI3,False); before your second for loop to swap the array orientation. Then ArraySetAsSeries(RSI3,True); after the loop to restore the array orientation.

for(i=limit; i>=0; i--) {
    RSI[i ] = iRSI(Symbol(),Period(),rsi_period,PRICE_CLOSE,i);
    RSI2[i] = iRSI(Symbol(),Period(),rsi_period_2,PRICE_CLOSE,i);
    RSI3[i] = iRSI(Symbol(),Period(),rsi_period_3,PRICE_CLOSE,i);
}

ArraySetAsSeries(RSI3,False);
for(i=limit; i>=0; i--) {
    ma=iMAOnArray(RSI3,0,bb_period,0,0,i); // midle line
    stdev=iStdDevOnArray(RSI3,0,bb_period,0,0,i); // dev
    BBUP[i]=ma+bb_dev*stdev; // up line
    BBDOWN[i]=ma-bb_dev*stdev; // down line
    UP[i]=0;
    DOWN[i]=0;
}  
ArraySetAsSeries(RSI3,True);

if(limit<Bars-1) limit++;
for(i=limit; i>0; i--) {
    if( RSI[i] <= BBDOWN[i] && 
        RSI[i+1] > BBDOWN[i] && 
        RSI2[i] <= BBDOWN[i] && 
        RSI2[i+1] > BBDOWN[i] && 
        RSI3[i] <= BBDOWN[i] && 
        RSI3[i+1] > BBDOWN[i]) {

        DOWN[i] = iLow(_Symbol, _Period, i);
    }
    if( RSI[i] >= BBUP[i] && 
        RSI[i+1] < BBUP[i+1] && 
        RSI2[i] >= BBUP[i] && 
        RSI2[i+1] < BBUP[i+1] && 
        RSI3[i] >= BBUP[i] && 
        RSI3[i+1] < BBUP[i+1]) {

        UP[i]= iHigh(_Symbol, _Period, i);
    }
}

Basic indicator structure

You need to go through the MQL4 Documentation and learn the proper structure of an indicator. There needs to be an OnInit() function where you initialise values. Then an OnCalculate() function where you fill the indicator buffers.

//+-----------------------------------------------------------------+
//| Custom indicator initialization function                        |
//+-----------------------------------------------------------------+
int OnInit()
  {
   //--- indicator buffers mapping

   ArraySetAsSeries(RSI3,True);
   //---
   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[])
  {
   // Do your calculations here
   //--- return value of prev_calculated for next call
   return(rates_total);
  }

If you use iBandsOnArray() to calculate Bollinger bands you won't need to swap the array direction after it is set in OnInit()

If the indicator is compiling but crashing, you will need to debug it. Simplest way is to look at the errors in the log and add PrintFormat() statements throughout your code so you can see what the indicator is doing at different points and see where it crashes.



来源:https://stackoverflow.com/questions/44132346/how-to-check-3-rsi-values-against-the-bollinger-bands

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!