//+------------------------------------------------------------------+
//|                                   Daily, Weekly & Monthly Pivots |
//|                      Copyright 2012, Deltabron - Paul Geirnaerdt |
//|                                          http://www.deltabron.nl |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, Deltabron - Paul Geirnaerdt"
#property link      "http://www.deltabron.nl"

#property indicator_separate_window
#property indicator_buffers 8

#define version            "v1.0.2"

//+------------------------------------------------------------------+
//| Release Notes                                                    |
//+------------------------------------------------------------------+
// v1.0.0, 7/3/12
// * Initial release
// v1.0.1, 8/30/12
// * Introduced addSundayToMonday option
// v1.0.2, 8/31/12
// * Added MA option

extern string  gen               = "----General inputs----";
extern string  nonPropFont   = "Lucida Console";
extern int     fontSize          = 14;

extern string  ind               = "----Indicator inputs----";
extern int     maxBars           = 0;
extern int     lineWidth         = 2;
extern bool    showW1            = false;
extern bool    showD1            = true;
extern bool    showH4            = true;
extern bool    showH1            = false;
extern bool    showM30           = false;
extern bool    showM15           = false;
extern bool    showM5            = false;
extern string  ind_ma            = "----Moving average----";
extern bool    showMA            = true;
extern string  ind_tf            = "----MA timeFrame H1,H4,D1,W1----";
extern string  MATimeFrame       = "D1";
extern string  ind_or            = "----MA period----";
extern int     MAPeriod          = 21;
extern string  ind_sm            = "----Add Sunday candles to Monday?----";
extern bool    addSundayToMonday = true;

extern string  col               = "----Colo(u)rs----";
extern color   colorW1           = C'0xFF,0x00,0x00';
extern color   colorD1           = C'0xFF,0x44,0x44';
extern color   colorH4           = C'0xFF,0x88,0x88';
extern color   colorH1           = C'0xFF,0xCC,0xCC';
extern color   colorM30          = C'0x00,0xFF,0x00';
extern color   colorM15          = C'0x44,0xFF,0x44';
extern color   colorM5           = C'0x88,0xFF,0x88';
extern color   colorMA           = C'0x44,0x44,0xFF';

//---- buffers
double W1Buffer[];
double D1Buffer[];
double H4Buffer[];
double H1Buffer[];
double M30Buffer[];
double M15Buffer[];
double M5Buffer[];
double MABuffer[];

//---- global variables
string   indicatorName = "TMA Slope MTF";
string   shortName;
datetime currentTime;
string   almostUniqueIndex;
bool     sundayCandlesDetected;                          
int      userTimeFrame;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   ArraySetAsSeries( MABuffer, true );

   shortName = indicatorName + " - " + version;
   IndicatorShortName(shortName);

   SetIndexBuffer ( 0, W1Buffer );
   SetIndexBuffer ( 1, D1Buffer );
   SetIndexBuffer ( 2, H4Buffer );
   SetIndexBuffer ( 3, H1Buffer );
   SetIndexBuffer ( 4, M30Buffer );
   SetIndexBuffer ( 5, M15Buffer );
   SetIndexBuffer ( 6, M5Buffer );
   SetIndexBuffer ( 7, MABuffer );

   SetIndexLabel ( 0, "W1" );
   SetIndexLabel ( 1, "D1" );
   SetIndexLabel ( 2, "H4" );
   SetIndexLabel ( 3, "H1" );
   SetIndexLabel ( 4, "M30" );
   SetIndexLabel ( 5, "M15" );
   SetIndexLabel ( 6, "M5" );
   SetIndexLabel ( 7, "MA" );
   
   sundayCandlesDetected = false;
   for ( int i = 0; i < 8; i++ )
   {
      if ( TimeDayOfWeek( iTime( NULL, PERIOD_D1, i ) ) == 0 )
      {
         sundayCandlesDetected = true;
         break;
      }
   }
   
   string now = TimeCurrent();
   almostUniqueIndex = StringSubstr(now, StringLen(now) - 3);

   userTimeFrame = PERIOD_D1;
	if ( MATimeFrame == "M5" )  userTimeFrame = PERIOD_M5;
	else if ( MATimeFrame == "M15" ) userTimeFrame = PERIOD_M15;
	else if ( MATimeFrame == "M30" ) userTimeFrame = PERIOD_M30;
	else if ( MATimeFrame == "H1" )  userTimeFrame = PERIOD_H1;
	else if ( MATimeFrame == "H4" )  userTimeFrame = PERIOD_H4;
	else if ( MATimeFrame == "D1" )  userTimeFrame = PERIOD_D1;
	else if ( MATimeFrame == "W1" )  userTimeFrame = PERIOD_W1;

   return ( 0 );
}

//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{
   int windex = WindowFind ( shortName );
   if ( windex > 0 )
   {
      ObjectsDeleteAll ( windex );
   }   

   return ( 0 );
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
   SetIndexStyle ( 0, DRAW_LINE, STYLE_SOLID, lineWidth, colorW1 );
   SetIndexStyle ( 1, DRAW_LINE, STYLE_SOLID, lineWidth, colorD1 );
   SetIndexStyle ( 2, DRAW_LINE, STYLE_SOLID, lineWidth, colorH4 );
   SetIndexStyle ( 3, DRAW_LINE, STYLE_SOLID, lineWidth, colorH1 );
   SetIndexStyle ( 4, DRAW_LINE, STYLE_SOLID, lineWidth, colorM30 );
   SetIndexStyle ( 5, DRAW_LINE, STYLE_SOLID, lineWidth, colorM15 );
   SetIndexStyle ( 6, DRAW_LINE, STYLE_SOLID, lineWidth, colorM5 );
   SetIndexStyle ( 7, DRAW_LINE, STYLE_SOLID, lineWidth, colorMA );

   int i;
   int counted_bars = IndicatorCounted();

   if ( counted_bars < 0 ) return ( -1 );
   if ( counted_bars > 0 ) counted_bars--;
   int limit = Bars - counted_bars;
   if ( maxBars > 0 && limit > maxBars ) limit = maxBars;

   for ( i = 0; i < limit; i++ )
   {
      currentTime = Time[i];
      
      if ( showW1 ) W1Buffer[i] = GetSlope( Symbol(), PERIOD_W1, iBarShift ( NULL, PERIOD_W1, currentTime ) );
      if ( showD1 ) D1Buffer[i] = GetSlope( Symbol(), PERIOD_D1, iBarShift ( NULL, PERIOD_D1, currentTime ) );
      if ( showH4 ) H4Buffer[i] = GetSlope( Symbol(), PERIOD_H4, iBarShift ( NULL, PERIOD_H4, currentTime ) );
      if ( showH1 ) H1Buffer[i] = GetSlope( Symbol(), PERIOD_H1, iBarShift ( NULL, PERIOD_H1, currentTime ) );
      if ( showM30 ) M30Buffer[i] = GetSlope( Symbol(), PERIOD_M30, iBarShift ( NULL, PERIOD_M30, currentTime ) );
      if ( showM15 ) M15Buffer[i] = GetSlope( Symbol(), PERIOD_M15, iBarShift ( NULL, PERIOD_M15, currentTime ) );
      if ( showM5 ) M5Buffer[i] = GetSlope( Symbol(), PERIOD_M5, iBarShift ( NULL, PERIOD_M5, currentTime ) );
      
      if ( i == 0 )
      {
         int row = 0;
         if ( showW1 ) { ShowTable("W1", W1Buffer[i], colorW1, row); row++; }
         if ( showD1 ) { ShowTable("D1", D1Buffer[i], colorD1, row); row++; }
         if ( showH4 ) { ShowTable("H4", H4Buffer[i], colorH4, row); row++; }
         if ( showH1 ) { ShowTable("H1", H1Buffer[i], colorH1, row); row++; }
         if ( showM30 ) { ShowTable("M30", M30Buffer[i], colorM30, row); row++; }
         if ( showM15 ) { ShowTable("M15", M15Buffer[i], colorM15, row); row++; }
         if ( showM5 ) { ShowTable("M5", M5Buffer[i], colorM5, row); row++; }
         if ( showMA ) { ShowTable(StringConcatenate( "MA(", MAPeriod, ")-", MATimeFrame), MABuffer[i], colorMA, row); row++; }
      }   
   }

   if ( showMA )
   {
      for ( i = 0; i < limit; i++ )
      {
         if ( MATimeFrame == "M5" )  MABuffer[i] = iMAOnArray( M5Buffer, 0, MAPeriod, 0, MODE_LWMA, i );
         else if ( MATimeFrame == "M15" ) MABuffer[i] = iMAOnArray( M15Buffer, 0, MAPeriod, 0, MODE_LWMA, i );
         else if ( MATimeFrame == "M30" ) MABuffer[i] = iMAOnArray( M30Buffer, 0, MAPeriod, 0, MODE_LWMA, i );
         else if ( MATimeFrame == "H1" )  MABuffer[i] = iMAOnArray( H1Buffer, 0, MAPeriod, 0, MODE_LWMA, i );
         else if ( MATimeFrame == "H4" )  MABuffer[i] = iMAOnArray( H4Buffer, 0, MAPeriod, 0, MODE_LWMA, i );
         else if ( MATimeFrame == "W1" )  MABuffer[i] = iMAOnArray( W1Buffer, 0, MAPeriod, 0, MODE_LWMA, i );
         else MABuffer[i] = iMAOnArray( D1Buffer, 0, MAPeriod, 0, MODE_LWMA, i );
      }
   }

   return ( 0 );
}

//+------------------------------------------------------------------+
//| GetSlope()                                                       |
//+------------------------------------------------------------------+
double GetSlope(string symbol, int tf, int shift)
{
   int shiftWithoutSunday = shift;
   if ( addSundayToMonday && sundayCandlesDetected && tf == PERIOD_D1 )
   {
      if ( TimeDayOfWeek( iTime( symbol, PERIOD_D1, shift ) ) == 0  ) shiftWithoutSunday++;
   }   
   double atr = iATR(symbol, tf, 100, shiftWithoutSunday + 10) / 10;
   double gadblSlope = 0.0;
   if ( atr != 0 )
   {
      double dblTma = calcTmaTrue( symbol, tf, shiftWithoutSunday );
      double dblPrev = calcPrevTrue( symbol, tf, shiftWithoutSunday );
      gadblSlope = ( dblTma - dblPrev ) / atr;
   }
   
   return ( gadblSlope );

}//End double GetSlope(int tf, int shift)

//+------------------------------------------------------------------+
//| calcTmaTrue()                                                    |
//+------------------------------------------------------------------+
double calcTmaTrue( string symbol, int tf, int inx )
{
   // return ( iMA( symbol, tf, 21, 0, MODE_LWMA, PRICE_CLOSE, inx ) );

   double dblSum  = 0;
   double dblSumw = 0;
   int jnx, knx;
   int sundayCandles = 0;

   for ( jnx = 0, knx = 21; jnx < 21; jnx++, knx-- )
   {
      if ( addSundayToMonday && sundayCandlesDetected && tf == PERIOD_D1 )
      {
         if ( TimeDayOfWeek( iTime( symbol, PERIOD_D1, inx + jnx + sundayCandles ) ) == 0 ) sundayCandles++;
      }   
      dblSum  += iClose( symbol, tf, inx + jnx + sundayCandles ) * knx;
      dblSumw += knx;
   }
   
   return ( dblSum / dblSumw );
}

//+------------------------------------------------------------------+
//| calcPrevTrue()                                                   |
//+------------------------------------------------------------------+
double calcPrevTrue( string symbol, int tf, int inx )
{
   double dblSum  = iClose( symbol, tf, inx ) * 20;
   double dblSumw = 20;
   int jnx, knx;
   int sundayCandles = 0;
   
   for ( jnx = 1, knx = 21; jnx < 22; jnx++, knx-- )
   {
      if ( addSundayToMonday && sundayCandlesDetected && tf == PERIOD_D1 )
      {
         if ( TimeDayOfWeek( iTime( symbol, PERIOD_D1, inx + jnx + sundayCandles ) ) == 0 ) sundayCandles++;
      }   
      dblSum  += iClose( symbol, tf, inx + jnx + sundayCandles ) * knx;
      dblSumw += knx;
   }
   
   return ( dblSum / dblSumw );
}

//+------------------------------------------------------------------+
//| ShowTable()                                              |
//+------------------------------------------------------------------+
void ShowTable( string showText, double showValue, color showColor, int row )
{
   string objectName;
   int windex = WindowFind ( shortName );

   objectName = almostUniqueIndex + "_tmamtf_obj_name_" + row;
   if ( ObjectFind ( objectName ) == -1 )
   {
      if ( ObjectCreate ( objectName, OBJ_LABEL, windex, 0, 0 ) )
      {
         ObjectSet ( objectName, OBJPROP_CORNER, 1 );
         ObjectSet ( objectName, OBJPROP_XDISTANCE, 75 );
         ObjectSet ( objectName, OBJPROP_YDISTANCE, 20 * row + 10 );
      }
   }
   ObjectSetText ( objectName, showText, fontSize, nonPropFont, showColor );

   objectName = almostUniqueIndex + "_tmamtf_obj_value_" + row;
   if ( ObjectFind ( objectName ) == -1 )
   {
      if ( ObjectCreate ( objectName, OBJ_LABEL, windex, 0, 0 ) )
      {
         ObjectSet ( objectName, OBJPROP_CORNER, 1 );
         ObjectSet ( objectName, OBJPROP_XDISTANCE, 75 - 60 );
         ObjectSet ( objectName, OBJPROP_YDISTANCE, 20 * row + 10 );
      }
   }
   showText = RightAlign(DoubleToStr(showValue, 2), 5);
   ObjectSetText ( objectName, showText, fontSize, nonPropFont, showColor );
}
   
//+------------------------------------------------------------------+
//| Right Align Text                                                 |
//+------------------------------------------------------------------+
string RightAlign ( string text, int length = 10, int trailing_spaces = 0 )
{
   string text_aligned = text;
   for ( int i = 0; i < length - StringLen ( text ) - trailing_spaces; i++ )
   {
      text_aligned = " " + text_aligned;
   }
   return ( text_aligned );
}

//+------------------------------------------------------------------+

