IV Analysis For ThinkOrSwim

antwerks

Well-known member
VIP
VIP Enthusiast
IV is Implied Volatility -
Implied volatility (IV) is the options market’s estimate of how much a stock might move in the future. It is not a direction call. High IV does not mean “stock should go up” or “stock should go down.” It means the market is pricing a larger expected move.

For stock trading, IV matters because it tells you how much uncertainty, event risk, and demand for protection/speculation is embedded in options. Even if you only trade shares, IV helps you judge whether the market is calm, nervous, complacent, or bracing for a catalyst.

The clean way to think about IV: it is the price of uncertainty.

And yes The Linda is my take on LBR 3/10 oscillator - about the same really
Code:
declare lower;

# =========================
# StochasticSlow 4x10 RedCloud - Linda
# ThinkScript Conversion
# =========================

input kLength = 4;
input dSmoothing = 10;

# Calculate %K
def lowestLow  = Lowest(low, kLength);
def highestHigh = Highest(high, kLength);

# Prevent division by zero
def rangea = highestHigh - lowestLow;

def kRaw =
    if rangea != 0 then
        100 * (close - lowestLow) / rangea
    else
        0;

# Wilder smoothing
def kSlow = WildersAverage(kRaw, dSmoothing);
def dLine = WildersAverage(kSlow, dSmoothing);

# =========================
# %D Color Logic
# =========================
plot K = kSlow;
K.SetLineWeight(3);
K.SetDefaultColor(CreateColor(44, 164, 182));

plot D = dLine;
D.SetLineWeight(4);

D.AssignValueColor(
    if dLine > dLine[1]
    then Color.BLUE
    else Color.YELLOW
);

# =========================
# Horizontal Levels
# =========================
plot Level50 = 50;
Level50.SetDefaultColor(Color.WHITE);
Level50.SetLineWeight(2);

plot Level0 = 0;
Level0.SetDefaultColor(Color.BLACK);
Level0.SetLineWeight(2);

# =========================
# CLOUD BETWEEN K & D
# =========================
AddCloud(
    K,
    D,
    Color.GREEN,
    CreateColor(225, 30, 218)
);

# =========================
# RED CLOUD BELOW 50
# when BOTH are below 50
# =========================
AddCloud(
    if dLine < 50 and kSlow < 50 then Level50 else Double.NaN,
    Level0,
    CreateColor(199, 29, 29),
    CreateColor(199, 29, 29)
);

# =========================
# YELLOW CLOUD
# when K < 50 and D >= 50
# =========================
AddCloud(
    if kSlow < 50 and dLine >= 50 then Level50 else Double.NaN,
    Level0,
    Color.YELLOW,
    Color.YELLOW
);

AddCloud(
    if kSlow > 50 and dLine <= 50 then Level50 else Double.NaN,
    Level0,
    Color.VIOLET,
    Color.VIOLET
);

#=========================
# SIMPLE CALL / PUT SIGNALS
#=========================

def D_Blue =
    dLine > dLine[1];

def D_Yellow =
    dLine <= dLine[1];

def RecentBlue =
    D_Blue or D_Blue[1] or D_Blue[2];

def RecentYellow =
    D_Yellow or D_Yellow[1] or D_Yellow[2];

def CallSignal =
    kSlow crosses above dLine and
    RecentBlue;

def PutSignal =
    kSlow crosses below dLine and
    RecentYellow;

AddVerticalLine(
    CallSignal,
    "C",
    Color.LIGHT_GREEN,
    Curve.MEDIUM_DASH
);

AddVerticalLine(
    PutSignal,
    "P",
    Color.LIGHT_RED,
    Curve.MEDIUM_DASH
);

plot CallArrow =
    if CallSignal
    then kSlow
    else Double.NaN;

CallArrow.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
CallArrow.SetDefaultColor(Color.GREEN);
CallArrow.SetLineWeight(3);

plot PutArrow =
    if PutSignal
    then kSlow
    else Double.NaN;

PutArrow.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
PutArrow.SetDefaultColor(Color.RED);
PutArrow.SetLineWeight(3);

#=========================
# LABELS
#=========================

AddLabel(
    yes,
    "K: " + Round(kSlow,1),
    if kSlow > 50 then Color.GREEN else Color.RED
);

AddLabel(
    yes,
    "D: " + Round(dLine,1),
    if dLine > 50 then Color.GREEN else Color.RED
);

AddLabel(
    yes,
    if kSlow > dLine then "MOMENTUM: BULLISH"
    else "MOMENTUM: BEARISH",
    if kSlow > dLine then Color.GREEN else Color.RED
);

AddLabel(
    yes,
    if dLine > dLine[1] then "TREND: IMPROVING"
    else "TREND: WEAKENING",
    if dLine > dLine[1]
    then Color.CYAN
    else Color.YELLOW
);

AddLabel(
    yes,
    if dLine > 50 and kSlow > 50 then "REGIME: BULL"
    else if dLine < 50 and kSlow < 50 then "REGIME: BEAR"
    else "REGIME: TRANSITION",
    if dLine > 50 and kSlow > 50 then Color.GREEN
    else if dLine < 50 and kSlow < 50 then Color.RED
    else Color.ORANGE
);

AddLabel(
    yes,
    if dLine > 50 and kSlow > dLine then "ACTION: BUY PULLBACKS"
    else if dLine < 50 and kSlow < dLine then "ACTION: SELL RALLIES"
    else "ACTION: WAIT",
    if dLine > 50 and kSlow > dLine then Color.GREEN
    else if dLine < 50 and kSlow < dLine then Color.RED
    else Color.GRAY
);

AddLabel(
    yes,
    if dLine > 50 and
       kSlow > dLine and
       dLine > dLine[1]
    then "A+ LONG"

    else if dLine < 50 and
            kSlow < dLine and
            dLine < dLine[1]
    then "A+ SHORT"

    else "NO EDGE",

    if dLine > 50 and
       kSlow > dLine and
       dLine > dLine[1]
    then Color.GREEN

    else if dLine < 50 and
            kSlow < dLine and
            dLine < dLine[1]
    then Color.RED

    else Color.GRAY
);


AddLabel(
    yes,

    if (kSlow - dLine) > 15 then "THRUST: EXTREME BULL"
    else if (kSlow - dLine) > 8 then "THRUST: STRONG BULL"
    else if (kSlow - dLine) > 0 then "THRUST: BULL"
    else if (kSlow - dLine) < -15 then "THRUST: EXTREME BEAR"
    else if (kSlow - dLine) < -8 then "THRUST: STRONG BEAR"
    else if (kSlow - dLine) < 0 then "THRUST: BEAR"
    else "THRUST: NEUTRAL",

    if (kSlow - dLine) > 15 then Color.GREEN
    else if (kSlow - dLine) > 8 then CreateColor(0,200,0)
    else if (kSlow - dLine) > 0 then Color.DARK_GREEN
    else if (kSlow - dLine) < -15 then Color.RED
    else if (kSlow - dLine) < -8 then CreateColor(220,0,0)
    else if (kSlow - dLine) < 0 then Color.DARK_RED
    else Color.GRAY
);

def Braid =
    AbsValue(kSlow - dLine) < 5 and
    AbsValue(kSlow - 50) < 10;

AddLabel(
yes,
if Braid then "BRAID: CONSOLIDATION"
else "",
Color.GRAY
);

#=========================
# DSMA TREND STATE
#=========================

input fastLength = 21;
input slowLength = 55;

def FastDSMA = ExpAverage(close, fastLength);
def SlowDSMA = ExpAverage(close, slowLength);

def Separation = FastDSMA - SlowDSMA;

def RMSBase =
    Sqrt(Average(Sqr(Separation), 50));

def TrendScore =
    if RMSBase != 0
    then Separation / RMSBase
    else 0;

def StrongBull =
    TrendScore > 1.5;

def Bull =
    TrendScore > 0.25 and TrendScore <= 1.5;

def StrongBear =
    TrendScore < -1.5;

def Bear =
    TrendScore < -0.25 and TrendScore >= -1.5;

def Neutral =
    AbsValue(TrendScore) <= 0.25;

AddLabel(
yes,

if StrongBull then "DSMA ACTION: BUY CALLS"
else if Bull then "DSMA ACTION: BUY PULLBACKS"
else if StrongBear then "DSMA ACTION: TREND SHORTS"
else if Bear then "DSMA ACTION: SELL RALLIES"
else "DSMA ACTION: WAIT",

if StrongBull then Color.CYAN
else if Bull then Color.GREEN
else if StrongBear then Color.MAGENTA
else if Bear then Color.RED
else Color.GRAY
);

 
Last edited by a moderator:

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

If you do not have a good IV script here is one I like
Code:
declare lower;

#Antwerks Version V1 ============================================================
# Implied Volatility Plain-English Dashboard
# Swing Trading IV Analyzer
# ============================================================
# Purpose:
# - Shows current implied volatility
# - Estimates IV Rank and IV Percentile
# - Reads IV trend: rising, falling, flat
# - Compares price direction vs IV direction
# - Labels the setup in plain English
# - Estimates expected move over selected days
#
# Notes:
# - Works best on optionable stocks / ETFs.
# - Some symbols may not return clean implied volatility data.
# - IV is annualized, so expected move uses sqrt(days / 365).
# ============================================================

input ivLookback = 252;
input trendLength = 5;
input compressionLookback = 20;
input highIVLevel = 70;
input lowIVLevel = 30;
input expectedMoveDays = 30;
input showIVLine = yes;
input showIVRankLine = yes;
input showMidLine = yes;

def price = close;
def ivRaw = imp_volatility();

# Carry prior value if IV temporarily returns NaN
def iv =
    if !IsNaN(ivRaw) then ivRaw
    else iv[1];

# ============================================================
# IV Rank Style
# Current IV position inside lookback high-low range
# ============================================================

def ivHigh = Highest(iv, ivLookback);
def ivLow = Lowest(iv, ivLookback);
def ivRange = ivHigh - ivLow;

def ivRank =
    if ivRange != 0 then
        100 * (iv - ivLow) / ivRange
    else
        0;

# ============================================================
# IV Percentile Style
# Approximation: percentage of lookback bars where IV was below current IV
# ============================================================

def countBelow =
    fold i = 1 to ivLookback + 1
    with count = 0
    do count + if iv > GetValue(iv, i) then 1 else 0;

def ivPercentile =
    if ivLookback != 0 then
        100 * countBelow / ivLookback
    else
        0;

# ============================================================
# IV Trend and Price Trend
# ============================================================

def ivChange = iv - iv[trendLength];
def priceChange = price - price[trendLength];

def ivRising = ivChange > 0;
def ivFalling = ivChange < 0;
def ivFlat = !ivRising and !ivFalling;

def priceRising = priceChange > 0;
def priceFalling = priceChange < 0;
def priceFlat = !priceRising and !priceFalling;

# ============================================================
# Price / IV Matrix
# This is the core interpretation engine
# ============================================================

def priceUpIVUp = priceRising and ivRising;
def priceUpIVDown = priceRising and ivFalling;
def priceDownIVUp = priceFalling and ivRising;
def priceDownIVDown = priceFalling and ivFalling;

# ============================================================
# Compression / Expansion
# Compare current IV range behavior to prior range behavior
# ============================================================

def currentIVRange =
    Highest(iv, compressionLookback) - Lowest(iv, compressionLookback);

def priorIVRange =
    Highest(iv[compressionLookback], compressionLookback) -
    Lowest(iv[compressionLookback], compressionLookback);

def ivExpansion = currentIVRange > priorIVRange;
def ivCompression = currentIVRange < priorIVRange;

# ============================================================
# Expected Move
# Expected Move = price * IV * sqrt(days / 365)
# ============================================================

def expectedMove =
    price * iv * Sqrt(expectedMoveDays / 365);

def expectedMovePct =
    if price != 0 then
        100 * expectedMove / price
    else
        0;

def upperExpected = price + expectedMove;
def lowerExpected = price - expectedMove;

# ============================================================
# Setup Classification
# ============================================================

def highIV = ivRank >= highIVLevel or ivPercentile >= highIVLevel;
def lowIV = ivRank <= lowIVLevel and ivPercentile <= lowIVLevel;
def midIV = !highIV and !lowIV;

def coiledSetup =
    lowIV and ivCompression;

def eventRiskSetup =
    highIV and ivExpansion;

def premiumCooling =
    highIV and ivFalling;

def premiumBuilding =
    ivRising and ivExpansion;

# ============================================================
# Plots
# ============================================================

plot IVPercent =
    if showIVLine then iv * 100 else Double.NaN;
IVPercent.SetDefaultColor(Color.CYAN);
IVPercent.SetLineWeight(2);

plot IVRankLine =
    if showIVRankLine then ivRank else Double.NaN;
IVRankLine.SetDefaultColor(Color.YELLOW);
IVRankLine.SetLineWeight(2);

plot HighLine = highIVLevel;
HighLine.SetDefaultColor(Color.RED);
HighLine.SetStyle(Curve.SHORT_DASH);

plot LowLine = lowIVLevel;
LowLine.SetDefaultColor(Color.GREEN);
LowLine.SetStyle(Curve.SHORT_DASH);

plot MidLine =
    if showMidLine then 50 else Double.NaN;
MidLine.SetDefaultColor(Color.GRAY);
MidLine.SetStyle(Curve.SHORT_DASH);

# ============================================================
# Labels
# ============================================================

AddLabel(
    yes,
    "IV: " + Round(iv * 100, 1) + "%",
    Color.CYAN
);

AddLabel(
    yes,
    "IV Rank: " + Round(ivRank, 0) + "/100",
    if ivRank >= highIVLevel then Color.RED
    else if ivRank <= lowIVLevel then Color.GREEN
    else Color.YELLOW
);

AddLabel(
    yes,
    "IV Percentile: " + Round(ivPercentile, 0) + "%",
    if ivPercentile >= highIVLevel then Color.RED
    else if ivPercentile <= lowIVLevel then Color.GREEN
    else Color.YELLOW
);

AddLabel(
    yes,
    if ivRising then "IV Trend: Rising"
    else if ivFalling then "IV Trend: Falling"
    else "IV Trend: Flat",
    if ivRising then Color.RED
    else if ivFalling then Color.GREEN
    else Color.GRAY
);

AddLabel(
    yes,
    if ivExpansion then "IV State: Expansion"
    else if ivCompression then "IV State: Compression"
    else "IV State: Neutral",
    if ivExpansion then Color.MAGENTA
    else if ivCompression then Color.GREEN
    else Color.GRAY
);

AddLabel(
    yes,
    if highIV then "Premium: Expensive / Event-Risk Zone"
    else if lowIV then "Premium: Cheap / Coiled Zone"
    else "Premium: Normal / Mid-Range",
    if highIV then Color.RED
    else if lowIV then Color.GREEN
    else Color.YELLOW
);

AddLabel(
    yes,
    if priceUpIVUp then "Matrix: Price Up + IV Up = momentum/speculation, chase risk rising"
    else if priceUpIVDown then "Matrix: Price Up + IV Down = calm advance, fear easing"
    else if priceDownIVUp then "Matrix: Price Down + IV Up = fear/protection demand, respect downside"
    else if priceDownIVDown then "Matrix: Price Down + IV Down = selling orderly or exhaustion possible"
    else "Matrix: Price/IV flat or mixed",
    if priceUpIVUp then Color.MAGENTA
    else if priceUpIVDown then Color.GREEN
    else if priceDownIVUp then Color.RED
    else if priceDownIVDown then Color.ORANGE
    else Color.GRAY
);

AddLabel(
    yes,
    "Expected Move " + expectedMoveDays + "D: +/- $" + Round(expectedMove, 2) +
    " (" + Round(expectedMovePct, 1) + "%)",
    Color.WHITE
);

AddLabel(
    yes,
    "Expected Range: $" + Round(lowerExpected, 2) + " to $" + Round(upperExpected, 2),
    Color.WHITE
);

AddLabel(
    coiledSetup,
    "Setup: Low IV + Compression = potential coiled swing setup",
    Color.GREEN
);

AddLabel(
    eventRiskSetup,
    "Setup: High IV + Expansion = big move priced, avoid casual long premium",
    Color.RED
);

AddLabel(
    premiumCooling,
    "Setup: IV Falling = premium cooling / post-event reset possible",
    Color.GREEN
);

AddLabel(
    premiumBuilding and !highIV,
    "Setup: IV Rising From Base = movement expectations building",
    Color.MAGENTA
);

AddLabel(
    priceDownIVUp,
    "Posture: Defensive / failed-bounce shorts get cleaner",
    Color.RED
);

AddLabel(
    priceUpIVDown,
    "Posture: Bullish repair / cleaner for shares or longer-dated calls",
    Color.GREEN
);

AddLabel(
    priceUpIVUp and highIV,
    "Posture: Momentum hot but options may be overpriced",
    Color.MAGENTA
);

AddLabel(
    priceUpIVUp and !highIV,
    "Posture: Early expansion, bullish if price structure confirms",
    Color.GREEN
);

AddLabel(
    priceDownIVDown,
    "Posture: Do not assume panic; downside pressure may be cooling",
    Color.ORANGE
);

***** Just a note -Reason: implied volatility is quoted as annualized calendar-year volatility, not trading-day volatility. Options decay and event risk exist over weekends and holidays, so the market’s IV convention is usually calendar-day based.

 
Last edited by a moderator:
Oh yes, Mikey likes your take on the LBR 3/1)! And, thanks for the quick response to my ?'s.

.....I just saw your next post with the incredible graphic, and I think Ive figured it out....You are a different breed of human.....the AMAZING ONE! What's this site's version of the Heisman Trophy?
 
@antwerks - Have you ever created a scan using your 'Linda' indicator in a crossover Bullish/Bearish approach?
Code:
def lowestLow = Lowest(low, 4);
def highestHigh = Highest(high, 4);
def rangea = highestHigh - lowestLow;

def kRaw =
    if rangea != 0
    then 100 * (close - lowestLow) / rangea
    else 0;

def kSlow = WildersAverage(kRaw, 10);
def dLine = WildersAverage(kSlow, 10);

plot scan =
    dLine > dLine[1] and
    dLine[1] <= dLine[2];
 
@antwerks - Have you ever created a scan using your 'Linda' indicator in a crossover Bullish/Bearish approach?
Code:
input emaFastLen = 8;
input emaSlowLen = 20;
input atrLen = 14;
input emaSlopeSmooth = 3;

input repairLookback = 10;
input repairMinLowerWickPct = 0.30;
input repairMinBodyPct = 0.25;
input repairMaxDistanceBelow21ATR = 1.50;
input repairRequireCloseAbovePriorHigh = no;

def price = close;

def emaFast = ExpAverage(price, emaFastLen);
def emaSlow = ExpAverage(price, emaSlowLen);

def tr = TrueRange(high, close, low);
def atrRaw = Average(tr, atrLen);
def atr = if atrRaw != 0 then atrRaw else 0.0001;

def emaFastSlope =
    (emaFast - emaFast[emaSlopeSmooth]) / atr;

def recentRangeLow =
    low <= Lowest(low[1], repairLookback);

def candleRange =
    high - low;

def candleBody =
    AbsValue(close - open);

def repairBodyPct =
    if candleRange != 0 then candleBody / candleRange else 0;

def lowerWick =
    Min(open, close) - low;

def lowerWickPct =
    if candleRange != 0 then lowerWick / candleRange else 0;

def closeOffLow =
    if candleRange != 0 then
        (close - low) / candleRange >= 0.65
    else
        no;

def bullishRepairCandle =
    close > open and
    repairBodyPct >= repairMinBodyPct and
    closeOffLow;

def bullishWickRejection =
    lowerWickPct >= repairMinLowerWickPct and
    closeOffLow;

def closeAbovePriorHigh =
    close > high[1];

def priorHighOK =
    if repairRequireCloseAbovePriorHigh then closeAbovePriorHigh else yes;

def notTooFarBelow21 =
    close >= emaSlow - atr * repairMaxDistanceBelow21ATR;

def downsideMomentumStalling =
    emaFastSlope > emaFastSlope[1];

plot scan =
    recentRangeLow and
    notTooFarBelow21 and
    downsideMomentumStalling and
    priorHighOK and
    (
        bullishRepairCandle or
        bullishWickRejection or
        closeAbovePriorHigh
    );
 
@antwerks - Have you ever created a scan using your 'Linda' indicator in a crossover Bullish/Bearish approach?
Code:
input emaFastLen = 8;
input emaSlowLen = 20;
input atrLen = 14;
input emaSlopeSmooth = 3;
input reclaimLookback = 3;

def price = close;

def emaFast = ExpAverage(price, emaFastLen);
def emaSlow = ExpAverage(price, emaSlowLen);

def atr = Average(TrueRange(high, close, low), atrLen);
def validATR = if atr != 0 then atr else 0.0001;

def emaFastSlope =
    (emaFast - emaFast[emaSlopeSmooth]) / validATR;

def emaSlowSlope =
    (emaSlow - emaSlow[emaSlopeSmooth]) / validATR;

def bullishStructure =
    emaFast > emaSlow;

def priceAbove21 =
    close > emaSlow;

def priceAboveFast =
    close > emaFast;

def ema21Rising =
    emaSlowSlope > 0;

def fresh21Reclaim =
    close > emaSlow and
    close[1] <= emaSlow[1];

def recent21Reclaim =
    Highest(
        if fresh21Reclaim then 1 else 0,
        reclaimLookback
    ) > 0;

plot scan =
    bullishStructure and
    recent21Reclaim and
    emaFastSlope > 0 and
    ema21Rising and
    priceAbove21 and
    priceAboveFast;
 
If you get a few minutes, can you give a name/title for the first, second and third scripts for the scans? (sorry I'm a dummy about these things!)
 
Last edited:

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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