knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.path = "man/figures/README-", out.width = "100%" )
R.MFIV can be installed via:
remotes::install_github("m-g-h/R.MFIV")
The VIX is defined as:
knitr::include_graphics("man/figures/VIX_formulas.PNG")
where the term in brackets under the square root is a linear interpolation of two Implied Variances, which are given by the second formula. The CBOE approach of the VIX calculation is explained in the CBOE VIX Whitepaper.
In order to calculate the VIX and its individual variables, this package provides the following functionality as explained in the following sections
1. Short Walkthrough
interpolate_rfr()CBOE_F_O()CBOE_K_0()CBOE_option_selection()CBOE_sigma_sq()CBOE_VIX_variables()CBOE_VIX_index()option_descriptives()2. Processing a whole dataset (using data.table)
CBOE_interpolation_terms()3. Visualise the VIX-Index
plot_VIX()result_browser()4. Analyse the Option-Data Quality
option_descriptives()5. Improve Option-Data Quality using Smoothing Methods
JandT_2007_smoothing_method()JandT_2007_sigma_sq()Load exemplary package data
library(R.MFIV) data(option_dataset) option_dataset
We select an exemplary entry for the calculation. This observation will be our "near-term" contract. Also note that option_quotes is a "nested" data.table itself
t <- option_dataset$t[2] exp <- option_dataset$exp[2] option_quotes <- option_dataset$option_quotes[[2]] option_quotes
Next we calculate the Risk-Free-Rate R
library(lubridate) R <- interpolate_rfr(date = as_date(t), exp = exp, ret_table = F) R
Calculate At-The-Money Forward Price F~0~
## Set expiration time to 4 PM exp <- exp + hours(16) ## Calculate maturity in years maturity <- time_length(exp-t, unit = "years") ## Calculate ATM Forward F_0 <- CBOE_F_0(option_quotes = option_quotes, R = R, maturity = maturity) F_0
Calculate At-The-Money Strike price K~0~
K_0 <- CBOE_K_0(option_quotes = option_quotes, F_0 = F_0) K_0
Select option quotes per CBOE rule
option_quotes <- CBOE_option_selection(option_quotes = option_quotes, K_0 = K_0) option_quotes
Calculate the Implied Variance σ^2^
sigma_sq <- CBOE_sigma_sq(sel_option_quotes = option_quotes, K_0 = K_0, F_0 = F_0, maturity = maturity, R = R) sigma_sq
Do the same for a second maturity, this time all at once. This observation will be our "next-term" contract.
## Select observation 5 t2 <- option_dataset$t[3] exp2 <- option_dataset$exp[3] option_quotes2 <- option_dataset$option_quotes[[3]] ## Risk free rate R2 <- interpolate_rfr(date = as_date(t2), exp = exp2, ret_table = F) ## Set expiration time to 4 PM exp2 <- exp2 + hours(16) ## Calculate maturity in years maturity2 <- time_length(exp2-t2,unit = "years") ## Calculate all VIX vars at once VIX_vars <- CBOE_VIX_vars(option_quotes = option_quotes2, R = R2, maturity = maturity2, ret_vars = T) VIX_vars
Calculate and interpolate the VIX index from both maturities
CBOE_VIX_index(maturity = c(maturity, maturity2), sigma_sq = c(sigma_sq,VIX_vars$sigma_sq))
Optionally calculate Option Descriptives, i.e. the strike price range and spacing in standard-deviation (SD) units of the used option quotes:
price <- option_dataset$price[2] option_descriptives(option_quotes = option_quotes, K_0 = K_0, R = R, price = price, maturity = maturity)
data.table and future.apply)To speed up the calculations, we employ parallelised versions of the apply family. However, you can still use the standard ones.
library(future.apply) plan(multisession, workers = 4) ## Parallelize using four cores
Determine the expiration terms for the interpolation. 1 indicates the near-term, 2 the next-term option. We only keep those observations which are relevant for the weekly and monthly VIX calculation.
## Determine maturity option_dataset[, maturity := time_length((exp + hours(16) - t),unit = "years")] ## Weekly and monthly expiration terms option_dataset[, `:=`(term_wk = future_sapply(maturity, CBOE_interpolation_terms, method = "weekly", future.seed = 1337), term_mn = future_mapply(CBOE_interpolation_terms, maturity, as_date(t), as_date(exp), MoreArgs = list(method = "monthly"), future.seed = 1337) )] ## Select only options needed for the weekly and monthly VIX option_dataset <- option_dataset[!is.na(term_wk) | !is.na(term_mn)] option_dataset
Calculate the Implied Variances for a complete dataset
## Calculate risk-free-rate and maturity option_dataset[, `:=`(R = interpolate_rfr(date = as_date(t), exp = exp))] ## Calculate CBOE MFIV for the whole dataset option_dataset[, sigma_sq := future_mapply(CBOE_VIX_vars, option_quotes, R, maturity, future.seed = 1337) ] option_dataset
Optionally, if you want to keep the intermediate variables:
## This function converts the mapply results below to a data.table multicols <- function(matrix){ data.table::as.data.table(t(matrix))[, lapply(.SD, unlist)] }
## Calculate VIX for the whole dataset, including intermediate variables option_dataset[, c("F_0", "K_0", "n_put_raw", "n_call_raw", "n_put", "n_call", "sigma_sq") := multicols(future_mapply(CBOE_VIX_vars, option_quotes, R, maturity, MoreArgs = list(ret_vars = T), future.seed = 1337) )] option_dataset
Calculate the VIX indices
## Weekly VIX weekly <- option_dataset[!is.na(term_wk)][, .(VIX_wk = CBOE_VIX_index(maturity = maturity, sigma_sq = sigma_sq)), by = .(ticker, t)] ## Monthly VIX monthly <- option_dataset[!is.na(term_mn)][, .(VIX_mn = CBOE_VIX_index(maturity = maturity, sigma_sq = sigma_sq)), by = .(ticker, t)] VIX_data <- weekly[monthly, on = .(ticker, t)] VIX_data
Display the data
plot_VIX(VIX_data)
You can use result_browser(VIX_data) to display an interactive Shiny App that allows to browse through the results
Calculate descriptive variables for the option-data quality
## Calculate the option descriptives using the `multicols()` function from above option_dataset[, c("SD", "max_K", "min_K", "mean_delta_K", "n_put", "n_call") := multicols(future_mapply(option_descriptives, option_quotes, K_0, R, price, maturity) )] option_dataset
## Use the Jiang & Tian (2007) smoothing method to fill in and extrapolate the option quotes. option_dataset[, option_quotes_smooth := future_mapply(JandT_2007_smoothing_method, option_quotes, K_0, price, R, maturity, F_0, SIMPLIFY = F)] option_dataset
Let's look at one nest of smoothed option_quotes
## Calculate the option descriptives using the `multicols()` function from above smooth_quotes <- option_dataset$option_quotes_smooth[[1]] min(smooth_quotes$K) max(smooth_quotes$K) length(smooth_quotes$K) ## Average spacing in price units mean(smooth_quotes$K - data.table::shift(smooth_quotes$K), na.rm = T) ## Spacing in SD units 3 / (option_dataset$SD[[1]] * option_dataset$price[[1]] * sqrt(option_dataset$maturity[[1]]))
Now calculate the MFIV using the Jiang & Tian (2007) method:
option_dataset[, sigma_sq_smooth := future_mapply(JandT_2007_sigma_sq, option_quotes_smooth, K_0, maturity, R)]
Calculate the respective VIX indices
## Weekly VIX weekly_smooth <- option_dataset[!is.na(term_wk)][, .(VIX_wk_smooth = CBOE_VIX_index(maturity = maturity, sigma_sq = sigma_sq_smooth)), by = .(ticker, t)] ## Monthly VIX monthly_smooth <- option_dataset[!is.na(term_mn)][, .(VIX_mn_smooth = CBOE_VIX_index(maturity = maturity, sigma_sq = sigma_sq_smooth)), by = .(ticker, t)] VIX_data_smooth <- weekly_smooth[monthly_smooth, on = .(ticker, t)] VIX_data_2 <- VIX_data[VIX_data_smooth, on = .(ticker, t)] plot_VIX(data = VIX_data_2, VIX_vars = c("VIX_wk", "VIX_mn", "VIX_wk_smooth", "VIX_mn_smooth"))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.