• LIMITED TIME OFFER: use coupon code PRIMEDAY at checkout to save $50 off VIP membership (down to $149 / year). Valid through Tuesday 6/22.

VIX Contango Indicator for ThinkorSwim

reknirt

New member
I'm trying to write an indicator plotting percent contango between spot VIX -- last closing VIX price -- and the near month /VX future. I got the idea from an indicator Jeff Augen did here:

The indicator starts about 11:10

In theory the indicator should follow the S&P very closely -- at least until backwardation occurs and the near month contract becomes more expensive than spot VIX.

However, my indicator seems to be very noisy, whereas Augen's follows the S&P extremely closely. My formula for calculating the difference is:

contangoPercent = (NearContract - SpotVIX) / SpotVIX;

I corrected some of the noise by filtering out NaNs and replacing them with the previous bar. But I'm still not sure if my calculation is correct. Here is my code:

Code:
def month = GetMonth();
def daysTillExp = Next3rdFriday(2) - 30;
def whichMonth = if daysTillExp > 4 then month
    else if daysTillExp < 5 and month == 12
        then 1
    else if daysTillExp < 5
     then month + 1
    else double.nan;

def Year = GetYear();
def Year_Ext = Year - 2000;
def agg = AggregationPeriod.day;

def SpotVIX = close("VIX");
def NearContract = if whichMonth == 1
                   then Close(symbol = "/VXF" + Year_Ext, period = agg)
                   else if whichMonth == 2
                   then Close(symbol = "/VXG" + Year_Ext, period = agg)
                   else if whichMonth == 3
                   then Close(symbol = "/VXH" + Year_Ext, period = agg)
                   else if whichMonth == 4
                   then Close(symbol = "/VXJ" + Year_Ext, period = agg)
                   else if whichMonth == 5
                   then Close(symbol = "/VXK" + Year_Ext, period = agg)
                   else if whichMonth == 6
                   then Close(symbol = "/VXM" + Year_Ext, period = agg)
                   else if whichMonth == 7
                   then Close(symbol = "/VXN" + Year_Ext, period = agg)
                   else if whichMonth == 8
                   then Close(symbol = "/VXQ" + Year_Ext, period = agg)
                   else if whichMonth == 9
                   then Close(symbol = "/VXU" + Year_Ext, period = agg)
                   else if whichMonth == 10
                   then Close(symbol = "/VXV" + Year_Ext, period = agg)
                   else if whichMonth == 11
                   then Close(symbol = "/VXX" + Year_Ext, period = agg)
                   else if whichMonth == 12
                   then Close(symbol = "/VXZ" + Year_Ext, period = agg)
                   else double.nan;

# if the calculations on any of the bar return NaN, use the previous bar.

def spotFiltered = if IsNaN(spotVIX) then  spotFiltered[1]  else SpotVIX;
def nearFiltered = if IsNaN(NearContract) then  nearFiltered[1]  else NearContract;

plot contangoPercent = simpleMovingAvg((nearFiltered - spotFiltered) / spotFiltered, 5, 0);
#plot contangoPercent = (NearContract - SpotVIX) / SpotVIX;


plot zeroLine = 0;

addLabel(yes, daysTillExp);
addLabel(yes, whichMonth);
addLabel(yes, Next3rdFriday(2));

addlabel(Close(symbol = "VIX") <= NearContract,"Contango", color.green);
addlabel(Close(symbol = "VIX") > NearContract,"Backwardation", color.red);

# End Code VIX Contango/Normal Backwardation

Here is what it currently looks like on an /ES chart

FzCbahe.png


I appreciate any help!
 

rbapf

New member
The following is a study which uses the VIX futures to calculate the M1/M2 contango. It appears to work most of the time except for the second half of each December. Can anyone see where I went wrong?

Code:
input January = "/VXF";
input February = "/VXG";
input March = "/VXH";
input April = "/VXJ";
input May = "/VXK";
input June = "/VXM";
input July = "/VXN";
input August = "/VXQ";
input September = "/VXU";
input October = "/VXV";
input November = "/VXX";
input December = "/VXZ";

def Year = GetYear();

def JanuaryLength = 31;
def FebruaryLength = if Year % 4 == 0 then 29 else 28;
def MarchLength = 31;
def AprilLength = 30;
def MayLength = 31;
def JuneLength = 30;
def JulyLength = 31;
def AugustLength = 31;
def SeptemberLength = 30;
def OctoberLength = 31;
def NovemberLength = 30;
def DecemberLength = 31;

def Day = GetDayOfMonth(GetYYYYMMDD());
def WeekDay = GetDayOfWeek(GetYYYYMMDD());
def Month = GetMonth();

def MonthLength = if Month == 1 then JanuaryLength else if Month == 2 then FebruaryLength else if Month == 3 then MarchLength else if Month == 4 then AprilLength else if Month == 5 then MayLength else if Month == 6 then JuneLength else if Month == 7 then JulyLength else if Month == 8 then AugustLength else if Month == 9 then SeptemberLength else if Month == 10 then OctoberLength else if Month == 11 then NovemberLength else DecemberLength;

def AdjMonth = if Month == Month[1] then if (Day > MonthLength - 16 and Day < MonthLength - 8 and WeekDay == 3) then if Month == 12 then 1 else Month + 1 else if AdjMonth[1] != Month then AdjMonth[1] else Month else Month;

def M1 = close(Concat(if AdjMonth == 1 then January else if AdjMonth == 2 then February else if AdjMonth == 3 then March else if AdjMonth == 4 then April else if AdjMonth == 5 then May else if AdjMonth == 6 then June else if AdjMonth == 7 then July else if AdjMonth == 8 then August else if AdjMonth == 9 then September else if AdjMonth == 10 then October else if AdjMonth == 11 then November else December, Year % 100));

def M2 = close(if AdjMonth == 12 then Concat(January, (Year % 100) + 1) else Concat(if AdjMonth == 1 then February else if AdjMonth == 2 then March else if AdjMonth == 3 then April else if AdjMonth == 4 then May else if AdjMonth == 5 then June else if AdjMonth == 6 then July else if AdjMonth == 7 then August else if AdjMonth == 8 then September else if AdjMonth == 9 then October else if AdjMonth == 10 then November else December, Year % 100));

plot Contango = M2 / M1 - 1;

plot zeros = 0;
 

XeoNoX

Well-known member
VIP
@reknirt theres no percent of contango, because contango is contango, its like saying its in order or not in order, theres no percent of the order, its either true or false, theres no percent of true or false, its in order or its not. however theres percent of the difference from the spot and the futures .

To help you out...
heres a code from Mobius and AlphaInvestor

you simply have to plug in the mathematical equation for the symbol you want to get the percent from and plug in the formula for percent.

plot percent = ((NearContract - SpotVIX) / SpotVIX)*100;

Code:
# VIX Contango / Normal Backwardation Labels

# Mobius

# Chat Room Request 12.29.2015



# 02/28/2016 - AlphaInvestor - added color coded contango / backwardation label

# 02/28/2016 - AlphaInvestor - converted from Oil to VIX

# 12/01/2019 - AI - changed to 2 year option string



def Month = GetMonth();

def Year = GetYear();

#def Year_Ext = Year - 2010;

def Year_Ext = Year - 2000;  # AI - Fix year for new symbol logic

def agg = AggregationPeriod.DAY;

def NextContract = if Month == 1

                   then close(symbol = "/VXJ" + Year_Ext, period = agg)

                   else if Month == 2

                   then close(symbol = "/VXK" + Year_Ext, period = agg)

                   else if Month == 3

                   then close(symbol = "/VXM" + Year_Ext, period = agg)

                   else if Month == 4

                   then close(symbol = "/VXN" + Year_Ext, period = agg)

                   else if Month == 5

                   then close(symbol = "/VXQ" + Year_Ext, period = agg)

                   else if Month == 6

                   then close(symbol = "/VXU" + Year_Ext, period = agg)

                   else if Month == 7

                   then close(symbol = "/VXV" + Year_Ext, period = agg)

                   else if Month == 8

                   then close(symbol = "/VXX" + Year_Ext, period = agg)

                   else if Month == 9

                   then close(symbol = "/VXZ" + Year_Ext, period = agg)

                   else if Month == 10

                   then close(symbol = "/VXF" + (Year_Ext + 1), period = agg)

                   else if Month == 11

                   then close(symbol = "/VXG" + (Year_Ext + 1), period = agg)

                   else if Month == 12

                   then close(symbol = "/VXH" + (Year_Ext + 1), period = agg)

                   else Double.NaN;

def Month6Contract = if Month == 1

                   then close(symbol = "/VXQ" + Year_Ext, period = agg)

                   else if Month == 2

                   then close(symbol = "/VXU" + Year_Ext, period = agg)

                   else if Month == 3

                   then close(symbol = "/VXV" + Year_Ext, period = agg)

                   else if Month == 4

                   then close(symbol = "/VXX" + Year_Ext, period = agg)

                   else if Month == 5

                   then close(symbol = "/VXZ" + Year_Ext, period = agg)

                   else if Month == 6

                   then close(symbol = "/VXF" + (Year_Ext + 1), period = agg)

                   else if Month == 7

                   then close(symbol = "/VXG" + (Year_Ext + 1), period = agg)

                   else if Month == 8

                   then close(symbol = "/VXH" + (Year_Ext + 1), period = agg)

                   else if Month == 9

                   then close(symbol = "/VXJ" + (Year_Ext + 1), period = agg)

                   else if Month == 10

                   then close(symbol = "/VXK" + (Year_Ext + 1), period = agg)

                   else if Month == 11

                   then close(symbol = "/VXM" + (Year_Ext + 1), period = agg)

                   else if Month == 12

                   then close(symbol = "/VXN" + (Year_Ext + 1), period = agg)

                   else Double.NaN;

def YearOutContract = if Month == 1

                   then close(symbol = "/VXF" + (Year_Ext + 1), period = agg)

                   else if Month == 2

                   then close(symbol = "/VXG" + (Year_Ext + 1), period = agg)

                   else if Month == 3

                   then close(symbol = "/VXH" + (Year_Ext + 1), period = agg)

                   else if Month == 4

                   then close(symbol = "/VXJ" + (Year_Ext + 1), period = agg)

                   else if Month == 5

                   then close(symbol = "/VXK" + (Year_Ext + 1), period = agg)

                   else if Month == 6

                   then close(symbol = "/VXM" + (Year_Ext + 1), period = agg)

                   else if Month == 7

                   then close(symbol = "/VXN" + (Year_Ext + 1), period = agg)

                   else if Month == 8

                   then close(symbol = "/VXQ" + (Year_Ext + 1), period = agg)

                   else if Month == 9

                   then close(symbol = "/VXU" + (Year_Ext + 1), period = agg)

                   else if Month == 10

                   then close(symbol = "/VXV" + (Year_Ext + 1), period = agg)

                   else if Month == 11

                   then close(symbol = "/VXX" + (Year_Ext + 1), period = agg)

                   else if Month == 12

                   then close(symbol = "/VXZ" + (Year_Ext + 1), period = agg)

                   else Double.NaN;

AddLabel(1, "Date: " + Month +

            "/" +

             AsPrice(Year) +

          "  Current Contract: " +

             "/VX" +

          "  Curr Cont Price = " +

             AsDollars(close("/VX")) +

          "  Next Month Contract Price = " +

             AsDollars(NextContract) +

          "  6 Months Out = " +

             AsDollars(Month6Contract) +

          "  One Year Out = " +

             AsDollars(YearOutContract), Color.WHITE);



AddLabel(close("/VX") <= NextContract, "Contango", Color.GREEN);

AddLabel(close("/VX") > NextContract, "Backwardation", Color.RED);



AddLabel(close("/VX") <= NextContract

         and NextContract <= Month6Contract, " /VX Typical ", Color.GREEN);

AddLabel(close("/VX") > NextContract, " /VX Front Month Inverted ", Color.RED);

AddLabel(NextContract > Month6Contract, " /VX Back Month Inverted ", Color.RED);




# End Code VIX Contango/Normal Backwardation
 
Last edited:

Similar threads

Top