//+------------------------------------------------------------------+
//| TRO_Center_of_Gravity                      Center of Gravity.mq4 |
//| Original Code from NG3110@latchess.com                           |                                    
//| Linuxser 2007 for TSD    http://www.forex-tsd.com/               |
//+------------------------------------------------------------------+
#property  copyright "ANG3110@latchess.com"
//---------ang_PR (Din)--------------------
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_color1 RoyalBlue
#property indicator_color2 LimeGreen
#property indicator_color3 LimeGreen
#property indicator_color4 Goldenrod
#property indicator_color5 Goldenrod
//+--------- TRO MODIFICATION ---------------------------------------+ 

extern bool   Sound.Alert    = true ;
extern string Sound.File1     = "ahooga.wav" ; // TRO
extern string Sound.File2     = "Corkpop.wav" ; // TRO
extern string Sound.File3     = "siren.wav" ; // TRO

extern bool   Show.PriceBox  = true ;
extern int    myBoxWidth     = 3;

//-----------------------------------
extern int bars_back = 125;
extern int m = 2;
extern int i = 0;
extern double kstd = 2.0;
extern int sName = 1102;
//-----------------------
double fx[], sqh[], sql[], stdh[], stdl[];
double ai[10,10], b[10], x[10], sx[20];
double sum;
int    ip, p, n, f;
double qq, mm, tt;
int    ii, jj, kk, ll, nn;
double sq, std;

//+--------- TRO MODIFICATION ---------------------------------------+ 
string symbol, tChartPeriod,  tShortName ;  
int    digits, period  ; 

datetime Trigger ;

int OldBars = -1 ;

color tColor = Yellow ;
color TL1color      = White ;

//*******************************************
int init()
{

//+--------- TRO MODIFICATION ---------------------------------------+  

   period       = Period() ;     
   tChartPeriod =  TimeFrameToString(period) ;
   symbol       =  Symbol() ;
   digits       =  Digits ;   

   tShortName = "shict"+ symbol + tChartPeriod  ;
   
   IndicatorShortName("Center of Gravity");
   SetIndexStyle(0, DRAW_LINE);
   SetIndexBuffer(0, fx);
   SetIndexBuffer(1, sqh);
   SetIndexBuffer(2, sql);
   SetIndexBuffer(3, stdh);
   SetIndexBuffer(4, stdl);
   p = MathRound(bars_back);
   nn = m + 1;
   ObjectCreate("pr" + sName, 22, 0, Time[p], fx[p]);
   ObjectSet("pr" + sName, 14, 159);
   return(0);
}
//----------------------------------------------------------
int deinit()
{
   ObjectDelete("pr" + sName);

//+--------- TRO MODIFICATION ---------------------------------------+ 
   ObjectDelete(tShortName+"01"); 
   ObjectDelete(tShortName+"02"); 
   ObjectDelete(tShortName+"03"); 
   ObjectDelete(tShortName+"04"); 
   ObjectDelete(tShortName+"05");         
         
         
}
//**********************************************************************************************
int start()
{
   int mi;
//-------------------------------------------------------------------------------------------
   ip = iBarShift(Symbol(), Period(), ObjectGet("pr" + sName, OBJPROP_TIME1));
   p = bars_back; 
   sx[1] = p + 1;
   SetIndexDrawBegin(0, Bars - p - 1);
   SetIndexDrawBegin(1, Bars - p - 1);
   SetIndexDrawBegin(2, Bars - p - 1);
   SetIndexDrawBegin(3, Bars - p - 1);
   SetIndexDrawBegin(4, Bars - p - 1); 
//----------------------sx-------------------------------------------------------------------
   for(mi = 1; mi <= nn * 2 - 2; mi++)
   {
      sum = 0;
      for(n = i; n <= i + p; n++)
      {
         sum += MathPow(n, mi);
      }
      sx[mi + 1] = sum;
   }  
//----------------------syx-----------
   for(mi = 1; mi <= nn; mi++)
   {
      sum = 0.00000;
      for(n = i; n <= i + p; n++)
      {
         if(mi == 1)
            sum += Close[n];
         else
            sum += Close[n] * MathPow(n, mi - 1);
      }
      b[mi] = sum;
   } 
//===============Matrix=======================================================================================================
   for(jj = 1; jj <= nn; jj++)
   {
      for(ii = 1; ii <= nn; ii++)
      {
         kk = ii + jj - 1;
         ai[ii, jj] = sx[kk];
      }
   }  
//===============Gauss========================================================================================================
   for(kk = 1; kk <= nn - 1; kk++)
   {
      ll = 0; mm = 0;
      for(ii = kk; ii <= nn; ii++)
      {
         if(MathAbs(ai[ii, kk]) > mm)
         {
            mm = MathAbs(ai[ii, kk]);
            ll = ii;
         }
      }
      if(ll == 0)
         return(0);   

      if(ll != kk)
      {
         for(jj = 1; jj <= nn; jj++)
         {
            tt = ai[kk, jj];
            ai[kk, jj] = ai[ll, jj];
            ai[ll, jj] = tt;
         }
         tt = b[kk]; b[kk] = b[ll]; b[ll] = tt;
      }  
      for(ii = kk + 1; ii <= nn; ii++)
      {
         qq = ai[ii, kk] / ai[kk, kk];
         for(jj = 1; jj <= nn; jj++)
         {
            if(jj == kk)
               ai[ii, jj] = 0;
            else
               ai[ii, jj] = ai[ii, jj] - qq * ai[kk, jj];
         }
         b[ii] = b[ii] - qq * b[kk];
      }
   }  
   x[nn] = b[nn] / ai[nn, nn];
   for(ii = nn - 1; ii >= 1; ii--)
   {
      tt = 0;
      for(jj = 1; jj <= nn - ii; jj++)
      {
         tt = tt + ai[ii, ii + jj] * x[ii + jj];
         x[ii] = (1 / ai[ii, ii]) * (b[ii] - tt);
      }
   } 
//===========================================================================================================================
   for(n = i; n <= i + p; n++)
   {
      sum = 0;
      for(kk = 1; kk <= m; kk++)
      {
         sum += x[kk + 1] * MathPow(n, kk);
      }
      fx[n] = x[1] + sum;
   } 
//-----------------------------------Std-----------------------------------------------------------------------------------
   sq = 0.0;
   for(n = i; n <= i + p; n++)
   {
      sq += MathPow(Close[n] - fx[n], 2);
   }
   sq = MathSqrt(sq / (p + 1)) * kstd;
   std = iStdDev(NULL, 0, p, MODE_SMA, 0, PRICE_CLOSE, i) * kstd;
   for(n = i; n <= i + p; n++)
   {
      sqh[n] = fx[n] + sq;
      sql[n] = fx[n] - sq;
      stdh[n] = fx[n] + std;
      stdl[n] = fx[n] - std;
   } 
//-------------------------------------------------------------------------------
   ObjectMove("pr" + sName, 0, Time[p], fx[p]);
//----------------------------------------------------------------------------------------------------------------------------

//+--------- TRO MODIFICATION ---------------------------------------+  

   fx[0]   = NormalizeDouble(fx[0],digits) ;
   sql[0]  = NormalizeDouble(sql[0],digits) ;
   sqh[0]  = NormalizeDouble(sqh[0],digits) ;     
   stdh[0] = NormalizeDouble(stdh[0],digits) ;
   stdl[0] = NormalizeDouble(stdl[0],digits) ;
         
      if ( Trigger != Time[0] &&  Sound.Alert ) 
      {
        if( Close[0] == fx[0]  ) { Trigger = Time[0] ;  PlaySound(Sound.File1); }
        if( Close[0] == sqh[0] ) { Trigger = Time[0] ;  PlaySound(Sound.File2); }     
        if( Close[0] == sql[0] ) { Trigger = Time[0] ;  PlaySound(Sound.File2); }        
        if( Close[0] == stdh[0] ) { Trigger = Time[0] ;  PlaySound(Sound.File3); }    
        if( Close[0] == stdl[0] ) { Trigger = Time[0] ;  PlaySound(Sound.File3); }                 
      } 
  if(Show.PriceBox) { DoBox() ; } 
 
   return(0);
}
//==========================================================================================================================   

//+--------- TRO MODIFICATION ---------------------------------------+  
void DoBox()    
{


       if (ObjectFind(tShortName+"01") != 0)
      {
          ObjectCreate(tShortName+"01",OBJ_ARROW,0,Time[0],fx[0]);
          ObjectSet(tShortName+"01",OBJPROP_ARROWCODE,SYMBOL_RIGHTPRICE);
          ObjectSet(tShortName+"01",OBJPROP_COLOR,indicator_color1);  
          ObjectSet(tShortName+"01",OBJPROP_WIDTH,myBoxWidth);  
      } 
      else
      {
         ObjectMove(tShortName+"01",0,Time[0],fx[0]);
         ObjectSet(tShortName+"01",OBJPROP_COLOR,indicator_color1);  
      }

       if (ObjectFind(tShortName+"02") != 0)
      {
          ObjectCreate(tShortName+"02",OBJ_ARROW,0,Time[0],sqh[0]);
          ObjectSet(tShortName+"02",OBJPROP_ARROWCODE,SYMBOL_RIGHTPRICE);
          ObjectSet(tShortName+"02",OBJPROP_COLOR,indicator_color2);  
          ObjectSet(tShortName+"02",OBJPROP_WIDTH,myBoxWidth);  
      } 
      else
      {
         ObjectMove(tShortName+"02",0,Time[0],sqh[0]);
         ObjectSet(tShortName+"02",OBJPROP_COLOR,indicator_color2);  
      }

      
       if (ObjectFind(tShortName+"03") != 0)
      {
          ObjectCreate(tShortName+"03",OBJ_ARROW,0,Time[0],sql[0] );
          ObjectSet(tShortName+"03",OBJPROP_ARROWCODE,SYMBOL_RIGHTPRICE);
          ObjectSet(tShortName+"03",OBJPROP_COLOR,indicator_color3);  
          ObjectSet(tShortName+"03",OBJPROP_WIDTH,myBoxWidth);  
      } 
      else
      {
         ObjectMove(tShortName+"03",0,Time[0],sql[0]);
         ObjectSet(tShortName+"03",OBJPROP_COLOR,indicator_color3);  
      }
      

       if (ObjectFind(tShortName+"04") != 0)
      {
          ObjectCreate(tShortName+"04",OBJ_ARROW,0,Time[0],stdh[0]);
          ObjectSet(tShortName+"04",OBJPROP_ARROWCODE,SYMBOL_RIGHTPRICE);
          ObjectSet(tShortName+"04",OBJPROP_COLOR,indicator_color4);  
          ObjectSet(tShortName+"04",OBJPROP_WIDTH,myBoxWidth);  
      } 
      else
      {
         ObjectMove(tShortName+"04",0,Time[0],stdh[0]);
         ObjectSet(tShortName+"04",OBJPROP_COLOR,indicator_color4);  
      }
      

       if (ObjectFind(tShortName+"05") != 0)
      {
          ObjectCreate(tShortName+"05",OBJ_ARROW,0,Time[0],stdl[0]);
          ObjectSet(tShortName+"05",OBJPROP_ARROWCODE,SYMBOL_RIGHTPRICE);
          ObjectSet(tShortName+"05",OBJPROP_COLOR,indicator_color5);  
          ObjectSet(tShortName+"05",OBJPROP_WIDTH,myBoxWidth);  
      } 
      else
      {
         ObjectMove(tShortName+"05",0,Time[0],stdl[0]);
         ObjectSet(tShortName+"05",OBJPROP_COLOR,indicator_color5);  
      }
             
   return(0);
}


//+--------- TRO MODIFICATION ---------------------------------------+  

string TimeFrameToString(int tf)
{
   string tfs;
   switch(tf) {
      case PERIOD_M1:  tfs="M1"  ; break;
      case PERIOD_M5:  tfs="M5"  ; break;
      case PERIOD_M15: tfs="M15" ; break;
      case PERIOD_M30: tfs="M30" ; break;
      case PERIOD_H1:  tfs="H1"  ; break;
      case PERIOD_H4:  tfs="H4"  ; break;
      case PERIOD_D1:  tfs="D1"  ; break;
      case PERIOD_W1:  tfs="W1"  ; break;
      case PERIOD_MN1: tfs="MN";
   }
   return(tfs);
}


