实现欧式期权类

Posted

技术标签:

【中文标题】实现欧式期权类【英文标题】:Implementing a European Option class 【发布时间】:2021-06-01 21:11:43 【问题描述】:

我需要实现类Option_Pricer,它封装了与看涨期权和看跌期权定价相关的所有函数。老师给了我一个代码清单(.cpp 文件),我必须把它变成一个班级。因此,我在课堂上使用的所有功能都来自老师。我只需要将它们作为一个类来实现。

这是我到目前为止所做的:我已将代码拆分为两个不同的文件。一个称为 option_pricer.hpp,用作主文件 option_pricer.cpp 的标头。

//option_pricer.hpp
#define _USE_MATH_DEFINES
#include <iostream> 
#include <cmath>

class Option_Pricer 
    
private:
    
    void init();
    
public:
    
    double S;
    double K;
    double r;
    double v;
    double T;
    double x;
    double j;

 public:
    //Constructors
    call_price();
    put_price();
    norm_pdf();
    norm_cdf();
    d_j() const;

// Assignment operator
call_price& operator = (const call_price& call);
put_price& operator = (const put_price& put);
    
;

这里是主文件:

//option_pricer.cpp
#define _USE_MATH_DEFINES
#include <iostream> 
#include <cmath>
#include "option_pricer.hpp"


double Option_Pricer::norm_pdf(const double& x) const 
    return (1.0/(pow(2*M_PI,0.5)))*exp(-0.5*x*x); 


double Option_Pricer::norm_cdf(const double& x) const 
    double k = 1.0/(1.0 + 0.2316419*x);
    double k_sum = k*(0.319381530 + k*(-0.356563782 + k*(1.781477937 + k*(-1.821255978 + 1.330274429*k))));
    
    if (x >= 0.0) 
        return (1.0 -(1.0/(pow(2*M_PI,0.5)))*exp(-0.5*x*x) * k_sum);
                 
    else 
        return 1.0 - norm_cdf(-x);
                 


double Option_Pricer::d_j(const int& j, const double& S, const double& K, const double& r, const double& v, const double& T) const 
    return (log(S/K) + (r + (pow(-1,j 1))*0.5*v*v)*T)/(v*(pow(T,0.5)));


double Option_Pricer::call_price(const double& S, const double& K, const double& r, const double& v, const double& T) const 
    return S * norm_cdf(d_j(1, S, K, r, v, T))-K*exp(-r*T) * norm_cdf(d_j(2, S, K, r, v, T));

    
double Option_Pricer::put_price(const double& S, const double& K, const double& r, const double& v, const double& T) const 
      return -S*norm_cdf(-d_j(1, S, K, r, v, T))+K*exp(-r*T) * norm_cdf(-d_j(2, S, K, r, v, T)); 
    

    

int main() 
    
Option_Pricer p;
   p.S = 100.0;
   p.K = 100.0;
   p.r = 0.05;
   p.v = 0.2;
   p.T = 1.0;
double call_price = p.call_price();
double call_put = p.put_price();

 
// Finally we output the parameters and prices 
std::cout << "Underlying: " << p.S << std::endl;
std::cout << "Strike: " << p.K << std::endl;
std::cout << "Risk-Free Rate: " << p.r << std::endl;
std::cout << "Volatility: "<< p.v << std::endl;
std::cout << "Maturity: " << p.T << std::endl;
std::cout << "Call price: " << call_price << std::endl;
std::cout << "Put price: " << call_put << std::endl;

return 0; 
    

但是,您可以猜到,我的代码编译得并不好。我最常见的错误如下:

option_pricer.cpp:7:8: 错误:没有声明匹配‘double Option_Pricer::norm_pdf(const double&) const’ 7 |双 Option_Pricer::norm_pdf(const double& x) const | ^~~~~~~~~~~~~~~~

我不明白我应该如何从标题外部调用 norm_pdf(norm_cdf 和 d_j 的问题相同)。

我对 C++ 还很陌生(以前使用过 Python),因此我还不明白我应该如何从课堂外访问变量(S、K、...)。

我们将不胜感激!谢谢!

【问题讨论】:

我很难理解你在问什么。所有这些代码都相关吗? 你是从一本好书中学习 C++ 吗?我问这个,因为没有一本好书会以这种方式初始化非静态成员变量(这就是为什么你可能会遇到编译器错误)。你的书对默认构造函数、一般构造函数和初始化成员变量有什么看法?还是你试图将 Python 知识应用到 C++ 中而做错了? 一个关于编译器错误的问题无法重现编译器错误的全文,这是单向遗忘的旅程。添加编译器错误。更好的是,备份您的代码并生成一个minimal reproducible example,该minimal reproducible example 只生成一条错误消息(请注意,这条错误消息有时会持续到页面上)。通常,当您将代码减少到足以产生错误时,错误的原因就很明显了。 (1.0/(pow(2*M_PI,0.5))) -- 请注意,这是一个常数。调用pow 可能会影响性能。只需声明一个double 常量,而不必调用pow //Constructors 是不正确的评论。您的Option_Pricer 类没有构造函数。他们不在评论下方。 【参考方案1】:

您需要做出并理解类和对象之间的区别。很简单,对象是内存中值的集合,类是对这些值和代码的描述,这些代码将使用根据类描述组织的数据。

所以,由于Option_Pricer 是一个类,所以在你的main() 方法中说Option_Pricer.S = 100.0; 是没有意义的。您需要创建一个Option_Pricer 类型的对象,然后用您想要的值填充该对象的内存区域。一种常见的方法——特别是在你只是用数字数据初始化对象的情况下——是创建和使用构造函数,尽管你可以修改你的 init() 方法来获取参数和设置值,这很好也。您甚至可以像以前一样设置值,因为您设置了值public,但您必须修改对象,而不是类。

例如

int main()

   Option_Pricer p(100.0, 100.0, 0.5, 0.2, 1.0);
   double call_price = p.call_price();

   // or
   Option_Pricer p2;
   p2.init(100.0, 100.0, 0.5, 0.2, 1.0);
   double call_price2 = p2.call_price();

   // or, if you like typing or want the meaning of the numbers to be super clear
   Option_Pricer p3;
   p3.S = 100.0;
   p3.K = 100.0;
   p3.r = 0.05;
   p3.v = 0.2;
   p3.T = 1.0;

   // ...

这并不能解决您的代码的所有问题,但我将从解决上述问题开始。我认为,一旦您将对象的概念弄清楚了,其他人指出的问题就会更容易解决。

【讨论】:

感谢您的评论!我按照你的建议做了,我的代码已经在 OP 中修复了。仍然没有编译,但已经好多了!

以上是关于实现欧式期权类的主要内容,如果未能解决你的问题,请参考以下文章

基于二叉树蒙特卡洛模拟BS方程的期权定价模型

MATLAB点云处理:欧式聚类分割

20191016——期权:所有乐趣之所在

期权基础知识

如何通过二叉树对标的资产有现金流的美式期权估值

期权定价Python实现