Extended-Hours Highlighter v2 For ThinkOrSwim

SteveDay

Member
Plus
Improved Extended-Hours Highlighter v2
by Steve Day

The following study is a replacement for the built-in Extended-Hours Highlighter.

It's primary purpose was to allow customization of the highlighting color, which in the built-in version is a fixed gray. I ended up expanding it to give separate colors to the Pre-Market & After-Hours sessions.

At the heart of it is a rather elegant (even if I do say so myself) time-zone offset calculation, which I created last year. By applying the time-zone to the UTC date/time, my study is able to automatically detect the (start of) Pre-Market & (end of) After-Hours sessions, with zero user input needed. (Their times do not have to be entered manually ... unlike even ToS's built-in scripts!).

As a secondary feature I added Market "Open" & "Close" vertical lines, as well as another vertical line which separates each day and optionally shows the date (like TradingView).

To use the custom-color highlighting you will need to disable the system's "Highlight Extended Hours" function, from each chart's "Settings -> Equities" tab.

ThinkOrSwim shared study: http://tos.mx/VwKPicC

Screenshots below, and code below that...

---------------------------------------- Screenshot #1/3 ----------------------------------------
qF91uem.png

Screenshot showing the study enabled.

---------------------------------------- Screenshot #2/3 ----------------------------------------
8vaYQNl.png

Screenshot of the study disabled, showing the system built-in Extended-Hours Highlighter (which has a non-adjustable gray color), and no separators or date for each day.

---------------------------------------- Screenshot #3/3 ----------------------------------------
i6zJQ41.png

Screenshot of the where to disable the built-in Extended-Hours Highlighter. This must be done for each chart that you want to use my highlighter with.

All 3 screenshots on one page: https://imgur.com/a/YPiLqnn


Ruby:
#//# [SD] Improved Extended-Hours Highlighter v2.0.1
#==# -----------------------------------------------
#//# AUTHOR:    Steve Day
#//# CREATED:   2023/06/15
#//# MODIFIED:  2023/06/26
#//# All Rights Reserved.
#..#
#!!# NOTICE:    Feel free to share this script far and wide, as long as:
#!!#            1) You do not charge for, or "paywall" this script without my express permission.
#!!#            2) This full header is attached and I am credited as the author.
#..#
#..#
#//# PURPOSE:   Built primarily to replace the built-in "Extended Hours Highlighter",
#//#            which has a fixed highlight color (and fixed opacity).
#//#            My version highlights the Pre-Market/After-Hours sessions separately.
#//#            It will also display vertical lines to further highlight sessions.
#//#            The colors are fully customizable, and the date is also shown on the day separator.
#//#
#//# SCREENS:   https://imgur.com/a/YPiLqnn
#..#
#//# PROS:      Fully customizable. Everything can be toggled on/off.
#//#            Date displayed on day separators, like other charting platforms.
#//#            Re-written from the ground up. Much more streamlined than v1.x
#//# CONS:      It's forced to use "AddCloud" to highlight the extended sessions.
#//#            AddCloud can "muddy" charts, due to how TOS blends colors.
#//#            If this is a problem you can adjust the opacity of your colors,
#//#            - or turn them off and rely on the vertical lines to mark sessions.
#//#            The highlighting cloud starts and ends in the middle of a bar, there is no-
#//#            - way around this, as it is a limitation of ThinkOrSwim.
#..#
#//# NOTE:      I am open to freelance work. For offers, please contact: steve(at)steveday(dot)com
#..#
#//# Enjoy!

declare no_caching;
declare hide_on_daily;
declare once_per_bar;


#//# Inputs
input highlight_ExtSessions = yes;
input show_session_lines    = yes;
input line_style            = Curve.SHORT_DASH;
input show_market_text      = yes;#hint show_market_text: 'show_market_text' toggles the visibility of the 'open' or 'close' text on the market open and market close lines.
input show_date             = { "No" , "Normal", default "Zero Padded" };#hint show_date: Allows the user to select if they want the date displayed on each daily separation line.  'No' will display just the line without the date.  'Normal' will display the date, in a loose YYYY/mM/dD format, which leaves out any leading zeroes in the month or day numbers. The 'Zero Padded' option displays the date with leading zeroes added where necessary, so that it keeps the date a fixed length, in strict YYYY/MM/DD format.


#//# Colors
DefineGlobalColor("Ext.Session PM", CreateColor(128,64,0) );
DefineGlobalColor("Ext.Session AM", CreateColor(5,45,102) );
DefineGlobalColor("Day Separator" , Color.LIGHT_GRAY);
DefineGlobalColor("Market Open"   , CreateColor(0,140,0) );
DefineGlobalColor("Market Close"  , CreateColor(168,0,0) );


#//# Vars
def cap             = GetAggregationPeriod();
def date            = GetYYYYMMDD();
def time            = GetTime();
def date_day        = GetDayOfMonth(date);
def date_month      = GetMonth();
def date_year       = GetYear();
def barStart        = time;
def barEnd          = time + cap;
def msSinceMidnight = (time % AggregationPeriod.DAY);
def dayStart        = time - msSinceMidnight;
def dayEnd          = dayStart + AggregationPeriod.DAY;
def mktOpen         = RegularTradingStart(date);
def mktClose        = RegularTradingEnd(date);


#//# Session Logic
def isNewDay        = date > date[1] and !IsNaN(date[1]);
def isMarketHours   = time >  mktOpen  and time <  mktClose;
def isAfterHours    = time >= mktClose and time <= dayEnd;
def isPreMarket     = time >= dayStart and time <= mktOpen;


#//# Session Highlighter Logic
def trig_ExtHours = if highlight_ExtSessions and (cap < AggregationPeriod.DAY) then
                        if isPreMarket then Double.POSITIVE_INFINITY
                        else if isAfterHours then Double.NEGATIVE_INFINITY
                        else Double.NaN
                    else Double.NaN;

#//# Highlight Sessions
AddCloud( trig_ExtHours , -trig_ExtHours
        , GlobalColor("Ext.Session PM")
        , GlobalColor("Ext.Session AM") );


#//# Vertical Line Logic
def draw_NewDay     =   show_session_lines and (cap < AggregationPeriod.DAY)
                        and isNewDay;
def draw_MktOpen    =   show_session_lines and (cap < AggregationPeriod.DAY)
                        and (!isMarketHours[1] and isMarketHours) and !isNewDay;
def draw_MktClose   =   show_session_lines and (cap < AggregationPeriod.DAY)

                        and (isMarketHours[1] and !isMarketHours) and !isNewDay;


#//# Draw Vertical Lines (Session Separators)
AddVerticalLine(draw_NewDay
    ,   if show_date != show_date."No" then
            AsPrice(date_year) + "/" +
            if (show_date == show_date."Zero Padded") then
                Concat( if date_month < 10 then "0" else "" , AsPrice(date_month)) + "/" +
                Concat( if date_day < 10 then "0" else "" , AsPrice(date_day) )
            else
                AsPrice(date_month) + "/" +
                AsPrice(date_day)
        else ""

    , GlobalColor("Day Separator") , line_style );
AddVerticalLine(draw_MktOpen
    , if show_market_text then "open" else ""
    , GlobalColor("Market Open")   , line_style );
AddVerticalLine(draw_MktClose
    , if show_market_text then "close" else ""
    , GlobalColor("Market Close")  , line_style );
 
Last edited:

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

My apologies... In this version I had removed the time-zone code, as I didn't think it needed it (it doesn't for traders in the U.S. while our clocks are on summer time), because the difference between GMT & ET is only 4hrs EST (or 5hrs EDT), and trading ends at 8pm, which is midnight GMT. When the clocks change and the difference is then 5hrs and the next-day rollover would happen at 7pm.. 1hr before trading ends.

I am working hard to put it back in, while making it as optimized as possible (because any extra code is a burden on the Java-based ThinkScript compiler). I got it the time-zone code re-written last night, and also had to write a UTC to date/time converter in order to debug it. I'm still in the testing phase and am planning on releasing v2.0.2 this evening.

With the time-zone code, I am able to automatically calculating the time-zone offset of the local exchange/server versus GMT. I calculate it at the beginning and update it on every new calendar day, so it will handle daylight savings clock changes automatically. With the pre-calculated/buffered time-zone offset, I apply it to the current UTC time, which lets me calculate the precise start & end of each day - down to the millisecond. By applying the time-zone offset to UTC time I can handle boundaries that cross multiple days.

One such application that I am using this in is my time-based Daily Relative Volume study, which is taking many, many hours to develop, so I am not envisioning releasing that on the forum. I need to make it pay me back for some of the hard work I've put into that one. (So far I have it comparing the current Market volume to the highest and average of previous days, from the same time each day. It does not yet gaps in the data, where volume is low and no trading happens for several bars, but it will handle all of that flawlessly when released.)

I will be using the time-zone code in any future studies that I think will benefit from automatic session handling, or those that use time in one way or another (such as time-based studies, which look at bar data from a certain time, rather than just 'n' bars back).

Thank you for your patience.
Steve
 
My apologies... In this version I had removed the time-zone code, as I didn't think it needed it (it doesn't for traders in the U.S. while our clocks are on summer time), because the difference between GMT & ET is only 4hrs EST (or 5hrs EDT), and trading ends at 8pm, which is midnight GMT. When the clocks change and the difference is then 5hrs and the next-day rollover would happen at 7pm.. 1hr before trading ends.

I am working hard to put it back in, while making it as optimized as possible (because any extra code is a burden on the Java-based ThinkScript compiler). I got it the time-zone code re-written last night, and also had to write a UTC to date/time converter in order to debug it. I'm still in the testing phase and am planning on releasing v2.0.2 this evening.

With the time-zone code, I am able to automatically calculating the time-zone offset of the local exchange/server versus GMT. I calculate it at the beginning and update it on every new calendar day, so it will handle daylight savings clock changes automatically. With the pre-calculated/buffered time-zone offset, I apply it to the current UTC time, which lets me calculate the precise start & end of each day - down to the millisecond. By applying the time-zone offset to UTC time I can handle boundaries that cross multiple days.

One such application that I am using this in is my time-based Daily Relative Volume study, which is taking many, many hours to develop, so I am not envisioning releasing that on the forum. I need to make it pay me back for some of the hard work I've put into that one. (So far I have it comparing the current Market volume to the highest and average of previous days, from the same time each day. It does not yet gaps in the data, where volume is low and no trading happens for several bars, but it will handle all of that flawlessly when released.)

I will be using the time-zone code in any future studies that I think will benefit from automatic session handling, or those that use time in one way or another (such as time-based studies, which look at bar data from a certain time, rather than just 'n' bars back).

Thank you for your patience.
Steve
Hi Steve!
Thanks for sharing, I do like the idea. I had done something super simple to show the day of the week on my divider and I used some of the built-in TOS hours to make it work. That might be the work around for the time-zone stuff in this study. I just added a cloud in the last two lines to finish the concept.

4PcfAzL.png


Ruby:
declare hide_on_daily;
def GlobeX = GetTime() < RegularTradingStart(GetYYYYMMDD());
def DayOfWeek = getDayOfWeek(getYyyyMmDd());
AddVerticalLine(GlobeX and !Globex[1],if DayOfWeek == 1 then "Monday" else if DayOfWeek == 2 then "Tuesday" else if DayOfWeek == 3 then "Wednesday" else if DayOfWeek == 4 then "Thursday" else if DayOfWeek == 5 then "Friday" else "",Color.GRAY);

def RTH = GetTime() >= RegularTradingStart(GetYYYYMMDD());
AddCloud(if Globex then Double.POSITIVE_INFINITY else Double.NaN, Double.NEGATIVE_INFINITY, Color.GRAY, Color.GRAY);

Hopefully you could use that idea to get around the time zone dependence? Not sure if that will work for everyone or not but suspect that may be the way the built-in divider is working. Best of luck on your other indy!
 
Hi Steve!
Thanks for sharing, I do like the idea. I had done something super simple to show the day of the week on my divider and I used some of the built-in TOS hours to make it work. That might be the work around for the time-zone stuff in this study. I just added a cloud in the last two lines to finish the concept.
...
Hopefully you could use that idea to get around the time zone dependence? Not sure if that will work for everyone or not but suspect that may be the way the built-in divider is working. Best of luck on your other indy!
Hi Tony,

Thanks for the input. I believe that I was overcomplicating things and am going back to the simpler date rollover method instead, with Market hours still auto-setting using RegularTradingStart and RegularTradingEnd.

I did note that RegularTradingStart/End do not change before Bank Holidays, even though those trading days are sometimes shorter. (This July 3rd for instance, when trading ended around 1pm ET .. from memory).

Not sure why the RegularTradingStart/End requires a date input if the returned times do not change for special days.

Anyway, I've reverted back to the v2 model and am making refinements to it (such as cutoff periods, when you don't want to show the highlights or lines above certain timeframes .. for instance, with separator lines on a 2hr chart is far too messy and is difficult to read).
 
Thread starter Similar threads Forum Replies Date
C Extended Keltner Channels For ThinkOrSwim Custom 5
L Long Bar Highlighter For ThinkOrSwim Custom 3

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
316 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top