Sunday, April 5, 2015

ThinkorSwim / TOS Custom Quote Columns with Conditional Colors

There are several key levels and/or conditions that I have considered important over the years.  And within the past year, @FinancialTrader has further inspired and validated the use of those levels based on the methodical way he trades opening range breakout (ORB) setups. 

A few examples of the levels include where the stock currently trades (or has traded) in relationship to the prior high of day (pHOD) as well as the prior low of day (pLOD), and the 30 minute opening range.

So with my daily watchlist, I wanted to quickly see those conditions within a quote window with simple green and red boxes, so that I wouldn't have to even view and/or flip through multiple charts.

I've been a TradeStation user for many years and had already programmed the conditions within a customizable quote window they call RadarScreen.  But unless you meet certain trading volumes every month, they will charge you $60/month just for the RadarScreen add-on (in addition to the base platform fee of $99/month AND exchange data fees which never get waived).  

Doesn't seem like a good deal, especially since I'm winding down my trading volume and will likely miss my volume thresholds in the future.  So I wanted alternatives to TradeStation...as much as I love the platform.

This is where thinkorswim / TOS comes into play. Hard to believe I've had an account with them for nearly 20 years, ever since they were Datek and they had just created their revolutionary Island ECN...oh those were the days.  

I've NEVER paid any data or platform fees to TOS, even though the account has been mostly dormant for nearly 10 years!  Since FREE > $60/month, I started a crash course last month to learn more about TOS and programming with thinkScript.  

I credit a lot of my recent thinkScript learning to:

For the ORB code, it was great to see in the header comments for the original code that Prospectus created the script based on inspiration from the old school Trader-X blog.  That blog inspired me to return back to trading several years ago, and it feels like I've come full circle.  And although the blog is no longer active, it sure was good to see Trader-X post a new update back in February.

Explained below are few examples of how and what you can do to create red/green (or whatever color you choose) conditional boxes / columns in quote windows.  The code is based on very small modifications I've made to popular scripts that have in use for a while.  Since I'm still a novice, any good shortcuts or suggestions for improvements is much appreciated.

HOW TO ADD CUSTOM QUOTE INDICATOR COLUMNS WITH CONDITIONAL COLOR HIGHLIGHTING

1) Within a quote window, RIGHT click the small gray circle in the upper right part of the box next to Symbol.  Then click "Customize"

2)  Within the Customize Quotes or Watchlist window, scroll down to an unused "Custom..." item, and double-click it

3)  Go into the "Column name" and change it to the name of your new study (see below)

4)  Just to the right of "Column name" change the "Aggregation" to 5 min.

5)  Select the "thinkScript Editor" tab

6)  Remove any content within the editor

7)  Copy/paste your new code (see below) into the editor and press OK

8)  Highlight your newly created Custom Quote column in the left column, and move it to the right under "Current Set" 

9)  Press OK, and you should see the column in your quote window


CUSTOM COLUMN CODE BELOW

Custom column name: ORB
Definition:  If last traded price is either above or below the 30 minute opening range, then display green box with + or red box with -
thinkScript code:

# Original code by Prospectus & Thinkscripter
# Prospectus:
# Automatic Opening Range and Fibonacci Levels
# Inspired by Trader-X @ http://traderx.blogspot.com
# Thinkscripter:
# TS_OpeningRangeCloud

# Modified by @grove_under to display as custom column quotes
# with green/red background boxes

# Opening Range custom quote

input showOnlyToday = YES;
input InitialBalanceMinutes = 30;
input Market_Open_Time = 0930;
input Market_Close_Time = 1600;

def day = GetDay();
def lastDay = GetLastDay();
def isToday = If(day == lastDay, 1, 0);
def shouldPlot = If(showOnlyToday and isToday, 1, If(!showOnlyToday, 1, 0));
def pastOpen = If((SecondsTillTime(Market_Open_Time) > 0), 0, 1);
def pastClose = If((SecondsTillTime(Market_Close_Time) > 0), 0, 1);
def marketOpen = If(pastOpen and !pastClose, 1, 0);
def firstBar = If (day[1] != day, day - 1, 0);
def secondsUntilOpen = SecondsTillTime(Market_Open_Time);
def regularHours = SecondsTillTime(Market_Close_Time);
def secondsFromOpen = SecondsFromTime(Market_Open_Time);
def pastOpeningRange = If(secondsFromOpen >= (InitialBalanceMinutes * 60), 1, 0);

rec displayedHigh = If(high > displayedHigh[1] and marketOpen, high, If(marketOpen and !firstBar, 
displayedHigh[1], high));
rec displayedLow = If(low < displayedLow[1] and marketOpen, low, If(marketOpen and !firstBar, 
displayedLow[1], low));

rec IBHigh = If(pastOpeningRange, IBHigh[1], displayedHigh);
rec IBLow = If(pastOpeningRange, IBLow[1], displayedLow);

plot IBH = If(pastOpeningRange and marketOpen and shouldPlot, IBHigh, Double.NaN);
plot IBL = If(pastOpeningRange and marketOpen and shouldPlot, IBLow , Double.NaN);
assignBackgroundColor(if close > IBH then color.green else if close < IBL then color.red else 
color.current);

AddLabel(yes,if close > IBH then "+" else if close < IBL then "-" else " ", Color.DARK_ORANGE);


* * * * * * * * * *
Custom column name: pHOD/pLOD
Definition:  If last traded price is either above or below the pHOD or pLOD, then display green box with > or red box with <
thinkScript code:

# pHOD/pLOD +/- quote indicator

# Modified by @grove_under to display as custom column quotes
# with green/red background boxes if last price above pHOD or below pLOD

input aggregationPeriod = AggregationPeriod.DAY;
input length = 1;
input displace = -1;

plot PrevDayHigh = Highest(high(period =
aggregationPeriod)[-displace], length);
PrevDayHigh.SetDefaultColor(GetColor(3));
PrevDayHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);


plot PrevDayLow = Lowest(low(period =
aggregationPeriod)[-displace], length);
PrevDayLow.SetDefaultColor(GetColor(3));
PrevDayLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);

AddLabel(yes, if Close > PrevDayHigh then ">" else if Close < PrevDayLow then "<" else " ", Color.DARK_ORANGE);


* * * * * * * * * *
Custom column name: pLOD
Definition:  If today's low of day is below prior low of day, then red box
thinkScript code:

# pLOD broken
# Modified by @grove_under to display as custom column quotes
# with red background box if today's LOD < pLOD

input aggregationPeriod = AggregationPeriod.DAY;
input length = 1;
input displace = -1;

plot TodayHigh = Highest(high(period =
aggregationPeriod), length);

plot TodayLow = Lowest(low(period =
aggregationPeriod), length);
plot PrevDayHigh = Highest(high(period =
aggregationPeriod)[-displace], length);

plot PrevDayLow = Lowest(low(period =
aggregationPeriod)[-displace], length);

# Assign color to quote background
assignBackgroundColor(if TodayLow < PrevDayLow then color.dark_red else color.current);

AddLabel(yes, if TodayLow < PrevDayLow then "pLOD" else " ", Color.DARK_ORANGE);


* * * * * * * * * *
Custom column name: pHOD
Definition:  If today's high of day is above prior high of day, then display green box with pHOD
thinkScript code:

# pHOD broken
# Modified by @grove_under to display as custom column quotes
# with red background box if today's HOD > pHOD

input aggregationPeriod = AggregationPeriod.DAY;
input length = 1;
input displace = -1;

plot TodayHigh = Highest(high(period =
aggregationPeriod), length);

plot TodayLow = Lowest(low(period =
aggregationPeriod), length);

plot PrevDayHigh = Highest(high(period =
aggregationPeriod)[-displace], length);

plot PrevDayLow = Lowest(low(period =
aggregationPeriod)[-displace], length);

# Assign color to quote background
assignBackgroundColor(if TodayHigh > PrevDayHigh then color.dark_green else color.current);

AddLabel(yes, if TodayHigh > PrevDayHigh then "pHOD" else " ", Color.DARK_ORANGE);