Unusual ATR + PA Bull Hunter For ThinkOrSwim

KevBot

New member
VIP
Nh8Kzso.png


//=========================================================
// THIS CHART ALERTS YOU WHEN
// ATR and PRICE-ACTION are RISING,
// (AND) THE ATR CROSSES FROM ITS LOWER-to-UPPER 'NORMAL 2-WEEK RANGE'
// AND THIS CHART MAKES IT EASY TO SEE IT ALL HAPPEN
//=========================================================

I am a scalp-trader mostly, and I run this on a 1-Min / 1-Day chart....

I have found it pairs well with the AsGoodAsItGets indicator packet, and of course BuyTheDip... and the other premiere indicators on this site.

you can find those here: https://usethinkscript.com/threads/agaig-daytrading-scalping-for-success-in-thinkorswim.20383/

NOTE: ONLY USE THIS INDICATOR TO (HELP CONFIRM), NOT AS A STANDALONE

ToS SHARED LINK (Try it out!) : http://tos.mx/!doyPvgbf
1745818868680.png

BACKGROUND: Came up with this new ToS Chart for myself, and thought I'd share it with you all here. I'm a programmer by trade and for years now I have enjoy trying out new scripts ideas in ToS. A friend of mine and I have been talking a lot about ATR and Price-Action strategies as of late.
Anyways, here's what I have so far. Much like it's creator, its a work in progress.

Enjoy.

CONCEPT GOAL: Develop 'One chart' that does all the following, while keeping it easy to read and use.
1) Plots the ATR, and color code it by its behavior versus its Price-Action

2) Display the '2-WEEK NORMAL RANGE' as a cloud behind the ATR plot (LIGHT GREY)

3) Display the '4-WEEK NORMAL RANGE' as a cloud behind the ATR plot (MEDIUM GREY)

4) [TOP BAR] Colored Label to show the 'Current BULLISH/BEARISH State', and for 'How Many Candles' it has been in that state.

5. [TOP BAR] Two 'White or Grey' Labels; Current 2-WEEK and 4-WEEK NORMAL RANGE position of the ATR

6) Add a VERY STRONG BUY INDICATOR represented by a vertical green-line.
This line only appears when the current BULL/BEAR state is 'STRONG BULLISH' and...
the ATR has moved from the LOW NORMAL 2-WEEK RANGE, into the UPPER NORMAL 2-WEEK RANGE.

(*** You might say this Very Strong Indicator is the not-so secret sauce of this chart.)



ATR BehaviorPrice BehaviorSignalMeaning
ATR risingPrice risingBullish confirmationStrong bullish trend
ATR risingPrice fallingBearish confirmationStrong bearish trend
ATR fallingPrice risingWeak bullish moveUptrend losing strength
ATR fallingPrice fallingWeak bearish moveDowntrend losing strength
  • DARK_GREENWeak Bullish (Price ↑, ATR ↓)
  • GREENStrong Bullish (Price ↑, ATR ↑)
  • DARK_REDWeak Bearish (Price ↓, ATR ↓)
  • REDStrong Bearish (Price ↓, ATR ↑)

//=========================================================
// BELOW IVE ADDED SOME CONCEPTS FOR ANYONE NOT FAMILIAR
// WITH THE POWER OF ATR + PRICE-ACTION
//=========================================================

Rising Price + Rising ATR🔵 Bullish Strength
  • Stock price is going UP.
  • ATR is INCREASING (volatility is expanding with the move).
  • This is strong bullish behavior.
Falling Price + Rising ATR🔴 Bearish Strength
  • Stock price is going DOWN.
  • ATR is INCREASING (bigger candles as it falls).
  • This is strong bearish behavior.
Rising Price + Falling ATR⚪ Weak Bullish Move
  • Price is going up... but ATR is FALLING.
  • The move up is losing energy (warning sign for bulls).
Falling Price + Falling ATR⚪ Weak Bearish Move
  • Price is dropping but ATR is also FALLING.
  • The downtrend is running out of gas (warning sign for bears).
mod note:
Scroll down to next post for Scan and Watchlist Scripts
Here is the code for the Lower Chart Indicator:
Code:
declare lower;

# Settings
input atrLength = 14;              # ATR calculation length
input priceLength = 5;             # Price movement lookback
input regionLookbackShort = 14;    # Short-term ATR region (14 bars)
input regionLookbackLong = 30;     # Long-term ATR region (30 bars)
input showEveryNCandles = 1;       # Show label every N candles

# Calculate ATR
def ATR = Average(TrueRange(high, close, low), atrLength);

# Calculate Price and ATR Change
def priceChange = close - close[priceLength];
def atrChange = ATR - ATR[priceLength];

# Find historical High/Low for Short-Term (14 bars)
def ATRHighShort = Highest(ATR, regionLookbackShort);
def ATRLowShort = Lowest(ATR, regionLookbackShort);
def ATRMidShort = (ATRHighShort + ATRLowShort) / 2;

# Find historical High/Low for Long-Term (30 bars)
def ATRHighLong = Highest(ATR, regionLookbackLong);
def ATRLowLong = Lowest(ATR, regionLookbackLong);
def ATRMidLong = (ATRHighLong + ATRLowLong) / 2;

# --- Fill the ATR Regions Only (no visible boundary lines) ---
AddCloud(ATRHighShort, ATRLowShort, Color.WHITE, Color.WHITE);
AddCloud(ATRHighLong, ATRLowLong, Color.LIGHT_GRAY, Color.LIGHT_GRAY);

# --- Price and ATR Behavior Logic ---
def isStrongBullish = priceChange > 0 and atrChange > 0;
def isWeakBullish = priceChange > 0 and atrChange <= 0;
def isStrongBearish = priceChange < 0 and atrChange > 0;
def isWeakBearish = priceChange < 0 and atrChange <= 0;

# Define ATR State
def ATRState =
    if isStrongBullish then 1
    else if isWeakBullish then 2
    else if isStrongBearish then 3
    else if isWeakBearish then 4
    else 0;

# --- Track How Long ATR Has Been in Current State ---
def ATRStateChange = ATRState != ATRState[1];
def ATRStateCount = if ATRStateChange then 1 else ATRStateCount[1] + 1;

# --- ATR Colored Plot ---
plot ColoredATR = ATR;
ColoredATR.AssignValueColor(
    if isStrongBullish then Color.GREEN
    else if isWeakBullish then Color.DARK_GREEN
    else if isStrongBearish then Color.RED
    else if isWeakBearish then Color.DARK_RED
    else Color.GRAY
);
ColoredATR.SetLineWeight(2);

# --- New: Zero Line for Labels ---
plot ZeroLine = if IsNaN(close) then Double.NaN else 0;
ZeroLine.AssignValueColor(
    if isStrongBullish then Color.GREEN
    else if isWeakBullish then Color.DARK_GREEN
    else if isStrongBearish then Color.RED
    else if isWeakBearish then Color.DARK_RED
    else Color.GRAY
);
ZeroLine.SetLineWeight(5);
ZeroLine.SetStyle(Curve.SHORT_DASH);

# --- Place Only NUMBER at Zero Line ---
AddLabel(
    ATRStateCount % showEveryNCandles == 0,
    ATRStateCount,
    if isStrongBullish then Color.GREEN
    else if isWeakBullish then Color.DARK_GREEN
    else if isStrongBearish then Color.RED
    else if isWeakBearish then Color.DARK_RED
    else Color.GRAY
);

# --- Label 1: ATR Behavior Label (with candles count) ---
AddLabel(yes,
    (if isStrongBullish then "ATR is STRONG BULLISH "
    else if isWeakBullish then "ATR is WEAK BULLISH "
    else if isStrongBearish then "ATR is STRONG BEARISH "
    else if isWeakBearish then "ATR is WEAK BEARISH "
    else "ATR is NEUTRAL ")
    + "(for " + ATRStateCount + " candles)",
    if isStrongBullish then Color.GREEN
    else if isWeakBullish then Color.DARK_GREEN
    else if isStrongBearish then Color.RED
    else if isWeakBearish then Color.DARK_RED
    else Color.GRAY
);

# --- Label 2: ATR Position in Short-Term Historical Range (14 days) ---
AddLabel(yes,
    if ATR >= ATRMidShort then "ATR in UPPER 2-Week Range"
    else "ATR in LOWER 2-Week Range",
    if ATR >= ATRMidShort then Color.WHITE
    else Color.GRAY
);

# --- Label 3: ATR Position in Long-Term Historical Range (30 days) ---
AddLabel(yes,
    if ATR >= ATRMidLong then "ATR in UPPER 4-Week Range"
    else "ATR in LOWER 4-Week Range",
    if ATR >= ATRMidLong then Color.WHITE
    else Color.GRAY
);

# --- Signal when ATR becomes Strong Bullish and crosses into Upper Half ---
def strongBullishInUpperHalfNow = isStrongBullish and ATR >= ATRMidShort;
def wasNotInUpperHalfBefore = ATR[1] < ATRMidShort;
def triggerStrongBullishTransition = strongBullishInUpperHalfNow and wasNotInUpperHalfBefore;

# --- Track when the last trigger happened ---
def lastBullishBar = if triggerStrongBullishTransition then BarNumber() else lastBullishBar[1];

# --- How many bars ago was the last bullish trigger? ---
def barsSinceLastBullish = BarNumber() - lastBullishBar;

# --- Control how long the vertical line is visible ---
input fadeAfterBars = 4; # <-- Line "fades out" after 20 bars (adjust as you want)

# --- Add Vertical Line only if recent enough ---
AddVerticalLine(
    barsSinceLastBullish <= fadeAfterBars and triggerStrongBullishTransition,
    "    ",
    Color.GREEN,
    Curve.SHORT_DASH
);
 
Last edited by a moderator:
ATR PRICE BULL SCAN
Code:
#ATR_PRICE_BULL_SCAN
input atrLength = 14;
def priceUp = close > close[1];
def atr = Average(TrueRange(high, close, low), atrLength);
def atrUp = atr > atr[1];
plot scan = priceUp and atrUp;

ATR PRICE BEAR SCAN
Code:
#ATR_PRICE_BEAR_SCAN
input atrLength = 14;
def priceDown = close < close[1];
def atr = Average(TrueRange(high, close, low), atrLength);
def atrUp = atr > atr[1];
plot scan = priceDown and atrUp;

mod note:
ATR Price Watchlist
Code:
#ATR Price Watchlist

# Settings
input atrLength = 14;              # ATR calculation length
input priceLength = 5;             # Price movement lookback
input regionLookbackShort = 14;    # Short-term ATR region (14 bars)
input regionLookbackLong = 30;     # Long-term ATR region (30 bars)
input showEveryNCandles = 1;       # Show label every N candles

# Calculate ATR
def ATR = Average(TrueRange(high, close, low), atrLength);

# Calculate Price and ATR Change
def priceChange = close - close[priceLength];
def atrChange = ATR - ATR[priceLength];

# Find historical High/Low for Short-Term (14 bars)
def ATRHighShort = Highest(ATR, regionLookbackShort);
def ATRLowShort = Lowest(ATR, regionLookbackShort);
def ATRMidShort = (ATRHighShort + ATRLowShort) / 2;

# Find historical High/Low for Long-Term (30 bars)
def ATRHighLong = Highest(ATR, regionLookbackLong);
def ATRLowLong = Lowest(ATR, regionLookbackLong);
def ATRMidLong = (ATRHighLong + ATRLowLong) / 2;

# --- Price and ATR Behavior Logic ---
def isStrongBullish = priceChange > 0 and atrChange > 0;
def isWeakBullish = priceChange > 0 and atrChange <= 0;
def isStrongBearish = priceChange < 0 and atrChange > 0;
def isWeakBearish = priceChange < 0 and atrChange <= 0;

# Define ATR State
def ATRState =
    if isStrongBullish then 1
    else if isWeakBullish then 2
    else if isStrongBearish then 3
    else if isWeakBearish then 4
    else 0;

# --- Track How Long ATR Has Been in Current State ---
def ATRStateChange = ATRState != ATRState[1];
def ATRStateCount = if ATRStateChange then 1 else ATRStateCount[1] + 1;

AddLabel(yes,
    if isStrongBullish then "Bullish" 
    else if isWeakBullish then "WeakBullish"
    else if isStrongBearish then "Bearish"
    else if isWeakBearish then "WeakBearish" else "Null",
    if isStrongBullish then Color.GREEN
    else if isWeakBullish then Color.DARK_GREEN
    else if isStrongBearish then Color.RED
    else if isWeakBearish then Color.DARK_RED
    else Color.GRAY);
1745900322122.png
 
Last edited by a moderator:

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