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_INCLUDEDSuppose 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
                  
                  
                  
                  
                            
本文介绍了一个抽象的期权收益类的设计,并展示了如何通过派生类实现欧式看涨和看跌期权的具体收益计算。此外,还讨论了如何将这些派生类应用到Monte Carlo模拟中以对期权进行定价。
          
      
          
                
                
                
                
              
                
                
                
                
                
              
                
                
              
            
                  
被折叠的  条评论
		 为什么被折叠?
		 
		 
		
    
  
    
  
            


            