Confirmed Contrarian For ThinkOrSwim

justAnotherTrader

Active member
VIP
VIP Enthusiast
The Confirmed Contrarian - a Benchmark Reversion System​

Ok guys, im excited about this one. Honestly this might just be the best indicator I've created to date (might not be saying a whole lot but ya :D). This is my 4th Next-Gen indicator in this series and was actually created almost by accident. I was working to improve the elite performers found here and actually created a whole new indicator with a built in trading system around it. I hope you like it as much as I enjoyed making it (with my chatGPT partner).

The Confirmed Contrarian is a simple, visual trade execution framework designed to help you:
  • Buy fundamentally strong stocks when they’re stretched to the downside
  • Fade overheated runners when they’ve statistically overextended
  • Stay out of chop when no real edge is present

It uses Z-score-based mean reversion logic, paired with RSI, relative volume, and your choice of benchmark ETF (SPY, QQQ, etc.).

🔧 How It Works
The system calculates:
  • Cumulative Relative Strength: Measures your stock vs an ETF (like QQQ)
  • Z-Score: Tracks how far the stock has drifted from the normal relative relationship
  • Rolling Bands: Based on standard deviation (like Bollinger logic but for relative performance)
  • RSI: Confirms overbought/oversold context
  • Relative Volume: Confirms that the market is actually stepping in

When these conditions align, you get:
  • Buy arrows on strong reversion setups (Z < -1.5, RSI < 40, high relative volume)
  • Sell arrows when the stock is statistically extended (Z > +1.5, RSI > 60, high volume)
  • Contextual labels to give you the Z-score, RSI, volume strength, and entry confidence at a glance

🧠 Interpretation Labels
LabelMeaning
RelStrength ZTells you how far from "normal" the move is
RSIClassic overbought/oversold zone reference
Volume ConfirmsConfirms if action is backed by buyers/sellers
Buy/Sell Setup ConfirmedOnly lights up when all signals align
Z Sentiment ZoneInterprets Z-score into plain language like:
“Fade or Take Profits”, “Watch for Bottoming”, “Get Ready for Bounce”
Accumulation / DistributionShows if the market is likely rotating out or in at extremes


🧭 Designed For Traders Who:
  • Already do research and believe in the stock
  • Just want a clean, non-chasey entry system
  • Prefer volume-backed mean reversion over prediction
  • Want something visual, simple, and execution-focused


Check this out:
psT2FGV.png


The Case Study: The highlighted bubble on the chart represents a local bottom for ENPH. If you look at the slope line on volume it shows that volume was slowing down after the sell of. Continue down to the indicator and you will see that the price was extremely down relative to the benchmark, which I chose as SMH since it is a solar ETF. You currently, as of 5/4/2025 have a similar setup on ENPH right now so keep your eyes on it and see how it responds.

Code:
declare lower;

# === Inputs ===
input marketETF = {default "SPY", "QQQ", "DIA", "IWM", "TAN", "XLK", "XLF", "SMH"};
input lookback = 20;
input thresholdMult = 1.5;
input rsiLength = 14;
input rsiOversold = 40;
input rsiOverbought = 60;
input volLength = 20;
input relVolHigh = 1.5;
input relVolLow = 0.8;
input showLabels = yes;
input showArrows = yes;
input showThresholds = yes;
input useVolumeFilter = no;
input volumeMultiplier = 1.2;
input useTrendFilter = no;
input trendLength = 21;

# === Fetch ETF Close ===
def etfClose =
       if marketETF == marketETF."SPY" then close("SPY")
    else if marketETF == marketETF."QQQ" then close("QQQ")
    else if marketETF == marketETF."DIA" then close("DIA")
    else if marketETF == marketETF."IWM" then close("IWM")
    else if marketETF == marketETF."TAN" then close("TAN")
    else if marketETF == marketETF."XLK" then close("XLK")
    else if marketETF == marketETF."XLF" then close("XLF")
    else if marketETF == marketETF."SMH" then close("SMH")
    else Double.NaN;

def safeETF = if !IsNaN(etfClose) and etfClose != 0 then etfClose else close;

# === Relative Return Logic ===
def stockReturn = close / close[1] - 1;
def etfReturn = safeETF / safeETF[1] - 1;
def relReturn = stockReturn - etfReturn;

def cumStrength = Sum(relReturn, lookback);

plot CumRelStrength = cumStrength;
CumRelStrength.AssignValueColor(if cumStrength > 0 then Color.GREEN else if cumStrength < 0 then Color.RED else Color.GRAY);
CumRelStrength.SetLineWeight(2);

# === Rolling Bands (Standard Deviation-Based) ===
def stdev = StDev(cumStrength, lookback);
plot UpperThresh = if showThresholds then thresholdMult * stdev else Double.NaN;
plot LowerThresh = if showThresholds then -thresholdMult * stdev else Double.NaN;
UpperThresh.SetDefaultColor(Color.LIGHT_GREEN);
LowerThresh.SetDefaultColor(Color.PINK);
UpperThresh.SetStyle(Curve.LONG_DASH);
LowerThresh.SetStyle(Curve.LONG_DASH);

plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.LIGHT_GRAY);

# === Z-Score ===
def mean = Average(cumStrength, lookback);
def zScore = if stdev != 0 then (cumStrength - mean) / stdev else 0;

# === RSI and Relative Volume ===
def rsi = RSI(length = rsiLength);
def avgVol = Average(volume, volLength);
def relVol = if avgVol != 0 then volume / avgVol else 0;

# === Optional Filters ===
def volFilter = if useVolumeFilter then volume > avgVol * volumeMultiplier else 1;
def trend = ExpAverage(close, trendLength);
def slope = trend - trend[1];
def trendFilter = if useTrendFilter then slope > 0 else 1;
def showSignal = volFilter and trendFilter;

# === Reversion Buy/Sell Logic ===
def buySignal = zScore < -1.5 and rsi < rsiOversold and relVol > relVolHigh;
def sellSignal = zScore > 1.5 and rsi > rsiOverbought and relVol > relVolHigh;

# === Arrows ===
plot UpArrow = if showArrows and showSignal and buySignal then cumStrength else Double.NaN;
UpArrow.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
UpArrow.SetDefaultColor(Color.GREEN);
UpArrow.SetLineWeight(3);

plot DownArrow = if showArrows and showSignal and sellSignal then cumStrength else Double.NaN;
DownArrow.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
DownArrow.SetDefaultColor(Color.RED);
DownArrow.SetLineWeight(3);

# === Labels ===
AddLabel(showLabels,
    "RelStrength Z: " + Round(zScore, 2),
    if zScore < -1.5 then Color.GREEN else if zScore > 1.5 then Color.RED else Color.GRAY
);

AddLabel(showLabels,
    "RSI: " + Round(rsi, 1),
    if rsi < rsiOversold then Color.GREEN else if rsi > rsiOverbought then Color.RED else Color.GRAY
);

AddLabel(showLabels,
    if relVol > relVolHigh then "Volume Confirms"
    else if relVol < relVolLow then "Volume Weak"
    else "Neutral Volume",
    if relVol > relVolHigh then Color.GREEN else if relVol < relVolLow then Color.ORANGE else Color.GRAY
);

AddLabel(showLabels,
    if buySignal then "Buy Setup Confirmed"
    else if sellSignal then "Sell Setup Confirmed"
    else "No Setup",
    if buySignal then Color.CYAN else if sellSignal then Color.PINK else Color.DARK_GRAY
);

AddLabel(showLabels,
    if zScore > 2 then "Fade or Take Profits"
    else if zScore > 1.5 then "Watch for Buyer Exhaustion"
    else if zScore > 0.5 then "Trail Stop"
    else if zScore > -0.5 then "Neutral"
    else if zScore > -1.5 then "Watch for Bottoming"
    else if zScore > -2 then "Watch for Seller Exhaustion"
    else "Get Ready for Bounce",
 
    if zScore > 2 then Color.RED
    else if zScore > 1.5 then Color.ORANGE
    else if zScore > 0.5 then Color.YELLOW
    else if zScore > -0.5 then Color.GRAY
    else if zScore > -1.5 then Color.LIGHT_GREEN
    else if zScore > -2 then Color.GREEN
    else Color.DARK_GREEN
);

AddLabel(showLabels and (zScore > 1.5 or zScore < -1.5),
    if zScore > 1.5 then "Distribution"
    else "Accumulation",
    if zScore > 1.5 then Color.RED else Color.GREEN
);
 
Last edited by a moderator:

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

Thread starter Similar threads Forum Replies Date
W Laguerre True Range For ThinkOrSwim Custom 0
Ajordan930 Previous Day High Low Rectangle For ThinkOrSwim Custom 0
justAnotherTrader Energy Momentum EMA For ThinkOrSwim Custom 0
justAnotherTrader Next Gen Volume Momentum Oscillator For ThinkOrSwim Custom 0
justAnotherTrader ElitePerformers For ThinkOrSwim Custom 4

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
328 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