IV Label

cdmdgcex

New member
I am looking for a label that will show me what category the IV currently sits. I use a system of IV 1-5 and how i get this is by taking the 52 week historical volatility high and low. I then subtract the low from the high for the difference. I then divide that by 5. I take that number and add it to the 52 week, everything, if current IV is between the 52 week low and said number then my IV is 1.

Below is an example of historical volatility high being 150 and historical volatility low being 50. Current IV is 78 so my IV level would be 2.

150-50=100
100/5=20
IV 1 is between 50 and 70
IV 2 is between 71 and 90
IV 3 is between 91 and 110
IV 4 is between 111 and 130
IV 5 is between 131 and 150
 
Solution
I updated the study to show prior year implied volatility rather than historical volatility. I've learned that historical volatility shows actual volatility performance, whereas the prior year implied volatility shows where the IV was in the prior year. Comparing to either would be helpful I believe - so I re-arranged this code to show PY ImpVol rather than Historical Volatility, and it's below.

Edit: Updated to work on all charts above the daily. Will not work on intraday due to ThinkOrSwim's limit of 2,000 prior periods.

Code:
declare lower;
input showClouds = yes;

# ---- Plotting Current Year Implied Volatility (IV) ----
plot ImpVol = imp_volatility(symbol = GetUnderlyingSymbol());
ImpVol.SetDefaultColor(Color.CYAN)...
This is what I've thrown together. I think it will be really interesting to see if there's a way to get ToS to return the actual normal distribution percentile, which I think would be the most accurate way to go about it. Will have to play around with it some more.

Code:
declare lower;
input ShowClouds = yes;

# ---- Historical Volatility Code ----
input length = 20;
input basis = {default Annual, Monthly, Weekly, Daily};

def ap = GetAggregationPeriod();

Assert(ap >= AggregationPeriod.MIN, "Study can only be calculated for time-aggregated charts: " + ap);

def barsPerDay = (RegularTradingEnd(GetYYYYMMDD()) - RegularTradingStart(GetYYYYMMDD())) / ap;
def barsPerYear =
    if ap > AggregationPeriod.WEEK then 12
    else if ap == AggregationPeriod.WEEK then 52
    else if ap >= AggregationPeriod.DAY then 252 * AggregationPeriod.DAY / ap
    else 252 * barsPerDay;

def basisCoeff;
switch (basis) {
case Annual:
    basisCoeff = 1;
case Monthly:
    basisCoeff = 12;
case Weekly:
    basisCoeff = 52;
case Daily:
    basisCoeff = 252;
}

def clLog = Log(close / close[1]);
def HV = StDev(clLog, length) * Sqrt(barsPerYear / basisCoeff * length / (length - 1));
#HV.SetDefaultColor(Color.CYAN);

def HVHIGH = Highest(data = HV, length = 252);
#HVHIGH.SetDefaultColor(Color.RED);

def HVLOW = Lowest(HV, 252);
#HVLOW.SetDefaultColor(Color.DARK_GREEN);

def Difference = (HVHIGH - HVLOW) / 5;

# ---- Plotting IV Levels ----
plot HV1to2 = HVLOW + (Difference * 1);
plot HV2to3 = HVLOW + (Difference * 2);
plot HV3to4 = HVLOW + (Difference * 3);
plot HV4to5 = HVLOW + (Difference * 4);
HV1to2.SetDefaultColor(Color.WHITE);
HV2to3.SetDefaultColor(Color.WHITE);
HV3to4.SetDefaultColor(Color.WHITE);
HV4to5.SetDefaultColor(Color.WHITE);
HV1to2.SetStyle(Curve.SHORT_DASH);
HV2to3.SetStyle(Curve.SHORT_DASH);
HV3to4.SetStyle(Curve.SHORT_DASH);
HV4to5.SetStyle(Curve.SHORT_DASH);

# ---- Clouds ---
AddCloud(If showclouds then HVLOW else Double.NaN, if showclouds then HV1to2 else Double.NaN, Color.GREEN, Color.GREEN);
AddCloud(if showclouds then HV1to2 else Double.NaN, if showclouds then HV2to3 else double.nan, Color.LIGHT_GREEN, Color.LIGHT_GREEN);
AddCloud(If showclouds then HV2to3 else Double.NaN, if showclouds then HV3to4 else double.nan, Color.YELLOW, Color.YELLOW);
AddCloud(if showclouds then HV3to4 else Double.naN, if showclouds then HV4to5 else double.nan, Color.PINK, Color.PINK);
AddCloud(if showclouds then HV4to5 else Double.nan, if showclouds then HVHIGH else double.nan, Color.DOWNTICK, Color.DOWNTICK);

# ---- Current Implied Volatility  ----
plot ImpVol = imp_volatility(symbol = GetUnderlyingSymbol());
ImpVol.SetDefaultColor(Color.CYAN);
ImpVol.SetLineWeight(3);
AddLabel(1,"Current IV: " + ROUND(ImpVol,4) * 100 + " %",color.white);
AddLabel(1, "Percentile: " + if ImpVol < HV1to2 then 1
            else if ImpVol between HV1to2 and HV2to3 then 2
            else if ImpVol between HV2to3 and HV3to4 then 3
            else if ImpVol between HV3to4 and HV4to5 then 4
            else if ImpVol > HV4to5 then 5 else 0, if ImpVol < HV1to2 then Color.GREEN
            else if ImpVol between HV1to2 and HV2to3 then Color.LIGHT_GREEN
            else if ImpVol between HV2to3 and HV3to4 then Color.YELLOW
            else if ImpVol between HV3to4 and HV4to5 then Color.PINK
            else if ImpVol > HV4to5 then Color.PINK else Color.WHITE);

# ---- IV Rank ----
def IVRank = Round(((ImpVol - HVLOW) / (HVHIGH - HVLOW)), 4) * 100;
AddLabel(1, "IV Rank: " + IVRank + " %", Color.WHITE);

# ---- IV Percentile ----
#def num =


# ---- Bubbles ----
#def isLastBar = !IsNaN(close) and IsNaN(close[-1]);
#AddChartBubble(isLastbar, ImpVol, Round(ImpVol, 4) * 100 + " %", Color.WHITE,if HV2to3 > ImpVol then yes else no);

# ---- TroubleShoot ----
input Troubleshoot = no;
AddLabel(Troubleshoot, Round(HVLOW, 4) * 100 + " %", Color.YELLOW);
AddLabel(Troubleshoot, Round(HVHIGH, 4) * 100 + " %", Color.YELLOW);
AddLabel(Troubleshoot, Round(Difference, 4) * 100 + " %", Color.PINK);
AddLabel(Troubleshoot, HV1to2, Color.WHITE);
AddLabel(Troubleshoot, HV2to3, Color.WHITE);
AddLabel(Troubleshoot, HV3to4, Color.WHITE);
AddLabel(Troubleshoot, HV3to4, Color.WHITE);
 
Last edited:
Thank you. That is great. I put this together to identify, in more detail, the IV in 1 and 2 but i have no experience with thinkscript and had to borrow a small part of this to get started.. I am going to look and see if i can put them together.

declare lower;
declare hide_on_intraday;

DefineGlobalColor("IV", Color.white);
DefineGlobalColor("IV1", Color.GREEN);
DefineGlobalColor("IV2", Color.LIGHT_GREEN);
DefineGlobalColor("IV3", Color.YELLOW);
DefineGlobalColor("IV4", Color.LIGHT_RED);
DefineGlobalColor("IV5", Color.Red);

def period = 252;
def TIV = imp_volatility();

def IV = if !IsNaN(TIV) then TIV else TIV[-1];
plot ImpVol = IV;
ImpVol.setDefaultColor(GlobalColor("IV"));
def IV01 = round(iv * 100 ,0);
input HVPeriod = 21;

def clLog = Log(close / close[1]);
plot HV = stdev(clLog, HVPeriod) * Sqrt(HVPeriod * period / (HVPeriod - 1));
HV.SetDefaultColor(GlobalColor("IV3"));
AddLabel(no, "HV: " + Round(HV*100,0) + "%", GlobalColor("IV"));

def lowestHV = Lowest(HV, period);
def highestHV = Highest(HV, period);

def lowHV = round(lowesthv * 100 ,0);
def highHV = round(highesthv * 100 ,0);

def hvolatility =(highestHV-lowestHV);
def volmultiplier =(hvolatility/5);

def volatility = (highhv-lowhv);
def ivolmult =(volatility/5);
def HLIV = (volatility/10);
def LOWIV1 = (lowhv+hliv);
def HIGHIV1 = (lowhv+ivolmult);
DEF LOWIV2 = (LOWHV+IVOLMULT+HLIV);
DEF HIGHIV2 = (LOWHV+IVOLmult+IVOLmult);
def IV3 = (lowhv+ivolmult+ivolmult+ivolmult);
def IV4 = (lowhv+ivolmult+ivolmult+ivolmult+ivolmult);
def IV5 = (lowhv+ivolmult+ivolmult+ivolmult+ivolmult+ivolmult);

AddLabel(yes, "HV HIGH: " + Round(highestHV * 100, 0) , GlobalColor("IV"));
AddLabel(yes, "HV LOW: " + Round(lowestHV * 100, 0) , GlobalColor("IV"));
AddLabel(yes, "IV: " + Round(IV * 100, 0) , GlobalColor("IV"));
addLabel(yes, if iv01 < IV5 then "IV 5" else "0" , GlobalColor("IV5"));
addLabel(yes, if iv01 < IV4 then "IV 4" else "0" , GlobalColor("IV4"));
addLabel(yes, if iv01 < IV3 then "IV 3" else "0" , GlobalColor("IV3"));
addLabel(yes, if iv01 < HIGHIV2 then "HIGH IV 2" else "0" , GlobalColor("IV2"));
addLabel(yes, if iv01 < LOWIV2 then "LOW IV 2" else "0" , GlobalColor("IV2"));
addLabel(yes, if iv01 < HIGHIV1 then "HIGH IV 1" else "0" , GlobalColor("IV1"));
addLabel(yes, if iv01 < LOWIV1 then "LOW IV 1" else "0" , GlobalColor("IV1"));
 
I updated the study to show prior year implied volatility rather than historical volatility. I've learned that historical volatility shows actual volatility performance, whereas the prior year implied volatility shows where the IV was in the prior year. Comparing to either would be helpful I believe - so I re-arranged this code to show PY ImpVol rather than Historical Volatility, and it's below.

Edit: Updated to work on all charts above the daily. Will not work on intraday due to ThinkOrSwim's limit of 2,000 prior periods.

Code:
declare lower;
input showClouds = yes;

# ---- Plotting Current Year Implied Volatility (IV) ----
plot ImpVol = imp_volatility(symbol = GetUnderlyingSymbol());
ImpVol.SetDefaultColor(Color.CYAN);
ImpVol.SetLineWeight(2);

# ---- Plotting Prior Year Implied Volatility (PY_IV) ----
def agg = GetAggregationPeriod();
def PeriodsBack= if agg == 86400000 then 252 else if agg == 604800000 then 52 else if agg == 2592000000 then 12 else if agg == 7776000000 then 4 else if agg == 31536000000 then 1 else Double.NaN;
plot PYVolatility = ImpVol[PeriodsBack];
PYVolatility.SetDefaultColor(Color.Red);
PYVolatility.SetLineWeight(2);

def PY_IVHIGH = Highest(data = PYVolatility, length = PeriodsBack);
#PY_IVHIGH.SetDefaultColor(Color.RED);

def PY_IVLOW = Lowest(PYVolatility, PeriodsBack);
#PY_IVLOW.SetDefaultColor(Color.DARK_GREEN);

def Difference = (PY_IVHIGH - PY_IVLOW) / 5;

# ---- Plotting IV Levels Based on Prior Year Implied Volatility (PY_IV)----
plot PY_IV1to2 = PY_IVLOW + (Difference * 1);
plot PY_IV2to3 = PY_IVLOW + (Difference * 2);
plot PY_IV3to4 = PY_IVLOW + (Difference * 3);
plot PY_IV4to5 = PY_IVLOW + (Difference * 4);
PY_IV1to2.SetDefaultColor(Color.WHITE);
PY_IV2to3.SetDefaultColor(Color.WHITE);
PY_IV3to4.SetDefaultColor(Color.WHITE);
PY_IV4to5.SetDefaultColor(Color.WHITE);
PY_IV1to2.SetStyle(Curve.SHORT_DASH);
PY_IV2to3.SetStyle(Curve.SHORT_DASH);
PY_IV3to4.SetStyle(Curve.SHORT_DASH);
PY_IV4to5.SetStyle(Curve.SHORT_DASH);

# ---- Clouds ---
AddCloud(If showclouds then PY_IVLOW else Double.NaN, if showclouds then PY_IV1to2 else Double.NaN, Color.GREEN, Color.GREEN);
AddCloud(if showclouds then PY_IV1to2 else Double.NaN, if showclouds then PY_IV2to3 else double.nan, Color.LIGHT_GREEN, Color.LIGHT_GREEN);
AddCloud(If showclouds then PY_IV2to3 else Double.NaN, if showclouds then PY_IV3to4 else double.nan, Color.YELLOW, Color.YELLOW);
AddCloud(if showclouds then PY_IV3to4 else Double.naN, if showclouds then PY_IV4to5 else double.nan, Color.PINK, Color.PINK);
AddCloud(if showclouds then PY_IV4to5 else Double.nan, if showclouds then PY_IVHIGH else double.nan, Color.DOWNTICK, Color.DOWNTICK);

# ---- Chart Labels ----
AddLabel(1,"Current IV: " + ROUND(ImpVol,4) * 100 + " %",color.white);
AddLabel(1, "Percentile: " + if ImpVol < PY_IV1to2 then 1
            else if ImpVol between PY_IV1to2 and PY_IV2to3 then 2
            else if ImpVol between PY_IV2to3 and PY_IV3to4 then 3
            else if ImpVol between PY_IV3to4 and PY_IV4to5 then 4
            else if ImpVol > PY_IV4to5 then 5 else 0, if ImpVol < PY_IV1to2 then Color.GREEN
            else if ImpVol between PY_IV1to2 and PY_IV2to3 then Color.LIGHT_GREEN
            else if ImpVol between PY_IV2to3 and PY_IV3to4 then Color.YELLOW
            else if ImpVol between PY_IV3to4 and PY_IV4to5 then Color.PINK
            else if ImpVol > PY_IV4to5 then Color.PINK else Color.WHITE);

# ---- IV Rank ----
def IVRank = Round(((ImpVol - PY_IVLOW) / (PY_IVHIGH - PY_IVLOW)), 4) * 100;
AddLabel(1, "IV Rank: " + IVRank + " %", Color.WHITE);
 
Last edited:
Solution

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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