在c++和Python中使用蒙特卡罗方法计算看涨期权价格时显着的价格差异

Significant price difference while calculating call option price using Monte Carlo approach in C++ and Python?

本文关键字:Python c++ 计算 方法 蒙特卡罗      更新时间:2023-10-16

我正在尝试使用蒙特卡洛方法计算欧洲看涨期权的价格。我用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;
}

您的c++实现中有一个bug。

int seed = rand() %1000 + 1;

种子将在[1…]1000],这意味着你的高斯抽样高度相关

第二个错误是temp变量被声明为int

OK,经过简单的修改,见下面的代码,avg在c++版本是3.67

c++: http://codepad.org/D5UZql2P

Python: http://codepad.org/TeAYSwkV

因为这是蒙特卡罗,并且因为分布算法的实现在您自己的代码之外,所以您的问题很可能与随机数生成有关,而不是具体与所示的代码有关。

这意味着你不太可能在这里得到代码帮助。

您必须做的是确保两个实现对相同的数据工作相同。为此,您应该生成一组随机输入变量并分别保存它们——然后将相同的随机流提供给两种算法。这是控制蒙特卡罗随机数生成部分的唯一方法,并向您自己证明实现确实在逻辑上是相同的。