//+------------------------------------------------------------------+
//|                                                  TP1_Channel.mq4 |
//|                                                                  |
//|                                             senselesss@gmail.com |
//+------------------------------------------------------------------+
#property link        "senselesss@gmail.com"
#property description "TakeProfit1 Channel"
#property strict

//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_color5  Red
#property indicator_color6  DeepSkyBlue
#property indicator_color7  DarkOrange
#property indicator_color8  Aqua

//--- input parameter
input int    Len     = 30;
input double Lag     = 0;
input double Nx      = 10.0;
input double Enter   = -2.0;
input double Exit    = 0.5;

//--- buffers
double e1[];
double e2[];
double Av[];
double N[];
double B[];
double S[];
double ExB[];
double ExS[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(void)
  {
   string short_name;
   IndicatorBuffers(8);
   IndicatorDigits(Digits);
//--- indicator line
   SetIndexStyle(0,DRAW_NONE);
   SetIndexStyle(1,DRAW_NONE);
   SetIndexStyle(2,DRAW_NONE);
   SetIndexStyle(3,DRAW_NONE);
   SetIndexStyle(4,DRAW_LINE);
   SetIndexStyle(5,DRAW_LINE);
   SetIndexStyle(6,DRAW_LINE);
   SetIndexStyle(7,DRAW_LINE);
   SetIndexBuffer(0,e1);
   SetIndexBuffer(1,e2);
   SetIndexBuffer(2,Av);
   SetIndexBuffer(3,N);
   SetIndexBuffer(4,B);
   SetIndexBuffer(5,S);
   SetIndexBuffer(6,ExB);
   SetIndexBuffer(7,ExS);

   short_name="TP1 Channel ("+IntegerToString(Len)+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,"e1");
   SetIndexLabel(1,"e2");
   SetIndexLabel(2,"Av");
   SetIndexLabel(3,"N");
   SetIndexLabel(4,"4 - Buy");
   SetIndexLabel(5,"5 - Sell");
   SetIndexLabel(6,"6 - Exit Buy");
   SetIndexLabel(7,"7 - Exit Sell");
//--- check for input parameter
   if(Len <= 0)
     {
      Print("Wrong input parameter Len=",Len);
      return(INIT_FAILED);
     }
//---
   SetIndexDrawBegin(0,Len);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Average True Range                                               |
//+------------------------------------------------------------------+
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,limit;
   double F = 0, Fn = 0;

   ArraySetAsSeries(e1,true);
   ArraySetAsSeries(e2,true);
   ArraySetAsSeries(Av,true);
   ArraySetAsSeries(N,true);
   ArraySetAsSeries(B,true);
   ArraySetAsSeries(S,true);
   ArraySetAsSeries(ExB,true);
   ArraySetAsSeries(ExS,true);
   ArraySetAsSeries(close,true);

   limit = (rates_total) - prev_calculated;
   if(prev_calculated == 0) 
      {
      limit = rates_total - 2;
      F = 2 / ((double)Len + 1);
      e1[limit+1] = F * Close[limit+1];
      e2[limit+1] = F * e1[limit+1];
      Av[limit+1] = e1[limit+1] * (2 - Lag) - e2[limit+1] * (1 - Lag);
      Fn = 2 / (Len * Nx + 1);
      N[limit+1] = Fn * MathAbs(Close[limit+1] - Av[limit+1]);
      }
   for(i = limit; i > 0; i--)
     { 
     F = 2 / ((double)Len + 1);
     e1[i] = F * Close[i] + (1 - F) * e1[i + 1];
     e2[i] = F * e1[i] + (1 - F) * e2[i + 1];
     Av[i] = e1[i] * (2 - Lag) - e2[i] * (1 - Lag);
     Fn = 2 / ((double)Len * Nx + 1);
     N[i] = Fn * MathAbs(Close[i] - Av[i]) + (1 - Fn) * N[i + 1];
     
     B[i] = Av[i] + N[i] * Enter;
     S[i] = Av[i] - N[i] * Enter;
     ExB[i] = Av[i] + N[i] * Exit;
     ExS[i] = Av[i] - N[i] * Exit; 
     }  

   return(rates_total);
  }
//+------------------------------------------------------------------+
