Question: Bolinger bands

 
Hi all,

Need a little assistance with the below function that for some reason doesn't working for me:

extern double VolKatan = 3;

bool CheckVolKatan(){

double CurrentVol = iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,0);
double PrevVol = iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,1);

return (CurrentVol-PrevVol)>= VolKatan;
Print("VolKatan: ", VolKatan);
   
   
}

trying to check the current volatility comparing to previos bar volatility.

Thanks!
 
steve_o:
extern double VolKatan = 3;
bool CheckVolKatan(){

double CurrentVol = iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,0);
double PrevVol = iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,1);

return (CurrentVol-PrevVol)>= VolKatan;
Print("VolKatan: ", VolKatan);
   
   
}
 
steve_o:
trying to check the current volatility comparing to previos bar volatility.

I am not sure what you are trying to do here. Bollinger bands, and the iBands() function, are a measure of price, not a measure of volatility.

Your variables CurrentVol and PrevVol are going to be set to prices such as 1.12155 and 1.12238 (e.g. on EUR/USD). The difference between these prices is only ever going to exceed 3 (VolKatan) on instruments where the price is a large number, e.g. USD/JPY, or gold, or an equity index such as the DAX.

As a more minor matter of detail, the code will never get to this line:

Print("VolKatan: ", VolKatan);

... because the function returns and exits in the previous line.

 
steve_o:

Correction, I''m using this one to compare the gap between bolinger bands (upper on this case) of current bar and previous:
extern double VolKatan = 4;
double pips;

void OnInit()
  {
//---
  double ticksize = MarketInfo(Symbol(),MODE_TICKSIZE);
         if (ticksize == 0.00001 || ticksize == 0.001)
         pips = ticksize*10;
         else pips = ticksize;
  
//---
  }

bool CheckVolKatan(){

double CurrentVol = iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,0);
double PrevVol = iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,1);

if (CurrentVol-PrevVol >= VolKatan*pips)
   return (true);
      else return (false);

}
 
 
steve_o:
Correction, I''m using this one to compare the gap between bolinger bands (upper on this case) of current bar and previous: 

Well, that should work if the upper Bollinger band on the current bar is at least 4 pips higher than on the previous bar. (But only higher, not lower.) For example, your function currently returns true on AUD/USD D1.

But you are testing not only volatility, but also price movement. The upper Bollinger band can rise by 4 pips either because of an increase in volatility, or because the price action and moving average has risen, or a mixture of both. If the price rises in a steady fashion, with volatility remaining constant, your function can still return true.

 
jjc:

Well, that should work if the upper Bollinger band on the current bar is at least 4 pips higher than on the previous bar. (But only higher, not lower.) For example, your function currently returns true on AUD/USD D1.

But you are testing not only volatility, but also price movement. The upper Bollinger band can rise by 4 pips either because of an increase in volatility, or because the price action and moving average has risen, or a mixture of both. If the price rises in a steady fashion, with volatility remaining constant, your function can still return true.

Thanks jjc!

This is what i want from this function: to return true when the gap between the upper bands is 4  (or any other value I'll choose).

For some reason this is not working- do you see any reason for this on the code I attached.

Thanks. 

 
steve_o:

Please note the following:

  1. Bolinger Bands are made up of a central moving average and with upper and lower bands set at a certain ratio of the Standard Deviation of that Moving average. Although the Standard Deviation is a measure of volatility, the upper and lower bands however are not. A price change on the bands, can be due to either a change in the Standard Deviation or a change in the Moving Average, so you cannot rely on that change to measure volatility.
  2. A more accurate way of measuring volatility is to use the Standard Deviation iStdDev() (used in Bollinger Bands) or to use Average True Range iATR() (used in Keltner Channels).
  3. The current bar is always in a state of flux, meaning the the Close[0] is constantly changing, so any indicator based on the Close price of the current bar will also be in a state of constant update. Your "iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,0)" will also exhibit the same behavior. So depending on how your strategy works, consider comparing [2] and [1] instead of [1] and [0].
 
FMIC:

Please note the following:

  1. Bolinger Bands are made up of a central moving average and with upper and lower bands set at a certain ratio of the Standard Deviation of that Moving average. Although the Standard Deviation is a measure of volatility, the upper and lower bands however are not. A price change on the bands, can be due to either a change in the Standard Deviation or a change in the Moving Average, so you cannot rely on that change to measure volatility.
  2. A more accurate way of measuring volatility is to use the Standard Deviation iStdDev() (used in Bollinger Bands) or to use Average True Range iATR() (used in Keltner Channels).
  3. The current bar is always in a state of flux, meaning the the Close[0]is constantly changing, so any indicator based on the Close price of thecurrent bar will also be in a state of constant update. Your"iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,0)" will also exhibit thesame behavior. So depending on how your strategy works, consider comparing[2] and [1] instead of [1] and [0].

Hi FMIC,

Tried this with compring bars [2] and [1] but still getting wrong entries (some of the trades open when the value is less then 4).

 Will try it now with iStdDev()

 Thanks!

 
steve_o: Tried this with compring bars [2] and [1] but still getting wrong entries (some of the trades open when the value is less then 4). Will try it now with iStdDev()
Since you did not provide the rest of your code, we are unable to verify the logic of your code in order to see if there is another reason for the problem.
 
FMIC:
Since you did not provide the rest of your code, we are unable to verify the logic of your code in order to see if there is another reason for the problem.
you're right:-)- see b
//+------------------------------------------------------------------+
//|                                                         test.mq4 |
//|                                                             test |
//|                                             https://www.test.com |
//+------------------------------------------------------------------+
#property copyright "test"
#property link      "https://www.test.com"
#property version   "1.00"
#property strict

extern int TakeProfit=78;
extern int StopLoss=30;

int MagicNum = 1234;

extern double LotSize = 0.01;
extern bool UseTrailingStop = true;
extern int WhenToTrail = 60;
extern int TrailAmount = 12;
extern double VolKatan = 4;

double pips;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
void OnInit()
  {
//---
  double ticksize = MarketInfo(Symbol(),MODE_TICKSIZE);
         if (ticksize == 0.00001 || ticksize == 0.001)
         pips = ticksize*10;
         else pips = ticksize;
  
//---
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
//---
void OnTick()
  {
//---
 if (UseTrailingStop)AdjustTrail();
  //if (IsNewCandle());
  //if (Anan());
  bool check;
      check = (IsNewCandle()&& CheckSar());
      
      if ((check==true)&&(OpenOredrsThisPair(Symbol())<1))
      { 
      OrderSend(Symbol(), OP_BUY, LotSize, Ask, 1, Ask-(StopLoss*pips),Ask+(TakeProfit*pips)
   ," test Long Position",MagicNum,0,Green);
   return;
   }

   
  }
//+------------------------------------------------------------------+
bool IsNewCandle()
{
   static int BarsOnChart = 0;
   if (Bars == BarsOnChart)
   return (false);
   BarsOnChart = Bars;
   return(true);
}

//+------------------------------------------------------------------+
bool CheckSar (){

double CurrentSar = iSAR(NULL,0,0.02,0.2,0);

if (Ask > CurrentSar)
   return (true);
      else return (false);
      } 
//+------------------------------------------------------------------+
bool CheckVolKatan(){

double CurrentVol = iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,1);
double PrevVol = iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,2);

if (CurrentVol-PrevVol >= VolKatan*pips)
   return (true);
      else return (false);

}

//+------------------------------------------------------------------+
int OpenOredrsThisPair(string pair)
{
int total=0;
   for(int i=OrdersTotal()-1; i>=0; i--)
   {
   OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
   if(OrderSymbol()==pair) total++;
   }
   return(total);
}

//+------------------------------------------------------------------+
void AdjustTrail()
{
   for (int b=OrdersTotal()-1;b>=0;b--)
   {
   if(OrderSelect(b,SELECT_BY_POS,MODE_TRADES))
      if(OrderMagicNumber()==MagicNum)
         if(OrderSymbol()==Symbol())
            if(OrderType()==OP_BUY)
               if(Bid-OrderOpenPrice()>WhenToTrail*pips)
                 if(OrderStopLoss()<Bid-pips*TrailAmount)
                  OrderModify(OrderTicket(),OrderOpenPrice(),Bid-(pips*TrailAmount),OrderTakeProfit(),0,CLR_NONE);
   }
   }
   
//+------------------------------------------------------------------+
elow:
 
steve_o:
you're right:-)- see below:
This code doesn't seem to use the CheckVolkatan() function. It exists, but is not called from anywhere. It has no effect, and can currently be removed from the EA without preventing it compiling.
Reason: