在 C++ 和 Python 中使用 Monte Carlo 方法计算看涨期权价格时价格差异显着?
Significant price difference while calculating call option price using Monte Carlo approach in C++ and Python?
我正在尝试使用 Monte Carlo 方法计算欧式看涨期权的价格。我用 C++ 和 Python 编写了算法。据我所知,实施是正确的,随着 N(试验次数)变大,价格应该在两个程序中收敛到相似的值。
我的问题是,随着 N 变大,比如说从 1000 到 10000 次试验,价格会收敛到两个不同的值。在 C++ 中,价格收敛于 3.30 的值,而 Python 则收敛于 3.70.
我认为 0.40 的差距太大了,我应该得到更多类似的结果。为什么这个差距这么大?我做错了什么?我似乎找不到我的错误。
这是我使用的代码:
Python
import numpy as np
import matplotlib.pyplot as plt
def stoc_walk(p,dr,vol,periods):
w = np.random.normal(0,1,size=periods)
for i in range(periods):
p += dr*p + w[i]*vol*p
return p
s0 = 10;
drift = 0.001502
volatility = 0.026
r = 0.02
days = 255
N = 10000
zero_trials = 0
k=12
payoffs = []
for i in range(N):
temp = stoc_walk(s0,drift,volatility,days)
if temp > k:
payoff = temp-k
payoffs.append(payoff*np.exp(-r))
else:
payoffs.append(0)
zero_trials += 1
payoffs = np.array(payoffs)
avg = payoffs.mean()
print("MONTE CARLO PLAIN VANILLA CALL OPTION PRICING")
print("Option price: ",avg)
print("Initial price: ",s0)
print("Strike price: ",k)
print("Daily expected drift: ",drift)
print("Daily expected volatility: ",volatility)
print("Total trials: ",N)
print("Zero trials: ",zero_trials)
print("Percentage of total trials: ",zero_trials/N)
C++
//Call option Monte Carlo evaluation;
#include <iostream>
#include <random>
#include <math.h>
#include <chrono>
using namespace std;
/* double stoc_walk: returns simulated price after periods
p = price at t=t0
dr = drift
vol = volatility
periods (days)
*/
double stoc_walk(double p,double dr,double vol,int periods)
{
double mean = 0.0;
double stdv = 1.0;
/* initialize random seed: */
int seed = rand() %1000 + 1;
//unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator(seed);
std::normal_distribution<double> distribution(mean,stdv);
for(int i=0; i < periods; i++)
{
double w = distribution(generator);
p += dr*p + w*vol*p;
}
return p;
}
int main()
{
//Initialize variables
double s0 = 10; //Initial price
double drift = 0.001502; //daily drift
double volatility = 0.026; //volatility (daily)
double r = 0.02; //Risk free yearly rate
int days = 255; //Days
int N = 10000; //Number of Monte Carlo trials
double zero_trials = 0;
double k = 12; //Strike price
int temp = 0; //Temporary variable
double payoffs[N]; //Payoff vector
double payoff = 0;
srand (time(NULL)); //Initialize random number generator
//Calculate N payoffs
for(int j=0; j < N; j++)
{
temp = stoc_walk(s0,drift,volatility,days);
if(temp > k)
{
payoff = temp - k;
payoffs[j] = payoff * exp(-r);
}
else
{
payoffs[j] = 0;
zero_trials += 1;
}
}
//Average the results
double sum_ = 0;
double avg_ = 0;
for(int i=0; i<N; i++)
{
sum_ += payoffs[i];
}
avg_ = sum_/N;
//Print results
cout << "MONTE CARLO PLAIN VANILLA CALL OPTION PRICING" << endl;
cout << "Option price: " << avg_ << endl;
cout << "Initial price: " << s0 << endl;
cout << "Strike price: " << k << endl;
cout << "Daily expected drift: " << drift*100 << "%" << endl;
cout << "Daily volatility: " << volatility*100 << "%" << endl;
cout << "Total trials: " << N << endl;
cout << "Zero trials: " << zero_trials << endl;
cout << "Percentage of total trials: " << zero_trials/N*100 << "%";
return 0;
}
因为这是 Monte Carlo,并且因为分布算法的实现在您自己的代码之外,所以您的问题很可能与随机数生成有关,而不是具体与您的代码有关,如图所示.
这意味着您不太可能在此处获得这方面的代码帮助。
您必须做的是确保两种实现对相同的数据同样有效。为此,您应该生成一组随机输入变量并分别保存它们——然后将相同的随机流提供给两种算法。这是控制 Monte Carlo 的随机数生成部分并向自己证明实现在逻辑上确实相同的唯一方法。
您的 C++ 实现中存在错误。
int seed = rand() %1000 + 1;
种子将在 [1...1000] 范围内,这意味着您的高斯采样高度相关
第二个错误是 temp
变量被声明为 int
OK,简单修改后,看下面代码,avg
在C++版本中是3.67
C++:http://codepad.org/D5UZql2P
Python: http://codepad.org/TeAYSwkV
我正在尝试使用 Monte Carlo 方法计算欧式看涨期权的价格。我用 C++ 和 Python 编写了算法。据我所知,实施是正确的,随着 N(试验次数)变大,价格应该在两个程序中收敛到相似的值。
我的问题是,随着 N 变大,比如说从 1000 到 10000 次试验,价格会收敛到两个不同的值。在 C++ 中,价格收敛于 3.30 的值,而 Python 则收敛于 3.70.
我认为 0.40 的差距太大了,我应该得到更多类似的结果。为什么这个差距这么大?我做错了什么?我似乎找不到我的错误。
这是我使用的代码:
Python
import numpy as np
import matplotlib.pyplot as plt
def stoc_walk(p,dr,vol,periods):
w = np.random.normal(0,1,size=periods)
for i in range(periods):
p += dr*p + w[i]*vol*p
return p
s0 = 10;
drift = 0.001502
volatility = 0.026
r = 0.02
days = 255
N = 10000
zero_trials = 0
k=12
payoffs = []
for i in range(N):
temp = stoc_walk(s0,drift,volatility,days)
if temp > k:
payoff = temp-k
payoffs.append(payoff*np.exp(-r))
else:
payoffs.append(0)
zero_trials += 1
payoffs = np.array(payoffs)
avg = payoffs.mean()
print("MONTE CARLO PLAIN VANILLA CALL OPTION PRICING")
print("Option price: ",avg)
print("Initial price: ",s0)
print("Strike price: ",k)
print("Daily expected drift: ",drift)
print("Daily expected volatility: ",volatility)
print("Total trials: ",N)
print("Zero trials: ",zero_trials)
print("Percentage of total trials: ",zero_trials/N)
C++
//Call option Monte Carlo evaluation;
#include <iostream>
#include <random>
#include <math.h>
#include <chrono>
using namespace std;
/* double stoc_walk: returns simulated price after periods
p = price at t=t0
dr = drift
vol = volatility
periods (days)
*/
double stoc_walk(double p,double dr,double vol,int periods)
{
double mean = 0.0;
double stdv = 1.0;
/* initialize random seed: */
int seed = rand() %1000 + 1;
//unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator(seed);
std::normal_distribution<double> distribution(mean,stdv);
for(int i=0; i < periods; i++)
{
double w = distribution(generator);
p += dr*p + w*vol*p;
}
return p;
}
int main()
{
//Initialize variables
double s0 = 10; //Initial price
double drift = 0.001502; //daily drift
double volatility = 0.026; //volatility (daily)
double r = 0.02; //Risk free yearly rate
int days = 255; //Days
int N = 10000; //Number of Monte Carlo trials
double zero_trials = 0;
double k = 12; //Strike price
int temp = 0; //Temporary variable
double payoffs[N]; //Payoff vector
double payoff = 0;
srand (time(NULL)); //Initialize random number generator
//Calculate N payoffs
for(int j=0; j < N; j++)
{
temp = stoc_walk(s0,drift,volatility,days);
if(temp > k)
{
payoff = temp - k;
payoffs[j] = payoff * exp(-r);
}
else
{
payoffs[j] = 0;
zero_trials += 1;
}
}
//Average the results
double sum_ = 0;
double avg_ = 0;
for(int i=0; i<N; i++)
{
sum_ += payoffs[i];
}
avg_ = sum_/N;
//Print results
cout << "MONTE CARLO PLAIN VANILLA CALL OPTION PRICING" << endl;
cout << "Option price: " << avg_ << endl;
cout << "Initial price: " << s0 << endl;
cout << "Strike price: " << k << endl;
cout << "Daily expected drift: " << drift*100 << "%" << endl;
cout << "Daily volatility: " << volatility*100 << "%" << endl;
cout << "Total trials: " << N << endl;
cout << "Zero trials: " << zero_trials << endl;
cout << "Percentage of total trials: " << zero_trials/N*100 << "%";
return 0;
}
因为这是 Monte Carlo,并且因为分布算法的实现在您自己的代码之外,所以您的问题很可能与随机数生成有关,而不是具体与您的代码有关,如图所示.
这意味着您不太可能在此处获得这方面的代码帮助。
您必须做的是确保两种实现对相同的数据同样有效。为此,您应该生成一组随机输入变量并分别保存它们——然后将相同的随机流提供给两种算法。这是控制 Monte Carlo 的随机数生成部分并向自己证明实现在逻辑上确实相同的唯一方法。
您的 C++ 实现中存在错误。
int seed = rand() %1000 + 1;
种子将在 [1...1000] 范围内,这意味着您的高斯采样高度相关
第二个错误是 temp
变量被声明为 int
OK,简单修改后,看下面代码,avg
在C++版本中是3.67
C++:http://codepad.org/D5UZql2P
Python: http://codepad.org/TeAYSwkV