使用原始蒙地卡羅
背景資料:
算術亞洲看漲期權的原始蒙地卡羅算法是
$$ 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 次。
但是,您將無法複製粘貼並編譯它,因為我只是將其鍵入並組成了函式…