網路城邦
上一篇 回創作列表 下一篇   字體:
金融工程與並行運算:第二章 模擬法在財務工程的使用 Part 2
2018/07/03 12:26:10瀏覽664|回應0|推薦0
第四節 資產過程的描述與離散化

現代財務模型大都以連續交易作為分析的架構,亦即,交易是連續進行,兩次交易間的時間間隔為無限小,因此稱之為連續時間財務。然而,當我們要進行模擬時,卻是必須將之離散化。這是因為在實際進行模擬時,我們只能以有限的步數,模擬期末資產可能的價格。也因此,每次模擬的時間跨距(Time Interval)是有限的,而非無限小。這種以有限間隔的模擬實作,取代模型中間隔無限小的假設,稱之為離散化(Discretization),實務最常使用的是尤拉法(Euler Schemes)。另外尚有兩個較為精細的方法,分別是Milstein Schemes與二階法(Second-Order Method),然而由於效率上的考量,實務上使用的機會不大。

 

一、尤拉法

以傳統的Black-Scholes模型為例,

……………………………………………..(2.4.1)

最簡單的離散化為尤拉法的離散化,

因此,可得下面的迭代模擬方程式。

…………………………………(2.4.2)

(2.4.1)式可以改寫如下,

………………………………………………………….…(2.4.3)

(2.4.3)式的隨機微分方程式,在給定期初資產價格S0下,可以求得期末價格ST的移轉方程式如下,

……………………………....…(2.4.4)


由於,(2.4.4)式是公式解,因此不論時間跨距長短,都可以直接用來模擬期末價格。實務上,十萬次的模擬是一般的要求。

(2.4.2)式的差分方程式,在給定期初資產價格S1下,可以求得期末價格S2的移轉方程式如下,

……………………………………(2.4.5)

通常,我們以一天走一步的方式來進行模擬。因此,如果到期時間為一年,則一條模擬的路徑要走365步。十萬條的路徑應該是可以接受的模擬量。

 

二、Milstein

 

三、二階法

 

第五節 C#單資產風險中立的模擬

CPUProcess方案中,STBSProcess專案,我們以Black-Scholes資產價格程序為模擬的對象,


然而,實際在進行模擬時,我們採用(2.4.5)式一天一步的方式來模擬,

模擬的期限為一年,為了配合一些市場上交易契約的條件,我們假定需要一個月進行一次的比價。

假定起始日為2014/7/1,我們首先計算未來十二個比價的日期,與2014/7/1相減,算出每一比價日期要走的步數。

 

一、風險中立訂價理論:鞅性方法

Rt為一證券之t期之報酬率, rt為無風險報酬率,RP表風險溢酬,令E[RP]=α。則一證券之報酬率包含無風險報酬率與風險溢酬兩個成分。

…………............................…………...(2.5.1)

如果我們用Rt作為該證券之折現率,則此證券之t期市場價格可由下式求得,

……………………………...............................(2.5.2)

然而,由於Rt本身可能無法事前確定,因此我們不能直接使用(2.5.2)式計算證券t期之市場價格。

t期無風險債券Bt = 1,則Bt+1 = 1+rt。令Xt = St / Bt,如果我們經過某種方式處理,得到Et[Xt+1] = Xt。由於rt可由市場上直接觀察得到,因此Xt本身的計算沒有困難。

Et[Xt+1| Xt ] = Xt,此性質稱為鞅性(martingale),又稱之為一公平賭局(fair game)。如果我們將Xt視為t期末之財富,則t+1期末之財富的期望值Et[Xt+1| Xt ],等於t期末之財富。因此,t+1期的賭局是一個公平的賭局,參與者由此賭局賺得的財富期望值為零。

近代財務理論使用機率測度轉換的方法,以零息債券價格為計價單位,得到鞅性的良好性質。由此性質,得到衍生商品定價的一般理論,這也提供我們使用模擬方法計算選擇權價格理論基礎。使我們迴避掉估計證券風險溢酬的難題。下面說明模擬法實作的細節,至於有關鞅性定價理論的細節,有興趣的讀者可參考Neftci(2002)的說明。

 

二、實作的方法

考慮歐式選擇權,依據風險中立定價法,到期日為T,目前時間為t=0,我們可以下式估算期初選擇權價值,

…………………….............................(2.5.3)

若利率為固定不變,可簡化為

.……………….............................………(2.5.4)

模擬M次,求平均數可得估計值

………………………………............................…(2.5.5)

依據風險中立定價法,股價過程為


若目前價格為S0,未來T的價格為ST,則Ln(ST)為一常態分配,其平均數與標準差分別為

............................………….….(2.5.6)

Ln(ST/S0) 為服從下述之常態分配

……….................................(2.5.7)

估計值的誤差為

.…………….………...........................…….(2.5.8)

其中

................................….(2.5.9)

 

三、Black-Scholes解析解公式

Black-Scholes股票選擇權的公式中,他們基於無套利的條件,使用了風險中立的評價與(2.4.1)的股價隨機程序。其步驟為

1.假設股價的預期收益為無風險資產的收益率r

2.計算選擇權在到期日時預期的償付。

3.以無風險資產的收益率折現該償付。

藉由上述的分析,BlackScholes利用偏微分方程式,推導出了不支付股利股票的歐式買、賣權公式。買權和賣權價格公式分別為

…………………….........................(2.5.10)

…………..........................…(2.5.11)

其中

..………………..........................(2.5.12)

.........…………..……………..(2.5.13)

S = 目前股價,

K = 執行價格,

r = 融資利率為即期利率,

T = 距到期日的時間,

= 股價之波動性,

函數N(x)為標準常態變數之累積機率函數。

 

#001 namespace STBSProcess

#002 {

#003     public partial class Form1 : Form

#004     {

#005         public Form1()

#006         {

#007             InitializeComponent();

#008         }

#009         private void button2_Click(object sender, EventArgs e)

#010         {

#011             Application.Exit();

#012         }

#013         const int BlocksPerGrid = 256;

#014         const int ThreadsPerBlock = 512;

#015         static int NPath = ThreadsPerBlock * BlocksPerGrid; //131,072 Paths

#016         static int MStep = 13;

#017         static DateTime RefDate;

#018         static List<DateTime> FixingDate;

#019         static int[] h_StepGrid;

#020         double[,] S = new double[NPath, MStep];

#021         double[] Value = new double[NPath];

#022         private void button3_Click(object sender, EventArgs e)

#023         {

#024             double Asset = 100.0;

#025             double Strike = 100.0;

#026             double TTM = 1.0;

#027             double Sigma = 0.3;

#028             double Rate = 0.04;

#029             double Yield = 0.02;

#030             double dt = 1.0 / 365.0;

#031             // Analytic Benchmark

#032             double d1 = (Math.Log(Asset / Strike)

#033                 + (Rate - Yield + 0.5 * Sigma * Sigma) * TTM)

#034                 / (Sigma * Math.Sqrt(TTM));

#035             double d2 = d1 - Sigma * Math.Sqrt(TTM);

#036             double CValue = Asset * Math.Exp(-Yield * TTM) * DStat.NormDist(d1)

#037                 - Strike * Math.Exp(-Rate * TTM) * DStat.NormDist(d2);

#038             double PValue = Strike * Math.Exp(-Rate * TTM) * DStat.NormDist(-d2)

#039                 - Asset * Math.Exp(-Yield * TTM) * DStat.NormDist(-d1);

#040             //Random Rnd = new Random(1234);

#041             MersenneTwister Rnd = new MersenneTwister(1234);

#042             Stopwatch SW = new Stopwatch();

#043             RefDate = new DateTime(2014, 7, 1);

#044             FixingDate = new List<DateTime>();

#045             //MStep depend on the remaining FixingDay Number, Including RefDate

#046             // 0, 1, 2,..., 12, 0 for RefDate

#047             for (int i = 0; i < MStep; i++)

#048             {

#049                 FixingDate.Add(RefDate.AddMonths(i));

#050             }

#051             h_StepGrid = new int[MStep];

#052             for (int i = 0; i < MStep; i++)

#053             {

#054                 TimeSpan TS = FixingDate[i].Subtract(RefDate);

#055                 h_StepGrid[i] = (int)TS.TotalDays;

#056             }

#057             double s1, n1;

#058

#059             SW.Start();

#060             for (int i = 0; i < NPath; i++)

#061             {

#062                 s1 = Asset;

#063                 int diff = 0;

#064                 S[i, 0] = s1;

#065                 for (int j = 0; j < (MStep - 1); j++)

#066                 {

#067                     diff = h_StepGrid[j + 1] - h_StepGrid[j];

#068                     for (int k = 0; k < diff; k++)

#069                     {

#070                         n1 = DStat.N_Inv(Rnd.NextDouble());

#071                         s1 = s1 * Math.Exp(((Rate-Yield) - (Sigma*Sigma)/2.0) * dt

#072                             + (Sigma * Math.Sqrt(dt) * n1));

#073                     }

#074                     S[i, j + 1] = s1;

#075                 }

#076                 Value[i] = Math.Max(s1 - Strike, 0);

#077             }

#078             double sum = 0.0;

#079             for (int i = 0; i < NPath; i++)

#080             {

#081                 sum = sum + Value[i];

#082             }

#083             sum = (sum / NPath) * Math.Exp(-(Rate - Yield) * TTM);

#084             SW.Stop();

#085

#086             double gap = sum - CValue;

#087             double ratio = (gap / CValue) * 100.0;

#088             textBox1.Text = SW.ElapsedMilliseconds.ToString();

#089             textBox2.Text = CValue.ToString();

#090             textBox3.Text = sum.ToString();

#091             textBox4.Text = gap.ToString();

#092             textBox5.Text = ratio.ToString();

#093             listBox1.Items.Clear();

#094             for (int j = 0; j < MStep; j++)

#095             {

#096                 listBox1.Items.Add(S[0, j].ToString());

#097             }

#098         }

#099     }

#100 }

程式列表2.5

執行結果如上圖,運算時間約7.2秒,模擬值為12.8400,與解析解的理論值12.5677,誤差值為0.2723,誤差百分比約2.2%上下。我們也把前十個模擬路徑的值,作圖輸出,可以看到整個路徑上標的資產價格的變化。

( 創作其他 )
回應 推薦文章 列印 加入我的文摘
上一篇 回創作列表 下一篇

引用
引用網址:https://classic-blog.udn.com/article/trackback.jsp?uid=andydong1209&aid=113005559