N 个价格路径在 N 次迭代中不变的平均估计值
Mean estimates of the N price paths not changing over N-iterations
我对C++相对较新,所以如果标题不够,我深表歉意。我正在尝试做的是使用 N 个价格路径获得 40 个期权价格的估计值。从本质上讲,我想得到 N 个价格路径的 40 个不同的平均估计值。但我一定做错了什么,因为我每次都得到相同的平均价格。这是我的代码:
// Generate 40 estimates for the option price, using N paths
int m = 40;
MatrixXd SS(N,n+1);
VectorXd S(m);
for(int k = 0; k < m; k++){
MatrixXd Z = generateGaussianNoise(N,n);
for(int i = 0; i < N; i++){
SS(i,0) = S0;
for(int j = 1; j <= n; j++){
SS(i,j) = SS(i,j-1)*exp((double) (r - pow(sigma,2.0))*dt + sigma*sqrt(dt)*(double)Z(i,j-1));
}
}
S(k) = SS.mean();
}
cout << S << endl;
}
这也是我的整个代码:
#include <iostream>
#include <cmath>
#include <math.h>
#include <Eigen/Dense>
#include <Eigen/Geometry>
#include <random>
#include <time.h>
using namespace Eigen;
using namespace std;
void crudeMonteCarlo(int N,double K, double r, double S0, double sigma, double T, int n);
VectorXd time_vector(double min, double max, int n);
int main(){
int N = 100;
double K = 100;
double r = 0.2;
double S0 = 100;
double sigma = 0.4;
double T = 0.1;
int n = 10;
crudeMonteCarlo(N,K,r,S0,sigma,T,n);
return 0;
}
VectorXd time_vector(double min, double max, int n){
VectorXd m(n + 1);
double delta = (max-min)/n;
for(int i = 0; i <= n; i++){
m(i) = min + i*delta;
}
return m;
}
MatrixXd generateGaussianNoise(int M, int N){
MatrixXd Z(M,N);
random_device rd;
mt19937 e2(rd());
normal_distribution<double> dist(0.0, 1.0);
for(int i = 0; i < M; i++){
for(int j = 0; j < N; j++){
Z(i,j) = dist(e2);
}
}
return Z;
}
/*VectorXd Stock_process_Lognormal(double T, double S0, double K, double r, double sigma, int N, int n , int m){
VectorXd S(m);
}*/
void crudeMonteCarlo(int N,double K, double r, double S0, double sigma, double T, int n){
// Create time vector
VectorXd tt = time_vector(0.0,T,n);
VectorXd t(n);
double dt = T/n;
for(int i = 0; i < n; i++){
t(i) = tt(i+1);
}
// Generate standard normal Z matrix
MatrixXd Z = generateGaussianNoise(N,n);
// Generate 40 estimates for the option price, using N paths
int m = 40;
MatrixXd SS(N,n+1);
VectorXd S(m);
for(int k = 0; k < m; k++){
for(int i = 0; i < N; i++){
SS(i,0) = S0;
for(int j = 1; j <= n; j++){
SS(i,j) = SS(i,j-1)*exp((double) (r - pow(sigma,2.0))*dt + sigma*sqrt(dt)*(double)Z(i,j-1));
}
}
S(k) = SS.mean();
}
cout << S << endl;
}
我将generateGaussian
函数更改为种子rd()
尽管我仍然保持相同的输出(40 个期权价格估计值)。它们应该不同,因为我想运行 for 循环 40 次,每次都得到矩阵的平均值。这是我得到 40 次的 40 个估计值的输出:
99.422
您在40 次迭代k
循环之前调用generateGaussianNoise
,并且该循环中的任何内容都不会更改由随机生成的数据填充的Z
数组中的数据。 因此,每次您都会获得相同的数据。
解决此问题的一种方法是将generateGaussianNoise
拆分为两个函数,一个为随机生成器播种(在k
循环之前调用),另一个填充Z
数组(从k
循环中调用)。
或者,您可以在循环外部生成一个种子值,然后将其传递到generateGaussianNoise
(从k
循环中调用),同时以某种方式在每次迭代中更改值。 由于每次迭代都独立于以前的迭代,因此如果需要性能,这将允许多线程模拟。 还可以使用seed_seq
向随机数生成器提供多个种子值(例如,基于时间的种子值,序列中第二个值具有基于迭代的值)。
使用示例实现进行编辑:
例如,第一种方法的一种实现可能是更改generateGaussianNoise
以将随机数引擎作为参数:
MatrixXd generateGaussianNoise(int M, int N, mt19937 &e2){
MatrixXd Z(M,N);
normal_distribution<double> dist(0.0, 1.0);
for(int i = 0; i < M; i++){
for(int j = 0; j < N; j++){
Z(i,j) = dist(e2);
}
}
return Z;
}
然后在crudeMonteCarlo
中,您当前声明Z
的地方,将其替换为
mt19937 e2(random_device());
这将创建并初始化要使用的随机数引擎。 在k
循环中,在i
循环之前,声明Z
并调用generateGaussianNoise
,传入e2
:
MatrixXd Z = generateGaussianNoise(N,n,e2);
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 迭代时从向量和内存中删除对象
- 如何在c++迭代器类型中包装std::chrono
- 带过滤器的现代迭代c++集合
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- C++矢量迭代
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 擦除while循环中迭代的元素
- 实现一个在集合上迭代的模板函数
- 对于set上的循环-获取next元素迭代器
- 在向量内的向量上迭代
- 使用迭代深度优先搜索算法的未加权图的最短路径
- N 个价格路径在 N 次迭代中不变的平均估计值
- 是否可以从一系列路径迭代器或子路径创建文件系统 TS basic_path
- 环境路径目录迭代
- Boost:: Dijkstra 最短路径,如何从路径迭代器获取顶点索引
- 无法将Boost路径迭代器转换为字符串