//+------------------------------------------------------------------+
//|                                           FX Sniper's T3 CMO.mq4 |
//|                                      Original CMO Code by igorad |                                     
//|                                    Original T3 Code by FX Sniper |
//|                                  Copyright © 2007, Forex-TSD.com |
//|                                              Written by Linuxser |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, Forex-TSD.com "
#property link      "http://www.forex-tsd.com/"

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 Blue
#property indicator_color2 Green
#property indicator_color3 Red
#property indicator_width1    2
#property indicator_level1    0
#property indicator_level2   50
#property indicator_level3  -50 
#property indicator_maximum  100
#property indicator_minimum -100 
//----
extern int Length = 14; // Period of evaluation
extern int Price  =  0; // Price mode : 0-Close,1-Open,2-High,3-Low,4-Median,5-Typical,6-Weighted
extern int CMO_Period = 14;
extern int T3_Period = 5;
extern double b = 0.618;
extern bool Histogram  = false;

//----
double e1, e2, e3, e4, e5, e6;
double c1, c2, c3, c4;
double n, w1, w2, b2, b3;
double CMO[];
double CMOHup[];
double CMOHdn[];
double Bulls[];
double Bears[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators setting
    IndicatorBuffers(5);    
    SetIndexBuffer(0,CMO);
    SetIndexBuffer(3,Bulls);
    SetIndexBuffer(4,Bears);
    SetIndexBuffer(1, CMOHup);
    SetIndexBuffer(2, CMOHdn);
//----
    SetIndexStyle(0, DRAW_LINE);
    SetIndexStyle(1, DRAW_NONE);
    SetIndexStyle(2, DRAW_NONE);
    SetIndexStyle(3, DRAW_NONE);
    SetIndexStyle(4, DRAW_NONE); 
//---- name for DataWindow and indicator subwindow label
    string short_name="CMO T3("+Length+","+Price+")";
    IndicatorShortName(short_name);
    SetIndexLabel(0,"CMO T3");
//----
    SetIndexDrawBegin(0,Length);    
    SetIndexLabel(1, NULL);
    SetIndexLabel(2, NULL);   
//---- variable reset
    b2 = b*b;
    b3 = b2*b;
    c1 = -b3;
    c2 = (3*(b2 + b3));
    c3 = -3*(2*b2 + b + b3);
    c4 = (1 + 3*b + b3 + 3*b2);
    n = T3_Period;
//----
    if(n < 1) 
        n = 1;
    n = 1 + 0.5*(n - 1);
    w1 = 2 / (n + 1);
    w2 = 1 - w1;    
//----
    return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
    {
   int      shift, limit, counted_bars=IndicatorCounted();
   double   Price1, Price2;
//---- 
   if ( counted_bars < 0 ) return(-1);
   if ( counted_bars ==0 ) limit=Bars-Length-1;
   if ( counted_bars < 1 ) 
   for(int i=1;i<Length;i++) 
   {
   Bulls[Bars-i]=0;    
   Bears[Bars-i]=0;  
   CMO[Bars-i]=0; 
   }
      
   if(counted_bars>0) limit=Bars-counted_bars;
   limit--;
   
   for( shift=limit; shift>=0; shift--)
   {
   Price1 = iMA(NULL,0,1,0,0,Price,shift);
   Price2 = iMA(NULL,0,1,0,0,Price,shift+1); 
      
   Bulls[shift] = 0.5*(MathAbs(Price1-Price2)+(Price1-Price2));
   Bears[shift] = 0.5*(MathAbs(Price1-Price2)-(Price1-Price2));
   
   double SumBulls = 0, SumBears=0;
      for (i=0;i<Length;i++) 
      {
      SumBulls += Bulls[shift+i];
      SumBears += Bears[shift+i];
      }  
   CMO[shift] = (SumBulls-SumBears)/(SumBulls+SumBears)*100;
   e1 = w1*CMO[shift] + w2*e1;
   e2 = w1*e1 + w2*e2;
   e3 = w1*e2 + w2*e3;
   e4 = w1*e3 + w2*e4;
   e5 = w1*e4 + w2*e5;
   e6 = w1*e5 + w2*e6;    
   CMO[shift] = c1*e6 + c2*e5 + c3*e4 + c4*e3;  
       //----
       if(CMO[shift] >= 0)
           CMOHup[shift] = CMO[shift];
       else
           CMOHup[shift] = 0;   
       //----
       if(CMO[shift] < 0 )
           CMOHdn[shift] = CMO[shift];
       else
           CMOHdn[shift] = 0; 
     } 
     if(Histogram == true)
      {
         for(i=0; i<limit; i++)
         {
               SetIndexStyle(1,DRAW_HISTOGRAM);
               SetIndexStyle(2,DRAW_HISTOGRAM);             
         } 
         }   
//----
   return(0);
  }
//+------------------------------------------------------------------+