🥥C++计算资本市场收益及成本分配数学方程

关键词

C++ | 利率 | 复利 | 债卷 | 建模 | 现金流 | 模型 | 数学 | 资本市场 | 波动性 | 财务 | 相关性 | 股票 | 分析师 | 价值 | 线性插值 | 多项式插值 | 交易 | 矩阵 | 时间序列 | 卡玛比率 | 统计分布 | 高斯 | 卡方 | 绘图 | Qt C++ | 方程 | 常微分方程 | 偏微分方程 | 中值法 | 梯形法 | 辛普森法 | 欧拉法 | 二分法 | 割线法 | 牛顿法 | 线性规划 | 混合整数规划 | 蒙特卡罗 | 期权 | 概率

🏈page指点迷津 | Brief

🎯 要点

  1. 固定收益市场计算公式和模型:🎯C++计算简单利率。🎯C++计算离散复利利率和连续复利。🎯现金流建模,C++计算未来付款的现值,使用STL容器。🎯债卷建模,创建 C++ 类模拟债券工具并确定其年利率。

  2. 股票市场计算公式和模型:🎯C++计算给定股权投资,确定收盘价的简单移动平均线和指数移动平均线。🎯C++计算特定权益工具的波动性。🎯C++计算两种权益工具之间的相关性。🎯C++计算股票基本指标。

  3. C++计算技巧:🎯C++计算投资工具的利率。🎯C++计算财务报表并将其返回给调用客户端,同时避免返回数据泄漏。🎯C++确定证券的信用评级。🎯C++处理交易订单(买入、卖出或卖空)。🎯C++处理分析师的建议并返回股票的平均目标价格。🎯C++设计常见时间序列转换(添加或减去价格值以及删除不需要的值)。🎯C++复制存储交易文件。🎯C++处理交易日期。🎯C++矩阵表示交易数据运算。🎯C++使用模板计算阶乘。🎯C++表示卡玛比率,其是投资回报与可能的年度损失相比的衡量标准。 🎯C++生成统计分布,如高斯和卡方。🎯使用绘图工具和Qt C++绘图绘制价格图。

  4. 金融数学工具:🎯C++线性代数及其工具。🎯C++线性插值和多项式插值。🎯C++计算方程根方法:二分法、割线法、牛顿法。🎯C++数值积分法:中值法、梯形法、辛普森法和图解。🎯C++使用欧拉法求解常微分方程。🎯C++龙格-库塔法解常微分方程。🎯C++求解布莱克-斯科尔斯方程。🎯C++使用第三方库线性规划求解器。🎯C++线性规划建模,求解决已知回报投资的金融产品分配决策。🎯C++创建混合整数规划模型。

  5. 🎯C++使用线性规划模型,确定项目及其成本的最佳资源分配。🎯C++资产定价模型,确定最佳投资组合。🎯C++蒙特卡罗积分函数,模拟资产价格波动。🎯C++计算期权概率。

🍇C++牛顿-拉夫逊法寻找隐含波动性

牛顿-拉夫逊法

在满足某些假设的情况下,牛顿拉夫森算法是一种更有效的求根算法。特别是,g 必须具有易于计算的导数。如果导数是可分析计算的,那么这会进一步提高效率。 g 还必须“表现良好”,即它不能变化太大,否则该方法中使用的导数近似会变得更加不准确。

牛顿-拉夫逊的思想是使用解析导数对应该出现解的位置进行线性估计,这比区间二分法所采用的中点方法准确得多。因此,g 的起始近似值 g0g_0 由下式给出(其中x0x_0 是我们的初始猜测):

g0(x)=g(x0)+(xx0)g(x0) g_0(x)=g\left(x_0\right)+\left(x-x_0\right) g^{\prime}\left(x_0\right)

这可以重新排列为 x :

x=yg(x0)g(x0)+x0 x=\frac{y-g\left(x_0\right)}{g^{\prime}\left(x_0\right)}+x_0

这会导致 x 的更准确值的递归关系:

xn+1=yg(xn)g(xn)+xn x_{n+1}=\frac{y-g\left(x_n\right)}{g^{\prime}\left(x_n\right)}+x_n

对于某些预先指定的容差 ϵ\epsilon,与区间二分一样,当g(xn)y<ϵ \left|g\left(x_n\right)-y\right|<\epsilon 时算法终止。

用我们的金融符号重写,关系变为:

σn+1=CMB(σn)Bσ(σn)+σn \sigma_{n+1}=\frac{C_M-B\left(\sigma_n\right)}{\frac{\partial B}{\partial \sigma}\left(\sigma_n\right)}+\sigma_n

我们可以使用这种关系通过终止标准找到隐含波动率。

算法实现

 double call_vega(const double S, const double K, const double r, const double sigma, const double T) {
   return S * sqrt(T) * norm_pdf(d_j(1, S, K, r, sigma, T));
 }

以下是 black_scholes.h 的新标头列表:

 #ifndef __BLACK_SCHOLES_H
 #define __BLACK_SCHOLES_H
 ​
 class BlackScholesCall {
 private:
   double S;  
   double K;  
   double r;  
   double T; 
 ​
 public:
   BlackScholesCall(double _S, double _K, 
                    double _r, double _T);
 ​
   double option_price(double sigma) const;
   double option_vega(double sigma) const;
 };
 #endif

源列表也已更改为包含 option_vega 的实现,如 black_scholes.cpp 中所示:

 #ifndef __BLACK_SCHOLES_CPP
 #define __BLACK_SCHOLES_CPP
 ​
 #include "black_scholes.h"
 #include "bs_prices.h"
 ​
 BlackScholesCall::BlackScholesCall(double _S, double _K, 
                                    double _r, double _T) :
   S(_S), K(_K), r(_r), T(_T) {}
 ​
 ​
 double BlackScholesCall::option_price(double sigma) const {
   return call_price(S, K, r, sigma, T);
 }
 ​
 ​
 double BlackScholesCall::option_vega(double sigma) const {
   return call_vega(S, K, r, sigma, T);
 }
 ​
 #endif

下一阶段是创建牛顿-拉夫逊求解器本身。函数模板将接受一个 T 类型的对象(函子)和两个指向 T、g 和 g_prime 的成员函数(方法)的指针。以下是 newton_raphson.h 的列表:

 #ifndef __NEWTON_RAPHSON_H
 #define __NEWTON_RAPHSON_H
 ​
 #include <cmath>
 ​
 template<typename T, 
          double (T::*g)(double) const,
          double (T::*g_prime)(double) const>
 double newton_raphson(double y_target,       
                       double init,           
                       double epsilon,        
                       const T& root_func) {  
 ​
   double y = (root_func.*g)(init);  
   double x = init;                  
 ​
   while (fabs(y-y_target) > epsilon) {
     double d_x = (root_func.*g_prime)(x);
     x += (y_target-y)/d_x;
     y = (root_func.*g)(x);
   }
   return x;
 }
 ​
 #endif

现在我们可以创建 main() 函数来将所有代码包装在一起:

 #ifndef __MAIN_CPP
 #define __MAIN_CPP
 ​
 #include "black_scholes.h"
 #include "newton_raphson.h"
 #include <iostream>
 ​
 int main(int argc, char **argv) {
 ​
   double S = 100.0;  
   double K = 100.0;  
   double r = 0.05;   
   double T = 1.0;    
   double C_M = 10.5; 
 ​
   BlackScholesCall bsc(S, K, r, T);
 ​
   double init = 0.3; 
   double epsilon = 0.001;
 ​
   double sigma = newton_raphson<BlackScholesCall, 
                                 &BlackScholesCall::option_price,
                                 &BlackScholesCall::option_vega>(C_M, init, epsilon, bsc);
 ​
   std::cout << "Implied Vol: " << sigma << std::endl;
 ​
   return 0;
 }
 ​
 #endif

代码的输出由下式给出:

 Implied Vol: 0.201317

Last updated