design_pattern_derivative_payoff

In the option pricing framework, the first component which always changes is option's payoff.  Therefore, we need to  encapsulation the payoff class. First of all, we define an abstract PayOff class,

class PayOff{
public:
    PayOff(){};
    virtual double operator()(double spot) const = 0;
    virtual ~PayOff(){}
};
Note that

1. we need to define a pure virtual function, given the spot price, this function needs to be able to calculate option payoff.

2. the destructor needs to be virtual, otherwise, the derived class will always call the base destructor.

Then we have derived class for call and put options, what the derived classes need to do is to implement the virtual function.

class PayOffCall : public PayOff{
public:
    PayOffCall(double strike_):strike(strike_){}
    virtual double operator()(double spot) const{
        double value = spot - strike;
        return (value > 0 ? value : 0);
    }
    virtual ~PayOffCall(){}
private:
    double strike;
};

class PayoffPut : public PayOff{
public:
    PayOffPut(double strike_):strike(strike_){}
    virtual double operator()(double spot) const {
        double value = strike - spot;
        return (value > 0 ? value : 0);
    }
    virtual ~PayOffPut(){}
private:
    double strike;
};
We use the payoff class in a simple monte carlo fuction. The monte carlo function simulates a geometric Brownian motion, and use it to price European option. The gsl library is used to generate random numbers. The question is how should we pass the payoff class into such as monte carlo simulation function. One way is to use reference

#ifndef MONTECARLO_HPP_INCLUDED
#define MONTECARLO_HPP_INCLUDED

#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>

double SimpleMonteCarlo2(PayOff& thePayOff, double Expiry, double Spot, double Vol, double r, unsigned long NumberOfPaths){
    const gsl_rng_type * T;
    gsl_rng * rnd;
    gsl_rng_env_setup();
    T = gsl_rng_default;
    rnd = gsl_rng_alloc (T);

	double variance = Vol*Vol*Expiry;
	double rootVariance = sqrt(variance);
	double itoCorrection = -0.5*variance;
	double movedSpot = Spot*exp(r*Expiry+itoCorrection);
	double thisSpot;
	double runningSum=0;

	for (unsigned long i=0; i < NumberOfPaths; i++){
		double thisGaussian = gsl_ran_gaussian(rnd, 1.0);
		thisSpot = movedSpot*exp(rootVariance*thisGaussian);
		double thisPayOff = thePayOff(thisSpot);
		runningSum += thisPayOff;
	}

	double mean = runningSum / NumberOfPaths;
	mean *= exp(-r*Expiry);

	gsl_rng_free (rnd);

	return mean;
}
#endif // MONTECARLO_HPP_INCLUDED
Suppose we use

double SimpleMonteCarlo2(PayOff thePayOff, double Expiry, double Spot, double Vol, double r, unsigned long NumberOfPaths){}
There could be several problems,

1. payoff is an abstract class, therefore, complier will complain, we cannot create an object for abstract class.

2. we pass parameter by value not by reference, therefore, the default copy constructor will be called, then all the information of derived class could loss during the copy.

Another method is to pass a base class pointer, because we could always cast a derived class pointer to a base class pointer.

#ifndef MONTECARLO_HPP_INCLUDED
#define MONTECARLO_HPP_INCLUDED

#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>

double SimpleMonteCarlo2(PayOff* thePayOff, double Expiry, double Spot, double Vol, double r, unsigned long NumberOfPaths){
    const gsl_rng_type * T;
    gsl_rng * rnd;
    gsl_rng_env_setup();
    T = gsl_rng_default;
    rnd = gsl_rng_alloc (T);

	double variance = Vol*Vol*Expiry;
	double rootVariance = sqrt(variance);
	double itoCorrection = -0.5*variance;
	double movedSpot = Spot*exp(r*Expiry+itoCorrection);
	double thisSpot;
	double runningSum=0;

	for (unsigned long i=0; i < NumberOfPaths; i++){
		double thisGaussian = gsl_ran_gaussian(rnd, 1.0);
		thisSpot = movedSpot*exp(rootVariance*thisGaussian);
		double thisPayOff = (*thePayOff)(thisSpot);
		runningSum += thisPayOff;
	}

	double mean = runningSum / NumberOfPaths;
	mean *= exp(-r*Expiry);

	gsl_rng_free (rnd);

	return mean;
}
#endif // MONTECARLO_HPP_INCLUDED




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值