標籤:

山田的金融日記(6)-Longstaff-Schwartz演算法

手頭攢了一鎚子的project要完成,不知道還能不能畢業了- -

學C艹學一半開始搞C井作業,好幾次cout<< 後都特別生氣為啥不識別_(:з」∠)_

整理一下我做的C#裡面做的美式期權蒙特卡洛定價,如果有誤請大佬們指教。

這個作業不知道從入學開始用了幾種語言做了幾次,美式期權定價難於決定行權與否,這就需要有一個標準,讓我們站在某個/每個時間點判斷是否行權,也就是比較持有價值和行權價值哪個更加划算。

這裡的條件期望是很難直接去計算的,所以常見用Longstaff-Schwartz演算法來模擬早行權情況。

主要的思路就是用一個股價的二次多項式去近似Continuation value,和行權payoff比較決定是否行權。

首先還是老套路,用GBM 模擬m*n的路徑矩陣 S(i,j) ,m為時間點,n為路徑數。

然後用期權的payoff形式比如call為 Max(S_t-K,0) ,得出payoff矩陣,仍然為m*n維矩陣。

然後從最後一期開始反推,即i=T

我們設

y(j)=P(i+1,j) * e^{-r*dt}

x(j,1) = 1

x(j,2) = S(i,j)

x(j,3) = S(i,j)^2

其中i為時間點,從0~T;j為蒙特卡洛模擬的第j個路徑,P(i,j)就是payoff矩陣裡面第i行第j列的payoff,y為1xn矩陣,x為3xn矩陣,對其進行回歸後我們能得到三個beta:

y(i,j) = eta(0)+eta(1)*S(i,j)+eta(2)*S(i,j)^2

再將每個點的 S(i,j) 代入得到的 y(i,j) ,與 P(i,j) 比較,如果行權價值P大則保留,反之將後一期payoff的折現 P(i+1,j)*e^{-r*dt} 代入原來 P(i,j) 的位置。

另i-1重複這個步驟,從最後一期到第1期我們得到n個 S(1,j) ,將其折現求平均就是最簡單的美式期權價格了。

和CBOE的理論價格很接近了

參考文獻:

http://www.maths.manchester.ac.uk/~pjohnson/resources/math60082/lecture-monte-carlo-ls.pdf?

www.maths.manchester.ac.uk

附上我滿是loop的低級代碼o(╥﹏╥)o

static double AmeCall(double[,]S,double K, double r, double dt) { var Payoff = new double[S.GetLength(0), S.GetLength(1)]; for (int n = 0; n < S.GetLength(1); n++) { Payoff[S.GetLength(0) - 1, n] = Call(S[S.GetLength(0) - 1, n], K); } for (int i = S.GetLength(0)-2; i >=0 ; i--) { int count = 0; List<double> y = new List<double>(); List<double> x = new List<double>(); for (int j = 0; j < S.GetLength(1); j++) { Payoff[i, j] = Call(S[i, j], K); if (Payoff[i, j] > 0) { count += 1; y.Add(Payoff[i+1, j] * Math.Exp(-r * dt));x.Add(S[i, j]); } } if(count>2) { var ArrY = new double[count, 1];var ArrX = new double[count, 3]; for (int k = 0; k < count; k++) { ArrY[k, 0] = y[k]; ArrX[k, 0] = 1; ArrX[k, 1] = x[k]; ArrX[k, 2] = Math.Pow(x[k], 2); } var beta = OLS(ArrX, ArrY); for (int m = 0; m < S.GetLength(1); m++) { if (Payoff[i,m]<=0||Payoff[i, m] <= beta[0, 0] + beta[1, 0] * S[i, m] + beta[2, 0] * Math.Pow(S[i, m], 2)) { Payoff[i, m] = Math.Exp(-r * dt) * Payoff[i + 1, m]; } } } } double sum = 0; for (int v = 0; v < Payoff.GetLength(1); v++) { Payoff[0, v] = Math.Exp(-r * dt) * Payoff[1, v]; sum += Payoff[0, v]; } return sum/Payoff.GetLength(1); }

推薦閱讀:

山田的金融日記(4)-CVA(1)
山田的金融日記(3)-Quadratic Variation
結構化產品概述 Structured Products(一)
Libor Market Model 簡介2 ——分離波動率函數和校準(一部分)

TAG:金融數學 |