//+------------------------------------------------------------------
//|                                                     T3 taotra.mq4 
//|                                                            mladen 
//|                                                                  
//+------------------------------------------------------------------
#property copyright "www.forex-station.com"
#property link      "www.forex-station.com"

#property indicator_chart_window
#property indicator_buffers 8
#property strict
//
//
//
//
//

extern int                T3Period_1  = 44;               // T3 period 1
extern int                T3Period_2  = 52;               // T3 period 2
extern int                T3Period_3  = 60;               // T3 period 3
extern int                T3Period_4  = 68;               // T3 period 4
extern int                T3Period_5  = 76;               // T3 period 5
extern int                T3Period_6  = 84;               // T3 period 6
extern int                T3Period_7  = 92;               // T3 period 7
extern int                T3Period_8  = 100;              // T3 period 8
extern ENUM_APPLIED_PRICE T3Price     = PRICE_CLOSE;      // TE price to use
extern double             T3Hot       = 0.7;              // T3 hot
extern bool               T3Original  = false;            // T3 original?
extern int                LinesWidth  = 1;                // Lines width
extern color              ColorFast   = clrLimeGreen;     // Fast t3 ma's color
extern color              ColorMiddle = clrGold;          // Middle t3 ma's color
extern color              ColorSlow   = clrPaleVioletRed; // Slow t3 ma's color

//
//
//
//
//

double t31[];
double t32[];
double t33[];
double t34[];
double t35[];
double t36[];
double t37[];
double t38[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int init()
{
   IndicatorBuffers(8);
      SetIndexBuffer(0,t31);
      SetIndexBuffer(1,t32);
      SetIndexBuffer(2,t33);
      SetIndexBuffer(3,t34);
      SetIndexBuffer(4,t35);
      SetIndexBuffer(5,t36);
      SetIndexBuffer(6,t37);
      SetIndexBuffer(7,t38);
   return(0);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int start()
{
   int i,limit,counted_bars=IndicatorCounted();

   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
           limit=MathMin(Bars-counted_bars,Bars-1);

           //
           //
           //
           //
           //
           
           static bool colorsSet=false;
                  if (!colorsSet)
                  {
                     colorsSet = true; for (i=0;i<8; i++)
                        if (i<4)
                              SetIndexStyle(i,NULL,NULL,LinesWidth,gradientColor(i  ,4,ColorFast,ColorMiddle));
                        else  SetIndexStyle(i,NULL,NULL,LinesWidth,gradientColor(i-4,4,ColorMiddle,ColorSlow));
                  }
   //
   //
   //
   //
   //

      for(i=limit; i>=0; i--)
      {
         double price = iMA(NULL,0,1,0,MODE_SMA,T3Price,i);
            if (T3Period_1>0) t31[i] = iT3(price,T3Period_1,T3Hot,T3Original,i,0);
            if (T3Period_2>0) t32[i] = iT3(price,T3Period_2,T3Hot,T3Original,i,1);
            if (T3Period_3>0) t33[i] = iT3(price,T3Period_3,T3Hot,T3Original,i,2);
            if (T3Period_4>0) t34[i] = iT3(price,T3Period_4,T3Hot,T3Original,i,3);
            if (T3Period_5>0) t35[i] = iT3(price,T3Period_5,T3Hot,T3Original,i,4);
            if (T3Period_6>0) t36[i] = iT3(price,T3Period_6,T3Hot,T3Original,i,5);
            if (T3Period_7>0) t37[i] = iT3(price,T3Period_7,T3Hot,T3Original,i,6);
            if (T3Period_8>0) t38[i] = iT3(price,T3Period_8,T3Hot,T3Original,i,7);
      }
      return(0);
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

#define t3Instances 8
double workT3[][t3Instances*6];
double workT3Coeffs[][6];
#define _tperiod 0
#define _c1      1
#define _c2      2
#define _c3      3
#define _c4      4
#define _alpha   5

//
//
//
//
//

double iT3(double price, double period, double hot, bool original, int i, int tinstanceNo=0)
{
   if (ArrayRange(workT3,0) != Bars)                 ArrayResize(workT3,Bars);
   if (ArrayRange(workT3Coeffs,0) < (tinstanceNo+1)) ArrayResize(workT3Coeffs,tinstanceNo+1);

   if (workT3Coeffs[tinstanceNo][_tperiod] != period)
   {
     workT3Coeffs[tinstanceNo][_tperiod] = period;
        double a = hot;
            workT3Coeffs[tinstanceNo][_c1] = -a*a*a;
            workT3Coeffs[tinstanceNo][_c2] = 3*a*a+3*a*a*a;
            workT3Coeffs[tinstanceNo][_c3] = -6*a*a-3*a-3*a*a*a;
            workT3Coeffs[tinstanceNo][_c4] = 1+3*a+a*a*a+3*a*a;
            if (original)
                 workT3Coeffs[tinstanceNo][_alpha] = 2.0/(1.0 + period);
            else workT3Coeffs[tinstanceNo][_alpha] = 2.0/(2.0 + (period-1.0)/2.0);
   }
   
   //
   //
   //
   //
   //
   
   int instanceNo = tinstanceNo*6;
   int r = Bars-i-1;
   if (r == 0)
      {
         workT3[r][0+instanceNo] = price;
         workT3[r][1+instanceNo] = price;
         workT3[r][2+instanceNo] = price;
         workT3[r][3+instanceNo] = price;
         workT3[r][4+instanceNo] = price;
         workT3[r][5+instanceNo] = price;
      }
   else
      {
         workT3[r][0+instanceNo] = workT3[r-1][0+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(price                  -workT3[r-1][0+instanceNo]);
         workT3[r][1+instanceNo] = workT3[r-1][1+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(workT3[r][0+instanceNo]-workT3[r-1][1+instanceNo]);
         workT3[r][2+instanceNo] = workT3[r-1][2+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(workT3[r][1+instanceNo]-workT3[r-1][2+instanceNo]);
         workT3[r][3+instanceNo] = workT3[r-1][3+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(workT3[r][2+instanceNo]-workT3[r-1][3+instanceNo]);
         workT3[r][4+instanceNo] = workT3[r-1][4+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(workT3[r][3+instanceNo]-workT3[r-1][4+instanceNo]);
         workT3[r][5+instanceNo] = workT3[r-1][5+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(workT3[r][4+instanceNo]-workT3[r-1][5+instanceNo]);
      }

   //
   //
   //
   //
   //
   
   return(workT3Coeffs[tinstanceNo][_c1]*workT3[r][5+instanceNo] + 
          workT3Coeffs[tinstanceNo][_c2]*workT3[r][4+instanceNo] + 
          workT3Coeffs[tinstanceNo][_c3]*workT3[r][3+instanceNo] + 
          workT3Coeffs[tinstanceNo][_c4]*workT3[r][2+instanceNo]);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

color gradientColor(double step, int totalSteps, color from, color to)
{
   step = (int)MathMax(MathMin(step,totalSteps-1),0);
      color newBlue  = getColor((int)step,totalSteps,(from & 0XFF0000)>>16,(to & 0XFF0000)>>16)<<16;
      color newGreen = getColor((int)step,totalSteps,(from & 0X00FF00)>> 8,(to & 0X00FF00)>> 8) <<8;
      color newRed   = getColor((int)step,totalSteps,(from & 0X0000FF)    ,(to & 0X0000FF)    )    ;
      return(newBlue+newGreen+newRed);
}
color getColor(int stepNo, int totalSteps, color from, color to)
{
   double step = (from-to)/(totalSteps-1.0);
   return((color)MathRound(from-step*stepNo));
}


