程式

使用原始蒙地卡羅

  • April 3, 2017

背景資料:

算術亞洲看漲期權的原始蒙地卡羅算法是

$$ Y = e^{-rT}(\overline{S}_A - K)^{+} $$並且控制是$$ C e^{-rT}(\overline{S}_G - K)^{+} $$ 控制變數估計量是 $$ \begin{align*} Y(\beta) &= Y - \beta(C - \mu_C)\ &= e^{-rT}(\overline{S}_A - K)^{+} - \beta(e^{-rT}(\overline{S}_G - K)^{+} - \mathbb{E}[C]) \end{align*} $$ 我們估計 $ \mathbb{E}[Y(\beta)] $ 使用樣本均值

$$ \frac{1}{N}\sum Y_i - \hat{\beta}N^{}(C_i - \mathbb{E}[C]) $$在哪裡$$ \hat{\beta}_N^{} = \frac{\sum{i=1}^{n}(Y_i - \overline{Y})(C_i - \overline{C})}{\sum_{i=1}^{n}(C_i - \overline{C})^{2}} $$ 具有離散監控的算術 Asain 選項具有支付功能

$$ \begin{align*} \text{call payoff} &: \ (\overline{S}_A - K)^{+}\ \text{put payoff} &: \ (K - \overline{S}_A)^{+} \end{align*} $$ 在哪裡$$ \overline{S}A = \frac{1}{n}\sum{i=1}^{n}S(t_i) $$ 幾何 Asain 期權具有相同的收益函式,但算術 Asain 期權具有相同的收益函式,但算術平均值 $ \overline{S}_A $ 被幾何平均取代

$$ \overline{S}G = \left(\prod{i=1}^{n}S(t_i)\right)^{1/n} $$ 股票價格模型是GBM模型: $$ S(t_i) = S(0)\exp((r-\sigma^2/2)t_i + \sigma W(t_i)) $$ 在哪裡 $ W(t) $ 是標準的布朗運動 $ [0,T] $ . 將 GBM 模型乘以 $ i = 1,\ldots,n $ 我們獲得$$ \overline{S}G = \left(\prod{i=1}^{n}S(t_i)\right)^{1/n} = S(0)\exp\left(\left(r - \frac{\sigma^2}{2}\right)\left(\frac{1}{n}\sum_{i=1}^{n}t_i\right) + \frac{\sigma}{n}\sum_{i=1}^{n}W(t_i)\right) $$ 問題:

考慮一個 Asain 算術看漲期權 $ K = 100 $ , $ r = 0.2 $ , $ S_0 = 100 $ , $ \sigma = 0.4 $ ,對標的股票過程使用對數正態模型。讓期滿 $ T = 0.1 $ 和 $ n = 10 $ 平均價格。產生 $ 40 $ 期權價格的估計,使用 $ N = 100,1000,10000 $ 價格路徑,使用原始的蒙地卡羅。

我關於這個問題的問題如下。我知道當我生成時間向量時 $ t $ 它會變大 $ 10 $ . 現在,我的困惑在於股價模型

$$ S(t_i) = S(0)\exp((r-\sigma^2/2)t_i + \sigma W(t_i)) $$ 尺寸是多少 $ S(t_i) $ ? 我們要生成 $ N = 100,1000,10000 $ 價格路徑,但我的時間向量 $ t $ 只有大小 $ 10 $ 那麼尺寸是多少 $ S(t_i) $ ? 我有同樣的問題 $ W(t_i) $ . 非常感謝您對以下內容的任何建議。 更新:

我相信大小 $ S(t_i) $ 和 $ W(t_i) $ 將有大小 $ 10 $ 但我不明白我們將如何生成 $ N $ 路徑大小的大小 $ N $ 遠大於 $ 10 $ .

對數正態模型是

$$ S(t_n) = S(0)\exp\left((r-\sigma^2/2)t_n \sigma\sqrt{t_n}Z\right) $$ 由於我需要設置什麼大小,我不確定如何生成它 $ Z $ , ETC…

這是我到目前為止所做的程式碼,如果有人能告訴我如何生成 $ 40 $ 使用的期權價格估計 $ N = 100,1000,10000 $ 價格路徑。

// Create time vector
VectorXd tt = time_vector(0.0,T,n);
VectorXd 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 N paths of stock prices

這是我的完整程式碼,我自己弄清楚了:

#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);
   static random_device rd;
   static mt19937 e2(time(0));
   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;
}

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++){
       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();
   }






}

這是一些用於生成估值的虛擬碼:

Asset asset(); //some asset object that holds all the data.

vector<double> timeline; //this is your vector of times.
size_t nTimes = timeline.size();
vector<double> dts(nTimes); //vector of fwd prices on the same timeline.
vector<double> fwds(nTimes); //vector of fwd prices on the same timeline.
vector<double> fwdRatios(nTimes); //vector of fwd prices on the same timeline.
double vol = 0.2; //Your BS vol.    

for(size_t iTimeline=0; iTimeline<nTimes; iTimeline++){
   fwds(i) = asset.getForward(timeline[iTimeline]);
   if(iTimeline==0){
       fwdRatios(0) = fwds(i) / asset.getSpot();
       dts(0) = timeline(0);
   }else{
       fwdRatios(i) = fwds(i) / fwds(i-1);
       dts(i) = timeline(i) - timeline(i-1);
   }
}

//Some random number generator - 
PRNG<Distribution::Normal> prng();

size_t nTrajectories = 100000;

Matrix<double> trajectories(nTimes, nTrajectories);
for(size_t iTrajectory=0; iTrajectory<nTrajectories ; iTrajectory++){
   trajectories(0, iTrajectory) = asset.getSpot() * fwdRatios(0) * exp(-0.5*vol*vol*dts(0) + vol*sqrt(dts(0)*prng.next());

   for(size_t iTimeline=1; iTimeline<nTimes; iTimeline++){
       trajectories(iTimeline, iTrajectory) = trajectories(iTimeline-1, iTrajectory) * fwdRatios(iTimeline) * exp(-0.5*vol*vol*dts(iTimeline) + vol*sqrt(dts(iTimeline))*prng.next());
   }
}

vector<double> payoffs(nTrajectories);
for(size_t iTrajectory=0; iTrajectory<nTrajectories ; iTrajectory++){
   payoffs(iTrajectory) = calculatePayoff(trajectories.row(iTrajectory));
}

那會給你一個樣品價格。如果您想執行 40 次,只需在其周圍再放一個 foo 循環即可執行 40 次。

但是,您將無法複製粘貼並編譯它,因為我只是將其鍵入並組成了函式…

引用自:https://quant.stackexchange.com/questions/33394