《quantitative finance with cpp》阅读笔记7---bs看涨期权定价公式两种cpp代码
作者:yunjinqi   类别:    日期:2023-11-25 16:18:20    阅读:454 次   消耗积分:0 分    
// my_function.h
#include <iostream>
#include <vector>

const double pi = 3.1415926;
const double sqrt_2_pi = sqrt(2 * pi);

const double a0 = 2.50662823884;
const double a1 = -18.61500062529;
const double a2 = 41.39119773534;
const double a3 = -25.44106049637;
const double b1 = -8.47351093090;
const double b2 = 23.08336743743;
const double b3 = -21.06224101826;
const double b4 = 3.13082909833;
const double c0 = 0.3374754822726147;
const double c1 = 0.9761690190917186;
const double c2 = 0.1607979714918209;
const double c3 = 0.0276438810333863;
const double c4 = 0.0038405729373609;
const double c5 = 0.0003951896511919;
const double c6 = 0.0000321767881768;
const double c7 = 0.0000002888167364;
const double c8 = 0.0000003960315187;

int recursiveAdd(int n);

void recursivePrint(int a, int b);

int fibonacciCal(int n);

double normcdf(double x);

double my_normcdf(double x);

double hornerFunction(double x, double a0, double a1);

double hornerFunction(double x, double a0, double a1, double a2);

double hornerFunction(double x, double a0, double a1, double a2, double a3);

double hornerFunction(double x, double a0, double a1, double a2, double a3, double a4);

double hornerFunction(double x, double a0, double a1, double a2, double a3, double a4,
    double a5);

double hornerFunction(double x, double a0, double a1, double a2, double a3, double a4,
    double a5, double a6);

double hornerFunction(double x, double a0, double a1, double a2, double a3, double a4,
    double a5, double a6, double a7);

double hornerFunction(double x, double a0, double a1, double a2, double a3, double a4,
    double a5, double a6, double a7, double a8);

double my_hornerFunction(const double& x, std::vector<double>& a);

double norminv(double x);

double my_norminv(double x);

double my_blackScholesCallPrice(double strike, double timeToMaturity,
    double spot, double volatility, double riskFreeRate);

double blackScholesCallPrice(double strike, double timeToMaturity,
    double spot, double volatility, double riskFreeRate);


my_function.cpp

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



int recursiveAdd(int n) {
	/*Write a recursive function to compute the sum of the numbers between 1 and n*/
	if (n == 1) {
		return 1;
	}
	else {
		return n + recursiveAdd(n - 1);
	}
}

void recursivePrint(int a, int b) {
	if (a == b) {
		std::cout << a << std::endl;
	}
	else if (a < b){
		std::cout << a << " ";
		recursivePrint(++a, b);
		
	}
	else {
		std::cout << " the input maybe wrong";
	}
}

int fibonacciCal(int n) {
	if (n == 0) {
		return 1;
	}
	else if (n == 1) {
		return 1;
	}
	else if (n < 0) {
		std::cout << "warnings,input n is wrong, please input n>=0";
		return NULL;
	}
	else {
		return fibonacciCal(n - 1) + fibonacciCal(n - 2);
	}
}

double normcdf(double x) {
	return 0.5 * erfc(-x * sqrt(0.5));
}

double my_normcdf(double x) {
	/* 计算标准正太分布的累计概率分布
	*/
	if (x >= 0) {
		x = abs(x);
		double pi = 3.1415926;
		double k = 1 / (1 + 0.2316419 * x);
		double v5 = k * (0.319381530 + k * (-0.356563782 + k * (1.781477937 + k * (-1.821255978 + 1.330274429 * k))));
		double temp = 1.0 / sqrt_2_pi * exp(-0.5 * x * x) * v5;
		return 1 - temp;
	}
	else {
		x = abs(x);
		double pi = 3.1415926;
		double k = 1 / (1 + 0.2316419 * x);
		double v5 = k * (0.319381530 + k * (-0.356563782 + k * (1.781477937 + k * (-1.821255978 + 1.330274429 * k))));
		double temp = 1.0 / sqrt_2_pi * exp(-0.5 * x * x) * v5;
		return temp;
	}
	

}

double my_hornerFunction(const double & x, std::vector<double> &a) {
	/*std::cout << "a value is " << std::endl;
	for (int size_t = 0; size_t < a.size(); size_t++) {
		std::cout << "  " << a[size_t];
	}*/
	std::vector<double> a_copy(a);
	/*std::cout << "a_copy value is " << std::endl;
	for (int size_t = 0; size_t < a_copy.size(); size_t++) {
		std::cout << "  " << a_copy[size_t];
	}*/
	//std::cout << std::endl;
	if (a_copy.size() == 2) {
		return a_copy[0] + x * a_copy[1];
	}
	else if (a_copy.size() <= 1) {
		std::cout << "warnings,input vector or array is wrong" << std::endl;
		return NULL;
	}
	else {
		double a_value = a_copy[0];
		a_copy.erase(a_copy.begin(), a_copy.begin() + 1);
		return a_value + x * my_hornerFunction(x, a_copy);
	}
}


double hornerFunction(double x, double a0, double a1) {
	//std::cout << "01 normal value is " << a0 + x * a1 << std::endl;
	return a0 + x * a1;
}

double hornerFunction(double x, double a0, double a1, double a2) {
	//std::cout << "02 a0 = " << a0 << " x = " << x << " result = " << result << std::endl;
	return a0 + x * hornerFunction(x, a1, a2);
}

double hornerFunction(double x, double a0, double a1, double a2, double a3) {
	return a0 + x * hornerFunction(x, a1, a2, a3);
}

double hornerFunction(double x, double a0, double a1, double a2, double a3, double a4) {
	return a0 + x * hornerFunction(x, a1, a2, a3, a4);
}

double hornerFunction(double x, double a0, double a1, double a2, double a3, double a4,
	double a5) {
	return a0 + x * hornerFunction(x, a1, a2, a3, a4, a5);
}

double hornerFunction(double x, double a0, double a1, double a2, double a3, double a4,
	double a5, double a6) {
	return a0 + x * hornerFunction(x, a1, a2, a3, a4, a5, a6);
}

double hornerFunction(double x, double a0, double a1, double a2, double a3, double a4,
	double a5, double a6, double a7) {
	return a0 + x * hornerFunction(x, a1, a2, a3, a4, a5, a6, a7);
}

double hornerFunction(double x, double a0, double a1, double a2, double a3, double a4,
	double a5, double a6, double a7, double a8) {
	return a0 + x * hornerFunction(x, a1, a2, a3, a4, a5, a6, a7, a8);
}

double norminv(double x) {
	// We use Moro's algorithm
	double y = x - 0.5;
	if (y<0.42 && y>-0.42) {
		double r = y * y;
		return y * hornerFunction(r, a0, a1, a2, a3) / hornerFunction(r, 1.0, b1, b2, b3, b4);
	}
	else {
		double r;
		if (y < 0.0) {
			r = x;
		}
		else {
			r = 1.0 - x;
		}
		double s = log(-log(r));
		double t = hornerFunction(s, c0, c1, c2, c3, c4, c5, c6, c7, c8);
		if (x > 0.5) {
			return t;
		}
		else {
			return -t;
		}
	}
}

double my_norminv(double x) {
	// We use Moro's algorithm
	double y = x - 0.5;
	if (y<0.42 && y>-0.42) {
		double r = y * y;
		std::vector<double> a = { a0, a1, a2, a3 };
		std::vector<double> b = { 1.0, b1, b2, b3, b4 };
		return y * my_hornerFunction(r, a) / my_hornerFunction(r, b);
	}
	else {
		double r;
		if (y < 0.0) {
			r = x;
		}
		else {
			r = 1.0 - x;
		}
		double s = log(-log(r));
		std::vector<double> c = { c0, c1, c2, c3, c4, c5, c6, c7, c8 };
		double t = my_hornerFunction(s, c);
		if (x > 0.5) {
			return t;
		}
		else {
			return -t;
		}
	}
}

double my_blackScholesCallPrice(double strike, double timeToMaturity,
	double spot, double volatility, double riskFreeRate) {
	double numetator = log(spot / strike) + (riskFreeRate + volatility * volatility / 2) * timeToMaturity;
	double e_t = volatility * sqrt(timeToMaturity);
	double d1 = numetator / e_t;
	double d2 = d1 - e_t;
	double nd1 = my_normcdf(d1);
	//std::cout << "d1 = " << d1 << " my_normcdf(d1) = " << my_normcdf(d1) << std::endl;
	double nd2 = my_normcdf(d2);
	double c0 = spot * nd1 - strike * nd2 * exp(-riskFreeRate * timeToMaturity);
	return c0;
}

double blackScholesCallPrice(double strike, double timeToMaturity,
	double spot, double volatility, double riskFreeRate) {
	double numerator = log(spot / strike)
		+ (riskFreeRate + volatility * volatility * 0.5) * timeToMaturity;
	double denominator = volatility * sqrt(timeToMaturity);
	double d1 = numerator / denominator;
	double d2 = d1 - denominator;
	//std::cout << "d1 = " << d1 << " normcdf(d1) = " << normcdf(d1) << std::endl;
	double t1 = normcdf(d1) * spot;
	double t2 = normcdf(d2) * strike * exp(-riskFreeRate * timeToMaturity);
	return t1 - t2;
}


版权所有,转载本站文章请注明出处:云子量化, http://www.woniunote.com/article/372
上一篇:《quantitative finance with cpp》阅读笔记6---计算公司的净利润
下一篇:《quantitative finance with cpp》阅读笔记8---使用cpp画出看涨期权股票价格和期权价格的关系