Circuit Breaker Halt Indicator for ThinkorSwim

Nice work on the halt indicator! Im glad someone else decided to undertake this. I just noticed a stock today the monitor after 3:30 ET showed too low of a halt point. I think you need to fix a little math for that time and price stock. See image.

EDIT: I just read the comment in the code and see it mentioned no halt down currently for that time period. I didn't realize that. Good to know.

Hi Wannaspeed, Is it possible you can share the script for the "volume" area you have on the chart. i like the info you have displayed in there all in one place. Thanks alot
g7bLvLY.png
 
Hi Wannaspeed, Is it possible you can share the script for the "volume" area you have on the chart. i like the info you have displayed in there all in one place. Thanks alot
Did you know that clicking on a member's avatar will allow you to see when a member was last seen on the uTS forum? @Wannaspeed has not been seen in a while. :(

His volume labels are several scripts, overlaid together.
These scripts are sprinkled throughout various threads:
Start with these threads and if they don't float your boat, search volume labels for many more.
https://usethinkscript.com/threads/...essure-indicator-labels-for-thinkorswim.8466/
https://usethinkscript.com/threads/volume-profile-indicator-pocs.8153/
https://usethinkscript.com/threads/volume-stats-watchlist-scan-labels-for-thinkorswim.970/
 
Did you know that clicking on a member's avatar will allow you to see when a member was last seen on the uTS forum? @Wannaspeed has not been seen in a while. :(

His volume labels are several scripts, overlaid together.
These scripts are sprinkled throughout various threads:
Start with these threads and if they don't float your boat, search volume labels for many more.
https://usethinkscript.com/threads/...essure-indicator-labels-for-thinkorswim.8466/
https://usethinkscript.com/threads/volume-profile-indicator-pocs.8153/
https://usethinkscript.com/threads/volume-stats-watchlist-scan-labels-for-thinkorswim.970/
my bad Merry, i was reading the thread that i didnt pay attention to last time seen. Thank you. Hope all is well with WannaSpeed
 
Is there any rhyme or reason/ methodology to determining what the opening price will be around when a stock opens from a halt??
 
Here is my code for an updated Halt Estimate Indicator for Tier 2 Stocks. Thanks to @Wannaspeed for the original solution! Btw I am only a novice so my coding may not be following best practices, but I spent a lot of time trying to follow the LULD Rules here and here to my ability & it seems to work pretty well. Please improve/fix anything that needs it.

This has been updated for the new February 2020 Limit Up Limit Down halt rules. They eliminated the doubling of the bands from 9:30 to 9:45, and also changed the doubling rules slightly from 3:35-4pm. I tried to follow all of the halt rules, and it also works during the 5 minutes after a halt.

It is somewhat future proof in case they change the rules again. The percentages, hours, and price ranges are adjustable near the top of the code. So, for example, there is now no doubling in the first 15min of opening, but if they change that back, you can just type in the new changeover time for "normal_Hours_Start". The "930" could be changed back to "945" and the new percentages for the opening period would need to be changed below. You can also update price boundaries (the changeover price for what they consider a low, mid, or high priced stock) if that changes.

Because of limits of thinkscript data, there are limits to accuracy of the estimated halt price. Here are some of the major obstacles I encountered:
(1) Determining the average price for transactions over the last 5 minutes
- We don't (to my knowledge) have access to the real average price a stock traded at in a given 1-minute bar, so I estimate it as (high+low)/2, the midpoint of the bar. For example, if a bar has 95% of its transactions near the low, and only 5% near the high, the estimate will be off.

(2) 30 Seconds Reference Price rule: "The reference price will only be updated if the new reference price is at least 1% away in either direction from the current. Each new Reference Price shall remain in effect for at least 30 seconds."
- We only have access to minute chart data, so reference prices that are held for 30 seconds are impossible to get exactly right. We could be updating the reference when we shouldn't or vice-versa. For example if a new bar starts with a huge move, we don't know if we are within the 30 second hold. If we are, the current price band should stay put. If not, it should update based on the current bar's movement (in addition to the previous 5 min of bars).

(3) Previous 5 Minutes
- The definition of previous 5 minutes seems to be a live rolling 5 minute period. Since we can access only full minute bar data, this won't be totally accurate either.

Given these limitations, for each bar there are 2 estimated halt prices calculated for the upper band and 2 for the lower band. One uses the midpoint of the current bar in the calculation, and the more conservative one assumes the current bar's price spent more time inward, closer to the reference. Other considerations are also calculated.

There are 3 display modes:
Range - Shaded area between the two calculated halt estimates of each band
Line - A line of the conservative halt estimate for each band
Area - Shades the entire area above the upper conservative band, and below the lower conservative band

I personally prefer Range. With it I have a better idea of where a halt is likely to occur.

Remember this indicator is just an estimate. A halt may (and will) sometimes occur before the price reaches a band, or it may not occur even though price has reached a band. It seems a halt also requires the price to touch the real band for 15 seconds for a halt to occur, so that may cause some misses too.

Btw the bubbles showing actual halts are a separate script I created here. It only shows the length of a likely halt after a new bar after the fact. I like using them both together.

1-MINUTE CHART ONLY
TIER 2 STOCKS ONLY. Not accurate on tier 1 (S&P 500, Russell 1000 stocks)

Range
9n4Zipz.png


Line
AdN6LV1.png


Area
3rBf2db.png



Code:
# LULD Halt Estimate Indicator 1.01 by Lenny
# - various code concepts from multiple posts at Usethinkscript.com

# v1.0  5/2/20  -original
# v1.01 6/9/20  -minor fix in situation where there is no lower band

# 1-MINUTE CHART ONLY
# TIER 2 STOCKS ONLY. Not accurate on tier 1 (S&P 500, Russell 1000 stocks)
# Works with 3 (or less) stock price ranges (Low, Mid, High)
# Works with 3 (or less) time periods for each price range (Open, Normal, Close)
#   (If opening and/or closing hours are not used, enter same time and boundries as normal hours)
declare hide_on_daily;

#=================  INPUTS  =================#

input display_Mode = {default Range, Line, Area};
input show_today_only = yes;
input show_labels = yes;

# Hour ranges (enter duplicate of normal hours if no opening or closing hours difference)
input open_Time  = 0930;
input normal_Hours_Start = 0930;
input normal_Hours_End = 1535;
input close_Time = 1600;

# Adjust bands very slightly inward for margin of error
# (by default 1% of the difference between ref price and band)
def Estimate_Adjustment_Percent = 1;    # 1% recommended


#==========  BOUNDRIES AND LIMITS  ==========#

# Price range boundries (Low/Mid, Mid/High priced stocks)
def LowPriceMax = .75;
def MidPriceMax = 3.00;

# Low-priced stocks percentage / dollar(alt) limit bands
def LowPriceOpenPercent   = 75;        # Will choose lower of percent and dollar value
def LowPriceOpenAlt       = .15;
def LowPriceNormalPercent = 75;        # Will choose lower of percent and dollar value
def LowPriceNormalAlt     = .15;
def LowPriceClosePercentUp   = 150;    # upper and lower have different rules for low priced stocks (currently)
def LowPriceCloseAltUp       = .30;    # Will choose lower of percent and dollar value
def LowPriceClosePercentDown = 0;      # 0 = no limit, no lower band needed (currently)
def LowPriceCloseAltDown     = 0;      # 0 = no limit, no lower band needed (currently)

# Mid-priced stocks percentage limit bands
def MidPriceOpenPercent   = 20;
def MidPriceNormalPercent = 20;
def MidPriceClosePercent  = 40;

# High-priced stocks percentage limit bands
def HighPriceOpenPercent   = 10;
def HighPriceNormalPercent = 10;
def HighPriceClosePercent  = 10;

# Minimum reference price change (%)
def RefMinChangePercent = 1;            # must move 1% to move bands (LULD rules)


#================= DEFs =====================#

def Active = SecondsFromTime(open_Time) >= 0 and SecondsTillTime(close_Time) - 1 >= 0;
def Today  = GetDay() == GetLastDay();
def isMinuteAgg = (GetAggregationPeriod() == AggregationPeriod.MIN);
def Qualifies = if show_today_only then Today and Active and isMinuteAgg else Active and isMinuteAgg;
def FirstBar = Active == 1 and Active[1] == 0;
def CurrentMinute = RoundDown(SecondsFromTime(open_Time) / 60, 0) + 1;
def MinFromPrevBar = CurrentMinute - CurrentMinute[1];
def PriorClose = close(period = AggregationPeriod.DAY)[1];
def lastBarClose = close[1];
def ExtendBar1 = FirstBar[1] and IsNaN(close) and !IsNaN(close[1]); #1st bar bands will extend to right so 1st bar is visible live

def LowPriced = PriorClose < LowPriceMax;
def MidPriced = PriorClose >= LowPriceMax and PriorClose <= MidPriceMax;
def HighPriced = PriorClose > MidPriceMax;
def OpeningHours = SecondsFromTime(open_Time) >= 0 and SecondsTillTime(normal_Hours_Start) > 0;
def NormalHours  = SecondsFromTime(normal_Hours_Start) >= 0 and SecondsTillTime(normal_Hours_End) > 0;
def ClosingHours = SecondsFromTime(normal_Hours_End) >= 0 and SecondsTillTime(close_Time) > 0;


#======= CALCULATE REFERENCE ESTIMATES =======#

def vol = volume;
def histAvgPrice = hl2;
def histAvgPriceVol = histAvgPrice * vol;

def Bar0AvgPriceUp    = (open + low) / 2;        # Bar0 = current bar
def Bar0AvgPriceVolUp = Bar0AvgPriceUp * vol;
def Bar0AvgPriceLw    = (open + high) / 2;
def Bar0AvgPriceVolLw = Bar0AvgPriceLw * vol;
def Bar0AvgPriceHL2   =  hl2;
def Bar0AvgPriceHL2Vol = Bar0AvgPriceHL2 * vol;

def Bar1AvgPriceVol = histAvgPriceVol[1];
def Bar2AvgPriceVol = histAvgPriceVol[2];
def Bar3AvgPriceVol = histAvgPriceVol[3];
def Bar4AvgPriceVol = histAvgPriceVol[4];
def Bar5AvgPriceVol = histAvgPriceVol[5];

def Bar0Within5Min = 1;
def Bar1Within5Min = CurrentMinute[1] >= CurrentMinute - 4 and CurrentMinute[1] > 0;
def Bar2Within5Min = CurrentMinute[2] >= CurrentMinute - 5 and CurrentMinute[2] > 0;
def Bar3Within5Min = CurrentMinute[3] >= CurrentMinute - 5 and CurrentMinute[3] > 0;
def Bar4Within5Min = CurrentMinute[4] >= CurrentMinute - 5 and CurrentMinute[4] > 0;
def Bar5Within5Min = CurrentMinute[5] >= CurrentMinute - 5 and CurrentMinute[5] > 0;

def totalAvgPriceVolUp =
    (Bar0AvgPriceVolUp * Bar0Within5Min) + (Bar1AvgPriceVol * Bar1Within5Min) + (Bar2AvgPriceVol * Bar2Within5Min) +
    (Bar3AvgPriceVol * Bar3Within5Min) + (Bar4AvgPriceVol * Bar4Within5Min) + (Bar5AvgPriceVol * Bar5Within5Min);
def totalAvgPriceVolLw =
    (Bar0AvgPriceVolLw * Bar0Within5Min) + (Bar1AvgPriceVol * Bar1Within5Min) + (Bar2AvgPriceVol * Bar2Within5Min) +
    (Bar3AvgPriceVol * Bar3Within5Min) + (Bar4AvgPriceVol * Bar4Within5Min) + (Bar5AvgPriceVol * Bar5Within5Min);
def totalAvgPriceVolHL2 =
    (Bar0AvgPriceHL2Vol * Bar0Within5Min) + (Bar1AvgPriceVol * Bar1Within5Min) + (Bar2AvgPriceVol * Bar2Within5Min) +
    (Bar3AvgPriceVol * Bar3Within5Min) + (Bar4AvgPriceVol * Bar4Within5Min) + (Bar5AvgPriceVol * Bar5Within5Min);
def totalVol =
    (vol * Bar0Within5Min) + (vol[1] * Bar1Within5Min) + (vol[2] * Bar2Within5Min) +
    (vol[3] * Bar3Within5Min) + (vol[4] * Bar4Within5Min) + (vol[5] * Bar5Within5Min);

def vwapUp  = totalAvgPriceVolUp / totalVol;
def vwapLw  = totalAvgPriceVolLw / totalVol;
def vwapHL2 = totalAvgPriceVolHL2 / totalVol;

#Reference must move at least 1% or previous ref constinues
def RefMinIncDecimal = (RefMinChangePercent  *.01) + 1;
def RefMinDecDecimal = 1 - (RefMinChangePercent  *.01);
def RefPriceUp =
    if (FirstBar or MinFromPrevBar >= 5) then Bar0AvgPriceUp else
    if (vwapUp >= RefPriceUp[1] * RefMinIncDecimal) or (vwapUp <= RefPriceUp[1] * RefMinDecDecimal) then vwapUp else RefPriceUp[1];
def RefPriceLw =
    if (FirstBar or MinFromPrevBar >= 5) then Bar0AvgPriceLw else
    if (vwapLw >= RefPriceLw[1] * RefMinIncDecimal) or (vwapLw <= RefPriceLw[1] * RefMinDecDecimal) then vwapLw else RefPriceLw[1];
def RefPriceHL2 =
    if (FirstBar or MinFromPrevBar >= 5) then Bar0AvgPriceHL2 else
    if (vwapHL2 >= RefPriceHL2[1] * RefMinIncDecimal) or (vwapHL2 <= RefPriceHL2[1] * RefMinDecDecimal) then vwapHL2 else RefPriceHL2[1];


#============= CALCULATE BANDS ==============#

def UpperBand1 =
if LowPriced and OpeningHours then RefPriceUp + Min(RefPriceUp * LowPriceOpenPercent * .01 , LowPriceOpenAlt) else
if LowPriced and NormalHours then RefPriceUp + Min(RefPriceUp * LowPriceNormalPercent * .01 , LowPriceNormalAlt) else
if LowPriced and ClosingHours then RefPriceUp + Min(RefPriceUp * LowPriceClosePercentUp * .01 , LowPriceCloseAltUp) else

if MidPriced and OpeningHours then RefPriceUp + (RefPriceUp * MidPriceOpenPercent * .01) else
if MidPriced and NormalHours then RefPriceUp + (RefPriceUp * MidPriceNormalPercent * .01) else
if MidPriced and ClosingHours then RefPriceUp + (RefPriceUp * MidPriceClosePercent * .01) else

if HighPriced and OpeningHours then RefPriceUp + (RefPriceUp * HighPriceOpenPercent * .01) else
if HighPriced and NormalHours then  RefPriceUp + (RefPriceUp * HighPriceNormalPercent * .01) else
if HighPriced and ClosingHours then  RefPriceUp + (RefPriceUp * HighPriceClosePercent * .01) else Double.NaN;

def UpperBand2 =
if LowPriced and OpeningHours then RefPriceHL2 + Min(RefPriceHL2 * LowPriceOpenPercent * .01 , LowPriceOpenAlt) else
if LowPriced and NormalHours then RefPriceHL2 + Min(RefPriceHL2 * LowPriceNormalPercent * .01 , LowPriceNormalAlt) else
if LowPriced and ClosingHours then RefPriceHL2 + Min(RefPriceHL2 * LowPriceClosePercentUp * .01 , LowPriceCloseAltUp) else

if MidPriced and OpeningHours then RefPriceHL2 + (RefPriceHL2 * MidPriceOpenPercent * .01) else
if MidPriced and NormalHours then RefPriceHL2 + (RefPriceHL2 * MidPriceNormalPercent * .01) else
if MidPriced and ClosingHours then RefPriceHL2 + (RefPriceHL2 * MidPriceClosePercent * .01) else

if HighPriced and OpeningHours then RefPriceHL2 + (RefPriceHL2 * HighPriceOpenPercent * .01) else
if HighPriced and NormalHours then  RefPriceHL2 + (RefPriceHL2 * HighPriceNormalPercent * .01) else
if HighPriced and ClosingHours then  RefPriceHL2 + (RefPriceHL2 * HighPriceClosePercent * .01) else Double.NaN;

def LowerBand1 =
if LowPriced and OpeningHours then RefPriceLw - Min(RefPriceLw * LowPriceOpenPercent * .01 , LowPriceOpenAlt) else
if LowPriced and NormalHours then RefPriceLw - Min(RefPriceLw * LowPriceNormalPercent * .01 , LowPriceNormalAlt) else
   
if LowPriced and ClosingHours and LowPriceClosePercentDown == 0 and LowPriceCloseAltDown == 0 then 0 else
if LowPriced and ClosingHours and (LowPriceClosePercentDown == 0 or LowPriceCloseAltDown == 0) then
    RefPriceLw - Max(RefPriceLw * LowPriceClosePercentDown * .01 , LowPriceCloseAltDown) else
if LowPriced and ClosingHours then RefPriceLw - Min(RefPriceLw * LowPriceClosePercentDown * .01 , LowPriceCloseAltDown) else

if MidPriced and OpeningHours then RefPriceLw - (RefPriceLw * MidPriceOpenPercent * .01) else
if MidPriced and NormalHours then RefPriceLw - (RefPriceLw * MidPriceNormalPercent * .01) else
if MidPriced and ClosingHours then RefPriceLw - (RefPriceLw * MidPriceClosePercent * .01) else

if HighPriced and OpeningHours then RefPriceLw - (RefPriceLw * HighPriceOpenPercent * .01) else
if HighPriced and NormalHours then  RefPriceLw - (RefPriceLw * HighPriceNormalPercent * .01) else
if HighPriced and ClosingHours then  RefPriceLw - (RefPriceLw * HighPriceClosePercent * .01) else Double.NaN;

def LowerBand2 =
if LowPriced and OpeningHours then RefPriceHL2 - Min(RefPriceHL2 * LowPriceOpenPercent * .01 , LowPriceOpenAlt) else
if LowPriced and NormalHours then RefPriceHL2 - Min(RefPriceHL2 * LowPriceNormalPercent * .01 , LowPriceNormalAlt) else
   
if LowPriced and ClosingHours and LowPriceClosePercentDown == 0 and LowPriceCloseAltDown == 0 then 0 else
if LowPriced and ClosingHours and (LowPriceClosePercentDown == 0 or LowPriceCloseAltDown == 0) then
    RefPriceHL2 - Max(RefPriceHL2 * LowPriceClosePercentDown * .01 , LowPriceCloseAltDown) else
if LowPriced and ClosingHours then RefPriceHL2 - Min(RefPriceHL2 * LowPriceClosePercentDown * .01 , LowPriceCloseAltDown) else

if MidPriced and OpeningHours then RefPriceHL2 - (RefPriceHL2 * MidPriceOpenPercent * .01) else
if MidPriced and NormalHours then RefPriceHL2 - (RefPriceHL2 * MidPriceNormalPercent * .01) else
if MidPriced and ClosingHours then RefPriceHL2 - (RefPriceHL2 * MidPriceClosePercent * .01) else

if HighPriced and OpeningHours then RefPriceHL2 - (RefPriceHL2 * HighPriceOpenPercent * .01) else
if HighPriced and NormalHours then  RefPriceHL2 - (RefPriceHL2 * HighPriceNormalPercent * .01) else
if HighPriced and ClosingHours then  RefPriceHL2 - (RefPriceHL2 * HighPriceClosePercent * .01) else Double.NaN;

# Adjust bands very slightly inward (by default 1% of the difference between ref price and band)
def EstimateAdj = Estimate_Adjustment_Percent * .01;
def adjustedUpper1 = if UpperBand1 <= UpperBand2 then UpperBand1 - ((UpperBand1  - RefPriceUp)  * EstimateAdj) else UpperBand1;
def adjustedUpper2 = if UpperBand2  < UpperBand1 then UpperBand2 - ((UpperBand2  - RefPriceHL2) * EstimateAdj) else UpperBand2;
def adjustedLower1 = if LowerBand1 >= LowerBand2 and LowerBand1 != 0 then LowerBand1 + ((RefPriceLw  - LowerBand1)  * EstimateAdj) else LowerBand1;
def adjustedLower2 = if LowerBand2  > LowerBand1 and LowerBand2 != 0 then LowerBand2 + ((RefPriceHL2 - LowerBand2)  * EstimateAdj) else LowerBand2;

# Adjust a band when prior bar closed at likely true band limit, but 15 seconds requirement likely carries band over to current bar
def carryOverBand = high == lastBarClose and low == lastBarClose;
def FinalUpper1 = if !FirstBar then if lastBarClose >= adjustedUpper1[1] and carryOverBand and MinFromPrevBar == 1
    then lastBarClose else adjustedUpper1 else adjustedUpper1;
def FinalUpper2 = if !FirstBar then if lastBarClose >= adjustedUpper2[1] and carryOverBand and MinFromPrevBar == 1
    then lastBarClose else Max(adjustedUpper1 , adjustedUpper2) else adjustedUpper2;
def FinalLower1 = if !FirstBar then if lastBarClose <= adjustedLower1[1] and carryOverBand and MinFromPrevBar == 1
    then lastBarClose else adjustedLower1 else adjustedLower1;
def FinalLower2 = if !FirstBar then if lastBarClose <= adjustedLower2[1] and carryOverBand and MinFromPrevBar == 1
    then lastBarClose else Min(adjustedLower1 , adjustedLower2) else adjustedLower2;
def nearestUpper = Min(FinalUpper1, FinalUpper2);
def nearestLower = Max(FinalLower1, FinalLower2);

# 1st bar bands will extend to right 1 bar so 1st bar is visible live
def FinalUpper1Ext  = if ExtendBar1 then FinalUpper1[1] else FinalUpper1;
def FinalUpper2Ext  = if ExtendBar1 then FinalUpper2[1] else FinalUpper2;
def FinalLower1Ext  = if ExtendBar1 then FinalLower1[1] else FinalLower1;
def FinalLower2Ext  = if ExtendBar1 then FinalLower2[1] else FinalLower2;
def nearestUpperExt = if ExtendBar1 then nearestUpper[1] else nearestUpper;
def nearestLowerExt = if ExtendBar1 then nearestLower[1] else nearestLower;

def mode;
switch (display_Mode) {
case Range: mode = 1;      #Range
case  Area: mode = 2;      #Area
case  Line: mode = 3; }    #Line

AddCloud(if Qualifies and mode == 1 then FinalUpper1Ext else Double.NaN, FinalUpper2Ext, Color.GRAY, Color.GRAY, 1);
AddCloud(if Qualifies and mode == 1 then FinalLower1Ext else Double.NaN, FinalLower2Ext, Color.GRAY, Color.GRAY, 1);
AddCloud(if Qualifies and mode == 2 then nearestUpperExt else Double.NaN, Double.POSITIVE_INFINITY, Color.GRAY, Color.GRAY, 0);
AddCloud(if Qualifies and mode == 2 then nearestLowerExt else Double.NaN, Double.NEGATIVE_INFINITY, Color.GRAY, Color.GRAY, 0);

plot Upper_Line = if Qualifies and mode == 3 then nearestUpperExt else Double.NaN;
Upper_Line.SetDefaultColor(Color.GRAY);
Upper_Line.SetStyle(Curve.FIRM);
Upper_Line.HideBubble();

plot Lower_Line = if Qualifies and mode == 3 then nearestLowerExt else Double.NaN;
Lower_Line.SetDefaultColor(Color.GRAY);
Lower_Line.SetStyle(Curve.FIRM);
Lower_Line.HideBubble();

AddLabel(Qualifies and show_labels, "HaltUp: " + AsDollars(nearestUpper) + "  HaltLw: " + (if nearestLower == 0 then "None" else AsDollars(nearestLower)), Color.ORANGE);
Hello or you can end it this way to save space. Than it will say Hot or Cold...
AddLabel(Qualifies and show_labels, " Hot: " + AsDollars(nearestUpper) + " Cold: " + (if nearestLower == 0 then "None" else AsDollars(nearestLower) + " "), Color.LIGHT_ORANGE);
 
Alright I created the Indicator. It took a long time so feel free to send a donation if you find it useful.

Halt Indicator V2 https://tos.mx/woWh7eq
EDIT:Use this one, the code has been updated to fix a small issue on stocks under .75 https://tos.mx/AQBubMo

Source code:

Code:
#Created By Brent Vogl (Wannaspeed, Brent V)
#Do not Distribute without Creator's Permission
#Do you love my indicator? Help me out with a paypal donation by copy/Paste the link below!
#Paypal Donate: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4CRL8BNAESUHW&source=url
#Date created 11/19/19
#Version 2.1
#Shows Estimated Halt High or Halt Low
################ Inputs (choose what you want to display)
Input showPriorclose = yes;
Input showFiveMinutePrice = yes;
Input showHaltHighPlot = yes;
Input showHaltLowPlot = yes;
#input lowLimit = 0.75;
#input highLimit = 3;
################ Prior Close Price
def aggregationPeriod = AggregationPeriod.DAY;
def displace = -1;
def Priorclose =close(period =aggregationPeriod)[-displace];
################ Definitions
def isopen=if secondsFromTime(0945)>=0 and secondstillTime(1535)>=0 then 1 else 0;
#def beforeStart = GetTime() < RegularTradingStart(getYYYYMMDD());
#def isopen=if secondsFromTime(0930)>=0 and secondstillTime(0945)>=0 and secondsFromTime(1535) and secondsTillTime(1600) then 1 else 0;
def FiveMinPrice = close(period = AggregationPeriod.min)[5];
Def HaltHigh = (if isopen then FiveMinPrice * 1.10 else FiveMinPrice *1.20);
Def HaltLow = if isopen then FiveMinPrice / 1.10 else FiveMinPrice /1.20;
Def HaltHighBetween = (if isopen and priorclose between .75 and 3 then FiveMinPrice * 1.20 else FiveMinPrice *1.40);
Def HaltLowBetween = if isopen and priorclose between .75 and 3 then FiveMinPrice / 1.20 else FiveMinPrice /1.40;
Def HaltHighUnder = if isopen and priorclose is less than 0.75 then FiveMinPrice * 1.75 else FiveMinPrice *2.5;
Def HaltLowUnder = if isopen and priorclose <= 0.75 then FiveMinPrice / 1.75 else FiveMinPrice /2.5;
Def HaltHigh15 = if isopen and priorclose <= 0.75 then fiveMinPrice + 0.15 else fiveMinPrice + 0.30;
Def HaltLow15 = if isopen and priorclose <= 0.75 then fiveMinPrice - 0.15 else fiveMinPrice - 0.30;
################ Labels & Plots
Addlabel (showPriorclose, + Priorclose, color.dark_GRAY);
Addlabel (ShowFiveMinutePrice, + FiveMinPrice, color.DaRK_GRAY);
Addlabel (Priorclose >=3, HaltHigh, color.light_GREEN);#For stocks over $3
#Addlabel (yes, HaltHigh, color.light_GREEN);
Addlabel (Priorclose between 0.75 and 3, HaltHighBetween, color.light_GREEN);#For stocks between .75-3
Addlabel (Priorclose between 0.75 and 3, HaltLowBetween, color.pink);#For stocks between .75-3
Addlabel (Priorclose >=3, HaltLow, color.pINK); #Fors stocks over $3
#Addlabel (Priorclose <=0.75, HaltHighUnder, color.light_Green); #Fors stocks under .75
Addlabel (Priorclose <=0.75, if HaltHighUnder > HaltHigh15 then HaltHigh15 else haltHighUnder, color.light_Green); #Stocks under .75
#Addlabel (Priorclose <=0.75, HaltLowUnder, color.pINK); #Fors stocks under .75
Addlabel (Priorclose <=0.75, if HaltLowUnder < HaltLow15 then HaltLow15 else haltLowUnder, color.pink);#Stocks Under .75 ###check
#Addlabel (yes, HaltLow, color.pINK);
plot HHighOver3 = if ShowHalthighPlot > 0 and Priorclose >=3 then Halthigh else Double.NaN;
plot HLowOver3 = if ShowHaltLowPlot > 0 and Priorclose >=3 then HaltLow else Double.NaN;
plot HhighBEtween = if ShowhaltHighPlot > 0 and between(PriorClose, .75, 3) then HaltHighBetween else Double.NaN;
#plot HHighBetween = if ShowhaltHigh > 0 and priorclose >= lowLimit and priorclose <= highLimit then HaltHighBetween else Double.NaN;
plot HLowBEtween = if ShowhaltLowPlot > 0 and between(PriorClose, .75, 3) then HaltLowBetween else Double.NaN;
#plot HHighUnder = if ShowhaltHighPlot > 0 and Priorclose <= .75 then HaltHighUnder else Double.NaN;
plot HHighUnder = if ShowhaltHighPlot > 0 and Priorclose <= 0.75 then Min(HaltHighUnder, HaltHigh15) else Double.NaN;
#plot HLowUnder = if ShowhaltLowPlot > 0 and Priorclose <= 0.75 then HaltLowUnder else Double.NaN;
plot HLowUnder = if ShowhaltLowPlot > 0 and Priorclose <= 0.75 then Max(HaltLowUnder, HaltLow15) else Double.NaN;###Check
############

It only works on a 1 minute chart, because of limitations with the aggregation period. I don't know if there's a different way to find out the price for 5 minutes ago on other chart time periods. but if anyone knows how I can try to implement it.

By default it shows yesterday's close price, and the close price from 5 mins ago. These can be turned off. It has an upper and lower halt indicator in light green and pink, It also shows an upper/lower Plot by default, which can also be turned off individually. Just because the price touches or overlaps the halt price does not mean the stock will halt, it has to stay at that level for 15 seconds. Also the stock may halt if there's huge volatility between the bid and the ask. This Indicator only compares the close price 5 mins ago to the current price, so it's only a guideline (though it should be pretty accurate). This indicator will not work for tier 1 stocks, though I don't think this is too necessary because they rarely have Volatility Halts. I may try to implement a daily average volume parameter that factors the lower 5/10% for tier 1 stocks at a later date, but its low priority for me because I rarely trade them.

This Indicator does take into account the first 15 minutes of the day and the last 25 minutes, and increases the ranges respectively. It also factors in the price (over $3, Between .75-3 and under .75) and will do the lesser of either 15/30 cents or 75%/150% for stocks under .75. It does continue to show the Halt prices, and plots for Premarket and Post market although there are no halts during this time. I will try to implement a toggle to disable for Aftermarket hours.

I have no idea the characteristics of the Halt indicator during the first 5 minutes of market open. I'm not sure how the SEC handles it either... (is it based on Open price or premarket prices? This indicator will be based on premarket data. Though Im sure it could be adapted if it needs different data during this period. Anyway, if you have any questions, tips, or notice any bugs or odd behavior feel free to let me know.

4toouVl.png
 
Last edited:
I'm not great with thinkscript but I don't use TOS charts, so is there a way to put the LU and LD on a watchlist instead?

TvhkKz7.png


I tried messing around and moving around/taking out some code to see if it would work but it shows NaN, anyone know how I can get this to work?
 
Last edited:
Not sure if someone is still looking for this to work on charts other than 1min. if yes, just use a different constant to match your time on your chart. eg., if you want this to work on 2 min chart, change the aggregation period to match (and adjust script to do a +2 instead of +1):

def agg = AggregationPeriod.TWO_MIN;
Can you write up the code for a 5 Day 5 Minute chart? I cant seem to get it to work.

Is there any rhyme or reason/ methodology to determining what the opening price will be around when a stock opens from a halt??
You can see the estimated resumption price of a halted stock on MooMoo. I use thinkorswim, but I'll switch over to MooMoo when a stock is halted just to see it's resumption price. In my experience it's been pretty accurate. I also use Zendoo's halt scanner on youtube to see what's halted and resumption times.

If anyone know's a better way to see halt resumption price within ToS, let me know.
 
Alright I created the Indicator. It took a long time so feel free to send a donation if you find it useful.

Halt Indicator V2 https://tos.mx/woWh7eq
EDIT:Use this one, the code has been updated to fix a small issue on stocks under .75 https://tos.mx/AQBubMo

Source code:

Code:
#Created By Brent Vogl (Wannaspeed, Brent V)
#Do not Distribute without Creator's Permission
#Do you love my indicator? Help me out with a paypal donation by copy/Paste the link below!
#Paypal Donate: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4CRL8BNAESUHW&source=url
#Date created 11/19/19
#Version 2.1
#Shows Estimated Halt High or Halt Low
################ Inputs (choose what you want to display)
Input showPriorclose = yes;
Input showFiveMinutePrice = yes;
Input showHaltHighPlot = yes;
Input showHaltLowPlot = yes;
#input lowLimit = 0.75;
#input highLimit = 3;
################ Prior Close Price
def aggregationPeriod = AggregationPeriod.DAY;
def displace = -1;
def Priorclose =close(period =aggregationPeriod)[-displace];
################ Definitions
def isopen=if secondsFromTime(0945)>=0 and secondstillTime(1535)>=0 then 1 else 0;
#def beforeStart = GetTime() < RegularTradingStart(getYYYYMMDD());
#def isopen=if secondsFromTime(0930)>=0 and secondstillTime(0945)>=0 and secondsFromTime(1535) and secondsTillTime(1600) then 1 else 0;
def FiveMinPrice = close(period = AggregationPeriod.min)[5];
Def HaltHigh = (if isopen then FiveMinPrice * 1.10 else FiveMinPrice *1.20);
Def HaltLow = if isopen then FiveMinPrice / 1.10 else FiveMinPrice /1.20;
Def HaltHighBetween = (if isopen and priorclose between .75 and 3 then FiveMinPrice * 1.20 else FiveMinPrice *1.40);
Def HaltLowBetween = if isopen and priorclose between .75 and 3 then FiveMinPrice / 1.20 else FiveMinPrice /1.40;
Def HaltHighUnder = if isopen and priorclose is less than 0.75 then FiveMinPrice * 1.75 else FiveMinPrice *2.5;
Def HaltLowUnder = if isopen and priorclose <= 0.75 then FiveMinPrice / 1.75 else FiveMinPrice /2.5;
Def HaltHigh15 = if isopen and priorclose <= 0.75 then fiveMinPrice + 0.15 else fiveMinPrice + 0.30;
Def HaltLow15 = if isopen and priorclose <= 0.75 then fiveMinPrice - 0.15 else fiveMinPrice - 0.30;
################ Labels & Plots
Addlabel (showPriorclose, + Priorclose, color.dark_GRAY);
Addlabel (ShowFiveMinutePrice, + FiveMinPrice, color.DaRK_GRAY);
Addlabel (Priorclose >=3, HaltHigh, color.light_GREEN);#For stocks over $3
#Addlabel (yes, HaltHigh, color.light_GREEN);
Addlabel (Priorclose between 0.75 and 3, HaltHighBetween, color.light_GREEN);#For stocks between .75-3
Addlabel (Priorclose between 0.75 and 3, HaltLowBetween, color.pink);#For stocks between .75-3
Addlabel (Priorclose >=3, HaltLow, color.pINK); #Fors stocks over $3
#Addlabel (Priorclose <=0.75, HaltHighUnder, color.light_Green); #Fors stocks under .75
Addlabel (Priorclose <=0.75, if HaltHighUnder > HaltHigh15 then HaltHigh15 else haltHighUnder, color.light_Green); #Stocks under .75
#Addlabel (Priorclose <=0.75, HaltLowUnder, color.pINK); #Fors stocks under .75
Addlabel (Priorclose <=0.75, if HaltLowUnder < HaltLow15 then HaltLow15 else haltLowUnder, color.pink);#Stocks Under .75 ###check
#Addlabel (yes, HaltLow, color.pINK);
plot HHighOver3 = if ShowHalthighPlot > 0 and Priorclose >=3 then Halthigh else Double.NaN;
plot HLowOver3 = if ShowHaltLowPlot > 0 and Priorclose >=3 then HaltLow else Double.NaN;
plot HhighBEtween = if ShowhaltHighPlot > 0 and between(PriorClose, .75, 3) then HaltHighBetween else Double.NaN;
#plot HHighBetween = if ShowhaltHigh > 0 and priorclose >= lowLimit and priorclose <= highLimit then HaltHighBetween else Double.NaN;
plot HLowBEtween = if ShowhaltLowPlot > 0 and between(PriorClose, .75, 3) then HaltLowBetween else Double.NaN;
#plot HHighUnder = if ShowhaltHighPlot > 0 and Priorclose <= .75 then HaltHighUnder else Double.NaN;
plot HHighUnder = if ShowhaltHighPlot > 0 and Priorclose <= 0.75 then Min(HaltHighUnder, HaltHigh15) else Double.NaN;
#plot HLowUnder = if ShowhaltLowPlot > 0 and Priorclose <= 0.75 then HaltLowUnder else Double.NaN;
plot HLowUnder = if ShowhaltLowPlot > 0 and Priorclose <= 0.75 then Max(HaltLowUnder, HaltLow15) else Double.NaN;###Check
############

It only works on a 1 minute chart, because of limitations with the aggregation period. I don't know if there's a different way to find out the price for 5 minutes ago on other chart time periods. but if anyone knows how I can try to implement it.

By default it shows yesterday's close price, and the close price from 5 mins ago. These can be turned off. It has an upper and lower halt indicator in light green and pink, It also shows an upper/lower Plot by default, which can also be turned off individually. Just because the price touches or overlaps the halt price does not mean the stock will halt, it has to stay at that level for 15 seconds. Also the stock may halt if there's huge volatility between the bid and the ask. This Indicator only compares the close price 5 mins ago to the current price, so it's only a guideline (though it should be pretty accurate). This indicator will not work for tier 1 stocks, though I don't think this is too necessary because they rarely have Volatility Halts. I may try to implement a daily average volume parameter that factors the lower 5/10% for tier 1 stocks at a later date, but its low priority for me because I rarely trade them.

This Indicator does take into account the first 15 minutes of the day and the last 25 minutes, and increases the ranges respectively. It also factors in the price (over $3, Between .75-3 and under .75) and will do the lesser of either 15/30 cents or 75%/150% for stocks under .75. It does continue to show the Halt prices, and plots for Premarket and Post market although there are no halts during this time. I will try to implement a toggle to disable for Aftermarket hours.

I have no idea the characteristics of the Halt indicator during the first 5 minutes of market open. I'm not sure how the SEC handles it either... (is it based on Open price or premarket prices? This indicator will be based on premarket data. Though Im sure it could be adapted if it needs different data during this period. Anyway, if you have any questions, tips, or notice any bugs or odd behavior feel free to let me know.

4toouVl.png
Is there an updated version of the V2 script? I'm getting an exception when trying to load the shared item. It's saying there are unsupported characters in the name.
 
Is there an updated version of the V2 script? I'm getting an exception when trying to load the shared item. It's saying there are unsupported characters in the name.
When saving the shared item; change the name to anything without spaces or dashes; as they are "unsupported characters"
 

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

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
482 Online
Create Post

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