//+------------------------------------------------------------------+
//|                                               KeltnerChannel.mq4 |
//+------------------------------------------------------------------+
#property copyright "www.forex-station.com"
#property link      "www.forex-station.com"
#property strict
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_label1  "Upper Keltner band"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrLimeGreen
#property indicator_width1  2
#property indicator_label2  "Middle Keltner band"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrLimeGreen
#property indicator_width2  2
#property indicator_label3  "Lower Keltner band"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrLimeGreen
#property indicator_width3  2

input int                MaPeriod        = 14;                // Ma period;
input ENUM_MA_METHOD     MaMode          = MODE_LWMA;         // Ma method
input ENUM_APPLIED_PRICE PriceMode       = PRICE_CLOSE;       // Ma price
input int                AtrPeriod       = 21;                // Atr period
input double             K               = 2;                 // Atr bands multiplier
enum  enAtrMode
      {
         atr_Rng,                                             // Atr band level calculated using range
         atr_Atr                                              // Atr band level calculated using atr
      };
input enAtrMode          AtrMode         = atr_Rng;          

double upK[],mid[],dnK[];

//+------------------------------------------------------------------+
//|                                                                   
//+------------------------------------------------------------------+

int OnInit()
{
   SetIndexBuffer(0,upK,INDICATOR_DATA); 
   SetIndexBuffer(1,mid,INDICATOR_DATA);
   SetIndexBuffer(2,dnK,INDICATOR_DATA);
      
   IndicatorSetString(INDICATOR_SHORTNAME," Keltner channels ");
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason) {  }

//
//
//

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 i=rates_total-prev_calculated+1; if (i>=rates_total) i=rates_total-1; 
     
   //
   //
   //
   
   for (; i>=0 && !_StopFlag; i--)
   {
      double atr=0;
      for (int k=0; k<AtrPeriod && (i+k+1)<rates_total; k++)
         if (AtrMode==atr_Atr)
               atr += fmax(high[i+k],close[i+k+1])-fmin(low[i+k],close[i+k+1]);
         else  atr += high[i+k]-low[i+k];
               atr /= AtrPeriod;
               
      mid[i] = iMA(_Symbol,_Period,MaPeriod,0,MaMode,PriceMode,i);
      upK[i] = mid[i] + atr * K;
      dnK[i] = mid[i] - atr * K;
} 
return(rates_total);
}  

