//+------------------------------------------------------------------+
//|                                                 !TMA True v2.mq4 |
//|                                  Copyright © 2011, John Wustrack |
//|                                        john_wustrack@hotmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, John Wustrack"
#property link      "john_wustrack@hotmail.com"

#property indicator_chart_window

#property indicator_buffers 5
#property indicator_color1 Yellow
#property indicator_color2 Blue
#property indicator_color3 Red
#property indicator_color4 Lime
#property indicator_color5 Lime
#property indicator_style4 STYLE_DOT
#property indicator_style5 STYLE_DOT

extern int xi_Period = 56;
extern int xi_ATR.Period = 100;
extern double xd_ATR.Mult = 2.0;
extern color xc_Text = LightGray;

double IB_TMA[], IB_TMA.Up[], IB_TMA.Dn[];
double IB_Upper[], IB_Lower[];

int gi_PipsDecimal;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   IndicatorBuffers(5);
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,IB_TMA);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,IB_TMA.Up);
   SetIndexStyle(2,DRAW_LINE);
   SetIndexBuffer(2,IB_TMA.Dn);
   SetIndexStyle(3,DRAW_LINE);
   SetIndexBuffer(3,IB_Upper);
   SetIndexStyle(4,DRAW_LINE);
   SetIndexBuffer(4,IB_Lower);
   
   SetIndexDrawBegin(0,xi_Period);
   SetIndexDrawBegin(1,xi_Period);
   SetIndexDrawBegin(2,xi_Period);
   SetIndexDrawBegin(3,xi_Period);
   SetIndexDrawBegin(4,xi_Period);
   
   SetIndexLabel(0,"TMA Mid line");
   SetIndexLabel(3,"TMA Upper line");
   SetIndexLabel(4,"TMA Lower line");
   
   IndicatorDigits(Digits);

   gi_PipsDecimal = Get_Pips_Decimal();
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   ObjectDelete("!TMA True v2 Range");
   ObjectDelete("!TMA True v2 Trend");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
//----
   int counted_bars = IndicatorCounted();
   
   if (counted_bars < 0) return (-1);
   if (counted_bars > 0) counted_bars--;
   int limit = Bars - counted_bars;
   double ld_Range, ld_Pips;
   
   for (int i=limit; i>=0; i--)
      {
      IB_TMA[i] = EMPTY_VALUE;
      IB_TMA.Up[i] = EMPTY_VALUE;
      IB_TMA.Dn[i] = EMPTY_VALUE;
      
      IB_TMA[i] = iMA(NULL,0,xi_Period,0,MODE_LWMA,PRICE_CLOSE,i);
      
      // Color 
      if (IB_TMA[i] > IB_TMA[i+1])
         IB_TMA.Up[i] = IB_TMA[i];
      if (IB_TMA[i] < IB_TMA[i+1])
         IB_TMA.Dn[i] = IB_TMA[i];
         
      // Draw upper & lower boundaries
      ld_Range = iATR(NULL,0,xi_ATR.Period,i+10);
      IB_Upper[i] = IB_TMA[i] + (ld_Range * xd_ATR.Mult);
      IB_Lower[i] = IB_TMA[i] - (ld_Range * xd_ATR.Mult);
      
      }
      
   // Get the range and trend range of the TMA
   ld_Range = IB_Upper[1] - IB_Lower[1];
   ld_Pips = Convert_2_Pips(ld_Range);
   Object_Create("!TMA True v2 Range",5,25,"TMA Range: "+DoubleToStr(ld_Pips,gi_PipsDecimal),10,"Arial",xc_Text);

   if (IB_TMA.Up[1] == EMPTY_VALUE && IB_TMA.Dn[1] == EMPTY_VALUE)
      Object_Create("!TMA True v2 Trend",5,5,"TMA Trend: n/a",10,"Arial",xc_Text);
   else
      {
      ld_Range = Get_Trend_Range();
      ld_Pips = Convert_2_Pips(ld_Range);
      Object_Create("!TMA True v2 Trend",5,5,"TMA Trend: "+DoubleToStr(ld_Pips,gi_PipsDecimal),10,"Arial",xc_Text);
      }

      // Calculate the distances between bid & bands
      double ld_Dist.Pts, ld_Dist.Pips;
      
      // Distance to mid
      ld_Dist.Pts = MathAbs(Bid - IB_TMA[0]);
      ld_Dist.Pips = Convert_2_Pips(ld_Dist.Pts);
      ObjectCreate("!Mid",OBJ_TEXT,0,0,0);
      ObjectSet("!Mid",OBJPROP_TIME1,Time[0]+(3*Period()*60));
      ObjectSet("!Mid",OBJPROP_PRICE1,IB_TMA[0]);
      ObjectSetText("!Mid",DoubleToStr(ld_Dist.Pips,gi_PipsDecimal),8,"Arial",xc_Text);
      
      // Distance to upper
      ld_Dist.Pts = MathAbs(Bid - IB_Upper[0]);
      ld_Dist.Pips = Convert_2_Pips(ld_Dist.Pts);
      ObjectCreate("!Upp",OBJ_TEXT,0,0,0);
      ObjectSet("!Upp",OBJPROP_TIME1,Time[0]+(3*Period()*60));
      ObjectSet("!Upp",OBJPROP_PRICE1,IB_Upper[0]);
      ObjectSetText("!Upp",DoubleToStr(ld_Dist.Pips,gi_PipsDecimal),8,"Arial",xc_Text);
      
      // Distance to lower
      ld_Dist.Pts = MathAbs(Bid - IB_Lower[0]);
      ld_Dist.Pips = Convert_2_Pips(ld_Dist.Pts);
      ObjectCreate("!Low",OBJ_TEXT,0,0,0);
      ObjectSet("!Low",OBJPROP_TIME1,Time[0]+(3*Period()*60));
      ObjectSet("!Low",OBJPROP_PRICE1,IB_Lower[0]);
      ObjectSetText("!Low",DoubleToStr(ld_Dist.Pips,gi_PipsDecimal),8,"Arial",xc_Text);

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| get TMA trend range                                              |
//+------------------------------------------------------------------+
double Get_Trend_Range()
  {
//----
   double pd_Range;
   int i;
   
   // Going up
   if (IB_TMA.Up[1] != EMPTY_VALUE)
      {
      for (i=2; i<Bars; i++)
         if (IB_TMA.Up[i] == EMPTY_VALUE) break;
      }
   
   // Going down   
   if (IB_TMA.Dn[1] != EMPTY_VALUE)
      {
      for (i=2; i<Bars; i++)
         if (IB_TMA.Dn[i] == EMPTY_VALUE) break;
      }
      
   pd_Range = MathAbs(IB_TMA[1]-IB_TMA[i-1]);   
//----
   return(pd_Range);
  }
//+------------------------------------------------------------------+
//| create screen objects                                            |
//+------------------------------------------------------------------+
void Object_Create(string ps_name,int pi_x,int pi_y,string ps_text=" ",int pi_size=12,
                  string ps_font="Arial",color pc_colour=CLR_NONE)
  {
//----
   
//   if (colour==CLR_NONE) colour=xcBackground;
      
   ObjectCreate(ps_name,OBJ_LABEL,0,0,0,0,0);
   ObjectSet(ps_name,OBJPROP_CORNER,3);
   ObjectSet(ps_name,OBJPROP_COLOR,pc_colour);
   ObjectSet(ps_name,OBJPROP_XDISTANCE,pi_x);
   ObjectSet(ps_name,OBJPROP_YDISTANCE,pi_y);
   
   ObjectSetText(ps_name,ps_text,pi_size,ps_font,pc_colour);

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| convert to points                                                |
//+------------------------------------------------------------------+
double Convert_2_Pts(double pd_Pips)
  {
//----
   int pd_Points=pd_Pips;  // Default - no conversion
   
 	if (Digits == 5 || (Digits == 3 && StringFind(Symbol(), "JPY") != -1)) 
 	   pd_Points=pd_Pips*10;
 	   
 	if (Digits == 6 || (Digits == 4 && StringFind(Symbol(), "JPY") != -1)) 
 	   pd_Points=pd_Pips*100;
//----
   return(pd_Points);
  }
//+------------------------------------------------------------------+
//| convert to pips                                                  |
//+------------------------------------------------------------------+
double Convert_2_Pips(double pd_Points)
  {
//----
   double pd_Pips=pd_Points/Point;  // Default - no conversion
   
 	if (Digits == 5 || (Digits == 3 && StringFind(Symbol(), "JPY") != -1)) 
 	   {
 	   pd_Pips=pd_Points/Point/10;
 	   }
 	   
 	if (Digits == 6 || (Digits == 4 && StringFind(Symbol(), "JPY") != -1)) 
 	   {
 	   pd_Pips=pd_Points/Point/100;
 	   }
//----
   return(pd_Pips);
  }
//+------------------------------------------------------------------+
//| get the pips decimal places                                      |
//+------------------------------------------------------------------+
int Get_Pips_Decimal()
  {
//----
   int pi_PipsDecimal = 0;  // Default - no decimals
   
 	if (Digits == 5 || (Digits == 3 && StringFind(Symbol(), "JPY") != -1)) 
 	   {
 	   pi_PipsDecimal = 1;
 	   }
 	   
 	if (Digits == 6 || (Digits == 4 && StringFind(Symbol(), "JPY") != -1)) 
 	   {
 	   pi_PipsDecimal = 2;
 	   }
//----
   return(pi_PipsDecimal);
  }
//+------------------------------------------------------------------+