Circuit Breaker Halt Indicator for ThinkorSwim

Good afternoon everyone!

Was anyone able to turn this into a scanner to populate stocks that are likely halted or stocks that just got halted?

Thanks
 
Was anyone able to turn this into a scanner to populate stocks that are likely halted or stocks that just got halted?

The Halt Estimate Indicator is consider complex by TOS so I don't think it can be used in a scan. However the other indicator, Halt Length Detector can be used to scan for a halt that has already occured recently. Use it with some minimim volume to filter out results that just have no volume for several minutes. Here is that as a scan:
Code:
# Recently halted Scan by Len20  6/6/20
# (Use with volume minimums to avoid stocks without volume showing up)
# Works on 1 min agregation only

input within_Bars = 3;
input Starttime = 0930;
input Endtime   = 1600;

def Active = SecondsFromTime(Starttime) >= 0 and SecondsTillTime(Endtime)-1 >= 0;
def Today  = GetDay() == GetLastDay();
def Qualifies = Active and Today;
def MinFromStart = rounddown(SecondsFromTime(Starttime)/60,0);
def minutesLastBar = MinFromStart - MinFromStart[1];       #difference in minutes

plot LikelyHalt = (Qualifies and minutesLastBar >= 5) within within_Bars bars;
 
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.
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.

g7bLvLY.png
 
Last edited:
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.

Thanks and thanks for the original script! Exactly, there is now no lower halt during closing hours for stocks under $ .75. I'm glad you posted that image. I noticed a little bug that showed the lower halt as $.01 instead of zero in that circumstance, so I just fixed that and updated the code above.
 
Thanks Wannaspeed and Len20, this is the only solution I found after a couple days of looking. Your effort is appreciated.
 
@Len20 I did Back Testing of your script(Halt Estimator and Length detector) for all the STOCKS that got halted in last 1 week due to LULD and your script works flawlessly. To back test i had to slightly change the script to enable it on historic data (input show_today_only = no) and it worked. Thanks so much for this. If you guys have some ideas that you are not able to execute due to constraints. please share that with me and i know a very good developer who can write the script.
 
@Len20 Excellent job coding. Can you make it just draw 1 horizontal line that goes all the way across chart at the estimated halt area? I understand it would have to be erased and redrawn every minute.

Thank you,
Drkellog
 
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);
Thanks a ton for this Len. Only issue I'm having is it changed my candle colors. Any idea how to change them back to the default red/green without messing up the rest of the script? Thanks
eee39dcc1a9b634cb1b5b88766950f65.png
 
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;
 
Along the same lines, is there an indicator on TOS that might be the equivalent of the "acceptable trade price range" that NASDAQ uses to trigger volatility halts? These halts trigger when the price exceeds the "acceptable trading price range" for a 15-sec period, which is a percentage calculation based on the average price of the previous 5-min trading period.
 
Along the same lines, is there an indicator on TOS that might be the equivalent of the "acceptable trade price range" that NASDAQ uses to trigger volatility halts? These halts trigger when the price exceeds the "acceptable trading price range" for a 15-sec period, which is a percentage calculation based on the average price of the previous 5-min trading period.

@Batman Welcome to the usethinkscript forums... There is no such indicator that I am aware of but you could probably write either a Study or a Scan for Alerts... Don't quote me on this but I think the trigger is a 10% move for the first halt... You'll want to verify on the NASDAQ site to be sure...
 
@Batman Welcome to the usethinkscript forums... There is no such indicator that I am aware of but you could probably write either a Study or a Scan for Alerts... Don't quote me on this but I think the trigger is a 10% move for the first halt... You'll want to verify on the NASDAQ site to be sure...
Thank you! Nice to be here. I posted a similar question in a Reddit group and someone recommended that I try this code as a TOS halt scanner. I'll try it out on Monday and see how it works!

The scanner code, from Redditor Mobius_ts:
secondsFromTime(0935) >= 0 and secondsTillTime(1545) >= 0 and

((highest(close, 5) >= Average(close[5], 5) * 1.05)

or

(lowest(close, 5) <= Average(close[5], 5) * .95))
 
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;
nice name. I go by Rated R 1914 in certain circles #mabties
 
Question. Wouldnt it be easier to code it something like



if(currentVol-3 > 5mil && currentVol-2 == 0 && currentVol-1 == 0){
halted = true;
}

(I know the syntax isnt correct but I only played with php as a kid and dont know what the thinkscript version of this code would look like. And even then I wasnt a php expert but you get the jist I think)

Trying to see if it would read that a stock WAS trading high volume, but then all of the sudden within 2 one minute candles went to zero volume indicating a likely halted situation. I was told on reddit that its not possible to set a dynamic alert such as:

Alert "$ticker may be halted!";

Where it would dynamically insert the ticker that is triggering the conditions.
 
Last edited:
Question. Wouldnt it be easier to code it something like



if(currentVol-3 > 5mil && currentVol-2 == 0 && currentVol-1 == 0){
halted = true;
}

(I know the syntax isnt correct but I only played with php as a kid and dont know what the thinkscript version of this code would look like. And even then I wasnt a php expert but you get the jist I think)

Trying to see if it would read that a stock WAS trading high volume, but then all of the sudden within 2 one minute candles went to zero volume indicating a likely halted situation. I was told on reddit that its not possible to set a dynamic alert such as:

Alert "$ticker may be halted!";

Where it would dynamically insert the ticker that is triggering the conditions.
no, because if there is a halt, there is no trading, there won't be a candle. candles don't exist during a halt. there will be a bigger time gap between candles when 1 shows up.
if you have a 1 min chart, you could check if the time difference from current candle and previous one is 1 min. if more, then possibly a halt. ( after ruling out, very low volume stock and after hours).
 
no, because if there is a halt, there is no trading, there won't be a candle. candles don't exist during a halt. there will be a bigger time gap between candles when 1 shows up.
if you have a 1 min chart, you could check if the time difference from current candle and previous one is 1 min. if more, then possibly a halt. ( after ruling out, very low volume stock and after hours).
Right on. I was asking on another forum if there was a way to count seconds passed since all programming software has a refresh rate to check and see if the curVolume == prevVolume after 120 seconds since it won't read halted candles as zero but they said no. Don't know why ToS would exclude that from their software. Almost seems deliberate
 

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
457 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