VIX: Backwardation Vs Contango
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//@version=5
// VIX: Backwardation Vs Contango 
// Quickly visualize Contango vs Backwardation in the VIX by plotting the price of the next 18months of futures contracts.

// Note: indicator does not map to time axis in the same way as price; it simply plots the progression of contract months out into the future; left to right; so timeframe doesn't matter for this plot
// There's likely some more efficient way to write this; e.g. when plotting for ZW; 15 of the security requests are redundant; but they are still made; and can make this slower to load
// TO UPDATE(every year recommended): in REQUEST CONTRACTS section, delete old contracts (top) and add new ones (bottom). Then in PLOTTING section, Delete old [expired] contract labels (bottom); add new [distant future] contract labels (top); adjust the X in 'bar_index-(X+_historical)' numbers accordingly

// This is one of several similar indicators: Meats | Metals | Grains | VIX

// Tips:
// -Right click and reset chart if you can't see the plot; or if you have trouble with the scaling.
// -Right click and add to new scale if you prefer this not to overlay directly on price. Or move to new pane below.

// --Added historical input: input days back in time; to see the historical shape of the Futures curve via selecting 'days back' snapshot
// updated contracts 30th Jan 2023
// © twingall


indicator("VIX: Backwardation Vs Contango", overlay = true, scale = scale.right)
_historical = input(0, "time travel back; days")
_adr = ta.atr(5)
colorNone= color.new(color.white, 100)

//Function to test if contract is expired
int oneWeek = 5*24*60*60*1000 // 5 or more days since last reported closing price => expired
isExp (int _timeClose)=>
    expired = _timeClose <= (last_bar_time-oneWeek) 

///REQUEST CONTRACTS---
[jun22,jun22t]=request.security(syminfo.root + "M2022",  "D",[close[_historical], time_close], ignore_invalid_symbol=true)
[jul22,jul22t]= request.security(syminfo.root + "N2022", "D", [close[_historical], time_close], ignore_invalid_symbol=true)
[aug22,aug22t]=request.security(syminfo.root + "Q2022",  "D",[close[_historical], time_close], ignore_invalid_symbol=true)
[sept22,sept22t] =request.security(syminfo.root + "U2022",  "D",[close[_historical], time_close], ignore_invalid_symbol=true)
[oct22,oct22t] = request.security(syminfo.root + "V2022",  "D",[close[_historical], time_close], ignore_invalid_symbol=true)
[nov22,nov22t] =request.security(syminfo.root + "X2022",  "D",[close[_historical], time_close], ignore_invalid_symbol=true)
[dec22,dec22t] =request.security(syminfo.root + "Z2022",  "D",[close[_historical], time_close], ignore_invalid_symbol=true)
[jan23,jan23t] =request.security(syminfo.root + "F2023",  "D",[close[_historical], time_close], ignore_invalid_symbol=true)
[feb23,feb23t]=request.security(syminfo.root + "G2023",  "D",[close[_historical], time_close], ignore_invalid_symbol=true)
[mar23,mar23t]=request.security(syminfo.root + "H2023",  "D",[close[_historical], time_close], ignore_invalid_symbol=true)
[apr23,apr23t] = request.security(syminfo.root + "J2023",  "D",[close[_historical], time_close], ignore_invalid_symbol=true)
[may23,may23t]=request.security(syminfo.root + "K2023",  "D",[close[_historical], time_close], ignore_invalid_symbol=true)
[jun23,jun23t]=request.security(syminfo.root + "M2023",  "D",[close[_historical], time_close], ignore_invalid_symbol=true)
[jul23,jul23t]= request.security(syminfo.root + "N2023", "D", [close[_historical], time_close], ignore_invalid_symbol=true)
[aug23,aug23t]=request.security(syminfo.root + "Q2023",  "D",[close[_historical], time_close], ignore_invalid_symbol=true)
[sept23,sept23t] = request.security(syminfo.root + "U2023",  "D",[close[_historical], time_close], ignore_invalid_symbol=true)
[oct23,oct23t] = request.security(syminfo.root + "V2023",  "D",[close[_historical], time_close], ignore_invalid_symbol=true)


//VX plotting
if barstate.islast and (syminfo.root=='VX' or syminfo.root== 'VIX') //also display on Volatility S&P 500 index: VIX
    label.new(bar_index-(_historical), close[_historical]+ 2*_adr, text = 'S\nN\nA\nP\nS\nH\nO\nT', textcolor = color.red, style=label.style_arrowdown, color= color.red, size = size.tiny)

    label.new(bar_index-(2+_historical), isExp(oct23t)?0:oct23, text = 'Oct23', textcolor  =isExp(oct23t)?colorNone: color.red, style=isExp(oct23t)?label.style_none:label.style_diamond, size = size.tiny)
    label.new(bar_index-(4+_historical), isExp(sept23t)?0:sept23, text ='Sept23',textcolor =isExp(sept23t)?colorNone:color.red, style=isExp(sept23t)?label.style_none:label.style_diamond, size = size.tiny)
    label.new(bar_index-(6+_historical), isExp(aug23t)?0:aug23, text = 'Aug23', textcolor = isExp(aug23t)?colorNone: color.red, style=isExp(aug23t)?label.style_none:label.style_diamond, size = size.tiny)
    label.new(bar_index-(8+_historical), isExp(jul23t)?0:jul23, text = 'Jul23', textcolor = isExp(jul23t)?colorNone: color.red, style=isExp(jul23t)?label.style_none:label.style_diamond, size = size.tiny)
    label.new(bar_index-(10+_historical), isExp(jun23t)?0:jun23, text = 'Jun23', textcolor = isExp(jun23t)?colorNone:color.red, style=isExp(jun23t)?label.style_none:label.style_diamond, size = size.tiny)
    label.new(bar_index-(12+_historical), isExp(may23t)?0:may23, text = 'May23', textcolor =isExp(may23t)?colorNone: color.red, style=isExp(may23t)?label.style_none:label.style_diamond, size = size.tiny)
    label.new(bar_index-(14+_historical), isExp(apr23t)?0:apr23, text = 'Apr23', textcolor =isExp(apr23t)?colorNone: color.red, style=isExp(apr23t)?label.style_none:label.style_diamond, size = size.tiny)
    label.new(bar_index-(16+_historical), isExp(mar23t)?0:mar23, text = 'Mar23', textcolor =isExp(mar23t)?colorNone: color.red, style=isExp(mar23t)?label.style_none:label.style_diamond, size = size.tiny)
    label.new(bar_index-(18+_historical), isExp(feb23t)?0:feb23, text = 'Feb23', textcolor =isExp(feb23t)?colorNone: color.red, style=isExp(feb23t)?label.style_none:label.style_diamond, size = size.tiny)
    label.new(bar_index-(20+_historical), isExp(jan23t)?0:jan23, text = 'Jan23', textcolor =isExp(jan23t)?colorNone: color.red, style=isExp(jan23t)?label.style_none:label.style_diamond, size = size.tiny)
    label.new(bar_index-(22+_historical), isExp(dec22t)?0:dec22, text = 'Dec22', textcolor =isExp(dec22t)?colorNone: color.red, style=isExp(dec22t)?label.style_none:label.style_diamond, size = size.tiny)
    label.new(bar_index-(24+_historical), isExp(nov22t)?0:nov22, text = 'Nov22', textcolor =isExp(nov22t)?colorNone: color.red, style=isExp(nov22t)?label.style_none:label.style_diamond, size = size.tiny)
    label.new(bar_index-(26+_historical), isExp(oct22t)?0:oct22, text = 'Oct22', textcolor =isExp(oct22t)?colorNone: color.red, style=isExp(oct22t)?label.style_none:label.style_diamond, size = size.tiny)
    label.new(bar_index-(28+_historical), isExp(sept22t)?0:sept22,text='Sept22', textcolor=isExp(sept22t)?colorNone: color.red,style=isExp(sept22t)?label.style_none:label.style_diamond, size = size.tiny)
    label.new(bar_index-(30+_historical), isExp(aug22t)?0:aug22, text = 'Aug22', textcolor =isExp(aug22t)?colorNone: color.red, style=isExp(aug22t)?label.style_none:label.style_diamond, size = size.tiny)
    label.new(bar_index-(32+_historical), isExp(jul22t)?0:jul22, text = 'Jul22', textcolor =isExp(jul22t)?colorNone: color.red, style=isExp(jul22t)?label.style_none:label.style_diamond, size = size.tiny)
    label.new(bar_index-(34+_historical), isExp(jun22t)?0:jun22, text = 'Jun22', textcolor =isExp(jun22t)?colorNone: color.red, style=isExp(jun22t)?label.style_none:label.style_diamond, size = size.tiny)
