#property copyright "Extreme TMA System"
#property link      "http://www.forexfactory.com/showthread.php?t=343533m"

#property indicator_chart_window
  
extern color NeutralColor = LightGray;
extern color BullColor = SeaGreen;
extern color ExtremeBullColor = Lime;
extern color BearColor = Orange;
extern color ExtremeBearColor = Red;
  
extern int TmaPeriod = 56;
extern int TmaAtrPeriod = 100;  
 
extern double TmaBandSize = 2;
extern double TmaSlopeThreshold = 0.5; 

extern double TmaBandSizeH1 = 3;
extern double TmaBandSizeH4 = 3;

extern int PivotHoursShift = 0;
extern double PivotThreshold = 10; 

extern int MaPeriod = 10;  
//This is the same as 4 in the original TMA MACross
extern int MaShift = 1;

extern int Size = 13;
extern string Font = "Arial";  
extern bool ShowPrice = false;
extern bool ShowDailyAtr = true;
extern bool ShowSpread = true;

extern bool ShowTmaSize = true; 
extern bool ShowTmaSizeH1 = true; 
extern bool ShowTmaSizeH4 = true; 

extern bool ShowSlope = true; 
extern bool ShowSlopeH1 = true; 
extern bool ShowSlopeH4 = true; 
extern bool ShowExtremeTMA = true; 

extern bool ShowSlopeChange = true; 
extern bool ShowPivotDistance = true;

extern bool ShowHeikenAshi = true;
extern bool ShowMACrossover = false;

extern bool AlertOn = false;
extern bool AlertMessage = true;
extern bool AlertEmail = false;
extern bool AlertSound = true;
extern string AlertSoundFile = "alert2.wav"; 



int LinearRegressionPeriod = 7; 

bool ShowLinearPriceChange = false; 


int Bottom = 25;
double Tick = 0;
bool AdditionalDigit;
double Pivots[];
 
int LastPivotDay= 0;
bool AlertHappened = false;
//+------------------------------------------------------------------+
//     expert initialization function                                |       
//+------------------------------------------------------------------+
int init()
  { 
  
   ArrayResize(Pivots,11);
	Tick = MarketInfo(Symbol(), MODE_TICKSIZE);	
   AdditionalDigit = MarketInfo(Symbol(), MODE_MARGINCALCMODE) == 0 && MarketInfo(Symbol(), MODE_PROFITCALCMODE) == 0 && Digits % 2 == 1;
   if (AdditionalDigit) {
        Tick *= 10;
    }    
       
   initGraph();
   return(0);                                                              
  }
  
int deinit()
  {
   deinitGraph();
   Print("shutdown error - ",GetLastError());                               
   return(0);                                                             
  }
int start()
  {
   main();
   return(0);                                                               
  }
  
void main()                                                             
  {   
   RefreshRates();  
   //General Info   
    
   double spread=NormalizeDouble(((Ask-Bid)/Point)/10,1);
   int dayShift = iBarShift(Symbol(),PERIOD_D1,Time[0]);
   
   double atr = iATR(Symbol(),PERIOD_D1, 14,dayShift);
   double price = NormalizeDouble(Close[0],4);     
   atr =  NormalizeDouble((atr/Point)/10,1);

   if (ShowSpread)  paintGeneral("SpreadValue", spread, NeutralColor, 1);
   if (ShowDailyAtr)  paintGeneral("AtrValue", atr, NeutralColor);
   if (ShowPrice)  paintPrice(price); 


   
   double tmaH1,tmaH1Prev,tmaH4,tmaH4Prev;
   
   //Tma Info
   GetPivots(Symbol());
      int shiftH1 = iBarShift(NULL,60,Time[0]);
      int shiftH4 = iBarShift(Symbol(),240,Time[0]);  
   if (ShowSlopeH1)
   {      
      tmaH1 = CalcTma(60, shiftH1); 
      tmaH1Prev  = CalcTma(60, shiftH1+1);
   }
   if (ShowSlopeH4)
   {    
      tmaH4 = CalcTma(240, shiftH4); 
      tmaH4Prev  = CalcTma(240, shiftH4+1);
   }
   
   //if (Symbol() == "EURUSDm") Print (" tmaH1 ",tmaH1," tmaH1Prev ",tmaH1Prev, " shiftH1 ", shiftH1, " Time[0] ", TimeToStr(Time[0])
   //, "iClose(Symbol(),60,shiftH1);", iClose(Symbol(),60,shiftH1), "iTime(Symbol(),60,shiftH1);", TimeToStr(iTime(Symbol(),60,shiftH1)));
   double tma = getTma(Symbol(),0, 0); 
   double tmaPrev  = getTma(Symbol(),0, 1);
   double tmaPrev2  = getTma(Symbol(),0, 2);
   double tmaPrev3  = getTma(Symbol(),0, 3);
   double priceSlope  = getPriceSlope(Symbol(),0,LinearRegressionPeriod);
   double pivotDist = GetNearestPivotDistance()/Tick;
   
   double tmaAtr = iATR( Symbol(), 0, TmaAtrPeriod, 10);   
   double tmaAtrH1 = iATR( Symbol(), 60, TmaAtrPeriod,shiftH1 + 10);
   double tmaAtrH4 = iATR( Symbol(), 240, TmaAtrPeriod, shiftH4 + 10);   
   double diff = Close[0] - tma;
   double extremeTma = (diff/tmaAtr) / TmaBandSize; 
   
   double n = tmaAtr * 0.1;    
   
   double tmaSlope = ((tma- tmaPrev) / n) ; 
   double tmaSlopeH1 = ((tmaH1- tmaH1Prev) / (tmaAtrH1 * 0.1)) ; 
   double tmaSlopeH4 = ((tmaH4- tmaH4Prev) / (tmaAtrH4 * 0.1)) ; 
   double tmaSlope1 = ((tmaPrev- tmaPrev2) / n) ; 
   double tmaSlope2 = ((tmaPrev2- tmaPrev3) / n) ;
   double tmaSlopeChange = ((tmaSlope - tmaSlope1) + (tmaSlope1 - tmaSlope2)) / 2.0;
   
   if (ShowTmaSize) paintGeneral("TmaSizeValue", (tmaAtr/Tick) * 2 * TmaBandSize   , NeutralColor);
   if (ShowTmaSizeH1) paintGeneral("TmaSizeH1Value", (tmaAtrH1/Tick) * 2 * TmaBandSizeH1   , NeutralColor);
   if (ShowTmaSizeH4) paintGeneral("TmaSizeH4Value", (tmaAtrH4/Tick) * 2 * TmaBandSizeH4   , NeutralColor);
      
      
   color c = NeutralColor;
   
   if (ShowExtremeTMA)
   {
      if(extremeTma<=-1){c = ExtremeBullColor; } 
      else if(extremeTma>=1){c = ExtremeBearColor; }
      else if(extremeTma>0){c = BearColor; }
      else if(extremeTma<0){c = BullColor; } 
      else {c = NeutralColor; }   
      paintGeneral("ExtremeTMA", extremeTma, c);  
   }

   if (ShowSlope)
   {
      if(tmaSlope<-1 * TmaSlopeThreshold){c = ExtremeBearColor; } 
      else if(tmaSlope>TmaSlopeThreshold){c = ExtremeBullColor; } 
      //else {c = NeutralColor; } 
      paintGeneral("TmaSlope", tmaSlope, c,2);  
   
   }
    
   if (ShowSlopeH1)
   {
      if(tmaSlopeH1 <-1 * TmaSlopeThreshold){c = ExtremeBearColor; } 
      else if(tmaSlopeH1 >TmaSlopeThreshold){c = ExtremeBullColor; } 
      else if(tmaSlopeH1 > 0){c = BullColor; } 
      else if(tmaSlopeH1 < 0 ){c = BearColor; } 
      else {c = NeutralColor; } 
      paintGeneral("TmaSlopeH1", tmaSlopeH1, c,2);
   }
   
   if (ShowSlopeH4)
   {
      if(tmaSlopeH4 <-1 * TmaSlopeThreshold){c = ExtremeBearColor; } 
      else if(tmaSlopeH4 >TmaSlopeThreshold){c = ExtremeBullColor; } 
      else if(tmaSlopeH4 > 0){c = BullColor; } 
      else if(tmaSlopeH4 < 0 ){c = BearColor; } 
      else {c = NeutralColor; } 
      paintGeneral("TmaSlopeH4", tmaSlopeH4, c,2);
   }
   
   if (ShowSlopeChange)
   {
      if(tmaSlopeChange<0 && extremeTma>= 1){c = ExtremeBearColor; } 
      else if(tmaSlopeChange<0){c = BearColor; } 
      else if(tmaSlopeChange>0 && extremeTma<= -1){c = ExtremeBullColor; }
      else if(tmaSlopeChange>0){c = BullColor; } 
      else {c = NeutralColor; } 
      paintGeneral("TmaSlopeChange", tmaSlopeChange* 100, c);
   }
   
   if(ShowLinearPriceChange)
   {
      if(priceSlope<0 && tmaSlopeChange>0){c = ExtremeBullColor; }    
      else if(priceSlope>0 && tmaSlopeChange<0){c = ExtremeBearColor; } 
      else {c = NeutralColor; }    
      paintGeneral("PriceSlope", priceSlope, c);
   }
   
   if(ShowPivotDistance)
   {
      if(pivotDist>0 && pivotDist < PivotThreshold){c = ExtremeBullColor; } 
      else if (pivotDist>0){c = BullColor; } 
      else if(pivotDist<0 && MathAbs(pivotDist) < PivotThreshold){c = ExtremeBearColor; } 
      else if(pivotDist<0){c = BearColor; }
      //else if(extremeTma>0){c = BearColor; }
      //else if(extremeTma<0){c = BullColor; } 
      else {c = NeutralColor; }   
      paintGeneral("PivotDistance", pivotDist, c);  
   }
   if(ShowHeikenAshi)
   {
      double ha = (GetHAClose(0) - GetHAOpen(0))/Tick;
      
      if(ha > 0 && extremeTma<=-1){c = ExtremeBullColor; } 
      else if(ha<0 && extremeTma>=1){c = ExtremeBearColor; }
      else if(ha>0){c = BullColor; }
      else if(ha<0 ){c = BearColor; } 
      else {c = NeutralColor; }   
   
      paintGeneral("HeikenAshi", ha, c);   
   }
   
   if(ShowMACrossover)
   {
      double back = getMaBack(Symbol(),0); 
      double front = getMaFront(Symbol(),0);
      double maCrossover = back-front;
      
      if(maCrossover > 0 && extremeTma<=1){c = ExtremeBullColor; } 
      else if(maCrossover<0 && extremeTma<=-1){c = ExtremeBearColor; }
      else if(maCrossover>0){c = BullColor; }
      else if(maCrossover<0 ){c = BearColor; } 
      else {c = NeutralColor; }   
   
      paintGeneral("MaCrossover", maCrossover/Tick, c);
   }
   
   if (AlertOn)
   {
      if(extremeTma <= -1 && tmaSlope > -1 * TmaSlopeThreshold && tmaSlopeChange > 0 && MathAbs(pivotDist) < PivotThreshold)
      {
         Print("ALERT BUY");
         if(!AlertHappened)
         {
            string message = StringConcatenate(Symbol()," Extreme TMA Buy");
            
            if (AlertMessage) Alert(message);
            if (AlertEmail)   SendMail(message,message);
            if (AlertSound)   PlaySound(AlertSoundFile);
            AlertHappened = true;
        }      
      } 
      else if(extremeTma >= 1 && tmaSlope < TmaSlopeThreshold && tmaSlopeChange < 0 && MathAbs(pivotDist) < PivotThreshold)
      {
         Print("ALERT SELL");
         if(!AlertHappened)
         {
            message = StringConcatenate(Symbol()," Extreme TMA Sell");
            
            if (AlertMessage) Alert(message);
            if (AlertEmail)   SendMail(message,message);
            if (AlertSound)   PlaySound(AlertSoundFile);
            AlertHappened = true;
         } 
      }
      else
      {
         AlertHappened = false;
      }
   }
  
  }
  
  
//Data Retrieval
double getMaBack(string symbol, int timeFrame)
{
   int backIdx = MaShift - MaPeriod;
   //double back = iCustom(symbol,timeFrame,"Ma_Crossover_Lines",MaPeriod,MaShift,0,0);
   double back = iMA( symbol, timeFrame, MaPeriod + backIdx, 0, MODE_LWMA, PRICE_TYPICAL, 0);
   return (back);
}
double getMaFront(string symbol, int timeFrame)
{
   double front = iMA( symbol, timeFrame, MaPeriod, 0, MODE_LWMA, PRICE_TYPICAL, MaShift); 
   return (front);
} 
 
 
double getPriceSlope(string symbol, int timeFrame,int Length)
{

   double SumBars = Length * (Length - 1) * 0.5;
   double SumSqrBars = (Length - 1.0) * Length * (2.0 * Length - 1.0) / 6.0;
   double slope;
   int i=0;
   
   double Sum1 = 0;
   for(i=0;i<=Length-1;i++) Sum1 += i*iMA(NULL,0,1,0,1,PRICE_CLOSE,i);

   double SumY = 0;
   for(i=0;i<=Length-1;i++) SumY += iMA(NULL,0,1,0,1,PRICE_CLOSE,i);

   double Sum2 = SumBars * SumY;
   
   double Num1 = Length * Sum1 - Sum2;
   double Num2 = SumBars * SumBars - Length * SumSqrBars;

   if( Num2 != 0 ) 
	slope = 10000*Num1/Num2;
   else 
	slope = 0; 
    
   if (StringSubstr(Symbol(),3,3) == "JPY") slope = slope / 100;
   return (slope);
}

 double CalcTma(int timeFrame, int inx)
{ 
   double dblSum  = (TmaPeriod+1)*iClose(Symbol(),timeFrame,inx);
   double dblSumw = (TmaPeriod+1);
   int jnx, knx;
         
   for ( jnx = 1, knx = TmaPeriod; jnx <= TmaPeriod; jnx++, knx-- )
   {
      dblSum  += ( knx * iClose(Symbol(),timeFrame,inx+jnx) );
      dblSumw += knx;      
      
      if ( jnx <= inx )
      {         
         if (iTime(Symbol(),timeFrame,inx-jnx) > Time[0])
         {
            //Print (" TimeFrameValue ", TimeFrameValue , " inx ", inx," jnx ", jnx, " iTime(Symbol(),TimeFrameValue,inx-jnx) ", TimeToStr(iTime(Symbol(),TimeFrameValue,inx-jnx)), " Time[0] ", TimeToStr(Time[0])); 
            continue;
         }
         dblSum  += ( knx * iClose(Symbol(),timeFrame,inx-jnx) );
         dblSumw += knx;
      }
   }
   
   return( dblSum / dblSumw );
}
 

double getTma(string symbol, int timeFrame, int index)
{
   double dblSum  = (TmaPeriod+1)*iClose(symbol, timeFrame,index);
   double dblSumw = (TmaPeriod+1);
   int jnx, knx;
         
   for ( jnx = 1, knx = TmaPeriod; jnx <= TmaPeriod; jnx++, knx-- )
   {
      dblSum  += ( knx * iClose(symbol, timeFrame,index+jnx) );
      dblSumw += knx;

      if ( jnx <= index )
      {
         dblSum  += ( knx * iClose(symbol, timeFrame,index-jnx) );
         dblSumw += knx;
      }
   }
   
   return( dblSum / dblSumw );
}
 
// Start Pivot Code
double GetNearestPivotDistance()
{
   int index = 0;
   double minDistance = 999999;
   for(int i=0; i < ArraySize(Pivots);i++)
   {
      if(MathAbs(Close[0]-Pivots[i]) < minDistance)
      {
         minDistance = MathAbs(Close[0]-Pivots[i]);
         index = i;
      }      
   } 
   double distance = Close[0]-Pivots[index];
   
   return (distance);
   
}
void GetPivots(string symbol)
{
 
   double prices[4];
   datetime start = GetDayStart(Time[0]);
   if(LastPivotDay == start) return;
   GetPrevDayPrices(prices,start);
      
   double range = prices[PRICE_HIGH]-prices[PRICE_LOW];
   
   Pivots[0]=NormalizeDouble((prices[PRICE_HIGH]+prices[PRICE_LOW]+ prices[PRICE_CLOSE] )/3.0,Digits); 
    
   Pivots[1] = Pivots[0] - (0.382 *  range);
   Pivots[2] = Pivots[0] - (0.618033 *  range);
   Pivots[3] = Pivots[0] - (1 *  range);
   Pivots[4] = Pivots[0] - (1.618033 *  range);
   Pivots[5] = Pivots[0] - (2.618033 *  range);
   Pivots[6] = Pivots[0] + (0.382 *  range);
   Pivots[7] = Pivots[0] + (0.618033 *  range);
   Pivots[8] = Pivots[0] + (1 *  range);
   Pivots[9] = Pivots[0] + (1.618033 *  range);
   Pivots[10] = Pivots[0] + (2.618033 *  range);
   
   LastPivotDay = start;
  
//----
}

datetime GetDayStart(datetime timestamp) {

   
   // Shift to start of effective day (could be Sat/Sun)   
   timestamp -= PivotHoursShift * 3600;
   timestamp -= MathMod(timestamp, 86400);

   // Move weekend to Monday start
   if (TimeDayOfWeek(timestamp) == 0) {
      timestamp += 24 * 3600;
   }
   else if(TimeDayOfWeek(timestamp) == 6) {
      timestamp += 48 * 3600;
   }
   
   // Shift back to 5PM EST
   timestamp += PivotHoursShift * 3600;
   
	return(timestamp);
} 

void GetPrevDayPrices(double& prices[], datetime timestamp) {


	// Get the last bar of the previous trading day
	int numHoursShift = 1; // one hour back in most cases.
	// however if it's Weekly open, need to go back 49 hours.
	if (TimeDayOfWeek(timestamp - PivotHoursShift * 3600)==1) {
	  numHoursShift = 48;
	}

	// since iBarShift exact param = false, the previous existing bar will be returned
	int 		iBarIndex 		= iBarShift(NULL,PERIOD_H1,timestamp - numHoursShift*3600,false);
	datetime	dtPrevDayStart	= GetDayStart(iTime(NULL,PERIOD_H1,iBarIndex));
		
	// Get close price for the day and set initial values for high and low
	prices[PRICE_HIGH]	= 0;	prices[PRICE_LOW]	   = 9999;	prices[PRICE_OPEN]	= 0;
	prices[PRICE_CLOSE]	= iClose(NULL,PERIOD_H1,iBarIndex-1);
	
		
	// Iterate back and check for high/low prices until all of previous trading day covered
	while (GetDayStart(iTime(NULL,PERIOD_H1,iBarIndex)) == dtPrevDayStart) {
		prices[PRICE_HIGH] = MathMax(prices[PRICE_HIGH], iHigh (NULL,PERIOD_H1,iBarIndex));
		prices[PRICE_LOW]  = MathMin(prices[PRICE_LOW],  iLow  (NULL,PERIOD_H1,iBarIndex));
		prices[PRICE_OPEN] = iOpen(NULL,PERIOD_H1,iBarIndex);
		iBarIndex++;
	}
	return;
}
// End Pivot Code


//End Data Retrieval

//Drawing
void paintPrice(double value)
{ 
   int precision = 4;

   if (StringSubstr(Symbol(),3,3) == "JPY") precision = 2;
   ObjectSetText("ExtremeTmaInfo_PriceValue",DoubleToStr(value,precision),Size,Font,NeutralColor);
}    
 
  
 
void paintGeneral(string name, double value, color c, int precision = 1)
{   
   ObjectSetText("ExtremeTmaInfo_" + name,DoubleToStr(value,precision),Size,Font,c);
}    



//----------------------------------------   
void initGraph() 
{
   int bottom = Bottom;
   
   if(ShowMACrossover)
   {
      objectCreate("ExtremeTmaInfo_MaCrossover",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor); 
      objectCreate("ExtremeTmaInfo_MaCrossoverLabel",65,bottom,"Ma Crossover:",Size,Font,NeutralColor); 
      bottom = bottom + (Size * 1.6);
   }
   if(ShowHeikenAshi)
   {
      objectCreate("ExtremeTmaInfo_HeikenAshi",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor); 
      objectCreate("ExtremeTmaInfo_HeikenAshiLabel",65,bottom,"Heiken Ashi:",Size,Font,NeutralColor); 
      bottom = bottom + (Size * 1.6);
   }
   if (ShowPivotDistance)
   {
      objectCreate("ExtremeTmaInfo_PivotDistance",12,bottom,"9",Size,Font,NeutralColor); 
      objectCreate("ExtremeTmaInfo_PivotDistanceLabel",65,bottom,"Pivot Distance:",Size,Font,NeutralColor); 
      bottom = bottom + (Size * 1.6);     
   }
   
   if (ShowLinearPriceChange)
   {
      objectCreate("ExtremeTmaInfo_PriceSlope",12,bottom,"9",Size,Font,NeutralColor); 
      objectCreate("ExtremeTmaInfo_PriceSlopeLabel",65,bottom,"Price Change:",Size,Font,NeutralColor); 
      bottom = bottom + (Size * 1.6);   
   }
   if(ShowSlopeChange)
   {
      objectCreate("ExtremeTmaInfo_TmaSlopeChange",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
      objectCreate("ExtremeTmaInfo_TmaSlopeChangeLabel",65,bottom,"Slope Change:",Size,Font,NeutralColor);  
      bottom = bottom + (Size * 1.6);   
   }
   if (ShowExtremeTMA)
   {
      objectCreate("ExtremeTmaInfo_ExtremeTMA",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor); 
      objectCreate("ExtremeTmaInfo_ExtremeTMALabel",65,bottom,"Extreme TMA:",Size,Font,NeutralColor);
      bottom = bottom + (Size * 1.6);
   }
   if (ShowSlopeH4) 
   {
      objectCreate("ExtremeTmaInfo_TmaSlopeH4",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor); 
      objectCreate("ExtremeTmaInfo_TmaSlopeH4Label",65,bottom,"TMA Slope (H4):",Size,Font,NeutralColor); 
      bottom = bottom + (Size * 1.6);
   }
   
   if (ShowSlopeH1) 
   {
      objectCreate("ExtremeTmaInfo_TmaSlopeH1",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor); 
      objectCreate("ExtremeTmaInfo_TmaSlopeH1Label",65,bottom,"TMA Slope (H1):",Size,Font,NeutralColor); 
      bottom = bottom + (Size * 1.6);
   }
   
   if (ShowSlope) 
   {
      objectCreate("ExtremeTmaInfo_TmaSlope",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor); 
      objectCreate("ExtremeTmaInfo_TmaSlopeLabel",65,bottom,"TMA Slope:",Size,Font,NeutralColor); 
      bottom = bottom + (Size * 1.6);
   }
    

   if (ShowTmaSizeH4) 
   {
      objectCreate("ExtremeTmaInfo_TmaSizeH4Value",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
      objectCreate("ExtremeTmaInfo_TmaSizeH4Label",65,bottom,"TMA Size (H4):",Size,Font,NeutralColor); 
      bottom = bottom + (Size * 1.6);
   }
   
   if (ShowTmaSizeH1) 
   {
      objectCreate("ExtremeTmaInfo_TmaSizeH1Value",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
      objectCreate("ExtremeTmaInfo_TmaSizeH1Label",65,bottom,"TMA Size (H1):",Size,Font,NeutralColor); 
      bottom = bottom + (Size * 1.6);
   }
   if (ShowTmaSize) 
   {
      objectCreate("ExtremeTmaInfo_TmaSizeValue",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
      objectCreate("ExtremeTmaInfo_TmaSizeLabel",65,bottom,"TMA Size:",Size,Font,NeutralColor); 
      bottom = bottom + (Size * 1.6);
   }
      
      
   if (ShowSpread)
   { 
      objectCreate("ExtremeTmaInfo_SpreadValue",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
      objectCreate("ExtremeTmaInfo_SpreadValueLabel",65,bottom,"Spread:",Size,Font,NeutralColor);
      bottom = bottom + (Size * 1.6);
   }
   if (ShowDailyAtr)
   { 
      objectCreate("ExtremeTmaInfo_AtrValue",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);   
      objectCreate("ExtremeTmaInfo_AtrValueLabel",65,bottom,"Atr(14-day):",Size,Font,NeutralColor);
      bottom = bottom + (Size * 1.6); 
   }
   if (ShowPrice)
   { 
      objectCreate("ExtremeTmaInfo_PriceValue",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor); 
      objectCreate("ExtremeTmaInfo_PriceValueLabel",65,bottom,"Price:",Size,Font,NeutralColor); 
      bottom = bottom + (Size * 1.6);
   }

   WindowRedraw();
  }
//----------------------------------------   
void deinitGraph() 
  { 
   DeleteObjectsByPrefix("ExtremeTmaInfo_");  
   DeleteObjectsByPrefix("ParadoxInfo_");    
   WindowRedraw();
  }
  
//+------------------------------------------------------------------+
void objectCreate(string name,int x,int y,string text="-",int size=42,
                  string font="Arial",color colour=CLR_NONE)
  {
   ObjectCreate(name,OBJ_LABEL,0,0,0);
   ObjectSet(name,OBJPROP_CORNER,3);
   ObjectSet(name,OBJPROP_COLOR,colour);
   ObjectSet(name,OBJPROP_XDISTANCE,x);
   ObjectSet(name,OBJPROP_YDISTANCE,y);
   ObjectSetText(name,text,size,font,colour);
  } 
  
  
  
  
void DeleteObjectsByPrefix(string Prefix)
  {
   int L = StringLen(Prefix);
   int i = 0; 
   while(i < ObjectsTotal())
     {
       string ObjName = ObjectName(i);
       if(StringSubstr(ObjName, 0, L) != Prefix) 
         { 
           i++; 
           continue;
         }
       ObjectDelete(ObjName);
     }
  }
  //End Drawing
  
  

 
 
 
double GetHAClose(int index)
{
   return((Open[index]+High[index]+Low[index]+Close[index])/4);
}

double GetHAOpen(int index)
{
   //The higher you make this lookback the lower the error with the true Heiken Ashi Open)
   int lookback = 8;
   double open = GetHAClose(index+lookback);
   lookback--;
   for(int j = index + lookback;j > index;j--)
   {
      open = (open + GetHAClose(j)) / 2;
   }
   return (open);
}