The final method of calculating the Greeks is to use a combination of the FDM and Monte Carlo. The overall method is the same as above, with the exception that we will replace the analytical prices of the call/puts in the Finite Difference approximation and use a Monte Carlo engine instead to calculate the prices. This method is significantly more versatile as it can be extended to many differing types of contingent claim prices.
It is extremely important to re-use the random draws from the initial Monte Carlo simu- lation in calculating the incremented/decremented parameter paths. Thus, when calculating C(S, K, r, v, T ) and C(S + ∆S, K, r, v, T ) it is necessary to use the same random draws. Further, it is significantly more optimal as there is no need to calculate additional asset paths for each incremented parameter instance.
The following code calculates the Monte Carlo price for the Delta and the Gamma, making use of separate Monte Carlo prices for each instance. The essence of the Monte Carlo method is to calculate three separate stock paths, all based on the same Gaussian draws. Each of these draws will represent an increment (or not) to the asset path parameter, S. Once those paths have been generated a price for each can be calculated. This price is then substituted into the FDM derivative approximations, in exactly the same way as with the analytical formulae.
The final prices are passed to the monte carlo call price function by reference and the function itself isvoid. This provides a simple mechanism for returning multipledoubles from the function. An alternative would be to pass a vector of values by reference, to be set.
It is straightforward to modify the code to calculate the Vega, Rho or Theta (based on the Delta). A more ’production ready’ implementation would utilise an object-oriented framework. However, for the purposes of this chapter an OOP-based implementation would likely obscure the algorithm:
#include ” b l a c k s c h o l e s . h”
// P r i c i n g a European v a n i l l a c a l l o p t i o n w i t h a Monte C a r l o method // C r e a t e t h r e e s e p a r a t e p a t h s , e a c h w i t h e i t h e r an i n c r e m e n t , non− // i n c r e m e n t o r d e c r e m e n t b a s e d on d e l t a S , t h e s t o c k p a t h p a r a m e t e r
void m o n t e c a r l o c a l l p r i c e (const i n t num sims ,
const double S , const double K, const double
r ,
const double v , const double T, const double
double& p r i c e S p , double& p r i c e S , double& p r i c e S m ) {
// S i n c e we w i s h t o u s e t h e same G a u s s i a n random draws f o r e a c h p a t h , i t i s // n e c e s s a r y t o c r e a t e t h r e e s e p a r a t e d a d j u s t e d s t o c k p a t h s f o r e a c h // i n c r e m e n t / d e c r e m e n t o f t h e a s s e t double S p a d j u s t = ( S+d e l t a S ) ∗ exp (T∗ ( r −0.5∗ v∗v ) ) ; double S a d j u s t = S ∗ exp (T∗ ( r −0.5∗ v∗v ) ) ; double S m a d j u s t = ( S−d e l t a S ) ∗ exp (T∗ ( r −0.5∗ v∗v ) ) ; // These w i l l s t o r e a l l t h r e e ’ c u r r e n t ’ p r i c e s a s t h e Monte C a r l o // a l g o r i t h m i s c a r r i e d o u t double S p c u r = 0 . 0 ; double S c u r = 0 . 0 ; double Sm cur = 0 . 0 ;
// There a r e t h r e e s e p a r a t e pay−o f f sums f o r t h e f i n a l p r i c e
double p a y o f f s u m p = 0 . 0 ;
double p a y o f f s u m = 0 . 0 ;
double p a y o f f s u m m = 0 . 0 ;
// Loop o v e r t h e number o f s i m u l a t i o n s
f o r (i n t i =0; i <num sims ; i ++) {
double gauss bm = g a u s s i a n b o x m u l l e r ( ) ; // Random g a u s s i a n draw
// A d j u s t t h r e e s t o c k p a t h s
double e x p g a u s s = exp ( s q r t ( v∗v∗T) ∗ gauss bm ) ; // P r e c a l c u l a t e S p c u r = S p a d j u s t ∗ e x p g a u s s ; S c u r = S a d j u s t ∗ e x p g a u s s ; Sm cur = S m a d j u s t ∗ e x p g a u s s ; // C a l c u l a t e t h e c o n t i n u a l pay−o f f sum f o r e a c h i n c r e m e n t / d e c r e m e n t p a y o f f s u m p += s t d : : max ( S p c u r − K, 0 . 0 ) ; p a y o f f s u m += s t d : : max ( S c u r − K, 0 . 0 ) ; p a y o f f s u m m += s t d : : max ( Sm cur − K, 0 . 0 ) ; }
151
// There a r e t h r e e s e p a r a t e p r i c e s
p r i c e S p = ( p a y o f f s u m p / s t a t i c c a s t<double>(num sims ) ) ∗ exp(− r ∗T) ; p r i c e S = ( p a y o f f s u m / s t a t i c c a s t<double>(num sims ) ) ∗ exp(− r ∗T) ; p r i c e S m = ( p a y o f f s u m m / s t a t i c c a s t<double>(num sims ) ) ∗ exp(− r ∗T) ; }
double c a l l d e l t a m c (const i n t num sims , const double S , const double K,
const double r , const double v , const double T, const double d e l t a S ) { // These v a l u e s w i l l b e p o p u l a t e d v i a t h e m o n t e c a r l o c a l l p r i c e f u n c t i o n . // They r e p r e s e n t t h e i n c r e m e n t e d Sp ( S+d e l t a S ) , non−i n c r e m e n t e d S ( S ) and // d e c r e m e n t e d Sm ( S−d e l t a S ) p r i c e s . double p r i c e S p = 0 . 0 ; double p r i c e S = 0 . 0 ; double p r i c e S m = 0 . 0 ; // C a l l t h e Monte C a r l o p r i c e r f o r e a c h o f t h e t h r e e s t o c k p a t h s // (We o n l y need two f o r t h e D e l t a )
m o n t e c a r l o c a l l p r i c e ( num sims , S , K, r , v , T, d e l t a S , p r i c e S p , p r i c e S , p r i c e S m ) ;
return ( p r i c e S p − p r i c e S ) / d e l t a S ; }
double call gamma mc (const i n t num sims , const double S , const double K,
const double r , const double v , const double T, const double d e l t a S ) { // These v a l u e s w i l l b e p o p u l a t e d v i a t h e m o n t e c a r l o c a l l p r i c e f u n c t i o n . // They r e p r e s e n t t h e i n c r e m e n t e d Sp ( S+d e l t a S ) , non−i n c r e m e n t e d S ( S ) and // d e c r e m e n t e d Sm ( S−d e l t a S ) p r i c e s . double p r i c e S p = 0 . 0 ; double p r i c e S = 0 . 0 ; double p r i c e S m = 0 . 0 ; // C a l l t h e Monte C a r l o p r i c e r f o r e a c h o f t h e t h r e e s t o c k p a t h s
// (We need a l l t h r e e f o r t h e Gamma) m o n t e c a r l o c a l l p r i c e ( num sims , S , K, r , v , T, d e l t a S , p r i c e S p , p r i c e S , p r i c e S m ) ; return ( p r i c e S p − 2∗ p r i c e S + p r i c e S m ) / ( d e l t a S ∗ d e l t a S ) ; } i n t main (i n t a r g c , char ∗∗ a r g v ) { // F i r s t we c r e a t e t h e p a r a m e t e r l i s t double S = 1 0 0 . 0 ; // O p t i o n p r i c e double d e l t a S = 0 . 0 0 1 ; // O p t i o n p r i c e i n c r e m e n t double K = 1 0 0 . 0 ; // S t r i k e p r i c e double r = 0 . 0 5 ; // Risk−f r e e r a t e (5%) double v = 0 . 2 ; // V o l a t i l i t y o f t h e u n d e r l y i n g (20%) double T = 1 . 0 ; // One y e a r u n t i l e x p i r y
i n t num sims = 1 0 0 0 0 0 0 0 0 ; // Number o f s i m u l a t i o n s t o c a r r y o u t f o r Monte C a r l o
// Then we c a l c u l a t e t h e D e l t a and t h e Gamma f o r t h e c a l l
double c a l l d e l t a m = c a l l d e l t a m c ( num sims , S , K, r , v , T, d e l t a S ) ;
double call gamma m = call gamma mc ( num sims , S , K, r , v , T, d e l t a S ) ;
// F i n a l l y we o u t p u t t h e p a r a m e t e r s and g r e e k s
s t d : : c o u t << ”Number o f s i m s : ” << num sims << s t d : : e n d l ; s t d : : c o u t << ” U n d e r l y i n g : ” << S << s t d : : e n d l ; s t d : : c o u t << ” D e l t a u n d e r l y i n g : ” << d e l t a S << s t d : : e n d l ; s t d : : c o u t << ” S t r i k e : ” << K << s t d : : e n d l ; s t d : : c o u t << ” Risk−F r e e Rate : ” << r << s t d : : e n d l ; s t d : : c o u t << ” V o l a t i l i t y : ” << v << s t d : : e n d l ; s t d : : c o u t << ” M a t u r i t y : ” << T << s t d : : e n d l << s t d : : e n d l ; s t d : : c o u t << ” C a l l D e l t a : ” << c a l l d e l t a m << s t d : : e n d l ; s t d : : c o u t << ” C a l l Gamma: ” << call gamma m << s t d : : e n d l ; }
Here is the output of the program:
Number o f s i m s : 1 0 0 0 0 0 0 0 0 U n d e r l y i n g : 100
153 Delta Gamma Analytic 0.636831 0.018762 FDM/Analytic 0.636845 0.0187633 FDM/MC 0.636894 0.0188733 D e l t a u n d e r l y i n g : 0 . 0 0 1 S t r i k e : 100 Risk−F r e e Rate : 0 . 0 5 V o l a t i l i t y : 0 . 2 M a t u r i t y : 1 C a l l D e l t a : 0 . 6 3 6 8 9 4 C a l l Gamma: 0 . 0 1 8 8 7 3 3
Here is a summary table with the calculation of the Delta and Gamma for a European vanilla call option across all of the methods listed above:
The values are extremely similar, even for the Monte Carlo based approach, albeit at the computational expense of generating the random draws. The FDM/MC approach can be applied to other contingent claims where an analytical solution is not forthcoming and this is often the method used in practice.
Chapter 12
Asian/Path-Dependent Options
with Monte Carlo
In this chapter I’m going to discuss how to price a certain type of Exotic option known as a Path-Dependent Asian in C++ using Monte Carlo Methods. It is considered ”exotic” in the sense that the pay-off is a function of the underlying asset at multiple points throughout its lifetime, rather than just the value at expiry. It is an example of a multi look option. An Asian option utilises the mean of the underlying asset price sampled at appropriate intervals along its lifetime as the basis for its pay-off, which is where the “path-dependency” of the asset comes from. The name actually arises because they were first devised in 1987 in Tokyo as options on crude oil futures.
There are two types of Asian option that we will be pricing. They are the arithmetic Asian and the geometric Asian. They differ only in how the mean of the underlying values is calculated. We will be studying discrete Asian options in this chapter, as opposed to the theoretical continuous Asian options. The first step will be to break down the components of the program and construct a set of classes that represent the various aspects of the pricer. Before that however, I will brief explain how Asian options work (and are priced by Monte Carlo).