• No results found

Hestons pricing formula for a stochastic volatility

In document Financial Numerical Recipes in C++ pdf (Page 190-195)

Heston (1993) relaxes the Black-Scholes assumption of a constant volatility by introducing a stochastic volatility. He nds exact solutions for European options.

Let S be the stock price and v the volatility. These two variables are assumed to follow joint stochastic processes.

dS(t) = Sdt +pv(t)Sdz1(t)

dpv(t) = pv(t)dt + v(t)Sdz2(t)

The two processes z1 and z2 have correlation . Rewrite the process for the volatility as

dv(t) = ( v(t)) dt + pv(t)dz2

Let (S; v; t) be the price of volatility risk. Under a constant interest rate r P (t; T ) = e r(T t)

Consider a call option with strike price K. Its price is given by Formula 19.2. Price of Call option using Hestons formula The option price is

C(s; v; t) = SP1 KP (t; T )P2 where Pj(x; v; T; ln(K)) = 12+1 Z 1 0 Re e i ln(K)f j(x; v; T; ) i d fj(x; v; T; ) = eC(;)+D(;)v+ix C(; ) = ri +a2 (bj i + d) 2 ln 1 ged 1 g D(; ) = bj i + d2 1 ed 1 ged u1= 12; u2= 12 a = b1= + b2= + x = ln(S) g = bbj i + d j i d d =q(i bj)2 2(2uji 2) Notation: S: price of undelying security. K: exercise price.

The implementation of this pricing formula has some instructive C++ features. First, it illustrates cal-

culations of of complex variables. Complex numbers is part of the C++ standard, and are accessed by

including the

statement. Complex numbers are templated, it is necessary to specify what type of oating point type to use, such as complex<double> or complex<double double>.

To evaluate the price it is also necessary to do a numerical integration. In the calculation this is solved by a call to an external routine. We use a routine provided by the Gnu GSL project.1

Example

Given the following set of parameters: S = 100, K = 100, r = 0:01, v = 0:01, = 0:5, = 0, = 2, = 0, = 0:01 and = 0:01, price a call option using the Heston formula

C++program:

double S=100; double K=100; double r=0.01; double v=0.01; double tau=0.5; double rho=0; double kappa=2; double lambda=0.0; double theta=0.01; double sigma=0.01;

cout << "heston call price "

<< heston call option price( S, K, r, v, tau, rho, kappa, lambda, theta, sigma) << endl;

Output from C++program:

heston call price 3.06944

#include <iostream> #include <cmath> #include <complex> using namespace std;

#include "gsl/gsl_integration.h"

struct heston parms {double K; double x; double r; double v; double tau; double kappa; double theta; double rho; double sigma; double lambda; int j;};

extern "C"{

double heston integrand j(double phi, void *p){

struct heston parms* parms = (struct heston parms*)p; double K = (parms >K); double x = (parms >x); double v = (parms >v); double r = (parms >r); double kappa = (parms >kappa);

double theta = (parms >theta); double rho = (parms >rho); double sigma = (parms >sigma); double lambda = (parms >lambda); double tau = (parms >tau); double j = (parms >j);

double sigma sqr = pow(sigma,2); double uj; double bj;

if (j==1){ uj=0.5; bj=kappa+lambda rho*sigma; } else { uj= 0.5; bj=kappa+lambda; };

complex <double> i(0,1); double a = kappa*theta;

complex<double> d = sqrt( pow(rho*sigma*phi*i bj,2) sigma sqr*(2*uj*phi*i pow(phi,2)) ); complex<double> g = (bj rho*sigma*phi*i+d)/(bj rho*sigma*phi*i d);

complex<double> C = r*phi*i*tau+(a/sigma sqr)*((bj rho*sigma*phi*i+d)*tau 2.0*log((1.0 g*exp(d*tau))/(1.0 g))); complex<double> D = (bj rho*sigma*phi*i+d)/sigma sqr * ( (1.0 exp(d*tau))/(1.0 g*exp(d*tau)) );

complex<double> f1 = exp(C+D*v+i*phi*x); complex<double> F = exp( phi*i*log(K))*f1/(i*phi); return real(F);

};};

inline double heston Pj(double S, double K, double r, double v, double tau, double sigma, double kappa, double lambda, double rho, double theta, int j){ double x=log(S);

struct heston parms parms = { K, x, r, v, tau, kappa, theta, rho, sigma, lambda, j}; size t n=10000;

gsl integration workspace* w = gsl integration workspace alloc(n); gsl function F;

F.function = &heston integrand j; F.params=&parms;

double result, error;

gsl integration qagiu(&F,0,1e 7,1e 7,n,w,&result,&error); // integral to innity starting at zero return 0.5 + result/M PI;

};

double heston call option price(const double& S, const double& K, const double& r, const double& v, const double& tau, const double& rho, const double& kappa, const double& lambda, const double& theta, const double& sigma){ double P1 = heston Pj(S,K,r,v,tau,sigma,kappa,lambda,rho,theta,1);

double P2 = heston Pj(S,K,r,v,tau,sigma,kappa,lambda,rho,theta,2); double C=S*P1 K*exp( r*tau)*P2;

return C; };

Chapter 20

Pricing of bond options, basic models

Contents

20.1 Black Scholes bond option pricing . . . 192 20.2 Binomial bond option pricing . . . 194

The area of xed income securities is one where a lot of work is being done in creating advanced mathematical models for pricing of nancial securities, in particular xed income derivatives. The focus of the modelling in this area is on modelling the term structure of interest rates and its evolution over time, which is then used to price both bonds and xed income derivatives. However, in some cases one does not need the machinery of term structure modelling which we'll look at in later chapters, and price derivatives by modelling the evolution of the bond price directly.

Specically, suppose that the price of a Bond follows a Geometric Brownian Motion process, just like the case we have studied before. This is not a particularly realistic assumption for the long term behaviour of bond prices, since any bond price converges to the bond face value at the maturity of the bond. The Geometric Brownian motion may be OK for the case of short term options on long term bonds.

20.1 Black Scholes bond option pricing

Given the assumed Brownian Motion process, prices of European Bond Options can be found using the usual Black Scholes formula, as shown in C++Code 20.1 for a zero coupon bond and C++Code 20.2 for the

case of an option on a coupon bond.

#include <cmath> #include "normdist.h"

double bond option price put zero black scholes(const double& B, const double& X, const double& r, const double& sigma, const double& time){ double time sqrt = sqrt(time);

double d1 = (log(B/X)+r*time)/(sigma*time sqrt) + 0.5*sigma*time sqrt; double d2 = d1 (sigma*time sqrt);

double p = X * exp( r*time) * N( d2) B * N( d1); return p;

};

#include <cmath> #include <vector> using namespace std; #include "normdist.h" #include "fin_recipes.h"

double bond option price put coupon bond black scholes( const double& B, const double& X, const double& r, const double& sigma, const double& time,

const vector<double> coupon times, const vector<double> coupon amounts){ double adjusted B=B;

for (unsigned int i=0;i<coupon times.size();i++) { if (coupon times[i]<=time) {

adjusted B = coupon amounts[i] * exp( r*coupon times[i]); };

};

return bond option price put zero black scholes(adjusted B,X,r,sigma,time); };

In document Financial Numerical Recipes in C++ pdf (Page 190-195)