
//+-------------------------------------------------------------------------------------------+
//|                                                                                           |
//|                                SonicR TzPivots.mq4                                       |
//|                                                                                           |
//+-------------------------------------------------------------------------------------------+

#property copyright "CaveMan, Domas4 and Traderathome, Copyright @ 2010"
#property link      "email: traderathome@msn.com"

/*=============================================================================================

SonicR TzPivots:
This is a Benchmark performance, time zone shift, pivots indicator, made possible by "Caveman", 
who generously devoted his time and programming skills to produce the time zone shift code. it
is anticipated this indicator can handle any situation where there are gaps between trading 
days, where there are partial trading days, or both.  Caveman also provided the DST code which 
automates the turning On/Off of DST, so there is no need to adjust your time zone shift 
settings twice a year.  And it provides for customizing your own DST setting in case you or 
your broker are in a time zone not covered by the DST code as it is.

Another key feature is the "universal" price labeling, provided by "Domas4", enabling this
indicator to be used for non-forex items such as gold and stocks.  

This indicator differs from the TzPivotsD_v3.4 in that it is tailored to the SonicR method of
trading.  Only the basic pivots are shown, and they are shown only in the full screen format. 
           
You can read more about time zone input settings and the other external inputs for this 
indicator in the sections following.                                                     
                                                                               - Traderathome                                                                  
----------------------------------------------------------------------------------------------- 
Introduction - Time Zone Inputs:

   "HrsServerTzFromGMT" input:    
   This is your software server's local timezone expressed in relation to GMT.  For example, 
   some MetaQuotes MT4 servers (live and demo) reside at a location 2 hours ahead of GMT, 
   hence GMT+2, and so the input here is "+2" (or just "2" for a positive relationship).  If,
   for example, your software server is in London, England which is normally GMT+0, and is 
   GMT+1 during Daylight Savings Time (DST), you would normally enter "0", but change it to 
   "1" during DST.  If your MT4 server is at GMT, then enter "0".
                     
   "HrsChoiceTzFromGMT" input:
   This is the timezone you desire to base the pivot calculations on.  It must be expressed in 
   relation to GMT.  If you desire the same timezone as your server, enter in the same # you 
   entered for the server.  If you desire London time, it would be "+1" during DST and "0" 
   otherwise.  If you desire GMT time, then enter "0".  If you desire NY time (GMT-5) then 
   enter "-5", etc.
     
   An example:
   If your software server is located in the Eastern Standard Time zone (GMT-5) and you want 
   the pivot levels to be based upon the London trading session (GMT+1 during DST, otherwise 
   GMT+0), then enter "-5" for the "HrsServerTzFromGMT" timezone.  For the "HrsChoiceTzFromGMT" 
   timezone enter "1" during DST, otherwise  enter "0".
   
   Final note:
   Please understand that the "HrsServerTzFromGMT" timezone setting depends on the time 
   displayed on your MetaTrader charts.  Determine from that what Tz the server is in (hence, 
   the Tz shift from GMT Tz), no matter what the clock on your wall says.  To get normal, 
   non-time shifted pivot calculations, simply use "0" for both timezone inputs, or use the
   "HrsServerTzFromGMT" for both inputs. 
                        
-----------------------------------------------------------------------------------------------
Comments regarding the Indicator Window inputs:

Indicator_On:
   Use "true" to turn this indicator "ON", and "false" to turn  it "OFF".  This way you do not 
   have to delete the indicator from the chart's list of indicators when you do not want the
   pivots displayed.
   
Use_For_Forex:
   Input "true" for forext trading.  Input "false" for non-forex trading. 
   
Exit_Period_Choices:
   Shows the allowed inputs for the next item.
   
Exit_If_Period_Exceeds:
   Input the chart time frame above which you do not want to see the pivots displayed.
   
Use_Day_Formula:
   Input "true" for Daily pivots.  Input "false" for Fibonacci pivots.
                                         
HrsServerTZFromGMT:
   Enter the number of hours difference between GMT and the time zone your platform server.
   Your server time is evident in the time scale below the charts.  Use World Clock.com 
   (http://www.timeanddate.com/worldclock/) to help you to determine how many hours the server
   time zone is from GMT (and in which direction).  If the server is east of GMT, the number 
   entry is positive.  If the server is west of GMT, the number entry is negative.
     
HrsChoiceTzfromGMT:
   Enter the number of hours difference between GMT and the timezone you select for the pivots
   calculations.  For example, if you wish to have the pivots day start at NY time, then enter
   "-5", since NY is 5 hours west of GMT.  If you wish to have the day start at Zurich time,
   then enter "1", since Zurich is 1 hour east of GMT.  Non-time shifted pivot calculatiions 
   can be produced by entering the same number as you did in the previous input. 

Pivot_Color:
   Enter the color for the pivot line.
   
Pivot_LinesStyle:
   Enter the desired line style number (0=solid, 1=dash, 2=dot, 3=dashdot, 4=dashdashdot). 
     
Pivot_SolidLineThickness:
   Enter the number (1+) for the deired thickness of the solid line.    
           
PivotLabels_Color:
   Enter the color for the pivot lines labels.
         
PivotLabels_FontStyle:
   Enter the name of the font style you want.  Arial, Batang and Verdana are good for plain
   type.  Arial Bold and Verdana Bold produce good "medium thickness" type.  Arial Black 
   produces good "bold thickness" type. 
   
PivotLabels_FontSize:
   Enter number for size of font desired (usually 8 - 12).     
  
Show_Price_in_LineLabels:
   The pivot line labels have IDs, but selecting "true" will add the price anytime you have 
   these labels on the chart.   
      
Show_MarginLabels:
   "true" displays price labels in the right margin.  "false" does not display the prices
   in the right margin.

Preeminate_MarginLabels:
   "true" forces the pivot lines and their right margin labels to be on top.  "false" leaves
   them subordinated by default.
   
PlaceLabels_PerCent_Left: 
   Use numbers 100 - 0 to place labels from full left to right.  
       
Subordinate_PivotLabels:
   You can subordinate the labels to lay beneath chart lines and other chart items by setting
   this to "true".       
   
Show_Today_Separator:
   Enter "true" to display, "false" to not display.
    
Show_Yesterday_Separator:  
   Enter "true" to display, "false" to not display. 
        
Separators_Color:
   Enter a color for each type of line. 
   
Separators_Color:
   Enter a color for the Period Separators.
          
Separators_LinesStyle_01234:
   Your number entry selects the line style for the lines.  0=solid, 1=dash, 2=dashdot, 
   3=dashdot, and 4=dashdotdot.
   
Separators_SolidLinesThickness:
   Your number entry selects the width of solid lines.  0 and 1 = single width and 
   2, 3, 4 increase the thickness.  Coding assures that no matter what number this is set 
   at, non-solid line styles selected will still display without having to change this 
   entry back to 0, or 1.  

SeparatorsLabels_Color:
   Enter a color for the Period Separators labels. 
   
SeparatorLabels_FontStyle:
   As for the pivots labels, Enter the name of a font style.
   
SeparatorLabels_FontSize:
   Enter a number for font size (usually 8 - 12).
   
Subordinate_SeparatorLabels: 
   You can subordinate the labels to the lay beneath other chart items by setting this to
   "true".          
   
Label_Simple_or_Detailed_12:
   "1" will display simple Separator labels showing just the day name.  "2" will display 
   the GMT detail in the labels; the time zone shift hours from GMT that you have selected. 
    
PlaceAt_TopBot_12_OfChart:
   "1" will place the Period Separator labels at the top of the screen.  "2" will place 
   them at the bottom.  If the screen is enlarged, downsized, or scrolled, these labels 
   will move.  But the next data tick will restore their position.
   
Chart_OHLC_is_Shown:
   Enter "true" and the comments panel will drop down below the OHLC text.  Enter "false" and 
   with the OHLC unchecked in chart "Properties", the comments panel will display at the top.
   
Show_Data_Comment:
   Enter "true" to display the comments panel.
   
Data_Panel_Color:
   Enter a color for the background of the comments panel.  
   
Days_Used_For_Range_Data:
   Enter the number of days to be used in computing average daily trading range.  Typically
   you might enter 14 or 30.  The default is set to 30 days.          
                                                                                                                                                                          
=============================================================================================*/

#property indicator_chart_window
#property indicator_buffers 1  
#property indicator_color1  CLR_NONE  
#property indicator_width1  0

/*---------------------------------------------------------------------------------------------
Suggested Settings:             White Chart         Black Chart

CentralPivotColor               Blue                Blue
R_Color                         Tomato              FireBrick
S_Color                         LimeGreen           ForestGreen
MidPivotsColor                  Olive               C'108,108,0'    
PivotLabelsColor                LightSlateGray      DarkGray
SeparatorLinesColor             Olive               C'108,108,0'
SeparatorsLabelsColor           Crimson             Red
---------------------------------------------------------------------------------------------*/

//---- Global External Inputs
extern bool   Indicator_On                    = true;
extern bool   Use_For_Forex                   = true;
extern bool   Use_Day_Formula                 = false;
extern string Exit_Period_Choices             = "M1   M5   M15   M30   H1   H4   D1";
extern string Exit_If_Period_Exceeds          = "H1";
extern string _                               = "";
extern string Part_1                          = "Time Zone Settings:";
extern int    HrsServerTzFromGMT              = 2;   
extern int    HrsChoiceTzFromGMT              = 0;
extern string __                              = "";
extern string Part_2                          = "Pivot Line Settings:";
extern color  CentralPivot_Color              = Blue; 
extern int    CP_LineStyle_01234              = 2;
extern int    CP_SolidLineThickness           = 2; 
extern color  Resistance_Pivots_Color         = Tomato;
extern int    R_LineStyle_01234               = 2;
extern int    R_SolidLineThickness            = 2; 
extern color  Support_Pivots_Color            = LimeGreen; 
extern int    S_LineStyle_01234               = 2;
extern int    S_SolidLineThickness            = 2; 
extern bool   Show_MidPivots                  = false;
extern color  MidPivots_Color                 = Olive;
extern int    M_LineStyle_01234               = 2;
extern int    M_SolidLineThickness            = 1; 
extern string ___                             = "";     
extern string Part_3                          = "Pivot Label Settings:";  
extern color  PivotLabels_Color               = LightSlateGray; 
extern string PivotLabels_FontStyle           = "Verdana Bold";
extern int    PivotLabels_FontSize            = 10;
extern bool   Show_Price_in_PivotLabels       = true;
extern bool   Show_MarginLabels               = false;
extern bool   Preeminate_MarginLabels         = false;
extern int    PlaceLabels_PerCent_Left        = 50; 
extern bool   Subordinate_PivotLabels         = false;
extern string ____                            = "";
extern string Part_4                          = "Separator Settings:";
extern bool   Show_Today_Separator            = true;
extern bool   Show_Yesterday_Separator        = true;
extern color  Separators_Color                = Olive;
extern int    Separators_LineStyle_01234      = 2;
extern int    Separators_SolidLineThickness   = 1;
extern bool   Show_SeparatorLabels            = true;
extern color  SeparatorsLabels_Color          = Crimson; 
extern string SeparatorLabels_FontStyle       = "Verdana Bold";
extern int    SeparatorLabels_FontSize        = 8;
extern bool   Subordinate_SeparatorLabels     = false;
extern int    Labels_Simple_or_Detailed_12    = 1;
extern int    LabelsOnChart_TopBot_12         = 2;
extern string _____                           = "";
extern string Part_5                          = "Data Comment Settings:";
extern bool   Chart_OHLC_is_Shown             = true;
extern bool   Show_Data_Comment               = true;
extern color  Data_Panel_Color                = C'226,226,250';
extern int    Days_Used_For_Range_Data        = 30;
// Start - Added by CaveMan to cater for DST
extern string ______                          = "";
extern string Part_6                          = "DST Zone Settings:";
extern string note1                           = "Enter preset DST zone number 1 - 4";
extern string note2                           = "or enter ' 5 ' for a custom DST zone.";
extern string note3                           = "1 US   2 EU   3 AUS   4 NZ   5 Cust.";
extern int    DST_Zone                        = 1;
extern bool   Auto_Adjust_For_DST             = true;
extern string note4                           = "To customized A DST setting -";  
extern string note5                           = "Enter # month DST starts,";
extern int    Custom_DST_Start_Month          = 3; //March
extern string note6                           = "Enter # Sunday DST starts,";
extern string note7                           = "1-1st Sunday, 2-2nd ....7-Last Sunday";
extern int    Custom_DST_Start_Sunday         = 2; //2nd Sunday of March start DST
extern string note8                           = "Enter 24 hour time DST starts,";
extern string Custom_DST_Start_Time           = "02:00"; //DST starting time
extern string note9                           = "Repeat for DST end,";
extern int    Custom_DST_End_Month            = 11; //November
extern int    Custom_DST_End_Sunday           = 1;  //1st Sunday of November end DST
extern string Custom_DST_End_Time             = "02:00"; //DST ending time
// End - Added by CaveMan to cater for DST


//---- Global Buffers, Constants, Variables
int    MoveLabels, A, B, digits, fxDigits;
string Yesterday, Today, Price;
 
// Start - Added by CaveMan to cater for DST
int original_server_time;
int DST_shifted_server_time;
int LastRefresh;
int First_Time;
// End - Added by CaveMan to cater for DST

// Start - Added by CaveMan to decouple yHL and Yest/Today Separators from TzShift code
double today_high, today_low, today_open, yesterday_high, yesterday_open, yesterday_low, yesterday_close;
double true_yesterday_high, true_yesterday_low;
// End - Added by CaveMan to decouple yHL and Yest/Today Separators from TzShift code

//+-------------------------------------------------------------------------------------------+
//| Program Initialization                                                                    |
//+-------------------------------------------------------------------------------------------+
int init()
   { 
     
// Start - Added by CaveMan to cater for DST
   original_server_time = HrsServerTzFromGMT;
   DST_shifted_server_time = HrsServerTzFromGMT + 1;
   LastRefresh = TimeHour(iTime(NULL,0,0));
   First_Time = true;
// End - Added by CaveMan to cater for DST

   if (Use_For_Forex){
      string sub=StringSubstr(Symbol(), 3, 3);
      if (sub == "JPY") {fxDigits = 2;} else {fxDigits = 4;}}
               
   return(0);
   }
   
//+-------------------------------------------------------------------------------------------+
//| Program De-initialization                                                                 |
//+-------------------------------------------------------------------------------------------+
int deinit()
   {
   int obj_total= ObjectsTotal();  
   for (int k= obj_total; k>=0; k--){
      string name= ObjectName(k);           
      if (StringSubstr(name,0,17)=="[SonicR TzPivots]") {ObjectDelete(name);}}
   A=0; B=0; Comment("");
   return(0);
   }
   
//+-------------------------------------------------------------------------------------------+
//| Program Start                                                                             |
//+-------------------------------------------------------------------------------------------+
int start()
{
   deinit();if (Indicator_On == false) {return(0);}   
   
   //Exit if period is greater than -----------------------------------------------
   int E;
   if(Exit_If_Period_Exceeds== "M1") {E= 1;}
   if(Exit_If_Period_Exceeds== "M5") {E= 5;}
   if(Exit_If_Period_Exceeds== "M15") {E= 15;}
   if(Exit_If_Period_Exceeds== "M30") {E= 30;}
   if(Exit_If_Period_Exceeds== "H1") {E= 60;}
   if(Exit_If_Period_Exceeds== "H4") {E= 240;}
   if(Exit_If_Period_Exceeds== "D1") {E= 1440;}
   //if(Period() > E) {deinit(); return(-1);}    

// Start - Added by CaveMan to cater for DST
// Code will only check for DST on every new hour bar
   if(TimeHour(iTime(NULL,0,0)) == 0) LastRefresh = -1; // to cater for crossover into a new day
   if(First_Time || TimeHour(iTime(NULL,0,0)) > LastRefresh){
      if (Adjust_for_DST()){Print(" TzPivot - Daylight Savings Time (DST) is in effect.");}
      First_Time = false; LastRefresh = TimeHour(iTime(NULL,0,0));}
// End - Added by CaveMan to cater for DST

   //Tz shift code,let's find out which hour bars make today and yesterday---------------------
   datetime starttoday, startyesterday, startline, stopline, startlabel, startpivottoday;
   //double today_high,today_low,today_open,yesterday_high,yesterday_open,yesterday_low,yesterday_close; //CaveMan moved to Global 
   int      idxfirstbartoday, idxlastbartoday, idxfirstbaryesterday, idxlastbaryesterday,  
            idxstartyesterday, idxendyesterday;  //Caveman added idxstartyesterday and idxendyesterday 
                                   
   TzShift(HrsServerTzFromGMT,HrsChoiceTzFromGMT,idxfirstbartoday, idxfirstbaryesterday, idxlastbaryesterday, idxstartyesterday, idxendyesterday);
   
// Start - Added by CaveMan to decouple today/yesterday separator and pivots starting point    
   //All occurences of "startline = starttoday;" are replaced with "startline = startpivottoday;"
   startpivottoday = Time[1];//Start time of TF bar previous to current bar.  Start point for lines during 1st TF of new day.
   if (Time[0] > iTime(NULL, PERIOD_H1, idxfirstbartoday)){startpivottoday = iTime(NULL, PERIOD_H1, idxfirstbartoday);}       
// End - Added by CaveMan to decouple ytoday/yesterday separator and pivots starting point
   
// Start - Added by CaveMan to decouple yesterday_high/yesterday_low and today/yesterday separator
   starttoday = iTime(NULL, PERIOD_H1, idxfirstbartoday);
   startyesterday = iTime(NULL, PERIOD_H1, idxstartyesterday); 
   //The variables yesterday_high and yesterday_low are too highly coupled to indexes computed by TzShift(). With the 
   //modifications to handle holidays and Sunday data, it has become necessary to decouple yHL and the today/yesterday
   //separator from the rest of the codes without affecting the rest of the indicator codes.

   //Walk forward through yestday's start and collect high/lows within the same day
   true_yesterday_high= -99999;  // not high enough to remain alltime high
   true_yesterday_low=  +99999;  // not low enough to remain alltime low 
   for (int idxbar= idxstartyesterday; idxbar>=idxendyesterday; idxbar--)//Domas4 code
      {
      true_yesterday_high= MathMax(iHigh(NULL, PERIOD_H1, idxbar), true_yesterday_high);
      true_yesterday_low= MathMin(iLow(NULL, PERIOD_H1, idxbar), true_yesterday_low);      
      }
// End - Added by CaveMan to decouple yesterday_high/yesterday_low and today/yesterday separator   
   
   //Walk forward through yestday's start and collect high/lows within the same day
   yesterday_high= -99999;  // not high enough to remain alltime high
   yesterday_low=  +99999;  // not low enough to remain alltime low 
   for (idxbar= idxfirstbaryesterday; idxbar>=idxlastbaryesterday; idxbar--)//Domas4 code
      {
      if (yesterday_open==0) yesterday_open= iOpen(NULL, PERIOD_H1, idxbar);// grab first value for open      
      yesterday_high= MathMax(iHigh(NULL, PERIOD_H1, idxbar), yesterday_high);
      yesterday_low= MathMin(iLow(NULL, PERIOD_H1, idxbar), yesterday_low);      
      yesterday_close= iClose(NULL, PERIOD_H1, idxbar);
      }

   //Walk forward through today and collect high/lows within the same day
   today_open= iOpen(NULL, PERIOD_H1, idxfirstbartoday);  //Domas4 code
   today_high= -99999; 
   today_low=  +99999; 
   for (int j= idxfirstbartoday; j>=0; j--)
      {
      today_high= MathMax(today_high, iHigh(NULL, PERIOD_H1, j));
      today_low= MathMin(today_low, iLow(NULL, PERIOD_H1, j));
      }
   //Define yesterday/today data---------------------------------------------------------------    
   //Calculate Pivot Levels--------------------------------------------------------------------
   double p,d,q;   
   d = (today_high - today_low);
   q = (yesterday_high - yesterday_low);
   p = (yesterday_high + yesterday_low + yesterday_close) / 3;  
      
   if (Show_Data_Comment){        
      ObjectCreate("[SonicR TzPivots] Box1", OBJ_LABEL, 0, 0, 0, 0, 0);
      ObjectSetText("[SonicR TzPivots] Box1", "g", 91, "Webdings");//100
      ObjectSet("[SonicR TzPivots] Box1", OBJPROP_CORNER, 0);
      ObjectSet("[SonicR TzPivots] Box1", OBJPROP_XDISTANCE, 0);              
      if (Chart_OHLC_is_Shown) ObjectSet("[SonicR TzPivots] Box1", OBJPROP_YDISTANCE, 11);     
      if (Chart_OHLC_is_Shown==false) ObjectSet("[SonicR TzPivots] Box1", OBJPROP_YDISTANCE, 0);         
      ObjectSet("[SonicR TzPivots] Box1", OBJPROP_COLOR, Data_Panel_Color);
      ObjectSet("[SonicR TzPivots] Box1", OBJPROP_BACK, false);      
      //Daily Average Range
      int Ra=0, RaP=Days_Used_For_Range_Data;
      for(int i=1; i<=RaP; i++) {Ra = Ra + ((iHigh(NULL,PERIOD_D1,i)- iLow(NULL,PERIOD_D1,i))/Point);}
      Ra= (Ra/RaP)+1; //Add "1" to balance excessive rounding down 
      //Server net TZ shift and resultant offset from GMT   
      int gmt1 = HrsChoiceTzFromGMT - HrsServerTzFromGMT; //serverTZshift
      int gmt2 = HrsChoiceTzFromGMT;
      //Spread
      int spread = MarketInfo(Symbol(), MODE_SPREAD); 
      //Get time (H/M/S) remaining on current candle		
   	int h,m,s,t;    
      t=Time[0]+(Period()*60)-CurTime();
      s=t%60; string seconds= s; if (s<10) seconds= "0"+seconds; 
      m=(t-t%60)/60;   
      for(i=0; i<24; i++){
         if(m>=60){m=m-60;h=h+1;}
         string minutes= m; if (m<10) minutes= "0"+minutes;   
         string hours= h; if (h<10) hours= "0"+hours; 
         string timeleft= minutes+":"+seconds;
         if (h>=1) timeleft= hours+":"+minutes+":"+seconds;
         if (Period()>1440) timeleft= "OFF";}        
      //Set up Comment string
      string C= "     ", timeframe;
      string label = string Symbol();         
      if (Chart_OHLC_is_Shown) C= "\n";            
      if (Chart_OHLC_is_Shown==false) {
      if (Period()== 1)  C =C +  "   "+label+"   M1\n";
      else {if (Period()== 5)  C =C +  "   "+label+"   M5\n";
      else {if (Period()== 15) C =C +  "  "+label+"   M15\n";
      else {if (Period()== 30)  C =C +  "  "+label+"   M30\n";
      else {if (Period()== 60)  C =C +  "   "+label+"   H1\n";
      else {if (Period()== 240)  C =C +  "   "+label+"   H4\n";
      else {if (Period()== 1440)  C =C +  "  "+label+"   Daily\n";
      else {if (Period()== 10080) C =C +  ""+label+"   Weekly\n";
      else {if (Period()== 43200) C =C +  ""+label+"   Monthly\n"; }}}}}}}} }
      C=C + "----- SonicR TzPivots -----\n";
      C=C + "  Range Today:    "+DoubleToStr(MathRound(d/Point),0)+ "\n";      
      C=C + "          "+Days_Used_For_Range_Data+" Day:    "+ Ra + "\n";     
      C=C + "          Tz Shift:   " + gmt1 + "\n";
      C=C + "         To GMT:    " + gmt2 + "\n";
      C=C + "           Spread:    " + spread + "\n"; 
      C=C + "    Swap  Long:    "+DoubleToStr(MarketInfo(Symbol(),MODE_SWAPLONG),2) + "\n";
      C=C + "    Swap Short:   "+DoubleToStr(MarketInfo(Symbol(),MODE_SWAPSHORT),2) + "\n"; 
      C=C + "   New Candle:    "+timeleft +"\n";  
      Comment(C);}

   //Skip display of pivots on higher TFs, per user input--------------------------------------
   if(Period() <= E) { 
   
   //Calculate Pivot Levels--------------------------------------------------------------------
   double r1,r2,r3,r4,r5, s1,s2,s3,s4,s5;                 
   if(Use_Day_Formula) 
   {
   r3 = (2*p)+(yesterday_high-(2*yesterday_low));
   r2 = p+(yesterday_high - yesterday_low);  //r2 = p-s1+r1;
   r1 = (2*p)-yesterday_low;  
   s1 = (2*p)-yesterday_high;
   s2 = p-(yesterday_high - yesterday_low);  //s2 = p-r1+s1;
   s3 = (2*p)-((2* yesterday_high)-yesterday_low);
   }
   if(Use_Day_Formula == false)
   {
   r5 = p+ (q * 2.618);
   r4 = p+ (q * 1.618);
  	r3 = p+q;  
   r2 = p+ (q * 0.618); 
   r1 = p+ (q * 0.382); 
   s1 = p- (q * 0.382);     
   s2 = p- (q * 0.618);    
  	s3 = p-q; 
   s4 = p- (q * 1.618);
   s5 = p- (q * 2.618);  
   }                                    
   //Construct pivot lines and labels----------------------------------------------------------
   //Preparation: 
   A= 0; B= 0; if (Show_MarginLabels) B= 1;
   if (PlaceLabels_PerCent_Left < 0) {PlaceLabels_PerCent_Left =0;}
   if (PlaceLabels_PerCent_Left > 100) {PlaceLabels_PerCent_Left =100;} 
   MoveLabels = (WindowFirstVisibleBar()*PlaceLabels_PerCent_Left)/100;   
   startlabel= Time[MoveLabels];   
   string spc ="";
   startline = WindowFirstVisibleBar();
   stopline = Time[0];

   //-----Central Pivot------------------------------------------------------------------------    
   spc="                 ";//17
   if(Show_Price_in_PivotLabels){spc="                                 ";}//33 
   if(Use_Day_Formula){     
   Pivots("    DPV", p, CentralPivot_Color, CP_LineStyle_01234 ,
               CP_SolidLineThickness, startline, stopline, startlabel, B, spc);}
   if(Use_Day_Formula == false){  
   Pivots("    FPV", p, CentralPivot_Color, CP_LineStyle_01234 ,
               CP_SolidLineThickness, startline, stopline, startlabel, B, spc);}
                  
   //-----Main Pivots--------------------------------------------------------------------------
   spc="                 ";//17
   if(Show_Price_in_PivotLabels){spc="                                 ";}//33     
   if(R_LineStyle_01234>0){R_SolidLineThickness=0;} 
   if(S_LineStyle_01234>0){S_SolidLineThickness=0;} 

   Pivots("      R3", r3, Resistance_Pivots_Color, R_LineStyle_01234, R_SolidLineThickness, startline, stopline, startlabel, B, spc);   
   Pivots("      R2", r2, Resistance_Pivots_Color, R_LineStyle_01234, R_SolidLineThickness, startline, stopline, startlabel, B, spc); 
   Pivots("      R1", r1, Resistance_Pivots_Color, R_LineStyle_01234, R_SolidLineThickness, startline, stopline, startlabel, B, spc);   
   Pivots("      S1", s1, Support_Pivots_Color, S_LineStyle_01234, S_SolidLineThickness, startline, stopline, startlabel, B, spc);
   Pivots("      S2", s2, Support_Pivots_Color, S_LineStyle_01234, S_SolidLineThickness, startline, stopline, startlabel, B, spc);
   Pivots("      S3", s3, Support_Pivots_Color, S_LineStyle_01234, S_SolidLineThickness, startline, stopline, startlabel, B, spc);    

   if(Use_Day_Formula==false){
   Pivots("      R5", r5, Resistance_Pivots_Color, R_LineStyle_01234, R_SolidLineThickness, startline, stopline, startlabel, B, spc);  
   Pivots("      R4", r4, Resistance_Pivots_Color, R_LineStyle_01234, R_SolidLineThickness, startline, stopline, startlabel, B, spc);
   Pivots("      S4", s4, Support_Pivots_Color, S_LineStyle_01234, S_SolidLineThickness, startline, stopline, startlabel, B, spc);
   Pivots("      S5", s5, Support_Pivots_Color, S_LineStyle_01234, S_SolidLineThickness, startline, stopline, startlabel, B, spc);}
   
   //-----Midpoint Pivots----------------------------------------------------------------------
   if (Show_MidPivots==true) 
      {
      spc="                 ";//17
      if(Show_Price_in_PivotLabels){spc="                                 ";}//33              
      if(M_LineStyle_01234>0){M_SolidLineThickness=0;}

      Pivots("   mR3", (r2+r3)/2, MidPivots_Color, M_LineStyle_01234, M_SolidLineThickness, startline, stopline, startlabel, B, spc);
      Pivots("   mR2", (r1+r2)/2, MidPivots_Color, M_LineStyle_01234, M_SolidLineThickness, startline, stopline, startlabel, B, spc);
      Pivots("   mR1", (p+r1)/2,  MidPivots_Color, M_LineStyle_01234, M_SolidLineThickness, startline, stopline, startlabel, B, spc);
      Pivots("   mS1", (p+s1)/2,  MidPivots_Color, M_LineStyle_01234, M_SolidLineThickness, startline, stopline, startlabel, B, spc);
      Pivots("   mS2", (s1+s2)/2, MidPivots_Color, M_LineStyle_01234, M_SolidLineThickness, startline, stopline, startlabel, B, spc);
      Pivots("   mS3", (s2+s3)/2, MidPivots_Color, M_LineStyle_01234, M_SolidLineThickness, startline, stopline, startlabel, B, spc);
      
      if(Use_Day_Formula==false){
      Pivots("   mR5", (r4+r5)/2, MidPivots_Color, M_LineStyle_01234, M_SolidLineThickness, startline, stopline, startlabel, B, spc);
      Pivots("   mR4", (r3+r4)/2, MidPivots_Color, M_LineStyle_01234, M_SolidLineThickness, startline, stopline, startlabel, B, spc);      
      Pivots("   mS4", (s3+s4)/2, MidPivots_Color, M_LineStyle_01234, M_SolidLineThickness, startline, stopline, startlabel, B, spc);
      Pivots("   mS5", (s4+s5)/2, MidPivots_Color, M_LineStyle_01234, M_SolidLineThickness, startline, stopline, startlabel, B, spc);}     
      }
 
   //Draw the Period Separators and labels-----------------------------------------------------
   if(Period() < 1440) 
      {
      if(Show_Today_Separator){
         int DZ = HrsChoiceTzFromGMT;
         string GMT = "(GMT)        ";
         if(DZ>0 &&  DZ<10) {GMT = "(GMT +"+ DZ +")   ";}
         if(DZ>=10) {GMT = "(GMT +"+ DZ +") ";}
         if(DZ<0 && DZ>-10) {GMT = "(GMT "+ DZ +")    ";}
         if(DZ<=-10) GMT = "(GMT "+ DZ +")  ";         
         if(Separators_LineStyle_01234>0) {Separators_SolidLineThickness=1;}	
      	double YadjustTop = (WindowPriceMax()-WindowPriceMin())/5000;
      	double YadjustBot = (WindowPriceMax()-WindowPriceMin())/(400/SeparatorLabels_FontSize); 	
         double level = WindowPriceMax() - YadjustTop; if (LabelsOnChart_TopBot_12==2){level = WindowPriceMin() + YadjustBot;}
         if (Labels_Simple_or_Detailed_12 == 2){
            Separator("YesterdayEnd", Today + GMT, starttoday, SeparatorsLabels_Color,level);}
         else{Separator("YesterdayEnd", Today, starttoday, SeparatorsLabels_Color,level);}}
                
      if(Show_Yesterday_Separator){     
         if (Labels_Simple_or_Detailed_12 == 2){
            Separator("YesterdayStart", Yesterday + GMT, startyesterday, SeparatorsLabels_Color,level);}
         else{Separator("YesterdayStart", Yesterday, startyesterday, SeparatorsLabels_Color,level);}}        
      } 
   }   
   //------ Finished   
   return(0);
}

//+-------------------------------------------------------------------------------------------+
//| Pivots sub-routine to name and draw pivot lines and labels                                |                                                                                  |
//+---------------------------------------------------------------------------------------- --+
void Pivots(string text, double level, color col1, int linestyle, int thickness, 
   datetime startline, datetime stopline, datetime startlabel, int CC, string spc)
   {
   //Assign names to lines and labels---------------------------------------------------------- 
   string pivotline = "[SonicR TzPivots] " + StringTrimLeft(text) + " Line"; 
   string pivotlabel = "[SonicR TzPivots] " + StringTrimLeft(text) + " Label";

   //Create or move horizontal line------------------------------------------------------------
   
   //Define the line configuration    
   int a = linestyle, b = thickness, c =1; if (a==0)c=b;  
   int G= true;//subordinated right margin labels & pivot lines    
   int Z; 
   if (CC == 0){Z = OBJ_TREND;}
   if (CC == 1){Z = OBJ_HLINE;}
   int F = true; 
   
   if (Show_MarginLabels && Preeminate_MarginLabels) {G = false;}
   
   //Draw the horizontal line 
   if (ObjectFind(pivotline) != 0){
      ObjectCreate(pivotline, Z, 0, startline, level, stopline, level);
      ObjectSet(pivotline, OBJPROP_STYLE, linestyle);
      ObjectSet(pivotline, OBJPROP_COLOR, col1);
      ObjectSet(pivotline, OBJPROP_WIDTH, c);
      ObjectSet(pivotline, OBJPROP_BACK, G); 
      ObjectSet(pivotline, OBJPROP_RAY, F);}
   else{
      ObjectMove(pivotline, 0, startline, level);
      ObjectMove(pivotline, 1, stopline, level);}
           
   //Create or move the labels----------------------------------------------------------------
      
   //Define the standard digits used for Price
   if (Use_For_Forex==false) {Price=DoubleToStr(level, fxDigits);}
   else {Price=DoubleToStr(level, Digits);}   
   if (Show_Price_in_PivotLabels && StrToInteger(text)==0) {text = text + "   " + Price;}      
   text = spc + text;
   
   //Draw the labels             
   if (ObjectFind(pivotlabel) != 0){
      ObjectCreate(pivotlabel, OBJ_TEXT, 0, startlabel, level);     
      ObjectSetText(pivotlabel, text, PivotLabels_FontSize, PivotLabels_FontStyle, PivotLabels_Color);
      ObjectSet(pivotlabel, OBJPROP_BACK, false);        
      if(Subordinate_PivotLabels) {ObjectSet(pivotlabel, OBJPROP_BACK, true);}}
   else{ObjectMove(pivotlabel, 0, startlabel, level);}       
   }
   
//+-------------------------------------------------------------------------------------------+
//| Separator sub-routine to name and draw separator lines and labels                         |                                                        
//+-------------------------------------------------------------------------------------------+
void Separator(string objname, string text, int x, color col1, double vleveltext) 
   {
   string vline= "[SonicR TzPivots] " + objname, vlabel = vline + " Label";
   
   if (ObjectFind(vline) != 0){ 
      ObjectCreate(vline, OBJ_TREND, 0, x, 0, x, 100);
      ObjectSet(vline, OBJPROP_STYLE, Separators_LineStyle_01234);
      ObjectSet(vline, OBJPROP_COLOR, Separators_Color);
      ObjectSet(vline, OBJPROP_WIDTH, Separators_SolidLineThickness);
      ObjectSet(vline, OBJPROP_BACK, true);}
   else{
      ObjectMove(vline, 0, x, 0); 
      ObjectMove(vline, 1, x, 100);}
        
   if(Show_SeparatorLabels == true){                           
      if (ObjectFind(vlabel) != 0){
         ObjectCreate (vlabel, OBJ_TEXT, 0, x, vleveltext);
         ObjectSetText(vlabel, text, SeparatorLabels_FontSize, SeparatorLabels_FontStyle, SeparatorsLabels_Color); 
         ObjectSet(vlabel, OBJPROP_BACK, false);         
         if(Subordinate_SeparatorLabels) {ObjectSet(vlabel, OBJPROP_BACK, true);}}       
      else{ObjectMove(vlabel, 0, x, vleveltext);}}
   }
   
//+-------------------------------------------------------------------------------------------+
//| TzShift sub-routine computes index of first/last bars of yesterday & first bar  of today  |
//+-------------------------------------------------------------------------------------------+
void TzShift(int tzServer, int tzChoice, int &idxfirstbartoday, int &idxfirstbaryesterday,int &idxlastbaryesterday,
             int &idxstartyesterday, int &idxendyesterday)//CaveMan adds 2 variables to decouple yHL & Yest/Today separators                
   {      
   int tzdiff               = tzServer - tzChoice,
       tzdiffsec            = tzdiff*3600, 
       barsperday           = (1440/PERIOD_H1),      
       dayofweektoday       = TimeDayOfWeek(iTime(NULL, PERIOD_H1, 0) - tzdiffsec),
       dayofweektofind      = -1;     
                
   //Due to gaps in the data, and shift of time around weekends (due to time zone)
   //it is not as easy as to just look back for a bar with 00:00 time  
   idxfirstbartoday= 0; idxfirstbaryesterday= 0;  idxlastbaryesterday= 0;     
   switch (dayofweektoday) { 
      case 0: dayofweektofind = 5; break; // Sun (Sunday considered as short trading day)
      default: dayofweektofind = dayofweektoday -1; break;}                    

   //Search backwards for the last occurence of a "today's first bar"
   for (int i=1; i<=barsperday + 1; i++){
      datetime timet = iTime(NULL, PERIOD_H1, i) - tzdiffsec;
      if(TimeDayOfWeek(timet) != dayofweektoday) {idxfirstbartoday = i-1;break;}}
   for (int j= 0; j<=2*barsperday + 1; j++) {
      datetime timey = iTime(NULL, PERIOD_H1, i+j) - tzdiffsec;
      if(TimeDayOfWeek(timey) == dayofweektofind) {idxlastbaryesterday = i+j; break;}}
   for (j= 1; j<=barsperday; j++) {
      datetime timey2 = iTime(NULL, PERIOD_H1, idxlastbaryesterday+j) - tzdiffsec;
      if(TimeDayOfWeek(timey2) != dayofweektofind){idxfirstbaryesterday = idxlastbaryesterday+j-1; break;}}
      
        
// Start - Added by CaveMan to cater for missing/partial previous day's data  
   //This section added to assign yesterday's start & end index for use by yHL & Yest/Today separators
   // Search for Friday if yesterday is a Sunday
   if (dayofweektofind != 0)
         {
          idxstartyesterday = idxfirstbaryesterday; // Assign yesterday's first bar location to index
          idxendyesterday = idxlastbaryesterday;    // Assign yesterday's last bar location to index
         }
   else // Search for Friday's data range
         {
            //Search backwards for the last occurence of a "today's first bar"
            for (i=1; i<=barsperday + 1; i++){
               timet = iTime(NULL, PERIOD_H1, i) - tzdiffsec;
               if(TimeDayOfWeek(timet) != dayofweektoday) {idxfirstbartoday = i-1;break;}}
            for (j= 0; j<=2*barsperday + 1; j++) {
               timey = iTime(NULL, PERIOD_H1, i+j) - tzdiffsec;
               if(TimeDayOfWeek(timey) == 5) {idxlastbaryesterday = i+j; break;}}
            for (j= 1; j<=barsperday; j++) {
               timey2 = iTime(NULL, PERIOD_H1, idxlastbaryesterday+j) - tzdiffsec;
               if(TimeDayOfWeek(timey2) != 5){idxfirstbaryesterday = idxlastbaryesterday+j-1;break;}}

           idxstartyesterday = idxfirstbaryesterday; // Assign yesterday's first bar location to index
           idxendyesterday = idxfirstbartoday + 1;    // Assign yesterday's last bar location to index
          }
   //This section takes care of the Christmas and New Year Day problem where there is a day of partial data on the eve
   //of these holidays followed by an entire day without any data at all. The workaround to handle this on market
   //open after the holiday is to use data from the day before the eve of the holiday right up to the end of the eve of
   //the holiday for pivot computation. E.g. On the 26 December market opens after Christmas. Use full day data of 23rd 
   //plus partial data of 24th Dec to compute the pivots. Same applies to New Year Day.
   int YesterdayBarsTotal = idxfirstbaryesterday - idxlastbaryesterday;
   if (YesterdayBarsTotal == 0)   
      {
         if (dayofweektofind == 0) { dayofweektofind = 4;} 
         else if (dayofweektofind == 1) { dayofweektofind = 5;} 
         else {dayofweektofind = dayofweektofind - 1;}

         //Repeat this search with the new dayofweektofind information
         for (i=1; i<=barsperday + 1; i++){
            timet = iTime(NULL, PERIOD_H1, i) - tzdiffsec;
            if(TimeDayOfWeek(timet) != dayofweektoday) {idxfirstbartoday = i-1;break;}}
         for (j= 0; j<=2*barsperday + 1; j++) {
            timey = iTime(NULL, PERIOD_H1, i+j) - tzdiffsec;
            if(TimeDayOfWeek(timey) == dayofweektofind) {idxlastbaryesterday = i+j; break;}}
         for (j= 1; j<=3*barsperday; j++) {
            timey2 = iTime(NULL, PERIOD_H1, idxlastbaryesterday+j) - tzdiffsec;
            if(TimeDayOfWeek(timey2) != dayofweektofind){idxfirstbaryesterday = idxlastbaryesterday+j-1;break;}}
         idxstartyesterday = idxfirstbaryesterday; // Assign yesterday's first bar location to index
         idxendyesterday = idxlastbaryesterday;    // Assign yesterday's last bar location to index
         YesterdayBarsTotal = idxfirstbaryesterday - idxlastbaryesterday;
       }      
   //Standard codes to handle days of partial data (including Fridays and Sundays)
   //If one hour bars < 24, use additional data from one more day back 
   if (YesterdayBarsTotal < 23)
      { 
         if (dayofweektoday == 0 && dayofweektofind == 4) {dayofweektofind = 3;} // for Sunday, search Thursday and found Thursday partial data, then search Wednesday.
         else if (dayofweektoday == 1 && dayofweektofind == 4) {dayofweektofind = 4;} // for Monday, Friday no data then include Thursday and Sunday data.
         else if (dayofweektofind == 0 || dayofweektofind == 1) { dayofweektofind = 5;} 
         else { dayofweektofind = dayofweektofind - 1; }
            //Search backwards for the last occurence of a "today's first bar"
            for (i=1; i<=barsperday + 1; i++){
               timet = iTime(NULL, PERIOD_H1, i) - tzdiffsec;
               if(TimeDayOfWeek(timet) != dayofweektoday) {idxfirstbartoday = i-1;break;}}
            for (j= 0; j<=3*barsperday + 1; j++){ // Need to increase another 24 hours to search
               timey = iTime(NULL, PERIOD_H1, i+j) - tzdiffsec;
               if(TimeDayOfWeek(timey) == dayofweektofind) {idxlastbaryesterday = i+j; break;}}
            for (j= 1; j<=4*barsperday; j++) {
               timey2 = iTime(NULL, PERIOD_H1, idxlastbaryesterday+j) - tzdiffsec;
               if(TimeDayOfWeek(timey2) != dayofweektofind){idxfirstbaryesterday = idxlastbaryesterday+j-1;break;}}     
   //This small section handles a very unique combination of events that coincide during the short opening trading hours 
   //of the Sunday following Christmas Day and New Year Day if both of these holidays happen to fall on a Thursday. 
   //This occured on the short Sunday trading hours before Monday kicks in. For those few hours, pivot used on Friday are 
   //extended into Sunday. These pivot levels are calculated using full Thursday's data. In this unique situation, 
   //Thursday was New Year Day (major public holiday)with no data at all. This will cause TzPivot to malfunction in similar 
   //situation in the future. As a workaround, for those short few hours of Sunday, if a similar situation should occur,
   //partial data of Wednesday and Friday will be used for pivot computation. 
         YesterdayBarsTotal = idxfirstbaryesterday - idxlastbaryesterday;
         if (YesterdayBarsTotal == 0)   
            {
               if (dayofweektofind == 1) { dayofweektofind = 5;}
               else {dayofweektofind = dayofweektofind - 1;}
               //Repeat this search with the new dayofweektofind information
               for (i=1; i<=barsperday + 1; i++){
                  timet = iTime(NULL, PERIOD_H1, i) - tzdiffsec;
                  if(TimeDayOfWeek(timet) != dayofweektoday) {idxfirstbartoday = i-1;break;}}
               for (j= 0; j<=2*barsperday + 1; j++) {
                  timey = iTime(NULL, PERIOD_H1, i+j) - tzdiffsec;
                  if(TimeDayOfWeek(timey) == dayofweektofind) {idxlastbaryesterday = i+j; break;}}
               for (j= 1; j<=3*barsperday; j++) {
                  timey2 = iTime(NULL, PERIOD_H1, idxlastbaryesterday+j) - tzdiffsec;
                  if(TimeDayOfWeek(timey2) != dayofweektofind){idxfirstbaryesterday = idxlastbaryesterday+j-1;break;}}
               idxlastbaryesterday = idxfirstbartoday + 1;
             }
   //Include partial day's data and combine with previous day's data for pivot computation. Do not include for Sundays
   //as Sunday short trading hours uses Friday's pivots that are computed from full Thursday's data.
   //This is more for handling of holidays including Christmas and New Year Day. 
            if (dayofweektoday != 0) idxlastbaryesterday = idxfirstbartoday + 1; 
       }      
            
// End - Added by CaveMan to cater for missing/partial previous day's data 
       
      int today_start = TimeDayOfWeek(iTime(NULL,PERIOD_H1, idxfirstbartoday) - tzdiffsec);
      int yesterday_start = TimeDayOfWeek(iTime(NULL,PERIOD_H1, idxstartyesterday) - tzdiffsec);//CaveMan modified from idxfirstbaryesterday
      switch(today_start){
         case 0: Today = "      Sunday    "; break;
         case 1: Today = "      Monday    "; break;
         case 2: Today = "    Tuesday     "; break;
         case 3: Today = "Wednesday     "; break;
         case 4: Today = "    Thursday    "; break;
         case 5: Today = "      Friday    ";  break;}               
      switch(yesterday_start){
         case 0: Yesterday = "      Sunday    "; break;
         case 1: Yesterday = "      Monday    "; break;
         case 2: Yesterday = "    Tuesday     "; break;
         case 3: Yesterday = "Wednesday     "; break;
         case 4: Yesterday = "    Thursday    "; break;
         case 5: Yesterday = "      Friday    ";  break;}                 
   }
   
// Start - Added by CaveMan to cater for DST
//+------------------------------------------------------------------------------+
//| Calculate and return actual date given which Sunday of the month information |
//|  --> Only US and EU DST is supported for the time being.                     |
//+------------------------------------------------------------------------------+
bool Adjust_for_DST()
   {
// This definition section can be made into extern for user configuration but not neccesary.

      string Instructions1       = "Enter which Sunday of the month";
      string Instructions2       = "DST should start and end.";
      string Instructions3       = "1,2,3,4,5,6 = 1st, 2nd, 3rd, 4th, 5th and 6th";
      string Instructions4       = "7 = Last Sundy of the month";

      int us_dst_start_sunday    = 2;        // 2nd Sunday of March start DST
      int us_dst_month_start     = 3;        // March
      string us_dst_time_start   = "02:00";  // DST starting time
      int us_dst_end_sunday      = 1;        // 1st Sunday of November end DST
      int us_dst_month_end       = 11;       // November
      string us_dst_time_end     = "02:00";  // DST ending time
 
      int eu_dst_start_sunday    = 7;        // 2nd Sunday of March start DST
      int eu_dst_month_start     = 3;        // March
      string eu_dst_time_start   = "02:00";  // DST starting time
      int eu_dst_end_sunday      = 7;        // 1st Sunday of November end DST
      int eu_dst_month_end       = 10;       // November
      string eu_dst_time_end     = "02:00";  // DST ending time
 
      int aus_dst_start_sunday    = 1;        // 2nd Sunday of March start DST
      int aus_dst_month_start     = 4;        // March
      string aus_dst_time_start   = "02:00";  // DST starting time
      int aus_dst_end_sunday      = 1;        // 1st Sunday of November end DST
      int aus_dst_month_end       = 10;       // November
      string aus_dst_time_end     = "02:00";  // DST ending time

      int nz_dst_start_sunday    = 1;        // 2nd Sunday of March start DST
      int nz_dst_month_start     = 4;        // March
      string nz_dst_time_start   = "02:00";  // DST starting time
      int nz_dst_end_sunday      = 7;        // 1st Sunday of November end DST
      int nz_dst_month_end       = 9;       // November
      string nz_dst_time_end     = "02:00";  // DST ending time

      datetime us_dst_start, us_dst_end; // dst start and end datetime
      datetime eu_dst_start, eu_dst_end; 
      datetime aus_dst_start, aus_dst_end; 
      datetime nz_dst_start, nz_dst_end; 
      datetime cus_dst_start, cus_dst_end; 
      
      int cus_dst_month_start   = Custom_DST_Start_Month;
      int cus_dst_start_sunday  = Custom_DST_Start_Sunday;
      string cus_dst_time_start = Custom_DST_Start_Time;
      int cus_dst_month_end     =  Custom_DST_End_Month;   
      int cus_dst_end_sunday    = Custom_DST_End_Sunday;
      string cus_dst_time_end   =  Custom_DST_End_Time;  
   
//    Print("US DST Start/End Date = ", TimeToStr(us_dst_start), " / ", TimeToStr(us_dst_end));
//    Print("EU DST Start/End Date = ", TimeToStr(eu_dst_start), " / ", TimeToStr(eu_dst_end));
      
      us_dst_start  = check_date(us_dst_start_sunday,  us_dst_month_start,  us_dst_time_start);
      us_dst_end    = check_date(us_dst_end_sunday,    us_dst_month_end,    us_dst_time_end);
      eu_dst_start  = check_date(eu_dst_start_sunday,  eu_dst_month_start,  eu_dst_time_start);
      eu_dst_end    = check_date(eu_dst_end_sunday,    eu_dst_month_end,    eu_dst_time_end);
      aus_dst_start = check_date(aus_dst_start_sunday, aus_dst_month_start, aus_dst_time_start);
      aus_dst_end   = check_date(aus_dst_end_sunday,   aus_dst_month_end,   aus_dst_time_end);
      nz_dst_start  = check_date(nz_dst_start_sunday,  nz_dst_month_start,  nz_dst_time_start);
      nz_dst_end    = check_date(nz_dst_end_sunday,    nz_dst_month_end,    nz_dst_time_end);
      cus_dst_start = check_date(cus_dst_start_sunday, cus_dst_month_start, cus_dst_time_start);
      cus_dst_end   = check_date(cus_dst_end_sunday,   cus_dst_month_end,   cus_dst_time_end);

      if (Auto_Adjust_For_DST && DST_Zone == 1 && iTime(NULL,0,0) > us_dst_start && iTime(NULL,0,0) < us_dst_end)
         {
            HrsServerTzFromGMT = DST_shifted_server_time;
            return(true);
         }
      else if (Auto_Adjust_For_DST && DST_Zone == 2 && iTime(NULL,0,0) > eu_dst_start && iTime(NULL,0,0) < eu_dst_end)
         {
            HrsServerTzFromGMT = DST_shifted_server_time;
            return(true);
         }
      else if (Auto_Adjust_For_DST && DST_Zone == 3 && iTime(NULL,0,0) > aus_dst_start && iTime(NULL,0,0) < aus_dst_end)
         {
            HrsServerTzFromGMT = DST_shifted_server_time;
            return(true);
         }
      else if (Auto_Adjust_For_DST && DST_Zone == 4 && iTime(NULL,0,0) > nz_dst_start && iTime(NULL,0,0) < nz_dst_end)
         {
            HrsServerTzFromGMT = DST_shifted_server_time;
            return(true);
         }
      else if (Auto_Adjust_For_DST && DST_Zone == 5 && iTime(NULL,0,0) > cus_dst_start && iTime(NULL,0,0) < cus_dst_end)
         {
            HrsServerTzFromGMT = DST_shifted_server_time;
            return(true);
         }
      else
         {
            HrsServerTzFromGMT = original_server_time;
            return(false);
         }
}
 
//+------------------------------------------------------------------------------+
//| Calculate and return actual date given which Sunday of the month information |
//+------------------------------------------------------------------------------+
datetime check_date(int which_sunday, int which_month, string what_time)
{
   string start_date;
   int day_of_week, start_day;

   if (which_sunday == 7)  // Last Sunday of the month
      {
         for (int i = 31; i > 20; i--)
            {
               start_date = TimeYear(iTime(NULL,0,0)) + "." + which_month + "." + i;
               day_of_week = TimeDayOfWeek(StrToTime(start_date));
               if (day_of_week == 0) // equals to Sunday
                  {
                     start_date = TimeYear(iTime(NULL,0,0)) + "." + which_month + "." + i + " " + what_time;
                     break;
                   }
             } 
      }
   else // other Sundays of the month besides last Sunday of the month
      {
         start_date = TimeYear(iTime(NULL,0,0)) + "." + which_month + "." + "1";
         day_of_week = TimeDayOfWeek(StrToTime(start_date));
   
         if (day_of_week == 0) start_day = 1 + 7*(which_sunday - 1);
         else start_day = 1 + (7 - day_of_week) + 7 * (which_sunday - 1);
   
         start_date = TimeYear(iTime(NULL,0,0)) + "." + which_month + "." + start_day + " " + what_time;
      }
      
   return(StrToTime(start_date));
}
// End - Added by CaveMan to cater for DST

//+-------------------------------------------------------------------------------------------+
//| Program End                                                                               |                                                        
//+-------------------------------------------------------------------------------------------+