//+------------------------------------------------------------------+
//|                                   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_chart_window
#property indicator_buffers 4

#define version            "v1.0.9"

#import "kernel32.dll"
   int GetSystemTime(int& buf[]);
#import

//+------------------------------------------------------------------+
//| Release Notes                                                    |
//+------------------------------------------------------------------+
// v1.0.0, 6/29/12
// * Initial release
// v1.0.1, 7/2/12
// * Disabled lines if current timeframe >= pivot type
// * Option to integrate Sunday candles into Monday, if any
// * Option to show order of close by pivots
// v1.0.2, 7/6/2012
// * Option to start S&R lines at relevant bar
// v1.0.3, 7/12/2012
// * Fixed some issues with painting extension lines
// v1.0.4, 11/21/12
// * Added daily open
// * Added user settings for line style and width
// * Added order option without S&R values
// * Added order background option to show signal strength
// * Adeed user settings to include distance and value in S&R extension lines
// * Added fibonacci levels for current day
// v1.0.5, 12/17/12
// * Added order label with background for 10.2
// v1.0.6, 12/20/12 by Nanningbob
// * Added colors and variable for 10.2a & 10.3
// v1.0.7, 1/6/13 by NanningBob
// * Some more color changes and arrow directions
// v1.0.8, 1/8/13
// * Introduced hour shift for pivot calculation, credits Jellybean     /* EXPERIMENTAL */
// * Added 'shiftTextFibs' user setting
// v1.0.9, 1/11/13
// * Improved on GMT hour shift
// * Added user setting to display NB 10.x features

#define EPSILON             0.00000001

extern string  gen               = "----General inputs----";
extern string  textFont          = "Arial";
extern int     textSize          = 8;
extern color   textColor         = Red;

extern string  ind               = "----Indicator inputs----";
extern int     maxBars           = 2000;
extern bool    addSundayToMonday = true;
extern bool    shiftDayChange    = true;
extern int     hoursFromGMT      = 2;
extern string  lines             = "----Lines----";
extern bool    showDailyLine     = true;
extern bool    showDailyOpenLine = true;
extern bool    showWeeklyLine    = false;
extern bool    showMonthlyLine   = false;
extern string  sr                = "----S&R----";
extern bool    showDailySR       = true;
extern bool    showDailyOpenSR   = true;
extern bool    showWeeklySR      = false;
extern bool    showMonthlySR     = false;
extern bool    startSRAtOwnBar   = false;
extern bool    showFibonacci     = false; 
extern bool    includeDistance   = true;
extern bool    includeValue      = true;
extern string  ord               = "----Order----";
extern bool    showOrder         = true;
extern bool    showSRInOrder     = false;
extern bool    showOrderBackground = true;
extern int     shiftTextDaily    = 6;
extern int     shiftTextWeekly   = 6;
extern int     shiftTextMonthly  = 6;
extern int     shiftTextFibs     = 16;
extern string  nbb               = "----NanningBob 10.x----";
extern bool    show10.x          = true;
extern int     orderX10.2        = 30;
extern int     orderY10.2        = 50;
extern int     orderX10.3        = 30;
extern int     orderY10.3        = 20;
extern string  sty               = "----Line Style----";
extern int     styleDaily        = 0;
extern int     styleDailyOpen    = 0;
extern int     styleWeekly       = 0;
extern int     styleMonthly      = 0;
extern string  width             = "----Line Width----";
extern int     widthDaily        = 3;
extern int     widthDailyOpen    = 2;
extern int     widthWeekly       = 1;
extern int     widthMonthly      = 1;
extern string  col               = "----Line Colo(u)r----";
extern color   colorDaily        = Lime;
extern color   colorDailyOpen    = White;
extern color   colorWeekly       = Gold;
extern color   colorMonthly      = DeepPink;
extern color   colorFibonacci    = Pink;
extern color   colorOrder        = White;

//---- buffers
double DBuffer[];
double WBuffer[];
double MBuffer[];
double DOBuffer[];

//---- global variables
datetime currentTime;
int      pivotDayStart;
int      hourShift;
double   multiplier;
double   lastHigh, lastLow, lastClose;
double   DP, DS1, DR1, DS2, DR2, DS3, DR3;
double   WP, WS1, WR1, WS2, WR2, WS3, WR3;
double   MP, MS1, MR1, MS2, MR2, MS3, MR3;
double   DO;
int      pivotBar;
string   pivotNames[33] = { "DP", "DS1", "DR1", "DS2", "DR2", "DS3", "DR3",
                            "WP", "WS1", "WR1", "WS2", "WR2", "WS3", "WR3",
                            "MP", "MS1", "MR1", "MS2", "MR2", "MS3", "MR3",
                            "DO", "P",
                            "FibS1", "FibS2", "FibS3", "FibS4", "FibS5", 
                            "FibR1", "FibR2", "FibR3", "FibR4", "FibR5"
                          };
double   pivotValues[23][2];                          
bool     sundayCandlesDetected;                          

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   multiplier = 10000;
   if ( StringFind ( Symbol(), "JPY" ) != -1 )
   {
      multiplier = 100;
   }
   
   sundayCandlesDetected = false;
   for ( int i = 0; i < 8; i++ )
   {
      if ( TimeDayOfWeek( iTime( NULL, PERIOD_D1, i ) ) == 0 )
      {
         sundayCandlesDetected = true;
         break;
      }
   }

   hourShift = getGMTHour() - TimeHour(TimeCurrent()) + hoursFromGMT;
   pivotDayStart = Time[Bars - 1];         
   
   SetIndexBuffer ( 0, DBuffer );
   SetIndexBuffer ( 1, WBuffer );
   SetIndexBuffer ( 2, MBuffer );
   SetIndexBuffer ( 3, DOBuffer );

   SetIndexLabel ( 0, "DP" );
   SetIndexLabel ( 1, "WP" );
   SetIndexLabel ( 2, "MP" );
   SetIndexLabel ( 3, "DO" );
   
   if ( Period() >= PERIOD_D1 )
   {
      showDailyLine = false;
      showDailySR = false; 
   }   
   if ( Period() >= PERIOD_W1 )
   {
      showWeeklyLine = false;
      showWeeklySR = false; 
   }   
   if ( Period() >= PERIOD_MN1 )
   {
      showMonthlyLine = false;
      showMonthlySR = false; 
   }   

   // Line text objects
   // Daily
   if ( showDailySR )
   {
      createSR( 0, 7 );
      createExtension( 0, 7, colorDaily );
   }
   // Weekly
   if ( showWeeklySR )
   {
      createSR( 7, 14 );
      createExtension( 7, 14, colorWeekly );
   }
   // Monthly
   if ( showMonthlySR )
   {
      createSR( 14, 21 );
      createExtension( 14, 21, colorMonthly );
   }
   // Daily Open
   if ( showDailyOpenSR )
   {
      createSR( 21, 22 );
      createExtension( 21, 22, colorDailyOpen );
   }
   // Daily Open
   if ( showFibonacci )
   {
      createSR( 22, 33 );
      createExtension( 22, 33, colorFibonacci );
   }
   return ( 0 );
}

//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{
   for ( int i = ObjectsTotal() - 1; i >= 0; i-- )
   {
      for ( int j = 0; j < ArraySize( pivotNames ); j++ )
      {
         if ( ObjectFind( pivotNames[j] ) != -1 ) ObjectDelete( pivotNames[j] );
         if ( ObjectFind( pivotNames[j] + "ext" ) != -1 ) ObjectDelete( pivotNames[j] + "ext" );
      }
      if ( ObjectFind( "DWMpivotText10.3" ) != -1 ) ObjectDelete( "DWMpivotText10.3" );
      if ( ObjectFind( "DWMpivotText10.3lbl" ) != -1 ) ObjectDelete( "DWMpivotText10.3lbl" );
      if ( ObjectFind( "DWMpivotText10.2" ) != -1 ) ObjectDelete( "DWMpivotText10.2" );
      if ( ObjectFind( "DWMpivotText10.2lbl" ) != -1 ) ObjectDelete( "DWMpivotText10.2lbl" );
   }      
   deleteCell( "orderBackground10.3" );
   deleteCell( "orderBackground10.2" );
   ObjectDelete( "orderBackgroundBullet10.3" );
   ObjectDelete( "orderBackgroundBullet10.2" );

   return ( 0 );
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
   SetIndexStyle ( 0, DRAW_LINE, styleDaily, widthDaily, colorDaily );
   SetIndexStyle ( 1, DRAW_LINE, styleWeekly, widthWeekly, colorWeekly );
   SetIndexStyle ( 2, DRAW_LINE, styleMonthly, widthMonthly, colorMonthly );
   SetIndexStyle ( 3, DRAW_LINE, styleDailyOpen, widthDailyOpen, colorDailyOpen );

   int i, j;
   int shiftText;
   datetime start;

   int counted_bars = IndicatorCounted();

   if ( counted_bars < 0 )
   {
      return ( -1 );
   }

   if ( counted_bars > 0 )
   {
      counted_bars--;
   }
   int limit = Bars - counted_bars;

   if ( limit > maxBars )
   {
      limit = maxBars;
   }
   for ( i = limit; i >= 0; i-- )
   {
      currentTime = Time[i];
      
      // Daily
      if ( shiftDayChange )
      {
         int barHour = iBarShift( NULL, PERIOD_H1, Time[i] );
         int shiftHour = TimeHour( iTime( NULL, PERIOD_H1, barHour ) ) + hourShift;
         if ( shiftHour < 0 ) shiftHour += 24;
         if ( shiftHour > 23 ) shiftHour -= 24;
         
         lastHigh = iHigh( NULL, PERIOD_H1, iHighest( NULL, PERIOD_H1, MODE_HIGH, 24, barHour + shiftHour + 1 ) );
         lastLow = iLow( NULL, PERIOD_H1, iLowest( NULL, PERIOD_H1, MODE_LOW, 24, barHour + shiftHour + 1 ) );
         lastClose = iClose( NULL, PERIOD_H1, barHour + shiftHour + 1 );
         
         DP = ( lastHigh + lastLow + lastClose ) / 3;
         DO = iOpen( NULL, PERIOD_H1, barHour + shiftHour );

         DR1 = ( 2 * DP ) - lastLow;
         DS1 = ( 2 * DP ) - lastHigh;
         DR2 = DP + ( lastHigh - lastLow );
         DS2 = DP - ( lastHigh - lastLow );
         DR3 = ( 2 * DP ) + ( lastHigh - ( 2 * lastLow ) );
         DS3 = ( 2 * DP ) - ( ( 2 * lastHigh ) - lastLow );
         
         // Jellybean's code
         /*
         if ( getPivotDay( Time[i + 1] ) != getPivotDay( Time[i] ) )
         {
            int pivotDayBars = iBarShift( NULL, 0, pivotDayStart ) - i;
            lastHigh = High[iHighest( NULL, 0, MODE_HIGH, pivotDayBars, i + 1 )];
            lastLow = Low[iLowest( NULL, 0, MODE_LOW, pivotDayBars, i + 1 )];
            lastClose = Close[i + 1];
            
            DP = ( lastHigh + lastLow + lastClose ) / 3;
            DR1 = ( 2 * DP ) - lastLow;
            DS1 = ( 2 * DP ) - lastHigh;
            DR2 = DP + ( lastHigh - lastLow );
            DS2 = DP - ( lastHigh - lastLow );
            DR3 = ( 2 * DP ) + ( lastHigh - ( 2 * lastLow ) );
            DS3 = ( 2 * DP ) - ( ( 2 * lastHigh ) - lastLow );
            
            DO = Open[i];
            
            pivotDayStart = Time[i];     
         }
         */
      }
      else
      {
         pivotBar = iBarShift ( NULL, PERIOD_D1, currentTime ) + 1;

         if ( addSundayToMonday && sundayCandlesDetected )
         {
            if ( TimeDayOfWeek( iTime( NULL, PERIOD_D1, pivotBar ) ) == 0 )
            {
               // Sunday, shift to friday
               pivotBar = pivotBar + 1;
            }
         }   

         // Is this a weekday?
         lastLow = iLow ( NULL, PERIOD_D1, pivotBar );
         lastHigh = iHigh ( NULL, PERIOD_D1, pivotBar );
         lastClose = iClose ( NULL, PERIOD_D1, pivotBar );

         if ( addSundayToMonday && sundayCandlesDetected )
         {
            if ( TimeDayOfWeek( iTime( NULL, PERIOD_D1, pivotBar ) ) == 1 )
            {
               // Monday, add Sunday
               lastLow = MathMin( iLow ( NULL, PERIOD_D1, pivotBar ), iLow ( NULL, PERIOD_D1, pivotBar + 1 ) );
               lastHigh = MathMax( iHigh ( NULL, PERIOD_D1, pivotBar ), iHigh ( NULL, PERIOD_D1, pivotBar + 1 ) );
            }
         }

         DP = ( lastHigh + lastLow + lastClose ) / 3;
         DR1 = ( 2 * DP ) - lastLow;
         DS1 = ( 2 * DP ) - lastHigh;
         DR2 = DP + ( lastHigh - lastLow );
         DS2 = DP - ( lastHigh - lastLow );
         DR3 = ( 2 * DP ) + ( lastHigh - ( 2 * lastLow ) );
         DS3 = ( 2 * DP ) - ( ( 2 * lastHigh ) - lastLow );

         // Daily Open
         pivotBar = iBarShift( NULL, PERIOD_D1, currentTime );
         DO = iMA( NULL, PERIOD_D1, 1, 0, MODE_SMA, PRICE_OPEN, pivotBar );
      }
      
      if ( showDailyLine ) DBuffer[i] = DP;

      if ( showDailyOpenLine ) DOBuffer[i] = DO;

      // Weekly
      pivotBar = iBarShift ( NULL, PERIOD_W1, currentTime );
      lastLow = iLow ( NULL, PERIOD_W1, pivotBar + 1 );
      lastHigh = iHigh ( NULL, PERIOD_W1, pivotBar + 1 );
      lastClose = iClose ( NULL, PERIOD_W1, pivotBar + 1 );

      WP = ( lastHigh + lastLow + lastClose ) / 3;
      WR1 = ( 2 * WP ) - lastLow;
      WS1 = ( 2 * WP ) - lastHigh;
      WR2 = WP + ( lastHigh - lastLow );
      WS2 = WP - ( lastHigh - lastLow );
      WR3 = ( 2 * WP ) + ( lastHigh - ( 2 * lastLow ) );
      WS3 = ( 2 * WP ) - ( ( 2 * lastHigh ) - lastLow );

      if ( showWeeklyLine ) WBuffer[i] = WP;

      // Monthly
      pivotBar = iBarShift ( NULL, PERIOD_MN1, currentTime );
      lastLow = iLow ( NULL, PERIOD_MN1, pivotBar + 1 );
      lastHigh = iHigh ( NULL, PERIOD_MN1, pivotBar + 1 );
      lastClose = iClose ( NULL, PERIOD_MN1, pivotBar + 1 );
      
      MP = ( lastHigh + lastLow + lastClose ) / 3;
      MR1 = ( 2 * MP ) - lastLow;
      MS1 = ( 2 * MP ) - lastHigh;
      MR2 = MP + ( lastHigh - lastLow );
      MS2 = MP - ( lastHigh - lastLow );
      MR3 = ( 2 * MP ) + ( lastHigh - ( 2 * lastLow ) );
      MS3 = ( 2 * MP ) - ( ( 2 * lastHigh ) - lastLow );

      if ( showMonthlyLine ) MBuffer[i] = MP;
      
      if ( showFibonacci && i == 0 )
      {
         shiftText = shiftTextFibs * 60 * Period();
         start = iTime( NULL, PERIOD_D1, 0 );
         double fib;
         double range = getAverageRange();
         fib = DO + ( range * 0.382 );
         ObjectMove ( "FibR1ext", 0, start, fib );
         ObjectMove ( "FibR1ext", 1, Time[0], fib );
         ObjectMove ( "FibR1", 0, Time[0] + shiftText, fib );
         ObjectSetText ( "FibR1", "FibR1 " + getExtensionText( fib ) );
         fib = DO - ( range * 0.382 );
         ObjectMove ( "FibS1ext", 0, start, fib );
         ObjectMove ( "FibS1ext", 1, Time[0], fib );
         ObjectMove ( "FibS1", 0, Time[0] + shiftText, fib );
         ObjectSetText ( "FibS1", "FibS1 " + getExtensionText( fib ) );
         fib = DO + ( range * 0.618 );
         ObjectMove ( "FibR2ext", 0, start, fib );
         ObjectMove ( "FibR2ext", 1, Time[0], fib );
         ObjectMove ( "FibR2", 0, Time[0] + shiftText, fib );
         ObjectSetText ( "FibR2", "FibR2 " + getExtensionText( fib ) );
         fib = DO - ( range * 0.618 );
         ObjectMove ( "FibS2ext", 0, start, fib );
         ObjectMove ( "FibS2ext", 1, Time[0], fib );
         ObjectMove ( "FibS2", 0, Time[0] + shiftText, fib );
         ObjectSetText ( "FibS2", "FibS2 " + getExtensionText( fib ) );
         fib = DO + ( range * 0.764 );
         ObjectMove ( "FibR3ext", 0, start, fib );
         ObjectMove ( "FibR3ext", 1, Time[0], fib );
         ObjectMove ( "FibR3", 0, Time[0] + shiftText, fib );
         ObjectSetText ( "FibR3", "FibR3 " + getExtensionText( fib ) );
         fib = DO - ( range * 0.764 );
         ObjectMove ( "FibS3ext", 0, start, fib );
         ObjectMove ( "FibS3ext", 1, Time[0], fib );
         ObjectMove ( "FibS3", 0, Time[0] + shiftText, fib );
         ObjectSetText ( "FibS3", "FibS3 " + getExtensionText( fib ) );
         fib = DO + ( range * 1.000 );
         ObjectMove ( "FibR4ext", 0, start, fib );
         ObjectMove ( "FibR4ext", 1, Time[0], fib );
         ObjectMove ( "FibR4", 0, Time[0] + shiftText, fib );
         ObjectSetText ( "FibR4", "FibR4 " + getExtensionText( fib ) );
         fib = DO - ( range * 1.000 );
         ObjectMove ( "FibS4ext", 0, start, fib );
         ObjectMove ( "FibS4ext", 1, Time[0], fib );
         ObjectMove ( "FibS4", 0, Time[0] + shiftText, fib );
         ObjectSetText ( "FibS4", "FibS4 " + getExtensionText( fib ) );
         fib = DO + ( range * 1.382 );
         ObjectMove ( "FibR5ext", 0, start, fib );
         ObjectMove ( "FibR5ext", 1, Time[0], fib );
         ObjectMove ( "FibR5", 0, Time[0] + shiftText, fib );
         ObjectSetText ( "FibR5", "FibR5 " + getExtensionText( fib ) );
         fib = DO - ( range * 1.382 );
         ObjectMove ( "FibS5ext", 0, start, fib );
         ObjectMove ( "FibS5ext", 1, Time[0], fib );
         ObjectMove ( "FibS5", 0, Time[0] + shiftText, fib );
         ObjectSetText ( "FibS5", "FibS5 " + getExtensionText( fib ) );
      }
      
      if ( showOrder && i == 0 )
      {
         double P = Bid;
         if ( showSRInOrder )
         {
            ArrayInitialize(pivotValues, 0.0);
            for ( j = 0; j < 23; j++ )
            {
               pivotValues[j][1] = j;
            }
            pivotValues[0][0] = DP;
            pivotValues[1][0] = DS1;
            pivotValues[2][0] = DR1;
            pivotValues[3][0] = DS2;
            pivotValues[4][0] = DR2;
            pivotValues[5][0] = DS3;
            pivotValues[6][0] = DR3;
            pivotValues[7][0] = WP;
            pivotValues[8][0] = WS1;
            pivotValues[9][0] = WR1;
            pivotValues[10][0] = WS2;
            pivotValues[11][0] = WR2;
            pivotValues[12][0] = WS3;
            pivotValues[13][0] = WR3;
            pivotValues[14][0] = MP;
            pivotValues[15][0] = MS1;
            pivotValues[16][0] = MR1;
            pivotValues[17][0] = MS2;
            pivotValues[18][0] = MR2;
            pivotValues[19][0] = MS3;
            pivotValues[20][0] = MR3;
            pivotValues[21][0] = DO;
            pivotValues[22][0] = P;

            ArraySort(pivotValues, WHOLE_ARRAY, 0, MODE_ASCEND);
            
            int index;
            for ( j = 0; j < 20; j++ )
            {
               if ( pivotValues[j][0] > Bid )
               {
                  break;
               }
            }
            
            string pivotsText;

            if ( j > 2 )
            {
               index = pivotValues[j - 3][1];
               pivotsText = pivotNames[index];
            }   
            if ( j > 1 )
            {
               index = pivotValues[j - 2][1];
               pivotsText = StringConcatenate( pivotsText, " ", pivotNames[index] );
            }   
            if ( j > 0 )
            {
               index = pivotValues[j - 1][1];
               pivotsText = StringConcatenate( pivotsText, " ", pivotNames[index] );
            }   
            if ( j < 20 )
            {
               index = pivotValues[j + 0][1];
               pivotsText = StringConcatenate( pivotsText, " ", pivotNames[index] );
            }   
            if ( j < 19 )
            {
               index = pivotValues[j + 1][1];
               pivotsText = StringConcatenate( pivotsText, " ", pivotNames[index] );
            }   
         }
         else
         {
            ArrayInitialize(pivotValues, 0.0);
            for ( j = 0; j < 23; j++ )
            {
               pivotValues[j][1] = j;
            }
            pivotValues[0][0] = DP;
            pivotValues[7][0] = WP;
            pivotValues[14][0] = MP;
            pivotValues[21][0] = DO;
            pivotValues[22][0] = P;

            ArraySort(pivotValues, WHOLE_ARRAY, 0, MODE_ASCEND);
            
            bool priceSet = false;
            pivotsText = "";
            for ( j = 0; j < 23; j++ )
            {
               if ( pivotValues[j][0] < EPSILON ) continue;
               index = pivotValues[j][1];
               pivotsText = StringConcatenate( pivotsText, " ", pivotNames[index] );
            }
         }

         // Display Order Text For 10.3
         string objectName = "DWMpivotText10.3";
         if ( ObjectFind ( objectName ) == -1 )
         {
            if ( ObjectCreate ( objectName, OBJ_LABEL, 0, 0, 0 ) )
            {
               ObjectSet ( objectName, OBJPROP_CORNER, 3 );
               ObjectSet ( objectName, OBJPROP_XDISTANCE, orderX10.3 );
               ObjectSet ( objectName, OBJPROP_YDISTANCE, orderY10.3 );
            }
         }
         ObjectSetText ( objectName, pivotsText, 10, textFont, colorOrder );
         
         int cellWidth = 120;
         if ( showSRInOrder ) cellWidth = 135;

         if ( show10.x )
         {
            // Display '10.3' Label to Right of Order Text For 10.3
            objectName = "DWMpivotText10.3lbl";
            if ( ObjectFind ( objectName ) == -1 )
            {
               if ( ObjectCreate ( objectName, OBJ_LABEL, 0, 0, 0 ) )
               {
                  ObjectSet ( objectName, OBJPROP_CORNER, 3 );
                  ObjectSet ( objectName, OBJPROP_XDISTANCE, orderX10.3 - 19 );
                  ObjectSet ( objectName, OBJPROP_YDISTANCE, orderY10.3 + 18 );
                  ObjectSet ( objectName, OBJPROP_ANGLE, 90 );
               }
            }
            ObjectSetText ( objectName, "10.3", 7, textFont, colorOrder );
            
            // Display Order Text For 10.2
            objectName = "DWMpivotText10.2";
            if ( ObjectFind ( objectName ) == -1 )
            {
               if ( ObjectCreate ( objectName, OBJ_LABEL, 0, 0, 0 ) )
               {
                  ObjectSet ( objectName, OBJPROP_CORNER, 3 );
                  ObjectSet ( objectName, OBJPROP_XDISTANCE, orderX10.2 );
                  ObjectSet ( objectName, OBJPROP_YDISTANCE, orderY10.2 );
               }
            }
            ObjectSetText ( objectName, pivotsText, 10, textFont, colorOrder );
            
            // Display '10.2' Label to Right of Order Text For 10.2
            objectName = "DWMpivotText10.2lbl";
            if ( ObjectFind ( objectName ) == -1 )
            {
               if ( ObjectCreate ( objectName, OBJ_LABEL, 0, 0, 0 ) )
               {
                  ObjectSet ( objectName, OBJPROP_CORNER, 3 );
                  ObjectSet ( objectName, OBJPROP_XDISTANCE, orderX10.2 - 19 );
                  ObjectSet ( objectName, OBJPROP_YDISTANCE, orderY10.2 + 18 );
                  ObjectSet ( objectName, OBJPROP_ANGLE, 90 );
               }
            }
            ObjectSetText ( objectName, "10.2a", 7, textFont, colorOrder );

            // Display Order Arrow For 10.3
            if ( showDailyOpenLine )
            {
               // Direction
               int arrow = 225;
               if ( DO < DP ) arrow = 226; else arrow = 225;
               drawBullet( "orderBackgroundBullet10.3", 3, cellWidth + orderX10.3, orderY10.3, colorOrder, arrow );
            }
            
            // Display Order Arrow For 10.2a
            if ( showDailyOpenLine )
            {
               // Direction 10.2a
               arrow = 224; // Ranging
               if ( DP > WP && Bid > WP) arrow = 225; // Up
               if ( DP < WP && Bid < WP) arrow = 226; // Down
               drawBullet( "orderBackgroundBullet10.2", 3, cellWidth + orderX10.2, orderY10.2, colorOrder, arrow );
            }
         }

         // Display Order Background
         if ( showOrderBackground )
         {
            // STANDARD DWMPIVOT COLORS FOR 10.3
            color colorOrderBackground = Gray;//missed 10.3 trade
            if ( show10.x )
            {
               if ( DP > DO && P > DO ) colorOrderBackground = Maroon; //10.3 sell trade possible
               if ( DP < DO && P < DO ) colorOrderBackground = DarkGreen;//10.3 buy trade possible
            }
            drawCell( 0, "orderBackground10.3", 3, orderX10.3 - 10, orderY10.3 - 11, cellWidth, 20, colorOrderBackground );

            // STANDARD DWMPIVOT COLORS FOR 10.2A
            if ( show10.x )
            {
               colorOrderBackground = Goldenrod;
               // Triple alignment
               if ( DP > WP && Bid > WP && Bid > DP ) colorOrderBackground = DarkGreen;  // 10 .2a Trend 10.3 buy reenter trend 
               if ( DP > WP && Bid > WP && Bid < DP ) colorOrderBackground = LimeGreen;  // 10.2a viable BUY trade/ranging/reversal     
               if ( DP < WP && Bid < WP && Bid < DP ) colorOrderBackground = Maroon;     // 10.2a Trend 10.3 sell reenter trend
               if ( DP < WP && Bid < WP && Bid > DP ) colorOrderBackground = HotPink;    // 10.2a viable sell trade/ranging/reversal
               drawCell( 0, "orderBackground10.2", 3, orderX10.2 - 10, orderY10.2 - 11, cellWidth, 20, colorOrderBackground );
            }
            else
            {
               deleteCell( "orderBackground10.2" );
            }
         }

      }
      
      if ( !showOrder && i == 0 )
      {
         deleteCell( "orderBackground10.3" );
         deleteCell( "orderBackground10.2" );
      }
   }


   // Move text
   // Daily
   if ( showDailySR )
   {
      shiftText = shiftTextDaily * 60 * Period();
      ObjectMove ( "DP", 0, Time[0] + shiftText, DP );
      ObjectSetText ( "DP", "DP " + getExtensionText( DP ) );
      ObjectMove ( "DS1", 0, Time[0] + shiftText, DS1 );
      ObjectSetText ( "DS1", "DS1 " + getExtensionText( DS1 ) );
      ObjectMove ( "DR1", 0, Time[0] + shiftText, DR1 );
      ObjectSetText ( "DR1", "DR1 " + getExtensionText( DR1 ) );
      ObjectMove ( "DS2", 0, Time[0] + shiftText, DS2 );
      ObjectSetText ( "DS2", "DS2 " + getExtensionText( DS2 ) );
      ObjectMove ( "DR2", 0, Time[0] + shiftText, DR2 );
      ObjectSetText ( "DR2", "DR2 " + getExtensionText( DR2 ) );
      ObjectMove ( "DS3", 0, Time[0] + shiftText, DS3 );
      ObjectSetText ( "DS3", "DS3 " + getExtensionText( DS3 ) );
      ObjectMove ( "DR3", 0, Time[0] + shiftText, DR3 );
      ObjectSetText ( "DR3", "DR3 " + getExtensionText( DR3 ) );
   }
   // Weekly
   if ( showWeeklySR )
   {
      shiftText = shiftTextWeekly * 60 * Period();
      ObjectMove ( "WP", 0, Time[0] + shiftText, WP );
      ObjectSetText ( "WP", "WP " + getExtensionText( WP ) );
      ObjectMove ( "WS1", 0, Time[0] + shiftText, WS1 );
      ObjectSetText ( "WS1", "WS1 " + getExtensionText( WS1 ) );
      ObjectMove ( "WR1", 0, Time[0] + shiftText, WR1 );
      ObjectSetText ( "WR1", "WR1 " + getExtensionText( WR1 ) );
      ObjectMove ( "WS2", 0, Time[0] + shiftText, WS2 );
      ObjectSetText ( "WS2", "WS2 " + getExtensionText( WS2 ) );
      ObjectMove ( "WR2", 0, Time[0] + shiftText, WR2 );
      ObjectSetText ( "WR2", "WR2 " + getExtensionText( WR2 ) );
      ObjectMove ( "WS3", 0, Time[0] + shiftText, WS3 );
      ObjectSetText ( "WS3", "WS3 " + getExtensionText( WS3 ) );
      ObjectMove ( "WR3", 0, Time[0] + shiftText, WR3 );
      ObjectSetText ( "WR3", "WR3 " + getExtensionText( WR3 ) );
   }
   // Monthly
   if ( showMonthlySR )
   {
      shiftText = shiftTextMonthly * 60 * Period();
      ObjectMove ( "MP", 0, Time[0] + shiftText, MP );
      ObjectSetText ( "MP", "MP " + getExtensionText( MP ) );
      ObjectMove ( "MS1", 0, Time[0] + shiftText, MS1 );
      ObjectSetText ( "MS1", "MS1 " + getExtensionText( MS1 ) );
      ObjectMove ( "MR1", 0, Time[0] + shiftText, MR1 );
      ObjectSetText ( "MR1", "MR1 " + getExtensionText( MR1 ) );
      ObjectMove ( "MS2", 0, Time[0] + shiftText, MS2 );
      ObjectSetText ( "MS2", "MS2 " + getExtensionText( MS2 ) );
      ObjectMove ( "MR2", 0, Time[0] + shiftText, MR2 );
      ObjectSetText ( "MR2", "MR2 " + getExtensionText( MR2 ) );
      ObjectMove ( "MS3", 0, Time[0] + shiftText, MS3 );
      ObjectSetText ( "MS3", "MS3 " + getExtensionText( MS3 ) );
      ObjectMove ( "MR3", 0, Time[0] + shiftText, MR3 );
      ObjectSetText ( "MR3", "MR3 " + getExtensionText( MR3 ) );
   }

   // Daily Open
   if ( showDailyOpenSR )
   {
      shiftText = shiftTextDaily * 60 * Period();
      ObjectMove ( "DO", 0, Time[0] + shiftText, DO );
      ObjectSetText ( "DO", "DO " + getExtensionText( DO ) );
   }
   // Move extension lines
   // Daily
   if ( showDailySR )
   {
      ObjectMove ( "DPext", 0, Time[1], DP );
      ObjectMove ( "DPext", 1, Time[0], DP );
      ObjectMove ( "DR1ext", 0, Time[1], DR1 );
      ObjectMove ( "DR1ext", 1, Time[0], DR1 );
      ObjectMove ( "DR2ext", 0, Time[1], DR2 );
      ObjectMove ( "DR2ext", 1, Time[0], DR2 );
      ObjectMove ( "DR3ext", 0, Time[1], DR3 );
      ObjectMove ( "DR3ext", 1, Time[0], DR3 );
      ObjectMove ( "DS1ext", 0, Time[1], DS1 );
      ObjectMove ( "DS1ext", 1, Time[0], DS1 );
      ObjectMove ( "DS2ext", 0, Time[1], DS2 );
      ObjectMove ( "DS2ext", 1, Time[0], DS2 );
      ObjectMove ( "DS3ext", 0, Time[1], DS3 );
      ObjectMove ( "DS3ext", 1, Time[0], DS3 );
   }
   // Weekly
   if ( showWeeklySR )
   {
      start = Time[1];
      if ( startSRAtOwnBar ) start = iTime( NULL, PERIOD_W1, 0 );
      ObjectMove ( "WPext", 0, start, WP );
      ObjectMove ( "WPext", 1, Time[0], WP );
      ObjectMove ( "WR1ext", 0, start, WR1 );
      ObjectMove ( "WR1ext", 1, Time[0], WR1 );
      ObjectMove ( "WR2ext", 0, start, WR2 );
      ObjectMove ( "WR2ext", 1, Time[0], WR2 );
      ObjectMove ( "WR3ext", 0, start, WR3 );
      ObjectMove ( "WR3ext", 1, Time[0], WR3 );
      ObjectMove ( "WS1ext", 0, start, WS1 );
      ObjectMove ( "WS1ext", 1, Time[0], WS1 );
      ObjectMove ( "WS2ext", 0, start, WS2 );
      ObjectMove ( "WS2ext", 1, Time[0], WS2 );
      ObjectMove ( "WS3ext", 0, start, WS3 );
      ObjectMove ( "WS3ext", 1, Time[0], WS3 );
   }
   // Monthly
   if ( showMonthlySR )
   {
      start = Time[1];
      if ( startSRAtOwnBar ) start = iTime( NULL, PERIOD_MN1, 0 );
      ObjectMove ( "MPext", 0, start, MP );
      ObjectMove ( "MPext", 1, Time[0], MP );
      ObjectMove ( "MR1ext", 0, start, MR1 );
      ObjectMove ( "MR1ext", 1, Time[0], MR1 );
      ObjectMove ( "MR2ext", 0, start, MR2 );
      ObjectMove ( "MR2ext", 1, Time[0], MR2 );
      ObjectMove ( "MR3ext", 0, start, MR3 );
      ObjectMove ( "MR3ext", 1, Time[0], MR3 );
      ObjectMove ( "MS1ext", 0, start, MS1 );
      ObjectMove ( "MS1ext", 1, Time[0], MS1 );
      ObjectMove ( "MS2ext", 0, start, MS2 );
      ObjectMove ( "MS2ext", 1, Time[0], MS2 );
      ObjectMove ( "MS3ext", 0, start, MS3 );
      ObjectMove ( "MS3ext", 1, Time[0], MS3 );
   }

   // Daily Open
   if ( showDailyOpenSR )
   {
      ObjectMove ( "DOext", 0, Time[1], DO );
      ObjectMove ( "DOext", 1, Time[0], DO );
   }
   return ( 0 );
}

//+------------------------------------------------------------------+
//| getGMTHour()                                                     |
//+------------------------------------------------------------------+
int getGMTHour()
{
   int buffer[4];
   GetSystemTime( buffer );
   return ( buffer[2] & 0xFFFF );
}
//+------------------------------------------------------------------+
//| getPivotDay()                                                    |
//+------------------------------------------------------------------+
int getPivotDay( datetime barTime  )
{
   int day = TimeDayOfWeek( barTime + hourShift * 3600 );

   if ( day == 0 ) day++;
   if ( day == 6 ) day--;

   return( day );
}
//+------------------------------------------------------------------+
//| Average Range                                                    |
//+------------------------------------------------------------------+
double getAverageRange()
{
	int i;
	int bar = 1;
    int longADRPeriod = 100;
    int shortADRPeriod = 3;
	double localHigh, localLow;
	double highMALong, lowMALong;
	double highMAShort, lowMAShort;
	for ( i = 0; i < longADRPeriod; i++ )
	{
		localLow = iLow ( NULL, PERIOD_D1, bar );
		localHigh = iHigh ( NULL, PERIOD_D1, bar );
		if ( addSundayToMonday && sundayCandlesDetected )
		{
			if ( TimeDayOfWeek( iTime( NULL, PERIOD_D1, bar ) ) == 0 )
			{
				// Sunday, shift to friday
				bar++;
			}
			localLow = iLow ( NULL, PERIOD_D1, bar );
			localHigh = iHigh ( NULL, PERIOD_D1, bar );
			if ( TimeDayOfWeek( iTime( NULL, PERIOD_D1, bar ) ) == 1 )
			{
				// Monday, add Sunday
				localLow = MathMin( iLow ( NULL, PERIOD_D1, bar ), iLow ( NULL, PERIOD_D1, bar + 1 ) );
				localHigh = MathMax( iHigh ( NULL, PERIOD_D1, bar ), iHigh ( NULL, PERIOD_D1, bar + 1 ) );
			}
		}
		lowMALong += localLow;
		highMALong += localHigh;
		if ( i < shortADRPeriod )
		{
			lowMAShort += localLow;
			highMAShort += localHigh;
		}
		bar++;
	}
	lowMALong /= longADRPeriod;
	highMALong /= longADRPeriod;
	lowMAShort /= shortADRPeriod;
	highMAShort /= shortADRPeriod;

	return ( MathMin( highMALong - lowMALong, highMAShort - lowMAShort ) );
}

//+------------------------------------------------------------------+
//| Create Objects                                                   |
//+------------------------------------------------------------------+
void createSR( int startIndex, int endIndex )
{
   for ( int i = startIndex; i < endIndex; i++ )
   {
      ObjectCreate ( pivotNames[i], OBJ_TEXT, 0, 0, 0 );
      ObjectSetText ( pivotNames[i], pivotNames[i], textSize, textFont, textColor );
   }   
}      
//+------------------------------------------------------------------+
//| Create Extension                                                 |
//+------------------------------------------------------------------+
void createExtension( int startIndex, int endIndex, color colorExtension )
{
   for ( int i = startIndex; i < endIndex; i++ )
   {
      ObjectCreate ( pivotNames[i] + "ext", OBJ_TREND, 0, 0, 0, 0, 0 );
      ObjectSet ( pivotNames[i] + "ext", OBJPROP_COLOR, colorExtension );
      ObjectSet ( pivotNames[i] + "ext", OBJPROP_STYLE, STYLE_DOT );
   }   
}
//+------------------------------------------------------------------+
//| Get Extension Text                                               |
//+------------------------------------------------------------------+
string getExtensionText( double value )
{
   string showText;
   if ( includeDistance || includeValue )
   {
      showText = showText + " (";
   }
   if ( includeValue )
   {
      showText = showText + DoubleToStr ( value, Digits );
      if ( includeDistance )
      {
         showText = showText + ", " + DoubleToStr ( ( value - Close[0] ) * multiplier, 1 );
      }
      showText = showText + ")";
   }
   else if ( includeDistance )
   {
      showText = showText + DoubleToStr ( ( value - Close[0] ) * multiplier, 1 ) + ")";
   }
   return ( showText );
}
//+------------------------------------------------------------------+
//| Draw Cell                                                        |
//+------------------------------------------------------------------+
void drawCell ( int nWindow, string nCellName, int corner, double nX, double nY, double nWidth, double nHeight, color nColor )
{
   double   iHeight, iWidth, iXSpace;
   int      iSquares, i;

   if ( nWidth > nHeight )
   {
      iSquares = MathCeil ( nWidth / nHeight ); // Number of squares used.
      iHeight  = MathRound ( ( nHeight * 100 ) / 77 ); // Real height size.
      iWidth   = MathRound ( ( nWidth * 100 ) / 77 ); // Real width size.
      iXSpace  = iWidth / iSquares - ( ( iHeight / ( 9 - ( nHeight / 100 ) ) ) * 2 );

      for ( i = 0; i < iSquares; i++ )
      {
         ObjectCreate   ( nCellName + i, OBJ_LABEL, nWindow, 0, 0 );
         ObjectSetText  ( nCellName + i, CharToStr ( 110 ), iHeight, "Wingdings", nColor );
         ObjectSet      ( nCellName + i, OBJPROP_CORNER, corner );
         ObjectSet      ( nCellName + i, OBJPROP_XDISTANCE, nX + iXSpace * i );
         ObjectSet      ( nCellName + i, OBJPROP_YDISTANCE, nY );
         ObjectSet      ( nCellName + i, OBJPROP_BACK, true );
      }
   }
   else
   {
      iSquares = MathCeil ( nHeight / nWidth ); // Number of squares used.
      iHeight  = MathRound ( ( nHeight * 100 ) / 77 ); // Real height size.
      iWidth   = MathRound ( ( nWidth * 100 ) / 77 ); // Real width size.
      iXSpace  = iHeight / iSquares - ( ( iWidth / ( 9 - ( nWidth / 100 ) ) ) * 2 );

      for ( i = 0; i < iSquares; i++ )
      {
         ObjectCreate   ( nCellName + i, OBJ_LABEL, nWindow, 0, 0 );
         ObjectSetText  ( nCellName + i, CharToStr ( 110 ), iWidth, "Wingdings", nColor );
         ObjectSet      ( nCellName + i, OBJPROP_XDISTANCE, nX );
         ObjectSet      ( nCellName + i, OBJPROP_YDISTANCE, nY + iXSpace * i );
         ObjectSet      ( nCellName + i, OBJPROP_BACK, true );
      }
   }
}

//+------------------------------------------------------------------+
//| Delete Cell                                                      |
//+------------------------------------------------------------------+
void deleteCell(string name)
{
   int square = 0;
   while ( ObjectFind( name + square ) > -1 )
   {
      ObjectDelete( name + square );
      square++;
   }   
}

//+------------------------------------------------------------------+
//| drawBullet()                                                     |
//+------------------------------------------------------------------+
void drawBullet( string cellName, int corner, int col, int row, color bulletColor, int bulletChar = 108 )
{
   if ( ObjectFind ( cellName ) == -1 )
   {
      if ( ObjectCreate   ( cellName, OBJ_LABEL, 0, 0, 0 ) )
      {
         ObjectSet      ( cellName, OBJPROP_XDISTANCE, col );
         ObjectSet      ( cellName, OBJPROP_YDISTANCE, row );
         ObjectSet      ( cellName, OBJPROP_CORNER, corner );
         ObjectSet      ( cellName, OBJPROP_BACK, true );
      }
   }
   ObjectSetText  ( cellName, CharToStr ( bulletChar ), 9, "Wingdings", bulletColor );
}

//+------------------------------------------------------------------+
//| deleteBullet()                                                   |
//+------------------------------------------------------------------+
void deleteBullet( string cellName )
{
   if ( ObjectFind( cellName ) != -1 ) ObjectDelete( cellName );
}


