I've been working on this for weeks, but am not able to generate a solution and not seeing anything online. I need to get the last candle close of the back month /VX expiration and the first candle open of the current month /VX expiration. Any help would be GREATLY appreciated. Code that I'm currently working based on: https://usethinkscript.com/threads/vx-futures-contango-indicator-for-thinkorswim.1177/
and image attached.
and image attached.
Code:
# VX Futures Contango
# tomsk
# 12.8.2019
# V1.0 - 11.28.2019 - thelonelytrader - Initial version of posted study
# V2.0 - 12.08.2019 - tomsk - Major revamped version to handle /VX taxonomy
# Displays Contango relationship between the Front and Back Month /VX futures
#
# According to the design from the original author, there are three possible
# input flavors. It is set to default to option #3, for contango % thresholds
# 1 For relative cumulative difference with respect to Front month
# 2 For absolute difference.
# 3 For Contango % thresholds, from (BM-FM)*100/FM.
# https://usethinkscript.com/threads/vx-futures-contango-indicator-for-thinkorswim.1177/#post-11256
# tomsk post #5
# Modified 7/30/2025 Frank Galan - Need to get first bar close of back monthe /VX expiration and current month /VX expiration open
declare lower;
declare hide_on_intraday;
input showBubbles = no;
input showDebug = no;
input showDebug2 = no;
input showLabel = no;
input Threshold_shortVol = 6.77;
input Threshold_longVol = 2.90;
input flavor = 3;
# Below flags the date for expiring Front Month /VX futures per CBOE specs
# Note: Regarding the Holidays, only one occurrence since 2010, which is
# hard coded in line below. For some unknown reason, TOS does not respond
# to daily /VX futures per specification before August 2010, so data seems
# valid after Aug 2010
#
# In debugging observed TOS sometimes misses complete trading days, the
# "/VX" reference in TOS does not match the CBOE spec for settlement and
# TOS "opportunities" seem to be dynamic (not static bugs). TOS inferred no
# trading of "/VX" between 7/16/2013 and 7/22/2016. (Missing 3 trading days)
script VXexp {
def date = GetYYYYMMDD();
def isholiday = date == 20140319; # Manual injection of holiday on 4/18/14 which alters VX settlement date in March.
def n3rdfa = Next3rdFriday(1);
def n3rdfb = Next3rdFriday(2);
def n3rdf = if (n3rdfa < 4) then n3rdfb else n3rdfa; # Pick Next month's expiration, not this month.
plot VXexp = if (isholiday) then 1 else ((n3rdf == 30) and !isholiday[1]);#and (dow == 3);
}
script LsD {
input date = 2010;
plot LsD = date - 2000;
}
def date = GetYYYYMMDD();
def dom = GetDayOfMonth(date);
def newmo = dom < dom[1];
def incmo = if newmo then 0 else if VXexp() then 1 else incmo[1];
def Y_ = GetYear();
def Y = LsD(Y_);
def MM = GetMonth();
def fm = if (MM + incmo) > 12 then 1 else (MM + incmo);
def fmchange = fm != fm[1];
def fmY = if fmchange then (if (MM + incmo) > 12 then LsD(Y + 1) else Y) else fmY[1];
def bm = if (fm + 1) > 12 then 1 else if (fm - 1) < 0 then 12 else (fm-1);
def bmY = if fmchange then (if (bm < 3) then LsD(Y_ + 1) else Y) else bmY[1];
#AddLabel(1, "/VX Contango Relationship", Color.YELLOW);
AddLabel(showDebug, "Back Month Symbol = " + ((if bm == 1 then "/VXF" else
if bm == 2 then "/VXG" else
if bm == 3 then "/VXH" else
if bm == 4 then "/VXJ" else
if bm == 5 then "/VXK" else
if bm == 6 then "/VXM" else
if bm == 7 then "/VXN" else
if bm == 8 then "/VXQ" else
if bm == 9 then "/VXU" else
if bm == 10 then "/VXV" else
if bm == 11 then "/VXX" else
if bm == 12 then "/VXZ" else " ") + bmY), Color.PINK);
AddLabel(showDebug, "Front Month Symbol = " + ((if fm == 1 then "/VXF" else
if fm == 2 then "/VXG" else
if fm == 3 then "/VXH" else
if fm == 4 then "/VXJ" else
if fm == 5 then "/VXK" else
if fm == 6 then "/VXM" else
if fm == 7 then "/VXN" else
if fm == 8 then "/VXQ" else
if fm == 9 then "/VXU" else
if fm == 10 then "/VXV" else
if fm == 11 then "/VXX" else
if fm == 12 then "/VXZ" else " ") + fmY), Color.PINK);
def fmp = open(symbol = (if fm == 1 then "/VXF" else
if fm == 2 then "/VXG" else
if fm == 3 then "/VXH" else
if fm == 4 then "/VXJ" else
if fm == 5 then "/VXK" else
if fm == 6 then "/VXM" else
if fm == 7 then "/VXN" else
if fm == 8 then "/VXQ" else
if fm == 9 then "/VXU" else
if fm == 10 then "/VXV" else
if fm == 11 then "/VXX" else
if fm == 12 then "/VXZ" else " ") + bmY);
def bmp = close(symbol = (if bm == 1 then "/VXF" else
if bm == 2 then "/VXG" else
if bm == 3 then "/VXH" else
if bm == 4 then "/VXJ" else
if bm == 5 then "/VXK" else
if bm == 6 then "/VXM" else
if bm == 7 then "/VXN" else
if bm == 8 then "/VXQ" else
if bm == 9 then "/VXU" else
if bm == 10 then "/VXV" else
if bm == 11 then "/VXX" else
if bm == 12 then "/VXZ" else " ") + bmY);
AddLabel(showDebug, "fm = " + fm, Color.YELLOW);
AddLabel(showDebug, "bm = " + bm, Color.YELLOW);
AddLabel(showDebug, "fmp = " + fmp, Color.YELLOW);
AddLabel(showDebug, "bmp = " + bmp, Color.YELLOW);
AddLabel(showDebug, "MM = " + MM, Color.YELLOW);
AddLabel(showDebug, "Y_ = " + Y_, Color.YELLOW);
AddLabel(showDebug, "Y = " + Y, Color.YELLOW);
AddLabel(showDebug, "bmY = " + bmY, Color.YELLOW);
# TOS may miss some vx futures quotes, so if this occurs re-use the prior
# day close for the missing entry. The filter below accomplishes this.
def fmpfiltered = if IsNaN(fmp) then fmpfiltered[1] else fmp;
def bmpfiltered = if IsNaN(bmp) then bmpfiltered[1] else bmp;
def reladj = if (bmpfiltered > 0) then bmpfiltered else 1;
AddLabel(showDebug, "fmpfiltered = " + fmpfiltered, Color.Yellow);
AddLabel(showDebug, "bmpfiltered = " + bmpfiltered, Color.Yellow);
# def fmpfiltered = if isnan(fmp) then if (fmpfiltered[1]>0) then fmpfiltered[1] else double.nan else fmp;
# def bmpfiltered = if isnan(bmp) then if (bmpfiltered[1]>0) then bmpfiltered[1] else double.nan else bmp;
def AbsDiffContango = if (BarNumber() < 5)
then 0
else (if (flavor == 1)
then (bmpfiltered - fmpfiltered) / reladj
else (bmpfiltered - fmpfiltered));
def ContangoBias = if (BarNumber() < 5)
then 0
else ContangoBias[1] + (if (flavor == 1)
then (bmpfiltered - fmpfiltered) / reladj
else (bmpfiltered - fmpfiltered));
plot FmBmContango = if IsNaN(fmp) then Double.NaN
else if (flavor == 2)
then AbsDiffContango
else if (flavor == 3)
then Double.NaN
else ContangoBias;
FmBmContango.DefineColor("green", Color.GREEN);
FmBmContango.DefineColor("red", Color.RED);
FmBmContango.DefineColor("white", Color.WHITE);
def ContangoPerCentage = 100 * AbsDiffContango / fmpfiltered;
AddLabel(showDebug2, "AbsDiffContango = " + AbsDiffContango, Color.YELLOW);
AddLabel(showDebug2, "ContangoBias = " + ContangoBias, Color.YELLOW);
AddLabel(showDebug2, "FmBmContango = " + FmBmContango, Color.YELLOW);
AddLabel(showDebug2, "ContangoPerCentage = " + ContangoPerCentage, Color.YELLOW);
plot Cper = if ((flavor == 3) and (IsNaN(fmp) == 0)) then ContangoPerCentage else Double.NaN;
Cper.DefineColor("Green", Color.GREEN);
Cper.DefineColor("Red", Color.RED);
Cper.DefineColor("White", Color.WHITE);
Cper.AssignValueColor(if (ContangoPerCentage > Threshold_shortVol) then Cper.Color("Green")
else if (ContangoPerCentage > Threshold_longVol) then Cper.Color("White")
else Cper.Color("Red"));
Cper.SetPaintingStrategy(PaintingStrategy.POINTS);
def Direction = ContangoBias > ContangoBias[1];
def DirectionChanges = if (BarNumber() == 1) then 0
else if (Direction != Direction[1]) then DirectionChanges[1] + 1
else DirectionChanges[1];
FmBmContango.AssignValueColor(if (ContangoBias > ContangoBias[1]) then FmBmContango.Color("Green")
else if (ContangoBias == ContangoBias[1]) then FmBmContango.Color("White")
else FmBmContango.Color("Red"));
FmBmContango.SetPaintingStrategy(PaintingStrategy.POINTS);
def InContango = if ((BarNumber() == 1) or (DirectionChanges < 1)) then 0 else InContango[1] + (bmpfiltered > fmpfiltered);
def NotContango = if ((BarNumber() == 1) or (DirectionChanges < 1)) then 0 else NotContango[1] + (bmpfiltered <= fmpfiltered);
plot UpperThreshold = if (flavor == 3) then Threshold_shortVol else Double.NaN;
plot LowerThreshold = if (flavor == 3) then Threshold_longVol else Double.NaN;
AddChartBubble(showBubbles and Direction and !Direction[1], ContangoBias, DirectionChanges, Color.GRAY, 1);
AddChartBubble(showBubbles and !Direction and Direction[1], ContangoBias, DirectionChanges, Color.YELLOW, 0);
AddVerticalLine(VXexp(), "/VX Expiration", Color.WHITE);
# End VX Futures Contango
Last edited by a moderator: