Hi all,
I’ve recently become very interested in trading double calendars, and it’s really important for me to see the double calendar prices and the short/long ratio.
About two years ago, I found this script online, but I forgot the source. It keeps showing “Missing data.” Could anyone give me a hand with this?
Thanks so much.
I’ve recently become very interested in trading double calendars, and it’s really important for me to see the double calendar prices and the short/long ratio.
About two years ago, I found this script online, but I forgot the source. It keeps showing “Missing data.” Could anyone give me a hand with this?
Thanks so much.
Code:
# Option Volume/Open Interest Indicator
#https://usethinkscript.com/threads/options-vol-open-interest-for-thinkorswim.313/
#Base script for creating symbol strings found there.
#Retooled by shortvol to display double calendar prices
#Day of the week targets the front expiration cycle short.
#So From Monday 1 enter 2DTE and 4DTE.
#Share Link
#Old build shared link https://tos.mx/MD0vCaN
declare lower;
input My_Symbol = "SPXW";
input Expiry_bubbles = yes;
input Day_Of_Week = 1;
input front_dte = 2;
input Back_DTE = 4;
input My_Strike_Call = 4050;
input My_Strike_Put = 3950;
AddLabel(yes, "Front Expiry Day Of Week 1 = Mon 5 = Fri ");
AddLabel(yes, "Day of week " + Day_Of_Week + " ", Color.GREEN);
AddLabel(yes, "Front Expiry DTE= " + front_dte + " ", Color.GREEN);
AddLabel(yes, "Back Expiry DTE= " + Back_DTE + " ", Color.GREEN);
AddLabel(yes, " Call Strike " + My_Strike_Call + " ");
AddLabel(yes, " Put Strike " + My_Strike_Put + " ");
def Time = RegularTradingStart(GetYYYYMMDD()) / 1000 ;
def D = 86400 ;
def mod = (Floor(Time / 86400) + 4 ) % 7;
def mod1 = (Floor( (Time + (D * 1)) / 86400) + 4 ) % 7;
def mod2 = (Floor( (Time + (D * 2)) / 86400) + 4 ) % 7;
def mod3 = (Floor( (Time + (D * 3)) / 86400) + 4 ) % 7;
def mod4 = (Floor( (Time + (D * 4)) / 86400) + 4 ) % 7;
def mod5 = (Floor( (Time + (D * 5)) / 86400) + 4 ) % 7;
def mod6 = (Floor( (Time + (D * 6)) / 86400) + 4 ) % 7;
def Find = if mod == Day_Of_Week then Day_Of_Week else 0;
def Find1 = if mod1 == Day_Of_Week then 1 else 0;
def Find2 = if mod2 == Day_Of_Week then 2 else 0;
def Find3 = if mod3 == Day_Of_Week then 3 else 0;
def Find4 = if mod4 == Day_Of_Week then 4 else 0;
def Find5 = if mod5 == Day_Of_Week then 5 else 0;
def Find6 = if mod6 == Day_Of_Week then 6 else 0;
#def Find7 = if Mod6 == Day_Of_Week then 7 else 0;
def active = Find == Day_Of_Week;
#def sum_Finder = Find + Find1 + Find2 + Find3 + Find4 + Find5 + Find6; #+ find7 ;
def sum_find = if Find == Day_Of_Week then front_dte else Double.NaN;
def data = GetYYYYMMDD();
def getyear = Round(data / 10000, 0);
def getmonth = Round((data % 10000) / 100, 0);
def getdom = (data % 100);
def Is_january = if active == yes and getmonth == 1 and getdom + sum_find > 31 then getmonth + 1 else 0;
def Is_February = if active == yes and getmonth == 2 and getdom + sum_find > 28 then getmonth + 1 else 0;
def Is_March = if active == yes and getmonth == 3 and getdom + sum_find > 31 then getmonth + 1 else 0;
def Is_April = if active == yes and getmonth == 4 and getdom + sum_find > 30 then getmonth + 1 else 0;
def Is_May = if active == yes and getmonth == 5 and getdom + sum_find > 31 then getmonth + 1 else 0;
def Is_June = if active == yes and getmonth == 6 and getdom + sum_find > 30 then getmonth + 1 else 0;
def Is_July = if active == yes and getmonth == 7 and getdom + sum_find > 31 then getmonth + 1 else 0;
def Is_August = if active == yes and getmonth == 8 and getdom + sum_find > 31 then getmonth + 1 else 0;
def Is_September = if active == yes and getmonth == 9 and getdom + sum_find > 30 then getmonth + 1 else 0;
def Is_October = if active == yes and getmonth == 10 and getdom + sum_find > 31 then getmonth + 1 else 0;
def Is_November = if active == yes and getmonth == 11 and getdom + sum_find > 30 then getmonth + 1 else 0;
def Is_December = if active == yes and getmonth == 12 and getdom + sum_find > 31 then 1 else 0;
def Next_Month = if active == yes then Is_january + Is_February + Is_March + Is_April + Is_May + Is_June + Is_July + Is_August + Is_September + Is_October + Is_November + Is_December else Next_Month[1];
def Filtered_Month_Active = if active == yes and Next_Month == 0 then getmonth else Next_Month;
def Filtered_Month = if active == no then Filtered_Month[1] else Filtered_Month_Active;
def Is_january_dom = if active == yes and getmonth == 1 and getdom + sum_find > 31 then getdom + sum_find - 31 else 0;
def Is_February_dom = if active == yes and getmonth == 2 and getdom + sum_find > 28 then getdom + sum_find - 28 else 0;
def Is_March_dom = if active == yes and getmonth == 3 and getdom + sum_find > 31 then getdom + sum_find - 31 else 0;
def Is_April_dom = if active == yes and getmonth == 4 and getdom + sum_find > 30 then getdom + sum_find - 30 else 0;
def Is_May_dom = if active == yes and getmonth == 5 and getdom + sum_find > 31 then getdom + sum_find - 31 else 0;
def Is_June_dom = if active == yes and getmonth == 6 and getdom + sum_find > 30 then getdom + sum_find - 30 else 0;
def Is_July_dom = if active == yes and getmonth == 7 and getdom + sum_find > 31 then getdom + sum_find - 31 else 0;
def Is_August_dom = if active == yes and getmonth == 8 and getdom + sum_find > 31 then getdom + sum_find - 31 else 0;
def Is_September_dom = if active == yes and getmonth == 9 and getdom + sum_find > 30 then getdom + sum_find - 30 else 0;
def Is_October_dom = if active == yes and getmonth == 10 and getdom + sum_find > 31 then getdom + sum_find - 31 else 0;
def Is_November_dom = if active == yes and getmonth == 11 and getdom + sum_find > 30 then getdom + sum_find - 30 else 0;
def Is_December_dom = if active == yes and getmonth == 12 and getdom + sum_find > 31 then getdom + sum_find - 31 else 0;
def Next_Month_dom = if active == yes then Is_january_dom + Is_February_dom + Is_March_dom + Is_April_dom + Is_May_dom + Is_June_dom + Is_July_dom + Is_August_dom + Is_September_dom + Is_October_dom + Is_November_dom + Is_December_dom else Next_Month_dom[1];
def Dom_active = if active == yes and Next_Month_dom == 0 then getdom + sum_find else Next_Month_dom;
def Dom = if active == no then Dom[1] else Dom_active;
#Begin Strike building
#Try to avoid missing instruments
def getagg = if IsNaN(GetAggregationPeriod())
then getagg[1]
else GetAggregationPeriod();
def rollover = GetYYYYMMDD() == GetYYYYMMDD()[1];
## Stack on filtered data
def ExpYear = getyear;
def ExpMonth2 = Filtered_Month;
;
def ExpDOM = Dom ;
#MK Year Exp Digit Format - MK
def ExpYY = ExpYear - 2000; # convert YYYY to 0-10 number YY or Y
def ExpY1 = if ExpYY > 9 # if year is double digit
then Round(ExpYY / 10, 0) # use round to shear off first digit of YY (ex. 19, 1.9, 9)
else 0; # otherwise make first digit zero
def ExpY2 = if ExpYY > 9 # if year is double digit
then Round((ExpYY / 10) - ExpY1, 1) * 10 # isolate tenths of Y.Y as whole number # isolate tenths of Y.Y as whole number (ex. 1.9, 0.9, 9) -- fixed
else ExpYY; # otherwise return unprocessed single digit year
#MK Month Expiry Digit Format -MK
def ExpM1 = if ExpMonth2 > 9 # if double digit
then Round(ExpMonth2 / 10, 0) # get month first digit
else 0; # else return 0
def ExpM2 = if ExpMonth2 > 9 # if double digit
then Round((ExpMonth2 / 10) - ExpM1, 1) * 10 # isolate tenths of M.M as whole number -- fixed
else ExpMonth2; # otherwise return unprocessed single digit monthly
#MK Day Expiry Digit Format -MK
def ExpD1 = if ExpDOM > 9 # if double digit
then AbsValue(RoundDown(AbsValue(ExpDOM) / 10, 0)) # get day first digit
else 0; # else return 0
def ExpD2 = if ExpDOM > 9 # if double digit
then AbsValue((Round((ExpDOM / 10) - ExpD1, 1) * 10)) # isolate tenths of M.M as whole number -- fixed
else AbsValue(ExpDOM); # otherwise return unprocessed single digit month
#NPTrading : Strike price determined based on current close price but could be previous day close
def Strike = My_Strike_Call ; #round(open("SPX",getagg)/5,0)*5;
def Strike_Close = Round(close("SPX", getagg) / 5, 0) * 5;
def PutOptionohlc420_Close = close("." + My_Symbol + Concat((ExpY1), "") + Concat((ExpY2), "") + Concat((ExpM1), "") + Concat((ExpM2), "") + Concat((ExpD1), "") + Concat((ExpD2), "") + "P" + AsPrice(My_Strike_Put), getagg);
def callOptionohlc420_Close = close("." + My_Symbol + Concat((ExpY1), "") + Concat((ExpY2), "") + Concat((ExpM1), "") + Concat((ExpM2), "") + Concat((ExpD1), "") + Concat((ExpD2), "") + "C" + AsPrice(My_Strike_Call), getagg);
def straddle_close = if IsNaN(PutOptionohlc420_Close + callOptionohlc420_Close ) then (if active and active[1] == no then 0 else straddle_close [1]) else (PutOptionohlc420_Close + callOptionohlc420_Close ) ;
AddChartBubble(straddle_close == 0 and Expiry_bubbles == yes, 100, "Missing data", Color.PINK, yes);
plot EM_C = straddle_close;
# Start of Back Expiry Region
def sum_find_Back = if active == yes then Back_DTE - front_dte else sum_find_Back[1];
def getmonth_Back = if active == yes then Filtered_Month else getmonth_Back[1];
def getyear_Back = if IsNaN(GetYear())
then getyear_Back[1]
else if active == yes then GetYear() else getyear_Back[1];
def getDOM_Back = Dom; #Link starting DOM for Back Expiry to Front calculation
def Is_january_Back = if active == yes and getmonth_Back == 1 and getDOM_Back + sum_find_Back > 31 then getmonth_Back + 1 else 0;
def Is_February_Back = if active == yes and getmonth_Back == 2 and getDOM_Back + sum_find_Back > 28 then getmonth_Back + 1 else 0;
def Is_March_Back = if active == yes and getmonth_Back == 3 and getDOM_Back + sum_find_Back > 31 then getmonth_Back + 1 else 0;
def Is_April_Back = if active == yes and getmonth_Back == 4 and getDOM_Back + sum_find_Back > 30 then getmonth_Back + 1 else 0;
def Is_May_Back = if active == yes and getmonth_Back == 5 and getDOM_Back + sum_find_Back > 31 then getmonth_Back + 1 else 0;
def Is_June_Back = if active == yes and getmonth_Back == 6 and getDOM_Back + sum_find_Back > 30 then getmonth_Back + 1 else 0;
def Is_July_Back = if active == yes and getmonth_Back == 7 and getDOM_Back + sum_find_Back > 31 then getmonth_Back + 1 else 0;
def Is_August_Back = if active == yes and getmonth_Back == 8 and getDOM_Back + sum_find_Back > 31 then getmonth_Back + 1 else 0;
def Is_September_Back = if active == yes and getmonth_Back == 9 and getDOM_Back + sum_find_Back > 30 then getmonth_Back + 1 else 0;
def Is_October_Back = if active == yes and getmonth_Back == 10 and getDOM_Back + sum_find_Back > 31 then getmonth_Back + 1 else 0;
def Is_November_Back = if active == yes and getmonth_Back == 11 and getDOM_Back + sum_find_Back > 30 then getmonth_Back + 1 else 0;
def Is_December_Back = if active == yes and getmonth_Back == 12 and getDOM_Back + sum_find_Back > 31 then 1 else 0;
def Next_Month_Back = if active == yes then Is_january_Back + Is_February_Back + Is_March_Back + Is_April_Back + Is_May_Back + Is_June_Back + Is_July_Back + Is_August_Back + Is_September_Back + Is_October_Back + Is_November_Back + Is_December else Next_Month_Back[1];
def Filtered_Month_Back_active = if active == yes and Next_Month_Back == 0 then getmonth_Back else Next_Month_Back;
def Filtered_Month_Back = if active == no then Filtered_Month_Back[1] else Filtered_Month_Back_active;
def Is_january_dom_Back = if active == yes and getmonth_Back == 1 and getDOM_Back + sum_find_Back > 31 then getDOM_Back + sum_find_Back - 31 else 0;
def Is_February_dom_Back = if active == yes and getmonth_Back == 2 and getDOM_Back + sum_find_Back > 28 then getDOM_Back + sum_find_Back - 28 else 0;
def Is_March_dom_Back = if active == yes and getmonth_Back == 3 and getDOM_Back + sum_find_Back > 31 then getDOM_Back + sum_find_Back - 31 else 0;
def Is_April_dom_Back = if active == yes and getmonth_Back == 4 and getDOM_Back + sum_find_Back > 30 then getDOM_Back + sum_find_Back - 30 else 0;
def Is_May_dom_Back = if active == yes and getmonth_Back == 5 and getDOM_Back + sum_find_Back > 31 then getDOM_Back + sum_find_Back - 31 else 0;
def Is_June_dom_Back = if active == yes and getmonth_Back == 6 and getDOM_Back + sum_find_Back > 30 then getDOM_Back + sum_find_Back - 30 else 0;
def Is_July_dom_Back = if active == yes and getmonth_Back == 7 and getDOM_Back + sum_find_Back > 31 then getDOM_Back + sum_find_Back - 31 else 0;
def Is_August_dom_Back = if active == yes and getmonth_Back == 8 and getDOM_Back + sum_find_Back > 31 then getDOM_Back + sum_find_Back - 31 else 0;
def Is_September_dom_Back = if active == yes and getmonth_Back == 9 and getDOM_Back + sum_find_Back > 30 then getDOM_Back + sum_find_Back - 30 else 0;
def Is_October_dom_Back = if active == yes and getmonth_Back == 10 and getDOM_Back + sum_find_Back > 31 then getDOM_Back + sum_find_Back - 31 else 0;
def Is_November_dom_Back = if active == yes and getmonth_Back == 11 and getDOM_Back + sum_find_Back > 30 then getDOM_Back + sum_find_Back - 30 else 0;
def Is_December_dom_Back = if active == yes and getmonth_Back == 12 and getDOM_Back + sum_find_Back > 31 then getDOM_Back + sum_find_Back - 31 else 0;
def Next_Month_dom_Back = if active == yes then Is_january_dom_Back + Is_February_dom_Back + Is_March_dom_Back + Is_April_dom_Back + Is_May_dom_Back + Is_June_dom_Back + Is_July_dom_Back + Is_August_dom_Back + Is_September_dom_Back + Is_October_dom_Back + Is_November_dom_Back + Is_December_dom_Back else Next_Month_dom_Back[1];
def Dom_Back_active = if active == yes and Next_Month_dom_Back == 0 then getDOM_Back + sum_find_Back else Next_Month_dom_Back;
def Dom_Back = if active == no then Dom_Back[1] else Dom_Back_active;
def ExpMonth2_back = Filtered_Month_Back;
def ExpYear_back = getyear;
def ExpDOM_back = Dom_Back ;
#MK Year Exp Digit Format - MK
def ExpYY_Back = ExpYear_back - 2000; # convert YYYY to 0-10 number YY or Y
def ExpY1_Back = if ExpYY_Back > 9 # if year is double digit
then Round(ExpYY_Back / 10, 0) # use round to shear off first digit of YY (ex. 19, 1.9, 9)
else 0; # otherwise make first digit zero
def ExpY2_Back = if ExpYY_Back > 9 # if year is double digit
then Round((ExpYY_Back / 10) - ExpY1_Back , 1) * 10 # isolate tenths of Y.Y as whole number # isolate tenths of Y.Y as whole number (ex. 1.9, 0.9, 9) -- fixed
else ExpYY_Back; # otherwise return unprocessed single digit year
#MK Month Expiry Digit Format -MK
def ExpM1_Back = if ExpMonth2_back > 9 # if double digit
then Round(ExpMonth2_back / 10, 0) # get month first digit
else 0; # else return 0
def ExpM2_Back = if ExpMonth2_back > 9 # if double digit
then Round((ExpMonth2_back / 10) - ExpM1_Back , 1) * 10 # isolate tenths of M.M as whole number -- fixed
else ExpMonth2_back ; # otherwise return unprocessed single digit monthly
#MK Day Expiry Digit Format -MK
def ExpD1_back = if ExpDOM_back > 9 # if double digit
then AbsValue(RoundDown(AbsValue(ExpDOM_back) / 10, 0)) # get day first digit
else 0; # else return 0
def ExpD2_Back = if ExpDOM_back > 9 # if double digit
then AbsValue((Round((ExpDOM_back / 10) - ExpD1_back, 1) * 10)) # isolate tenths of M.M as whole number -- fixed
else AbsValue(ExpDOM_back); # otherwise return unprocessed single digit month
#Plot Friday = ExpDom_F - 1;
def PutOptionohlc420_Back_Close =
close("." + My_Symbol + Concat((ExpY1_Back), "") + Concat((ExpY2_Back), "") + Concat((ExpM1_Back), "") + Concat((ExpM2_Back), "") + Concat((ExpD1_back), "") + Concat((ExpD2_Back), "") + "P" + AsPrice(My_Strike_Put), getagg);
def callOptionohlc420_Back_Close =
close("." + My_Symbol + Concat((ExpY1_Back), "") + Concat((ExpY2_Back), "") + Concat((ExpM1_Back), "") + Concat((ExpM2_Back), "") + Concat((ExpD1_back), "") + Concat((ExpD2_Back), "") + "C" + AsPrice(My_Strike_Call), getagg);
def straddle_Back_Close = if IsNaN(PutOptionohlc420_Back_Close + callOptionohlc420_Back_Close ) then (if active and active[1] == no then 0 else straddle_Back_Close[1]) else (PutOptionohlc420_Back_Close + callOptionohlc420_Back_Close ) ;
AddChartBubble(straddle_Back_Close == 0 and Expiry_bubbles == yes, 100, "Missing data", Color.CYAN, yes);
plot EM_Straddle_Back_Close = straddle_Back_Close;
plot Current_Price = straddle_Back_Close - straddle_close;
Current_Price.AssignValueColor(if Current_Price > Current_Price[1] then Color.GREEN else Color.RED);
AddChartBubble(GetYYYYMMDD() != GetYYYYMMDD()[1] and Expiry_bubbles == yes, 100, "Front Expiry " + Concat((ExpM1), "") + Concat((ExpM2), "") + "-" + Concat((ExpD1), "") + Concat((ExpD2), "") + "-" + Concat((ExpY1), "") + Concat((ExpY2), ""), Color.CYAN, yes);
AddLabel(yes, "Front Expiry" + Concat((ExpM1), "") + Concat((ExpM2), "") + "-" + Concat((ExpD1), "") + Concat((ExpD2), "") + "-" + Concat((ExpY1), "") + Concat((ExpY2), ""), Color.CYAN);
AddChartBubble(GetYYYYMMDD() != GetYYYYMMDD()[1] and Expiry_bubbles == yes, 100, " Back Expiry " + Concat((ExpM1_Back), "") + Concat((ExpM2_Back), "") + "-" + Concat((ExpD1_back), "") + Concat((ExpD2_Back), "") + "-" + Concat((ExpY1_Back), "") + Concat((ExpY2_Back), "") , Color.PINK, yes);
AddLabel(yes, "Back Expiry" + Concat((ExpM1_Back), "") + Concat((ExpM2_Back), "") + "-" + Concat((ExpD1_back), "") + Concat((ExpD2_Back), "") + "-" + Concat((ExpY1_Back), "") + Concat((ExpY2_Back), ""), Color.PINK);
# dow_holidays_01
# halcyonguy
# 22-04-06
# check if a trading day is skipped, holidays
# compare 2 day of week #'s to see if a date was skipped
# dow 1 = monday , 5 = friday
# mobius
def year = Round(data / 10000, 0);
def month = Round((data % 10000) / 100, 0);
def day = (data % 100);
#addLabel(1, "date: " + month + "/" + day + "/" + AsPrice(year), color.white);
def bn = BarNumber();
def lastbar = !IsNaN(close[0]) and IsNaN(close[-1]);
def lastcls = if !IsNaN(close) and !lastbar then close else if lastbar then close else lastcls[1];
def DOW = GetDayOfWeek(GetYYYYMMDD());
def daystart = if GetDay() != GetDay()[1] then 1 else 0;
#def dayend = if GetDay() != GetDay()[-1] then 1 else 0;
# if no skip = 99
def dayskipped;
if bn == 1
then {
dayskipped = 99;
} else if (daystart and DOW == 2 and DOW[1] != 1)
then {
dayskipped = 1;
} else if (daystart and DOW == 3 and DOW[1] != 2)
then {
dayskipped = 2;
} else if (daystart and DOW == 4 and DOW[1] != 3)
then {
dayskipped = 3;
} else if (daystart and DOW == 5 and DOW[1] != 4)
then {
dayskipped = 4;
} else if (daystart and DOW == 1 and DOW[1] != 5)
then {
dayskipped = 5;
} else {
dayskipped = 99;
}
input show_bubble = yes;
AddChartBubble(show_bubble and dayskipped != 99, lastcls,
(if dayskipped == 1 then "Monday"
else if dayskipped == 2 then "Tuesday"
else if dayskipped == 3 then "Wednesday"
else if dayskipped == 4 then "Thursday"
else if dayskipped == 5 then "Friday"
else "") + "\n" +
"skipped\n" +
"before\n" +
( month + "/" + day + "/" + AsPrice(year) )
, Color.CYAN, no);
input show_vertical_line = yes;
AddVerticalLine(show_vertical_line and dayskipped != 99,
(if dayskipped == 1 then "Monday"
else if dayskipped == 2 then "Tuesday"
else if dayskipped == 3 then "Wednesday"
else if dayskipped == 4 then "Thursday"
else if dayskipped == 5 then "Friday"
else "") + " skipped before " + ( month + "/" + day + "/" + AsPrice(year)) , Color.CYAN);
# ---------------------------------------------------------
input test1_dow = no;
AddChartBubble( test1_dow, lastcls, DOW , Color.YELLOW, no);
#
AddLabel(yes, "Short Long Ratio " + ( straddle_close / straddle_Back_Close ));
plot short_long_ratio = ( straddle_close / straddle_Back_Close ) * 100;
short_long_ratio.SetDefaultColor(Color.RED);
Attachments
Last edited by a moderator: