Nothing
## ---- include = FALSE---------------------------------------------------------
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.width = 7,
fig.height = 6,
fig.align = 'center'
)
## ----setup--------------------------------------------------------------------
library(NFCP)
# Set seed for reproducibility:
set.seed(412)
## -----------------------------------------------------------------------------
model_parameters_2F <- NFCP_parameters(N_factors = 2,
GBM = TRUE,
initial_states = FALSE,
N_ME = 5)
## Print the vector of parameters of the specified commodity pricing model:
print(model_parameters_2F)
## -----------------------------------------------------------------------------
###Method 1 - Stitch Crude Oil Contracts according to maturity matching:
SS_oil_stitched <- stitch_contracts(futures = SS_oil$contracts,
futures_TTM = c(1, 5, 9, 13, 17)/12, maturity_matrix = SS_oil$contract_maturities,
rollover_frequency = 1/12, verbose = TRUE)
##Plot the Stitched Maturities:
matplot(as.Date(rownames(SS_oil_stitched$maturities)), SS_oil_stitched$maturities,
type = 'l', main = "Stitched Contract Maturities",
ylab = "Time To Maturity (Years)", xlab = "Date", col = 1)
## -----------------------------------------------------------------------------
print(SS_oil$two_factor)
## -----------------------------------------------------------------------------
##Example 1 - Replicating the Schwartz and Smith (2000)
##Two-Factor Crude Oil commodity pricing model:
Oil_2F <- NFCP_Kalman_filter(
parameter_values = SS_oil$two_factor,
parameter_names = names(SS_oil$two_factor),
log_futures = log(SS_oil$stitched_futures),
futures_TTM = SS_oil$stitched_TTM,
dt = SS_oil$dt,
verbose = TRUE,
debugging = TRUE)
## -----------------------------------------------------------------------------
Oil_2F_parameters <- SS_oil$two_factor[1:7]
### Assume a constant measurement error in parameters of 1%:
Oil_2F_parameters["ME_1"] <- 0.01
Oil_2F_contracts <- NFCP_Kalman_filter(
parameter_values = Oil_2F_parameters,
parameter_names = names(Oil_2F_parameters),
log_futures = log(SS_oil$contracts),
futures_TTM = SS_oil$contract_maturities,
dt = SS_oil$dt,
verbose = TRUE,
debugging = TRUE)
## -----------------------------------------------------------------------------
print(SS_oil$two_factor[8:12])
## -----------------------------------------------------------------------------
# Estimate a GBM model:
Oil_1F <- NFCP_MLE(
## Arguments
log_futures = log(SS_oil$stitched_futures),
dt = SS_oil$dt,
futures_TTM= SS_oil$stitched_TTM,
N_factors = 1,
N_ME = 3,
ME_TTM = c(0.5, 1, 1.5),
print.level = 0)
##Print results:
print(round(rbind(`Estimated Parameter` = Oil_1F$estimated_parameters,
`Standard Error` = Oil_1F$standard_errors),4))
## -----------------------------------------------------------------------------
print(matrix(c(Oil_1F$MLE, Oil_2F$`Log-Likelihood`),
dimnames = list(c("One-Factor", "Two-Factor"), "Log-Likelihood")))
## -----------------------------------------------------------------------------
print(round(rbind("One-Factor" = Oil_1F$`Information Criteria`,
"Two-Factor" = Oil_2F$`Information Criteria`), 4))
## -----------------------------------------------------------------------------
##Replicate Table 3 of Schwartz and Smith (2000):
print(round(t(Oil_2F[["Term Structure Fit"]]),4))
## -----------------------------------------------------------------------------
CN_table3 <- matrix(nrow = 2, ncol = 2, dimnames = list(c("One-Factor","Two-Factor"), c("RMSE", "Bias")))
CN_table3[,"Bias"] <- c(Oil_1F$`Filtered Error`["Bias"], Oil_2F$`Filtered Error`["Bias"])
CN_table3[,"RMSE"] <- c(Oil_1F$`Filtered Error`["RMSE"], Oil_2F$`Filtered Error`["RMSE"])
print(round(CN_table3, 4))
## ---- out.width='.49\\linewidth'----------------------------------------------
##One Factor
matplot(as.Date(rownames(Oil_1F$V)), Oil_1F$V, type = 'l',
xlab = "", ylab = "Observation Error",
main = "Contract Observation Error: One-Factor Model"); legend("bottomright",
colnames(Oil_2F$V),col=seq_len(5),cex=0.8,fill=seq_len(5))
##Two-Factor
matplot(as.Date(rownames(Oil_2F$V)), Oil_2F$V, type = 'l',
xlab = "", ylab = "Observation Error", ylim = c(-0.3, 0.2),
main = "Contract Observation Error: Two-Factor Model"); legend("bottomright",
colnames(Oil_2F$V),col=seq_len(5),cex=0.8,fill=seq_len(5))
## -----------------------------------------------------------------------------
matplot(cbind(Oil_1F$`Term Structure Fit`["RMSE",], Oil_2F$`Term Structure Fit`["RMSE",]),
type = 'l', main = "Root Mean Squared Error of Futures Contracts",
xlab = "Contract", ylab = "RMSE"); legend("right",c("One-Factor", "Two-Factor"),
col=1:2,cex=0.8,fill=1:2)
## -----------------------------------------------------------------------------
##Replicate Figure 4 of Schwartz and Smith (2000):
SS_figure_4 <- cbind(`Equilibrium Price` =
exp(Oil_2F$X[,1]),
`Spot Price` =
Oil_2F$Y[,"filtered Spot"])
matplot(as.Date(rownames(SS_figure_4)), SS_figure_4, type = 'l',
xlab = "", ylab = "Oil Price ($/bbl, WTI)", col = 1,
main = "Estimated Spot and Equilibrium Prices for the Futures Data")
## -----------------------------------------------------------------------------
plot(as.Date(rownames(SS_oil$contracts)), sqrt(Oil_2F_contracts$P_t[1,1,]),
type = 'l', xlab = "Date", ylab = "Std. Dev.",
main = "Time Series of the Std. Dev for State Variable 1")
## -----------------------------------------------------------------------------
##Figure 1 and 2 of Schwartz and Smith (2000) was developed using Enron data
##and an assumption that mu was approximately 3% p.a.:
Enron_values <- c(0.0300875, 0.0161, 0.014, 1.19, 0.115, 0.158, 0.189)
names(Enron_values) <- NFCP_parameters(2, TRUE, FALSE, 0, FALSE, FALSE)
## -----------------------------------------------------------------------------
## Replicate figure 1 of Schwartz and Smith (2000):
SS_expected_spot <- spot_price_forecast(x_0 = c(2.857, 0.119),
parameters = Enron_values,
t = seq(0,9,1/12),
percentiles = c(0.1, 0.9))
##Factor one only:
equilibrium_theta <- Enron_values[!names(Enron_values) %in%
c("kappa_2", "lambda_2", "sigma_2", "rho_1_2")]
SS_expected_equilibrium <- spot_price_forecast(x_0 = c(2.857, 0),
equilibrium_theta,
t = seq(0,9,1/12),
percentiles = c(0.1, 0.9))
SS_figure_1 <- cbind(SS_expected_spot, SS_expected_equilibrium)
matplot(seq(0,9,1/12), SS_figure_1, type = 'l', col = 1, lty = c(rep(1,3), rep(2,3)),
xlab = "Time (Years)", ylab = "Spot Price ($/bbl, WTI)",
main = "Probabilistic Forecasts for Spot and Equilibrium Prices")
## -----------------------------------------------------------------------------
## Replicate Figure 2 of Schwartz and Smith (2000):
#Forecast expected spot prices under the "True" stochastic process:
SS_expected_spot <- spot_price_forecast(x_0 = c(2.857, 0.119),
parameters = Enron_values,
t = seq(0,9,1/12),
percentiles = c(0.1, 0.9))
#Forecast expected futures prices under the Risk-Neutral stochastic process:
SS_futures_curve <- futures_price_forecast(x_0 = c(2.857, 0.119),
parameters = Enron_values,
futures_TTM = seq(0,9,1/12))
SS_figure_2 <- cbind(SS_expected_spot[,2], SS_futures_curve)
matplot(seq(0,9,1/12), log(SS_figure_2), type = 'l', col = 1,
xlab = "Time (Years)", ylab = "Log(Price)",
main = "Futures Prices and Expected Spot Prices")
## -----------------------------------------------------------------------------
## Maximum Observed Maturity:
max_maturity <- max(tail(SS_oil$contract_maturities,1), na.rm = TRUE)
##Estimated Futures Prices:
### One Factor (GBM):
oil_TS_1F <- futures_price_forecast(x_0 = Oil_1F$x_t,
parameters = Oil_1F$estimated_parameters,
futures_TTM = seq(0,max_maturity,1/12))
### Two Factor:
oil_TS_2F <- futures_price_forecast(x_0 = Oil_2F$x_t,
parameters = SS_oil$two_factor,
futures_TTM = seq(0,max_maturity,1/12))
matplot(seq(0,max_maturity,1/12), cbind(oil_TS_1F, oil_TS_2F), type = 'l',
xlab = "Maturity (Years)", ylab = "Futures Price ($)",
main = "Estimated and observed oil futures prices on 1995-02-14");
points(tail(SS_oil$contract_maturities,1), tail(SS_oil$contracts,1))
legend("bottomleft", c("One-factor", "Two-Factor", "Observed"),
col=2:4,cex=0.8,fill=c(1,2,0))
## -----------------------------------------------------------------------------
###Test the Volatility Term Structure Fit of the Schwartz-Smith Two-Factor Oil Model:
V_TSFit <- TSfit_volatility(
parameters = SS_oil$two_factor,
futures = SS_oil$stitched_futures,
futures_TTM = SS_oil$stitched_TTM,
dt = SS_oil$dt)
##Plot Results:
matplot(V_TSFit["Maturity",], cbind(Oil_1F$`Term Structure Volatility Fit`["Theoretical Volatility",],
V_TSFit["Theoretical Volatility",]), type = 'l',
xlab = "Maturity (Years)", ylab = "Volatility (%)",
ylim = c(0, 0.5), main = "Volatility Term Structure of Futures Returns"); points(
V_TSFit["Maturity",], V_TSFit["Empirical Volatility",]); legend("bottomleft",
c("Empirical", "One-Factor", "Two-Factor"),col=0:2,cex=0.8,fill=0:2)
## -----------------------------------------------------------------------------
##100 antithetic simulations of one year of monthly observations
simulated_spot_prices <- spot_price_simulate(
x_0 = Oil_2F$x_t,
parameters = SS_oil$two_factor,
t = 1,
dt = 1/12,
N_simulations = 1e3,
antithetic = TRUE,
verbose = TRUE)
##Plot Price Paths:
matplot(seq(0,1,1/12), simulated_spot_prices$spot_prices, type = 'l',
xlab = "Forecasting Horizon (Years)",
ylab = "Spot Price ($/bbl, WTI)", main = "Simulated Crude Oil prices")
## -----------------------------------------------------------------------------
##Plot 95% Prediction interval:
prediction_interval <- rbind.data.frame(apply(simulated_spot_prices$spot_prices, 1,
FUN = function(x) stats::quantile(x, probs = c(0.025, 0.975))),
Mean = rowMeans(simulated_spot_prices$spot_prices))
matplot(seq(0,1,1/12), t(prediction_interval), type = 'l', col = c(2,2,1),
lwd = 2, lty = c(2,2,1), xlab = "Forecasting Horizon (Years)",
ylab = "Spot Price ($/bbl, WTI)", main = "Simulated Crude Oil 95% Confidence Interval")
## -----------------------------------------------------------------------------
## Simulate Crude Oil Contract Prices under a Two-Factor model
simulated_contracts <- futures_price_simulate(x_0 = c(log(SS_oil$spot[1,1]), 0),
parameters = Oil_2F_parameters,
dt = SS_oil$dt,
N_obs = nrow(SS_oil$contracts),
futures_TTM = SS_oil$contract_maturities)
##Plot Simulated prices:
matplot(as.Date(rownames(SS_oil$contracts)), simulated_contracts$futures_prices,
type = 'l', ylab = "Futures Price ($/bbl, WTI)", xlab = "Observations",
main = "Simulated Futures Contracts")
## -----------------------------------------------------------------------------
Option_prices <- matrix(rep(0,2), nrow = 2, ncol = 3, dimnames = list(c("One-Factor", "Two-Factor"), c("European", "American", "Early Exercise Value")))
# Strike Price:
strike <- 20
# Annual risk-free interest rate:
risk_free <- 0.05
# Maturity of option and future:
option <- 1
future <- 2
## American option only - number of antithetic simulations, time step (in years):
time_step <- 1/50
monte_carlo <- 1e5
## One-factor European put option value:
Option_prices[1,1] <- European_option_value(x_0 = Oil_1F$x_t,
parameters = Oil_1F$estimated_parameters,
futures_maturity = future, option_maturity = option, K = strike, r = risk_free)
## Two-factor European put option value:
Option_prices[2,1] <- European_option_value(x_0 = Oil_2F$x_t,
parameters = SS_oil$two_factor,
futures_maturity = future, option_maturity = option, K = strike, r = risk_free)
## One-factor American put option value:
Option_prices[1,2] <- American_option_value(x_0 = Oil_1F$x_t,
parameters = Oil_1F$estimated_parameters,
futures_maturity = future, option_maturity = option, K = strike, r = risk_free,
N_simulations = monte_carlo, dt = time_step)
## Two-factor American put option value:
Option_prices[2,2] <- American_option_value(x_0 = Oil_2F$x_t,
parameters = SS_oil$two_factor,
futures_maturity = future, option_maturity = option, K = strike, r = risk_free,
N_simulations = monte_carlo, dt = time_step)
Option_prices[,3] <- Option_prices[,2] - Option_prices[,1]
## Print results:
print(round(Option_prices,3))
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.