SDX-TzPivots_v1

Download script
Author: Copyright Shimodax
SDX-TzPivots_v1

Technical Logic Overview

This script is an automated technical analysis tool designed to calculate and display various "Pivot Points" and significant price levels on a trading chart. It helps traders identify potential areas of support and resistance by analyzing historical price action from the previous trading sessions.

Core Functionality

The primary logic of the script revolves around identifying the high, low, and closing prices of two specific periods: Yesterday and Today. By processing this data, the script automatically draws horizontal lines on your chart that represent key mathematical levels used by many traders to gauge market sentiment and potential price reversals.

Key Components of the Logic:

  • Time Zone Intelligence: One of the sophisticated features of this script is its ability to handle different time zones. It can distinguish between your local computer's time and a specific "Destination Time Zone" (such as the London or New York sessions). This ensures that the levels are calculated based on the correct global trading sessions, regardless of where you are physically located.

  • Automated Data Collection: The script automatically scans back through the previous day’s hourly bars to find:

    • Yesterday’s High and Low: The extreme price points reached during the previous session.
    • Yesterday’s Close: The final price at which the previous session ended.
    • Today’s Open: The starting price of the current trading day.
  • Advanced Mathematical Level Calculations: Once the data is collected, the script generates several types of technical indicators:

    • Standard Pivot Points: Calculates a central "Pivot" point and multiple Support (S1, S2, S3) and Resistance (R1, R2, R3) levels.
    • Fibonacci Levels: Automatically identifies key retracement percentages (38.2%, 50%, and 61.8%) based on the range of yesterday's price movement.
    • Camarilla Breakout Levels: Calculates specific "H" and "L" levels used by traders to identify potential breakout points for the current session.
    • Midpoint Pivots: Identifies the exact mathematical center between every primary Support and Resistance level, providing even finer detail for entries and exits.
    • Sweet Spots: Dynamically identifies specific price zones based on the current market bid price.
  • Visual Representation & Reporting: To make this data actionable, the script handles all the "heavy lifting" of the visual interface:

    • Dynamic Drawing: It automatically creates and updates horizontal lines that move as new price data arrives.
    • Labels: It places text labels on the chart so you can instantly identify which line is which (e.g., "R1", "Pivot", "S3").
    • On-Screen Dashboard: The script generates a comprehensive summary in the top-left corner of your chart, providing a quick reference for daily ranges (in pips), highs, lows, and all calculated pivot levels at a glance.

Summary for the User

In simple terms, this script acts as an automated analyst. Instead of you having to manually calculate complex math formulas every morning to find where the "floor" and "ceiling" of the market might be, the script looks at yesterday's performance and draws those boundaries for you in real-time, adjusting automatically for different time zones and trading sessions.

Price Data Components
Series array that contains open time of each barSeries array that contains open prices of each barSeries array that contains the highest prices of each barSeries array that contains the lowest prices of each barSeries array that contains close prices for each bar
Miscellaneous
It issuies visual alerts to the screen
10 Views
0 Downloads
0 Favorites
SDX-TzPivots_v1
/*-----------------------------+
|			       |
| Shared by www.Aptrafx.com    |
|			       |
+------------------------------*/

//+------------------------------------------------------------------+
//|                                                        Pivot.mq4 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright Shimodax"
#property link      "http://www.strategybuilderfx.com"


#property indicator_chart_window

// ---- user input ---------------
/* 
   LocalTimeZone: TimeZone for which MT4 shows your local time, 
                  e.g. 1 or 2 for Europe (GMT+1 or GMT+2 (daylight 
                  savings time).  Use zero for no adjustment.
                  
   DestTimeZone:  TimeZone for the session from which to calculate
                  the levels (e.g. 1 or 2 for the European session
                  (without or with daylight savings time).  
                  Use zero for GMT
                  
  Example: If your MT server is living in the EST (Eastern Standard Time, 
           GMT-5) zone and want to calculate the levels for the London trading
           session (European time in summer GMT+1), then enter -5 for 
           LocalTimeZone, 1 for Dest TimeZone. 
            
           Please understand that the LocalTimeZone setting depends on the
           time on your MetaTrader charts (for example the demo server 
           from MetaQuotes always lives in CDT (+2) or CET (+1), no matter
           what the clock on your wall says.
           
           If in doubt, leave everything to zero.
*/


extern int LocalTimeZone= 0;
extern int DestTimeZone= 0;

extern int LineStyle= 2;
extern bool ShowComment = true;
extern bool ShowLevelPrices = false;
extern bool ShowHighLowOpen = true;
extern bool ShowSweetSpots = true;
extern bool ShowPivots = true;
extern bool ShowFibos= false;
extern bool ShowMidPitvot = false;
extern bool ShowCamarilla = false;

extern int BarForLabels= 10;     // number of bars from right, where lines labels will be shown

extern bool DebugLogger = false;



/*
   The following doesn't work yet, please leave it to 0/24:
                  
   TradingHoursFrom: First hour of the trading session in the destination
                     time zone.
                     
   TradingHoursTo: Last hour of the trading session in the destination
                   time zone (the hour starting with this value is excluded,
                   i.e. 18 means up to 17:59 o'clock)
                   
   Example: If you are lving in the EST (Eastern Standard Time, GMT-5) 
            zone and want to calculate the levels for the London trading
            session (European time GMT+1, 08:00 - 17:00), then enter
            -5 for LocalTimeZone, 1 for Dest TimeZone, 8 for HourFrom
            and 17 for hour to.
*/

int TradingHoursFrom= 0;
int TradingHoursTo= 24;
       



//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   return(0);
}

int deinit()
{
   int obj_total= ObjectsTotal();
   
   for (int i= obj_total; i>=0; i--) {
      string name= ObjectName(i);
    
      if (StringSubstr(name,0,7)=="[PIVOT]") 
         ObjectDelete(name);
   }
   
   return(0);
}
  
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
   static datetime timelastupdate= 0;
   static datetime lasttimeframe= 0;
   
   datetime startofday= 0,
            startofyesterday= 0;

   double today_high= 0,
            today_low= 0,
            today_open= 0,
            yesterday_high= 0,
            yesterday_open= 0,
            yesterday_low= 0,
            yesterday_close= 0;

   int idxfirstbaroftoday= 0,
       idxfirstbarofyesterday= 0,
       idxlastbarofyesterday= 0;

   
   // no need to update these buggers too often   
   if (CurTime()-timelastupdate < 600 && Period()==lasttimeframe)
      return (0);
      
   lasttimeframe= Period();
   timelastupdate= CurTime();
   
   //---- exit if period is greater than daily charts
   if(Period() > 1440) {
      Alert("Error - Chart period is greater than 1 day.");
      return(-1); // then exit
   }

   if (DebugLogger) {
      Print("Local time current bar:", TimeToStr(iTime(NULL, PERIOD_H1, 0)));
      Print("Dest  time current bar: ", TimeToStr(iTime(NULL, PERIOD_H1, 0)- (LocalTimeZone - DestTimeZone)*3600), ", tzdiff= ", LocalTimeZone - DestTimeZone);
   }


   // let's find out which hour bars make today and yesterday
   ComputeDayIndices(LocalTimeZone, DestTimeZone, idxfirstbaroftoday, idxfirstbarofyesterday, idxlastbarofyesterday);

   startofday= iTime(NULL, PERIOD_H1, idxfirstbaroftoday);  // datetime (x-value) for labes on horizontal bars
   startofyesterday= iTime(NULL, PERIOD_H1, idxfirstbarofyesterday);  // datetime (x-value) for labes on horizontal bars

   

   // 
   // 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 (int idxbar= idxfirstbarofyesterday; idxbar>=idxlastbarofyesterday; idxbar--) {

      if (yesterday_open==0)  // grab first value for open
         yesterday_open= iOpen(NULL, PERIOD_H1, idxbar);                      
      
      yesterday_high= MathMax(iHigh(NULL, PERIOD_H1, idxbar), yesterday_high);
      yesterday_low= MathMin(iLow(NULL, PERIOD_H1, idxbar), yesterday_low);
      
      // overwrite close in loop until we leave with the last iteration's value
      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, idxfirstbaroftoday);  // should be open of today start trading hour

   today_high= -99999; // not high enough to remain alltime high
   today_low=  +99999; // not low enough to remain alltime low
   for (int j= idxfirstbaroftoday; j>=0; j--) {
      today_high= MathMax(today_high, iHigh(NULL, PERIOD_H1, j));
      today_low= MathMin(today_low, iLow(NULL, PERIOD_H1, j));
   }
      
   
   // draw the vertical bars that marks the time span
   double level= (yesterday_high + yesterday_low + yesterday_close) / 3;
   SetTimeLine("YesterdayStart", "yesterday", idxfirstbarofyesterday, CadetBlue, level - 4*Point);
   SetTimeLine("YesterdayEnd", "today", idxfirstbaroftoday, CadetBlue, level - 4*Point);
   
   
   if (DebugLogger) 
      Print("Timezoned values: yo= ", yesterday_open, ", yc =", yesterday_close, ", yhigh= ", yesterday_high, ", ylow= ", yesterday_low, ", to= ", today_open);


   //
   //---- Calculate Levels
   //
   double p, q, d, r1,r2,r3, s1,s2,s3;
   
   d = (today_high - today_low);
   q = (yesterday_high - yesterday_low);
   p = (yesterday_high + yesterday_low + yesterday_close) / 3;
   
   r1 = (2*p)-yesterday_low;
   r2 = p+(yesterday_high - yesterday_low);              //	r2 = p-s1+r1;
	r3 = (2*p)+(yesterday_high-(2*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);


   //---- High/Low, Open
   if (ShowHighLowOpen) {
      SetLevel("Y\'s High", yesterday_high,  Orange, LineStyle, startofyesterday);
      SetLevel("T\'s Open", today_open,      Orange, LineStyle, startofday);
      SetLevel("Y\'s Low", yesterday_low,    Orange, LineStyle, startofyesterday);
   }

   //---- High/Low, Open
   if (ShowSweetSpots) {
      int ssp1, ssp2;
      double ds1, ds2;
      
      ssp1= Bid / Point;
      ssp1= ssp1 - ssp1%50;
      ssp2= ssp1 + 50;
      
      ds1= ssp1*Point;
      ds2= ssp2*Point;
      
      SetLevel(DoubleToStr(ds1,Digits), ds1,  Gold, LineStyle, Time[10]);
      SetLevel(DoubleToStr(ds2,Digits), ds2,  Gold, LineStyle, Time[10]);
   }

   //---- Pivot Lines
   if (ShowPivots==true) {
      SetLevel("R1", r1,      Blue, LineStyle, startofday);
      SetLevel("R2", r2,      Blue, LineStyle, startofday);
      SetLevel("R3", r3,      Blue, LineStyle, startofday);
      
      SetLevel("Pivot", p,    Magenta, LineStyle, startofday);

      SetLevel("S1", s1,      Red, LineStyle, startofday);
      SetLevel("S2", s2,      Red, LineStyle, startofday);
      SetLevel("S3", s3,      Red, LineStyle, startofday);
   }
   
   //---- Fibos of yesterday's range
   if (ShowFibos) {
      // .618, .5 and .382
      SetLevel("Low - 61.8%", yesterday_low - q*0.618,      Yellow, LineStyle, startofday);
      SetLevel("Low - 38.2%", yesterday_low - q*0.382,      Yellow, LineStyle, startofday);
      SetLevel("Low + 38.2%", yesterday_low + q*0.382,      Yellow, LineStyle, startofday);
      SetLevel("LowHigh 50%", yesterday_low + q*0.5,        Yellow, LineStyle, startofday);
      SetLevel("High - 38.2%", yesterday_high - q*0.382,    Yellow, LineStyle, startofday);
      SetLevel("High + 38.2%", yesterday_high + q*0.382,    Yellow, LineStyle, startofday);
      SetLevel("High + 61.8%", yesterday_high +  q*0.618,   Yellow, LineStyle, startofday);
   }


   //----- Camarilla Lines
   if (ShowCamarilla==true) {
      
      double h4,h3,l4,l3;
	   h4 = (q*0.55)+yesterday_close;
	   h3 = (q*0.27)+yesterday_close;
	   l3 = yesterday_close-(q*0.27);	
	   l4 = yesterday_close-(q*0.55);	
	   
      SetLevel("H3", h3,   Khaki, LineStyle, startofday);
      SetLevel("H4", h4,   Khaki, LineStyle, startofday);
      SetLevel("L3", l3,   Khaki, LineStyle, startofday);
      SetLevel("L4", l4,   Khaki, LineStyle, startofday);
   }


   //------ Midpoints Pivots 
   if (ShowMidPitvot==true) {
      // mid levels between pivots
      SetLevel("MR3", (r2+r3)/2,    Green, LineStyle, startofday);
      SetLevel("MR2", (r1+r2)/2,    Green, LineStyle, startofday);
      SetLevel("MR1", (p+r1)/2,     Green, LineStyle, startofday);
      SetLevel("MS1", (p+s1)/2,     Green, LineStyle, startofday);
      SetLevel("MS2", (s1+s2)/2,    Green, LineStyle, startofday);
      SetLevel("MS3", (s2+s3)/2,    Green, LineStyle, startofday);
   }


   //------ Comment for upper left corner
   if (ShowComment) {
      string comment; 
      
      comment= comment + "-- Good luck with your trading! ---\n";
      comment= comment + "Range: Yesterday "+DoubleToStr(MathRound(q/Point),0)   +" pips, Today "+DoubleToStr(MathRound(d/Point),0)+" pips" + "\n";
      comment= comment + "Highs: Yesterday "+DoubleToStr(yesterday_high,Digits)  +", Today "+DoubleToStr(today_high,Digits) +"\n";
      comment= comment + "Lows:  Yesterday "+DoubleToStr(yesterday_low,Digits)   +", Today "+DoubleToStr(today_low,Digits)  +"\n";
      comment= comment + "Close: Yesterday "+DoubleToStr(yesterday_close,Digits) + "\n";
      comment= comment + "Pivot: " + DoubleToStr(p,Digits) + ", S1/2/3: " + DoubleToStr(s1,Digits) + "/" + DoubleToStr(s2,Digits) + "/" + DoubleToStr(s3,Digits) + "\n" ;
      comment= comment + "Fibos: " + DoubleToStr(yesterday_low + q*0.382, Digits) + ", " + DoubleToStr(yesterday_high - q*0.382,Digits) + "\n";
      
      Comment(comment); 
   }

   return(0);
}

 
//+------------------------------------------------------------------+
//| Compute index of first/last bar of yesterday and today           |
//+------------------------------------------------------------------+
void ComputeDayIndices(int tzlocal, int tzdest, int &idxfirstbaroftoday, int &idxfirstbarofyesterday, int &idxlastbarofyesterday)
{     
   int tzdiff= tzlocal - tzdest,
       tzdiffsec= tzdiff*3600;
   
   int dayofweektoday= TimeDayOfWeek(iTime(NULL, PERIOD_H1, 0) - tzdiffsec),  // what day is today in the dest timezone?
       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
   //
   
   idxfirstbaroftoday= 0;
   idxfirstbarofyesterday= 0;
   idxlastbarofyesterday= 0;
       
   switch (dayofweektoday) {
      case 6: // sat
      case 0: // sun
      case 1: // mon
            dayofweektofind= 5; // yesterday in terms of trading was previous friday
            break;
            
      default:
            dayofweektofind= dayofweektoday -1; 
            break;
   }
   
   if (DebugLogger) {
      Print("Dayofweektoday= ", dayofweektoday);
      Print("Dayofweekyesterday= ", dayofweektofind);
   }
       
       
   // search  backwards for the last occrrence (backwards) of the day today (today's first bar)
   for (int i=1; i<=25; i++) {
      datetime timet= iTime(NULL, PERIOD_H1, i) - tzdiffsec;
      if (TimeDayOfWeek(timet)!=dayofweektoday) {
         idxfirstbaroftoday= i-1;
         break;
      }
   }
   

   // search  backwards for the first occrrence (backwards) of the weekday we are looking for (yesterday's last bar)
   for (int j= 0; j<=48; j++) {
      datetime timey= iTime(NULL, PERIOD_H1, i+j) - tzdiffsec;
      if (TimeDayOfWeek(timey)==dayofweektofind) {  // ignore saturdays (a Sa may happen due to TZ conversion)
         idxlastbarofyesterday= i+j;
         break;
      }
   }


   // search  backwards for the first occurrence of weekday before yesterday (to determine yesterday's first bar)
   for (j= 1; j<=24; j++) {
      datetime timey2= iTime(NULL, PERIOD_H1, idxlastbarofyesterday+j) - tzdiffsec;
      if (TimeDayOfWeek(timey2)!=dayofweektofind) {  // ignore saturdays (a Sa may happen due to TZ conversion)
         idxfirstbarofyesterday= idxlastbarofyesterday+j-1;
         break;
      }
   }


   if (DebugLogger) {
      Print("Dest time zone\'s current day starts:", TimeToStr(iTime(NULL, PERIOD_H1, idxfirstbaroftoday)), 
                                                      " (local time), idxbar= ", idxfirstbaroftoday);

      Print("Dest time zone\'s previous day starts:", TimeToStr(iTime(NULL, PERIOD_H1, idxfirstbarofyesterday)), 
                                                      " (local time), idxbar= ", idxfirstbarofyesterday);
      Print("Dest time zone\'s previous day ends:", TimeToStr(iTime(NULL, PERIOD_H1, idxlastbarofyesterday)), 
                                                      " (local time), idxbar= ", idxlastbarofyesterday);
   }
}


//+------------------------------------------------------------------+
//| Helper                                                           |
//+------------------------------------------------------------------+
void SetLevel(string text, double level, color col1, int linestyle, datetime startofday)
{
   int digits= Digits;
   string labelname= "[PIVOT] " + text + " Label",
          linename= "[PIVOT] " + text + " Line",
          pricelabel; 

   // create or move the horizontal line   
   if (ObjectFind(linename) != 0) {
      ObjectCreate(linename, OBJ_TREND, 0, startofday, level, Time[0],level);
      ObjectSet(linename, OBJPROP_STYLE, linestyle);
      ObjectSet(linename, OBJPROP_COLOR, col1);
   }
   else {
      ObjectMove(linename, 1, Time[0],level);
      ObjectMove(linename, 0, startofday, level);
   }
   

   // put a label on the line   
   if (ObjectFind(labelname) != 0) {
      ObjectCreate(labelname, OBJ_TEXT, 0, MathMin(Time[BarForLabels], startofday + 2*Period()*60), level);
   }
   else {
      ObjectMove(labelname, 0, MathMin(Time[BarForLabels], startofday+2*Period()*60), level);
   }

   pricelabel= " " + text;
   if (ShowLevelPrices && StrToInteger(text)==0) 
      pricelabel= pricelabel + ": "+DoubleToStr(level, Digits);
   
   ObjectSetText(labelname, pricelabel, 8, "Arial", White);
}
      

//+------------------------------------------------------------------+
//| Helper                                                           |
//+------------------------------------------------------------------+
void SetTimeLine(string objname, string text, int idx, color col1, double vleveltext) 
{
   string name= "[PIVOT] " + objname;
   int x= iTime(NULL, PERIOD_H1, idx);

   if (ObjectFind(name) != 0) 
      ObjectCreate(name, OBJ_TREND, 0, x, 0, x, 100);
   else {
      ObjectMove(name, 0, x, 0);
      ObjectMove(name, 1, x, 100);
   }
   
   ObjectSet(name, OBJPROP_STYLE, STYLE_DOT);
   ObjectSet(name, OBJPROP_COLOR, DarkGray);
   
   if (ObjectFind(name + " Label") != 0) 
      ObjectCreate(name + " Label", OBJ_TEXT, 0, x, vleveltext);
   else
      ObjectMove(name + " Label", 0, x, vleveltext);
            
   ObjectSetText(name + " Label", text, 8, "Arial", col1);
}

Comments