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)...

Internet Name

New member
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:

cdmdgcex

New member
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"));
 

Internet Name

New member
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

Similar threads

Top