//------------------------------------------------------------------ #property copyright "© mladen, 2018" #property link "mladenfx@gmail.com" #property description "Volatility bands" //------------------------------------------------------------------ #property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 3 #property indicator_label1 "Volatility band up" #property indicator_type1 DRAW_LINE #property indicator_color1 clrLimeGreen #property indicator_style1 STYLE_DOT #property indicator_label2 "Volatility band middle" #property indicator_type2 DRAW_LINE #property indicator_color2 clrDarkGray #property indicator_style2 STYLE_DOT #property indicator_label3 "Volatility band down" #property indicator_type3 DRAW_LINE #property indicator_color3 clrOrangeRed #property indicator_style3 STYLE_DOT // //--- input parameters // enum enDevType { use_classical, // Use classical deviations use_rooke // Use David Rooke type of deviations }; input int inpBandPeriod = 20; // Bands period period input double inpBandDeviations = 2; // Bands deviations input ENUM_APPLIED_PRICE inpPrice = PRICE_CLOSE; // Price input enDevType inpDeviationsType = use_rooke; // Deviations type // //--- // double bandu[],bandm[],bandd[],prices[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,bandu,INDICATOR_DATA); SetIndexBuffer(1,bandm,INDICATOR_DATA); SetIndexBuffer(2,bandd,INDICATOR_DATA); SetIndexBuffer(3,prices,INDICATOR_CALCULATIONS); //--- indicator short name assignment IndicatorSetString(INDICATOR_SHORTNAME,"Volatility bands ("+(string)inpBandPeriod+","+(string)inpBandDeviations+")"); //--- successful init return (INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator de-initialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { return; } //+------------------------------------------------------------------+ //| 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[]) { if(Bars(_Symbol,_Period)0) { workTema[r][_tema1+instanceNo] = workTema[r-1][_tema1+instanceNo]+alpha*(price -workTema[r-1][_tema1+instanceNo]); workTema[r][_tema2+instanceNo] = workTema[r-1][_tema2+instanceNo]+alpha*(workTema[r][_tema1+instanceNo]-workTema[r-1][_tema2+instanceNo]); workTema[r][_tema3+instanceNo]=workTema[r-1][_tema3+instanceNo]+alpha*(workTema[r][_tema2+instanceNo]-workTema[r-1][_tema3+instanceNo]); } return(workTema[r][_tema3+instanceNo]+3.0*(workTema[r][_tema1+instanceNo]-workTema[r][_tema2+instanceNo])); } // // // In the original article the second method is how deviation is // calculated . It is a questionableble method , but if we apply // standard calculation the bands tend to be "spiky".That is the // reason to have the "UseClassicalDeviations" option // // double iDeviationPlus(double &values[],double &ma[],int period,int i) { double sum=0; if(inpDeviationsType==use_classical) for(int k=0; k=0; k++) sum += (values[i-k]-ma[i]) *(values[i-k]-ma[i]); else for(int k=0; k=0; k++) sum += (values[i-k]-ma[i-k])*(values[i-k]-ma[i-k]); return(MathSqrt(sum/period)); } // //--- // double getPrice(ENUM_APPLIED_PRICE tprice,const double &open[],const double &close[],const double &high[],const double &low[],int i,int _bars) { switch(tprice) { case PRICE_CLOSE: return(close[i]); case PRICE_OPEN: return(open[i]); case PRICE_HIGH: return(high[i]); case PRICE_LOW: return(low[i]); case PRICE_MEDIAN: return((high[i]+low[i])/2.0); case PRICE_TYPICAL: return((high[i]+low[i]+close[i])/3.0); case PRICE_WEIGHTED: return((high[i]+low[i]+close[i]+close[i])/4.0); } return(0); } //+------------------------------------------------------------------+