https://github.com/cran/fOptions
Tip revision: 429a9b1805024ce58873e3229048371980a535a2 authored by Diethelm Wuertz on 08 August 1977, 00:00:00 UTC
version 221.10065
version 221.10065
Tip revision: 429a9b1
xmpDWChapter084.R
#
# Examples from the forthcoming Monograph:
# Rmetrics - Financial Engineering and Computational Finance
# A Practitioner's Guide for R and SPlus Programmers
# written by Diethelm Wuertz
# ISBN to be published
#
# Details:
# Examples from Chapter 7.4
# Heston-Nandi Option Pricing
#
# List of Examples, Exercises and Code Snippets
#
# * Example: Computing the Price of Heston-Nandi Options
# * Example: Computing the Greeks of Heston-Nandi Options
# * Example: HN Options Pricing - GARCH(1,1) Simulation
# * Example: HN Options Pricing - Max LogLikelihood Estimation
# * Example: HN Options Pricing - Scaling of Prices
# * Example: Investigate the Smile Effect
#
# *** This list is not yet complete ***
#
# Author:
# (C) 2002-2005, Diethelm Wuertz, GPL
# www.rmetrics.org
# www.itp.phys.ethz.ch
# www.finance.ch
#
################################################################################
### Example: Computing the Price of Heston-Nandi Options
# Calculate the price of Heston-Nandi Garch(1,1)
# call and put options.
###
# Set the Model Parameters for the HN Garch(1,1) Option:
model = list(lambda = -0.5, omega = 5e-6, alpha = 1e-8,
beta = 0.7, gamma = 10)
S = X = 100
Time.inDays = 250
r.daily = 0.05/250
###
# List the R Function:
HNGOption
###
# Compute the Option Price:
# Call:
HNGOption(TypeFlag = "c", model, S, X, Time.inDays, r.daily)
# Put:
HNGOption(TypeFlag = "p", model, S, X, Time.inDays, r.daily)
###
# Compare with the Black-Scholes Formula:
# Unconditional Variance:
sigma2.daily = (model$alpha + model$omega) /
(1-model$beta-model$alpha*model$gamma^2)
# Call:
GBSOption("c", S = 100, X = 100, Time = 1, r = 0.05,
b = 0.05, sigma = sqrt(sigma2.daily*250))
# Put:
GBSOption("p", S = 100, X = 100, Time = 1, r = 0.05,
b = 0.05, sigma = sqrt(sigma2.daily*250))
###
# ------------------------------------------------------------------------------
### Example: Computing the Greeks of Heston-Nandi Options
# Calculate the sensitiviteis delta and gamma of
# Heston-Nandi Garch(1,1) call and put options.
###
# Option Parameters:
S = X = 100
Time.inDays = 125
r.daily = 0.05/250
model = list(lambda = -0.5, omega = 2.3e-6, alpha = 2.9e-6,
beta = 0.85, gamma = 184.25)
sigma.daily = sqrt((model$alpha + model$omega) /
(1 - model$beta - model$alpha*model$gamma^2))
# Print:
S; X; Time.inDays; r.daily; sigma.daily
model
###
# Compute the Delta
# and compare the result with the finite dfference approaximation:
Summary = NULL
# Call:
Greek = HNGGreeks("Delta", "c", model, S, X, Time.inDays, r.daily)
C1 = HNGOption("c", model, S*0.9999, X, Time.inDays, r.daily)$price
C2 = HNGOption("c", model, S*1.0001, X, Time.inDays, r.daily)$price
numGreek = (C2-C1)/(0.0002*S)
Diff = 100*(Greek-numGreek)/Greek
Summary = rbind(Summary, c(Greek, numGreek, Diff))
# Put:
Greek = HNGGreeks("Delta", "p", model, S, X, Time.inDays, r.daily)
C1 = HNGOption("p", model, S*0.9999, X, Time.inDays, r.daily)$price
C2 = HNGOption("p", model, S*1.0001, X, Time.inDays, r.daily)$price
numGreek = (C2-C1)/(0.0002*S)
Diff = 100*(Greek-numGreek)/Greek
Summary = rbind(Summary, c(Greek, numGreek, Diff))
# Print:
dimnames(Summary) <-
list(c("Call", "Put"), c("Greek", "numGreek", "Diff"))
Summary
###
# Do the same for the Gamma Sensitivity ...
Summary = NULL
# Call:
Greek = HNGGreeks("Gamma", "c", model, S, X, Time.inDays, r.daily)
C0 = HNGOption("c", model, S, X, Time.inDays, r.daily)$price
C1 = HNGOption("c", model, S*0.9999, X, Time.inDays, r.daily)$price
C2 = HNGOption("c", model, S*1.0001, X, Time.inDays, r.daily)$price
numGreek = (C2 - 2*C0 + C1)/(0.0002*S/2)^2
Diff = 100*(Greek-numGreek)/Greek
Summary = rbind(Summary, c(Greek, numGreek, Diff))
# Put:
Greek = HNGGreeks("Gamma", "p", model, S, X, Time.inDays, r.daily)
C0 = HNGOption("p", model, S, X, Time.inDays, r.daily)$price
C1 = HNGOption("p", model, S*0.9999, X, Time.inDays, r.daily)$price
C2 = HNGOption("p", model, S*1.0001, X, Time.inDays, r.daily)$price
numGreek = (C2 - 2*C0 + C1)/(0.0002*S/2)^2
Diff = 100*(Greek-numGreek)/Greek
Summary = rbind(Summary, c(Greek, numGreek, Diff))
# Print:
dimnames(Summary) <-
list(c("Call", "Put"), c("Greek", "numGreek", "Diff"))
Summary
###
# ------------------------------------------------------------------------------
### Example: HN Options Pricing - GARCH(1,1) Simulation
# Description:
# Simulate time series with the same parameters as those
# fitted by Heston and nandi to the SP500 data ranging
# the three years from 01/08/1992 to 12/30/1994.
# DATA:
# Index Value at 2:30 PM
# No. of observations 755
# r - TBill rate (3.7%)
# RESULT:
# lambda omega alpha beta gamma THETA PERS MLLH
# Sym: 0.7 1.6e-6 1.0e-6 0.92 --- 9.2% 0.92 3492
# Asym: 0.2 5.0e-6 1.0e-6 0.59 421 8.0% 0.77 3504
# Reference:
# S. Heston and S. Nandi, 1997
# A Closed-Form GARCH Option Pricing Model
###
# Fit a Symmetric HN-GARCH(1,1) Process:
set.seed(4711)
model = list(lambda = 0.7, omega = 1.6e-6, alpha = 1e-6,
beta = 0.92, gamma = 0, rf = 0.037/252)
ts.sym = hngarchSim(model, n = 755, n.start = 100)
par(mfcol = c(3, 2), cex = 0.5)
ts.plot(ts.sym, main = "Symmetric Data")
###
# Fit an Asymmetric HN-GARCH(1,1) Process:
set.seed(4711)
model = list(lambda = 0.2, omega = 5.0e-6, alpha = 1e-6,
beta = 0.59, gamma = 421, rf = 0.037/252)
ts.asym = hngarchSim(model, n = 755, n.start = 100)
ts.plot(ts.asym, main = "Asymmetric Data")
# Plot Both:
ts.plot(ts.asym, main = "Both Data Sets")
lines(ts.sym, col = "red")
###
# ACF Plots:
result = acf(abs(ts.sym), main = "ACF: Symmetric Data")
result = acf(abs(ts.asym), main = "ACF: Asymmetric Data")
###
# ------------------------------------------------------------------------------
### Example: HN Options Pricing - Max LogLikelihood Estimation
# Simulate time series with the same parameters as those
# fitted by Heston and nandi to the SP500 data ranging
# from 2/8/1992 to 30/12/1994, finally re-fit the parameters.
# DATA:
# Index Value at 2:30 PM
# No. of observations 755
# r - TBill rate (3.5%)
# RESULT:
# lambda omega alpha beta gamma THETA PERS MLLH
# Sym: 0.7 1.6e-6 1.0e-6 0.92 --- 9.2% 0.92 3492
# Asym: 0.2 5.0e-6 1.0e-6 0.59 421 8.0% 0.77 3504
# Reference:
# S. Heston and S. Nandi, 1997
# A Closed-Form GARCH Option Pricing Model
###
# SP500 Data from MASS Package:
require(MASS)
data(SP500)
returns = SP500[505:(505+755)]/100
model.sym = list(lambda = 0.2, omega = 1.6e-6, alpha = 1e-6,
beta = 0.92, gamma = 0, rf = 0.035/252)
model.asym = list(lambda = 0.7, omega = 5e-6, alpha = 1e-6,
beta = 0.59, gamma = 421, rf = 0.035/252)
###
# Estimate the Symmetric HN-GARCH(1,1) Parameters:
fit.sym = hngarchFit(x = returns, model = model.sym,
symmetric = TRUE)
fit.sym
###
# Estimate the Asymmetric HN-GARCH(1,1):
fit.asym = hngarchFit(x = returns, model = model.asym,
symmetric = FALSE)
fit.asym
###
# Summarize Results:
data.frame(cbind(
SYM = unlist(model.sym),
SYM.FIT = unlist(fit.sym$model),
ASYM = unlist(model.asym),
ASYM.FIT = unlist(fit.asym$model)
))
###
# Diagnostic Analysis:
par(mfcol = c(3,2), cex=0.5)
summary(fit.sym)
summary(fit.asym)
###
# Moment Statistics:
unlist(hngarchStats(model.sym))
unlist(hngarchStats(model.asym))
unlist(hngarchStats(fit.sym$model))
unlist(hngarchStats(fit.asym$model))
###
# ------------------------------------------------------------------------------
### Example: HN Options Pricing - Scaling of Prices
# The example shows for the HN Garch(1,1) model
# the scaling in price/strike and volatility*time.
###
# Initial Parameter Setting:
scales = c(1/2, 1, 2)
Model = list(lambda=-0.5, omega=1e-6, alpha=1e-6, beta=0.5, gamma=0)
par (mfrow = c(2, 2), cex = 0.7)
###
# Price/Strike Variation:
S = seq(75, 125, by = 5); X = 100
Time = 126
###
# HNG:
plot(x = c(0.75, 1.25), y = c(0, 28), type = "n",
xlab = "S/X", ylab = "Call Price",
main = "HN: Volatility*Time fixed")
for (j in 1:length(scales)) {
model = Model
model$omega = Model$omega*scales[j]
model$alpha = Model$alpha*scales[j]
for (i in 1:length(S)) {
x = S[i]/X
y = HNGOption("c", model, S[i], X, Time/scales[j], 0)$price
points(x, y, col = j, pch = (j+2)) } }
legend(0.8, 26, legend = c("scale = 1/2", "scale = 1", "scale = 2"),
pch = "\3\4", bty = "n", col = 1:3)
###
# BS:
plot(x = c(0.75, 1.25), y = c(0, 28), type = "n",
xlab = "S/X", ylab = "Call Price",
main = "BS: Volatility*Time fixed")
for (j in 1:length(scales)) {
model = Model
model$omega = Model$omega/scales[j]
model$alpha = Model$alpha/scales[j]
sigma = sqrt((model$alpha+model$omega)/(1-model$beta))
print(sigma^2 * Time*scales[j])
for (i in 1:length(S)) {
x = S[i]/X
y = GBSOption("c", S[i], X, Time*scales[j], r=0, b=0,
sigma=sigma)$price
points(x, y, col = j, pch = (j+2)) } }
legend(0.8, 26, legend = c("scale = 1/2", "scale = 1", "scale = 2"),
pch = "\3\4", bty = "n", col = 1:3)
###
# Volatility*Time Variation:
S = 100; X = 100
Time = c((12:1)*21, 5, 1)
sigma = sqrt((Model$alpha+Model$omega)/(1-Model$beta)); 252*sigma
###
# HNG:
plot(x = c(-252, 0) , y = c(1.5, 0), type = "n", xlab = "Days",
ylab = "Put Price / scale", main = "HN: S/X fixed")
for ( j in 1:length(scales) ) {
S.scaled = S*scales[j]; X.scaled = X*scales[j]
for (i in 1:length(Time)) {
x = -Time[i]
y = HNGOption("c", Model, S.scaled, X.scaled, Time[i], 0)$price /
scales[j]
points(x, y, col = j, pch = (j+2)) } }
legend(-240, 0.6, legend = c("scale = 0.5", "scale = 1", "scale = 2"),
pch = "\3\4", bty = "n", col = 1:3)
###
# BS:
plot(x = c(-252, 0) , y = c(1.5, 0), type = "n", xlab = "Days",
ylab = "Put Price / scale ", main = "BS: S/X fixed")
for (j in 1:length(scales) ) {
S.scaled = S*scales[j]; X.scaled = X*scales[j]
for (i in 1:length(Time)) {
x = -Time[i]
y = GBSOption("c", S.scaled, X.scaled, Time[i], 0, 0, sigma)$price /
scales[j]
points(x, y, col = j, pch = (j+2)) } }
legend(-240, 0.6, legend = c("scale = 0.5", "scale = 1", "scale = 2"),
pch = "\3\4", bty = "n", col = 1:3)
###
# ------------------------------------------------------------------------------
### Example: Investigate the Smile Effect
# This program calculates for the estimated symmetric and asymmetric
# Garch(1,1) the implied volatility from the Black and Scholes Option
# Pricing formula assuming that the real market follows ideally the
# Heston Nandi Option Garch(1,1) model
###
# Show the GBSVolatility function:
GBSVolatility
###
# Compute Smile - Parameters:
S = 85:115; X = 100
Time.inDays = 126
model = list(lambda=-0.5, omega=6e-6, alpha=4e-6, beta=0.8, gamma=0)
sigma = sqrt(252*(model$alpha+model$omega)/(1-model$beta))
sigma
###
# Pricing the Put:
Put <- impVola <- NULL
for (i in 1:length(S)) {
Price = HNGOption("p", model, S[i], X, Time.inDays, 0)$price
Put = c(Put, Price)
Volatility = GBSVolatility(Price, "p", S[i], X, Time.inDays/252, 0, 0)
impVola = c(impVola, Volatility)
cat("\n\t", i, "\t", S[i], "\t", Price, "\t", Volatility) }
###
# Plot:
par(mfrow = c(2, 2), cex = 0.7)
plot(S/X, Put,
xlab = "S/X", ylab = "Price", main = "HN Put Price")
plot(S/X, impVola,
xlab = "S/X", ylab = "Volatility", main = "BS Implied Volatility")
###
################################################################################