You are on page 1of 217

目 錄

前言..............................................................................................6
前言
致謝..............................................................................................7
致謝
第 1 章 介紹................................................................................8
介紹
1.1 金融學概覽 ....................................................................................................................... 8
1.2 收益分佈假設 ................................................................................................................... 9
1.3 數學和統計方法 ............................................................................................................... 9
1.4 數值方法 ........................................................................................................................... 9
1.5 Excel 解決方案................................................................................................................. 9
1.6 本書主題 ......................................................................................................................... 10
1.7 有關 Excel 工作簿...........................................................................................................11
1.8 意見和建議 ......................................................................................................................11

第 2 章 高級 Excel 函數和過程 ..............................................12


2.1 訪問 Excel 函數.............................................................................................................. 12
2.2 數學類函數 ..................................................................................................................... 13
2.3 統計類函數 ..................................................................................................................... 14
2.3.1 使用頻率函數 Frequency .................................................................................... 15
2.3.2 使用分位元數函數 Quartile ................................................................................ 17
2.3.3 使用正態函數 Norm............................................................................................ 17
2.4 查找類函數 ..................................................................................................................... 18
2.5 其他類型函數 ................................................................................................................. 19
2.6 審核工具 ......................................................................................................................... 20
2.7 模擬運算表(Data Tables) .......................................................................................... 21
2.7.1 建立單變數類比運算表 ...................................................................................... 21
2.7.2 建立雙變數類比運算表 ...................................................................................... 22
2.8 XY 圖 ............................................................................................................................... 23
2.9 訪問資料分析和規劃求解 ............................................................................................. 26
2.10 使用區域名稱 ............................................................................................................... 27
2.11 回歸分析 ....................................................................................................................... 29
2.12 單變數求解 ................................................................................................................... 31
2.13 矩陣代數以及相關函數 ............................................................................................... 32
2.13.1 矩陣介紹 ............................................................................................................ 32
2.13.2 矩陣轉置 ............................................................................................................ 33
2.13.3 矩陣相加 ............................................................................................................ 33
2.13.4 矩陣相乘 ............................................................................................................ 33
2.13.5 矩陣求逆 ............................................................................................................ 34
2.13.6 線性方程組求解 ................................................................................................ 35
2.13.7 Excel 矩陣函數小結 ........................................................................................... 36
小結........................................................................................................................................ 36

第 3 章 VBA 介紹 ....................................................................38
3.1 掌握 VBA 的好處........................................................................................................... 38
3.2 VBA 的面向物件觀點..................................................................................................... 39
3.3 編寫 VBA 宏................................................................................................................... 40
3.3.1 簡單 VBA 副程式................................................................................................ 40
3.3.2 交互函數 MsgBox ............................................................................................... 41
3.3.3 編寫環境 .............................................................................................................. 42
3.3.4 輸入代碼並運行宏 .............................................................................................. 43
3.3.5 錄製按鍵和編輯代碼 .......................................................................................... 43
3.4 編程要素 ......................................................................................................................... 45
3.4.1 變數和資料類型 .................................................................................................. 45
3.4.2 VBA 陣列變數...................................................................................................... 46
3.4.3 控制結構 .............................................................................................................. 48
3.4.4 控制重複過程 ...................................................................................................... 48
3.4.5 在代碼中使用 Excel 和 VBA 函數..................................................................... 50
3.4.6 編程的一般觀點 .................................................................................................. 50
3.5 宏與試算表之間的通信 ................................................................................................. 50
3.6 副程式實例 ..................................................................................................................... 53
3.6.1 圖表 ...................................................................................................................... 54
3.6.2 正態概率散點圖 .................................................................................................. 56
3.6.3 用規劃求解產生有效邊界 .................................................................................. 58
小結........................................................................................................................................ 61
附錄 3A Visual Basic 編輯器 ................................................................................................ 62
附錄 3B 用‘相對引用’模式來錄製按鍵......................................................................... 65

第 4 章 編寫 VBA 用戶定義函數...........................................68
用戶定義函數
4.1 簡單銷售傭金函數 ......................................................................................................... 68
4.2 在工作表中創建 Commission(Sales)函數..................................................................... 69
4.3 多參數期權定價函數 ..................................................................................................... 70
4.4 在 VBA 中運算元組....................................................................................................... 72
4.5 陣列變數的期望和方差函數 ......................................................................................... 73
4.6 陣列變數的組合方差函數 ............................................................................................. 75
4.7 輸出陣列形式的函數 ..................................................................................................... 77
4.8 在用戶定義函數中調用 Excel 和 VBA 函數................................................................ 78
4.8.1 在用戶定義函數中使用 VBA 函數.................................................................... 79
4.8.2 增益集 .................................................................................................................. 79
4.9 編寫 VBA 函數的優缺點............................................................................................... 79
小結........................................................................................................................................ 80
附錄 4A 演示函數如何處理陣列 ........................................................................................ 81
附錄 4B 二叉樹期權定價函數 ............................................................................................ 82
編寫函數練習 ........................................................................................................................ 87
第 5 章 股票的有關簡介 .........................................................92
第 6 章 投資組合最優化 .........................................................93
6.1 組合的均值和方差 ......................................................................................................... 93
6.2 組合的風險-收益表示 .................................................................................................. 95
6.3 用規劃求解得到有效點 .................................................................................................. 95
6.4 求有效邊界(黃和利曾伯格的方法) .......................................................................... 98
6.5 有約束邊界組合 ............................................................................................................ 100
6.6 無風險資產和風險資產的結合 .................................................................................... 102
6.7 問題一 一種無風險資產和一種風險資產的組合 ...................................................... 102
6.8 問題二 存在兩種風險資產的組合 .............................................................................. 104
6.9 問題三 一種無風險資產和一個風險投資組合 .......................................................... 105
6.10 Module1 中的用戶定義函數....................................................................................... 107
6.11 Module1 中用於解決三類常見組合問題的函數 ....................................................... 108
6.12 模組 M 中的巨集功能..................................................................................................110
小結.......................................................................................................................................111

第 7 章 資產定價....................................................................
資產定價 112
7.1 單因素模型 .....................................................................................................................112
7.2 估計β係數 .....................................................................................................................113
7.3 資本資產定價模型(CAPM)......................................................................................115
7.4 方差-協方差矩陣 .........................................................................................................115
7.5 風險值(VaR) ..............................................................................................................117
7.6 水準財富 .........................................................................................................................119
7.7 正態和對數正態分佈矩之間的關係 ............................................................................ 120
7.8 Module1 中的用戶定義函數......................................................................................... 121
小結...................................................................................................................................... 122

第 8 章 投資組合業績評價 ...................................................123
8.1 傳統業績評價方法 ........................................................................................................ 123
8.2 主動—被動管理 ........................................................................................................... 125
8.3 風格分析(Style Analysis) ......................................................................................... 127
8.4 簡單風格分析 ................................................................................................................ 128
8.5 滾動時段風格分析 ....................................................................................................... 129
8.6 風格權重的置信區間 .................................................................................................... 130
8.7 Module1 中的用戶定義函數......................................................................................... 132
小結...................................................................................................................................... 134

第 9 章 股票期權介紹 ...........................................................136
9.1 布萊克-舒爾斯公式的起源.......................................................................................... 136
9.2 布萊克-舒爾斯公式...................................................................................................... 137
9.3 對沖投資組合(Hedge Portfolios) ............................................................................ 138
9.4 風險中性定價 ............................................................................................................... 139
9.5 風險中性定價的單期二叉樹模型 ............................................................................... 140
9.6 期權平價關係(Put-Call Parity) ................................................................................ 141
9.7 紅利(Dividends)....................................................................................................... 142
9.8 美式期權的特徵 ........................................................................................................... 142
9.9 數值方法 ....................................................................................................................... 142
9.10 波動率和非正態股票收益 ......................................................................................... 143
小結...................................................................................................................................... 143

第 10 章 二叉樹 .....................................................................145
10.1 二叉樹介紹 ................................................................................................................. 145
10.2 簡化的二叉樹 ............................................................................................................. 146
10.3 JR 二叉樹..................................................................................................................... 147
10.4 CRR 樹 ......................................................................................................................... 150
10.5 二項分佈近似與布萊克-舒爾斯公式........................................................................ 151
10.6 CRR 二叉樹的收斂性 ................................................................................................. 152
10.7 LR 樹............................................................................................................................ 153
10.8 CRR 樹與 LR 樹的比較 .............................................................................................. 154
10.9 美式期權和 CRR 美式二叉樹 ................................................................................... 155
10.10 Module0 和 Module1 中的用戶定義函數 ................................................................ 157
小結...................................................................................................................................... 158

第 11 章 布萊克-舒爾斯公式
布萊克 舒爾斯公式................................................160
舒爾斯公式
11.1 布萊克-舒爾斯公式.................................................................................................... 160
11.2 在 Excel 中運用布萊克-舒爾斯公式......................................................................... 161
11.3 外匯(Currencies)和商品(Commodities)期權................................................... 162
11.4 計算期權的‘希臘’參數............................................................................................... 163
11.5 對沖組合 ..................................................................................................................... 164
11.6 布萊克-舒爾斯公式的正式推導 ................................................................................ 166
11.7 Module1 中的用戶定義函數....................................................................................... 168
小結...................................................................................................................................... 169

第 12 章 歐式期權定價的其他數值方法.............................171
歐式期權定價的其他數值方法
12.1 蒙特卡羅模擬介紹 ..................................................................................................... 171
12.2 對偶變數(Antithetic Variables)類比 ..................................................................... 173
12.3 准隨機抽樣(Quasi-Random Sampling)模擬......................................................... 173
12.4 模擬方法比較 ............................................................................................................. 175
12.5 蒙特卡羅 模擬中的希臘參數計算 ........................................................................... 176
12.6 數值積分 ..................................................................................................................... 176
12.7 Module1 中的用戶定義函數....................................................................................... 177
小結...................................................................................................................................... 179

第 13 章 非正態分佈和隱含波動率.....................................181
非正態分佈和隱含波動率
13.1 非正態分佈假設下的布萊克-舒爾斯 公式 .............................................................. 181
13.2 隱含波動率(Implied Volatility) ............................................................................. 182
13.3 調整偏度(Skewness)和峰度(Kurtosis) ............................................................ 183
13.4 波動率曲線(The Volatility Smile) ......................................................................... 185
13.5 Module1 中的用戶定義函數....................................................................................... 186
小結...................................................................................................................................... 189

第 14 章 債券期權定價介紹 .................................................190
14.1 利率期限結構 ............................................................................................................. 191
14.2 附息債券的現金流和到期收益率 ............................................................................. 192
14.3 二叉樹 ......................................................................................................................... 192
14.4 布萊克的債券期權定價公式 ..................................................................................... 193
14.5 久期和凸性 ................................................................................................................. 194
14.6 符號............................................................................................................................. 195
小結...................................................................................................................................... 195

第 15 章 利率模型..................................................................197
利率模型
15.1 Vasicek 利率期限結構模型......................................................................................... 197
15.2 Vasicek 模型對零息票債券歐式期權定價................................................................. 199
15.3 Vasicek 模型對附息債券歐式期權定價..................................................................... 200
15.4 CIR 利率期限結構模型 .............................................................................................. 201
15.5 CIR 模型對零息票債券歐式期權定價....................................................................... 202
15.6 CIR 模型附息債券歐式期權定價............................................................................... 202
15.7 Module 1 中的用戶定義函數...................................................................................... 203
小結...................................................................................................................................... 205

第 16 章 擬合利率期限結構 .................................................206
16.1 對數正態分佈利率樹 ................................................................................................. 206
16.2 正態利率二叉樹 ......................................................................................................... 208
16.3 BDT 樹 ......................................................................................................................... 209
16.4 用 BDT 樹為債券期權定價 ....................................................................................... 210
16.5 Module 1 中的用戶定義函數.......................................................................................211
小結...................................................................................................................................... 213

附錄 其他 VBA 函數 .............................................................214
預測...................................................................................................................................... 214
ARIMA 模型........................................................................................................................ 215
樣條...................................................................................................................................... 216
特徵值和特徵向量 .............................................................................................................. 217
前言

當被問到為什麼要攀登珠穆朗瑪峰時,登山員通常會說:“因為它在那兒。”而我們
寫《高級金融建模》這本書則出於相反的原因。無論是以前還是現在,幾乎沒有一本書重點
突出和解釋 VBA 函數在 Excel 中的應用。另一方面,能夠掌握金融領域數值方法精髓的書
也寥寥無幾。
有人認為,像 Excel 這樣的電子製表軟體,不能滿足高級技術和數值分析領域(如金融
衍生工具的定價)的需要,現在這種想法已經過時。以前通過專門的套裝軟體和語言進行的
計算,現在可以應用有效的代碼和 VBA 函數,在一台普通的電腦上只需一秒就可以完成。
通過使用 Excel 和 VBA 編碼,可以使得以前處於黑箱中的計算過程明朗化。
最初,宏的出現拓寬了 Excel 的應用範圍,後來這一應用促進了 VBA 語言在 Excel 中
的全面發展,從股票計算、期權計算,最後到債券計算,VBA 廣泛應用于金融領域中的各
種計算。在本書中,可以學習到一些新的 Excel 技巧,並可更深入地理解數值方法在金融中
的應用。
本書的基礎部分來源於倫敦商學院的 MBA 選修課程講義《基於電腦的金融建模》 。書
中的股票部分是學習《資產組合管理》課程的基礎,該課程每年在日內瓦的國際貨幣銀行中
心舉辦一次。而關於期權和債券的章節則來自城市大學商學院電腦碩士課程《數值方法》 。
本書適用于研究生和本科高年級學生。
使用本書時,讀者必須採取積極嘗試的態度,學會提出問題並解決問題,既要理解書
中的代碼和 VBA 用戶定義函數,也要勇於在實踐中應用它們。由於假設資產收益服從對數
正態分佈,並將二叉樹作為一種核心數值方法,因此我們的解釋可以建立在概率和統計中常
用的結論基礎上。全書採用了統一的符號,並且用圖片顯示了 Excel 和 VBA 的應用過程,
這些都有助於讀者更好地理解本書內容。
致謝

本書得益於之前的學術研究者和金融研究機構,他們發展了有關金融理論,並提出了
相應的數值方法,從而形成了本書的基本內容。用牛頓的話來說,“如果我看得更遠,那是
因為我站在巨人的肩膀上”。
感謝倫敦商學院和城市大學商學院的同事,特別是 Elroy Dinenis,保羅·馬什和 Kiriakos
Vlahos。
同時,還感謝薩姆·惠特克對我們的熱心鼓勵,作為一位編輯,他付出了很大的努力和
耐心。
最後,感謝家人和朋友對我們的耐心,因為本書醞釀了較長一段時間,這期間給他們添
了不少麻煩。
第 1 章 介紹

我們希望《高級金融建模》一書可以證明,能夠應用電子製表軟體成功地實現大部分
的金融模型。這些模型從二十世紀五十年代早期發展到九十年代末期,覆蓋了整個金融領
域,包括股票、股票期權和債券期權。只要輔助使用 VBA 語言,這些模型完全能在 Excel
試算表中實現。而用戶定義函數提供了一個方便的程式庫,使得計算的速度和準確度大大提
高。
《高級金融建模》應該看作是這個領域中傳統教材的補充讀物(它甚至是對傳統教材
的糾正) 。本書沒有列出金融模型的詳細推導過程,目的是為了能夠涵蓋更多的模型和方法,
特別是將重點放在更新的研究成果上。
金融領域發展的重要理論包括:二十世紀五十年代的組合理論,六十年代的資本資產
定價模型(CAPM) ,以及七十年代的布萊克-舒爾斯公式,這些理論中的解析解現在都能直
接計算。這都得益於最近一二十年來發展的數值演算法。通過選擇適當的參數,二叉樹方法
在股票和債券期權定價的數值演算法中扮演著重要的角色。在最近幾年,金融領域的研究重
點落在尋找有效的計算方法上,而不是理論本身。
儘管本書覆蓋了大部分的金融領域,並且包括了不少複雜的模型,但只需應用 Excel,
以及 Excel 中內嵌的函數和 VBA 程式,就能完美地解決問題。這使得我們可以將常用的假
設(對數正態分佈) 、數學問題(期望)和數值方法(二叉樹)在金融建模領域統一起來。
當然,我們也努力確保本書使用一致和簡單的符號,以便表達的更加清晰。
嘗試在本書中覆蓋大部分的金融研究課題,這對我們來說既是一個挑戰也是一個機
遇。機遇就是我們可以縱覽金融領域,並將資產定價中的假設、數學問題、數值方法和 Excel
的解法連接起來,總結出一般性規律。在以下的幾節中,將簡要地描述在股票、期權和債券
計算中,關於金融、數學、數值方法和 Excel 特點方面的一些問題。以下的內容將會在以後
的章節中詳細地分析。

1.1 金融學概覽

現代金融學作為一門學科與經濟學分離,起源于 1952 年馬可維茨創立的組合理論。馬


可維茨利用效用理論對個人投資者的選擇進行建模,並且建立“均值-方差”方法來檢驗收
益(以資產的平均收益來度量)和風險(以資產收益的方差來度量)之間的關係。這一研究
成果後來導致了夏普,林特恩和特雷納的資本資產定價模型(CAPM)的發展。CAPM 是一
個均衡模型,它描述了股票的期望收益。模型中引入 beta 作為測量可分散風險的因數,並
證明構建股票組合能夠有效地減少個別風險事件帶來的總體風險。
另外一個重要的理論就是布萊克和舒爾斯的股票期權定價公式,這個公式是構築在對
沖組合(無風險)的基礎上的。同時,默頓對布萊克-舒爾斯公式進行了擴展,使其適用於
連續股利的情況,並可對商品期貨期權和外匯期權定價。公式最初的推導需要解物理學中常
見的擴散方程,但用風險中性方法也可以推導出來。
1.2 收益分佈假設

儘管組合理論是根據個人投資者的選擇推導出來的,但是它也可以通過對資產價格收
益的分佈進行合理假設來推導。標準的假設就是股票收益服從對數正態分佈,或者假設股票
的對數收益服從正態分佈。最近,業界學者檢驗了實際分佈同嚴格正態分佈之間的偏離效應
(偏度和峰度),並建議使用一些其他的分佈(如逆 gamma 分佈)。
而債券與股票相比有許多不同之處,因此債券期權定價的出發點是短期利率。一般假
設短期利率服從對數正態分佈或正態分佈。這些概率分佈的特性被廣泛應用于各種金融研究
中。

1.3 數學和統計方法

在關於股票的章節中,涉及到最優化數學方法。這些最優化方法可能含有約束條件,

如夏普基於資產收益所進行的分析。在他的分析中, β 代表線性回歸的斜率。

期權定價是在風險中性的條件下求統計學中的數學期望。對數股票價格的正態分佈可
以用離散的二項分佈來近似。二項分佈為計算期權的期望價格提供了一個框架。

1.4 數值方法

在關於組合最優化的章節中,最優化涉及到組合的方差,而解決最優化的數值方法是
二次規劃。風格分析也用到了二次規劃,也就是使得誤差的方差最小。而線性回歸也是通過
選擇斜率係數來使誤差項的平方和最小,儘管它通常不被看作是最優化問題。與一般最優化

問題有所不同的是,線性回歸為計算 β 係數提供了一個直接公式。

在為期權定價方面,二叉樹方法為計算風險中性期望提供了一個分析框架。我們通過
檢驗三個不同二叉樹的收斂效應來強調參數選擇的重要性。這些二叉樹也可以給美式期權定
價,在美式期權中,期權可以在到期日之前的任意時刻執行。
在歐式期權中,像蒙特卡羅模擬和數值積分等技巧也經常用到。而數值迭代方法,特
別是牛頓-拉夫森方法,可以用來估算期權市場價格中的隱含波動率。

1.5 Excel 解決方案

試算表展示了如何應用 Excel 進行建模。在每張工作表中,所有單格中的公式都很容易


計算,而我們也儘量對單格中的中間計算過程進行合併。試算表具有靈活的特點,當參數改
變時,結果也隨之發生變化,這方便使用者檢驗參數對計算結果的影響。
書中所有的模型和方法都會實現兩次:一次通過試算表,另一次通過 VBA 函數。這樣
做的目的是檢驗數值計算的精確度。
部分 VBA 程式是巨集,這通常被視為 VBA 在 Excel 中的主要應用。但絕大部分計算程
式都是用戶定義函數。我們會展示這些函數用 VBA 語言編寫是如何的簡單,並說明它們如
何與 Excel 的內嵌函數結合在一起,包括功能強大的矩陣函數。
Excel 中的單變數求解 )和規劃求解
單變數求解(Goal Seek) )是用來解決最優化問題的。
規劃求解(Solver)
我們會展示這些方法如何在 VBA 用戶定義函數和巨集中自動實現。Excel 的另外一個未被
充分利用的功能是陣列函數(用 Ctrl+Shift+Enter 組合鍵來調用) ,我們會在用戶定義函數
中使用它們。為了提高效率,在用戶定義函數中使用的二叉樹只採用了一維陣列(向量)而
不是二維陣列(矩陣)。

1.6 本書主題

本書包括四部分,第一部分介紹用 Excel 進行高級建模的特點,其後三部分是其在金融


領域的應用。應用的三部分內容分別涉及股票、股票期權和債券期權。
第 2 章介紹本書需要用到的高級 Excel 函數和技巧。重點關注 Excel 中的陣列函數,並
用較短的篇幅介紹矩陣運算的相關知識。
第 3 章介紹 VBA 編程環境和一種循序漸進地編寫 VBA 副程式(巨集)的方法。並用
例子說明宏是如何自動操作和重複 Excel 中的任務的。
第 4 章介紹 VBA 用戶定義函數,它在金融計算中至關重要。強調如何處理標量變數和
陣列變數,包括將它們作為 VBA 函數的輸入變數和輸出變數。另外,用循序漸進的方法列
舉了一些例子。特別地,通過寫用戶定義函數為歐式期權(布萊克-舒爾斯公式)和美式期
權定價(二叉樹)。
第 5 章介紹第一個應用部分——如何處理股票。
第 6 章講解組合最優化,利用規劃求解
規劃求解和分析解。規劃求解
規劃求解 規劃求解經常用於試算表計算,並
規劃求解
能在 VBA 宏中自動執行,因此在本章的其他部分也會頻繁出現。通過採用 Excel 和 VBA 中
的陣列函數,我們演示了如何得到資產組合有效邊界上的點。組合理論的發展衍生分為三個
常見問題,它們將在後面的章節中介紹。
第 7 章轉入資產定價,從單因數模型出發,介紹資本資產定價模型(CAPM) ,最後討
論風險值(VaR)。本章的另一個主題是關於資產對數收益服從正態分佈的假設。
第 8 章的主要內容是各種模型的效果測定,從最早使用的單參數測量到目前最具實用
性的多因數模型(如風格分析)。在本書中,我們第一次說明在風格分析中如何確定資產權
重的置信區間。
第 9 章介紹第二個應用部分,即如何處理股票期權。在股票對數收益服從正態分佈的
假設下,我們演示了構建對沖組合在布萊克-舒爾斯期權定價公式中的重要地位。並具體解
釋了期權價值是風險中性條件下期權未來收入期望值的折現值。
第 10 章介紹二叉樹,它被看作是對數股票價格服從的連續正態分佈在離散情況下的近
似。實際應用時,由於二叉樹方法能夠有效地處理美式期權的定價問題,因此它成為期權定
價數值方法的核心。本章為二叉樹方法列舉了三套不同的參數選擇,其中包括 LR 樹。與標
準的二叉樹相比,它擁有更好的收斂性和準確度。並利用一個九期樹作例子,用戶定義函數
能夠處理任何期數的二叉樹定價。
第 11 章回到布萊克-舒爾斯公式,並演示了它的適應性(能夠對外匯和商品期貨期權定
價)和它對資產價格假設的依賴性。
第 12 章介紹計算布萊克-舒爾斯公式中期望值的兩種方法。這兩種方法分別是蒙特卡羅
模擬法和數值積分法。儘管對簡單期權來說,這兩種方法並沒有多大的優勢,但在為複雜的
期權定價時,它們扮演著重要角色。
第 13 章放開關於資產對數收益服從正態分佈的假設,介紹在背離原來假設的基礎上(主
要通過改變偏度和峰度參數),由期權市場價格確定的隱含波動率曲線(volatility smile)。
本章還介紹了計算歐式期權價格隱含波動率的有效方法。
第 14 章為第三個應用部分,即如何處理債券期權。由於債券與股票相比存在許多不同
的屬性,因此為債券期權定價時出現的數學問題和使用的數值方法也有所不同。我們根據一
系列零息票債券價格來定義期限結構,並展示用短期利率如何構建二叉樹模型,這個模型可
以為零息票債券現金流定價。
第 15 章涵蓋了兩個利率模型,Vasicek 模型以及考克斯,英格索爾和羅斯模型(CIR
模型)。我們分析了零息票債券價格和零息票債券期權的解析解,並介紹了為附息債券期權
定價的一種方法。
第 16 章介紹了在給定零息票債券期限結構的情況下,如何用短期利率構建二叉樹模
型。構造著名的布萊克-德曼-托伊利率樹模型(用試算表和用戶定義函數),並展示它如何
為歐式和美式零息票債券期權定價。
附錄中是其他用戶定義函數,這些函數與我們選定的幾個應用部分的聯繫不很密切。但
它們是有用的工具箱,可以作為 ARIMA 模型、樣條、特徵值和其他計算過程的函數。

1.7 有關 Excel 工作簿

第 一 部 分集 中 介紹 Excel 函 數和 理解 VBA 語 言。 這 部 分有 三 個相 關 工作 簿 ,
AMFEXCEL,VBSUB 和 VBFNS 分別對應於第 2,3 和 4 章。
第二部分是關於股票的三個工作簿,EQUTY1,EQUTY2 和 EQUTY3,分別對應第 6,
7 和 8 章。
第三部分關於股票期權有四個工作簿,OPTION1,OPTION2,OPTION3 和 OPTION4,
分別對應第 10,11,12 和 13 章。
第四部分關於債券方面有兩個工作簿,BOND1 和 BOND2,對應第 14,15 和 16 章,
具體見書中的解釋。
附錄有一個工作簿 OTHERFNS。

1.8 意見和建議

儘管花費了很大精力收集材料和撰寫本書,我們仍然很樂意接受意見、建議甚至是改
正和改善。請發到電子郵箱 mstaunton@london.edu 或者通過以下網頁與我們聯繫。
www.london.edu/ifa/services/services.html 或 者
www.business.city.ac.uk/irmi/mstaunton.html。
第 2 章 高級 Excel 函數和過程

本章回顧了本書用到的一些函數和過程。包括 Excel 中各類函數中的數學、統計和查找


函數,以及常用過程,如建立模擬運算表(Data Tables)和用 XY 圖顯示結果等。還包括
匯總資料集、進行回歸分析以及訪問 Excel 單變數求解(Goal Seek)和規劃求解(Solver)
的方法。目的是為了闡明和保證這些內容能掃清讀者前面的障礙。高級 Excel 用戶可以略過
這些內容,或在需要的時候再來參考本章的內容。為了使這些不同的主題更有趣和更具有交
互性,本文提供了一個包含本章全部常式的工作簿 AMFEXCEL.xls,可以用來檢測讀者的
熟練程度。

2.1 訪問 Excel 函數

Excel 提供了許多工作表函數,它們是一些已經編寫好的計算程式。函數常用於試算表
的簡單計算,在 VBA 巨集代碼和用戶定義函數中也經常用到這些基本函數(見第三章和第
四章) 。
點擊標準工具欄中的粘貼函數
粘貼函數按鈕(標記為 fx)就可以訪問這些函數。函數嚮導
粘貼函數 函數嚮導如圖
函數嚮導
2.1 所示,函數分為幾個不同的類別:如數學與三角函數類、統計類、邏輯類、查找與引用
類,等等。

【參照書中第 9 頁的圖 2.1】

圖 2.1 粘貼函數對話方塊顯示數學與三角函數
粘貼函數 數學與三角函數類別中的
數學與三角函數 COMBIN 函數

如圖 2.1 所示,數學與三角函數
數學與三角函數類別中的
數學與三角函數 COMBIN 函數被選中,這時對話方塊下面出
現該函數輸入值和輸出值的簡單描述。要想得到更詳細的描述,可以點擊幫助 幫助按鈕(標記
幫助
為?)

點擊確定
確定按鈕之後,就會出現提供適當參數輸入框的公式面板,如圖
確定 2.2 所示。需要輸
入的資訊可以用鍵盤鍵入(如這裏),也可以通過選擇試算表中的網格來引用(點擊輸入框
右側的按鈕可以縮小公式面板)。注意,可以拖動公式面板離開它原來的位置。點擊面板上
的確定
確定按鈕或編輯欄中的勾號,就可以把公式輸入到試算表。
確定

【參照書中第 10 頁的圖 2.2】

圖 2.2 在公式面板中建立 COMBIN 函數

圖 2.2 顯示,在公式面板裏輸入 COMBIN 函數參數的時候,編輯欄中會相應地出單格


公式的基本結構,而且粘貼函數粘貼函數按鈕會呈現出‘按下’狀態。還應該注意的是,粘貼名稱
粘貼函數 粘貼名稱按
粘貼名稱
鈕(標記為 =ab)可以將已命名的單格粘貼到公式中。 (為單格區域以及引用單格區域命名
的內容見 2.10 節。)
不僅可以訪問 Excel 自帶的函數,粘貼函數
粘貼函數按鈕還可以訪問用戶定義函數,見第四章內
粘貼函數
容。
討論完如何訪問函數後,接下來我們介紹一些常用的數學和統計類函數。

2.2 數學類函數

本書用到的數學與三角函數
數學與三角函數有:EXP(x)、LN(x)、SQRT(x)、RAND()、FACT(x)和
數學與三角函數
COMBIN(number,number_chosen)。
x
EXP(x)返回指數函數的值,exp(x)或 e 。例如:

 EXP(1)返回 e 的值(2.7183,小數位數為 4)
2
 EXP(2)返回 e 的值(7.3891,小數位數為 4)

−1
 EXP(-1)返回 1/e 或 e 的值(0.36788,小數位數為 5)

在金融計算時,經常需要利用複利(或折現)因數將不同時段的現金流轉換為未來價值

(或現值)
。給定連續複利 r,則一年的複利因數為 exp(r),對應的年利率為 ra ,如果複利以
年為基礎,則公式為:

ra = exp(r ) − 1
關於連續複利以及 EXP 函數的應用,將在 2.7.1 節的模擬運算表中作進一步的闡述。
LN(x)返回 x 的自然對數值。注意,x 必須為正,否則函數會因數值溢出而返回#NUM!。
例如:
 LN(0.36788)的返回值為-1
 LN(2.7183)的返回值為 1
 LN(7.3891)的返回值為 2
 LN(-4)的返回值為#NUM!
在金融領域,我們經常與(自然)對數收益打交道,可以利用 LN 函數將收益值轉換為
對數收益。
SQRT(x)返回 x 的平方根。很顯然,x 必須為非負,否則函數會因數值溢出而返回#NUM!。
RAND()產生[0, 1]區間均勻分佈的亂數。每次試算表重新計算時,產生的亂數都不一
樣。用蒙特卡羅模擬法計算期權價格時,我們可以利用 RAND()函數來產生亂數。
FACT(number)返回整數 number 的階乘,它等於 1×2×3×…×number。例如:
 FACT(6)的返回值為 720
COMBIN(number,number_chosen) 返 回 number 個 元 素 的 組 合 值 ( 子 集 大 小 為
,子集可以按任何順序組合。例如,如果某支股票的價格在四個離散時間
number_chosen)
裏要麼上漲,要麼下跌,則出現三次上漲(和一次下跌)序列的個數為:
COMBIN(4,1) = 4 或者 COMBIN(4,3) = 4
也就是這樣四個序列‘上漲-上漲-上漲-下跌’、‘上漲-上漲-下跌-上漲’、
‘上漲-下跌-上漲-上漲’和‘下跌-上漲-上漲-上漲’。從統計的角度來說,

COMBIN(4,3)表示從 4 個元素中選擇 3 個元素的組合值,通常記為 4 C 3(或者通用的 n C r )


Excel 中還有一些函數可以進行矩陣轉置、矩陣相乘、或求方陣的逆。相應的函數分別
為:
 TRANSPOSE(array)返回矩陣 array 的轉置
 MMULT(array1,array2)返回兩個矩陣的乘積
 MINVERSE(array)返回矩陣 array 的逆矩陣
這些函數都屬於數學類函數。可能有些讀者對矩陣並不熟悉,為了熟悉這些函數,我們
將在本章的末尾對矩陣做介紹(見 2.13) 。

2.3 統計類函數

Excel 中有一些函數可以快速匯總資料集(Excel 術語叫‘陣列’)的一些特徵。如函


數 AVERAGE(array)返回陣列的平均值,STDEV(array)返回陣列的標準差,MAX(array)和
MIN(array)返回陣列的最大值和最小值。
為了考察資料集的分佈,還要瞭解一些其他的函數。例如,QUARTILE 函數返回一個
資料集的四分位元數,而 FREQUENCY 函數則返回一個資料集分組後的頻率分佈。
Excel 還提供一些概率分佈函數,如正態分佈函數 NORMSDIST 和正態分佈反函數
NORMSINV 等。
還有一些有用的二元(二個變數)統計函數,它們在進行回歸分析和相關性分析時用處
很大。例如:
 INTERCEPT(known_y’s,known_x’s)
 SLOPE(known_y’s,known_x’s)
 RSQ(known_y’s,known_x’s)
 STEYX(known_y’s,known_x’s)
 CORREL(known_y’s,known_x’s)
 COVAR(known_y’s,known_x’s)
還有一個大家不太熟悉的陣列函數 LINEST(known_y’s,known_x’s),它以陣列的形式返
回一些必要的回歸統計量。此類函數將在 2.11 節介紹回歸分析內容時作詳細說明。我們還
將把它們的返回值與資料回歸分析過程中的回歸結果作對比。
下一節,我們將通過 AMFEXCEL 工作簿裏 Frequency and Snorm 表中的例子來說明
如何使用 FREQUENCY、QUARTILE 以及各種正態分佈函數。

2.3.1 使用頻率函數 Frequency

FREQUENCY(data_array,bins_array)統計一個資料集中出現在特定間隔(或‘bins’)
中的元素個數,並以一豎列陣列返回。‘bins_array’為用於對 ‘data_array’ 中的數值
進行分組的間隔陣列。由於該函數是以陣列的形式返回,所以在輸入函數之前,必須在試算
表中為返回值選定一個相鄰的單格區域。
我們從 AMFEXCEL 工作簿 Frequency and Snorm 表中的一個例子出發,來說明如何
使用 FREQUENCY 函數。如圖 2.3 所示,D10:D71 列和 E10:E71 列中的月收益和對數收
益(採用 LN 函數)資料的統計資訊放在第 4 到第 7 行。假設現在我們想得到對數收益
(E10:E71),即所謂‘data_array’的頻率分佈。目的是為了檢測這些資料是否近似地服
從正態分佈。首先,我們為分組確定間隔。觀察一下最大和最小的對數收益,範圍在-0.16
到+0.20 之間,分為 10 到 12 個間隔比較合適。將間隔值輸入到 G5:G14 中,這些值作為對
數收益分組的上邊界。

Return for months 1-62:1-62 月份的收益數據;


Summary Statistics:統計量;
Returns:收益;
Ln Returns:對數收益;
Frequency Distribution:頻率分佈;
Mean:均值;St Dev:標準差;Max:最大值;Min:最小值;interval:間隔;freq:頻數;
%freq:頻率百分比;%cum freq:累積頻率百分比;Month:月份;Total:共計

【參照書中第 13 頁的圖 2.3】

圖 2.3 計算對數收益資料的頻率分佈

為了正確地輸入 FREQUENCY 函數,先選定單格區域 H5:H15。然後鍵入=,並點擊粘



貼函數按鈕(標記為 fx)來完成句法:
貼函數
=FREQUENCY(E10:E71, G5:G14)
在輸入完最後一個括弧‘)’後,將滑鼠放在 Excel 的編輯欄,然後按下 Ctrl+Shift+Enter
組合鍵,就可以完成函數輸入了。(你需要用三個手指同時按下,否則無效。如果失敗了,
使輸出範圍繼續保持在‘選中’狀態,然後按下編輯 編輯鍵(F2)
編輯 ,必要時重新編輯公式,然後
再次按下 Ctrl+Shift+Enter 鍵。)
此時你會看到單格中的函數被一對大括弧‘{}’括起來了,而且單格 G5:G15 中出現了
頻率陣列。結果如圖 2.4 所示。在單格 H17 中使用 SUM 函數檢查一下頻率資料之和是否等
於 62。
查看結果,我們可以看出,沒有低於-0.16 的對數收益,處在-0.16 和-0.12 之間的有 6
個值,而大於 0.20 的對數收益也沒有。 (FREQUENCY 返回陣列的最底下單格 G15 中,包
含了超過‘bins’上限 0.20 的數值個數。)
由於 FREQUENCY 函數的輸出是陣列形式,所以不能對其中的某個單格作修改。如果
間隔陣列改變了,則當前的輸出陣列必須先刪除,然後重新輸入函數。
可以將計算出來的頻率轉換為百分比頻率(分別除以資料集的大小 62) ,並進而計算出
累積百分比頻率,如圖 2.4 中的 I 列和 J 列所示。百分比頻率和累積百分比頻率公式可以在
Frequency 表中看到。

Return for months 1-62:1-62 月份的收益數據;


Summary Statistics:統計量;
Returns:收益;
Ln Returns:對數收益;
Frequency Distribution:頻率分佈;
Mean:均值;St Dev:標準差;Max:最大值;Min:最小值;interval:間隔;freq:頻數;
%freq:頻率百分比;%cum freq:累積頻率百分比;Month:月份;Total:共計

【參照書中第 14 頁的圖 2.4】

圖 2.4 對數收益的百分比頻率和累積百分比頻率分佈

顯示累積百分比頻率的最好方法是用 XY 圖,資料點用一條沒有標記的平滑曲線連接。
要生成圖 2.5 中所示的圖形,可以選擇單格區域 G5:G14 和 J5:J14 作為資料源。注意,如
果要選中一些不連續的區域,可以先選擇第一個區域,然後按下 Ctrl 鍵不放鬆,再選擇第
二個以及後繼的區域。

Frequency Distribution:頻率分佈;
interval:間隔;freq:頻數;theory:理論值;Cumulative Frequency:累積頻率;
actual:實際值;
%freq:頻率百分比;%cum freq:累積頻率百分比;Month:月份;Total:共計

【參照書中第 14 頁的圖 2.5】

圖 2.5 累積百分比頻率圖(實際資料和嚴格正態分佈的資料)

對於正態分佈的對數收益,累積分佈呈一個 S 形(如圖中的虛線所示)
。而實際的對數
收益資料則可能是由於偏度的原因,與正態分佈有一些偏離。

2.3.2 使用分位元數函數 Quartile

QUARTILE(array,quart)函數返回資料集四分位元數。其中的第二個參數‘quart’是一
個整數,表明返回哪一個四分位數:即,quart=0 時,返回陣列的最小值;quart=1 時,返
回第 1/4 分位數(即排序後,處於陣列 25%處的值) ;quart=2 時,返回中位數(50%)
;quart=
時,返回第 3/4 分位數(75%);如果是 4,返回最大值。
QUARTILE 函數提供了一個快捷並相對容易的方法來得到一個資料集的累積分佈。例
如在圖 2.6 的單格 H22 中輸入:
QUARTILE(E10:E71,G22)
這裏 G22 中的值為 1,於是該函數返回第 1/4 四分位數。單格中顯示的數值為-0.043,也就
是說,在選定的陣列中,低於-0.043 的對數收益占整個資料集的 25%。第 2/4 分位數為
0.028,是中位數,第 3/4 分位數為 0.075,低於此數的對數收益占整個資料集的 75%。圖
2.6 還畫出了區域 H21:H25 的 XY 圖,並對數據點作了標記。可以看出,基於五個數據點上
的累積分佈曲線與圖 2.5 中的分佈曲線頗為相似。

Quartiles:四分位數值;Cumulative Frequency from quartiles:四分位元點的累積頻率

【參照書中第 15 頁的圖 2.6】

圖 2.6 使用 QUARTILE 計算 Frequency 表中的對數收益累積分佈

第 3.5 節演示如何在 VBA 中進行陣列處理時會用到 QUARTILE 函數。與 QUARTILE


相關的函數,PERCENTILE(array,k),返回一個資料集的第 k 個百分位點的數值,第 4.7 節
演示如何編寫陣列函數時會用到此函數。

2.3.3 使用正態函數 Norm

在統計類函數中,與正態分佈有關的函數名稱都是以 NORM 開頭的,後面跟著字母 S


時,則專指標準正態分佈。
NORMSDIST(z)返回標準正態累積分佈函數值。NORMSINV(probability)返回給定概率
下標準正態分佈的分位數。
函數 NORMDIST(x,mean,standard_dev,cumulative)的功能則強大的多,它適用於任何
正態分佈。如果‘cumulative’的值為 1(或 TRUE),則返回累積分佈函數值;如果
‘cumulative’的值為 0(或 FALSE),則返回概率密度函數值。圖 2.7 顯示,在 Norm 表
中,單格 C5 和 D5 中分別輸入的是概率密度和左尾概率。這兩個單格公式都使用了
NORMDIST 函 數 , 且 均 值 和 方 差 均 為 0 和 1 。 在 C5 中 , 函 數 最 後 一 個 輸 入 項
(‘cumulative’)的值為 0,因此返回值為概率密度,而在 D5 中,其值為 1,從而得到
左尾概率。給定左尾概率時的分位元數可以用 NORMINV 函數得到,如單格 F5 所示。
拷貝這些公式,並檢測其結果,進一步熟悉這些函數。
最後,我們將得到對數收益的累積百分比頻率分佈。檢驗正態性的方法之一是採用觀測
資料的均值和方差,利用 NORMDIST 函數計算一組理論上的百分比頻率。結果見工作表
Frequency 中的 K 列(見圖 2.5)
。理論分佈與實際收益分佈在圖 2.5 中一起顯示。很明顯,
兩者之間有一定的差距。

Excel Normal Functions for N(0,1):Excel 正態分佈函數

【參照書中第 17 頁的圖 2.7】

圖 2.7 工作表 Snorm 中的一般正態分佈函數

Excel 提供了大量的函數來進行資料匯總和理論分佈建模。本書的股票和期權部分將用
到它們。

2.4 查找類函數

在含有相關資訊的表格中,查找函數可以根據不同的輸入資訊,檢索出其相關的資訊。
例如,在圖 2.8 中,我們利用 VLOOKUP 函數從波動率及對應的期權價格表中檢索出給定
波動率下的布萊克-舒爾斯期權價格。 (布萊克-舒爾斯公式的基本理論見第 11 章。)
一般來講,函數 VLOOKUP(lookup_value,table_array,col_index_num,range_lookup)
可以在給定表格(‘table_array’)中的最左一列中查找出匹配值,然後返回同一行中指定
列(‘col_index_num’)中的數值。缺省情況下,表格中的第一列是按昇冪排列的(這就
暗示 range_lookup=1(或 TRUE))。實際上,在本例中,最後一個參數可以忽略不寫。
關於查找的例子可以在工作表 LookUp 中找到。為了檢驗你是否已經理解,可以用
VLOOKUP 函數查找出不同銷售額下應付的傭金,傭金率放在單格區域 F5:G7 中。然後滾
動到下面的布萊克-舒爾斯期權價格查詢表,如圖 2.8 所示。
所要查找的波動率放在 C17(20%)中,表格陣列為 F17:G27,波動率按昇冪排列,
期權價格在表格的第二列。因此,單格 D18 中的公式為:
VLOOKUP(C17, F17:G27,2)
返回波動率為 20%時對應的期權價格為 9.73。

Black-Scholes Call Value Lookup Table:布萊克-舒爾斯看漲期權定價表;


Volatility:波動率;BS Call Value:布萊克-舒爾斯看漲期權價值;

【參照書中第 17 頁的圖 2.8】

圖 2.8 工作表 LookUp 中查找給定波動率下的期權價格

要查找的值(‘lookup_value’)可以近似(或精確)地匹配表格中第一列的資料,在
匹配的基礎上找到同一行中指定列的資料,並返回。可以試著在 C17 中輸入不同的值,如
20.5%、21.5%等,看看這個查找函數是如何工作的。
‘range_lookup’參數是一個邏輯值(TRUE 或者 FALSE) ,表明是進行近似匹配還是
精確匹配。如果是 TRUE 或忽略,則進行近似匹配。這時如果沒有找到完全相同的值,就
會用比‘lookup_value’小的最大值來匹配。如果是 FALSE,VLOOKUP 函數將進行精確
匹配,這時沒有找到完全相同的值就會返回錯誤值#NA。
與 VLOOKUP 類似的函數 HLOOKUP 則對行資料進行匹配,先查找表格中第一行中的
匹配資料,然後返回同一列中指定行的資料。
MATCH 和 INDEX 也 是 查 找 類 函 數 , 參 看 圖 2.8 中 的 演 示 。 函 數
MATCH(lookup_value,lookup_array,match_type) 返 回 單 一 列 ( 或 行 ) 中 在 指 定 方 式 下
(‘match_type’) ,與指定數值匹配的陣列元素的相對位置。注意該函數返回的是匹配數
值在陣列中的位置,而不是數值本身。
如果 match_type 為 0,函數則返回精確匹配的數值位置,不管陣列如何排序。如果
match_type 為 1,則返回近似匹配的數值位置,此時需要陣列按昇冪排列。如果 match_type
為-1,也返回近似匹配的數值位置,但此時需要陣列按降冪排列。
在圖 2.8 中,G 列中的期權價格按昇冪排列。為了找出陣列中匹配 9.73 的數值位置,
可以在 D22 中輸入公式:
=MATCH(C21,G17:G27,1)
其返回值為 6。
函數 INDEX 返回表或區域裏特定行列中的數值。在圖 2.9 中,特定的行和列為單格 C25
和 C26 中的值,於是返回陣列 F17:G27 中第六列、第二行中的值。

Black-Scholes Call Value Lookup Table:布萊克-舒爾斯看漲期權定價表;


Volatility:波動率;BS Call Value:布萊克-舒爾斯看漲期權價值;

【參照書中第 18 頁的圖 2.9】

圖 2.9 工作表 LookUp 中的函數公式和結果

如果陣列是單一列(或者單一行),參數‘col_num’(或‘row_num’)可以為空。你可
以改變一下單格 D27 中的值來練習函數 INDEX 在這種情況下的使用方法。
我們將在本書的股票部分應用 VLOOLUP、MATCH 以及 INDEX 函數。

2.5 其他類型函數

在介紹試算表公式的同時,我們也想盡可能地介紹一些‘通用’的公式,它們可以處理
一些相關但不完全相同的情況。例如,圖 2.10 中顯示的是某只債券在某年的現金流,可以
是 0,可以是利息,也可以是本金加上利息。

Bond Cashflows:債券現金流;Cash Flows for bonds:債券的現金流量

【參照書中第 18 頁的圖 2.10】


圖 2.10 工作表 Bonds 中含有混合定址以及嵌套 IF 函數的通用公式

IF 函數給出了兩種狀況下的不同結果,而含有一級嵌套的 IF 函數則可以給出三種不同的結
果(嵌套越多,可給出的結果也越多)。單格 C11 中的現金流公式含有一級嵌套:
=IF($B11<C$6,C$5,IF($B11=C$6,100+C$5,0))
如果把 C11 中的公式拷貝到 C11:H13 中,就會得到每只債券每年的現金流。
對於類型 1 的債券,現金流依賴於不同年份(單格 B11)和債券到期時間(C6) 。如果
年份在到期時間之前(B11<C6) ,則現金流就是利息 C5;如果剛好到期(B11=C6)
,則現
金流為本金加上利息;其他情況(B11>C6)則現金流為 0。內嵌的 IF 函數處理到期年份以
及到期年份之後的現金流,而週邊的 IF 函數則處理第一種狀態下的利息收入。
在輸入公式時我們採用了‘混合定址’方式,這是為了保證在拷貝單格公式時,引用能
夠作正確地變化。我們輸入 C$6 和 C$5 是為了保證在沿著列 C 向下拷貝時,始終將行 5 和
行 6 中的資料作為到期年份和利息率。而$B11 則隨著年份的不同變為$B12 和$B13。我們
輸入$B11,則當公式拷貝到 D 列中時,B 列中的資料仍然作為年份來計算,而 C$5 和 C$6
則變為 D$5 和 D$6。
在複製複雜模型的結果時,編寫這種通用公式得到的收穫比節約的時間更有價值。

2.6 審核工具

對於複雜的單格公式,使用審核
審核按鈕組將會給你很大的幫助。從功能表欄中調出該按鈕
審核
組的方法之一,是點擊視圖
視圖功能表下的工具欄
視圖 工具欄,然後選擇用戶定義
工具欄 用戶定義…。在如圖 2.11 中所示
用戶定義
的用戶定義
用戶定義對話方塊中,選中審核
用戶定義 審核,就會出現審核
審核 審核按鈕組。
審核

【參照書中第 19 頁的圖 2.11】


圖 2.11 訪問審核
審核工具欄及其主要按鈕
審核

這組按鈕如圖 2.11 所示,它們的名稱從左到右分別為追蹤引用單格


追蹤引用單格、移去引用單格追
追蹤引用單格 移去引用單格追
蹤箭頭、追蹤從屬單格
蹤箭頭 追蹤從屬單格。
追蹤從屬單格
回到試算表,選中單格 C11,然後點擊追蹤引用單格
追蹤引用單格按鈕,就可以顯示出單格
追蹤引用單格 C11 中
引用到的單格,如圖 2.12 所示。(圖中也顯示了 F13 中引用到的單格。)點擊移去引用單
移去引用單
格追蹤箭頭就可以清除這些箭頭。
格追蹤箭頭

Bond Cashflows:債券現金流;Cash Flows for bonds:債券的現金流量

【參照書中第 20 頁的圖 2.12】

圖 2.12 工作表 Bonds 中的追蹤引用單格


追蹤引用單格按鈕使用演示
追蹤引用單格

用戶定義對話方塊可以按你的意願來定制工具欄。如果你點擊命令
用戶定義 命令頁,並選中某一類
命令
別,你可以選擇並拖動命令
命令列表中的工具按鈕將按鈕拖到工具欄中。相反,你也可以選擇和
命令
拖動按鈕將按鈕移出工具欄(使它們返回工具框)。

2.7 模擬運算表(
模擬運算表(Data Tables)

模擬運算表(Data Tables)可以執行單格公式一系列的重複計算,而不用拷貝或重新
輸入公式。AMFEXCEL 工作簿中有不少類比運算表的應用實例。這裏用 CompoundDTab
工作表中計算複利和折現因數的例子說明單變數和雙變數輸入類比運算表的使用方法。在工
作表 DSBTab 中也有其他一些關於模擬運算表應用的例子。

2.7.1 建立單變數類比運算表

圖 2.13 給出了利率為 5%的年連續複利因數(單格 C10 中)


。利率為 5%的年折現因數
則放在單格 C11 中。單格中的公式也同時顯示出來。
可以得到包含不同時段複利因數和折現因數的表格,如 t=1、2、一直到 10 年。用模擬
運算表來完成這項任務,首先規劃一下適當的版面,如圖中的第 16 行及其下方所示的那樣。
需要重複計算的公式放在模擬運算表的第一行(行 16)。因此在 D16 中,公式為
‘=C10’,這使得它與單格 C10 中的公式聯繫起來。同樣的,在 E16 中,公式為‘=C11’。
作為輸入變數,時間 t 的資訊則放在 C 列,其起始行在公式行之下。注意,單格 C16 是處
在公式行中,並且它的值為空。圖 2.13 例子中所謂的表格區域就是 C16:E26。

Continuous Compounding:連續複利;
Enter formula(s) for output:輸入公式;
Enter numbers for input variable t:為參數 t 輸入數位;
【參照書中第 21 頁的圖 2.13】

圖 2.13 工作表 CompoundDTab 中單變數輸入類比運算表版面佈局

現在工作表就可以進行模擬運算表計算了,只需簡單地做如下操作:
 選中表格區域 C16:E26
 在主功能表中,點擊資料 資料中的類比運算表
資料 類比運算表
在對話方塊中:列輸入單格
列輸入單格中輸入單格
列輸入單格 確定按鈕
C7,然後點擊確定
確定

結果如圖 2.14 所示,表中單元格格式的可讀性更強。單格中顯示的是數位,但實際上包含


的是陣列公式。這些數值是動態的,如果假定的資料如利率 r,或變數 t 發生了改變,則它
們將被重新計算一遍。可以試著將 C5 中的利率改成 6%,然後觀察單格數值的變化。接下
來,請將利率改回 5%。

Compounding/Discounting Factors:複利/折現因數;
Enter formula(s) for output:輸入公式;
Enter numbers for input variable t:為參數 t 輸入數位;

【參照書中第 22 頁的圖 2.14】

圖 2.14 模擬運算表中不同時段的複利因數和折現因數

2.7.2 建立雙變數類比運算表

假設我們希望計算出不同利率不同時段的折現因數(單格 C11 中的公式)。同樣,首先


必須規劃雙變數輸入的類比運算表版面佈局。一種可能的版面佈局如圖 2.15 所示。

Enter formula(s) for output:輸入公式;


Enter numbers for input variable t:為參數 t 輸入數位;

【參照書中第 22 頁的圖 2.15】

圖 2.15 CompoundDTab 中雙變數的類比運算表版面佈局

這裏,表格區域為 C30:I40。第一列數值是計算折現因數需要用到的時間 t(列輸入變數)。


第 30 行中則列出五種利率值(行輸入變數) 。在表格左上角的單格(C30)中則包含著根據
不同利率和時間計算折現因數的公式。C30 中的公式為‘=C11’,它與 C11 中的折現因數
計算公式相聯繫。
計算表格中資料的步驟如下:
 選擇表格區域 C30:I40
 在主功能表中,點擊資料
資料中的類
資料 類比運算表
在對話方塊中:列輸入單格
列輸入單格輸入
列輸入單格 C7
行輸入單格為
行輸入單格 C5
然後點擊確定
確定按鈕
確定

其結果如圖 2.16 所示。將圖中利率為 5%時計算出的資料與圖 2.14 中的資料做一個對


比,看看是否一致。

Enter formula(s) for output:輸入公式;


Enter numbers for input variable t:為參數 t 輸入數位;

【參照書中第 23 頁的圖 2.16】

圖 2.16 模擬運算表中不同利率不同時段的折現因數

模擬運算表在處理‘what-ifs’類問題時極為有用。其優點在於表格能夠自動地適應模
型的變化。而其缺點在於:如果工作表中含有大量的模擬運算表,當輸入改變後,連續的重
新計算會降低處理速度。基於這個原因,有時可能需要關掉類比運算表的自動重算功能。
建立類比運算表需要注意一下幾點:
 到目前為止,Excel 要求模擬運算表的輸入單格必須與模擬運算表在同一個工作表
中。
 類比運算表單格中的公式是以陣列形式出現的,例如,模擬運算表單格的輸入為
{=TABLE(C5,C7)},其中的 C5 和 C7 是輸入單格。既然是以陣列的形式出現,那
麼你就不能編輯它。
 如果要重建或者擴建模擬運算表,可以先選中所有包含了{=TABLE()}的單格,然後
點擊編輯編輯功能表下的清除所有
編輯 清除所有,或者直接按
清除所有 Del 鍵。
 改變輸入或其他假定的資料,會導致類比運算表重新計算,除非缺省的計算方法做
了有意的改動。

在大型模型中,類比運算表中每一個輸入的重新計算可能需要很長的時間,這時可以關
閉模擬運算表的自動重算功能。要做到這一點,可以進行如下操作
 點擊工具
工具功能表下的選項
工具 選項
 點擊重新計算
重新計算頁,選中除模擬運算表外
重新計算 除模擬運算表外,
除模擬運算表外,自動重算選項
自動重算

當自動重算功能關閉後,按下 F9,強迫所有的模擬運算表重新計算一遍。
如果你對期權定價的布萊克-舒爾斯公式很熟悉,你可以通過建立工作表 BSDTab 中建
議的三個模擬運算表來鞏固模擬運算表方面的知識。它同樣可以用來計算布萊克-舒爾斯看
漲期權價格對即期股票價格 S 的敏感度,以及對其他輸入變數的敏感度。

2.8 XY 圖

Excel 提供了許多類型的圖表,但是在數學、科學和金融方面,XY 散點圖是最有用的。


在不會產生混淆的情況下,我們簡稱其為 XY 圖。關於 XY 圖,很重要的一點是它的 X 軸和
Y 軸都是數值刻度。而所有其他的雙軸圖表(包括折線圖),只有縱坐標軸是數值刻度,而
橫坐標軸則是標籤型。
可以用圖表嚮導
圖表嚮導來建立一個
圖表嚮導 XY 圖,共有四個步驟,它們分別是圖表類型
圖表類型、圖表源資料
圖表類型 圖表源資料、
圖表源資料
圖表選項和圖表位置
圖表選項 圖表位置。其中最重要的是第二步,圖表源資料
圖表位置 圖表源資料。這些步驟已經在
圖表源資料 2.7.1 節中討
論單輸入變數類比運算表的結果時提到,並在圖 2.14 中作了演示。CompoundDTab 工作表
中畫圖所用到的類比運算表結果區域為 C17:E26,C 列中的資料作為 x 值,D 列和 E 列中
的資料用來作圖。選中作圖的區域後,按下列步驟進行:

1. 點擊主工具欄中的圖表嚮導
圖表嚮導按鈕。
圖表嚮導 (它像一個小的條形圖。)在步驟 1 的對話方塊中(如
圖 2.17 所示),選擇圖表類型
圖表類型;這裏,選擇
圖表類型 XY 散點圖子圖表類型中的無數據點平滑線散點
散點圖 無數據點平滑線散點
圖。點擊按下不放可查看示
按下不放可查看示例
按下不放可查看示例按鈕。如果覺得不錯,就可以點擊下一步
下一步按鈕。
下一步

【參照書中第 24 頁的圖 2.17】

圖 2.17 圖表類型對話方塊
圖表類型

2. 在步驟 2 的對話方塊中,檢查資料區域
資料區域輸入框中的資料源是否是正確的,注意,Excel
資料區域
將這個資料區域理解為三列資料。點擊系列 系列頁,可以看到系列
系列 系列 1 中的 X 值和 Y 值。點擊名

稱輸入框,選擇工作表中單格或是直接鍵入(compound)的方式為當前啟動的系列加一個
名稱。圖 2.18 中顯示系列
系列 2 的名稱改成了單格 E15 中的 discount。點擊下一步
下一步按鈕繼續。
下一步
【參照書中第 25 頁的圖 2.18】

圖 2.18 在圖表源資料
圖表源資料對話方塊中指定
圖表源資料 X 值和 Y 值

3. 在步驟 3 的對話方塊中,輸入圖表選項
圖表選項,如標題、格線、圖例等。在我們的例子中,
圖表選項
象圖 2.19 中顯示的那樣,增加標題並去掉格線就夠了。點擊下一步
下一步按鈕繼續。
下一步
【參照書中第 25 頁的圖 2.19】

圖 2.19 圖表選項對話方塊
圖表選項

4. 在步驟 4 的對話方塊中,決定圖表位置
圖表位置。圖表可以作為工作表的一部分
圖表位置 (嵌入式圖表)

也可以作為一個分開的圖表頁。通常是作為一個嵌入式圖表,這樣就可以看到圖表源資料變
化的效果了,如圖 2.20 顯示的那樣。

【參照書中第 26 頁的圖 2.20】

圖 2.20 圖表位置對話方塊
圖表位置

從專業的角度來看,圖 2.21 這種未經加工的圖表還需要做進一步的修飾,用以改進它


的外觀。主要的改進有,將繪圖區的背景顏色改為白色(無背景顏色) ,在圖表選項
圖表選項中的坐
圖表選項 坐
標軸頁裏改變坐標軸,就像在標題
標軸 標題和圖例
標題 圖例中那樣。經常需要改變的是坐標軸刻度,以及標題
圖例
的字體等。繪圖區的大小也需要調整。有的資料系列可能需要顯示資料點(啟動資料系列並
重新設定格式)。通過修改,就可以得到圖 2.14 中顯示的那種圖表了。

Compounding/Discounting Factors:複利/折現因數;

【參照書中第 26 頁的圖 2.21】

圖 2.21 由圖表嚮導
圖表嚮導生成的未經加工的圖表
圖表嚮導

2.9 訪問資料分析和規劃求解

Excel 有一些附加的模組,這些模組在完全安裝時是可用的,但如果選擇節省空間的安
裝,則被忽略。我們需要用到規劃求解和資料分析回歸過程,因此需要先檢查一下工具 工具功能
工具
表,看看它們是否可用。如圖 2.22,其中含有規劃求解
規劃求解和資料分
規劃求解 資料分析
資料分析選項。如果工具 工具功能表
工具
中沒有,你可以點擊增益集增益集選項(也在工具
增益集 工具功能表中)
工具 。在如圖 2.22 所示的對話方塊中選中
分析工具庫、分析工具庫
分析工具庫 分析工具庫-
分析工具庫 函數和規劃求解
-VBA 函數 規劃求解,然後點擊確定
規劃求解 確定按鈕。安裝完畢後,你就
確定
可以在工具
工具功能表中看到這兩個選項了。
工具
【參照書中第 27 頁的圖 2.22】

圖 2.22 含有資料分析
資料分析和規劃求解
資料分析 規劃求解選項的工具
規劃求解 工具功能表,以及增益集
工具 增益集對話方塊
增益集

在解最優化問題時,可以對規劃求解的使用作最好的描述,因此這部分內容將放在本書
股票部分的 6.5 節,在那裏,使用規劃求解來求解最優的組合權重。
在利用函數和分析工具庫來進行回歸分析之前,我們先簡單地介紹一下區域名稱,它在
選擇和引用大範圍資料時是很有用的。

2.10 使用區域名稱

圖 2.23 顯示的是 AMFEXCEL 工作簿 Beta 表中的股票 A 和股票指數收益的開始部分。


在接下來的一節裏,我們要對股票收益和指數收益進行回歸分析,看看它們之間是否存在一
定的關係。為了詳細說明計算過程,先給包含資料的單格區域取一個名稱是很有用的,比如
說,將資料區域 B5:B64 命名為 ShareA,將資料區域 C5:C64 命名為 Index。
【參照書中第 28 頁的圖 2.23】

圖 2.23 帶有名稱的資料區域,粘貼名稱
粘貼名稱按鈕以及定義名稱
粘貼名稱 定義名稱對話方塊
定義名稱

需要命名的區域被選中後,就可以在主功能表欄左下方的名稱框裏鍵入你想取的名稱,
如圖 2.23 所示。這樣,在 Beta 工作表中,名稱 ShareA 就與區域 B5:B64 綁定起來。另外,
還可以選擇插入 插入功能表下的名稱
插入 名稱選項,然後點擊定義
名稱 定義選項來為選中的區域命名,在出現的對
定義
話方塊中鍵入名稱 ShareA 即可,如圖 2.23 所示。這樣,選擇和引用收益區域時就可以用
它的名稱來代替了,比如選定名稱框中的名稱 ShareA,或是在輸入函數時使用粘貼名稱粘貼名稱按
粘貼名稱
鈕。

2.11 回歸分析

假設讀者已經對簡單的回歸分析(兩個變數)很熟悉,在本書的股票部分將用到它。這
裏,我們概述一下怎樣利用 Excel 來進行必要的計算。實際上,Excel 有多種方法來進行回
歸運算,主要有兩類:使用 Excel 函數和使用分析工具庫中的簡單回歸程式。我們將用 Beta
工作表中的股票和指數收益來演示這兩種不同的簡單回歸方法,首先用 Excel 函數,然後使
用資料分析回歸過程。如果你對這些函數和過程不熟悉,Beta 工作表提供了一個適當的練
習版面。
Excel 提供了一些進行回歸分析時經常用到的函數。圖 2.24 展示了回歸方程的截距、斜
率函數,以及兩種擬和度函數:R 平方和標準差
平方 標準差(STEYX
標準差 表示‘standard eror of Y given
X’)。由於資料區域已被命名,所以可以用粘貼名稱 粘貼名稱按鈕把它們的名稱輸入到函數中。這
粘貼名稱
些函數結果會隨著輸入資料(ShareA 和 Index 區域中的資料)的變化而動態變化。

Excel regression functions:Excel 回歸函數;

【參照書中第 29 頁的圖 2.24】

圖 2.24 Beta 工作表中的 Excel 回歸函數

除了上面提到的這些函數,還有一個 LINEST 陣列函數,它以兩列收益資料為輸入項,


返回陣列形式的基本回歸量。注意,在書寫 LINEST 句法時,為函數的輸出選擇一個適當大
小的區域是很重要的。圖 2.25 顯示了函數 LINEST(ShareA,Index,,1)在函數參數
函數參數面板中
函數參數
輸入參數時的情況,此時輸出區域 F40:G44 已經被選定。‘Const’參數為空,而‘Stats’
參數為 1,這時會輸出全部的回歸統計值。

【參照書中第 29 頁的圖 2.25】

圖 2.25 在公式面板中建立 LINEST 陣列函數


陣列輸出如圖 2.26 所示(包括注解)。除了斜率和截距(這裏它們的標記分別為 Beta
和 Alpha),LINEST 還提供了擬合的標準差,以及一個基本的方差分析結果(也叫
‘ANOVA’)

Output from Linest(Remember Ctrl+Shift+Enter):


Linest 函數的輸出結果(記住要按下組合鍵 Ctrl+Shift+Enter)

【參照書中第 30 頁的圖 2.26】

圖 2.26 Beta 表中採用 LINEST 函數來分析收益資料的陣列輸出

下一步,我們來練習一下分析工具庫中的回歸過程。首先,點擊功能表工具 工具下的資料分
工具 資料分
析選項,然後點擊回歸
回歸,於是就出現了圖
回歸 2.27 中顯示的對話方塊。同樣,對話方塊中的 Y
區域和 X 區域可以通過選擇單格區域來引用,也可以通過輸入名稱來引用(如果區域已經
命名的話)。一般來說,指定一個資料表中左上角的單格作為輸出區域比接受缺省輸出選項
(將結果輸出到一個新工作表中)更方面一些。

【參照書中第 30 頁的圖 2.27】

圖 2.27 設定分析工具庫的回歸計算以及輸出選項

結果如圖 2.28 所示,回歸方程的截距和斜率放在單格 F23 和 F24 中。R 平方和標準差


平方 標準差
(殘差的標準方差)放在 F12 和 F13 中。輸出是靜態的,也就是說,這些數值不再隨著輸
入資料的變化而變化。如果任何輸入資料發生了改變,分析過程是不需要調整的,但必須手
動重新計算。
【參照書中第 31 頁的圖 2.28】

圖 2.28 Beta 工作表中分析工具庫回歸程式的分析結果

為了對比演示函數的動態特性,我們假設 4 月份的指數後來被更正為 0.08(不是現在


C8 中的-0.08)
。如果輸入改變了,則 F31:F34 以及 F40:F44 中的函數結果會立即更新,例
如,RSQ 會從 0.4755 變為 0.3260。而要想更新分析工具庫的分析結果,則必須將回歸過
程重新運行一遍。
分析工具庫程式的靜態輸出特性使得它們在計算時不像 Excel 函數那樣有吸引力。這些
程式是由 Excel 版本 4 中的舊 XLM 巨集語言編寫的。更重要的是,不同於大多數 Excel 函
數,它們很難在 VBA 用戶定義函數中被調用。

2.12 單變數求解

單變數求解是另一類 Excel 靜態過程。這種工具可以在已知單個公式預期結果的情況


下,求解公式的輸入值。例如,在圖 2.29 中,股票期權的布萊克-舒爾斯看漲期權價格與市
場價格不一致。 (布萊克-舒爾斯期權價格依賴於標的股票的波動率,並需要對未來波動率作
估計。)假設我們想要知道波動率大小為多少時,能使得兩者一致,也就是使得兩者之間的
差距(G9)為 0。這是單變數求解的一個典型應用。
在 BSDTab 表中使用單變數求解,可以點擊工具
工具功能表下的單變數求解
工具 單變數求解選項。填寫如圖
單變數求解
2.30 中所示的輸入框,然後點擊確定 確定按鈕。單變數求解的處理結果如圖
確定 2.31 所示,要使布
萊克-舒爾斯期權價格與市場價格一致,波動率必須為 23%。

Black-Scholes Option Values:布萊克-舒爾斯期權價值;


Black-Scholes Call Value:布萊克-舒爾斯看漲期權價值

【參照書中第 32 頁的圖 2.29】

圖 2.29 BSDTab 表中的 BS 看漲期權價格和市場價格

【參照書中第 32 頁的圖 2.30】

圖 2.30 利用單變數求解求波動率(C9),使得 BS 價格與市場價格一致


Black-Scholes Option Values:布萊克-舒爾斯期權價值;
Black-Scholes Call Value:布萊克-舒爾斯看漲期權價值

【參照書中第 32 頁的圖 2.31】

圖 2.31 單變數求解求出的波動率大小

單變數求解從一個初值開始,然後採用一種迭代方法使結果與設定值逐漸靠近。可變單 可變單
格中的數值就作為初值,在這裏是 20%。求解時,你可以改變一個單格中的輸入值,也可
以改變多個單格中的輸入值(見第 6 章)

作為練習,可以將市場價格改為 9,然後在 BSDTab 表中用單變數求解來求出相應的波
動率。

2.13 矩陣代數以及相關函數

矩陣的概念在代數中應用非常廣泛,它為結構相似的方程提供了一個緊湊的表達形式。
矩陣運算看起來很像代數運算,但是矩陣相乘卻顯得很複雜。Excel 包含了一些有用的矩陣
函數,它們屬於數學類函數,要想熟練地使用它們,必須先瞭解一些矩陣的基本背景知識。
接下來的一節,我們將解釋一下矩陣的概念,然後介紹矩陣的轉置、相加、相乘以及逆運算。
演示這些運算的常式放在 AMFEXCEL 工作簿的 MatDef 表中。對矩陣很熟悉的讀者,可以
跳過這節內容,直接看一下矩陣函數小結(2.13.7)就可以了。

2.13.1 矩陣介紹

在代數中,一個矩形的數值陣列就是矩陣。只有一列數值的矩陣通常被稱為列向量;同
樣,只有一行數值的矩陣被稱為行向量。在 Excel 中,矩形的單格區域被稱為陣列。下面的
這些數值區域都可以看成為矩陣:
−3 2 7
−3 2 7
2 2 20 19
6 7 2 20 19
4 7 9 21
7 9 21
0 13 3

在這裏‘||’只是一個符號。如果我們將上面的四個矩陣分別起名為 x、y、A 和 B,則


x 就是一個列向量,y 是一個行向量。矩陣 A 有三行三列,因此是一個方陣。B 不是方陣,
因為它有四行和三列,它是一個 4×3 的矩陣。行數 r 和列數 c 給出了一個矩陣的維數,有時
寫成(r×c)的形式。例如,如果:

2
x= 並且 y = 6 7
4
則 x 的維數為(2×1),而 y 的維數為(1×2)

2.13.2 矩陣轉置

矩陣的轉置是將矩陣的行轉換為列(反之亦然)。很明顯,列向量 x 的轉置是一個行向
T
量,表示為 x 。圖 2.32 中的試算表演示了列向量 x 和行向量 y 的轉置過程。

TRANSPOSE 函數作用於陣列區域,並返回它的轉置矩陣。例如,單格 C4:C5 中 2×1


向量 x 的轉置矩陣維數為(1×2)。使用 TRANSPOSE 函數時,先選中單格區域 I4:J4,然
後鍵入公式:
=TRANSPOSE(C4:C5)
然後按下組合鍵 Ctrl+Shift+Enter。其結果如圖 2.32 所示。

Array Manipulation:陣列操作;Transposes:轉置;
Array:陣列;dim:維數;

【參照書中第 34 頁的圖 2.32】

圖 2.32 MatDef 工作表中演示的矩陣運算

2.13.3 矩陣相加

兩個矩陣相加是將對應的元素分別相加。因此,這兩個陣列必須具有相同的維數。所以,
T
x 和 y 是不能相加的,而 x 和 y 具有相同的維數,2×1,它們是可以相加的,其結果如下:

2 6 8
x + yT = + = =z
4 7 11
如果將向量 y 數乘以 10,則 y 中的每一個元素都乘以 10。結果如下:

10 y = 10* 6 7 = 60 7 0
這相當於 10 個 y 相加。

2.13.4 矩陣相乘

兩矩陣作相乘運算時,必須有一個維數是相等的,即,一個矩陣的列數必須等於另一個
矩陣的行數。簡稱其為‘維數一致’。如果要得到乘積 xy,則 x 的列數必須等於 y 的行數,
(2×1)乘以(1×2),其結果為一個(2×2)的矩陣。
在圖 2.32 中,單格 C10:D11 中乘積 xy 的計算過程如下:
2 2*6 2 *7 12 14
6 7= =
4 4*6 4 *7 24 28
就是說,乘積 xy 第一行第一列的元素是 x 第一行元素乘以 y 第一列元素的結果,如此類推。
作為對比,乘積 yx 是維數(1×2)乘以(2×1)
,結果為(1×1),也就是說,它只包含
一個元素。觀察單格 C13 中的乘積 yx,其計算過程如下:

2
6 7 = 6 * 2 + 7 * 4 = 40
4
這些計算結果表明,乘積 xy 與乘積 yx 是不相等的。所以相乘的順序很重要的。
MMULT 陣列函數返回的是兩個矩陣‘array1’和‘array2’的乘積。因此,為了得到
乘積 xy 的(2×2)矩陣元素,必須先選中一個 2×2 的單格區域,然後鍵入或利用粘貼函數
粘貼函數
按鈕輸入如下的公式:
=MMULT(C4:C5,C7:D7)
最後記住同時按下組合鍵 Ctrl+Shift+Enter。
如果資料區域 C4:C5 和 C7:D7 分別命名為 x 和 y,則公式可以簡單地寫成:
=MMULT(x,y)
再考慮兩個大點的陣列:

12 4 16 19 −2
C= 並且 D =
3 13 5 12 14
C 和 D 的維數分別為(2×2)和(2×3)
,既然 C 的列數與 D 的行數相同,因此乘積 CD
是可以得到的,它的維數是(2×3) ,計算過程如下:

(12*16 + 4 *5) (12 *19 + 4*12) (−12 * 2 + 4*14) 212 276 32


CD = =
(3*16 + 13*5) (3*19 + 13*12) (−3* 2 + 13*14) 113 213 176
但是,乘積 DC 卻不能成立,因為兩者的維數不匹配(D 的列數不等於 C 的行數)
。一
般地講,矩陣相乘是不能互換的,所以通常 CD≠ ≠DC。
如果 C 和 D 分別是上面兩個陣列的名稱,則單格公式:
=MMULT(C,D)
將生成一個(2×3)的陣列。

2.13.5 矩陣求逆

一個方陣 I,它的對角線上的元素全為 1,而其他的元素全為 0,我們叫這個方陣為單位


矩陣。因此:

1 0 0 L 0
0 1 0 L 0
0 0 1 L 0 是一個單位矩陣。
L L L L L
0 0 0 L 1
假設 D 是前面提到的(2×3)的矩陣,而 I 是一個(2×2)的單位矩陣。那麼:

1 0 16 19 −2 16 19 −2
ID = * = =D
0 1 5 12 14 5 12 14
任何矩陣與一個適當維數的單位矩陣相乘都等於該矩陣本身(就如同與 1 相乘一樣)。

現在假設 A 是一個維數為 n 的方陣,也就是一個 n×n 矩陣。如果存在一個方陣 A−1 ,滿

足下面的條件,我們就把它叫做矩陣 A 的逆矩陣:
A−1 A = AA−1 = I
例如,
−3 2 7 −0.175 −0.015 0.072
A= 2 20 19 則 A−1 = −0.064 0.079 −0.050
7 9 21 0.086 −0.029 0.045
並且
1 0 0
−1
AA = I = 0 1 0
0 0 1
求一個矩陣的逆矩陣是一件很麻煩的事。幸運的是,函數 MINVERSE 可以直接求矩陣
的逆。例如,為了得到圖 2.33 中矩陣 A 的逆矩陣,我們先選中一個 3×3 的單格區域 I17:K19,
然後輸入陣列公式:
=MINVERSE(C17:E19)
就可以了。讀者可以將結果與 A 相乘來檢測一下它是否正確。

Array:陣列;dim:維數;

【參照書中第 336 頁的圖 2.33】

圖 2.33 MatDef 工作表中顯示的矩陣逆運算

2.13.6 線性方程組求解

矩陣逆運算的用途之一是對如下形式的方程組求解:

−3 x1 + 2 x2 + 7 x3 = 20

2 x1 + 20 x2 + 19 x3 = −5

7 x1 + 9 x2 + 21x3 = 0
它們可以寫成矩陣的形式:Ax=b,其中:
−3 2 7 20 x1
A= 2 20 19 b = −5 x = x2
7 9 21 0 x3
要想解這組方程,可以將方程的兩邊分別乘以矩陣 A 的逆矩陣:

A−1 Ax = A−1b ,因此 Ix = A−1b 也就是 x = A−1b


在圖 2.33 中,解向量 x 就是在單格區域中利用矩陣相乘求得的:
=MMULT(I17:K19,C21:C23)
並不是所有的線性方程組都有唯一解,在一些特殊條件下,它可能有多個解。方程組
−1
Ax=b 有唯一解的充要條件是:矩陣 A 為方陣,且它有逆矩陣 A−1。通常,它的解由 x = A b

求得。

2.13.7 Excel 矩陣函數小結

匯總一下,Excel 中有進行矩陣轉置、矩陣相乘、矩陣求逆運算的函數。對應的函數如
下:
TRANSPOSE(array) 返回一個矩陣的轉置
MMULT(array1, array2) 返回兩個矩陣的乘積
MINVERSE(array) 返回一個矩陣的逆矩陣
由於這些函數是以陣列形式輸出的,因此輸出陣列的大小必須預先知道。在選中適當大
小的區域之後,才能鍵入公式(或者利用粘貼函數 粘貼函數按鈕以及函數參數
粘貼函數 函數參數面板)
函數參數 。最後按下組合
鍵 Ctrl+Shift+Enter 而不是簡單的 Enter 鍵來輸入公式。如果操作失敗,可以保持輸出區域
在 ‘ 選 中 ’ 狀 態 , 然 後 按 下 編 輯 鍵 ( F2 ), 必 要 時 重 新 輸 入 公 式 , 最 後 再 按 一 次
Ctrl+Shift+Enter 組合鍵。
為了鞏固所學的知識,可以試著做一下 MatExs 工作表中的練習。
我們將在本書的股票部分大量地使用到矩陣函數,不管是用於試算表計算,還是用於
VBA 用戶定義函數。

小結

Excel 中有各種類型的函數和過程。它們包括數學、統計和查找類函數,以及常用的過
程,如建立模擬運算表和用 XY 散點圖顯示結果等。
要訪問函數,可以點擊粘貼函數
粘貼函數按鈕,函數的參數可以在函數參數
粘貼函數 函數參數對話方塊中輸入。區
函數參數
域名稱的使用可以簡化操作,特別是當區域比較大的時候。區域名稱可以用於函數參數
函數參數對話
函數參數
方塊中。
審計工具條給我們帶來很大的方便,特別是追蹤引用單格
追蹤引用單格、移去引用單格追蹤箭頭
追蹤引用單格 移去引用單格追蹤箭頭和追
移去引用單格追蹤箭頭 追
蹤從屬單格按鈕,它們在檢查公式時非常有用。
蹤從屬單格
熟悉各類函數是很必要的,因為它們能夠非常容易地嵌入到用戶定義函數中,進行 VBA
編碼時也經常用到它們。
在使用陣列函數時需要非常小心。必須預先知道輸出陣列的區域大小。然後選中適當大
小的單格區域並輸入公式,最後按下組合鍵 Ctrl+Shift+Enter。
嵌入式函數是動態的,也就是說,當它們的輸入資料發生改變時,函數結果也會隨之變
化。相比之下,一些過程如單變數求解和分析工具庫中的程式則是靜態的。資料堆疊(data
dump)的結果與初始資料是沒有關聯的。因此當輸入資料改變時,這些過程必須重新運行
一遍。
第 3 章 VBA 介紹

本章通過實例來介紹 Excel 中 VBA 和宏的應用。VBA 可以增強工作表的功能。這裏,


我們並不打算對 VBA 編程做全面的介紹,只是想通過例子來掌握一些必要的 VBA 編程知
識,瞭解一下編程語言的‘面向物件’功能,並採用一種增量方法來控制代碼。本章大部分
常式都只包含一些簡單的編碼,第一個常式‘hands-on’出現在 3.3.3 節中。然而在 3.6 節
中,有些應用程式被擴展的更加全面,並涉及到宏的應用。其中包括產生圖表的副程式,計
算並展示正態概率分佈圖的副程式,以及生成有效邊界的副程式。工作簿 VBSUB.xls 中包
含了本章討論的所有常式,可以將其作為參考。但還是建議讀者新建一個工作簿來編碼(不
要打開 VBSUB 工作簿)。
整本書會不斷的復習 VBA 編程知識。後面章節中提到的函數和巨集都是以本章和下一
章的內容為基礎的。

3.1 掌握 VBA 的好處

有經驗的用戶使用宏是出於兩種原因:方便控制重複計算;協助那些對試算表不熟的第
三方用戶。從我們的觀點來看,掌握 VBA 的主要目的是能夠利用函數和巨集來進行自動計
算。如果一系列計算由函數代替,則試算表模型將變得更為強大。Excel 提供了各種類型的
函數,而 VBA 可以將函數的範圍進一步擴大。另外,使用 VBA 巨集來產生圖表或進行自動
重複操作非常有用,如進行模擬。在這兩種情況下都需要使用 VBA,但第一種情況會使用
用戶定義函數,而第二種情況則使用巨集(副程式) 。然而兩種類型的編程代碼大部分都是
相同的,本章將集中講解宏的編寫方法,而在第四章則集中講解用戶定義函數的編寫方法。
Excel 中使用的編程語言叫做 Visual Basic for Applications,簡稱為 VBA。單詞 basic
表明這種語言源於古老的 BASIC 語言,這意味著 VBA 在處理大量計算時效率不高。當 PC
機變得越來越強大,並且試算表的功能越來越多時,試算表與專業計算套裝軟體之間的界限
也變得越來越模糊了。當前的問題是:完成一項任務的最佳途徑是什麼?如:發現‘有效邊
界’,模擬一隻股票的表現,或者求一個矩陣的‘特徵向量’。答案依賴於用戶的目的。試
算表的運算速度較慢,但計算過程卻很容易理解。而專業套裝軟體的運算速度很快,但其計
算過程太過晦澀。
根據要解決的問題來選擇 VBA 的使用方式是很重要的,試算表並不能提供所有問題的
解決方案。使用 VBA 副程式來處理自動重複計算任務是很有效的;使用 VBA 建立簡單函數
也是很方便的;但是想編寫強大的互動式程式,使得一個新手能夠訪問一個複雜的試算表模
型,則似乎非常困難。也許真有程式師可以處理這類問題,但我們並不提倡這樣做。VBA
不是所有編程任務的萬能靈藥,它應該被選擇性地使用,因為還有一些更為有效的方法來處
理那些計算量大的任務。
Excel 的宏錄製器(macro recorder)可以將用戶的按鍵轉化為 VBA 代碼,並且可以用
來提供適當的代碼。雖然我們可以不必知道底下的 VBA 代碼而直接使用宏錄製器,但我們
本章的目的是解釋並演示一些 VBA 的實際應用,這樣能使你更加有效地使用整個 Excel 套
裝軟體。也許在剛開始時,最好的辦法是先用宏錄製器產生初始代碼,然後在你熟悉 VBA
代碼之後,再選擇性地編輯(或重寫)這些代碼。
瞭解 VBA 副程式與函數之間的區別是很重要的。它們之間有較大的差異,包含一段源
代碼的函數可以返回數值(或陣列) ,而 VBA 副程式則不能。典型的 VBA 副程式是沒有輸
入項的,但它們可以執行一系列試算表命令(這些命令可以使用試算表單格中的數值,並改
變某些單格中的數值) 。而函數則可以接受輸入(或‘參數’) ,並在執行一系列數值計算後,
返回一個數值(或一個陣列) 。然而,不管是 VBA 副程式還是函數,試算表都是第一個發展
的工具。

3.2 VBA 的面向物件觀點

首先要掌握一些基本概念,實際上 VBA 是一種‘面向物件’的編程語言。每一個 Excel


物件代表 Excel 中的一個部件或者一項功能,例如:檔、工作表、區域、圖表、情節等等,
都是 Excel 的物件,Excel 本身也是一個物件(它是應用程式物件) 。可以通過 VBA 編程來
操縱 Excel 物件的屬性和調用這些物件。
描述物件和 VBA 的語言很多,但它們基本上可濃縮為四句相當籠統的話。教科書和 VBA
幫助檔中對此做了大量的解釋,但一般來說,這些解釋可能會使你覺得更加混亂。
第一句話:物件是一個集合。例如,Workbooks 物件包含了所有已打開的工作簿,
Worksheets(或者 Sheets)也一樣(包含一個工作簿中所有的工作表) ,Scenarios(一個
工作表中所有的情景)、Charts(一個工作表中所有的圖表)等等都是如此。然而,有些物
件只包含一個成員(也就是只有一個成員的集合) ,例如,Excel 只有一個 Application 物件
(它本身) ,試算表中任何一個單格都只有一個 Font 物件(儘管這個物件有多個屬性,如名
稱、字體大小等等。) 。這些單一的物件可以被直接引用,如簡單地寫成 Application.和 Font.
(物件後面緊跟一個‘句點’)的形式。集合中的單個物件可以用數位(1,2,3…)或名稱
索引,如 Workbooks(1).或者 Sheets(“inputs”).。區域物件是一個單一物件,它的引用方式
與集合相似,可以通過名稱和位址索引,如 Range(“data”).或者 Range(“A1:B20”).。
第二句話:物件是有層次的。下面的序列就展示了 Excel 中物件的層次特點。它顯示了
Model.xls 工作簿 inputs 表中的單格區域‘data’是如何通過它所處的層次位置被引用的:
Application.Workbooks(“Model.xls”).Sheets(“inputs”).Range(“data”)
當單格區域的名稱(這裏是‘data’)是唯一的時候,就不需要寫出所有的層次。如果
Model.xls 工作簿是當前的啟動文件,則寫成 Sheets(“inputs”).Range(“data”)就足夠了;或
者直接引用啟動檔:
ActiveWorkbook.Sheets(“inputs”).Range(“data”)
同樣地,如果只有 Model.xls 工作簿被打開,並且工作表 inputs 是當前的啟動頁,則寫成
ActiveSheet.Range(“data”)就足夠了。
第三句話:物件擁有屬性。屬性是一個物件的特性,是描述物件的數值或參數。VBA
可以給一個物件的屬性賦值,也可以讀取屬性的值。屬性的值一般是數位、文本、True 或
False 等等。可以編寫 VBA 代碼來改變 Excel 物件的屬性,進而控制它們。例如:
Application.ScreenUpdating = False
這一行代碼關閉了 Excel 在運行巨集時刷新螢幕的功能。ScreenUpdating 是 Application 物
件的一個屬性,它的值為 True/False。
另一個例子:
Range(“B23”).Name=”month2”
Range(“B23”).Value=4000
這 個 例 子 將 單 格 B23 的 名 稱 設 為 ‘ month2 ’ , 並 將 它 的 值 賦 為 4000 。 語 法 採 用
‘Object.Property’的形式。在這些例子中,‘Application’和‘Range’是對象,而
‘ScreenUpdating’、‘Name’和‘Value’是物件的屬性。下面一個例子讀取一個單格
的數值,並將它賦給變數‘firstval’:
firstval = Range(“B23”).Value
第四句話:物件擁有方法。方法是一組物件可以執行的,或者可以對物件進行操作的預
先定義的行為。下面是調用 Range 物件方法的例子:
Range(“A1:B3”).Select 選中單格區域 A1:B3
Range(“A1:B10”).Copy 拷貝單格區域 A1:B10 中的內容
Range(“storerange”).PasteSpecial 將 剪 貼 板 中 的 內 容 粘 貼 到 單 格
‘storerange’中
語 法 都 採 用 ‘ Object.Method ’ 的 形 式 。 在 上 面 的 例 子 中 , ‘ Range ’ 是 物 件 , 而
‘Select’、‘Copy’和‘PasteSpecial’則是物件的方法。Workbook 物件和 Worksheet
物件也有方法,例如:
Workbooks(“Model.xls”).Activate 將 Model.xls 工作簿啟動
Sheets(“inputs”).Delete 刪除工作表 inputs
上面的解釋可能不太完全,還有一些例外。實際錄製代碼時,你根本不必擔心物件屬性
與方法之間的差別。可以參考 Visual Basic 編輯器中的 Excel 物件流覽器,檢查特定物件的
語法是否正確。

3.3 編寫 VBA 宏

掌握任何一種語言都有一個積累的過程,一方面要學習語言規則,另一方面要不斷地試
驗和測試編碼。VBA 代碼是在 Excel 的編碼環境――Visual Basic 編碼器中編寫的。Excel 97
的編碼功能在 Excel 5/7 的基礎上得到了擴充和增強,為編碼提供了更多的支援。我們先從
檢查一些簡單常式的代碼入手。VBA 的 MsgBox 函數提供了一種簡單的方式來顯示計算結
果和回饋簡單的診斷資訊。我們將演示怎樣用巨集錄製器來生成代碼,並與手寫代碼作比
較。最後概述一下這兩種方法的優缺點。

3.3.1 簡單 VBA 副程式

一個子程式是一段獨立的 VBA 代碼;它是程式的基本組成部分。副程式執行一系列動


作,它由一些 VBA 語句組成,並被 Sub 和 End Sub 語句包圍起來。它的名稱後面有一對
空括弧(除非有另一個副程式給它傳遞參數)。
例如,下面的 LinkOne()副程式將一個單格中的內容連接到另一個單格中。代碼由一個
Sub 單詞開始,然後是宏的名稱,LinkOne。注釋語句說明了這個巨集的目的。(在文本前
加一個單引號,則該語句就會在程式運行時被忽略,這是一個為代碼加注釋的好方法。)第
一條語句使用到 Range 物件的 Value 屬性,第二句則用到 Formula 屬性:
Sub LinkOne()
‘enters a value in B3,then links cell B4 to B3
Range(“B3”).Value = 4000
Range(“B4”).Formula = “=b3”
End Sub
LinkOne 副程式在啟動的工作表中起作用。然而,如果這些操作的物件在工作表中存在
混淆,就應該更準確地引用單格。下面的副程式將 Inputs 工作表中的單格 B3 賦值為 4000。
然後將 B3 中的內容拷貝到同一個工作表的 B4 中:
Sub LinkTwo()
‘enters a value in B3,then links cell B4 to B3 on Inputs sheet
Sheets(“Inputs”).Range(“B3”).Value = 4000
Sheets(“Inputs”).Range(“B4”).Formula = “=b3”
End Sub
如果想在當前的啟動頁中執行此操作,則可以將上面的 Sheets(“Inputs”).用 ActiveSheet.代
替。
接下來的例子演示了 Excel 錄製器根據實際按鍵生成的代碼。將它與副程式 Factorial
的代碼作一下比較。這個子程式計算單格 B5 中數值(引用為 num)的階乘(表示為 fac),
並將結果輸出到 C5 中。它有兩個特點。首先,代碼使用了變數:i、fac 和 num。另外,它
在一個以 i 為指標的 For…Next 迴圈中採用重複相乘的方式來計算階乘。 (計數器的初始值
為 1,然後每迴圈一次,值加 1,直到達到它的上限 num。)
Sub Factorial()
‘Calculates the factorial of a number in B5
num = Range(“B5”).Value
fac = 1
For i=1 To num
Fac = i * fac
Next i
Range(“C5”).Value = fac
End Sub
除了要讀取試算表中的值和返回值給試算表外,這段代碼還使用了 Basic 語句,它基本上與
Excel 無關。這種類型的代碼必須手工輸入。

3.3.2 交互函數 MsgBox

一般來講,副程式的輸入值要麼來自試算表的單格,要麼來自用戶輸入(通過螢幕) ,
而它的輸出值要麼輸出到檔中,要麼直接顯示給用戶。VBA 的內嵌函數提供了兩種有用的
螢幕顯示方法,MsgBox()和 InputBox()。相對簡單的 MsgBox()函數在螢幕上顯示一條資訊,
然後等待用戶的反應。代碼如下:
Sub MsgBoxDemo1()
MsgBox “Click OK to continue”
End Sub
資訊(或‘提示’)必須用雙引號引起來。在這個簡單的 MsgBox 實例中,提示兩邊的括
弧是可選的。然而,當需要從 MsgBox 中得到回應,就必須使用括弧,這時 MsgBox 就象
函數一樣使用。如果有一個變數鏈結到提示上(使用連接符&),則 MsgBox 會變得更加有
用。例如,在 Factorial 副程式中,可以用下面的語句將結果傳遞給用戶:
MsgBox “Factorial is ”& fac
下面的代碼中,用戶用 InputBox 函數來輸入數值。這個 VBA 函數彈出一個對話方塊,顯示
一條資訊,並返回用戶的輸入值,這裏表示為 num。InputBox 語句中的參數是需要顯示的
資訊,也就是‘提示’。這裏的 InputBox 有一對括弧,說明它是作為一個函數被調用的,
它返回用戶的回答,num。階乘的計算仍是採用一個 For…Next 迴圈:
Sub Factorial()
‘calculates the factorial of a number
fac = 1
num = InputBox(“Enter number”)
For i = 1 To num
fac = i * fac
Next i
MsgBox “Factorial is ”& fac
End Sub
我們將利用這個簡單的例子來探討 3.4 節中巨集編程的組成元素。

3.3.3 編寫環境

Visual Basic 編輯器(簡稱 VBE)是副程式編寫、測試和調試的地方。假定 Excel 的


工作簿環境、功能表、命令和工具欄都處在常用的位置。當編寫 VBA 程式時,將 Excel 的
Visual Basic 工具欄調出來放在 Excel 窗口中(如圖 3.1 所示)
,是很有説明的。就像其他工
具欄一樣,這個工具欄中的按鈕可以執行一系列相關功能表命令,如運行巨集、錄製巨集和
調用 VBE(從左數第一、第二和第四個按鈕)等巨集命令工具。

【參照書中第 44 頁的圖 3.1】

圖 3.1 Excel 中的 Visaul Basic 工具欄

VBA 代碼不是寫在(或錄製在)工作表中,而是寫在(或錄製在)模組頁中。在 Excel 97


及以後的版本中,它們會出現在一個不同的視窗――Visual Basic 視窗中,編寫巨集時需要
在 Excel 視窗和 VB 視窗之間切換(使用組合鍵 Alt+Tab 或 Alt+F11)

讀者可以先作下面的練習:先在 Excel 中打開一個新檔,選擇工具 工具功能表下的巨集
工具 巨集選
巨集
項,然後點擊 Visual Basic 編輯器,就可以調出 VB 視窗。(或直接點擊 VB 工具欄中的 VBE
按鈕。)VB 視窗包括工程資源管理器、屬性視窗以及代碼視窗(這個視窗不常出現,除非
工作簿中含有模組) 。代碼視窗是程式編寫和/或按鍵錄製的地方。在 VB 視窗,可以參考 Excel
物件流覽器來檢查特定物件的 VBA 語句是否正確。 (在 VB 視窗中,點擊視圖 視圖功能表來訪問
視圖
物件流覽器,然後選擇左上角文本框中的 Excel。)
VBE 中也有一些調試和編輯工具,可以通過命令條或者專門的工具欄來訪問它們。有
關 Visual Basic 環境更多的細節可以查看本章後面的附錄 3A。
3.3.4 輸入代碼並運行宏

VBA 代碼在一個模組頁中輸入。要增加一個模組頁到工作簿中,可以點擊 VB 視窗插入


插入
功能表中的模組模組選項,這樣就會在代碼視窗中出現一個空白的模組頁。在代碼視窗鍵入下面
模組
的代碼:
Sub MsgBoxDemo()
MsgBox "Click OK to continue"
End Sub
在第一句的尾部,按下 Enter 鍵後,Excel 會自動加上 End Sub 語句。讀者也許已經注
意到了 VBE 的‘快速提示’特性,它可以協助用戶輸入一些可識別的語句。
可以用多種方法來運行副程式:
 在代碼視窗,只要將滑鼠指示器放在副程式代碼體內,然後點擊功能表運行 運行中的運
運行 運
行副程式/用戶表單
行副程式 用戶表單選項
用戶表單 (也可以點擊 VB 視窗功能表下 VB 標準工具欄中的運行 運行按
運行
鈕)。
 在 Excel 視窗,點擊工具 工具功能表下巨集
工具 巨集選項中的巨集
巨集 巨集,然後選擇 MsgBoxDemo 巨
巨集
集並運行它,或直接點擊 VB 工具欄中的運行 運行按鈕。
運行
 用快捷鍵來運行巨集(例如,使用組合鍵 Ctrl+Shift+G),或者為了加深印象,讀
者可以將巨集鏈結到試算表的一個按鈕上。

運行代碼時,如果出現一個運行時錯誤,運行過程就會停止。一個確定 確定對話方塊會說明
確定
錯誤的類型,儘管對於新手來說,這種說明不夠詳細。記住錯誤資訊之後,點擊確定 確定按鈕,
確定
滑鼠指示器就會跳到出現錯誤的語句那裏,並且這條語句會以高亮度的形式顯示(黃色) 。
更正錯誤之後,點擊運行 運行功能表下的重新設置
運行 重新設置(或者點擊工具欄中的黑色方框)來去掉黃色
重新設置
亮條,然後重新運行宏。
為了作進一步的練習,可以輸入下面改進後的 Factorial 副程式。在這個版本中,迴圈
語句被用於計算階乘的 Excel 函數 FACT 代替,注意,要在 VBA 代碼中使用 Excel 函數,
只需在 FACT 函數前加上首碼 Application.(或者 WorksheetFunction.)就可以了。
Sub Factorial()
'calculates the factorial of a number
num = InputBox("Enter integer number ","Calculate Factorial ")
fac = Application.Fact(num)
MsgBox "Factorial is " & fac
End Sub
為了避免記憶體溢出,副程式 Factorial 的輸入整數應小於 25。
這些簡單的宏都是手工輸入的。然而,許多操作代碼可以用 Excel 宏錄製器來生成,因
此下一節我們將介紹這種不同的編寫宏的方法。

3.3.5 錄製按鍵和編輯代碼

錄製器將按鍵轉換成 VBA 代碼,它在解釋單格位址時有兩種模式:絕對引用(缺省模


式)和相對引用模式。在開始的時候,基本上都是採用絕對引用模式,但在本章後面的附錄
3B 中給出了相對引用的使用細節。為了演示,我們用絕對引用模式錄製一個簡單的巨集,
將資料登錄到單格區域 B8:C10 中。
巨集錄製器可以在 Excel 表單中調用,點擊工具 工具功能表下巨集
工具 巨集中的錄製新巨集
巨集 錄製新巨集。給宏取
錄製新巨集
一個名稱,如 Entries,然後點擊確定 確定按鈕。
確定 (也可以點擊 VB 工具欄中的錄製巨集 錄製巨集按鈕。)
錄製巨集
這時會有一個小工具欄出現,裏面有一個停止錄製 停止錄製按鈕(還有一個‘相對引用’按鈕)
停止錄製 。不
要將相對引用
相對引用按鈕按下。
相對引用
在工作簿中,選中單格 B8 並在 B8 中鍵入 JAN;移動到 B9,鍵入 FEB 到 B9;移動到
B10,鍵入 Total 到 B10。然後到 C 列,選中 C8,鍵入 300;選中 C9,鍵入 400;選中 C10,
在單格中鍵入公式‘=SUM(C8:C9)’,並點擊停止錄製 停止錄製按鈕。點擊
停止錄製 VBE 按鈕,在代碼視窗
查看剛才按鍵的錄製代碼。它應該與下面這段代碼相似:
Sub Entries()
'entering data using absolute addresses
Range("B8").Select
ActiveCell.FormulaR1C1 = "JAN"
Range("B9").Select
ActiveCell.FormulaR1C1 = "FEB"
Range("B10").Select
ActiveCell.FormulaR1C1 = "Total"
Range("C8").Select
ActiveCell.FormulaR1C1 = "300"
Range("C9").Select
ActiveCell.FormulaR1C1 = "400"
Range("C10").Select
ActiveCell.FormulaR1C1 = "=SUM(R[-2]C:R[-1]C)"
Range("C11").Select
End Sub
當一個單格被‘選中’,它就變成了 ActiveCell(Application 物件的一個屬性,返回一個區
域)
。Entries 副程式用 ActiveCell.FormulaR1C1 屬性將輸入值輸入到 B8 至 C10 中。現在,
切換到 Excel 表單,點擊運行巨集 運行巨集按鈕(或者在代碼視窗,執行功能表操作運行
運行巨集 運行下的運行副
運行 運行副
程式/用戶表單
程式 用戶表單)運行巨集時,可以發現巨集的執行結果與前面的相同,也就是說,它也是
用戶表單
將資料填寫到區域 B8 至 C10 中。
作為一個 VBA 新手,最好的方法是先用宏錄製器錄製代碼,然後編輯改進代碼,使之
變得更加簡潔,然後對代碼進行歸納總結。錄製、編輯並測試代碼是一種很好的練習方法。
錄製代碼的運行結果與錄製時執行的一系列功能表操作的結果完全一致,如生成資料圖表、
進行資料排序、定制樞軸表(pivot tables)等。錄製器能夠為一些複雜的指令生成簡潔的
代碼。但是,如果錄製的操作中包含大量的滑鼠移動,則錄製器會生成相當冗長的代碼。在
這個時候就需要手工編寫代碼,或者先錄製,然後編輯。
為了演示,我們回過頭來看一看生成的 Entries 宏代碼。錄製的代碼中包含了許多‘選
中’單格的操作,但在編寫代碼時,這些操作是沒有必要的,可以直接將數值賦給指定的單
格。下面的代碼經過編輯,可以執行同樣的操作,但代碼就顯得簡潔多了:
Sub Entries1()
'entering data using absolute addresses
Range("B8").Formula= "JAN"
Range("B9").Formula = "FEB"
Range("B10").Formula = "Total"
Range("C8").Formula = "300"
Range("C9").Formula = "400"
Range("C10").Formula = "=SUM(C8:C9)"
End Sub
實際上對於單個單格區域物件,指定 Formula 屬性是不必要的,所以代碼可以簡單地寫為:
Sub Entries1()
'entering data using absolute addresses
Range("B8") = "JAN"
Range("B9") = "FEB"
Range("B10") = "Total"
Range("C8") = "300"
Range("C9") = "400"
Range("C10") = "=SUM(C8:C9)"
End Sub
整理代碼的一個可行方法是將冗餘的語句變為注釋(在前面加上一個單引號) ,然後運行宏
看看效果。
在編寫代碼時,經常需要顯示一些運行過程中產生的資訊,特別是計算的中間結果等。
此時,VBA 函數 MsgBox 就非常有用了。在編碼階段,增加一些簡單的注釋,用來描述宏
的行為,以及任何特性或要求等等,是很有用的。更重要的是,應該給出代碼可能的應用範
圍。
作為參考,本節討論的所有巨集都放在 ModuleA 模組中,可以在 VBSUB 工作簿的
IntroEX 表中運行它們。
分析前面提到的 Factorial 副程式可以得出,那些使用變數並採用 For…Next 迴圈語句
的代碼是不能通過錄製按鍵生成的,必須手工輸入。因此,接下來的章節將討論這一類更加
常規的編程方法。

3.4 編程要素

金融建模時,要編寫的許多代碼都是對數值計算進行控制。這包括對它賦值,採用適當
的結構來控制過程流,以及報告結果等。這些任務對所有的編程語言來說,都是最普通的。
VBA 程式的唯一不同之處就在於,它經常需要從試算表模型開始,其任務是由功能表操作
執行,而且關鍵的計算放在單格公式中,許多公式還包含 Excel 函數。幸運的是,將 Excel
函數嵌入到 VBA 代碼中是很容易的事。VBA 程式不是用來代替試算表模型的,而是用來擴
展和增強它們的功能的。我們先來簡要回顧一下關於變數的應用(特別是陣列變數) 、控制
過程流的結構,以及 VBA 中 Excel 函數的應用等相關內容。

3.4.1 變數和資料類型

編程時,變數是用來存儲和運算元據的。按照慣例,資料具有不同的形式或者說‘類
型’,而這會影響到它們在記憶體中的存儲空間。在大部分的數值計算中,主要有四種類型
的資料:小數型(傳統的十進位小數,也叫標量)、整型、邏輯型(True 或 False)和日期
型。而字元型變數存儲的是文本資訊。VBA 有一個非常有用的資料類型,variant,它可以
代表任何資料類型。它是缺省的資料類型,當我們不知道一個變數的類型時它是很有用的。
但是,variant 類型會佔用額外的記憶體空間,這在處理大量數值計算時會影響運行的速度。
還有一個‘物件’型資料類型,它可以引用一個物件,如一個區域或者工作表等。更詳細的
內容見 Green(1999)。
從 VBA 編程新手的角度來看,明確地聲明所有需要用到的變數是很重要的,這可以減
少代碼中錯誤的出現。你可以在每個模組頁的開頭寫上‘Option Explicit’語句來強制實行
這一點。(VBE 可以自動地增加該語句,在 VB 視窗點擊 工具 功能表下的選項 選項,然後選中
選項
要求變數聲明的選項。)這樣,在運行時,如果編輯器遇到一個未聲明的變數,就會返回一
要求變數聲明
個錯誤資訊。這在檢測代碼中是否有錯誤拼寫的變數名時顯得特別有用。金融建模時,聲明
變數的類型(作為整型、字串型還是邏輯型等)並不重要。但它可以用來在程式中說明變數
的用途。
變數聲明使用 Dim 關鍵字,如下面 Factorial 副程式中的第三行所示。這裏,聲明了兩
個變數,但沒有給出資料類型(如整型) 。缺省情況下,它們是 variant 類型:
Sub Factorial()
'calculates the factorial of a number
Dim fac,num
num = InputBox("Enter number ","Calculate Factorial ")
fac = Application.Fact(num)
MsgBox "Factorial is " & fac
End Sub
(順便提一句,注意這裏的 InputBox()函數,它返回用戶的輸入資訊,在這裏它有兩個參數,
第一個參數是提示資訊‘Enter number ’,而第二個參數(可選)則是對話方塊的標題。)
總體來講,副程式中用到的所有變數都應該用 Dim 關鍵字作顯式聲明。模組頁前的
‘Option Explicit’語句保證所有的變數必須預先聲明,否則,副程式就不能正確運行。

3.4.2 VBA 陣列變數

有時變數可以按名稱分組組成陣列(向量或者矩陣) 。例如,一個資料集累積分佈的所
有四分位元數可以用一個陣列變數 qvec()表示。陣列中的元素可以用下面的方式引用:
qvec(0),qvec(1)等。利用前面一章討論的對數收益資料,如圖 3.2 顯示,單格 H21:H25
中存放的是用 Excel 的 QUARTILE 函數計算出來的四分位數,第一個和最後一個分位元數
分別是資料集的最小和最大值,低於-0.043 的資料占整個資料集的 25%。因此陣列 qvec()
從單格區域 H21:H25 中得到資料,qvec(0)的值為-0.153,qvec(1)的值為-0.043,如此類推。

Quartiles:四分位數值;Cumulative Frequency from quartiles:四分位元點的累積頻率;

【參照書中第 49 頁的圖 3.2】

圖 3.2 VBSUB 工作簿 Data 表中的對數收益四分位數

擴展一下,陣列變數可以是多維的,例如,兩維的陣列變數 PQmat()代表包含一列四分
位數和一列分佈左百分位數的 5×2 陣列。例如,變數 PQmat()可以從 5×2 的單格區域 H21:I25
中得到資料,如圖 3.2 所示。儘管對陣列變數的命令沒有什麼規定,但選擇可以區分一維陣
列(向量)和二維陣列(矩陣)的名稱還是有幫助的。因此我們分別使用 qvec 和 PQmat
作為陣列變數名稱。
和其他變數一樣,陣列變數應該在使用之前先聲明。缺省情況下,VBA 從 0 開始對陣
列變數編號。因此如果聲明語句為:
Dim qvec(4)
則陣列 qvec()包含 5 個元素。擴展一下,如果兩維陣列 PQmat()的聲明為:
Dim PQmat(1,4)
則它包含 10 個元素。
如果希望 VBA 將 1 作為最小編號,必須在模組頁的開頭聲明‘Option Base 1’。有了這
個聲明後,陣列變數 qvec(4)就只有 4 個元素:qvec(1), qvec(2) ,qvec(3) 和 qvec(4)。
實際上,在本書的大部分 VBA 程式中,陣列的基數都設為 1。
‘Option Base’設置的作用可以從下面的 ArrayBase 宏中看出。當給模組頂部的
‘Option Base’賦不同的值時,產生的結果也不同。既然 VBA 陣列函數 Array()是用來輸
入真實陣列的,就沒有必要為陣列變數 avec 指定維數:
Sub ArrayBase()
‘gives b=20 if Option Base is 1;gives b=30 in absence of Option Base statement
Dim avec,b
avec = Array(10,20,30)
b = avec(2)
MsgBox “b is ”& b
End Sub
通常,開始時並不知道陣列元素的個數,要根據巨集的操作結果而定。這種所謂的‘動
態陣列’事先沒有設定元素個數。它用一對空括弧聲明,如 Dim qvec()或者 Dim PQmat()。
但是在使用任何無維數陣列之前,必須先用 ReDim 語句告訴 VBA 這個陣列有多少元素。
在下面的例子中,名為‘dvec’的區域包含了需要存儲到陣列變數 cvec 中的結果。在聲明
cvec 為陣列變數之後,它的維數就由 dvec 區域的元素個數決定,在 cvec 被使用之前需要
使用 ReDim 語句:
Sub SelectCount()
're-Dim data array cvec
Dim n, cvec()
Sheets("Data").Range("dvec").Select
n = Selection.Count
ReDim cvec(n)
End Sub
操作 VBA 中的陣列要比使用 Excel 的陣列公式(如 SUM、SUMPRODUCT 以及矩陣
函數)複雜的多。有些時候,陣列操作可以完全由 Excel 函數來完成。注意,如果代碼中不
需要訪問陣列中的單個元素,陣列就可以直接用變數名引用,如 qvec,而不用加上它的維
數。但是,陣列處理經常包括對其中元素的操作,對元素進行操作的最好方法是在一個迴圈
語句中應用陣列。在這種情況下,元素用 qvec(i)來標識,且一般需要使用 Dim qvec()和
ReDim 語句。要想避免出錯,需要非常小心地編碼。由 Excel 構建的 VBA 陣列在編號上有
些模糊,特別是在處理行向量和列向量時。為了避免混淆,在將一個陣列作為過程的輸入時,
Excel 一般對陣列元素從 1 開始編號。
3.4.3 控制結構

和其他編程語言一樣,VBA 也提供了一些控制流程的結構。這些包括條件語句,如
If…Then…Else,它先判斷條件是否滿足,然後根據判斷的結果改變執行的流程;還有 Select
Case,它從多個條件(Case)中選擇一個分支。迴圈結構允許重複運行一段執行語句。有
些迴圈重複執行特定的次數,如帶有計數器的 For…Next 迴圈,前面,我們在計算階乘時
用到過它。其他的語句,如 Do While…Loop,重複執行語句直到條件為 True(或直到條件
為 False)。本節先看一個關於 If…Then 的簡單例子,更多的關於 For…Next 迴圈語句和
Do While…Loop 語句的例子會在接下來的章節出現。很多教科書(如 Green,1999;
Walkenbach,1999;Wells 和 Harshbarger,1997)中對這些控制語句都作了更為詳細的
解釋,並給出了一些其他的例子。
在 Factorial 副程式中我們已經提到,VBA 的交互函數 InputBox 可以返回用戶的輸入資
訊。為了使程式更強大,我們應該將用戶輸入的一些錯誤進行輸入過濾掉更正。一種方法是
檢查輸入是否是數值型,如果不是就丟棄它。下面的代碼演示了兩個 If…Then 結構語句的
使用。一個是單行的 If…Then 語句,它沒有額外的代碼行。這條語句檢查 numtype 變數(VBA
函數 IsNumeric 的結果變數)是否為真,如果為真,就計算階乘。它的檢測語句和執行語句
在同一行中。第二個條件語句採用塊 If…Then 形式。如果用戶的輸入不是數值型,則用戶
會被警告,並且不進行階乘計算。當條件語句結束後,有一個 End If 語句:
Sub Factorial()
'calculates the factorial of a number
' filters out non numeric input
Dim fact, num
num = InputBox("Enter number ", "Calculate Factorial ")
numtype = IsNumeric(num) ‘True 或者 False
If numtype = ture then fac = Application.Fact(num) ‘單行的 If…Then
If numtype = False Then ‘塊 If…Then End If
MsgBox "Not a number. Try again" 'don't proceed
End If
End Sub
我們將在第四章的用戶定義函數中多次用到 If…Then…Else 語句。

3.4.4 控制重複過程

前面(見 3.3.1)的 Factorial 副程式演示了一個簡單的重複操作,For…Next 迴圈。下


面是一個不同的例子,Quartiles 副程式。它計算一個資料集(來自 VBSUB 工作簿 Data 表
中的區域 dvec)的四分位數,並在一系列的對話方塊中將結果一一顯示給用戶。
Option Base 0

Sub Quartiles()
'displays quartiles of range named 'dvec'
Dim i As Integer
Dim qvec 'to hold quartile
Dim dvec As Variant 'col vec of data
'fill array variable from spreadsheet range
dvec = Worksheets("Data").Range("dvec")

'calculate quartile one at a time & display


For i = 0 To 4
qvec = Application.Quartile(dvec, i)
MsgBox "Quartile no. " & i & " has value " & qvec
Next i
End Sub

查看一下 VBSUB 工作簿中的區域名稱,通過點擊 插入 功能表下名稱 名稱中的定義


名稱 定義選項,
定義
我們可以看到,名稱 dvec 是與 Data 表中 E 列的 LnReturns 資料區區域綁定的。在 Quartiles
副程式的代碼中,我們也使用 dvec 作為資料集陣列的變數名。為了表明 dvec 是一個向量
而不是標量,我們將它聲明為 Variant 型。檢查代碼,我們發現,在用工作表單格的資料填
充完陣列 dvec 之後,每個四分位數都被計算出來,並且用 For…Next 迴圈將其一個個地顯
示給了用戶。注意,在 VBA 代碼中使用 Excel 函數 QUARTILE 時,需要在前面加上
Application.或者是 WorksheetFunction.,我們將在下一節解釋其中的原因。
MsgBox 的提示資訊中含有 For…Next 的計數值以及當前的四分位數,這種辦法可行
的,但並不是處理輸出的最好方法。
另一種可進行重複操作的語句是 Do While…Loop。它會重複執行操作,直到條件滿足。
DelDuplicates 副 程 式 是 用 來 查 找 並 刪 除 一 個 資 料 表 中 的 重 複 行 , 它 用 於 演 示 Do
While…Loop 語句的使用方法。將資料資訊存儲到一個特定的‘code’區域之後,程式會
對 code 列中的資料一行行地作處理。如果 currentCell 中的數值與 nextCell 中的相同,則
刪除 currentCell 行。這裏 currentCell 和 nextCell 都是物件變數,因為它們代表的是物件(這
裏是 Range 物件)。由於它們是物件變數,因此它們必須用關鍵字 Set 來賦值。
Sub DelDuplicates()
Dim currentCell,nextCell
Range(“database”).Sort key1:=Range(“code”)
Set currentCell = Range(“code”)
Do While Not IsEmpty(currentCell)
Set nextCell = currentCell.Offset(1,0)
If nextCell.Value = currentCell.Value Then
currentCell.EntireRow.Delete
End If
Set currentCell = nextCell
Loop
End Sub

這個子程式還展示了 VBA 線上幫助的一些優勢。線上幫助


線上幫助 線上幫助可以在
線上幫助 VBE 中訪問,點擊幫幫
助功能表中的幫助索引
幫助索引即可。在幫助索
幫助索引 幫助索引
幫助索 引的 Delete 方法那一段中就含有上面的這段代碼,
並對它進行了詳細的解釋。不幸的是,並不是所有的幫助資訊都這樣詳細,但不管怎樣,線
上幫助中有許多有用的關於語句方面的資訊。這幾節中的內容只涉及到一些最常用的控制結
構語句。有關 VBA 編程技術還可以參看 Green(1999) ,Walkenbach(1999)以及 Wells
與 Harshbarger(1997)編著的教科書。

3.4.5 在代碼中使用 Excel 和 VBA 函數

從 Quartiles 副程式的代碼中我們知道,如果想在 VBA 程式中調用一個 Excel 函數,需


要 在 函 數 名 的 前 面 加 上 Application. 。 在 Excel2000 中 , 函 數 名 的 首 碼 可 以 是
WorksheetFunction 或者 Application。為了與 Excel 以前的版本相容,我們繼續使用
Application 首碼。相比而言,調用 VBA 函數就不需要任何首碼,如我們已經看到的 MsgBox、
IsNumeric、InputBox 等函數。實際上,VBA 中也有少量數值函數,目前只有 Abs, Cos, Exp,
Int,Log,Rnd,Sgn,Sin,Sqr 和 Tan,其中 Log 是自然對數函數(通常表示為 Ln) 。因
此,相同功能的 VBA 函數名的拼寫與 Excel 函數名的拼寫是不同的(例如,VBA 中的平方
根函數是 Sqr,而在 Excel 中是 SQRT) 。為了解決這種矛盾,我們規定,如果 VBA 和 Excel
函數能完成相同的計算時,必須使用 VBA 函數而不用 Excel 函數。 (例如,計算一些數值的
自然對數時,調用 Log 而不是 Applicaion.Ln;同樣地,調用 Sqr 而不是 Application.Sqrt。)

3.4.6 編程的一般觀點

結束這一節之前,我們對編程過程提出一些建議。採用結構化編程的目的是使程式按
一個有序的方式運行,這樣編碼就很容易進行,更重要的是,很容易修改。
先在紙上設計出整個應用程式的主要階段,並將整個任務分成幾個不同的子任務。然
後把每個子任務再分成一系列副程式,並對它們分別進行編碼和測試。如果可能,副程式應
保持合適的大小。結構化編程的一個原則是,代碼段應該只有一個入口和一個出口。程式控
制不能在代碼段的中間跳入或跳出。如果堅持這個原則,將各個分開的代碼段連接起來就會
很簡單。
程式經常需要更新和修改。如果在第一次編程時加上注釋,那麼搞清程式的邏輯就會容
易的多。只要可能,數值計算中的重要常量都應該用參數來表示(顯式聲明),這樣,當程
式用於不同的環境時,它們就很容易修改了。如果編寫的代碼能夠通用,這些額外的工作是
值得的。

3.5 宏與試算表之間的通信

介紹完編程中變數和控制結構的使用之後,本節討論一下 VBA 宏怎樣從試算表中獲得


輸入資訊,並將結果輸出到試算表中去。其重點在於宏與試算表之間的通信。
在許多案例中,一個子程式可分為三個部分:資料登錄,計算(或者操作輸入),然後
輸出結果。寫一個用於計算的 VBA 代碼通常涉及到傳統的編程技術。VBA 編程的新觀點是
與試算表之間的互動。可將這三個部分分開考慮:
 輸入值可以從試算表的單格中讀取得到,或用戶通過對話方塊直接輸入,輸入值存
儲在變數中。
 輸出值可以寫入單格,或者用對話方塊顯示給用戶。
 計算可以用代碼來完成(‘離線(offline)’)
,也可以使用單格中已存在的,或是
用 VBA 副程式寫入單格中的公式。

接下來的三個大家已經很熟悉的 Factorial 例子演示了輸入、計算和輸出的各種不同組


合。副程式 Factorial1 從用戶那裏得到輸入,計算時使用了 Excel 函數 FACT,並且用 MsgBox
函數來返回結果。整個副程式不與電子錶交互:
Sub Factorial1()
Dim fac, num
num = InputBox("Enter number ", "Calculate Factorial ")
fac = Application.fact(num)
MsgBox "Factorial is " & fac
End Sub

作為對比,Factorial2 從試算表的單格(B5)中得到輸入資訊,然後將計算出的階乘返
回給另一個單格(C5) :
Sub Factorial2()
'gets number from spreadsheet, uses Excel fact function, returns answer to
spreadsheet
Dim fac, num
num = Sheet1.Range("B5").Value
fac = Application.fact(num)
Sheet1.Range("C5").Value = fac
End Sub

而在副程式 Factorial3 中則作了進一步的修改,將用戶的輸入值寫入一個單格(B6)



然後將階乘公式寫入相鄰的另一個單格:
Sheet1.Range("C6").Formula = "=fact(b6)"
並將結果顯示給用戶。
Sub Factorial3()
'gets number from InputBox, calculates factorial in spreadsheet
' returns answer via MsgBox
Dim fac, num
num = InputBox("Enter number ", "Calculate Factorial ")
Range("B6").Value = num
Range("C6").Formula = "=fact(b6)"
fac = Range("c6").Value
MsgBox "Factorial is " & fac
End Sub
為了鞏固所學的知識,讀者可以根據自己的要求進一步改寫這些輸入——輸出副程式。
作為參考,VBSUB 工作簿的 ModuleF 模組中包含了所有這些階乘副程式的代碼,並且在
IntroEx 表中運行良好。改寫或者編寫副程式前,應該先看看附錄 3A 中關於 Visual Basic
編輯器的內容,特別是巨集編程步驟和調試部分。
當不需要進行單格對單格(cell-by-cell)的計算時,讀取試算表區域中的數值並將結果
寫入其他單格或區域的過程都是很簡單的。假設輸入資料在試算表區域 avec 中,要將這些
單格中的資料拷貝到另一個區域中,這個區域左上方的單格名稱為 aoutput。錄製器生成的
代碼在副程式 ReadWrite1 中,我們對它進行修改,就變成了 ReadWrite2 中的樣子:
Sub AReadWrite1() ' Macro recorded
Application.Goto Reference:="Avec"
Selection.Copy
Application.Goto Reference:="Aoutput"
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
Application.CutCopyMode = False
End Sub

Sub AReadWrite2() ' edited version


‘reads data,writes values to another range
Range("Avec").Copy
Range("Aoutput").PasteSpecial Paste:=xlValues
Application.CutCopyMode = False ‘cancels Copy mode
End Sub

如果計算過程需要對區域 avec 中的單個單格進行操作,代碼就會變得有些複雜。這些


計算可能需要在一個循環體中進行,並且計算結果需要一個一個地拷貝到輸出區域中。我們
先計算區域 avec 的單格個數,這樣就可以知道需要從 avec 中讀取多少個單格數值,也知
道需要拷貝多少個數值給輸出區域。假設我們要計算 avec 區域中各個單格資料的連乘。在
計算中,需要用到兩個變數 x 和 y,x 是 avec 的當前元素值,而 y 是當前的連乘值。假設
輸入區域 avec 的頂部單格命名為‘atop’,而輸出區域的頂部單格命名為‘aoutput’。下
面的副程式先一個一個地讀出單格資料,然後計算乘積,最後輸出當前的乘積:
Sub AReadWrite3()
'reads data from range avec, calculates
'running product & writes results to range below aoutput
Dim i As Integer, niter As Integer
Dim x, y
y=1
niter = Range("avec").Count

For i = 1 To niter
x = Range("atop").Offset(i - 1, 0)
y = y * x 'calculation routine
Range("aoutput").Offset(i - 1, 0) = y
Next i
End Sub
Offset(i,j)是一個非常有用的物件方法,它返回參考單格(這裏是 Range(“stop”))向下 i
行,向右 j 列的單格數據。例如,Range("atop").Offset(1, 0)代表的是單格 atop 正下方的單
格,等等。x 的第一個賦值是 Range("atop").Offset(0, 0),也就是 Range("atop")中的值。
作為巨集與電子錶之間通信的最後一個例子,我們來看看 Quartiles 副程式,改進它的
代碼使得它以陣列的形式返回五個四分位數給試算表。這個新的副程式 Quartiles1,先讀取
陣列 qvec()中的五個四分位數,然後將它們輸出到前面已命名的區域 qvec1 中。 (區域名稱
qvec1 與試算表中的區域 K20:K24 綁定,可以通過點擊插入 插入功能表下名稱
插入 名稱中的定義
名稱 定義選項來
定義
檢查。)
下面的代碼中,陣列變數 qvec(4)可以存儲五個數值。輸入和輸出陣列變數:dvec(資
料集)和 qvec(結果陣列) ,都被聲明為 Variants 類型,這暗示著它們不是簡單的標量。由
於不需要訪問 dvec 和 qvec1 中的單個元素,因此聲明它們時不用帶括弧()。在用試算表區
域 dvec 的資料填充完陣列變數 dvec 之後,陣列變數 qvec 中的每個元素會在一個 For…Next
迴圈中一一賦值。缺省情況下,VBA 以行的形式在試算表中建立陣列,因此需要使用 Excel
函數 Transpose 來將輸出陣列轉換成列向量:
Option Base 0
Sub Quartiles1()
'pastes 4 by 1 col vector of quartiles into range named 'qvec1'
'requires 2 named ranges in spreadsheet, dvec with data & qvec1 for results
Dim i As Integer
Dim qvec(4) 'quartiles array
Dim dvec As Variant 'col vec of data
Dim qvec1 As Variant 'results array
'fill array variable from spreadsheet range
dvec = Worksheets("Data").Range("dvec")
'calculate quartiles & assemble as col vector
For i = 0 To 4
qvec(i) = Application.Quartile(dvec, i)
Next i
qvec1 = Application.Transpose(qvec)
' transfer results into spreadsheet range qvec1
Worksheets("Data").Range("qvec1") = qvec1
End Sub

注意,在循環體中,只有一條語句執行。這裏要說明一點,在循環體內不要放任何不必
要的語句。循環體中任何與迴圈操作無關的語句都應該放在循環體外。
讀者可以用自己的資料和公式來改寫一下上面的這些代碼,從而鞏固所學的知識。作為
參考,VBSUB 工作表在 ModuleI 和 ModuleQ 模組中分別提供了 ReadWrite 和 Quartiles
副程式的代碼。
本節對編寫 VBA 副程式做了一個簡單的介紹。要想加強這方面的知識,可以參看
Green(1999)教科書的第 2 章,它是一本很好的 VBA 初級讀本。下一節將介紹三個更深入
一層的 VBA 應用實例,代碼和解釋都會更長。它們代表了巨集的一些實際應用,並且演示
了 VBA 編程的一些深層思想。

3.6 副程式實例

在本節中,我們進一步改寫了一些副程式,一來可以演示改進代碼的過程,二來可以展
示宏的一些應用領域。在編寫這些例子時,我們將錄製器和代碼編輯混合起來使用。這些副
程式包括:生成特殊類型的圖表,累積分佈和正態分佈作圖,求解的重複優化。
3.6.1 圖表

首先,我們改寫一個子程式,用來對一些資料(如圖 3.3 中列出的累積頻率資料)作圖。


假設頻率資料放在一個工作簿的 Data 表中,資料區域命名為‘chartdata’,我們的目
的是生成一個基於累積百分比頻率分佈的 XY 散點圖。圖表在 Data 表中作為一個物件來處
理。

Frequency Distribution:頻率分佈;Cumulative Frequency:累積頻率

【參照書中第 57 頁的圖 3.3】

圖 3.3 VBSUB 工作簿 Data 表中的頻率分佈以及圖表

對於一個 VBA 新手來說,他們並不知道操作圖表所需的代碼,因此最好是先用錄製器


來生成代碼。打開 VBA 錄製器,然後錄製對區域‘chartdata’繪圖的按鍵。在任何可能的
情況下,都應該用區域名稱來表示單格區域。錄製的名為 ChartNew()的宏代碼如下:
Sub ChartNew()
Charts.add
ActiveChart.ChartType = xlXYScatterSmoothNoMarkers ‘WizStep1
ActiveChart.SetSourceData Source:=Sheets("Data").Range("chartdata"),
PlotBy:= _
xlColumns ‘WizStep2
ActiveChart.Location Where:= xlLocationAsObject,Name:=”Data” ‘WizStep4
With ActiveChart ‘WizStep3
.HasTitle = True ‘Titles
.ChartTitle.Characters.Text = "Cumulative Distribution"
.Axes(xlCategory, xlPrimary).HasTitle = False
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "P(X>x)"
End With
With ActiveChart.Axes(xlCategory) ‘Gridlines
.HasMajorGridlines = False
.HasMinorGridlines = False
End With
With ActiveChart.Axes(xlValue)
.HasMajorGridlines = False
.HasMinorGridlines = False
End With
ActiveChart.HasLegend = False ‘Legend
End Sub
(右邊的注釋是為了解釋這段有點長的代碼。WizStep1 是 Chart Wizard Step 1 的簡
稱,如此類推。)
代 碼 中 Charts 集 合 增 加 了 一 個 新 的 圖 表 【 Charts.Add 】 , 這 個 圖 表 的 類 型 為
XYScatterSmoothNoMarkers 【 ActiveChart.ChartType 】, 作 為 資 料 源 的 單 格 區 域 為
‘chartdata’【ActiveChart.SetSourceData】。這段代碼是由圖表嚮導的前兩個步驟生成
的。在步驟一中,圖表類型被選中,而在步驟二中,定義了作為資料源的資料區域,並指定
了 它 的 結 構 ( 行 或 列 )。【 物 件 ActiveChart 的 SetSourceData 方 法 使 用 語 法 :
SetSourceData(Source,PlotBy)。】注意,由於 ActiveChart.SetSourceData 語句過長,有
一部分放在下一行,這時需要在這個代碼行的後面跟一個空白字元和一個下劃線(_) 。
代碼行:ActiveChart.Location Where:=xlLocationAsObject,Name:=”Data”由圖表嚮導
的第四步產生,它確保新的圖表將嵌入 Data 表內。(如果要將圖表放在一個分開的圖表頁
中,可以將代碼改為:ActiveChart.Location Where:=xlLocationAsNewSheet。)下面的大
部分代碼由圖表嚮導的第三步產生,它設定圖表選項。注意這一條語句:
‘With…End With’
當對一個物件作某些改變時,Excel 錄製器經常使用這條語句,在這裏是 ActiveChart 物件。
因此,下面的代碼:
With ActiveChart
.HasTitle = True
.ChartTitle.Characters.Text = "Cumulative Distribution"
.Axes(xlCategory, xlPrimary).HasTitle = False
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "P(X>x)"
End With
定義了圖表的標題,而接下來的代碼段則分別定義了圖表的網格、坐標軸和圖例。
錄製器生成的許多代碼沒有改變缺省值,因此這部分代碼可以刪除,從而使宏看起來更
加簡潔。第一步是注釋掉可能的冗餘語句(在語句的前面加一個單引號),然後檢查一下代
碼是否仍然象你希望的那樣運行。例如,下面的這段代碼中,在去掉注釋行後 ChartNew1
副程式仍能很好地運行:
Sub ChartNew1()
Charts.add
ActiveChart.ChartType = xlXYScatterSmoothNoMarkers
ActiveChart.SetSourceData Source:=Sheets("Data").Range("chartdata"),
PlotBy:= _
xlColumns
ActiveChart.Location Where:= xlLocationAsObject,Name:=”Data”
With ActiveChart
.HasTitle = True
.ChartTitle.Characters.Text = "Cumulative Distribution"
.Axes(xlCategory, xlPrimary).HasTitle = False
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "P(X>x)"
End With
‘With ActiveChart.Axes(xlCategory)
‘ .HasMajorGridlines = False
‘ .HasMinorGridlines = False
‘End With
With ActiveChart.Axes(xlValue)
.HasMajorGridlines = False
.HasMinorGridlines = False
End With
ActiveChart.HasLegend = False
End Sub
因此,這段代碼可以精簡為:
Sub ChartNew2()
' Same as ChartNew Macro after removing redundant lines
Charts.add
ActiveChart.ChartType = xlXYScatterSmoothNoMarkers
ActiveChart.SetSourceData Source:=Sheets("Data").Range("chartdata"), PlotBy:= _
xlColumns
ActiveChart.Location Where:=xlLocationAsObject, Name:="Data"
With ActiveChart
.HasTitle = True
.ChartTitle.Characters.Text = "Cumulative Frequency"
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Freq(X>x)"
End With
With ActiveChart.Axes(xlValue)
.HasMajorGridlines = False
End With
ActiveChart.HasLegend = False
ActiveChart.PlotArea.Select
Selection.Interior.ColorIndex = xlAutomatic
ActiveChart.Axes(xlValue).Select
With ActiveChart.Axes(xlValue)
.MaximumScale = 1
End With
End Sub

代碼 ActiveChart.PlotArea.Select 及其之後的代碼是後加的。這段代碼設置坐標軸 y 的
最大值為 1(或 100%),並且將繪圖區的缺省背景填充色灰色去掉。
前面提到的這些宏在工作簿的 ModuleC 模組中定義,並能在 Data 表中運行。

3.6.2 正態概率散點圖

正態概率散點圖是一種有用的資料視覺化工具。繪出的圖形可以表明觀測變數是否可以
假設服從正態分佈。假設有 50 個觀測值。我們先計算出服從正態分佈的 50 個順序值(叫
做 norm-scores)
,並用它們對照 50 個觀測值的標準化值(叫做 z-scores)繪圖。如果觀測
值是服從正態分佈的,則兩組值繪出的點大致在一條直線上。圖 3.4 中繪出的散點表明,觀
測值與正態分佈有一點偏差,特別是在分佈的尾部。
現在,Excel 的統計庫中已經步包括這種有用的繪圖工具了。
(資料分析工具庫回歸選
項中的正態概率分佈圖並不是傳統意義上的正態概率散點圖,它只是應變數的累積分佈圖。)

Normal Probability Plot:正態概率散點圖;


Norm-score:正態值;z-score:z-值;

【參照書中第 60 頁的圖 3.4】

圖 3.4 對數收益數據的正態分佈散點圖

假設觀測值放在 Data 表的名為 dvec 的區域中。在 VBA 代碼中,陣列變數 dvec 用於


存儲單格區域 dvec 中的資料。由於我們需要對陣列元素 dvec(i)進行處理,因此需將 dvec
聲明為 Variant 型(它是一個真正的物件變數,確切地說是一個 Range 物件變數)。第二個
變數,Znvec,用於存儲向量 z_scores 和 norm-scores,其中的一列存儲 dvec 中的值。這
些變數在副程式 NPPlotData 的開頭部分聲明。
既然變數 dvec 的值來自於單格區域,因此它需要用關鍵字 Set 來賦值,因此:
Set dvec = Sheets("Data").Range("dvec")
一旦 dvec 被賦值,dvec 中的觀測值個數就可以計算出來,那麼前面定義的陣列維數就可以
確定了。因此有下面這條語句:
ReDim Znmat(n, 2)
對資料集中的每一個觀測點,它的 z-score 和 norm-score 在一個 For…Next 迴圈中計
算出來。計算 z-score 時要用到 Excel 的 AVERAGE 函數和 STDEV 函數,而計算 norm-score
時則要用到 Excel 的 RANK 函數和標準正態分佈的逆函數(NORMSINV)。計算出來的值
放在一個 n×2 的矩陣 Znvec 中,然後按順序輸出到試算表的單格區域 Znvec 中。一旦數值
計算完畢,就可以用它們繪出一個 XY 散點圖。
下面是計算並繪製散點圖的全部代碼。代碼的倒數第二條語句是調用副程式
ChartNormPlot,這個子程式與 3.6.1 節中的圖表副程式有些相似。你可以在 VBSUB 工作
簿的 Data 表中運行 NPPlot 宏。

Option Explicit
Option Base 1

Sub NPPlotData()
' returns n by 2 matrix where n = no. of elements in dvec
' 1st col z-scores, 2nd col normscores for n obs.
Dim M, V, r, c
Dim i As Integer, n As Integer
Dim Znmat() As Variant
Dim dvec As Range

'data input from worksheet


Set dvec = Sheets("Data").Range("dvec") 'dvec as Range object
n = Application.Count(dvec)
ReDim Znmat(n, 2)

M = Application.Average(dvec)
V = Application.Var(dvec)
For i = 1 To n
Znmat(i, 1) = (dvec(i) - M) / Sqr(V)
r = Application.Rank(dvec(i), dvec, 1)
c = (r - 3 / 8) / (n + 1 / 4)
Znmat(i, 2) = Application.NormSInv(c)
Next i

'output results to range Znmat


Sheets("Data").Range("Znmat") = Znmat
With Sheets("Data").Range("Znmat")
.NumberFormat = "0.00"
.Name = "npdata"
End With
ChartNormPlot
End Sub

副程式 NPPlot 和 ChartNormPlot(在 NPPlot 中被調用)的代碼放在工作簿的 ModuleN 模


組頁中。

3.6.3 用規劃求解產生有效邊界

這個應用程式要求先對投資組合理論以及 Excel 插件規劃求解有一定的瞭解。讀者可以


等到學完第六章之後再來看這些內容。
在包含多個風險資產的投資組合中,我們需要求出有效組合的資產權重,也就是求出能
使得指定收益下風險最小的資產權重。可以直接用規劃求解來求解特定收益的最優權重問
題。如果對不同的收益反復求解這個最優化問題,就可以得到有效組合的風險——收益前沿
邊界,也就是所謂的有效邊界。
例如,圖 3.5 中給出了組合的三種資產權重分別為 40%、50%、10%時,組合的期望
收益為 2.2%。而目標收益是 7%,因此所求得的有效組合權重必須使得組合的收益為 7%,
且組合收益的標準差最小。

Asset Data:資產數據;
Correlation Matrix:相關係數矩陣;
VCV matrix:VCV 矩陣;Portfolio weights:組合權重;

【參照書中第 62 頁的圖 3.5】

圖 3.5 Eff1 表中組合的權重、期望收益以及收益的標準差


為了解決這個最優化問題,規劃求解需要設定可變單格 可變單格,求最小值或最大值的目標單格
可變單格 目標單格,以
目標單格
及限制條件
限制條件說明,限制條件
限制條件 限制條件用來限制可變單格中資料的變化範圍。在圖
限制條件 3.5 中,我們要求單
格 I10:I12 中的權重之和為 1,因此,單格 I10 中的公式寫成‘=1-SUM(I11:I12)’的形式。
為了進行最優化求解,可變單格 可變單格選擇 I11:I12,它們在表中命名為‘change1’。要求最小
可變單格
化的目標單格是名為‘portsd1’的收益標準差(I16)。這裏有一個明顯的限制條件:名為
‘portret1’的期望收益(單格 I15)必須等於目標收益(在 I5 中,命名為‘target1’) 。代
碼中要用到的一些區域名稱都顯示在試算表中。
執行完一次規劃求解,建議購買的 Bonds、Shares 以及出售的 TBills 的最優化比例就
顯示在圖 3.6 中。所求的有效組合在保證期望收益為 7%的情況下,它的最小標準差為
15.7%。改變 I5 中的目標期望收益,保持設置不變,再執行一遍規劃求解,就可以得到另
一個有效組合。很明顯,如果想得到整個有效邊界,最好的辦法是寫一個宏。如果錄製上面
的最優化操作,就可以得到下面的代碼:
Sub TrialMacro()
SolverReset
SolverOk SetCell:="$I$16", MaxMinVal:=2, ValueOf:="0", ByChange:="$I$11:$I$12"
SolverAdd CellRef:="$I$15", Relation:=2, FormulaText:="target1"
SolverOk SetCell:="$I$16", MaxMinVal:=2, ValueOf:="0", ByChange:="$I$11:$I$12"
SolverSolve
End Sub

Efficient Frontier points using Solver(no constraints on weights):


利用規劃求解計算出的有效邊界點(權重無約束情況下)
Asset Data:資產數據;
Correlation Matrix:相關係數矩陣;
VCV matrix:VCV 矩陣;
Efficient frontier portfolio:有效邊界組合;

【參照書中第 63 頁的圖 3.6】

圖 3.6 規劃求解出來的期望收益為 7%的最優組合權重

錄製出的代碼中含有一些規劃求解插件中的特殊 VBA 函數。特別是 SolverAdd 函數(它設


定一個限制條件),它有三個參數:第一個表示限制條件左側的單格引用,第二個表示操作
符的整型代碼(2 表示‘=’) ,第三個要麼是一個單格引用,要麼是一個數值。類似的,
SolverOK 函數的參數指定了需要解決的特殊優化問題。
要改進錄製的代碼,首先可以寫出函數名,並在後面的括弧裏寫上函數所需的參數,參
數之間用逗號隔開,然後使用區域名稱來引用單格位址。用在每一個 Solver 函數前的關鍵
字 Call 表明控制已經轉到一個函數過程中。(同時,它也禁用了函數的返回值。)編輯之後,
優化的代碼如下:
Sub Eff0()
' edited version of Eff0()
SolverReset
Call SolverAdd(Range("portret1"), 2, Range("target1"))
Call SolverOk(Range("portsd1"), 2, 0, Range("change1"))
Call SolverSolve(True)
SolverFinish
End Sub
SolverAdd 函數能夠確保期望收益(在名為‘portret1’的單格中)等於單格‘target1’中
設定的目標收益。而 SolverOk 函數控制最優化求解,保證單格區域‘change1’中的數值
能夠使得組合的標準差最小。SolverFinish 函數的作用相當於在求解之後,在求解結果對話
方塊中選擇選項,並點擊確定 確定按鈕。有了這個函數,求解結果對話方塊在宏的控制下不會出
確定
現。
要得到有效邊界,需要對一系列目標收益求出最優組合權重。假設這些目標收益從初值
1%(用 min_tgt 表示)開始,並以 2%(incr)遞增。不同的目標收益在一個 Do While…Loop
迴圈中產生,迴圈次數為 niter。對於每一個目標收益,Solver 都求出相應的最優權重。每
一次迴圈中唯一的變化是目標收益。這樣,在代碼中,大部分規劃求解設置都可以放在循環
體之外。只有用來改變目標收益的 SolverChange 函數需要放在循環體內。
Sub Eff1()
' repeated optimisation with given min_target & increment

' initialisation
Dim target1 As Double
Dim incr As Single
Dim i As Integer, niter As Integer
target1 = Range("min_tgt1").Value
incr = Range("incr1").Value
niter = Range("niter1").Value

' clearout previous results


Application.Goto Reference:="storestart1"
Selection.CurrentRegion.Select
If Selection.Columns.Count = 1 Then GoTo SetUpSolver 'special case
Selection.SpecialCells(xlCellTypeConstants, 1).Select
Selection.ClearContents

'set up Solver
SetUpSolver: 'for special case
If Selection.Columns.Count = 1 Then MsgBox ("Setting Up Solver. Continue ?")
Application.Goto Reference:="storestart1"
SolverReset
Call SolverAdd(Range("portret1"), 2, Range("target1"))
Call SolverOk(Range("portsd1"), 2, 0, Range("change1"))

' repeated part


' Application.ScreenUpdating = False
For i = 1 To niter
Range("target1").Value = target1
Call SolverChange(Range("portret1"), 2, Range("target1"))
Call SolverSolve(True)
SolverFinish
Range("target1").Copy
Range("storestart1").Offset(0, i).PasteSpecial Paste:=xlValues
Selection.NumberFormat = "0.0%"
Range("portwts1").Copy
Range("storestart1").Offset(1, i).PasteSpecial Paste:=xlValues
Selection.NumberFormat = "0.0%"
target1 = target1 + incr
Next i

Range("target1").Select
Application.CutCopyMode = False
Application.ScreenUpdating = True

End Sub

編寫完代碼後,就可以為這個宏增加一些描述,並且分配一個快捷鍵,就像錄製巨集時的那
樣。可以在 Excel 視窗中點擊 工具 功能表下巨集 巨集中的巨集
巨集 巨集選項。在巨集對話方塊中,選中
巨集
巨集的名稱(Eff1) ,然後點擊選項 選項按鈕。
選項
作為參考,計算有效邊界的宏代碼放在 VBSUB 工作簿的 ModuleS 模組頁中,並可以
在 Eff1 表中運行。在調用任何包含規劃求解的宏之前,必須先建立一個對規劃求解插件的
引用。保持 Visual Basic 模組在啟動狀態,然後點擊工具 工具功能表中的引用
工具 引用,然後流覽並找到
引用
Solver.xla(通常在\Office\Library 目錄下)

小結

VBA 是一種面向物件的 Basic 編程語言。與傳統的編程思想一樣,這種語言不但有變


數和編碼,在使用 Excel 物件時,還有方法和屬性。
首先需要在工作簿的一個模組頁中編寫副程式和函數,然後才能運行巨集來進行自動化
操作。Visual Basic 環境提供了調試宏和訪問 VBA 庫以及線上幫助的工具。
VBA 副程式的目的是執行動作,相比之下,VBA 用戶定義函數則是為了返回數值。在
進行金融建模時,我們發現函數比副程式更有用。除非是執行生成圖表這一類的操作,或者
完成利用規劃求解來進行自動優化的任務。副程式在進行一次性(one-off)管理任務時經
常用到,這種任務往往需要進行多次重複。
宏錄製器可以用來將動作轉換成 VBA 代碼。錄製按鍵有時在開始階段很有用,可以用
來得到代碼提示。但錄製器往往會為一個簡單的操作生成冗長的代碼,它會由於許多功能表
操作生成非常複雜的代碼。
多數 Excel 函數可以用在 VBA 巨集中,也有一些特殊的 VBA 函數在巨集中被調用。這
是衡量一個有經驗的 Excel 模型構建者水準的有效途徑。
掌握 VBA 後會帶來很多好處。用函數來代替一些計算可以增強單格公式的功能,並使
計算過程更加強大和快捷。熟練地使用宏來控制重複操作,可以減少很多試算表操作帶來的
錯誤。

參考文獻
Green,J.,1999,Excel 2000 VBA Programmer’s Reference,Vrox Press Ltd.,Birmingham.
Leonhard,W.,L.Hudspeth and T.J.Lee,1997,Excel 97 Annoyances, O’Reilly&Associates,
Inc., Sebastopol, CA.
Walkenbach,J.,1999,Excel 2000 Power Programming with VBA,IDG Books,Foster
City,CA
Wells,E. and S. Harshbarger,1997,Nicrosoft Excel 97 Developer’s Handbook,Microsoft
Press.

附錄 3A Visual Basic 編輯器

Excel 97(及其以後的版本)對 Visual Basic 編輯器作了大量的改動,此附錄將詳細介


紹它的一些特性。可以點擊 VBE 按鈕(在 VB 工具欄中)或在 Excel 表單中按下組合鍵
Alt+F11 來啟動 Visual Basic 編輯器。一旦啟動 Visual Basic 編輯器之後,你就可以用 Alt+Tab
組合鍵在 Excel 表單和 Visual Basic 表單之間切換。Visual Basic 編輯器也可以通過點擊
Excel 表單的 工具 功能表下巨集 巨集中的 Visual Basic 編輯器
巨集 編輯器選項打開。
Visual Basic 表單看起來如圖 3.7 中顯示的那樣,它的頂部有一個功能表欄和一個工具
欄;工程資源管理器和屬性視窗在左邊,代碼視窗在右邊。代碼視窗中顯示的是 Module1
的代碼,它其實就是 3.3.5 節中描述的資料登錄操作的錄製代碼。

【參照書中第 66 頁的圖 3.7】


圖 3.7 包含工程資源管理器、屬性視窗和代碼視窗的 Visual Basic 表單

第一次啟動 Visual Basic 編輯器時,工具欄和上述的那些視窗可能看不到。如果工具欄看不


到,可以單擊功能表視圖 視圖下工具欄
視圖 工具欄中的標準
工具欄 標準選項。同樣地,可以選中視圖
標準 視圖功能表中的工程資
視圖 工程資
源管理器和屬性視窗
源管理器 屬性視窗來顯示左側那兩個視窗。要顯示代碼模組,可以在工程資源管理器視窗
屬性視窗
中雙擊想要顯示的模組(這裏是 Module1)
顧名思義,代碼模組中包含著 VBA 程式碼。這些模組可以通過點擊功能表條插入 插入中的
插入
模組來插入。
模組 (注意,是模組 模組而不是類模組
模組 類模組,類模組
類模組 類模組是更高層次的應用,在本書中不作介紹。)
類模組
在工作表簿中,想插入多少模組就可以插入多少模組。實際應用中,一般將相關的巨集放在
同一個模組中。
工程資源管理器顯示所有已打開‘工程’的組成部分。它主要用來作為一個流覽工具,
通過它,用戶可以打開新的模組來存儲代碼,或是刪除已有的模組,或是啟動已存在的代碼
模組視窗。選中一個模組頁,檔 檔功能表允許移走這個模組頁(也就是刪除它) ,也可以列印
它裏面的內容。如果想從一個模組中拷貝 VBA 代碼到另一個模組,請不要用導出檔 導出檔選項。
導出檔
從一個模組中拷貝代碼到同一個工作簿中的其他模組,最好使用代碼視窗中的通用‘拷貝’
和‘粘貼’操作。
工程資源管理器中顯示的每個特定‘工程’中的每一個物件都有它自己的一組屬性,例
如,被啟動的工作簿中的每一個工作表,都有‘name’屬性。這些屬性可以通過屬性視窗
來修改。但是,由於修改屬性與模組的關係不大,因此我們在關於巨集的內容中不再講述這
個視窗的特性,只要知道每一個模組的名稱可以在這裏修改就行了。(例如,我們經常將模
組的名稱改為 M、0 和 1,將所有的宏都收集到 ModuleM 中,然後將陣列基準值為 0 的函
數放在 Module0 中,將陣列基準值為 1 的函數放在 Module1 中。)在實際應用中,當編寫
宏代碼時,關掉屬性視窗和工程資源管理器,並使代碼視窗最大化,這樣編寫代碼就顯得更
加方便了。
Visual Basic 表單有它自己的標準工具欄,如圖 3.8 所示,其中視圖
視圖 Microsoft Excel
按鈕在最左邊,點擊它可以把用戶帶回到 Excel 表單。中間部分的按鈕是關於編輯代碼、運
行和測試宏代碼的,而右側的這組按鈕則是用來打開其他視窗的,如立即視窗 立即視窗(用來測試單
立即視窗
條語句)和物件流覽器
物件流覽器(查找能夠在
物件流覽器 VBA 中適用的物件、方法和屬性)等。特別需要注意
的是運行巨集
運行巨集按鈕(一個指向右側的三角形)
運行巨集 ,重新設置
重新設置按鈕(一個正方形)和物件流覽器
重新設置 物件流覽器
按鈕(從右向左數第三個按鈕) 。

【參照書中第 67 頁的圖 3.8】

圖 3.8 VB 表單中的標準工具欄

用 VBA 編程時有兩種類型的程式:副程式(或巨集)和函數。只有副程式(或巨集)
可以錄製。錄製後的代碼通常需要在代碼視窗作進一步的修改,並用 Excel 調試工具來測
試。由於函數不能錄製,它們必須在一個代碼模組中手工編寫。因此錄製工具在編寫函數時
基本無用。
如前所述,副程式可以在 Excel 表單中運行(通過功能表操作,或者點擊 VB 工具欄中
的運行
運行按鈕,或者使用一個快捷鍵)
運行 。它們也可以在代碼視窗中運行(將滑鼠指示器移動到
副程式代碼體內的任何地方,然後點擊 VB 表單功能表下 VB 標準工具欄中的運行 運行按鈕)
運行 。
相比上面的兩種方法而言,如果我們能夠將副程式與按鈕綁定,也許會對用戶更友好。但是,
既然我們的工作簿相對來說更依賴函數而不是巨集,因此我們在此就不介紹這方面的內容,
讀者可以參考其他文獻來瞭解它。 (例如,可以參看 Leonhard et al.,1997 中的‘VBE and
developing macros’部分。)
注意,運行副程式時,如果 VBE 中斷了它,並告訴存在一個編譯錯誤時,VBE 會以一
種‘調試模式’掛起巨集操作,而此時副程式名會以黃色顯示。可以將滑鼠移到出錯的語
句,修改簡單的錯誤,然後點擊運行 運行功能表中的重新設置
運行 重新設置或點擊工具欄中的重新設置
重新設置 重新設置按鈕來
重新設置
跳出‘調試模式’。這時黃色條紋會消失,宏就可以重新運行了。

逐語句運行宏和使用其他調試工具

如果你的宏並不如你所期待的那樣運行,採用逐語句運行的方式是很有幫助的。如果你
通過功能表操作來運行巨集,選擇工具 工具功能表下的巨集
工具 巨集,然後選中巨集名稱,這時你需要在
巨集
巨集對話方塊中點擊逐語句 逐語句按鈕,而不是運行
逐語句 運行按鈕。這使得你能夠逐語句地運行宏。如果滑
運行
鼠不在代碼視窗,你可以點擊 VBA 工具欄中的運行 運行按鈕,選中要測試的宏,然後點擊逐語
運行 逐語
句按鈕。這時相應的代碼視窗就會打開,而且被選中的宏的第一條語句會高亮顯示(黃色)。
按下功能鍵 F8(或者逐語句 逐語句按鈕,如果它可見的話)執行語句到下一行。如果你希望
逐語句
看到試算表視窗中的動作,可以縮小 VBE 視窗,直到你可以看到視窗下面的 Excel 工作表,
或者使用 Alt+Tab 組合鍵在兩個視窗之間切換,並且觀察代碼視窗中巨集的逐步執行情況。
不中斷點擊 F8(或者逐語句 逐語句按鈕)就可以逐語句地運行宏了。有一個跳出
逐語句 跳出按鈕可以跳出逐
跳出
語句執行模式。也可以使用 VBE 編輯視窗中運行 運行功能表下的重新設置
運行 重新設置選項,點擊它就可以
重新設置
跳出逐語句執行模式或調試模式。
圖 3.9 中的調試工具欄中包含逐語句逐語句按鈕、逐過程
逐語句 逐過程按鈕和跳出
逐過程 跳出按鈕,它們是用來執行宏
跳出
代碼的。一個巨集如果按逐語句的模式來運行,被稱為‘中斷點模式’。如果巨集中還調用
其他的二級副程式,那麼點擊逐過程 逐過程按鈕就會直接執行這些二級副程式,而不是跳到二級副
逐過程
程式裏面逐語句地執行了。

【參照書中第 68 頁的圖 3.9】

圖 3.9 調試工具欄,逐語句
逐語句、跳出
逐語句 跳出和重新設置
跳出 重新設置按鈕分開顯示
重新設置

為了演示,我們先在 VB 表單中調出調試工具欄(點擊視圖 視圖下的工具欄


視圖 工具欄)
工具欄 ,並且試著以逐語 逐語
句的方式執行 Factorial 巨集(它的代碼在 VBSUB 工作簿的 ModuleA 模組頁中)。首先啟
動 IntroEx 表,選擇工具
工具功能表下巨集
工具 巨集中的巨集
巨集 巨集選項,選中 Factorial 巨集,如圖 3.10 所示,
巨集
然後點擊單步執行單步執行按鈕。這時
單步執行 VB 視窗就會出現,並且 Factorial 宏代碼的第一條語句高亮
顯示(黃色) 。點擊逐語句
逐語句按鈕繼續單步執行。當
逐語句 InputBox 要求輸入數值時,輸入 3 並點擊
確定按鈕。繼續單步執行(檢查循環體是否執行了三遍)
確定 ,直到 MsgBox 對話方塊出現,並
返回結果 6。
在任何時候,你都可以點擊重新設置
重新設置按鈕(或者點擊
重新設置 VBE 標準菜單欄運行
運行下的重新設
運行 重新設
置選項)來跳出單步執行模式。

【參照書中第 69 頁的圖 3.10】

圖 3.10 進入 Factorial 巨集的單步執行模式

為了作進一步的演示,我們先點擊本地視窗 本地視窗按鈕(調試工具欄中從右向左數第五個按鈕)
本地視窗 ,
然後再次單步執行 Factorial 宏。在新的觀測視窗中,隨著巨集代碼的一步步運行,會依次
出現變數 num、fac 和 i 的值。
另一個調試宏代碼的工具是插入中斷點,在宏代碼很長的時候它非常有用。當運行宏
時,一旦遇到中斷點就會停下來。這時運行進入中斷點模式,並且巨集可以單步執行。要想
插入一個中斷點,先找好代碼中的中斷點位置,然後點擊代碼左邊的灰色邊界,或者直接點
擊中斷點按鈕(圖 3.9 中顯示的小手)。要想去掉中斷點,只需再次點擊代碼左邊的灰色邊
界,或再次點擊中斷點按鈕。在 Factorial 宏代碼中,試著在 MsgBox 語句處加上中斷點,
然後執行宏代碼,看看能否正常執行到中斷點處。然後按一下 F8,將運行模式改為‘單步
執行’模式。(中斷點也可以用來調試函數,因為它提供了一種進入‘單步執行’模式並檢
測函數代碼執行情況的方法。)

附錄 3B 用‘相對引用’
相對引用’模式來錄製按鍵

錄製器將按鍵轉換成 VBA 代碼,它在解釋位址時有兩種模式:絕對引用(缺省模式)


和相對引用模式。在 3.3.5 節,錄製輸入資料到工作表中的巨集採用了絕對引用。這裏,我
們採用相對引用模式來看看生成的錄製代碼。
將滑鼠放在單格 B8 中,點擊工具工具功能表下巨集
工具 巨集中的錄製新巨集
巨集 錄製新巨集選項,從
錄製新巨集 Excel 表單中
調出巨集錄製器。然後給宏取一個名字,比如 RelEntries。這次,當停止錄用
停止錄用的按鈕出現在
停止錄用
螢幕中時,點擊‘相對引用’按鈕。這個按鈕會出現‘按下’狀態。然後象上次一樣,鍵入
月份的名稱。完成錄製後,生成的代碼看起來與上次不同:
Sub RelEntries()
'recorded with relative positions
ActiveCell.FormulaR1C1 = "JAN"
ActiveCell.Offset(1, 0).Range("A1").Select
ActiveCell.FormulaR1C1 = "FEB"
ActiveCell.Offset(1, 0).Range("A1").Select
ActiveCell.FormulaR1C1 = "Total"
ActiveCell.Offset(-2, 1).Range("A1").Select
ActiveCell.FormulaR1C1 = "300"
ActiveCell.Offset(1, 0).Range("A1").Select
ActiveCell.FormulaR1C1 = "400"
ActiveCell.Offset(1, 0).Range("A1").Select
ActiveCell.FormulaR1C1 = "=SUM(R[-2]C:R[-1]C)"
ActiveCell.Offset(1, 0).Range("A1").Select
End Sub
試著在工作表的不同單格處運行宏。輸入值會在滑鼠所在單格(啟動的單格引用為
Range(“A1”))的相對位置出現。它先每次向下移動一行,然後移到相鄰的列中。Offset 方
法,比如 Offset(1,0),返回一個 Range 物件,它處於當前單格同一列的下一行。選中的單
格總是被引用為“A1”(ActiveCell) ,而不管按鍵操作是否包括單格 A1。
為了從錄製器中得到更多的幫助,我們需要思考一下,到底絕對引用和相對引用中哪一
種模式更有用。通常,我們使用錄製器的缺省模式:絕對引用模式。但是,如果在工作表中
一行行地重複執行某些操作,採用相對引用模式似乎更方便一些。例如,如果你希望宏先選
中一個單格,執行一個動作,然後移動到當前單格的一個相對位置,這時應該使用相對引用
模式。但是,錄製完代碼之後,記住再次點擊相對引用 相對引用按鈕,將其返回到絕對引用模式。
相對引用
編輯 RelEntries 宏使它顯得更加簡潔。錄製的代碼中經常包含單格的‘選中’操作,
而這在編寫代碼時是沒有必要的。下面的這段改進後的代碼可以執行同樣的操作,但顯得簡
潔的多:
Sub ConciseEntries1()
'edited version
ActiveCell.Offset(0, 0).FormulaR1C1 = "JAN"
ActiveCell.Offset(1, 0).FormulaR1C1 = "FEB"
ActiveCell.Offset(2, 0).FormulaR1C1 = "Total"
ActiveCell.Offset(0, 1).FormulaR1C1 = "300"
ActiveCell.Offset(1, 1).FormulaR1C1 = "400"
ActiveCell.Offset(2, 1).FormulaR1C1 = "=SUM(R[-2]C:R[-1]C)"
End Sub
實際上,對於只包含一個單格的 range 物件,不需要特別指定 Formula 屬性,因此代碼可
以更簡單:
Sub ConciseEntries1()
'edited version
ActiveCell.Offset(0, 0) = "JAN"
ActiveCell.Offset(1, 0) = "FEB"
ActiveCell.Offset(2, 0) = "Total"
ActiveCell.Offset(0, 1) = "300"
ActiveCell.Offset(1, 1) = "400"
ActiveCell.Offset(2, 1) = "=SUM(R[-2]C:R[-1]C)"
End Sub
一個實用的清理代碼的方法是:先注釋掉冗餘語句(在語句前加上單引號),然後運行宏來
測試效果。
第 4 章 編寫 VBA 用戶定義函數

VBA 代碼不僅可以用於編寫試算表的自動操作程式,還可以用於編寫函數,這些函數
與 Excel 內嵌函數的工作方式是一樣的。函數在進行重複自動計算時非常有用。函數計算是
‘離表(off sheet)’執行的,函數一旦編寫完畢,就可以拷貝到不同的工作簿中使用。
VBA 副程式通常執行一個或多個動作,而 VBA 函數則是由一系列指令組成的,它們返
回單個數值(如 SUM 函數)或一個陣列(如 LINEST 函數) 。用戶定義函數能將編程語句
(包括迴圈和條件選擇語句)與 Excel 函數(如 NORMSDIST 和 MMULT)結合起來。
最簡單的函數是單值輸入單值輸出函數。本章從一個簡單的單值輸入單值輸出銷售傭金
函數開始,來描述編寫和使用函數的步驟。多標量輸入函數的編寫方式與它基本相同。作為
演示,我們將編寫基於布萊克-舒爾斯期權定價公式的函數。當輸入的資訊是陣列形式而不
是單個數值時,編寫函數就顯得複雜多了。為了演示如何進行陣列處理,我們還將使用一個
用來計算一組現金流的期望及方差的例子,和一個計算資產組合方差的例子。還有一些輸入
和輸出都是陣列形式的例子。這些函數的代碼放在 VBFNS.xls 工作簿中,鼓勵讀者用這些
例子來作練習,並練習本章後面的習題。

4.1 簡單銷售傭金函數

假設傭金率依賴於每月的總銷售額,傭金率顯示在圖 4.1 的單格 D5:E7 中。

Sales Commission Function:銷售傭金函數

【參照書中第 73 頁的圖 4.1】

圖 4.1 VBFNS.xls 工作簿 SalesCom 表中的銷售傭金率

如果單格 A5 中的數值表示總銷售額,那麼傭金(單格 B5 中)有三種計算方法,用帶


有嵌套 IF 函數的公式表示為:
=IF(AND(A5>=0,A5<1000),A5*0.08,IF(AND(A5>=10000,A5<20000),A5*0.105,A5*0
.12))
然而,如果需要頻繁地計算銷售傭金,而且涉及到更多的傭金率,這時最好是建立一個用戶
定義函數,它能象 Excel 其他函數一樣被調用。我們先來討論適用於編寫函數的 VBA 代碼,
然後在下一節解釋怎樣編寫代碼,並在工作簿中測試其結果。
參看下面一個名為 Commission 的函數代碼,它需要一個輸入值(或‘參數’) ,也就
是變數名為 Sales 的月總銷售額。函數的調用方式為 Commission(Sales),它的輸出就是所
欠的傭金。此段代碼在一個模組頁中編寫,就像宏一樣:
Option Explicit
Function Commission(Sales)
' Calculating sales commission
If Sales >= 0 And Sales < 10000 Then Commission = Sales * 0.08
If Sales >= 10000 And Sales < 20000 Then Commission = Sales * 0.105
If Sales >= 20000 Then Commission = Sales * 0.12
End Function

代碼解釋如下,首先要定義函數,以關鍵字 Function 開始,函數名為 Commission,並需


要一個輸入值,Sales,輸入變數放在括弧中。執行函數代碼時,有一個數值結果被賦給函
數名 Commission。條件語句 If…Then 決定適當的傭金率,並用它乘以銷售額。這三條語
句中只有一條被執行,因此函數值只取決於銷售水準。代碼以 End Function 語句結束。注
意,以單引號開頭的語句是注釋語句,它們不被執行。
作為好的編程習慣,模組頁開頭處的 Option Explicit 語句能夠確保 VBA 代碼中所有變
數都必須聲明。這裏僅有兩個變數:Commission 和 Sales,它們在函數的第一句已被隱式
聲明了,因此不需要再聲明一次。(詳細介紹見 4.3 節。)

4.2 在工作表中創建 Commission(Sales)函數


函數

在工作表中創建 Commission 函數時,先首在工作簿中插入一個模組頁。點擊工具 工具功能


工具
表下巨集
巨集選項中的 Visual Basic 編輯器,然後進入
巨集 編輯器 VB 視窗。點擊工程資源管理器
工程資源管理器,然後
工程資源管理器
點擊插入
插入功能表下的模組
插入 模組選項,這時會出現一個新的模組頁。然後就可以在代碼視窗中輸入
模組
函數代碼了(注意將 Option Explicit 語句寫在模組頁開頭) 。
可以在工作表中測試這個函數,輸入公式:
=Commission(25000)
其結果應該是 3000(因為這一水準銷售額的傭金率為 12%)
。或者使用單格 A5 中的資料,
使用公式:
=Commission(A5)
象 Excel 的其他函數一樣,粘貼函數 粘貼函數按鈕也可以用來幫助輸入
粘貼函數 Commission 這一類的函數。
所有用戶創建的函數都被歸於用戶定義 用戶定義類別。
用戶定義
創建的函數不正確時,單格中就出現一條錯誤資訊(如#NAME?或#VALUE?) ,通常表
明函數與輸入值之間不匹配,或者函數名寫錯了。Microsoft Visual Basic‘編譯錯誤’出現
錯誤時,表明代碼有錯誤。這時,先記下錯誤類型(經常是‘Variable not defined’) ,然
後點擊確定確定按鈕,並更正高亮顯示的錯誤。然後,點擊
確定 VB 標準工具欄中的重新設置重新設置按鈕
重新設置 (黑
色方框),它會把黃色條紋去掉。返回工作表,重新輸入創建的函數(按 F2 鍵然後輸入) 。
另一種檢測函數工作狀況的方法是在代碼中使用中斷點,並用本地視窗 本地視窗觀測計算出的數
本地視窗
值。例如,點擊語句:
If Sales>=0 And Sales<10000
左側的邊界設置一個中斷點(如附錄 3A 中的描述)。然後返回 SalesCom 表重新輸入
Commission 函數。當調用函數時,指標會跳回到函數代碼視窗,並且在單步運行餘下代碼
時,可以在本地視窗 本地視窗觀測到一系列計算結果。
本地視窗
在離開 VBE 時,可以在屬性視窗中將模組頁改名(如附錄 3A 中的描述),如改成
Module0。
接下一節中,我們將編寫幾個稍微複雜一點的函數,它們有多個輸入變數,並在代碼中
調用 Excel 函數以及 VBA 函數。下節用戶定義的函數是布萊克-舒爾斯期權定價函數。

4.3 多參數期權定價函數

Excel 至今還沒有利用布萊克-舒爾斯公式來計算期權價格的內嵌函數。因此,我們可以
編寫一個用戶定義函數來給看漲期權定價,命名為 BSCallValue。布萊克-舒爾斯公式的背
景知識將在本書的第三部分介紹。現在不必理解期權定價公式,這裏的目的只是將公式變成
VBA 代碼。
一個歐式看漲期權的布萊克-舒爾斯定價公式為:

c = S exp(− qT ) N (d1 ) − X exp(− rT ) N (d 2 )


其中,S 表示即期股票價格,X 表示看漲期權在 T 時刻的執行價格,r 表示無風險連續複利,
因此式子 exp(-rT)表示時間段 T 的無風險折現因數。股票的連續股利收益表示為 q,因此股
票價格 S 在定價公式中被 Sexp(-qT)代替。符號 N(d)用來表示小於 d 的累積標準正態概率。

其中, d1 和 d 2 為:

d1 = [ln( S / X ) + (r − q + σ 2 / 2)T ] /[σ T ]

d 2 = [ln( S / X ) + (r − q − σ 2 / 2)T ] /[σ T ] = d1 − σ T


σ 是股票的波動率。
圖 4.2 顯 示 了 一 份 6 個 月 到 期 的 股 票 期 權 的 詳 細 情 況 : 當 前 價 格

S = 100, X = 95, r = 8.0%, q = 3%, σ = 20% 。 d1 和 d 2 在單格 G8 和 G11 中計算得到,它

們的累積正態概率 N ( d1 ) 和 N ( d 2 ) 在單格 G9 和 G12 中使用 NORMSDIST 函數計算得到。

這些都是期權價格單格公式(G4 中)的輸入值:
=D4*D16*G9 – D5*D15*G12
其計算結果為 9.73。(對應的看跌期權價格顯示在單格 H4 中。)

看漲期權公式可以用一個用戶定義函數表示,它有六個輸入值( S , X , r , q, T , σ ),其

計算結果在單格 G5 中顯示。

Black-Scholes Formula:布萊克-舒爾斯公式
Call:看漲期權;Put:看跌期權;

【參照書中第 76 頁的圖 4.2】

圖 4.2 期權資訊與計算出來的布萊克-舒爾斯期權價格
函數 BSCallValue(S,X,r,q,tyr,sigma)的 VBA 代碼在下面給出。當前距期權到期日的時間表
示為 tyr(單位:年) , σ 表示為 sigma。布萊克-舒爾斯公式的計算相當複雜,因此我們在

代碼中使用了中間變數【DOne 表示 d1 ,而 NDOne 表示 N ( d1 ) 】:

Option Explicit
Function BSCallValue(S, X, r, q, tyr, sigma)
' Returns Black-Scholes Call Value (allowing for q=div yld)
Dim ert, eqt
Dim DOne, DTwo, NDOne, NDTwo
ert = Exp(-r * tyr) 'exp is the VBA function for 'e'
eqt = Exp(-q * tyr) 'dividend yield effect
DOne = (Log(S / X) + (r - q + 0.5 * sigma ^ 2) * tyr) / (sigma * Sqr(tyr))
DTwo = (Log(S / X) + (r - q - 0.5 * sigma ^ 2) * tyr) / (sigma * Sqr(tyr))
NDOne = Application.NormSDist(DOne)
NDTwo = Application.NormSDist(DTwo)
BSCallValue = (S * eqt * NDOne - X * ert * NDTwo)
End Function

模組頁開頭的 Option Explicit 語句強迫函數中所有的變數都要聲明。‘Dim’聲明了六個變


數(ert,eqt,DOne,DTwo,NDOne,NDTwo)。這些變數的名稱都具有描述的性質,如 Done

表示 d1 ,NDOne 表示 N ( d1 ) ,等等,它們將代碼與期權公式中的傳統符號聯繫起來。變數

ert 表示將到期日的收益轉換成現值的折現因數:代數形式為 exp(-rt)。變數 eqt 是影響股票


當前價格的股利收益,代數形式為 exp(-qT)。注意,輸入變數(如 S,X,等等)在函數命
令中已自動聲明,因此它們不需要在 Dim 語句中聲明。
這段代碼儘管看起來很笨拙,但其計算還是相對簡單的。三個運算式‘exp’、‘log’、
‘sqr’都是內嵌的 VBA 函數,分別表示指數、對數和平方根計算。當 VBA 函數和 Excel
函數都能進行相同的計算時,必須使用 VBA 函數而不是 Excel 函數。在代碼中調用 Excel
函數時,函數名前必須加上 Application.或 WorksheetFunction.。這裏:
NDOne = Application.NormSDist(DOne)語句調用了 Excel 函數 NORMSDIST。
於是,公式
=BSCallValue(100,95,8%,3%,0.5,20%)
的計算結果為 9.73。(單格 G5 中的公式將 D 列中的單格數值作為輸入,並顯示結果為 9.73。)
考慮一份歐式看跌期權的 BS 定價公式,由於看漲期權和看跌期權是對偶關係,所以歐
式看跌期權的定價公式如下:

p = − S exp(− qT ) N (− d1 ) + X exp(− rT ) N (− d 2 )

其中, d1 和 d 2 與前面的一樣。它與看漲期權公式的唯一區別在於: d1 和 d 2 前面的正號變

成了負號,並且布萊克-舒爾斯公式中的兩項都變了號。增加一個參數 iopt(當值為 1 時計
算看漲期權價格,當值為-1 時計算看跌期權價格) ,前面計算看漲期權價格的 VBA 代碼就
可以改寫成用來計算兩種歐式期權價格,看漲期權或看跌期權。
BSOptValue 函數的代碼在下面給出,它有七個輸入變數(包括 iopt,其值為 1 或-1)。

如果 iopt = -1,則 NDOne 變為 N ( − d1 ) ,NDTwo 變為 N ( −d 2 ) ,並且 BS 方程中兩項運算


式 前 的 符 號 也 同 時 改 變 。 在 工 作 表 中 測 試 一 下 , 看 看 BSOptValue(-1,
100,95,8%,3%,0.5,20%)的值是否為 2.40【而 BSOptValue(1, 100,95,8%,3%,0.5,20%)的值
為 9.73,與前面的一樣】 :
Function BSOptValue(iopt, S, X, r, q, tyr, sigma)
' Returns Black-Scholes Value (iopt=1 for call, -1 for put; q=div yld)
' Uses BSDOne fn
' Uses BSDTwo fn
Dim ert, eqt, NDOne, NDTwo
ert = Exp(-r * tyr)
eqt = Exp(-q * tyr)

NDOne = Application.NormSDist(iopt * BSDOne(S, X, r, q, tyr, sigma))


NDTwo = Application.NormSDist(iopt * BSDTwo(S, X, r, q, tyr, sigma))
BSOptValue = iopt * (S * eqt * NDOne - X * ert * NDTwo)

End Function
Function BSDOne(S, X, r, q, tyr, sigma)
' Returns Black-Scholes d1 value
BSDOne = (Log(S / X) + (r - q + 0.5 * sigma ^ 2) * tyr) / (sigma * Sqr(tyr))
End Function

Function BSDTwo(S, X, r, q, tyr, sigma)


' Returns Black-Scholes d2 value
BSDTwo = (Log(S / X) + (r - q - 0.5 * sigma ^ 2) * tyr) / (sigma * Sqr(tyr))
End Function

注意,中間量 DOne 和 DTwo 已經改寫成了函數,並在主函數中被調用。這樣做的目的是


使 VBA 代碼模組化,從而使代碼顯得更明晰,更容易發現錯誤所在。
總而言之,函數是一種有返回值的 VBA 程式,它們的代碼封裝在關鍵字 Function 和
End Function 中。緊跟關鍵字 Function 之後的是函數名稱,它後面括弧中的是一系列輸入
變數。接下來的是一組 VBA 語句,當函數運行時,輸出值由函數名返回:
Function name(input1,input2,…)
[statements]
[name = expression]
End Function
在一個好的 VBA 程式中,每一個模組頁都應該以 Option Explicit 語句開始,它強迫所有的
變數都必須聲明。注意,函數使用的變數都應該用 Dim 語句聲明,但函數的輸入變數不需
要聲明。如果代碼中需要使用 Excel 函數,則必須在函數名前面加上 Application.或者
WorksheetFunction.首碼。

4.4 在 VBA 中運算元組

事實上,帶有陣列輸入或輸出的函數編碼是比較複雜的。因此,在編寫這類函數之前,
有必要先弄清楚 Excel 是如何處理陣列的。在許多實例中,大家熟悉的 Excel 函數,如
SUM,AVERAGE,STDEV,SUMPRODUCT 和 NPV,都可以用來處理陣列。而在其他情形下,
則需要一些額外的安全措施才能使函數按預想的方式執行。特別是:
 在沒有合適的內嵌函數的情況下,處理陣列時,需要在一個循環體中執行重複操作。這
樣的話,就必須先計算陣列元素的個數,使用 Excel 函數 COUNT 可以很容易地得到它,
如 Application.Count(avec)。
 必須清楚陣列的編號方式。沒有 Option Base 語句時,則元素從 0(缺省值)開始編號。
模組頁開頭有 Option Base 1 語句時,則陣列中的元素從 1 開始編號,就象 Excel 通常
的操作。
 進行矩陣操作,如矩陣相乘時,需要先檢查一下矩陣維數的一致性。(一致性是指,如
果矩陣相乘,則前一矩陣 A 的列數必須等於後一矩陣 B 的行數。)對於任何矩陣操作,
都需要一些額外的代碼來確保矩陣的格式是正確的(行向量或列向量) 。

附錄 4A 通過一些簡單的函數演示如何在 VBA 中處理陣列,重點放在操作矩陣方面。


接下來的兩節將演示如何處理陣列,4.5 節中的 variance 函數直接處理陣列中的單個元
素,而 4.6 節中則使用 Excel 矩陣相乘函數和其他陣列函數來間接處理它們。

4.5 陣列變數的期望和方差函數

假設一項投資的未來現金流是不確定的,有五種可能結果,每結果出現的概率在圖 4.3
中的第一列顯示。計算現金流的期望值需要用每一現金流乘以它出現的概率,然後將乘積相
加,如 D 列所示。

Expected Values:期望值

【參照書中第 79 頁的圖 4.3】

圖 4.3 VBFNS 工作簿 ExpValues 表中的現金流及其概率

採用 Excel 函數來計算,可以寫成一條簡單的公式:
SUMPRODUCT(B5:B9,A5:A9)
注意,SUMPRODUCT 函數中的兩個陣列要麼都是列向量(本表) ,要麼都是行向量。
另外,如果第二個陣列的(這裏是 A5:A9)數值之和不為 1,則公式計算出來的期望值就是
錯誤的。
在工作表中計算方差則顯得不那麼緊湊,它需要先計算每個現金流與平均值的偏離量,
再用偏離量的平方與概率相乘,然後相加,如列 E 所示。因為在函數中,對每個元素的計
算是‘離表(off sheet)’執行的,所以使用 VBA 函數來計算方差(以及計算現金流的期
望值)將更有優勢。兩個函數,WVariance 和 ExpVal,都有兩個陣列形式的輸入變數,它
們是計算期望值時需要用到的現金流陣列 vvec 和概率陣列 pvec。
ExpVal(vvec,pvec) 函 數 的 代 碼 中 主 要 調 用 了 Excel 函 數 SUM , COUNT 和
SUMPRODUCT。由於 Excel 函數為這個函數處理了所有的陣列操作,因此它的代碼很直
接。前面的 If…Then 條件語句濾除了那些期望值無法有效計算的情況,也就是,如果陣列
pvec 中的數值相加不為 1,或兩個陣列中的元素個數不相時,將函數返回-1:
Function ExpVal(vvec, pvec)
' returns expected value for 2 arrays
If Application.Sum(pvec) <> 1 Or _
Application.Count(vvec) <> Application.Count(pvec) Then
ExpVal = -1
Exit Function
ElseIf pvec.Rows.Count <> vvec.Rows.Count Then vvec =
Application.Transpose(vvec)
End If
ExpVal = Application.SumProduct(vvec, pvec)
End Function

要使 SUMPRODUCT 函數能夠正常運行,兩個陣列形式的輸入變數必須是同一類型
的,要麼都是列向量,要麼都是行向量。如果輸入變數不是同一類型的,就需要將 vvec 轉
置。
WVariance 函數的 VBA 代碼中需要處理陣列中的單個元素。模組頁開頭的聲明 Option
Base 1 確保了陣列元素是以 1 開始編號的(與缺省值 0 相反)。與 ExpVal 函數一樣,條件
語句濾除了陣列 pvec 中的數值相加不為 1,或兩個陣列中的元素個數不相等的情況:
Option Base 1

Function WVariance(vvec, pvec)


'Returns variance of array of values, with attached probabilities
'Uses Function ExpVal
Dim Expx 'expected value
Dim i As Integer, n As Integer
If Application.Sum(pvec) <> 1 Or _
Application.Count(vvec) <> Application.Count(pvec) Then
WVariance = -1
Exit Function

If pvec.Rows.Count <> vvec.Rows.Count Then vvec =


Application.Transpose(vvec)
MsgBox ("vvec(1)" & vvec(1))
End If
Expx = ExpVal(vvec, pvec)
WVariance = 0
For i = 1 To Application.Count(pvec)
WVariance = WVariance + pvec(i) * (vvec(i) - Expx) ^ 2
' MsgBox ("WVariance " & WVariance)
Next i
WVariance = Application.Sum(WVariance)
End Function
同樣,If…Then 條件語句濾除了那些導致方差無法有效計算的情況。方差用一個
For…Next 迴圈來求得。注意,偏離值的平方表示成:(vvec(i) - Expx) ^ 2 的形式,這裏,
expx 是現金流 vvec(i)的期望值。這個值是用我們剛剛建立的 VBA 函數 ExpVal 求得的,因
此 VBA 代碼為:
Expx = ExpVal(vvec, pvec)
在迴圈指針 i 每迴圈一次加 1 的同時,方差也隨之增加 pvec(i) * (vvec(i) - Expx) ^ 2。
作為練習,可以編寫一個函數來計算現金流的標準差。記住,要使用 VBA 的內嵌函數
Sqr,而不能用 Excel 函數。在求平方根之前,先檢查一下 WVariance 函數求出的值是否有
意義(也就是說,它不能為負) ,這是一種很明智的做法。
(作為練習 4 的答案,求標準差
的 VBA 代碼放在本章的尾部。)
當創建的函數不能工作時,可能需要在適當的位置增加一些 MsgBox 函數來顯示中間
變數的值。例如,將圖 4.3 中單格 A5 的概率值由 0.05 改成 0.5,如果在語句 Exit Function
之前插入一條資訊(MsgBox “Got here”),就可以檢測函數的處理流程。
測試程式的另一種方法是在一個子程式中調用它。這時會出現運行時錯誤,也可以使用
調試器來跟蹤代碼。例如,編寫一個 CheckFn 巨集來建立陣列 vvec 和 pvec,然後調用函
數 WVariance。如果代碼中有錯誤,調試器會彈出錯誤資訊框:
Sub CheckFn()
‘Calls WVariance function
‘needs named ranges vvec,pvec in spreadsheet
Dim vvec As Variant,pvec As Variant
Set vvec = Range(“vvec”)
Set pvec = Range(“pvec”)
Range(“B22”).Value = WVariance(vvec,pvec)
End Sub

有必要為函數的用途寫一段簡要的描述,這樣在函數列表中訪問該函數時,它就會出現
對該函數的描述。在 VBE 中,保持相應的模組頁在啟動狀態。然後訪問物件流覽器,觀察
Excel 中不同物件的方法和屬性。在庫
庫中選擇當前的工作簿,並選擇函數代碼所在的模組,
然後在成員視窗
成員視窗選擇你創建的函數。點擊滑鼠右鍵,選擇選項屬性
成員視窗 屬性,這時會出現一個對話方
屬性
塊,這裏可以為你創建的函數增加一段簡單的描述。最後,點擊確定 確定按鈕來關閉對話方塊。
確定
可以通過粘貼函數
粘貼函數按鈕來訪問該函數,檢查剛才添加的描述資訊是否出現。
粘貼函數

4.6 陣列變數的組合方差函數

計算投資組合收益的均值和方差的函數是很容易編寫的。為了演示這一過程,我們用
Excel 函數寫一個工作表公式,然後將公式用 VBA 代碼完成,並產生出相應的函數。
圖 4.4 中的工作表包含有三種資產的風險和收益資訊,分別是 A、B 和 C,並顯示了等
權重時投資組合的計算結果。資產的收益資訊在單格 C5:C7 中,為列向量,在工作表公
式中可以用區域名稱 e 來引用,而在 VBA 代碼中用 retsvec 來引用。組合由三種資產組成,
權重放在單格區域 E5:E7 中,也是列向量,在工作表公式中用區域名稱 w 引用,在 VBA
代碼中用 wtsvec 來引用。
Portfolio Risk&Return:資產組合的風險和收益;
Asset Data:資產數據;Correlations:相關係數;VCV Matrix V:VCV 矩陣 V

【參照書中第 82 頁的圖 4.4】

圖 4.4 投資組合中三種資產的風險和收益

組合的期望收益(單格 G5 中)等於每種資產的期望收益乘以它們的權重然後相加(實
際上等於 0.093 或者 9.3%)。G5 中的公式 SUMPRODUCT(e,w)給出了加權收益,它使用
了區域名稱 w 和 e,這兩個列向量的元素個數是相同的。
三種資產的方差——協方差矩陣可以用相關係數矩陣(C10:E12)以及單個資產的標
準差(D5:D7)計算得到。其結果(C15:E17)矩陣的對角線上是單個資產的方差,而
其他則是兩種不同資產的協方差。假設此方差——協方差矩陣的區域名稱為 V。方差——協
方差矩陣,再加上權重陣列,構成了計算投資組合方差的基礎,計算時採用矩陣相乘的形式

wTVw ,其中 wT 表示權重向量 w 的轉置。在單格 G17 的計算方差公式中,調用了陣列轉


置 Excel 函數 TRANSPOSE 和矩陣相乘函數 MMULT。公式如下:
MMULT(TRANSPOSE(w),MMULT(V,w))
(由於這是一個陣列函數,因此在將公式輸入到 G17 中之後,別忘了按下組合鍵
Ctrl+Shift+Enter。)
要使 Excel 函數 MMULT 能夠正常工作,相乘矩陣的維數必須相符,即,前一個矩陣的
列數必須等於後一個矩陣的行數。這裏 TRANSPOSE(w)是一個 1×3 的行向量,而 MMULT
(V,w)是一個 3×1 的列向量,因此矩陣相乘是可以的,其結果為 0.0007(或者 0.07%)。

因此,對這個資產組合來說,收益的風險為 0.0007 = 0.0257(或2.57%) 。

編寫計算資產組合收益的函數其實很簡單,我們將這個函數取名為
PFReturn(wtsvec,retvec):
Option Base 1

Function PFReturn(retsvec, wtsvec)


'calculates weighted return for PortFolio
If Application.Count(retsvec) <> Application.Count(wtsvec) Then
PFReturn = "Counts not equal"
Exit Function
ElseIf retsvec.Rows.Count <> wtsvec.Rows.Count Then
wtsvec = Application.Transpose(wtsvec)
End If
PFReturn = Application.SumProduct(retsvec, wtsvec)
End Function

第二個函數 PFVariance(wtsvec,vcvmat)的代碼則有點複雜:
Function PFVariance(wtsvec, vcvmat) 'calculates PF variance
Dim nc As Integer, nr As Integer
Dim v1 As Variant
nc = wtsvec.Columns.Count
nr = wtsvec.Rows.Count
If nc > nr Then wtsvec = Application.Transpose(wtsvec)
v1 = Application.MMult(vcvmat, wtsvec)
PFVariance = Application.SumProduct(v1, wtsvec)
End Function

這個函數既有向量形式的輸入變數,又有矩陣形式的輸入變數,這就要求 VBA 代碼先


要檢測矩陣相乘的一致性。我們希望不管權重陣列是行向量還是列向量,函數都能正常工
作。這就需要考慮陣列的維數了。與權重陣列 wtsvec 有關的變數 nr 和 nc(分別代表陣列
的行數和列數)被聲明為整數型。為了使矩陣相乘能夠正常執行,權重向量必須是一個列向
量,因此有語句:
If nc > nr Then wtsvec = Application.Transpose(wtsvec)
在矩陣相乘時使用了一個臨時變數 v1,它在前面聲明為 Variant 型變數。3.4.1 節曾經
提到過,這是一個非常靈活的資料類型,可以存儲任何形式的資料,標量、陣列或矩陣。在
T
這裏 v1 存儲的是一個 3×1 的列向量 Vw。在 VBA 中一個能很方便地計算 w Vw 的方法是使

用 SUMPRODUCT 函數,它將兩個 3×1 列向量 w 和 Vw 中的元素分別相乘再相加。因此倒


數第二條語句:
PFVariance = Application.SumProduct(v1, wtsvec)
返回一個標量給 PFVariance。
PFVariance 函數代碼的重點在於確保 Excel 函數 MMULT 能夠正常計算。由於函數的
參數是用戶輸入的,因此必須編寫代碼來調整這些輸入,以確保矩陣相乘的一致性。但是,
由於 MMULT 函數和 SUMPRODUCT 函數處理的都是陣列計算,因此沒有必要在代碼中為
陣列 v1 定義維數,或操作單個元素。這使得代碼顯得相對簡單一些。
雖然工作表演示的是一個由三種資產組成的組合,但這兩個函數實際上可以處理任何大
小的陣列。

4.7 輸出陣列形式的函數

前面提到的所有函數都是將返回值傳遞給單個單格(也就是標量輸出)。有時,我們希
望函數能返回一組資料,就像 LINEST 函數那樣,它為一組有 k 個解釋變數的資料集返回一
個 5×(k+1)的回歸結果陣列。一般來說,編寫帶有陣列輸出的函數是有困難的,因為它
需要正確地配置和構建陣列。另外,用戶還需要線索來為公式的輸出選擇適當大小的區域。
函數名稱可以用來暗示函數返回的是向量還是矩陣,並且,在函數列表的函數描述欄可以提
供輸出結果的維數。在代碼中,變數名和定義的變數類型可以用來暗示是否需要對單個元素
進行處理。
這種方法可以用一個計算匯總統計量的例子來演示:顯示一個資料集的百分比分佈。其
目的是用一個函數返回向量或矩陣形式的計算結果。
假設資料集由許多價格資料組成,命名為 dvec,如圖 4.5 第一列所示。注意,圖中只
顯示了 120 個資料中的 12 個資料。
如果低於某一價格的元素個數占總數的 10%,20%,30%...,則這個價格被稱為資料
集分佈的十分位元數。它們只是百分位累積分佈的一個特例。就像資料集 dvec 的均值可以
用一個 Excel 函數計算一樣,我們也可以用 PERCENTILE 函數計算出不同的百分位數。加
上 0%的十分位數(即最小價格) ,總共有 11 個十分位數值。圖 4.5 顯示了這些十分位元數
以及它們對應的百分比。在作圖時,這個 11×2 的陣列就可以用來顯示資料的累積分佈情況
了。現在,我們的目的是編寫一個函數來返回一個 11×2 的數值矩陣。

Data for Summary:需要匯總的資料

【參照書中第 84 頁的圖 4.5】

圖 4.5 DecilesMat 函數計算出的統計值

函數 DecilesMat(dvec)的代碼如下。由於我們已經知道陣列的維數,因此在定義陣
列時,可以直接給出它的維數(Dim decmat(11,2))
。第一列存放用 Excel 函數 PERCENTILE
計算出的十分位數值;而第二列存放對應的百分比,0%、10%、20%等。
Option Base 1

Function DecilesMat(dvec)
' returns 11 by 2 array of deciles ready for X-Y plot
Dim i As Integer
Dim decmat(11, 2) As Variant 'output array
For i = 0 To 10
decmat(i + 1, 1) = Application.Percentile(dvec, 0.1 * i)
decmat(i + 1, 2) = 0.1 * i
Next i
DecilesMat = decmat
End Function

使用該函數時,先選中一個 11×2 的單格區域,然後鍵入陣列公式,或者通過函數列表


來輸入函數以及所需的資料集,最後按下組合鍵 Ctrl+Shift+Enter。

4.8 在用戶定義函數中調用 Excel 和 VBA 函數

我 們 已 經 看 到 , 可 以 在 VBA 代 碼 中 調 用 標 準 的 Excel 函 數 , 如 COUNT 和


SUMPRODUCT 等,只需在函數名前加上首碼 Application.或 WorksheetFunction.即可。目
前,我們還可以通過 Excel Visual Basic 幫助來得到‘可用於 Visual Basic 的 Worksheet
函數列表’。但是在最近的 Excel 升級版本中,調用 Excel 函數被證明是不牢靠的。還有一
點,儘管大部分 Excel 函數可以在 VBA 代碼中被調用,但並不是所有的標準函數都可以使
用。不過,調用 Excel 函數不僅可以鞏固用戶的 Excel 知識,也可以減少編寫函數的工作量。
另外,VBA 也提供了一系列的標準函數,它們的用法將在下面的章節時作簡單介紹。

4.8.1 在用戶定義函數中使用 VBA 函數

使用 VBA 函數時不需要任何首碼,如 MsgBox、InputBox 等等。有少量的 Excel 函數


可以用標準 VBA 函數代替,如 Excel 函數 SQRT 可以用 VBA 函數 Sqr 代替。並且要牢記,
在編寫函數時,必須用 VBA 函數而不要用功能相同的 Excel 函數。
VBA 也有一些數學函數:Abs、Atn,Cos,Exp,Log,Randomize,Rnd,Sgn,Sin,
Sqr 和 Tan。在 VB 編輯器的物件流覽器的 Math 模組中可以找到這些函數。除了
Randomize,其他的數學函數都有相應 Excel 函數,但對應的 Excel 函數的名稱是不同的,
它們分別是 ATAN、LN、RAND、SIGN 和 SQRT。
VBA 中還有一些‘轉換’函數:其中比較有用的有 Fix、Hex、Int 和 Oct。用小寫字母
輸入函數名時,如果 VBA 認識這個函數,它會自動地把函數名變成大寫。
總之,在 Excel 函數和 VBA 函數都可用的情況下,必須優先選擇 VBA 函數。它們在使
用時不需要加 Application.首碼。

4.8.2 增益集

分析工具庫(ATP)中包含了一些附加的函數,如 COUPDAYS、LCM 和 MULTINOMIAL


等,它是 Excel 的增益集。如果工具
工具功能表中沒有資料分析
工具 資料分析選項(見
資料分析 2.9 節),則必須先安
裝分析工具庫
分析工具庫。安裝之後,就可以在函數列表中看到大寫的
分析工具庫 ATP 函數名了。
要想在 VBA 模組頁中使用 ATP 函數,必須先做兩件事:
1. 在 Excel 中,用工具
工具功能表中的增益集
工具 增益集來安裝分析工具庫
增益集 分析工具庫-
分析工具庫 -VBA 函數函數。VBA
等價函數會以複件的形式出現在函數列表中,儘管名稱是大小字母混合的。
2. 在 VBE 中,調用工具
工具功能表中的引用
工具 引用選項來連接
引用 ATPVBAEN.xla 文件。
(這個
檔在步驟 1 中被載入。)現在,在 VBA 代碼中,可以象使用標準 VBA 函數一
樣使用 ATP 函數(也就是不需要 Application.首碼)。沒有這個引用,VBA 就不
能認出這些函數。

4.9 編寫 VBA 函數的優缺點

關於編寫 VBA 函數來進行工作表計算的優缺點,應該注意以下幾點。

優點:
優點:
相對於工作表計算和複雜的單格公式,函數的優點在於可以將大量的計算壓縮到一個單
格中。如果編碼正確並且函數名容易理解,用戶定義的函數可以為單個單格帶來相當強大的
功能。在單格中輸入函數比輸入複雜公式出錯的可能性要小。如果函數名和參數名都很清晰
易懂,那麼對於半熟練的用戶來說,使用它們比使用複雜的公式更容易一些。要想增強用戶
對使用函數的信心,最重要的一點是,必須對 VBA 代碼作清晰的注釋。
函數還有方便移植的優點,所有能訪問到它們的 VBA 代碼的工作簿中,都可以使用它
們。將工作簿 A 中的函數移植到工作簿 B 中的最佳辦法是:將 A 模組(如 ModuleA1)中
的代碼拷貝到 B 的模組(如 ModuleB1)中。注意,只需在 ModuleA1 中用常用的拷貝粘貼
方法將代碼複製到 ModuleB1 中即可。不需要從工程資源管理器視窗中‘導出’模組頁。為
了方便移植,最好將相關的函數放在同一個模組頁中,例如,VBFNS 工作簿的 ModuleB1
頁中包含了所有與布萊克-舒爾斯有關的函數。
函數也可以擴展(例如,為三種資產編寫的函數可以擴展到處理任何數量的資產)。為
了更加靈活方面,有些函數也可以合併起來(例如,在 BSOptValue 函數中增加一個 iopt
參數就可以同時計算看漲期權和看跌期權的價格) 。
有時,函數的存在意味著不必在工作表中建立複雜的結構。例如,如果將二叉樹的層次
作為函數的一個參數,就沒有必要為不同的層次複製二叉樹結構。 (見附錄 4B 用二叉樹方
法為期權定價的函數。)

缺點:
缺點:
有些人認為使用 VBA 編碼語言是用戶定義函數的一大缺點。但需要強調的是,編寫函
數只需要熟悉 VBA 的一個小子集。編程所需的句法和控制語句本質上是程式設計的基礎。
這是傳統的編程語言而不是 VBA 語言面向物件部分的內容。

函數不可能完成的任務
有些操作不能寫成函數。在 VBA 中重寫程式列代碼,或者插入臨時的空工作表,或者
使用規劃求解來求解最優化問題,這些都不能寫成函數的形式。同樣,有些操作,如建立圖
表,或根據某些值改變單格的顏色等,都不易用函數來實現。
本章附錄 4A 用 Excel 矩陣函數演示了運算元組的一些方法。附錄 4B 介紹用二叉樹方
法為期權定價的函數。本章的最後是一些編寫函數的簡單練習,及簡要答案。

小結

編寫 VBA 函數要利用用戶的工作表知識以及 Excel 函數知識。也涉及到程式設計方面


的知識,但只是在一個直接並顯而易見的水準上利用。
相比操作物件的副程式而言,VBA 函數能夠返回資料,函數中的任何計算都以‘離表
( off-sheet ) ’ 的 方 式 執 行 。 函 數 與 副 程 式 的 一 個 關 鍵 區 別 在 於 , 函 數 是 ‘ 被 動 的
(passive)’,也就是說,函數中的代碼不能操縱單格區域。
許多 Excel 內嵌函數都可以在用戶定義函數中調用:在 VBA 代碼中,它們名稱前需要
加上首碼 Application.或 WorksheetFunction.。VBA 還提供一些自己的函數,這些函數在調
用時不需要加首碼,並且可以在物件流覽器中引用。
用戶定義函數帶有參數,它們可以是數值、單格輸入或陣列輸入。函數參數在 Function
語句中被隱式聲明,因此不需要再顯式聲明。而函數中使用到的所有其他變數都應該預先聲
明,並賦予適當的資料類型。
函數可以返回單個資料,也可以返回一組資料。通常,處理陣列輸入和陣列輸出的函數
會更難於編寫。
在工作表中,可以直接鍵入函數及參數,也可以用粘貼函數
粘貼函數按鈕來調用用戶定義函數。
粘貼函數
它們在函數列表的用戶定義類別中列出。可以寫一些簡單的文檔來描述函數的功能以及所需
的參數,這樣,當在函數列表對話方塊中訪問函數時,就會出現一些有用的幫助資訊。
對於複雜的函數,採用模組化的編程方法是很明智的,先建立一系列中間函數,然後一
個個測試。

附錄 4A 演示函數如何處理陣列

第一個例子,函數 ArrayDemo1,演示 Excel 矩陣相乘及矩陣求逆的使用方法。要使函


數正常運行,Amat1 和 Amat2 都必須是方陣,並且具有相同的維數。由於所有的矩陣操作
都是由 Excel 函數完成的,所以代碼很直接。Amat12 是兩個矩陣的乘積,它也是一個矩陣,
在開始時它被定義成 Variant 型,說明它的類型和維數都不確定:
Function ArrayDemo1(Amat1, Amat2)
' Uses the MMult and MInverse Array functions
Dim Amat12 As Variant
Amat12 = Application.MMult(Amat1, Amat2)
ArrayDemo1 = Application.MInverse(Amat12)
End Function

如果一個矩陣與向量相乘,就必須確保兩者的維數一致。如果 Amat1 是一個 3×3 的矩


陣,而 avec 是一個 3×1 的列向量,則相乘的結果是一個 3×1 的列向量。函數 ArrayDemo2
的輸入是 avec 和 Amat1,輸出結果是一個列向量:
Function ArrayDemo2(avec, Amat1)
'post multiplying matrix (Amat1) by col vector (avec)
ArrayDemo2 = Application.MMult(Amat1, avec)
End Function

如果向量轉置成行向量,它可以‘左乘以’矩陣 Amat1,但結果將是不同的,實際上,
結果是一個 1×3 的行向量。第三行應該改成:
ArrayDemo2 = Application.MMult(Application.Transpose(avec),Amat1)

通常,我們將函數寫成像 Excel 函數那樣的表現形式。也就是說,不管輸入的陣列是行


向量還是列向量,我們的函數能夠處理。而函數的輸出向量必須是一個行向量。函數
ArrayDemo3 返回一個行向量,而不管輸入的陣列 avec 是什麼形式(也就是不管 avec 是
行向量還是列向量) 。如果 avec 是一個列向量,則它的行數將超過它的列數,在這種條件
下,函數會將這個向量轉置成一個行向量。而如果 avec 是一個行向量,則不用處理。函數
ArrayDemo3 返回一個行向量,不管輸入的向量是何種形式:
Function ArrayDemo3(avec)
' returning a row vector, whatever the input
Dim nr As Integer, nc As Integer
nr = avec.Rows.Count
nc = avec.Columns.Count
If nr >= nc Then avec = Application.Transpose(avec)
ArrayDemo3 = avec
End Function

下一個函數,ArrayDemo4,演示怎樣用 VBA 代碼逐元素(element-by-element)地建


立陣列。這裏,要著重強調的是,構建的這些陣列在缺省情況下都是行向量。基於這個原因,
矩陣相乘要按下面代碼中的方式執行,並返回一個行向量:
Function ArrayDemo4(Amat1)
' VBA sets up array avec as row array
Dim avec(3) As Variant
avec(1) = 3
avec(2) = 4
avec(3) = 5
ArrayDemo4 = Application.MMult(avec, Amat1)
End Function

另外,如果倒數第二行的代碼改為:
ArrayDemo4 = Application.MMult(,Amat1,Application.Transpose(avec))
則會執行一個不同的矩陣相乘運算,並返回一個不同值的列向量。
模組頁開頭的 Option Base 1 語句確保陣列元素從 1 開始編號,就像 Excel 平常操作的
那樣。如果 Option Base 語句被忽略,則陣列元素從 0 開始編號(缺省情況) (那麼接下來
的矩陣相乘會由於維數不一致而失敗) 。這裏,Option Base 語句確保陣列 avec 中的元素只
有三個:avec(1)、avec(2)和 avec(3),而沒有元素 avec(0)。
當 Excel 中沒有合適的陣列函數來滿足陣列操作的需要時,那麼,在一個循環體內對陣
列中的每一個元素進行處理就變得不可避免了。這樣,必須先計算出陣列的元素個數,我們
使用 Application.Count(avec) 。
(對於用戶定義函數自身創建的陣列,元素個數可以用陣列
的 UBound(和 LBound)計算得到。)

附錄 4B 二叉樹期權定價函數

布萊克-舒爾斯公式給出了歐式看漲期權和看跌期權的價格。另外一種期權定價的替代
方法是二叉樹方法,它可以用於更廣泛的期權定價。這種方法在期權生存期內使用一系列概
率驅動的二叉分支(股票價格只有以確定的數量向上和向下運動兩種方式)來近似股票價格
的變動。這個二叉樹結構產生了一個股票價格樹,價格樹有一組的終端價格和一簇價格運動
路徑。對於樹的每一個節點,股票期權的價格都可以計算出來,並且使用樹的概率結構,期
權的收益可以通過折現來得到它的現值。

CRR Option Valuation:CRR 期權定價

【參照書中第 90 頁的圖 4.6】

圖 4.6 用 CRR 二叉樹方法計算期權價格


圖 4.6 中的工作表顯示了計算看漲期權價格的細節(在單格 G17 中使用布萊克-舒爾斯
函數 BSOptValue)
,以及一個九期二叉樹的組成部分。期權的生存期(T = 0.5 年)被分成
九個期間,每個期間的長度為 δ t (這裏是 0.0556 年)。現在的目的是編寫另一個期權定價函
數,是基於二叉樹定價方法的期權定價函數。要理解 VBA 代碼,首先應該理解二叉樹是如
何定價的,因此現在需要暫時脫離主題,來瞭解一下這種方法的工作原理。
每一期計算都需要用到股票價格向上和向下運動的乘數(u 和 d)以及相應的概率 p 和

p* ,稱為考克斯,羅斯和魯賓斯坦(CRR)參數。參數的計算公式能夠保證股票的價格樹

與一個幾何擴散過程一致,該過程可以認為是股票價格運動的真實過程。關於 u、d、p 和 p*

的公式這裏不必考慮,這些公式用於計算起始價格以及所有九期價格時,會生成圖 4.7 所示
的股票價格樹。

Binomial Tree Valuation:二叉樹定價


Share:股票

【參照書中第 90 頁的圖 4.7】

圖 4.7 使用 CRR 參數計算的九期股票價格樹

從價格 100 開始,第一期有兩種可能的價格,分別是 104.83(100u)和 95.40(100d)。經


i 9 −i
過九期運動之後,一支向上運動了 i 次(向下運動了(9-i)次)的股票價格為 100u d ,

或者對於 n 級樹:

Sin = Su i d n −i
這使得到期日的期權有 10 種收益,如圖 4.8 中的單格區域 K49:K58 所示,它們可以用
下面的公式計算得到:

max[ Si − X , 0] for i=0,1,…,9 and S=100,X=95

例如,對於就此向上運動的股票,期權價格為:

max[100(1.048)9 − 95, 0] = 57.85


最後一步操作是對向量單格 K49:K58 中的資料定價,將它們分別乘以它們發生的概
率,然後折現到 0 時刻。這步操作需要對終期期權收益作‘倒推’處理,使用向上運動和
向下運動的概率,p 和 p*,並折現得到第 8 期中的資料,依此類推,直到得到它們的當前

值。例如,在第 8 級,單格 J50 中的期權價格為 [57.85 p + 44.09 p*] /1.0045 = 50.99 。每

一期的計算結果都顯示在圖 4.8 中,因此通過二叉樹定價方法計算出的最終期權價格顯示在


單格 B58 中(結果為 9.63,而布萊克-舒爾斯公式的計算結果為 9.73)。
Option Value:期權價值

【參照書中第 91 頁的圖 4.8】

圖 4.8 倒推並折現期權價格

如下面顯示,BinOptVal 函數的 VBA 代碼以 CRR 樹為基礎。嚴格地說,模組頁開頭的


Option Basic 0 語句是不必要的。它只是用來強調在這個函數中,所有的陣列元素都是從 0
開始編號的。函數有八個參數,包括 nstep,這個參數代表二叉樹的級數。函數返回一份歐
式期權的價格(iopt=1 時計算看漲期權的價格,iopt=-1 時計算看跌期權的價格) 。在本節的
最後我們會明白,很容易對這個函數進行擴展,使它能夠同時計算美式期權的價格:
Option Base 0

Function BinOptVal(iopt, iea, S, X, r, q, tyr, sigma, nstep)


' Returns Binomial Option Value (iopt = 1 for call, -1 for put;
' iea=1 for euro, 2 for amer)

Dim delt, erdt, ermqdt, u, d, P, pstar


Dim i As Integer, j As Integer
Dim vvec As Variant ' to be a vector
ReDim vvec(nstep) ' known size of vector

' calculate parameters


delt = tyr / nstep ' length of time step
erdt = Exp(r * delt) ' compounding factor
ermqdt = Exp((r - q) * delt) ' dividend effect
u = Exp(sigma * Sqr(delt)) ' up multiplier
d=1/u ' down multiplier
P = (ermqdt - d) / (u - d) ' up prob
pstar = 1 - P ' down prob

'calculating vector of option values after 9 steps


For i = 0 To nstep
vvec(i) = Application.Max(iopt * (S * (u ^ i) * (d ^ (nstep - i)) - X), 0)
Next i
'calculating conditional payoffs & discounting back step by step
For j = nstep - 1 To 0 Step -1
For i = 0 To j
vvec(i) = (P * vvec(i + 1) + pstar * vvec(i)) / erdt
Next i
Next j
BinOptVal = vvec(0)
End Function

定價過程的重點在於向量陣列 vvec(),它被定義成 Variant 類型。在 nstep=9 時,vvec()


有 10 個值,vvec(0)到 vvec(9),並使用語句 ReDim vvec(9)定義維數,要想該語句在各級
通用,可以寫成 vvec(nstep)。
定義完變數之後,開始對 CRR 二叉樹向上和向下運動的參數賦值。對於圖 4.6 中所示
的看漲期權,vvec()的初始值為:vvec(0)=57.85,vvec(1)=44.09,…,vvec(9)=0,它們其
實就是圖 4.8 的 K49:K58 中顯示的期權收益。在 VBA 代碼中,這些值用下面的公式計算得
到:

max[ S (u i d ( nstep −i ) ) − X , 0] i = 0,1, 2,..., nstep


生成 vvec()陣列初始值的語句為:
For i = 0 To nstep
vvec(i) = Application.Max(iopt * (S * (u ^ i) * (d ^ (nstep - i)) - X), 0)
Next i

接下來的五行代碼沿著樹形結構向後倒推、計算價格並折現:
For j = nstep - 1 To 0 Step -1
For i = 0 To j
vvec(i) = (P * vvec(i + 1) + pstar * vvec(i)) / erdt
Next i
Next j

檢查代碼,在每一個倒推步中(j 的值) ,vvec()陣列中的值被重新計算,並用計算出來


的新價格取代原來的期權價格。這樣做有一個好處,只需要能夠存儲一個(n+1)向量的有
限存儲空間即可。這樣在九期二叉樹中,當 j=8 時,vvec()被重新計算,結果變為:
vvec(0)=50.99,vvec(1)=37.89 等等,而在最後,當 j=0 時,vvec(0)變為 9.63。
(作為對比,
在工作表中,從第 9 期向第 0 期倒推,需要我們顯示 10 個向量的值,如圖 4.8 所示)。因
此,當 j=0 時,期權的即期價格就放在 vvec(0)中。
如單格 G15 所示,使用這個函數用九期二叉樹來計算看漲期權的價格,我們有:
BinOptVal(1,100,95,8%,3%,0.5,20%,9)
其返回值為 9.63。一般來說,當分的期數越多時,計算出的二叉樹期權價格與布萊克-
舒爾斯價格會越接近。例如,BinOptVal(1,100,95,8%,3%,0.5,20%,50)的返回值是 9.74。要
驗證這一點,可以先構建一個資料表,然後使用不同的期數來計算結果。
圖 4.6,4.7,4.8 中顯示的是一個看漲期權的二叉樹定價情況。如果期權是一個看跌期
權,則需要將輸入參數 iopt 改為 iopt=-1,並且將生成 vvec()陣列初始值的語句變為:
For i = 0 To nstep
vvec(i) = Application.Max(-1 * (S * (u ^ i) * (d ^ (nstep - i)) - X), 0)
Next i
它給出了看跌期權的終期收益。驗證一個看跌期權的計算結果:
= BinOptVal(-1,100,95,8%,3%,0.5,20%,9)
其結果為 2.40,而布萊克-舒爾斯價格為 2.49。
美式期權與歐式期權唯一的區別在於它可以提前執行,也就是說,它可以在期權到期之
前執行。但是對美式看漲期權來說,提前執行期權永遠是不值的(在沒有股利的情況下) ,
因此它們的定價與歐式期權完全一樣。但是,對於美式看跌期權來說,提前執行有時比持有
期權更具價值。為了在定價函數 BinOptVal 中調整 VBA 代碼,我們可以增加一個輸入參數
(iea=1 表示計算歐式期權,iea=2 表示計算美式期權),然後增加一條代碼:
'for Amer options, allowing for early exercise at each step
If iea = 2 Then vvec(i) = Application.Max(vvec(i), iopt * (S * (u ^ i) * (d ^ (j - i)) - X))

則合併後的整個二叉樹定價函數代碼如下,它可以用來計算歐式期權以及美式期權的價
格:
Function BinOptVal(iopt, iea, S, X, r, q, tyr, sigma, nstep)
' Returns Binomial Option Value (iopt = 1 for call, -1 for put;
' iea=1 for euro, 2 for amer)

Dim delt, erdt, ermqdt, u, d, P, pstar


Dim i As Integer, j As Integer
Dim vvec As Variant ' to be a vector
ReDim vvec(nstep) ' known size of vector

' calculate parameters


delt = tyr / nstep ' length of time step
erdt = Exp(r * delt) ' compounding factor
ermqdt = Exp((r - q) * delt) ' dividend effect
u = Exp(sigma * Sqr(delt)) ' up multiplier
d=1/u ' down multiplier
P = (ermqdt - d) / (u - d) ' up prob
pstar = 1 - P ' down prob

'calculating vector of option values after 9 steps


For i = 0 To nstep
vvec(i) = Application.Max(iopt * (S * (u ^ i) * (d ^ (nstep - i)) - X), 0)
Next i
'calculating conditional payoffs & discounting back step by step
For j = nstep - 1 To 0 Step -1
For i = 0 To j
vvec(i) = (P * vvec(i + 1) + pstar * vvec(i)) / erdt

'for Amer options, allowing for early exercise at each step


If iea = 2 Then vvec(i) = Application.Max(vvec(i), iopt * (S * (u ^ i) * (d ^ (j
- i)) - X))
Next i
Next j

BinOptVal = vvec(0)
End Function
前面計算出來的歐式看跌期權價格為 2.40,而採用九期二叉樹計算出來的美式看跌期
權的價格為 2.54。

編寫函數練習

1. 金融算術函數
編寫如下簡單金融計算函數:
i. FutrueValue(P,r,n,t),該函數返回投資 P 在 t 年後的未來價值,假設收益年利率為
r,一年計算 n 次複利。
ii. AnnPercentRate(rf,f)函數,該函數返回年利率為 rf,一年計算 f 次複利的實際利率。
iii. APRCont(r)函數,該函數返回連續複利為 r 的實際年利率。

2. 和與積和函數
編寫一個求和函數,該函數的功能與 Excel 函數 SUM 相同,用來將一個陣列中的數值
加總。
編寫一個求積和函數,模仿 Excel 函數 SUMPRODUCT(array1,array2),它用來計算兩
個陣列的元素乘積之和。在兩個陣列大小不一致時,返回錯誤資訊。

3. 淨現值函數
編寫一個函數 NetPV(cvec,rate),功能與 Excel 函數 NPV 相同,該函數需要兩個參數,
第一個參數是現金流陣列,第二個參數是折現率。

4. 現金流標準差函數
編寫一個函數,用來計算不同權重(pvec)的一組現金流(vvec)的標準差,如 4.5
節中討論的那樣。記住,要使用 VBA 的內嵌函數 Sqr,而不能使用 Excel 函數。

5. 回收期函數
工作表中顯示了一項投資計畫在未來五年的現金流。現金流初值是負的,而在第三年
裏,累積現金流變為正號,這個時刻被稱為工程的回收期(在這裏是 2.4 年) 。
決定回收期的中間計算已顯示在表中。其重點在於計算每年的累積現金流,以及判斷累
積現金流首次變為正數的時刻。編寫一個回收期函數 PayBack(cvec),它返回任何現金流陣
列的回收期。

【參照書中第 95 頁的圖】

練習答案
1. 金融算術函數代碼
Function FutureValue(P, r, n, t)
'returns future value of P, compounded at annual rate r,
'n times a year, for t years
FutureValue = P * (1 + r / n) ^ (n * t)
End Function

Function AnnPercentRate(rf, f)
'returns annual effective rate of compounding at rate rf, f times p.a.
Dim APR
APR = (1 + rf) ^ f - 1
AnnPercentRate = APR
End Function

Function APRCont(r)
'returns annual effective rate of compounding continuously at rate r p.a.
APRCont = Exp(r) - 1
End Function

2. 和與積和函數代碼
陣列求和:
Option Base 1

Function SumArray(avec)
'VBA version of Excel's SUM function
Dim n As Integer: Dim i As Integer
Dim total
n = Application.Count(avec) 'counts all elements in array
total = 0
For i = 1 To n
total = total + avec(i)
Next i
SumArray = total
End Function

陣列求積和:
Option Base 1

Function ProdArray(xvec, yvec)


'VBA version of Excel's SUMPRODUCT function
Dim i As Integer, j As Integer
Dim imax As Integer, jmax As Integer
imax = Application.CountA(xvec) 'counts all elements in 1st array
jmax = Application.CountA(yvec) 'counts all elements in 2nd array
If imax = jmax Then
ProdArray = 0
For i = 1 To imax
If Application.IsNumber(xvec(i)) And Application.IsNumber(yvec(i)) Then _
ProdArray = ProdArray + xvec(i) * yvec(i)
Next i
Else: ProdArray = "Counts don't match"
End If

ProdArray = ProdArray
End Function

3. 淨現值函數代碼
Option Base 1

Function NetPV(cflowvec, rate)


Dim i As Integer
NetPV = 0
For i = 1 To Application.Count(cflowvec)
NetPV = NetPV + cflowvec(i) / (1 + rate) ^ (i - 1)
Next i
NetPV = NetPV
End Function

4. 現金流標準差函數代碼
Option Base 1

Function StdDev(vvec, pvec)


Dim Var
If Application.Sum(pvec) <> 1 Or _
Application.Count(vvec) <> Application.Count(pvec) Then
StdDev = -1
Exit Function

'ElseIf pvec.Rows.Count <> vvec.Rows.Count Then vvec = Application.Transpose(vvec)


End If
Var = WVariance(vvec, pvec)
StdDev = Sqr(Var) 'Sqr(arg1) is VBA Math Fn
StdDev = Application.Round(StdDev, 2) 'to 2 d.pl

End Function

5. 回收期函數代碼
函數代碼如下,注意用粗體顯示的三個特點。
第一,陣列 cvec 中的元素要求必須是數值。這裏,Option Base 1 語句確保陣列 cvec
中的元素從 1 開始編號,cvec 中的元素可以用 cvec(1)、cvec(2)引用,最後一個元素 cvec(6)
的值為 60。陣列中沒有元素 cvec(0)。
第二,在函數開頭,用 If…Then…Else 語句濾除了那些導致回收期無法計算的情況,
這使得函數更加穩健(Robust)。(例如,如果第一個現金流為正,cvec(1)>=0,或者整個
現金流的累積值為負,Application.Sum(cvec)<0,則函數返回-1)。
第三點,陣列 cvec 中的元素是逐個處理的,每個現金流被一一加總來得到累積現金流,
並用變數 csum 表示。這種操作在一個 For…Next 循環體中進行,在循環體中,隨著 i 的不
斷增加直到最大值(Application.Count(cvec))
,單個現金流也被一一加總。當變數 csum 變
為正的時候,程式跳出 For…Next 循環體(Exit For)並計算回收期。
需要關注一下到底是哪一個現金流導致累積現金流由負變正的。在這個例子中,當 i=4
時,csum 從-20 變為+35,csum 的最後一個負值-20 出現在第 2 年底。因此,確切的回收
期就是 2 年加上分數 20/55,也就是 2.4 年。

回收期函數的 VBA 代碼:


Option Base 1

Function PayBack(cvec)
' calculates payback period (no. of years to 1 d.pl)
' initial cashflow must be negative
Dim csum
Dim i As Integer
If cvec(1) >= 0 Or Application.Sum(cvec) < 0 Then
PayBack = -1
Else
csum = 0
For i = 1 To Application.Count(cvec)
csum = csum + cvec(i)
If csum > 0 Then
Exit For
End If
Next i
csum = csum - cvec(i)
PayBack = Application.Round(i - 2 - csum / cvec(i), 1)
End If
End Function
第 5 章 股票的有關簡介

本書的第二部分主要介紹股票方面的相關內容。以下三章將分別介紹幾個不同的主題:
第 6 章介紹投資組合的最優化,第 7 章主要涉及資產定價,第 8 章則主要研究如何進行業
績評價。本章作為第二部分的簡介,扼要地總結了在本書的股票部分所涉及的相關金融理
論,以及在試算表中用到的定量數學方法。
在二十世紀五十年代,哈裏·馬可維茨創立了投資組合的均值-方差理論。從此以後,
金融學開始從經濟學中分離出來,成為一門新的學科。但它與經濟學仍有很大的聯繫。馬可
維茨指出,單只股票的自身風險與它對投資組合整體風險的貢獻是有很大區別的。投資組合
均值—方差理論的一個重要特點是,它認為收益和風險的關係與均值和方差的關係是一致
的。在收益服從正態分佈的假設條件下,金融理論可以用許多經典的統計分析方法來研究。
隨後,在二十世紀六十年代創立了資本資產定價模型 CAPM。它是股票期望收益的單因素
模型,其中引入的β值是衡量投資組合風險的重要指標。在 CAPM 模型的基礎上,又提出
了許多評價投資組合業績的方法。此後,對 CAPM 模型的研究主要集中在資產收益的多因
數模型上,其中最新的成果就是夏普于九十年代初提出的風格分析(Style Analysis) 。下面
三章將要介紹的內容包括:風險和收益的表示方法,投資組合的風險和收益,有效邊界理論,
單因素模型,CAPM,傳統的資產業績評價方法,風格分析,以及風險值 VaR。
本書的第二部分,首先按年代順序介紹了股票投資組合管理方法的發展狀況,然後以三
個相關的工作簿(EQUITY1.xls,EQUITY2.xls 和 EQUITY3.xls)為基礎,演示了不同金融
領域中反復出現的一些重要思想。投資組合理論經常由於計算能力的不足而受到制約。到了
今天,在 Excel 和高性能電腦的幫助下,這方面的制約已經基本不存在了(儘管有些應用只
涉及到少量的資產,而不是上千種股票) 。
以下三章中用到的最主要計算方法是一種最優化方法,即‘二次規劃’。這種方法可以
用 Excel 的規劃求解插件來實現。本文將介紹如何構建各種不同的投資組合最優化問題,並
正確地使用規劃求解來得到每種資產在整個組合中的最優權重。為了方便在第 6 章推導有
效邊界和在第 8 章進行風格分析,本文將對二次規劃的相關計算原理和應用進行反復說明。
在股票部分的研究中,經常用到的第二種方法是回歸方法。第 7 章將介紹如何用 Excel 中的
回歸功能來估計 CAPM 模型中的β係數。一般來講,用來估計資產風險和收益的許多計算,
都可以用 Excel 的統計計算功能來實現。第 6 章和第 8 章中還介紹了如何應用 VBA 宏來自
動調用規劃求解,從而更方便有效地生成各種圖表。
三個工作簿(EQUITY1.xls,EQUITY2.xls 和 EQUITY3.xls)中均包括需要用二次規劃
來解決的最優化問題,它們是:投資組合風險(邊界組合) ,殘差平方和(β估計值)和誤
差方差(風格分析) 。雖然有些簡單的問題可能有解析解,但作為一個基本方法,最優化問
題通常是通過一個反復迭代的尋找過程來找到最優解。在 Excel 中,這個尋找過程是由規劃
求解插件來實現的。規劃求解的使用方法將在 EQUITY1.xls 中的 EF2 表和 EQUITY3.xls 的
Style 表中進行詳細介紹。
本部分的股票建模技術不僅對股票本身具有重要意義,而且也為本書的第三部分(股票
期權估價)作了鋪墊。
第 6 章 投資組合最優化

本章研究個體投資者如何解決投資組合的最優化問題。所需的背景知識和許多實例可參
考 Bodie et al 的著作(1996,第六章和第七章)
。這裏,將集中討論如何利用試算表來進行
相關計算,並進一步研究常見的組合問題類型。在確定各類風險資產的權重時,主要使用了
Excel 裏的規劃求解,而對於常見的組合問題,還需要分析資金應如何分配在無風險資產和
風險資產上,此時更傾向於使用根據試算表相關公式設計出來的用戶定義函數。第 6.1 和
6.2 節主要介紹有關風險資產組合的預備知識。第 6.3 到 6.5 節集中介紹如何確定投資組合
中各類資產的最優權重。第 6.6 節介紹風險厭惡的概念以及如何權衡風險與收益。接下來的
第 6.7 節到 6.9 節,主要介紹如何使用試算表來解決常見的組合問題。在本章的練習部分還
詳細介紹了為分析投資組合而設計的用戶定義函數和巨集,見 EQUITY1.xls。

6.1 組合的均值和方差

所有的金融教科書都對投資組合的均值—方差模型進行過詳盡的描述和解釋(如 Bodie
。馬可維茨的工作大大簡化了投資
et al,1996,第七章介紹了風險投資組合的最優化問題)
組合的最優化問題。他指出,在最優化過程中,應該先找到均值-方差的有效投資組合,這
些組合就是那些在給定風險水準的情況下期望收益最高的有效點。這裏,風險用投資組合的
方差來度量(更嚴格地講,應該是方差平方根,即投資組合收益的標準差)。在對一組資產
建立組合分析模型時,應主要考慮以下兩點:
1) 投資組合收益的均值和方差;
2) 用風險-收益空間上的座標點來表示的投資組合;
在本文的研究中,自始至終都假設投資組合處於完全投資狀態,即對權重加上約束條
件——所有資產的投資權重之和必須為 100%。
給定一組風險資產及其相應權重,就可以確定一個投資組合。對於 n 種風險資產,有
如下的一般公式:

投資組合收益: E ( rp ) = ∑ w E (r )
i i

投資組合方差: Var ( rp ) = σ p =
2
∑∑ w w
i j cov(i, j ) ,其中 cov(i, i ) = σ i 2
其中 E(ri)代表第 i 種資產的期望收益,σi 代表第 i 種資產的風險(其收益的標準差)。
而元素 cov(i,j)則組成了通常所說的資產收益方差—協方差矩陣。從上面的公式可以看出,
組合的方差是組合中各資產權重的二次函數。投資組合的風險用它的標準差來度量。
在使用試算表時,採用那些便於輸入的投資組合收益和方差運算式會很有好處。鑒於上
面列出的求和公式非常不方便輸入到表格中,這裏採用兩種可供選擇的方法:(i)以 Excel
向量和矩陣乘法為基礎的單格公式; (ii)工作表中的用戶定義函數。
首先來看單格的計算公式,如果期望收益和投資組合的權重都用列向量形式來表示(分
別用 e 和 w 表示,行向量則對列向量進行轉置,即 eT 和 wT),方差—協方差用矩陣 V 表示,
那麼原來的公式就可以改寫成如下所示的簡單矩陣公式。Excel 陣列函數可以很容易地計算
出這些公式的結果。
矩陣表示 用 Excel 公式表示

投資組合收益: wT e = SUMPRODUCT ( w, e)

投資組合方差: wTVw = MMULT (TRANSPOSE ( w), MMULT (V , w))


圖 6.1 演示了對三種資產(國庫券、債券和股票)進行的上述計算。表中數據代表 1926
年到 1992 年三種資產的表現。這些資料是以年百分比收益資料為基礎,並應用 Excel 的
STDEV 和 AVERAGE 函數計算得到的。投資組合在三種資產間是這樣分配權重的:
40%:50%:10%。如果期望收益(C5:C7)和權重(I10:I12)的向量名分別為 e 和 w,方差—
協方差矩陣(C15:E17)為 V,那麼通過上面的 Excel 公式就可以計算出投資組合的收益和
方差。因此,權重分別為 40%:50%:10%的投資組合的期望收益為 2.2%(單格 I15) ,風險
為 7.0%(單格 I16),後者是由方差 0.0049(單格 I18)開方得到。

Risk&return with three assets:資產組合的風險和收益(由三種資產組成);


Asset Data:資產數據
Correlation Matrix:相關係數矩陣
VCV matrix:VCV 矩陣
Portfolio weights:組合權重

【參照書中第 104 頁的圖 6.1】

圖 6.1 計算包括三種資產投資組合的風險和收益

計算中使用的輸入資料包括這三種資產收益的方差—協方差矩陣。矩陣的元素由資產收
益之間的相關係數(單格 C10:E12)和標準差(D5:D7)計算得到。注意,圖 6.1 中求方差—
協方差矩陣中每個元素的一般公式如下:

= C11*VLOOKUP (C $14,$ B$5 : $ D$7, 3, FALSE ) *VLOOKUP ($ B16,$ B5 : $ D$7,3, FALSE )


上式計算的是國庫券和債券的協方差;與之對應的相關係數可以在單格 C11 中找到,
相應的標準差(國庫券和債券)可以在區域 B5:D7 中找到。
計算投資組合風險和方差的第二種方法是用 VBA 編寫用戶定義函數。假設期望收益和
組合權重向量分別用變數 retvec 和 wtsvec 表示,方差—協方差矩陣用 vcvmat 表示,於是
可 以 創 建 兩 個 名 稱 分 別 為 PortfolioReturn ( RETVEC , wtsvec ) 和 PortfolioVariance
(wtsvec,vcvmat)的函數,用來分別計算所需的風險和方差。投資組合的風險就是
PortfolioVariance 函數計算結果的平方根。在 Module1 中的用戶定義函數部分介紹了上述
函數的具體程式。對於那些不熟悉 Excel 矩陣函數的人來說,使用用戶定義函數比輸入單格
公式更為簡潔。
在第 6.2 到 6.5 節中,將以三種資產為例進一步解釋均值-方差投資組合理論,並且,
該理論可以很容易地推廣應用到多種資產的情況。
6.2 組合的風險-
組合的風險-收益表示

研究股票最重要的主題就是收益和風險。從圖 6.2 中可以清楚地看出,投資組合可以這


樣表示:在座標平面上,x 軸代表風險,y 軸代表收益。圖中顯示了三種單個資產及其組合
的所有可能位置。例如,風險最高的資產——股票,其位置在圖的右上角(風險=20.8%,
收益=9.0%) ,而國庫券的位置則靠近原點(風險=4.3%,收益=0.6%)
。在圖 6.1 所示的
投資組合中,其主要的組成部分是國庫券和債券(也有一部分股票),它在圖 6.2 中用標籤
為‘Fig1 PF’的點表示。雖然這個特定投資組合的期望收益為 2.2%,但是在保證該期望收
益不變的情況下,微調不同資產的權重會得到一個風險最小的投資組合。風險最小的投資組
合也被稱為有效組合;所有代表有效組合的點組成的曲線即為有效邊界。因此,所有權重達
到最佳的投資組合均位於有效邊界上,此時,在給定的目標收益下,該投資組合的風險最小。
圖中,這些有效組合或邊界組合被標記為無約束邊界。應該注意到這條邊界包含一個唯一的
最小方差點,因此,它也代表最小方差投資組合。在這裏,投資組合的權重之和必須為 1,
但除此之外,沒有更進一步的條件限制,因此此處使用了術語‘無約束邊界’。

The Efficient Frontier:有效邊界;


Expected Return:期望收益;
Risk(Standard Deviation):風險(標準差)

【參照書中第 106 頁的圖 6.2】

圖 6.2 投資組合的風險-收益表示

在接下來的幾節中,將從確定有效邊界上的單個點入手,進而得到整個邊界。然後將對
投資者所持有的單個資產權重加上約束條件(這將會把整個投資組合的收益限制在一個較小
的範圍內),並計算出那些有約束邊界上的點。注意,可以肯定的是,有約束邊界上的點總
是在無約束邊界上或在其右側,儘管由於圖的大小有限,我們不能在圖上清楚地看到這一點。
如果單個資產的權重沒有額外的約束條件,我們可以通過黃和利曾伯格給出的公式
(1988,第 6.4 節)來得到有效投資組合。但由於用規劃求解來得到有效組合比較容易解
釋,所以,接下來將首先介紹這種方法,然後將其擴展到單個資產權重有約束的情況。最後
介紹得到整個有效邊界的方法。

6.3 用規劃求解得到有效點

資產的相關資料由圖 6.3 給定,要求得到目標收益為 7%的有效投資組合。此問題就是


要求出在目標收益為 7%的情況下,收益方差最小的投資組合中,各種資產的權重分配情
況。因為規劃求解中有許多為最優化問題設計的反復迭代搜尋方法,所以這個標準的最優化
問題用 Excel 中的規劃求解可以很容易得到答案。既然投資組合的方差是權重的二次函數,
我們將用規劃求解來解決這個二次規劃問題。
Using Solver to reproduce Unconstrained Frontier Portfolios:
利用規劃求解重新產生無約束有效邊界組合
Asset Data:資產數據
Correlation Matrix:相關係數矩陣
VCV matrix:VCV 矩陣
Frontier Portfolio weights:有效邊界組合權重
Ctrl+Shift+U to run Macro:按下組合鍵 Ctrl+Shift+U 可以運行巨集

【參照書中第 107 頁的圖 6.3】

圖 6.3 用於進行最優化的工作表 EF1(在 EQUITY1.XLS 中)

Eppeb et al(1998)已明確指出了具有什麼樣代數結構的問題可以用二次規劃來解決,
以及如何用 Excel 的規劃求解解決這些問題。因此,這裏將在圖 6.3 的基礎上,簡明扼要地
解釋如何使用規劃求解來解決這個投資組合問題。注意圖中的區域名稱,如 I11:I12 為
change1,I15 為 portret1,等等。
在用規劃求解進行計算時,需要輸入可變單格 可變單格、作為最小化前提的目標單格
可變單格 目標單格和規範的約
目標單格 約
束條件。這些約束條件用來控制可變單格的取值範圍。注意,要滿足完全投資情況下的約束
束條件
條件,只需在單格 I10 中輸入下面的公式即可:

= 1 − SUM ( I11: I12)


於是,為了實現最優化而設置的可變單格 可變單格就是
可變單格 I11:I12,用區域名稱來表示就是 change1。
需要最小化的目標單格 目標單格是收益的標準差(I16)
目標單格 ,命名為 portsd1。在這個問題中有一個明確
的約束,即期望收益(單格 I15,命名為 portret1)必須等於目標值(在單格 I5 中,命名為
。(注意:此處的區域名稱在確定規劃求解參數,以及以後編寫 VBA 宏的過程中有
target1)
著特殊作用。)
用規劃求解處理上述過程的步驟如下:
規劃求解-在功能表欄裏選擇工具
1.調用規劃求解
規劃求解 工具,接著選擇選項
工具 選項,點擊規劃求解
選項 規劃求解;
規劃求解
規劃求解參數對話方塊裏的相應參數:
2.指定規劃求解
規劃求解
需要最優化的目標單格
目標單格(I16)
目標單格
指定最大化或是最小化,並且指定可變單格
可變單格(I11:I12)
可變單格 ,如圖 6.4 所示;
添加來指定約束條件,然後點擊確定
3.點擊添加
添加 確定(如圖
確定 6.4 的右上方所示) ,這個約束條件
保證了 I15 必須等於目標值(單格 I5) ;
選項,確保沒有選中採用線性模型
4.點擊選項
選項 採用線性模型
5.計算並在工作表中得到相應結果。
【參照書中第 108 頁的圖 6.4】

圖 6.4 用規劃求解實現方差最小化

應用規劃求解進行計算的結果如圖 6.5 所示。從最優權重分配比例中可以看出,需要持


有權重為正的是債券和股票,國庫券的權重則為負。從單格 I15 可以得到,所求的有效組合
在保證目標收益為 7%的情況下,實現了 15.7%的最小標準差。改變單格 I5 中給出的目標
期望收益,再次調用規劃求解,並按照前面所描述的步驟進行操作,將會得到另一個有效組
合。(為了驗證這一點,讀者可以將 I5 中的目標收益從 7%改為 3%,接著調用規劃求解計
算得到新的投資組合權重。另一個練習是用來確定唯一的最小方差投資組合權重。如果去掉
如圖 6.4 所示的約束條件 portret1=target1,那麼規劃求解將給出期望收益為 0.7%、風險
為 4.1%情況下各種資產的權重。)
既然現在對單個資產的權重沒有其他約束條件,那麼權重為負是可以接受的,這代表該
資產被賣空。實際上,在圖 6.5 給出的例子中,期望收益為 7%的邊界組合中,國庫券的持
有比率為-5.6%。這意味著,為了構建該組合,必須借入數額為該組合價值一部分的資金,
並為此部分資金支付利息,這就沖銷了其他兩種資產所獲得的部分期望收益。

Using Solver to reproduce Unconstrained Frontier Portfolios:


利用規劃求解重新產生無約束有效邊界組合
Asset Data:資產數據
Correlation Matrix:相關係數矩陣
VCV matrix:VCV 矩陣
Frontier Portfolio weights:有效邊界組合權重
Ctrl+Shift+U to run Macro:按下組合鍵 Ctrl+Shift+U 可以運行巨集

【參照書中第 108 頁的圖 6.5】

圖 6.5 期望收益為 7%的無約束邊界組合

到現在為止,我們用最小化投資組合風險的方法得到了最優投資組合權重。同樣,我們
可以通過在某一給定風險水準下最大化投資組合收益的方法來確定投資組合的權重。這對使
用規劃求解來說好像是不同的問題,但用這種方法得到的最優權重,與前面最小化方差方法
得到的有效邊界投資組合的最優權重是一致的。

6.4 求有效邊界(
求有效邊界(黃和利曾伯格的方法)
黃和利曾伯格的方法)

對單個資產的權重不加任何限制時,有效邊界可以用數學方法推導出來。雖然一些更高
級的教科書(例如愛爾頓和格魯伯,1995) ,是通過反復迭代去求解一組聯立方程來得到有
效邊界,但有一種更加簡潔有效的方法。黃和利曾伯格(以下簡稱 HL)給出了如何找到有
效邊界上的兩個點,並在這兩個點的基礎上得到整個邊界(直接應用布萊克的結論) 。本節
將利用他們給出的代數方法,計算時會用矩陣加以解釋,並推廣到投資組合有多種(多於三
種)可選擇資產的情況。下面將介紹如何使用 Excel 的陣列函數在試算表中求出有效邊界。
本節涉及的內容難度較大,初學者可以暫時略過,在完全理解本章後面的章節之後再來學習
本節。
圖 6.6 中的表 EF1HL 很清楚地定義了區域名稱,使得單格中的公式更加容易理解。期
望收益向量(C5:C7)被命名為 e,權重向量(I5:I7)為 w,A24:A26 所表示的向量命名為
u。C15:E17 所代表的方差-協方差矩陣命名為 V。如同前面解釋的那樣,投資組合的方差
可以寫成矩陣乘積 wTVw 的形式,結果放在單格 I11 中。
用 HL 法尋找有效組合時,需要知道方差-協方差矩陣的逆,這裏記為 V-1。Excel 中專
門用來進行矩陣求逆的函數是 MINVERSE。在使用陣列函數時,需要在表中一個 3×3 的區
域 H15:J17 中輸入公式:

= MINVERSE (C15 : E17)


注意,對陣列函數而言,在選擇好單格區域並輸入正確的公式之後,必須按下組合鍵
Ctrl+Shift+Enter 來結束輸入。
(如果沒有出現陣列公式括弧{},可以按下 F2 鍵重試一次。)
為了得到兩個邊界組合(標記為 g 和 g+h) ,黃和利曾伯格首先計算出四個數值(A,B,C
和 D) 。前三個值,A,B 和 C 是由前面的幾個向量和矩陣計算得到,第四個值 D 則是用 A、
B、C 計算得到:

A = u TV −1e B = eT V −1e C = u T V −1u D = BC − A2


現在引入兩個臨時行向量 I=V-1e 和 m=V-1u,結果分別存儲在表中單格區域 C24:C26
和 D24:D26 中,則上面四個矩陣乘法的運算式可以簡化為:
A = u T I B = eT I C = u T m
單格 G23 中有計算 A 的簡單單格公式:=MMULT(TRANSPOSE(u),I),其中調用了陣
列函數 MMULT,因此計算 A 的公式必須作為一個陣列函數來輸入(輸入 B 和 C 的公式時
與 A 類似)
。因為 A、B、C 和 D 的計算結果都是一個數值而非向量或矩陣,所以只需要用
單個單格來儲存它們。

Using Algebra to reproduce Unconstrained Frontier Portfolios:


利用規劃求解重新產生無約束有效邊界組合
Asset Data:資產數據
Correlation Matrix:相關係數矩陣
VCV matrix:VCV 矩陣;VCV inverse:VCV 矩陣的逆;
Portfolio weights:組合權重
Finding weights,g and h,to generate points on the frontier:
尋找權重,g 和 h,從而生成有效邊界上的點;
Generating Frontier Portfolios,using g and h:
利用 g 和 h 生成有效邊界

【參照書中第 110 頁的圖 6.6】

圖 6.6 用黃和利曾伯格的方法直接得到解析解

為計算邊界組合 g(期望收益為 0%)和邊界組合 g+h(期望收益為 100%)中各種資


產的權重,只需計算如下所示的兩個公式:

g = [ Bm − AI ] D h = [CI − Am] D
在輸入計算 g 的公式時,需要先選擇一個 3×1 的列向量區域,因為這是一個陣列公式。
輸入計算 h 的公式時與 g 類似。圖 6.6 中的單格 I24:I26 和 K24:K26 給出了這兩個邊界組合
的權重。
於是向量 g(124%,-20.5%,-3.5%)給出了國庫券、債券和股票的權重,這些權
重確定了有效邊界上期望收益為 0%的投資組合。同樣,向量 g+h 給出了另一組國庫券、債
券和股票的權重,這些權重確定了有效邊界上期望收益為 100%的投資組合。把上面得到的
向量 g 和 h 進行線性組合 g+h*T,可以得到有效邊界上給定期望收益為 T 的投資組合權重。
例如,從圖 6.6 的 33 到 38 行可以看出,期望收益為 7%的投資組合中包含-5.6%的國庫券、
35.8%的債券和 69.8%的股票(單格 D36:D38)。也就是說,為構造期望收益為 7%的最小
風險投資組合,需要買進債券和股票,同時賣空國庫券。這些用 HL 方法得到的結果與圖
6.5 中在沒有其他權重約束情況下用規劃求解得到的結果是一致的。
邊界上的其他點可以用陣列函數 g+h*T 計算得到,其中 T 是該點的期望收益。用這種
方法可以得到整個有效邊界。例如,在 Excel 中,一個模擬運算表可以將一系列期望收益(從
0%到 10%)作為輸入,計算出相應的投資組合風險和收益,然後可以在此表的基礎上畫出
一個 XY(散點)圖。在圖 6.2 中可以看到,用‘無約束邊界’標記的所有點都來自於上述
的模擬運算表。
顯然,在試算表中為得到兩個有效組合權重所進行的計算非常複雜。這就是我們採用
VCA 用戶定義函數來簡化公式輸入的原因。第 6.10 節將演示黃和利曾伯格的計算是如何通
過編程來實現的。HLPortfolioWeights 函數有四個重要變數:expret,retvec,vcvmat 和 rf
(這裏是-1)。expret 是該有效邊界組合的期望收益,retvec 是期望收益向量,而 vcvmat
是方差-協方差矩陣。該函數可以得到投資組合的權重。在圖 6.6 中,用此用戶定義函數得
到的權重放在單格 E36:E38 中。

6.5 有約束邊界組合

如果給單個資產的權重加上一些約束條件(例如權重必須非負),此時解析方法就不再
適用了。但是,使用規劃求解仍可以得到最優權重。為了與前面的情況區別開來,這裏把這
種情況下得到的投資組合叫做‘有約束’邊界組合。圖 6.7 展示了從表 EF2 中摘錄的部分
資訊,從表中可以看出,可能的組合權重放在單格 H8:J8 中(命名為 portwts2)
,其上面一
行是所能允許的最小權重,下面一行則列出了所能允許的最大權重(分別命名為 portmin2
和 portmax2)
。用規劃求解可以解決上述約束條件下的邊界組合問題,具體的操作如圖 6.8
所示。

Using Solver to generate the constrained Frontier:


利用規劃求解生成有約束有效邊界
Asset Data:資產數據
Correlation Matrix:相關係數矩陣
VCV matrix:VCV 矩陣
Constraints on Frontier Portfolio weights:對有效邊界組合權重的約束
Ctrl+Shift+U to run Macro:按下組合鍵 Ctrl+Shift+U 可以運行巨集

【參照書中第 111 頁的圖 6.7】

圖 6.7 約束條件下的投資組合權重最優化-工作表 EF2


【參照書中第 112 頁的圖 6.8】

圖 6.8 權重有約束時的規劃求解操作過程

用規劃求解得出的邊界組合中,各種資產的權重如下:國庫券 7.4%,債券 20.2%,股


票 72.6%。這個邊界組合的期望收益率仍為 7.0%,但是現在給權重加上了約束條件:權重
不能為負,國庫券、債券的最大權重分別為 10%和 20%,此時整個組合的標準差為 15.8%。
這與無約束條件下得到的只有 15.7%的方差相比,略有增加,這也說明了添加約束條件後
得到的結果通常要比無約束時差。
針對不同的目標期望收益,分別運用規劃求解進行計算,可以得到有約束邊界上的一
系列點(見圖 6.9)。使用宏的技巧將在 6.12 節中介紹。在上述那些權重的約束條件下,分
別選取從 6.8%到 9.0%的一系列目標期望收益。[讀者可以通過使用規劃求解來計算使期望
收益最小(大)化的權重,從而驗證這些數字]假設我們要進行 11 次最優化,上面所選取的
一系列收益就需分成 11 個目標收益,然後應用 11 次規劃求解,就可以得到期望收益在所
選範圍(從 6.8%到 9.0%)內的邊界組合。

Constrained Frontier Portfolios:有約束有效邊界組合

【參照書中第 112 頁的圖 6.9】

圖 6.9 有約束邊界組合的權重

圖 6.9 列出的投資組合在圖 6.2 中被標記為有約束的點(Constrained Points),最後一個


組合相當於只投資於股票。
總而言之,確定風險投資組合權重的常用方法,就是使用規劃求解進行最優化,其本
質上是一個數值反復迭代的過程。但是,在沒有對權重加上約束條件(除權重之和為 1 的
條件之外)的情況下,可以用 HL 給出的一系列公式得到最優權重,並可以用第 6.10 節中
介紹的用戶定義函數來進行具體計算。
6.6 無風險資產和風險資產的結合

從本節到 6.9 節主要介紹有關用風險資產構造投資組合的一些其他知識。但這一部分的


理論性較強,可以看作是一個附錄材料。本部分的重要性在於:這裏推導出來的公式可以用
來解決‘三類常見組合問題(three generic portfolio problems)’(Taggart,1996)
,並
可以編寫成用戶定義函數。這些函數可以為第 7、8 章的一些問題提供明確的解答。這裏我
們將介紹無風險資產(風險為零的資產)的基本概念,為下一章推導資本資產定價模型打下
基礎。
在討論完由三種(或三種以上)風險資產構造的投資組合,在給定目標收益情況下,
如何得到風險最小的有效組合之後,這裏將扼要介紹在投資中應如何權衡風險和收益。在決
定如何在一個由風險資產組成的投資組合與一種無風險資產之間分配投資時,權衡風險-收
益是需要考慮的主要因素。這一想法是在解決下面的三類常見組合問題時產生的:
問題一:一種風險資產和一種無風險資產的組合;
問題二:兩種風險資產的組合;
問題三:一種無風險資產和一個風險投資組合的組合。
在 Generic 表中演示了解決上述問題的試算表方法。
這裏需要定量分析個人對風險和收益的權衡,因此從經濟學中借用了效用函數這個概
念。假定個人擁有如下的效用函數:

U = E ( rp ) − 0.5 Aσ p 2
其中,投資者的風險厭惡係數 A 的值越大,由投資風險帶來的、需要從投資預期收益
中減去的懲罰項就越大。實驗表明,A 的值通常在 2 到 4 之間。下面的研究中,我們選擇了
A=3。
既然接下來的幾節都是研究兩種資產的情況,因此在此處把 6.1 節給出的投資組合收益
和風險的一般公式修改為只涉及兩種資產的情況:

投資組合收益: E ( rp ) = w1 E ( r1 ) + w2 E ( r2 )

投資組合風險: Var ( rp ) = σ p = w1 σ 1 + w2 σ 2 2 + 2w1w2 cov(1, 2)


2 2 2 2

其中,兩種資產收益的協方差 cov(1,2)可以用其相關性來度量,即 cov(1,2)=


corr(1,2)σ1σ2。無風險資產的收益用 rf 來表示,其方差為零,與其他風險資產的協方
差也為零。整個投資組合的風險等於方差的平方根。

6.7 問題一 一種無風險資產和一種風險資產的組合

三類常見組合問題中的第一個,是指由一種無風險資產(asset0)和一種風險資產
(asset1)組成的組合,收益不相關。圖 6.10 給出了這兩種資產的具體情況:無風險利率
是 1%,asset1 的風險和收益狀況與前面幾節所研究的投資組合中的債券是一樣的。我們把
投資於 asset1 的資金比例(單格 H14)從 0%變化到 100%,這就得到風險收益圖上連接代
表 asset0 的點到代表 asset1 的點的一條直線。圖 6.11 上標明了這條直線。
Generic Portfolio Problems:常見組合問題;
Problem One:risk-free asset and 1 risky asset:
問題一:無風險資產和一種風險資產的組合
Asset Data:資產數據;
Corr Matrix:相關係數矩陣;
VCV Matrix:VCV 矩陣;
Risk aversion coefficient:風險厭惡係數;
Optimal Portfolio:最優組合

【參照書中第 114 頁的圖 6.10】

圖 6.10 用試算表解決問題一(表 Generic)

Problem One:問題一;
Portfolio return:組合收益;
Portfolio risk(standard deviation):組合風險(標準差);
Portfolio utility:組合效用

【參照書中第 114 頁的圖 6.11】

圖 6.11 問題一中效用、收益與風險的關係圖

個體投資者將會根據他們的風險厭惡係數(單格 K6 中)在直線上選擇一個特定的、符
合自己要求的點。圖 6.11 還給出了假定風險厭惡係數為 3 時投資者的效用曲線,上面不同
點所代表的投資組合中 asset1 的比例是不同的(圖上表示為一系列離散點,其縱軸刻度在
圖的右邊) 。效用值從 0.01(所有資金都投資於 asset0)開始,隨著投資於 asset1 的資金
比例增加而平穩增加到最優點,接著開始減少到 0.006(所有資金都投資於 asset1)。
直線上的最優點就是效用最大點。可以通過下面的公式計算出 asset1 的權重(列在單
格 H14 中),得出最優點:

w1* =  E (r1 ) − rf  Aσ 12
在這個例子中,最優投資組合中包括 36%(35.9%)的風險資產投資,總效用是 0.012
(也就是說,等於該投資者獲得大小為 1.2%的確定性等價收益時所得到的效用) 。同樣可以
設計一個名為 Prob1OptimalRiskyWeight 的用戶定義函數,以此來求出權重(單格 H15)。
這將在 6.11 節中進行介紹。
注意,最優投資組合中風險資產的比例(與 asset0 投資比例的變動情況相反-因為二者
之和為 1)是由投資者的風險厭惡程度決定的。一個風險厭惡係數更大(例如 4)的投資者
將會把其最優投資組合中的風險資產比例減少到 27%。
6.8 問題二 存在兩種風險資產的組合

在問題二中,存在兩個風險資產。在後面的分析中,假設這兩種資產的情況分別與前
面例子中給出的債券和股票相同,則它們的收益存在微弱的正相關關係。具體的資料列在圖
6.12 中,其中單格 D25 給出了相關係數 0.23。

Problem Two:2 risky asset and no risk-free asset:


問題一:兩種風險資產的組合
Asset Data:資產數據;
Corr Matrix:相關係數矩陣;
VCV Matrix:VCV 矩陣;
Risk aversion coefficient:風險厭惡係數;
Optimal Risky Portfolio:最優風險組合
Minimum Variance Portfolio:最小方差組合

【參照書中第 115 頁的圖 6.12】

圖 6.12 用試算表解決問題二(表 Generic)

改變 asset1 的權重,可以描出整個邊界(見圖 6.13 所示的連續曲線)。由代表兩種風


險資產不同組合的風險收益點連接而成的這條曲線,很好地說明了投資分散化的好處。例
如,如果一個投資者最初把所有資金全投資於 asset1,那麼他把部分資金轉投到 asset2 上
會增加其所有投資的收益。他的投資組合風險也會因此而減小,只有在 asset2 的風險比
asset1 要大時才會出現例外。
上述資金從 asset1 轉投到 asset2 的過程將持續減小整個投資組合的風險,直到組合方
差達到最小,此時 asset1 的權重為 87.7%,組合的標準差為 9.77%。計算最小方差投資組
合的公式與投資者的風險厭惡係數無關,甚至可以認為該投資者對風險是完全厭惡的。
最小方差投資組合中 w1 的計算公式為:

σ 2 2 − ρ12σ 1σ 2  σ 12 + σ 2 2 − 2 ρ12σ 1σ 2 

為簡便起見,asset1 的權重記為 w1mv(單格 H24 中的 87.7%)


,asset2 的權重就是(1
mv
-w1 ) 。所以在 asset1 的權重為 87.7%時,投資組合的風險最小(9.77%) 。應該注意到,
此時組合的風險小於兩個風險資產各自的風險。
對風險更加偏好的投資者可以減少對 asset1 的投資,增加對 asset2 的投資。圖 6.13
給出了一個風險厭惡係數為 3 的投資者從不同的投資組合獲得的效用情況(圖上表示為一
系列離散點,其縱軸刻度在圖的右邊) ,從中可以看出效用一直增加,到風險大約為 15%時
達到最大值。這個投資者願意承受更大風險,在他的最優投資組合中,asset1 的權重為
35.2%,組合的標準差為 14.7%。
通過一系列的數學運算,我們可以得到 asset1 的最優風險權重運算式如下所示:
w1opt = w1mv + [ E (r1 ) − E (r2 ) ]  A (σ 12 + σ 2 2 − 2 ρ12σ 1σ 2 ) 

Problem Two:問題二;
Portfolio return:組合收益;
Portfolio risk(standard deviation):組合風險(標準差);
Portfolio utility:組合效用

【參照書中第 116 頁的圖 6.13】

圖 6.13 問題二中效用、收益與風險的關係圖

在單格 H29 中給出的權重確定了最優風險投資組合。最優投資組合中 asset1 的權重等


於最小方差投資組合中 asset1 的權重加上一個額外部分。這個額外部分與投資者的風險厭
惡係數有關,並且可以看作是投資者的投機需求。最優風險投資組合的效用是 0.033(這相
當於投資者獲得大小為 3.3%的確定性等價收益時得到的效用)
同樣,最優投資組合的權重可以通過用戶定義函數很容易計算出來。6.11 節將給出用
來計算該權重的 Prob2OptimalRiskyWeight 函數。

6.9 問題三 一種無風險資產和一個風險投資組合

常見組合問題中的最後一個問題研究一個無風險資產和一個風險投資組合的情況。通
常分兩步解決。首先計算風險投資組合中各種風險資產的最優權重(問題二的特殊情況) 。
其次確定投資如何在無風險資產和最優風險投資組合之間分配(實質上是問題一) 。圖 6.14
給出了詳細的計算過程。
首先,在不考慮無風險資產的情況下,確定投資如何在 asset1 和 asset2 之間達到最優
分配。前面一節給出了只考慮風險資產時兩種資產的最優分配比例大約為 35%:65%。假設
最優風險投資組合(此處記為 R)的預期收益為 E(rR)、標準差為σR,其中 asset1 的權重
為 F1。在第二步引入無風險資產後,我們需要確定合適的 F1 使投資組合 R 的收益-風險比
率最大,也就是說,選擇合適的 F1 使下式達到最大:

 E (rR ) − rf  σ R

簡單計算後(也可以像 Bodie 那樣從幾何上直接觀察圖形) ,我們會發現當連接有效邊


界上的投資組合與無風險資產的直線的斜率在直線與邊界相切時達到最大。為了計算切點處
各資產的權重,我們需要使用超額收益(即超過無風險利率的那部分收益) ,分別定義為 E
(R1)=E(r1)-rf 和 E(R2)=E(r2)-rf。最優投資組合權重的計算公式為:

F1opt = σ 2 2 E ( R1 ) + cov(1, 2) E ( R2 )  {σ 2 2 E ( R1 ) + σ 12 E ( R2 ) − cov(1, 2) [ E ( R1 ) + E ( R2 )]}


其中 E(R1)和 E(R2)是超出 rf 的那部分預期收益。
注意:最優風險投資組合的權重與風險厭惡係數無關,而與無風險利率有關。
Problem Three: risk-free asset and 2 risky asset:
問題一:無風險資產與兩種風險資產的組合
Asset Data:資產數據;
Corr Matrix:相關係數矩陣;
VCV Matrix:VCV 矩陣;
Risk aversion coefficient:風險厭惡係數;
Optimal Risky Portfolio:最優風險組合
Solved in 2 stages:採用兩步解決
Stage 1:Optimal Risky Portfolio(‘revised’ Problem2),第一步:最優化風險組合(‘修
正的’問題二)
Independent of A: 與 A 無關
Stage 2:Optimal Portfolio(using Problem1),第二步:最優化整個組合(利用問題一的
結論)
Depends on A :與 A 有關
Optimal Portfolio:最優組合

【參照書中第 117 頁的圖 6.14】

圖 6.14 用試算表解決問題三(表 Generic)

在單格 H41 中應用該公式可以得到 10.5%的權重,這意味著在最優風險投資組合中


asset1 和 asset2 的權重分別為 10.5%和 89.5%。
第二步要從第一步得到的最優投資組合出發,考慮如何在該組合和無風險資產之間分
配投資以使效用最大化。從而,6.8 節給出了風險投資組合的權重為[E(rR)-rf]/[AσR2],無風
險資產的權重則為 1-[E(rR)-rf]/[AσR2]。此處投資組合的權重與風險厭惡係數有關。
現在得到的最優投資組合包括 68.0%的風險投資組合和 32.0%的無風險資產,其效用
從 第 一 步 得 到 的 0.0292 增 加 到 0.0347 。 [ 此 處 風 險 投 資 組 合 的 權 重 也 可 以 用
Prob1OptimalRiskyWeight 函數求出(見單格 H50)]
接下來把 68%的投資分配到每種風險資產上,我們就得到如單格 H52:H54 所示的權
重。同樣,用戶定義函數 Prob3OptimalWeightVec 也可以給出整個最優投資組合的權重向
量(見單格 I52:I54) ,這將在 6.11 節加以介紹。
從圖 6.15 可以看出,邊界線上的每個點都代表 asset1 和 asset2 的某種組合。在引入
無風險資產之後,在連接風險投資組合的邊界和無風險資產的直線與邊界相切時,該切點就
是唯一的最優投資組合。(邊界上的這個切點可以仿照問題二的解決方式加以解釋。)從左
到右來看這條與邊界相切的直線,開始時所有資金均投資於無風險資產,在切點無風險資產
的權重為 0,接著到達最優風險投資組合的權重為 150%、而無風險資產的權重為負 50%的
點。(因為此處對無風險資產的權重沒有任何約束。)第二步(和問題三的答案)需要確定
投資者的最優投資組合在這條切線上的什麼位置。這裏又一次畫出了一系列的點表示投資者
的效用。從圖上可以看出,在我們選擇的風險厭惡係數下,效用將在風險約為 12.5%時達
到最大化。
Problem Three:問題三;
Portfolio return:組合收益;
Portfolio risk(standard deviation):組合風險(標準差);
Portfolio utility:組合效用

【參照書中第 118 頁的圖 6.15】

圖 6.15 問題三中效用、收益與風險的關係圖

現在,在某種意義上,從問題三到下一章推導出資本資產定價模型只需要再前進很小
的一步,最主要的難點將是如何將所有個體投資者的信心匯總,從而給出資產定價理論。

6.10 Module1 中的用戶定義函數

表 Module1 中給出了 Equity1 中用戶定義函數的有關程式。這些程式演示如何使用用


戶定義函數來處理陣列,包括陣列輸入、陣列函數、用陣列和標量進行計算、陣列形式輸出
等操作。例如,PortfolioReturn 函數的程式是:
Function PortfolioReturn(retvec, wtsvec)
returns the portfolio return
If Application.Count(retvec) = Application.Count(wtsvec) Then
If retvec.Columns.Count <> wtsvec.Columns.Count Then
wtsvec = Application.Transpose(wtsvec)
End If
PortfolioReturn = Application.SumProduct(retvec, wtsvec)
Else
PortfolioReturn = -1
End If
End Function
上面的程式是用來檢查計算中所用到的陣列維數是否相等。兩個陣列維數相同時可以
用 SumProduct 函數計算兩者乘積,其結果為一個標量。所以,計算時首先檢查陣列 retvec
和 wtsvec 包含的元素個數是否相同,並且當列數不同時還要對陣列 wtsvec 進行轉置。如
果這些陣列包含元素的個數不相等,上面的函數就會返回一個錯誤值-1。有了上述檢查,用
戶在定義函數時,輸入行向量或列向量都可以,而不拘泥於某種特定形式的向量。
使用 HLPortfolioWeights 函數(Module1 中有該函數的相關程式)處理有關陣列函數
時需要特別小心。一個關鍵問題是要注意函數所用陣列的維數。在 VBA 中一維陣列被儲存
為行向量,同樣,從用戶定義函數得到的一維陣列也將以行向量的形式輸出到工作表中。我
們將在下面的計算中遵守這個規則,確保用戶定義函數得到的 VBA 一維陣列以行向量的形
式輸出到 Excel 中。當然,我們也希望用戶定義函數中的向量可以採取另外一種形式—列向
量。例如,在某些情況下為了保證變數 uvec 和 retvec 是列向量,可以對它們進行轉置。
陣列函數中的中間變數同樣需要按照這個規則進行處理:
Dim I As Variant, m As Variant
I = Application.MMult(vinvmat, retvec)
m = Application.MMult(vinvmat, uvec)
變數 I 和 m 是從一個陣列函數得到的,並且將會作為其他陣列函數的輸入變數,所以
將它們聲明為 Variant 型,即沒有確定維數的變數。在使用 MMult 函數進行計算的過程中,
vinvmat 是一個 n×n 矩陣,而 retvec 是一個 n×1 向量。因此計算得到的陣列將是一個 n×1
(列)向量。
接下來要解決的問題是計算四個數值 a,b,c 和 d。前三個數可以通過一個陣列函數求
出,d 則可以根據前三個數計算得到。例如 a 可以通過單位向量陣列 uvec 和陣列 1 求出:

a = Application.Sum( Application.MMult ( Application.Transpose(uvec),1))


MMult 函數把一個 1×n(行)向量與一個 n×1(列)向量相乘,得到一個 1×1 陣列(標
量)。在 Excel 中這一點很容易做到,但在 VBA 中我們還需要使用 Sum 函數把這個陣列結
果轉化為一個標量。
最後的問題是如何處理陣列的單個元素和標量之間的混合運算。在 Excel 中,這一點也
很容易做到,具體情況參見列在單格 I24:I26 中的向量 g。但是,在 VBA 中最好用一個迴圈
來實現:
Dim wtsvec() As Variant
n = Application.Count(retvec)
ReDim wtsvec(n)
for I = 1 to n
gi = b * m(I, 1) – a * i(I, 1)
hi = c * i(I, 1) – a * m(I, 1)
wtsvec(i) = (gi + hi * expret) / d
next I
由於是通過計算出每個元素後得到 wtsvec,於是,將其聲明為 Variant()
,但最終還
是要用 ReDim 語句定義它的維數。迴圈中,可以用數量直接乘以陣列中的每個元素。

6.11 Module1 中用於解決三類常見組合問題的函數

Prob1OptimalRiskyWeight 函數有四個輸入,它是直接由 6.7 節給出的公式轉化為 VBA


程式而得到的。四個必要的輸入包括風險資產的收益和風險(r1 和 sig1) ,無風險利率(rf)
和風險厭惡係數(rraval) :
Function Prob1OptimalRiskyWeight(r1, rf, sig1, rraval)
’returns risky optimal weight when combined with risk-free asset
Prob1OptimalRiskyWeight = (r1 - rf) / (rraval * sig1 ^2)
End Function
接下來介紹的函數是 Prob2OptimalRiskyWeight,它可以用來解決問題二和問題三。該
函數共有 7 個輸入:r1,r2,sig1 和 sig2 是兩種風險資產的收益和標準差;rraval 是投資者
的風險厭惡係數,無風險利率是 rf。問題二中的無風險利率應該設為 0:
Function Prob2OptimalRiskyWeight(r1, r2, rf, sig1, sig2, corr12, rraval)
’returns optimal weight for risky asset1 when combined with risky asset2
’for case with no risk-free asset, enter Value of rf <= 0
Dim cov12, var1, var2, minvarw. w, xr1, xr2
cov12 = corr12 * sig1 * sig2
var1 = sig1 ^ 2
var2 = sig2 ^ 2
’first look at case with no risk-free asset
If rf <= 0 then
minvarw = (var2 – cov12) / (var1 + var2 –2 * cov12)
w = minvarw + (r1 – r2) / (rraval * (var1 + var2 –2 * cov12))
’then look at case with risk-free asset
Else
xr1 = r1 – rf
xr2 = r2 – rf
w = xr1 * var2 – xr2 * cov12
w = w / (xr1 * var2 + xr2 * var1 – ( xr1 + xr2) * cov12)
End If
Prob2OptimalRiskyWeight = w
End Function
在上面計算最優權重的程式中,cov12 表示協方差。變數 minvarw 是最小方差權重 w1mv,
w 是最優投資組合的權重 w1opt。
問題三的函數中需要使用問題一和問題二所使用的函數。顧名思義,
Prob3OptimalWeightVec 函數最後將以陣列的形式輸出三個最優權重。下面給出了完整的
程式,並對某些步驟進行了說明:
Function Prob3OptimalWeightVec(r1, r2, rf, sig1, sig2, corr12, rraval)
’returns optimal weight for risk-free asset and 2 risky assets
’uses Prob2OptimalRiskyWeight fn
’uses Prob1OptimalRiskyWeight fn
Dim w0, w1, w2, rr, sigr
w1 = Prob2OptimalRiskyWeight1(r1, r2, rf, sig1, sig2, corr12, rraval)
w2 = 1 – w1
rr = w1 * r1 + w2 * r2
sigr = Sqr((w1 * sig1) ^ 2 + (w2 * sig2) ^ 2 + 2 * w1 * w2 * corr12 * sig1 * sig2)
w0 = 1 - Prob1OptimalRiskyWeight(r1, rf, sig1, rraval)
w1 = (1 – w0) * w1
w2 = (1 – w0) * w2
Prob3OptimalWeightVec = Array(w0, w1, w2)
End Function
不考慮無風險資產時,問題就退化為問題二,asset1 和 asset2 的權重是這樣計算的:
w1 = Prob2OptimalRiskyWeight(r1, r2, rf, sig1, sig2, corr12, rraval)
w2 = 1 – w1
知道了這些權重之後,我們就可以計算風險投資組合的收益和風險:
rr = w1 * r1 + w2 * r2
sigr = Sqr((w1 * sig1) ^ 2 + (w2 * sig2) ^ 2 + 2 * w1 * w2 * corr12 * sig1 * sig2)
上面這些數位可以用來確定無風險資產的權重(本質上是問題一),因此需要使用
Prob1OptimalRiskyWeight 函數。

6.12 模組 M 中的巨集功能

本節將介紹可以求出有效邊界(前面的幾節中是用規劃求解求出的)的宏。規劃求解
是 Excel 的一個插件,在安裝之後才會出現在工具 工具功能表中。另外,為了在
工具 VBA 中使用規
劃求解功能,這個模組需要使用 Solver.Xla 插件。
Sub Efffrontier1()
SolverReset
Call SolverAdd(Range(“portret1”), 2, Range(“target1”))
Call SolverOk(Range(“portsd1”), 2, 0, Range(“change1”))
Call SolverSolve(True)
SolverFinish
End Sub
Efffrontier1 宏包含對規劃求解的一個簡單應用。SolverAdd 函數加上了必須的簡單約束
(數值 2 表示了這個等價約束) ,接著用 SolverOk 函數提出了要解決的問題(這裏的數值 2
說明要進行最小化)。SolverSolve 函數用來解決這個問題(參數 True 的作用是隱藏結果
屏),程式結尾部分的 SolverFinish 函數得到問題的答案並顯示在工作表中。
嚴格的說,程式中的 Call 並不是必需的,但是我們建議,在程式中使用了需要參數的
副程式時,最好使用 Call。在使用這個語句時,參數必須用括弧括起來。
Efffrontier2 宏相當複雜,這是因為它在一個迴圈中反復使用了規劃求解功能,最後得
到了整個有效邊界。迴圈的次數需要預先確定。最重要的是,在迴圈中我們要使用儘量少的
程式。規劃求解問題是在迴圈外建立的,在迴圈中需要使用 SolverChange 函數改變約束條
件等式的右端(目標預期收益) 。迴圈中,每次規劃求解迭代運算的結果將會用 PasteSpecial
命令複製到工作表的一個特定區域。下面就是該迴圈的程式:
Do While iter <= niter
Call SolverSolve(true)
SolverFinish
Range(“portwts2”).copy
Range(“effwts2”).Offset(iter, 0).PasteSpecial Paste:=xlValues
Range(“priter2”) = Range(“priter2”).Value + pradd
’amend portret constraint in Solver
Call SolverChange(Range(“portret2”), 2, Range(“priter2”))
iter = iter + 1
Loop
在這個巨集的開始部分用了兩次規劃求解:第一次是計算在給定的約束下可以得到的
投資組合最小收益(用 SolverOk 函數中給出的數值 2 表示) ;第二次是計算最大收益(用
SolverOk 函數中給出的數值 1 表示) 。在這個收益範圍內將選取若干個預先確定數目的目標
收益,針對每個不同的收益求出並儲存其相應的邊界組合權重。
SolverReset
’first calculate portfolio min return given constraints
Call SolverAdd(Range(“portwts2”), 3, Range(“portmin2”))
Call SolverAdd(Range(“portwts2”), 1, Range(“portmax2”))
Call SolverOk(Range(“portret2”), 2, 0, Range(“change2”))
Call SolverSolve(True)
SolverFinish
prmin = Range(“portret2”).Value
’then calculate portfolio max return given constraints
Call SolverOk(Range(“portret2”), 1, 0, Range(“change2”))
Call SolverSolve(True)
SolverFinish

小結

馬可維茨創建的投資組合最優化理論是本書整個股票部分的理論基礎。本節介紹了使用
Excel 的陣列函數功能,很容易把兩種資產投資組合均值和方差的基本計算公式推廣到多種
資產的情況。由於陣列函數可以實現矩陣乘法和矩陣求逆,我們可以用 Excel 求出黃和利曾
伯格的解析解,從而得到有效邊界。上述步驟可以通過用 Excel 工作表直接計算或用戶定義
函數的方式實現。
雖然上述理論很重要,但實際應用時需要諸如規劃求解之類的工具進行計算。本節證明
了在無約束情況下用規劃求解得到的解與 HL 的解析解是一致的,同時也給出了在單個資產
權重有約束的情況下如何使用規劃求解得到正確解答。另外,本節還介紹了在用工作表直接
計算和用宏時,如何使用規劃求解工具。
下一章我們將介紹金融理論的另一個重要發展-資本資產定價模型和模型中β值的作
用。接下來,我們將在股票收益服從對數正態分佈的假設下預測單個股票和投資組合的未來
價值和風險值。

參考文獻
Bodie, Z., A. Kane and A. J. Marcus, 1996,Investments, 3rd Edition, Richard E. Irwin,
Englewood Cliffs, NJ.
Elton, E. J. and M. J. Gruber, 1995, Modern Portfolio Theory and Investment Analysis,
John Wiley & Sons, Chichester.
Eppen, G. D., F. J. Gould, C. P. Schmidt, J. H. Moore and L. R. Weatherford, 1998,
Introductory Management Science, Decision Modeling with Spreadsheets, 5th edition,
Prentice Hall, New Jersey.
Huang, C. and R. Litzenberger, 1988, Foundations for Financial Economics, North
Holland, New York.
Taggart,R. A., 1996, Quantitative Analysis for Investment Management, Prentice Hall,
New Jersey.
第 7 章 資產定價

本章的研究將從單個投資者(微觀角度)轉移到包括多種資產的整個市場,並且觀察所
有投資者的行為(宏觀角度)。其中最主要的區別是我們原來描述的是個體行為,而現在我
們要把所有投資者作為一個整體來考慮,總結他們的行為。只有這樣,才能研究對金融資產
的定價。資本資產定價模型(CAPM)是在 60 年代由金融學院派發展起來的。其基礎是第
6 章介紹的投資組合均值-方差分析。其中一條重要的結論是:市場價格只反映了投資組合
的一部分風險。市場價格所反映的那部分風險是與市場表現相關,通常由β值來度量。在
Bodie et al.(1996)著作的第八章中詳細討論了 CAPM 的有關背景知識。
本章一開始就引入了單因素模型,並且解釋了如何計算相關風險,其中需要特別注意的
是β值和單個資產收益之間的方差—協方差矩陣是如何估計的。本章用到的核心數學方法就
是回歸,它主要用於估計單個資產的β值。一個資產的β值度量了該資產的收益與整個市場
收益的相關性。資產的β值是描述資產收益與市場相關性的唯一工具。但是,在單因素模型
中,協方差也是很容易計算的。工作簿 EQUITY2.xls 中展示了估計過程是如何實現的,其
中還包括許多為了減少計算量而編寫的用戶定義函數。
上一章,我們在用效用函數刻畫單個投資者偏好的假設下,推導出馬可維茨的均值-方
差模型。分析中並沒有考慮資產收益分佈。同樣,可以在忽略投資者偏好而假設資產收益服
從對數正態分佈的條件下,通過均值-方差模型得到與前面完全相同的理論結果。
在假設收益對數服從正態分佈的條件下,可以得到水準財富(horizon wealth)預測值
和風險值的解析解。本章同時給出了使用上述技巧的實例。在某種意義上,我們接受馬可維
茨關於收益和風險可以與正態分佈的均值和方差聯繫起來的觀點,於是我們可以借用統計學
的一些已有結論。另外,為了更容易實現在資產收益的正態和對數正態形式之間進行反復轉
換,我們對刻畫兩種分佈聯繫的有關理論進行實例解釋。

7.1 單因素模型

單因素模型為推導資產定價模型時更好地理解收益和風險有很大幫助。模型假設股票 i
的收益和指數 I 的收益之間存在一種線性關係。分別用 Ri 和 RI 表示股票 i 和指數 I 的超額收
益(即超過無風險收益的部分)時,模型可以寫成:

Ri = α i + β i RI + ei
其中αi 和βi 是模型的參數,於是股票收益可以分為兩部分:系統部分(αi+βiRI)和
殘差部分 ei。系統部分的αi 是指數 I 超額收益為 0 時的股票收益,而βiRI 則是與指數密切
相關的部分。於是,βi 度量了股票對指數運動所作出的反應。收益 ei 與指數無關,僅僅是
股票 i 所特有的。通常假設 ei 是一個隨機誤差項,其數學期望為 0,即 E(ei)=0,所以股票
i 的預期超額收益為:

E ( Ri ) = α i + βi E ( RI )
如果指數是一個市場指數(例如英國的 FTSE100 指數和美國的 S&P500 指數),此時
收益的系統部分就是‘與市場相關的’,殘差部分就是‘公司特有的’。參數β就度量了股
票相對市場的敏感性。
用股票和指數的超額收益(例如用 60 個月的收益資料)資料可以估計回歸參數αi 和β
2
i。同樣可以得到殘差方差σ(ei) 的估計值。

單因素模型同樣可以用來分解風險(為了與第六章保持一致,風險用方差來表示)。股
票 i 收益的方差可以分解為兩部分:第一部分反映系統風險,第二部分反映該股票特有的風
險:

Var ( Ri ) = σ i 2 = β i 2σ I 2 + σ ( ei )
2

此結論極大簡化了為得到方差-協方差矩陣所作的計算,具體計算過程將在第 7.4 節中
介紹。

7.2 估計β
估計β係數

估計β係數時,最好使用對數收益資料(實際上是超額收益的對數) 。表 Beta 給出了如


何通過對股票 A 和指數的月度收益(圖 7.1 的 B 和 C 列)進行回歸來估計單只股票的β係
數。這裏使用的指數是 FTSE100,共有 60 組股票 A 和指數的月度收益資料。β係數(更
嚴格地說是‘未校正’的β值)就是以股票超額收益作為被解釋變數、指數收益作為解釋變
數進行回歸得到的斜率。

Estimating Beta Coefficients using Ln Xs Returns:利用對數收益資料來估計 Beta 值

【參照書中第 126 頁的圖 7.1】

圖 7.1 用股票 A 的收益對市場指數的收益進行回歸來估計β值

Excel 提 供 了 許 多 可 以 用 來 估 計 斜 率 值 的 方 法 。 單 格 I7 中 的 公 式 =
SLOPE(B6:B65,C6:C65)採用了 Excel 的 SLOPE 函數來估計斜率βi。類似地,單格 I6 中
的 INTERCEPT 函數計算了回歸方程中的截據項α。在方程中代入α i i 和βi 的估計值可以得

到:
‘擬合(Fitted)收益’=-0.0013+1.5065×指數收益
E 列和 F 列分別給出了在每一個指數收益下得到的‘擬合(fitted)’股票收益和‘殘
差’(即實際收益減去‘擬合’股票收益的差)。殘差的大小是由殘差標準誤差(單格 I9)
度量的。殘差標準誤差可以通過另外一個 Excel 函數 STEYX(它與 SLOPE 函數的輸入是
相同的)得到。圖 7.2 為股票收益和指數收益的散點圖及相應的回歸直線。實際收益偏離這
條直線(因此與指數不相關)的程度被稱為這只股票的特有風險。它是前面提到的σ(ei)
的最佳估計。

Beta Regression:Beta 值回歸


Share Return:股票收益
Index Return:指數收益

【參照書中第 127 頁的圖 7.2】

圖 7.2 股票收益與市場收益的散點圖(包括回歸直線)

另外一種進行回歸分析的方法(雖然是以靜態的形式)是使用工具 工具功能表,然後選擇資
工具 資
料分析,點擊回歸
料分析 回歸,就得到如圖
回歸 7.3 所示單格 K6 下的回歸結果。截距和斜率在單格 L22:L23
中,殘差標準差在單格 I12 中。
使用 Excel 的 LINEST 函數可以得到更簡練的回歸結果。與上面只能給出一個靜態的、
不能改變結果的方法不同,此函數可以進行動態調用。LINEST 函數是一個陣列公式,這裏
有 5 行、2 列,因此需要預先選擇好一個 5×2 的區域來輸入該公式,並輸出回歸結果(接下
來不要忘記按下 Ctrl+Shift+Enter 組合鍵):

= LINEST ( B 6 : B 65, C 6 : C 65, TRUE , TRUE )


這些結果顯示在圖 7.3 的區域 O6:P10 中,對每個數字的解釋標籤列在 N 和 Q 列中。
LINEST 陣列中的元素可以使用 INDEX 函數得到(見單格 I11,I12,I14 和 I15)
。例如,
在單格 I14 中,β係數可以用下面公式得到:

= INDEX ( LINEST ( B 6 : B 65, C 6 : C 65, TRUE , TRUE ),1,1)


在單格 I15 中,β係數的標準差可以用下面公式得到:

= INDEX ( LINEST ( B 6 : B 65, C 6 : C 65, TRUE , TRUE ), 2,1)


在表 Beta 中我們可以清楚地看到,單格 I19 中用 STEYX 函數給出了股票的特有風險
(以年度標準差表示) ,單格 I23(殘差平方和再除以 n-2)同樣給出了股票的特有風險。股

票的年度風險等於月度風險乘以 12 得到。

Output from Tools/Data Analysis/Regression:


用功能表操作(工具/資料分析/回歸)得到的結果
Output from Linest
利用 Linest 函數得到的結果

【參照書中第 128 頁的圖 7.3】

圖 7.3 應用工具欄回歸
回歸命令得到的結果
回歸

在估計β值的過程中,還需要對它進行校正,校正後的β值才能用來預測股票的收益。
表中 1.51 的β值是從 60 組月度觀測資料中得到的樣本估計值。校正β值的原因是基於下
面的假設:整個市場上所有股票用價值加權的真實β值之和必須等於 1,並且較高的β樣本
估計值在要預測的時段裏有可能降低,同樣,較低的β樣本估計值在要預測的時段裏有可能
升高。因此β的樣本估計值將向 1.0 的總體均值調整。調整的幅度依賴於β樣本估計值的方
差(等於β樣本估計值標準差的平方)與總體β值方差的相對大小(假設為 0.32)。這個比
率就是均值回復因數(mean reversion factor)
。例中,見圖 7.4,回歸的β樣本估計值 1.51
用一個大小為 32%的均值回復因數進行調整,從而向整個市場的均值靠近。校正後的β值
顯示在單格 O31 中,大小為 1.34。均值回復因數也可以用來調整β樣本估計值的標準差。
下面摘錄的工作表顯示,用戶定義函數給出了一種更方便地調整β樣本估計值的方法。

Adjusting sample beta for mean reversion:


為均值回復因數調整β樣本

【參照書中第 129 頁的圖 7.4】

圖 7.4 為了預測股票收益而校正樣本β值

7.3 資本資產定價模型(
資本資產定價模型(CAPM)

前面一章,我們發展了組合優化理論,並且解決了第三個問題-投資者如何在最優風險
投資組合和無風險資產之間分配投資資金。CAPM 模型是基於下面假設建立起來的模型:
只存在一個最優風險投資組合;這個組合就是市場組合,市場組合中各種股票的權重等於其
價值占整個市場價值的比例。我們已經從只考慮單個投資者的微觀角度轉到了考慮所有投資
者的宏觀角度,這樣就可以介紹資產定價的有關理論了。CAPM 理論認為,β值,即股票
收益和市場收益的協方差,是市場定價的唯一因素。另一方面,投資者承擔單只股票的特有
風險將得不到任何回報,因為 CAPM 理論認為,對於所有股票而言,截據α的期望值為 0。
CAPM 是研究與市場預期收益相關的資產預期收益理論。此理論認為:對於一個風險
完全分散化的投資者,影響股票 i 預期超額收益 E(Ri)的唯一因素就是股票的系統風險(用
βi 來度量)。對所有股票而言,α的期望值為 0。用公式表示就是:

E ( Ri ) = β i E ( RM ) 因因E (α i ) = 0
其中,βi 等於 cov(Ri,RM)/σM2,E(RM)是市場的預期超額收益。βi E(RM)通常被稱為收益
的“CAPM 基準”。
假設在市場組合之外存在一個風險資產 x,通過解問題三可以推導出 CAPM,於是,問
題三的答案是,資產 x 的權重為 0。在前面一章中,我們假設投資者的效用函數為二次的(也
就是說,形式為 U=E(rp)-0.5AσP2) ,並在此基礎上發展了投資組合理論。CAPM 理論可以
不使用效用的概念,而通過資產收益服從對數正態分佈這個假設推導出來。我們將在 7.5 節
觀察一隻普通股票的收益形態以檢驗上述假設的合理性。

7.4 方差-
方差-協方差矩陣

上一章選擇風險投資組合時,都是試圖使組合風險最小化。確定投資組合的風險時,使
用了三種資產的方差-協方差矩陣。作為對比,表 VCV 包括 8 種資產的收益資料(實際上
是超額收益的對數) ,並計算了收益的相關係數矩陣和方差-協方差矩陣。計算可由用戶定
義函數 CorrMatrix 和 VCVMatrix 來實現。其中,CorrMatrix 函數中包含了 Excel 的 CORREL
函數,VCVMatrix 函數使用了 Excel 的 COVAR 函數。程式非常簡潔,可以從表 Module1
中得到。如圖 7.5 所示,得到的方差-協方差矩陣中包含 8 個方差和 28 個不同的協方差。

VCV Matrix:VCV 矩陣

【參照書中第 130 頁的圖 7.5】

圖 7.5 工作表 VCV 中 8 種相關股票收益的方差-協方差矩陣

n 種資產的 VCV 矩陣包括大約 n2/2 個不同的單格。當存在許多可供選擇的資產時,計


算 VCV 矩陣的工作量相當大,預測時還會出現許多困難。夏普的單因素模型就把輸入資料
的個數從一個不可能的量級 n2 減少到可以實現的量級 n。夏普假設除了各種資產與市場的
一般聯繫之外,不同資產之間沒有協方差(單因素) 。因此該模型中沒有考慮資產之間協方
差,而資產之間協方差顯著不為 0 的情況在這些資產所代表的公司同處一個行業時是很常
見的。
使用單因素 VCV 方法時,需要知道每只股票的βi 值和特有風險σ(ei)的估計值,以
及市場指數方差σM2。方差-協方差矩陣的非對角線元素可以通過下面的公式估計:

σ ij = β i β jσ M 2
對角線元素可以由單因素模型的風險分解方法得到:

σ i 2 = βiσ M 2 + σ ( ei )
2

為了用一個簡單的公式得到矩陣,我們用 HLOOKUP 函數把β值和特有風險從輸入資


料中摘錄出來,同時用一個 IF 語句為每一個對角線元素加上相應的殘差方差。如圖 7.6 所
示,單格 M41 所包含的公式是:

= $ M $36 * HLOOKUP ($ L 41,$ M $32 : $T $34, 2, FALSE ) * HLOOKUP ( M $40, $ M $32 : $T $34, 2, FALSE )

第一項,最開始的 HLOOKUP 函數用匹配 L 列中股票名的方式找到β i ,第二個


HLOOKUP 函數用匹配第 40 行股票名的方式找到βj。IF 語句用來找到對角線元素(行和列
的股票名相同) ,並且正確的加上殘差方差。雖然公式很長,但是要注意使用 IF 語句時,最
好只涉及公式中額外的元素,從而使公式容易理解一些。

Input Data for Single-Index Model VCV:


為單因素模型 VCV 輸入資料

【參照書中第 131 頁的圖 7.6】

圖 7.6 由單因素模型β值估計出來的方差-協方差矩陣
比較圖 7.5 和 7.6 的數值之後,就會發現單因素 VCV 矩陣低估了原來的 VCV 中那些處
於同一行業的股票之間的協方差。(那些資產依次代表兩個銀行、兩個保險公司和三個化學
公司。)
用戶定義函數 VCVSingleIndexMatrix 只需將收益資料作為輸入變數,就可以自動得出
β、特有風險的估計值,並且給出單因素 VCV 矩陣。該函數從單格 M55 開始。7.8 節給出
了該函數的具體程式。

7.5 風險值(
風險值(VaR)

本節我們介紹風險值(VaR)的概念,並在收益服從對數正態分佈假設的條件下,得到
股票風險值的解析解。
對股票收益的實證研究表明,它們通常具有一定的偏斜度。但是,對收益取對數後(通
常是自然對數)得到的分佈會更加對稱。因此與收益相比,對數收益通常更加對稱並且近似
的服從正態分佈。當對數收益服從正態分佈時,稱收益服從對數正態分佈。雖然在某些情況
下(例如處理日收益或資產收益波動性很低時)經常會忽略對數正態和正態分佈之間的顯著
區別,但精確的研究中絕對不能忽略這種差別。我們至少要理解這兩種分佈之間的區別,這
一點非常重要。兩者的一個主要區別是:專家在他們的學術研究中一般使用對數收益,而在
一般的商業軟體中通常使用普通(未經處理的)收益,並且假設它們服從正態分佈。另外,
研究中傾向於用超額收益(收益減去無風險利率)作為分析的基礎。本質上講,關鍵要知道
在分析中,需要假定股票價格收益服從何種分佈。
嚴格地說,我們需要檢驗‘收益’資料以確保這些資料大致服從正態分佈。一個比較簡
便的方法是生成一個正態概率分佈圖,例如 Beta 表中股票 A 的對數收益。生成正態概率分
佈圖的方法在第 3 章(3.6.2 節)中已經介紹過了。工作簿 EQUITY2.xls 中的表 1 給出了股
票 A 對數收益的散點圖。
在對數收益服從正態分佈的假設下,定義一個投資組合分佈的左尾(lower tail)值,資
產的價值會以一定的概率低於該值。分佈的左尾(lower tail)值就是風險值或 VaR。這種
度量的本質是把度量股票收益的波動率轉化為求正態分佈的百分位點。
知道了月度對數收益的均值和方差(分別用 M 和 V 表示)後,還需要知道服從對數正
態分佈收益資料的均值(用 M1 表示) 。因為本節和下節都要用到收益分佈的矩,所以在圖
7.10 中 對 它 們 進 行 了 總 結 , 其 中 對 數 正 態 矩 M1 和 正 態 分 佈 矩 之 間 關 係 是
M1=exp(M+0.5V)。
如果一個資產的月度對數收益服從正態分佈,其均值和方差分別為 M 和 V,那麼時間
段δt 內其收益同樣服從正態分佈,這時的均值和方差分別為 Mδt 和 Vδt。根據標準正態
分佈的有關理論,收益均值減去 1.64 倍標準差的概率為 5%,用公式表示就是:
 M δ t − 1.64 (V δ t ) 
 
即收益比上式數值低的概率為 5%。類似的,收益低於均值減去 1.96 倍標準差的概率
為 2.5%。‘z 值’(這裏 z=1.645)確定了分佈的左尾區域(這裏是 5%)
。如果一種資產
的初始價值是 S,那麼在δt 個月之後其價值將有 5%的概率低於:

S  M δ t − 1.64 (V δ t ) 
 
這就是該資產的風險值。更嚴格的說此處得到的是絕對風險值。只考慮波動率(忽略預
期收益 SMδt)時得到的就是相對風險值。
風險值只是一個數字,用來表示一個資產或投資組合可能出現的損失,風險值給出了在
給定的時間段(如一個月)和合適的概率(如 5%)下資產的最大預期損失是多少。在當前
的實際應用中,風險值被大多數主要的投資銀行用來集中度量其持有的投資組合每天出現損
失的風險。這些投資組合可能幾乎包括所有的金融資產,例如期權、債券、期貨和股票。此
處的解釋只針對由股票構成的投資組合,而沒有涉及如何計算其他金融資產的風險值(往往
比較複雜) 。
下面給出了由 8 種瑞士股票構成的投資組合風險值的計算過程,股票的收益展示在表
VCV 中。如圖 7.7 所示,這裏使用的是這 8 只股票的月度對數超額收益率。從 C 列到 J 列
給出了各種資產的 60 組月度對數收益率,其均值和方差列在第 8 到第 10 行中。拿 UBS 來
說,單格 W8 給出了它的均值(用公式=AVERAGE(C13:C72)算出),單格 W10 給出其方
差(公式=VARP(C13:C72))。計算相對風險值的公式主要用到了 UBS 的資產價值(單格
W16)、UBS 的方差(單格 W10)、所選擇的時間段(單格 W15 給出的一個月)和標準差
的倍數即‘z 值’(單格 W19) 。相對風險值(單格 W21)的意義可以解釋為:如果持有現
在價值為 1000 的 UBS 的股票,在今後一個月的時間內,其價值有 5%的概率減少 105.59
或更多。在計算相對風險值的過程中,我們假設資產在整個期間內有一個預期收益,但是這
個收益很小,可以忽略不計。(在計算每天的風險值時通常這麼考慮)
絕對風險值中包含了資產的預期收益(從單格 W12 的 M1 可以得到,此處 UBS 的月度
收益為 1.21%),並且要從相對風險值中減去這個正數(因為此處持有該股票)。計算預期
收益率(單格 W12 中的 M1)的過程中用到了對數正態和正態分佈矩之間的關係公式,該
公式將在 7.7 節介紹。因此,在我們的例子中單格 W24 給出的 93.5 的絕對風險值比相對風
險值要低。在上面給出的那些股票中,風險值最低的是 Roche,因為它的方差最小。

Estimating VaR using Lognormal Distribution:


利用對數正態分佈估計 VaR
Estimating Portfolio VaR using Lognormal Distribution:
利用對數正態分佈估計資產組合的 VaR

【參照書中第 133 頁的圖 7.7】

圖 7.7 在工作表 VCV 中計算 8 只瑞士股票的風險值

在知道單只股票的風險值和它們收益之間的相關係數矩陣之後,估計整個投資組合(此
處假設組合中 8 種股票的權重相等)的風險值也就不難了。單格 W30 中給出了整個投資組
合的相對風險值是 702.70,比所有單只股票的風險值之和 914.73 要小很多,這從另一個側
面證明了投資分散化可以減小投資風險。圖 7.7 給出了用於度量風險值的一些用戶定義函
數。
7.6 水準財富

本節中,我們將使用資產的對數收益及其均值 M 和方差 V 進行一系列分析。先給出對


數正態和正態兩種分佈矩之間的關係,如下所示:

M 1 = exp( M + 0.5V ) 和 M 2 = exp(2 M + 2V )


表 Forecast 中,在假設資產收益過去表現可以延續到未來的條件下,給出了如何利用
上述關係來估計未來某個時間點(如 T 年)的財富值。在具體估計的過程中,假設歷史收
益(以 1+r 的形式表示)是獨立同分佈的,都服從對數正態分佈。未來財富被定義為一系列
連續收益的乘積,因此它也服從對數正態分佈。圖 7.8 就是從表 Forecast 摘錄出來的。
令現在的財富值 W 0 為 1,一年以後的財富值為 W1。我們用收益所服從的對數正態分
佈的矩來得到 Ln(W 1)所服從的正態分佈的有關參數,並以此預測未來的財富值。

Generating probabilistic forecasts(Ibbotson & Sinquefield):


生成概率預測值

【參照書中第 134 頁的圖 7.8】

圖 7.8 在工作表 Forecast 中通過計算來預測未來的財富值

工作表的 B 列中給出了過去 70 年的一系列年度相關收益情況,其中第一個和第二個數


值分別為 1.0917 和 1.2310(單格 B6 和 B7)
。從 M1,M2,M 和 V 之間的關係我們可以得
到:

M = 2 ln( M 1) − 0.5ln( M 2)

V = −2 ln( M 1) + ln( M 2)
其中 M,V 的值分別為 0.0715、0.0324(分別列在圖 7.8 的單格 E6、E7 中)
。在對數
收益服從正態分佈的假設下,不同的預期收益分佈的參數列在 F 列中,其中預測收益的方
差與時間段的長度為負相關關係。無限期的預測收益為 7.41%,而收益的幾何均值為
7.23%。E 列給出了對於不同時間段由正態分佈的參數得到的預測收益,B 列是用對數正態
分佈的前兩階矩得到預測收益。
對於正態分佈,針對不同的時間段可以做出預測財富值的分佈圖。其置信水準(例如上
95%水準)由下面公式給出的“z 值”確定:

LN (WT ) = MT + 1.64 (VT )


其中,財富值將有 95%的概率低於 1.64 倍的標準差。通常,圖 7.8 中單格 K11 給出的
‘z 值’可以用 Excel 的 NORMSINV(pctile)函數計算出來,其中單格 K8 中給出了相應
的百分比。
給定所要預測的時間段 T 年和合適的“z 值”之後,我們就可以通過下式來預測未來財
富值:

WT = W0 exp( MT + z V T )
下面的圖 7.9 給出了過去 70 年的實際財富狀況和對未來 20 年財富的預測值,財富分
佈的上 95%,中間(50%)和下 5%水準都展示在圖中。

Forecast of Horizon Wealth: 水準財富的預測值

Wealth index:財富指數

【參照書中第 135 頁的圖 7.9】

圖 7.9 對預測的水準財富值所作的解釋

7.7 正態和對數正態分佈矩之間的關係

圖 7.10 中表格的內容值得仔細閱讀,因為在教科書中經常忽略收益和對數收益之間的
區別,並且無論是在研究股票還是在研究期權等其他重要領域時,理解對數正態和正態分佈
參數之間的差別對我們的研究有很大幫助。

資產 收益 對數收益
分佈 對數正態 正態
一階矩
二階矩

一階矩計算
二階矩計算

【參照書中第 136 頁的圖 7.10】

圖 7.10 正態分佈和對數正態分佈矩之間的關係

可以用分佈的中心矩來描述這個分佈(見上表中的正態分佈),也可以用原點矩來描述
這個分佈(見上表中的對數正態分佈) 。兩種分佈的一階矩都是其均值(記做 M1 或 M) ,二
階中心矩是方差 V,二階原點矩為 M2。在 Excel 中,可以對所有收益使用 SUMSQ 函數,
然後把計算結果除以收益的總個數,這就得到了 M2。
由於正態和對數正態分佈的矩存在上面給出的等價關係,可以根據一個分佈的參數求出
另一個分佈的參數。假設對數收益服從均值為 M、方差為 V 的正態分佈。於是利用上表第
二列最後兩行給出的公式可以算出相應收益服從對數正態分佈時的原點矩 M1 和 M2。同
樣,知道收益服從對數正態分佈時的原點矩之後,可以利用表中第三列最後兩行的公式求出
收益服從正態分佈的均值和方差(M 和 V)。

7.8 Module1 中的用戶定義函數

本 模 組 中 的 許 多 函 數 都 能 把 工 作 表 中 的 公 式 直 接 轉 化 到 VBA 。 這 些 函 數 包 括
ISHorizonWealth 函 數 和那 些 函 數 名 前 面 冠 有 Portfolio 的 函數 。 函 數 CorrMatrix 和
VCVMatrix 分別用來計算相關係數矩陣和方差-協方差矩陣,它們只需要輸入-收益矩陣
(retsmat)。這兩個函數都系統地選擇了收益矩陣中的兩列,應用 Excel 中的一些函數(這
裏主要使用了 CORREL 和 COVAR)來計算度量指標,然後在輸出矩陣中儲存計算結果。
這裏需要對 VCVMatrix 程式進行一點說明。在計算 VCV 矩陣時我們採用了樣本度量函
數(例如 VAR 函數) ,而不是總體度量函數(如 VARP 函數)。更為混亂的是,Excel 中的
COVAR 函數是用來度量總體值的,其計算乘以 n/(n-1)時才能得到樣本值。
本模組中最具獨創性的函數是計算單因素 VCV 矩陣函數。它有兩個輸入:收益矩陣
(retsmat)和市場收益向量(mktvec) 。下面詳細給出了該函數的程式。注意:在輸入矩陣
的階數確定之後,rvec()等變數的維數在後面的程式中要用 ReDim 語句加以聲明。
Function VCVSingleIndexMatrix(retsmat, mktvec)
’returns nxn sample single-index variance-covariance matrix
’uses PortfolioBeta fn
’uses PortfolioSpecificRisk fn
Dim vmkt, bi, sri
Dim i As Integer, j As Integer, nc As Integer, nr As Integer
Dim rvec() As Variant, bvec() As Variant, srvec() As Variant, Vcvmat() As Variant
nc = retsmat.Columns.Count
ReDim Vcvmat(nc, nc)
ReDim bvec(nc)
ReDim srvec(nc)
nr = retsmar.Rows.Count
ReDim rvec(nr)
’first calculate the input (beta, specific risks and market variance)
For j = 1 To nc
For i = 1 To nr
rvec(i) = retsmat(i, j)
Next i
bvec(j) =PortfolioBeta(rvec, mktvec)
srvec(j) = PortfolioSpecificRisk(rvec, mktvec, 1)
Next j
vmkt = Application.Var(mktvec)
’then cycle through vcv matrix
For I = 1 To nc
bi = bvec(i)
sri = srvec(i)
For j = 1 To nc
If j = i Then
Vcvmat(i, j) = (bi^ 2)*vmkt + (sri^ 2)
else
Vcvmat(I, j) = bi*bvec(j)*vmkt
Vcvmat(j, i) = Vcvmat(I, j)
End If
Next j
Next i
VCVSingleIndexMatrix = Vcvmat
End Function
在第一個 If… Then 迴圈中,j 指第 j 種資產,i 指第 i 個收益,用其他的用戶定義函數估
計了每種資產的β值和特有風險。第二個 If… Then 迴圈則在 VCV 矩陣的合適位置插入了
基於β值和特有風險的方差-協方差運算式。

小結

單因素模型的主要貢獻是把第六章中所研究的風險分為兩個部分:第一部分是直接受指
數或市場組合影響的風險,第二部分是單只股票或資產自身特有的風險。本章是應用單因素
模型來估計方差-協方差矩陣,並且用回歸分析得到了β係數。給出了分別使用工作表和用
戶定義函數時的所有計算過程(包括回歸和矩陣乘法)。
雖然單因素模型和資本資產定價模型的數學原理極為相似,但是 CAPM 要比單因素模
型向前多走了一大步。從 CAPM 的模型公式可以看出,只有投資者承擔的市場風險才能得
到回報。
可以通過單個投資者的效用和第六章介紹的常見組合問題推導出 CAPM 模型,同樣可
以採用股票的對數收益服從正態分佈的假設,直接得到 CAPM 模型。在此正態假設的基礎
上,本章解釋了如何根據歷史收益預測投資者未來財富的分佈和如何計算風險值。
下一章,將研究如何用單因素和多因素模型的被動標準來度量主動的投資戰略。

參考文獻
Bodie, Z., A. Kane and A. J. Marcus, 1996, Investments, 3rd Edition, Richard E. Irwin,
Englewood Cliffs, NJ.
第 8 章 投資組合業績評價

投資組合業績評價的主要目的是估計和比較不同投資策略的業績(歷史收益) 。對於由
風險資產構成的投資組合,本章的內容是選擇被動的還是主動的投資策略。另外,還將介紹
在確定風險投資組合的條件下,如何選擇無風險資產的投資水準。
對於一個完全被動的投資策略,投資者持有的組合完全複製市場指數(即成份股及其權
重與市場指數完全相同)。被動的投資者並不需要過多資訊,並且一般不交易其投資組合所
包含的股票,除非市場指數的結構(成份股或者權重)發生變化促使投資者改變持有的投資
組合。被動的投資者承受了市場風險並且獲得相應回報,其收益等於市場收益減去必需的交
易成本。
與之相反,主動投資者所持有的投資組合與市場指數構成不同,主要表現在投資組合的
部分或是所有股票的權重與市場指數不同。主動投資者需要得到充分的資訊並且比被動的投
資者承擔更多的交易成本。實際上,因為主動的投資者承受了特殊的風險並且承擔較多的交
易成本,所以從長期來看只有少數的主動投資者所獲的收益超過了被動的投資者。隨著主動
的投資策略變得越來越複雜,所以急需發展更為適用的組合業績評價方法和評價標準。
本章回顧了最早在二十世紀六十年代興起的有關投資組合業績評價的有關想法和九十
年代提出的最新的投資組合業績評價理論。所有的研究方法都用到了資產的收益(這樣做的
好處是股票和投資資金的相關資料都是可以得到的) 。傳統的投資組合業績評價理論是與前
面章節介紹的資產定價理論同時發展起來的。因此,夏普比率採用無風險資產的收益作為收
益基準,而其他三種方法以 CAPM(單因素模型)為基準。七十年代出現了另一種方法-
特雷納-布萊克模型(特雷納和布萊克,1973),這種方法把那些定價不合理的股票和一個
被動的市場指數投資組合混和起來,構築了一個最優風險投資組合。這種方法是基於第六章
中討論的常見組合問題提出的。投資組合業績評估和特雷納-布萊克模型在 Bodie et al
(1996)著作的第二十四章有詳細介紹。但是,Bodie et al 的書中並沒有介紹評估投資組
合貢獻的最新方法-風格分析(Style Analysis)。風格分析採用了多因素模型作為收益基
準,它是夏普於 1992 年提出的。
四種傳統的投資組合業績評價方法包括用投資組合相對於某個收益基準的收益除以相
應風險指標(如波動性、β值或特有風險)所得到的比率。表 EQUITY3.xls 詳細解釋了這
些評價方法。針對這些方法,也給出了相應的用戶定義函數。類似的,用試算表來實現特雷
納-布萊克“主動-被動”模型的過程中使用了一些函數,這些用戶定義函數在我們解決常
見組合問題時已經介紹過了。類似於求出有約束有效邊界時的處理方法,風格分析也用到了
Excel 的規劃求解來解決二次規劃問題。風格分析還有兩個擴展應用:求風格權重的置信區
間(同樣用規劃求解來實現)和暴露分析(exposure analysis,即一個滾動時期的風格分析,
它表示了隨著時間的改變投資基金風格的變化情況) 。因為進行暴露分析時反復用到了風格
分析,所以我們將用 Excel 的宏來實現暴露分析。

8.1 傳統業績評價方法

傳統的投資組合業績評價方法主要通過比較不同投資策略的歷史收益和風險對其進行
評價的。因為這些方法僅以單因素模型作為基準,所以現在看來都有點過時了,並且它們都
缺乏統計上的準確性和說服力。在此我們只把它們作為歷史方法進行介紹。
表 4Measures 展示了二十世紀六十年代後期在 CAPM 基礎上發展的投資組合業績評價
方法。它們的定義由如下公式給出:

夏普的方法:  rp − rf  σ ( rp )

特雷納的方法:  rp − rf  β p = 常常 + α p β p

詹森的方法: { }
α p = rp − rf + β p  rm − rf 

Appraisal 比率: α p σ ( ep )
其中,rp 和σ(rp)分別是投資組合的平均收益和收益標準差,αp 和βp 是 CAPM 模型
中描述該投資組合和市場表現之間關係的參數,σ(ep)是投資組合收益的特有風險(即收
益的標準差中不與市場相關的那部分),rf 是無風險資產的收益。這些評價方法是基於歷史
可以反映未來的假設,用歷史(後驗)資料計算相應指標從而預測(先驗)未來的情況。
夏普比率用超額收益除以投資組合的風險(投資組合收益的標準差)。特雷納指標是用
超額收益除以系統風險βp。詹森指標僅僅是αp,它等於投資組合的實際收益減去市場收益
已知的情況下用 CAPM 預測出來的組合收益,相當於“定價偏差”。Appraisal 比率等於α
p 除以投資組合的非系統風險。

Performance Measurement: 業績評價方法


Excess Returns:超額收益
Four Performance Measurement: 四種業績評價方法

【參照書中第 140 頁的圖 8.1】

圖 8.1 工作表 4Measures 中的業績評價指標

圖 8.1 中 C 和 D 列給出的收益均值,α,β等都是通過單只股票和市場指數的月度超
額收益得到。(注意:我們同樣可以選擇一個投資組合的收益來代替上面提到的單只股票的
收益)單格 C11 中顯示股票的α值(即單格 H12 中的詹森指標)為正,這說明該股票的收
益比用 CAPM 模型預測的結果要高。同樣,單格 H14 顯示的 Appraisal 比率也是正的。特
雷納指標等於一個常數加上αp/βp,這個常數就是市場組合的超額收益。但是,在我們的例
子中,α值不足以補償該股票比市場組合大的多的總風險,因此,如果用夏普指標來評價的
話,該股票的表現比市場要差。
上面幾種評價指標分母上的風險指標是不同的,這在很大程度上決定了這幾種方法的適
用範圍。例如,夏普指標只適用於評價整個投資組合的表現(因為它忽略了與市場的相關
性)。特雷納指標和詹森指標只適用於評價整個投資組合中的一部分投資業績。Appraisal
比率只適用於評價在一個核心的被動投資組合的基礎上,進行的幾個不同的主動投資策略的
業績。使用這些單因素的業績評價指標時必須要小心。一般來說,這些方法比我們在本章後
面部分介紹的多因素業績評價方法(例如風格分析)要差。

8.2 主動—
主動—被動管理

實踐中,許多投資經理假設大部分股票的價值是合理的,但是也有一部分股票被高估,
另一部分被低估。根據 CAPM 模型,在一定程度上,可以用股票的α值來評價其價值被高
估或低估的程度。
基於股票市場不是完全有效的假設,特雷納和布萊克給出了一個如何評估由定價不合理
股票構成的投資組合的模型。首先,他們給出了如何混和最優主動投資組合和被動市場組合
來得到最優風險投資組合。其次,他們描述了如何在無風險資產和最優風險投資組合之間分
配投資來構造最優投資組合。上面的兩個步驟與前面我們解決常見組合問題時首先考慮兩種
風險資產、然後考慮一種風險資產和一種無風險資產的做法是一致的(即分別在 6.8 和 6.7
節中介紹的問題二和問題一)。特雷納-布萊克方法採用了 Appraisal 比率,它是投資管理中
常用的“core-satellite”方法的基礎。

Active-Passive Exercise:主動-被動練習

A:Find Optimal Active Portfolio:A:發現最優主動投資組合

Optimal Active Portfolio: 最優主動投資組合

【參照書中第 141 頁的圖 8.2】

圖 8.2 工作表 AP 中的特雷納-布萊克模型

圖 8.2 的例子中,給出了投資經理認為定價不合理四隻股票的一些具體指標。例如,股
票 1 在下一年的預期超額收益為 1%(超出用 CAPM 模型得到的預測值) 。給定四種定價不
合理股票的預期收益、β值和特殊風險後,可以首先得到最優主動投資組合。特雷納-布萊
克方法認為應當使主動投資組合的 Appraisal 比率最大化。並證明了上面這種方法的結果等
價於持有這幾種股票:各股票的權重等於其預期收益除以各自的特有風險。這些比率列在單
格 G12:G15 中,它們之和列在單格 G17 中,最優主動投資組合中這四種股票的權重列在單
格 I12:I15 中。例如,最優主動投資組合中股票 1 的權重為 98.2%(=G12/G17)。結合這
四種股票的權重以及其他資訊,可以得到最優主動投資組合的預期超額收益為 3.7%,β值
為 1.27,特有風險為 24.8%(假設四種股票的特定風險是相互獨立的) 。
接下來的任務是在最優主動投資組合和被動市場組合之間分配投資(對於後者,其超額
收益等於單格中的股權風險溢價,總風險等於單格中的股票市場風險)。這裏可以利用 6.8
節中關於問題二的結論。6.8 節主要解決了存在兩種風險資產的情況,這同樣適用於存在兩
種投資組合的情況。因此圖 8.3 的單格 I23 給出了主動投資組合的權重,其計算公式為:

= Prob 2OptimalRiskyWeight1( B 24, E 24, B 4, B 29, E 29, B31, B 7)


B:Find Optimal Risky Portfolio:B:發現最優風險組合
Active:主動;Passive:被動;
Solve Prob2:Optimal Risky weights——解決問題二:最優風險權重
Optimal Risky Portfolio:最優風險組合

【參照書中第 142 頁的圖 8.3】

圖 8.3 在工作表 AP 中求出最優風險投資組合

這個公式的輸入項主要有:這兩個投資組合的收益和風險(B24,E24,B29 和 E29)、
它們的相關係數(B31),無風險利率(B4),風險厭惡係數(B7)
。結果顯示有 32.8%的資
金是投資於主動投資組合的。注意到最優風險投資組合的夏普比率比被動投資組合的要大,
這說明最優風險投資組合為風險提供了更多回報。
最後的任務是解決如何在最優風險投資組合和無風險資產之間分配投資。同樣,這個問
題的解決方法已經在 6.7 節中介紹過了,是第一個常見組合問題。圖 8.4 的單格 B41 給出
了最優風險投資組合的權重,其公式為:

= Prob1OptimalRiskyWeight ( I 28, B 4, I 32, B 7)


其中,此公式的輸入項為:最優風險投資組合的收益和風險(I28,I32),無風險利率
(B4),投資者的風險厭惡係數(B7)。計算結果顯示,投資於風險資產的比例少於 2/3
(61.2%)。

C:Find Optimal Portfolio:C:發現最優投資組合


Solve Prob1:split between risk-free and risky
解決問題 1:在風險資產與無風險資產之間分配投資
Optimal Portfolio:最優組合

【參照書中第 143 頁的圖 8.4】

圖 8.4 在工作表 AP 中確定特雷納-布萊克模型中風險資產和無風險資產的權重

圖 8.5 中的風險-收益圖解釋了主動和被動投資組合。根據資金在主動和被動投資組合
之間分配的不同,可以得到二者之間的邊界(邊界上的每個點反映了兩者的一種組合)。當
過圖上代表無風險資產(收益為 7%)的直線與該邊界相切時,就得到了最優風險投資組合。
風險厭惡係數不同將會改變最後的最優投資組合在直線上的位置。本例中無風險資產的投資
比例為 38.8%。
Active-Passive Exercise:主動-被動練習
Portfolio return:投資組合收益
Portfolio risk:投資組合風險
Risk-free:無風險
Passive:被動
Active:主動

【參照書中第 143 頁的圖 8.5】

圖 8.5 工作簿 EQUITY3 中特雷納-布萊克模型的圖表分析

8.3 風格分析(
風格分析(Style Analysis)

風格分析(style analysis)是最近發展起來的,基於收益的,投資基金評價方法。夏普
(1992)在九十年代初期率先建立了一個“資產類因素模型”,並根據風格(Style)和選
擇(Selection)來評價不同基金的業績。風格分析可以看作得到組合的逆過程。
投資基金可以分配到許多不同的國內市場(例如股票、債券和票據)和國外市場(例如
貨幣、外國股票和商品)。其中的每個市場還可以包括許多不同種類的資產。對於局外投資
者而言,通常不能得到一個特定基金所投資資產的詳細資訊。因為不同市場資產的業績是不
同的,所以,一方面很難分辨出每個市場對整個投資組合的收益所作貢獻的大小,另一方面
也很難分辨出每個市場中不同資產的貢獻大小。但是,可以得到該基金的收益資料,從而可
以進行風格分析。
風格分析是用一些已知的指數(其收益是可以得到)構建基準投資組合,然後將投資基
金的主動投資組合的業績與該基準組合進行比較。理論上,這些指數應該能反映不同資產類
別的活動性,這些指數應該是唯一和完全的,並且所包含資產報價是公開的,這樣一來,我
們就可以“被動地”追蹤這些指數。 (例如,夏普選擇了 12 個能包括美國投資基金投資選
擇的指數,並保證這些指數之間的重疊部分儘量少。)
用 f1、f2…fn 表示 n 種被動指數的收益,則用這 n 種指數對第 i 種投資基金進行風格分
析所用的公式為:

ri = [bi1 f1 + bi 2 f 2 + L + bin f n ] + ei
其中 ri 是第 i 種基金的收益,bij 是第 i 種基金在第 j 種指數中的權重,ei 是收益中不能用
上述因數解釋的部分。
把上面的收益多因素模型改變一下形式,轉化為基金收益和指數收益之差:

ei = ri − [bi1 f1 + bi 2 f 2 + L + bin f n ]
其中括弧中的部分可以看作是一個投資組合的收益。
夏普認為應該選擇合適的權重 bij 使得“追蹤誤差”ei 最小化,或者使 ei 的方差(它是
權重的二次函數)最小化。因為這些指數構成了一個投資組合,所以相應的權重之和應該為
1,並且每個指數的權重應該在 0-1 之間。
(對於基金來說,後面的那個約束條件可以修改為
允許賣空資產。)最優化之後得到的權重被稱為風格權重,並且與其相應的指數共同構成基
準投資組合。我們稱由各種指數按照相應最優風格權重構成的基金與原有基金的風格是相同
的。
可以用二次規劃來最小化樣本期內的追蹤誤差,並得到相應的風格權重。利用 Excel
中的規劃求解過程(選擇“工具
工具”,然後點擊“規劃求解
工具 規劃求解”)可以在工作表中很容易實現上
規劃求解
述計算。
可以通過計算基金收益的方差中由所選擇的風格模型解釋的比例大小來判斷風格分析
的效果。這與回歸分析中經常用到的決定係數 R2 類似,對於第 i 種基金的計算公式如下:

1 − [Var (ei ) Var (ri ) ]


夏普用同樣的一組指數,針對不同的投資基金構造了不同的基準投資組合,並應用上述
方法對這些基金的風格進行比較。下面幾節中我們將針對一個基金,研究它的風格和特徵。
接著,我們將研究風格權重是如何隨著時間改變而改變的,這同時也反映了該基金中各種資
產頭寸的變化。

8.4 簡單風格分析

EUQUITY3 中的 Style1 表包括一個基金和 8 個被動指數的月度收益資料。圖 8.6 給出


了該工作表最上面部分的內容。現在需要求出使誤差方差(單格 M6)最小的權重(單格
D16:J16 中 )。 這 裏 用 Excel 的 規 劃 求 解 過 程 來 實 現 。 注 意 : C16 中 的 公 式 是
1-SUM(D16:J16),這保證了所有的風格權重之和為 1。
進行分析前,應該先給出風格(單格 L21:L80)和追蹤誤差(單格 M21:M80)的有關公式。
第一個月的風格計算公式(單格 L21)為:

= SUMPRODUCT ($C $16 : $ J $16, C 21: J 21)

Style Analysis :風格分析


Solver-Style Model:利用規劃求解進行風格分析的模型

【參照書中第 145 頁的圖 8.6】

圖 8.6 工作表 Style1 中的簡單風格分析

公式中用 SUMPRODUCT 函數把風格權重和相應的指數收益相乘。第一個誤差項


(L21)就是單格 B21 中的基金收益和風格收益之差。同樣我們可以應用上面的公式計算出
其他月份的風格和誤差,這時單格 M6 中的誤差方差可以用樣本方差函數計算出來:
= VAR ( M 21: M 80)
因為誤差方差值一般很小(這裏是 0.0006) ,為了提高優化的精確性,在此基礎之上加
上了規模誤差方差值(乘以 10000)(如單格 M5 所示)。
第 15 和 17 行給出了權重的最小、最大值等約束條件,在此約束基礎上我們可以用規
劃求解來最小化單格 M5 中的規模誤差方差。圖 8.6 的最上面對規劃求解和得到的風格權重
進行了一些詳細說明。上述最優化過程可以通過功能表操作和編程來實現。功能表操作就是
使用工具中的規劃求解;編程則要通過副程式直接調用規劃求解中大量不同種類的函數。第
8.8 節將簡要介紹了相應的、在 ModuleM 中名稱為 Style1 的相應宏。同時按下組合鍵
Ctrl+Shift+S 可以調用該宏。
宏 Style1 還可以生成一個表,其中包括對於選定的指數使基金收益的誤差方差最小的
風格權重。從表中可以看出,在所研究的期間內,該基金的業績相當於這樣一個投資組合:
index3 的權重為 57.8%,index5 的權重為 14.2%,index4 的權重為 7.6%…。此例中選擇
的風格可以解釋基金收益 95.6%的波動性。總之,根據一個特定基金的風格權重可以構造
一個基準投資組合,在所研究的期間內該組合收益等於基金收益,根據該基準組合就可以比
較不同的主動基金經理的投資管理水準了。

8.5 滾動時段風格分析
滾動時段風格分析

前面一節中定義的風格實際上是整個研究期間內的風格平均值,要注意到風格是隨時間
不斷變化的。另一種分析方法是對於一系列連續的時期進行一系列的風格分析,這樣我們可
以 看出 隨著時 間的 變化, 風格 是否一 致。這 種滾 動時 段的風 格分析 有時 被稱 為暴露
(Exposure)分析。
如圖 8.7 所示,我們分別對前 24 個月、第 7-30 月等時間段的收益進行了風格分析,得
到了 7 個風格分析的時序資料(每次分析與前面的分析都有 18 個觀測是相同的)。
跟上一節相比,使用試算表計算時需要格外注意的是:計算每次風格分析的誤差方差時
要正確選擇相應的誤差項(如計算前 24 個月的誤差方差時要選擇相應的 1-24 月的誤差值,
而不要選擇 2-25 月等)。為了做到這一點,可以用 Excel 中建議的格式使用 INDEX 命令,
從而為方差計算公式選擇正確的開始和結束單格。單格 M23 給出了每次風格分析中計算誤
差方差的公式,其中開始月份列在 J6,結束月份列在 J7 中:

= VAR ( INDEX ($ M $38 : $ M $97, J 6,1) : INDEX ($ M $38 : $ M $97, J 7,1))


如果 J6 中的數值為 1,J7 的數值為 24,那麼上面公式等價於公式 VAR(M38:M61)。

Rolling Period Style Analysis-Exposure:滾動時段風格分析-暴露分析


Solver-Exposure Model:利用規劃求解進行暴露分析的模型

【參照書中第 147 頁的圖 8.7】


圖 8.7 工作表 Style2 中的暴露模型分析

最好使用宏來自動實現重複的風格分析。在 ModuleM 表的 Style2 宏裏,首先確定合適


的目標單格、可變單格和約束條件來建立規劃求解。在重複執行規劃求解的過程中,正確選
擇誤差方差的起止範圍(第幾月開始到第幾月結束) ,用規劃求解來最小化誤差方差,並且
把求出的權重複制到輸出區域。圖 8.8 給出了風格分析權重的時序資料圖。同時按下
Ctrl+Shift+E 這個組合鍵可以調用該巨集。

Exposure Analysis:暴露分析

【參照書中第 147 頁的圖 8.8】

圖 8.8 在滾動時段分析中改變風格權重

我們可以用暴露權重(從過去的 24 個月的資料估計得到)構造一個基準投資組合,並
比較該組合和主動基金在當月的業績。月末就可以比較主動基金和它的暴露基準組合的收益
情況,兩者業績的差異被稱為當月的選擇收益(Selection Return)
。這個選擇收益度量了在
該風格部門裏選擇的股票的影響和當月對基金所作的動態調整引起不同部門相應權重變化
的影響。例如,一個基金中某部門業績較好的股票的比重較大時將為其帶來正面影響,而增
加業績不好部門的頭寸將為其帶來負面影響。對一些月份的資料進行上述分析,就可以得到
該主動基金的累積選擇收益。夏普給出了如何用 t-檢驗來檢驗平均選擇收益的顯著性。

8.6 風格權重的置信區間

到現在為止,已經估計了風格權重(分別在簡單和滾動的基礎上) ,但是仍然不知道這
些權重的估計值是否顯著不為 0。為了使用統計方法來檢驗這一點,需要計算風格權重估計
值的標準差。
理論狀態下,風格分析中使用的指數應該是相互獨立的,因此任意指數的收益與其他指
數的收益不相關。實際上,指數一般包括多種可用資產,因此有時候與其他指數相關性較高,
不滿足理論假設。現在需要做的是從風格分析中去掉那些與其他指數過於相似的指數(替
代),這樣餘下指數的相關性就大大降低了。例如,開始分析的時候可能有 8 種指數,而經
過逐步篩選將剔除 4 種相關性較強的指數,最後可能利用互補性最強的 4 種指數進行風格
分析。
判斷指數之間替代性或互補性的一種方法是計算不同指數收益的相關係數矩陣。那些容
易被其他指數複製的指數與其他指數的相關性很強。如圖 8.9 所示,指數 3,6 和 8 與其他
四種指數的相關係數都在 0.5 以上。與之相反,那些很難複製的指數與其他指數的相關性較
差。例如,指數 1 和 2 與其他指數的相關係數都在 0.25 以下。
Correlation Matrix for Style Index Returns:風格指數收益的相關係數矩陣

【參照書中第 148 頁的圖 8.9】

圖 8.9 風格指數收益的相關係數矩陣

風格分析是在有約束的線性回歸基礎上發展起來的,因此,應該可以找到風格權重的置
信區間。這可以通過用其他的指數來估計該指數的風格來實現(Lobosco 和 DiBartolomeo
於 1997 首先指出了這一點)。上述風格的估計過程中沒有權重進行約束(除權重之和必須
為 1 之外),因此對於每個指數都會帶來一個無法解釋的波動率。這與前面介紹的評估基金
業績的風格模型有較大差別:那個模型中,為了得到所估計的風格權重的標準差(和置信區
間),首先給出了模型的主動標準差。這些都展示在圖 8.10 和 8.11 中。

Confidence Intervals for Style Weights


風格權重的置信區間
Solver-Style Model for Confidence Intervals:
利用規劃求解進行風格置信區間分析的模型

【參照書中第 149 頁的圖 8.10】

圖 8.10 工作表 Style3 給出的風格係數的置信區間

需要這樣一張試算表,它把指數收益矩陣自動分為兩部分:B 列是選定的單個指數的收
益 j ;D 到 J 列是餘下那些指數的收益。用單格 B10 中的 j*值和 INDEX 命令把選定的單個
*

指數分離出來。這裏用陣列的形式來返回收益陣列中選定單格的數值。上面的這些步驟用公
式表示在 B21 中就是:

= INDEX ($ P$21: $W $80, A21,$ B$9)


為了更方便的分開餘下的那些指數,可以設計一個名為 StyleSubMatrix 的用戶定義函
數,表 Module1 中介紹了該函數的一些具體的情況。
雖然現在對於單個指數的權重沒有約束條件,但是還需要仿照表 Style1 的方式創建新
表並用規劃求解進行計算。這時使用巨集 Style3 分析單個指數(用組合鍵 Ctrl+Shift+J 調
用)
、在集中分析 8 個風格指數時使用巨集 Style4(用組合鍵 Ctrl+Shift+K 調用)
。表 ModuleM
詳細解釋了上面這些公式的有關情況。

Confidence Intervals for Style Weights


風格權重的置信區間

【參照書中第 150 頁的圖 8.11】

圖 8.11 工作表 Style3 給出的風格係數的置信區間

利用對每個指數分別求得的主動標準差,估計最初對該基金進行風格分析時得到的風格
權重的標準差。單格 AB16 中的標準差公式為:

= $ AD$5 ( AB14* SQRT ($ AD$6 − $ AD$7 − 1) )


ASD 指數(單格 AB14)是標準差的除數。如果一個指數的 ASD 值比較高,那麼它就
很難用其他指數複製出來,標準差也比較低。這可以通過用權重的估計值除以合適的 ASD
指數實現。公式的計算結果也與最初進行風格分析時的樣本觀測值的數量和不為 0 的風格
權重的個數有關。
應用 t-統計量可以從風格分析中剔除那些 t 值顯著為 0 的指數,使風格分析更為準確 (在
95%的置信度下低於 2) 。
風格分析是一種非常有用的分析方法。自從二十世紀六十年代發展了 CAPM 相關基本
理論(和相關傳統業績評價方法)之後,學者們對如何發現在資產定價市場上出現的反常情
況做了一系列的研究。根據研究結果,投資組合業績的差異(一些時期業績好,另一些事情
業績差)是因為在不同的時期採取了大量的主動投資策略。到了八十年代,人們又發現了小
公司效應和基於股利收益和市盈率(Price-Earning Ratio)的投資策略。九十年代的主要發
現就是市淨率(Market-To-Book Ratio)和動量分析(Momentum)。人們為了發現市場上
可能的反常情況做出了很多努力,其直接結果就是發展了從被動基準投資組合(尤其是在美
國和英國)到模擬主動投資策略的一系列理論。目前風格分析是這些理論中最重要的一種,
因為它給出了一個多因素被動基準投資組合,在此基礎上我們可以比較和評價現有的反常的
主動投資策略的業績。

8.7 Module1 中的用戶定義函數

本模組包括四種業績評價方法所需要的函數。本模組僅僅把試算表中的函數直接轉化為
程式。
其中有一個函數的作用是從收益矩陣中刪除一行並得到維數減少的矩陣,這樣我們就可
以計算風格係數的置信區間了。本質上,該函數是對原有收益矩陣一行一行的完全複製,跳
過需要刪除的那一行(用虛擬變數 jadj)

Function StyleSubMatrix(indxmat, jstar)
’returns style index returns matrix less column j*
Dim i As Integer, j As Integer, jadj As Integer, nr As Integer, nc As Integer
Dim Submat() As Variant
nr = indxmat.Rows.Count
nc = indxmat.Columns.Count
ReDim Submat(nr, nc - 1)
jadj = 0
For j = 1 To nc – 1
If j >= jstar Then jadj = 1
For i = 1 To nr
Submat(i, j) = indxmat(i, j + jadj)
Next i
Next j
StyleSubMatrix = Submat
End Function
8.8ModuleM 中的宏
風格分析的二次規劃公式比求有效組合的二次規劃公式要略微簡單一些。這兩個公式為
權重設定了上下限,但是風格分析中沒有等價於滿足目標收益要求的等式約束。Style1 的副
程式主要是規劃求解的一個簡單應用,它直接使用了規劃求解中的函數。SolverAdd 函數給
出了約束條件,而用 SolverOk 解決:
Sub Style1()
Range(“change1”).Value = 0.1
Range(“A1”).Select
SolverReset
Call SolverAdd(Range(“constraint1”), 3, Range(“con1min”))
Call SolverAdd(Range(“constraint1”), 1, Range(“con1max”))
Call SolverOk(Range(“target1”), 2, 0, Range(“change1”))
Call SolverSolve(True)
SolverFinish
Call Chart1
Application.ScreenUpdating = True
End Sub
Chart1 副程式是用巨集錄製器編寫的,它主要用圖表嚮導在一張新的工作表上作圖。
程式最後兩行的作用是用資料標籤的形式顯示數值並且減少圖表的背景色彩。這些程式都是
用巨集錄製器編寫的,這要比邊看幫助和使用說明邊寫程式簡便得多。注意:這段程式可以
單獨使用,也可以在 Style1 中作為副程式調用。
Sub Chart1()
Charts.Add
ActiveChart.ChartWizard Source:=Sheets(“Style1”).Range(“chart1s”),_
Gallery:=xlColumn, Format:=6, PlotBy:=xlRows,_
CategoryLabels:=1, SeriesLabels:=0,HasLegend:=2, Title:=_
“Style Analysis”, CategoryTitle:= “”, ValueTitle:= “”, ExtraTitle_
:= “”
ActiveChart.ApplyDataLabels Type:=xlShowValue, LegendKey:=False
ActiveChart.PlotArea.Interior.ColorIndex = xlNone
End Sub
副程式 Style2 僅僅是規劃求解函數的重複應用。應該注意在初始化之後,規劃求解是
如何在迴圈之前建立起來的。每次迴圈將調用 SolverSolve 進行下一次風格分析,然後將求
得的權重複制到輸出區域。這裏注意語句 Range(“exp0”).Offset(iter, 1)中的 Offset 是如何在
輸出區域內迴圈使用的。
Sub Style2()
Dim iter As Integer, niter As Integer, rstep As Integer
Range(“exp17”).ClearContents
Range(“change2”).Value = 0.1
Range(“A1”).Select
SolverReset
Call SolverAdd(Range(“constraint2”), 3, Range(“con2min”))
Call SolverAdd(Range(“constraint2”), 1, Range(“con2max”))
Call SolverOk(Range(“target2”), 2, 0, Range(“change2”))
rstep = 6
niter = 7
iter = 1
Do While iter <= niter
Range(“smonth2”).Value = 1 + (iter - 1) * rstep
Call SolverSolve(True)
SolverFinish
Range(“constraint2”).Copy
Range(“exp0”).Offset(iter, 1).PasteSpecial Paste:=xlValues
iter = iter + 1
Loop
Call Chart2
Application.ScreenUpdating = True
End Sub
接下來的副程式 Style3 和 Style4 的編寫方法,與上面介紹的兩段副程式類似。

小結

本章從兩個不同視角研究了投資組合業績的評價方法。第一視角的研究方法不是很細
緻,主要是在前面一章的理論基礎之上發展的傳統業績評價方法。第二視角則根據多因素模
型進行風格分析,並給出更為準確的判斷標準。
傳統的評價方法是根據投資組合收益和風險的歷史資料對組合進行簡單排序。這些方法
很容易用試算表實現,但是它們是由單因素(CAPM)模型發展出來的,也缺乏統計上的說
服力和準確性。
基於部分股票的價格是不合理的假設基礎之上,特雷納和布萊克根據 CAPM 模型給出
了“主動-被動”模型。該模型主要的任務是將主動投資組合與市場組合結合起來,構建一
個最優風險投資組合。可以看到,第 6 章中提到的常見組合問題可以用來解決在“主動-被
動”模型中遇到的問題。
在建立 CAPM 模型後的幾十年裏,學者們為了找到可以反映風險回報的、不同於β值
的其他評價指標做了不計其數的實證研究。為了發現市場上潛在的定價偏差(如規模、市淨
率),又發展出來一些更為專業的指標(如大盤股、小盤股、價值和成長) 。這些研究成果推
動了多因素模型的發展,進一步為建立更好的投資組合業績評價基準打下基礎。
本章介紹了風格分析的方法,它是一種以多因素模型為基礎的主動投資策略的評價方
法。這種方法需要用二次規劃來解決問題(就像在第 6 章那樣),具體的實現過程可以使用
Excel 工作表中的規劃求解或者是宏。可以對一段時期進行風格分析,但更為有用的是對一
系列連續的流動時期進行風格分析,這樣可以發現風格模式(Style Pattern)隨時間的變動
情況。
與傳統的評價方法不同,利用風格分析可以進行統計推斷。在對標準風格分析進行修改
的基礎上,可以給出風格權重的置信區間。同樣可以檢驗一個主動基金隨時間變化的
Selection Return 在統計上的顯著性。
從二十世紀五、六十年代創建的投資組合最優化和資產定價理論到九十年代的風格分
析,在這些理論的發展過程中,夏普做出了很大貢獻-他發展了 CAPM 模型和風格分析。正
如我們在附注的試算表中看到的那樣,這是理論和實際應用的一次完美結合,幫助我們更全
面認識了股票。

參考文獻
Bodie, Z., A. Kane and A. J. Marcus, 1996, Investments, 3rd Edition, Richard E. Irwin,
Englewood Cliffs, NJ.
Lobosco, A. and D. DiBartolomeo, 1997, “Approximating the Confidence Intervals For
Sharpe Style Weights”, Financial Analysts Journal, July/Aug, 80-85.
Sharpe, W. F., 1992. “Asset Allocation: Management Style and Performance
Measurement”, Journal of Portfolio Management, Winter, 7-19.
Treynor, J. and F. Black, 1973, “How To Use Security Analysis To Improve Portfolio
Selection”. Journal of Business, 46, 66-86.
第 9 章 股票期權介紹

期權的重要性是不容置疑的。自從 1973 年,布萊克和邁倫。舒爾斯出版了最早關於期


權定價的論文以來,大量的金融產品被開發出來並在全世界交易。而且,除了股票,該理論
還延伸到債券以及實物資產等領域。
看漲期權(Call Option)是一種能夠以預先協定的執行價買入某種資產的權利;看跌期
權(Put Option)則是一種能夠以預先協定的執行價出售某種資產的權利。歐式期權
(European option)只允許在到期日執行,而美式期權(American option)則允許在到期日
之前(包括到期日)的任意時刻執行。儘管布萊克-舒爾斯定價模型是用來對歐式期權定價
的,但實際交易中大多數是美式期權。
本書期權部分的結構有別於股票部分。本章總體介紹了期權的概念和理論,這些內容將
在下面四章中作詳細介紹。研究期權定價的目的是為各種衍生工具定價,下面的章節將介紹
各種不同的定價方法。這些方法的適用性部分依賴于期權的類型,以及布萊克-舒爾斯定價
模型及其擴展模型是否適用。如果不適用,可以使用其他的數值方法。本章介紹期權定價的
一些主要思想,在後續四章的試算表模型中會逐步充實這些內容。有些概念是環環相扣的,
很多地方都需要用到它們,因此在本章提前介紹,然後在以後的章節擴展。
不同定價方法將在工作簿 OPTION1,2,3,4 的工作表中演示。一些小例子用來展示
計算過程,用戶定義函數中也包含這些計算過程。由於可以通過設置反映問題大小的參數(如
二叉樹定價的期數,模擬的次數等)來推廣函數的使用,所以這種方式功能強大而且能自動
處理大型計算。
本章首先介紹期權定價的發展歷史,然後引入布萊克-舒爾斯定價公式,接下來介紹有
關對沖投資組合(hedge portfolios)以及風險中性定價(risk-neutral valuation)的主要思想。期
權的有些性質本章先不作介紹,例如歐式、美式期權的區別,波動率估計以及看漲期權和看
跌期權的關係等等。最後討論期權定價的數值方法。主要的定價方法包括二叉樹(binomial
tree)的運用(第十章)及其模擬(simulation)(第十二章)。第十一章重點介紹布萊克-舒爾
斯定價公式,第十三章討論某些假設條件(如對數收益的正態性)不成立情況下的定價方法。
象討論股票那樣,本書強調的是理解並在試算表中實現有關期權的計算。本章並不介紹
期權的所有背景理論,對於有關細節問題,建議讀者查看相關的專業書籍(如赫爾,2000
及 Bodie et al.1996)
。例如,簡單期權的基本定義,它們的盈虧狀況圖,以及看漲和看跌期
權的平價關係等在赫爾的第 1 和第 7 章,及 Bodie et al 的第 19 章中有介紹。期權定價的基
本理論在 Bodie et al 的第 20 章有介紹,更深層次的內容可以在赫爾的第 9,10 和 11 章中
找到。

9.1 布萊克-舒爾斯公式的起源
布萊克 舒爾斯公式的起源

費希爾·布萊克(1989)曾進寫過一篇短文介紹他和邁倫。舒爾斯怎樣得出著名的布萊
克-舒爾斯公式,為了強調其對現代金融學的傑出貢獻,這裏重點介紹其中的一些觀點。在
他們的分析中,核心思想是可以用一定數量的股票和一份期權構造一個完全對沖的組合。術
語“對沖(hedge)”的含義是,由於期權價值的變動可以抵消股票價格的變動,因此組合資
產的價值在一段較短時間內不隨股票價格的變化而變化。因此,對沖投資組合也是一種無風
險組合。
接下來,在 1965 年發表的論文中提出了資產定價模型(CAPM),許多研究機構設法
將它運用於股票以外的其他領域,如債券,企業現金流,以及認股權證(warrant)等。當
時(1965)的認股權證市場(由企業發行的一種長期期權)發展迅速,遠甚於 OTC 市場短
期期權。
學者們首先估計認股權證在到期日的預期收益,然後將其折現來得到其價格,這種方法
忽略了股票的預期收益以及合理的折現率。布萊克發現認股權證的價值由股票的總風險決定
而不是由股票的預期收益決定。
布萊克和舒爾斯發現,股票的預期收益等於確定狀況下的無風險利率,因此,期權的預
期收益也可以用這個利率折現得到。他們的手稿(1970 年)提出了著名的布萊克-舒爾斯公
式,但當時卻被《政治經濟雜誌(Journal of Political Economy)》拒絕!在默頓·米勒和吉
恩·法馬的幫助下,文章才在 1971 年 8 月被接收,但要求作進一步的修改。文章最終發表在
《政治經濟雜誌》1973 年 5/6 月期刊上。同樣在 1973 年,這不僅是巧合,芝加哥期權交
易所(Chicago Board Option Exchange)成立,交易 16 家公司的股票看漲期權。
現在看來,布萊克-舒爾斯公式其實並不複雜,但是它在期權定價理論方面得到廣泛應
用,而且邁倫·舒爾斯和羅伯特·默頓也因此在 1997 年 10 月獲得諾貝爾經濟學獎,這些足以
說明它的重要性。可惜布萊克在 1996 年去世,因此未能享受這一殊榮。
簡要介紹完布萊克-舒爾斯公式的歷史後,接下來看一看實際的布萊克-舒爾斯公式。

9.2 布萊克-舒爾斯公式
布萊克 舒爾斯公式

布萊克-舒爾斯公式可以直接給歐式期權定價,但它也可以為其他一些期權定價(歐式
期權的特點是僅能在到期日執行) 。股票部分已經提到過,假定期權標的股票對數收益服從
正態分佈。假設期權(標的股票的即期價格為 S)是一個看漲期權,期限為 T,只有在到期
日才能執行,執行價格為 X。那麼在 T 時刻,期權的收益為:

max(S T − X ,0)

S T 是標的股票在 T 時刻的價格,是一個服從某種概率分佈的隨機變數。
通常可以將股票價格的運動看成是一個隨機過程,或者更準確的說,是幾何布朗運動(這

種股票價格運動模型可以參看赫爾的第 10 章)。使用數學語言,這意味著隨機變數 S T 可以

寫成隨機的形式:

S T = S exp(YT ) = S exp( µ T − εσ T )

這裏,隨機變數 YT 服從正態分佈,而變數 ε 則服從標準正態分佈,即其均值為 0,標準差

為 1。 YT 的均值為 µ T ,標準差為 σ T ,並且有:

µ T = ( µ − 0.5σ 2 )T , σT = σ T

其中 µ 是股票的期望收益, σ 是股票的年波動率。由於 YT 等於 ln( ST S ) ,則 ln( ST S ) 同

樣服從正態分佈,即股票的對數收益服從正態分佈。
在布萊克-舒爾斯分析方法中,看漲期權可以與一定數量的標的股票構成完全對沖的無
風險組合。因此這個組合的收益必須等於無風險收益。用一個偏微分方程(應用數學中常見
的熱擴散方程)表示。該方程的解就是布萊克-舒爾斯公式。
歐式看漲期權(不支付紅利)的布萊克-舒爾斯定價公式為:

c = SN (d 1 ) − X exp(−rT ) N (d 2 )
其中, S 為股票的即期價格, X 為期權在 T 時刻的執行價,r 為複利計算的無風險利率,因

此運算式 exp(− rT ) 為 T 時段的無風險折現因數, N ( d ) 為 d 的累積標準正態分佈函數。這

裏, d 1 和 d 2 可以表示為:

d 2 = ln( S X ) + (r + 0.5σ 2 )  σ T

d 2 = ln( S X ) + (r − 0.5σ 2 )  σ T
我們將在第 11 章更加深入的分析布萊克-舒爾斯公式。注意,股票的期望收益 µ 並沒有出現
在公式中。在我們完全理解對沖組合的重要性後,就會明白其中的原因了。

9.3 對沖投資組合(
對沖投資組合(Hedge Portfolios)

在布萊克-舒爾斯公式中一個令人感到驚訝的地方是,股票的期望收益 µ 沒有出現在運
算式中。然而,這可由下面來解釋,可以創建對沖投資組合,且公式中使用無風險利率。但
是,術語“對沖投資組合”的確切含義是什麼呢?
布萊克-舒爾斯看漲期權公式可以寫成下面的形式:

c = hS − B ,其中 h = N (d 1 ) , B = X exp(− rT ) N (d 2 )
等式右邊的投資組合,包括一定數量的股票和無風險貸款,它可以完全複製左邊的看漲期權
(該變數即“複製組合(replicating-portfolio)”)
。 布萊克-舒爾斯公式顯示,看漲期權的
價值必須等於複製組合的淨投資值。

將布萊克-舒爾斯公式變型為 B = [hS − c ],就可以用看漲期權來構造一個對沖組合。買

入 h 數量的股票,賣出一份看漲期權,即可構造出一個固定價值為 B 的對沖組合。我們用 h

來代替 N ( d1 ) ,由此可以看出,對沖比率 N ( d1 ) 實際上是用來對沖期權價格變動風險的股

票數量。
假設在某一時段,股票價格的變動只是簡單地以一個確定的比率上漲或下跌,即簡單的
單期二叉樹過程。例如:假設在 t=0 時刻,股票的即期價格為 100(S) ,在 t=1 時刻,股
價如果上漲,則為 115(上漲比率為 1.15);股價如果下跌,則為 95(下跌比率為 0.95)。
如果期權在 t=1 時刻的執行價格為 100,那麼在到期日,期權的收益要麼為 15(股價上漲) ,
要麼為 0(股價下跌),見圖 9.1。
注意,目前並不知道股票上漲或下跌的概率。但是,如果買入 0.75 份的股票,而賣出
1 份看漲期權,這個對沖組合將得到一個確定的收益 71.25(上漲時為 0.75×115-15;下跌時
為 0.75×0.95)。由於組合的價值不依賴於股票的最終價格,即它是無風險的,因此該組合在
這個時段必須獲得無風險收益,如 5%。所以將 t=1 時刻的收益折現到 t=0 時刻的折現因數
應為 1 1.05 。使淨投資運算式(0.75*100-c)與折現收益( 71.25 1.05 )相等,可以求得期

權的價格 c(等於 7.14)。


通過分析布萊克-舒爾斯公式,可以得到構造對沖組合的合理對沖比率(h=0.75)以及
期權的價格(c=7.14)。

【參照書中第 160 頁的圖 9.1】

圖 9.1 股票價格變動的單期二叉樹模型

歸納一下圖 9.1 中的例子以及圖 9.2 中的符號說明,可以得出,如果 huS − cu = hdS − c d ,

即 h = (cu − c d ) [S (u − d )],則投資組合在 t=1 時刻的收益就是確定的。

因此,對沖比率為測量期權價格變動相對股票價格變動的比率。

【參照書中第 161 頁的圖 9.2】

圖 9.2 股票、看漲期權及對沖組合在單期二叉樹模型中的符號表示

9.4 風險中性定價

對沖組合的存在使得我們可以運用風險中性定價方法來計算期權價格。在風險中性的世
界裏,所有的投資者都對風險無所謂,因此所有的資產(並不限於布萊克-舒爾斯分析中的
對沖組合)可以通過對其預期收益折現來定價。注意,這裏並沒有說所有資產的風險都是相
同的,或者真的無風險,只是說在採用這種定價方法時可以假設投資者是風險中性的。
在風險中性的世界裏,期權的價格等於其預期收益按無風險利率折現的現值,即:

c = exp( − rT ) E Q [max( S T − X ,0)]

其中, E Q 指在風險中性概率測度 Q 下的期望收益。變換一下布萊克-舒爾斯公式,就能夠

更加清楚地看出這一點:

c = exp(− rT )[S exp(rT ) N (d 1 ) − XN (d 2 )]

上面方括號中的運算式就代表期權的期望收益。 N ( d 2 ) 則表示期權在風險中性條件下被執

行的概率。
在接下來的章節中,將會不斷出現有關風險中性條件下的期權價格計算。例如,在第
10 章,二叉樹將會提供一種計算期望收益的結構,而在第 12 章,蒙特卡羅模擬和數值積分
技術都提供了計算期望收益的代替方法。

9.5 風險中性定價的單期二叉樹模型

前面已經討論了在風險中性條件下的定價問題,當時只簡單地假設股票的變動是單期二
叉樹過程。在風險中性條件下,所有的資產都有相同的期望收益,因此股票和債券的期望收
益相同。然而,債券可以帶來確定的固定收益,比如說 5%,而與股票的收益無關。假設股
價上漲時股票的收益為 15%,而股價下跌時收益為-5%。接下來就是要找到股價上漲和下跌
的隱含概率,使得股票的期望收益與債券相等。
資產的期望收益是其各種可能收益的加權平均,記股價上漲的概率為 p,則股票的期望
收益為:

(15%) p + (−5%)(1 − p )
結果取決於 p 值的大小。如果假設 p=0.5,則股票的期望收益為 0.5,正好與債券相同。我
們稱此時的 p 值(0.5)為風險中性下的隱含上漲概率。
結合圖 9.2 中的符號,如果股票在 t=0 時刻的價格為 S,而在 t=1 時刻,股價上漲時為
uS,概率為 p;股價下跌時為 dS,概率為 1-p,則股票在 t=1 時刻的期望收益為:

uSp + dS (1 − p )
其中 u 和 d 分別為股票價格的相對變化量。如果單期的無風險利率為 r,則根據風險中性定
價,可以得到:

[uSp + ds(1 − p)] (1 + r ) = S 也就是 p = [(1 + r ) − d ] [u − d ]

(嚴格地說,對於時間段 τ ,折現因數應該是 exp(− rτ ) ,而不是簡單的 1 (1 + r ) ,因此,

隱含概率為 p = [exp(rτ ) − d ] [u − d ] 。)

得到了隱含概率(implied probabilities)後,就可以利用它們求其他資產進行風險中性
定價。看漲期權的價格其實就是期權加權平均收益的現值(或折現值) 。如果期權的執行價
格為 100,則股價為 115 時收益為 15,而股價為 95 時收益為 0。因此,該期權的期望收益

為 0.5×15=7.5。用無風險折現因數對其折現(使用前面提到的單期折現因數 1 1.05 )
,可以

得到期權的價格為 7.14,這與前面用對沖組合得到的結果一致。
風險中性定價方法適用於所有資產,而不僅僅是無風險資產。相應的股票現值為[(115)
×0.5+(95)×0.5]=100.0。
很明顯,多期二叉樹是對單期二叉樹方法的改進,它會給出一個更精確的股票終值

( ST )
,也更加接近股票價格的分佈。例如,如果期權的有效期是三個月,那麼一個兩期二

叉樹將有三個不同終值,一個九期二叉樹將提供十個不同終值,即 n 期二叉樹將提供(n+1)
個不同終值。對於一個九期二叉樹,每期代表 1/3 個月。我們需要知道二叉樹每期時段的長
短,股票價格向上(或向下)運動的概率,以及價格在經過九期變化後的累積效果是否與我
們假設的股價分佈模型一致。終值服從二項概率分佈,當期數增加,離散的二項分佈將逐步
接近連續的正態分佈。增加期數的目的是為了用二叉樹模擬前面提到的隨機過程,也就是假
設股票價格服從的幾何布朗運動。
通過對某一時段股價變化建模,可以用一個多期二叉樹來模擬布萊克-舒爾斯方法中的
正態分佈。由於該方法廣泛地用於對各種期權定價,因此二叉樹定價的基本方法將在下一章
做深入分析。

9.6 期權平價關係(
期權平價關係(Put-Call Parity)

前面的布萊克-舒爾斯公式計算的是看漲期權價格。和看漲期權一樣,也有看跌期權,
它提供一種在到期日能夠以執行價 X 出售資產的權利。在經過時段 T 後看跌期權的收益為:

max( X − S T ,0)
歐式看漲期權和看跌期權(僅能夠在到期日執行)之間存在一種非常有名的關係,被稱為看
漲期權和看跌期權的平價關係,如果看漲期權和看跌期權的標的股票(當前價格為 S)相同,
且執行價也相同,則有關係式:

c + X exp(− rT ) = p + S
其中, p 是看跌期權的價格。右邊看跌期權和股票的組合完全複製了一看漲期權和負債的
組合。這意味著看漲期權的定價公式很容易應用於看跌期權。因此,布萊克-舒爾斯關於看
跌期權的定價公式為(標的股票沒有紅利):

p = − SN (− d 1 ) + X exp(− rT ) N (− d 2 )

注意,看跌期權的對沖比率等於 − ( N ( − d1 )) = ( N ( d1 ) − 1) ,為負值,而看漲期權的對沖比

率是 N ( d1 ) ,為正值。

一般不推薦用兩個不同的公式來計算看漲期權和看跌期權的價格。偏向通過試算表和一
個帶參數‘iopt’的 VBA 函數來計算看漲期權和看跌期權的價格,當參數為 1 時計算看漲
期權,為-1 時計算看跌期權,這比複製看漲期權公式,然後作微小修改得出的看跌期權公
式要好一些。
9.7 紅利(
紅利(Dividends)

初期的布萊克-舒爾斯公式並不考慮紅利,但是默頓擴展了這個公式,將紅利納入考慮
範圍,並用於給其他期權定價,如外匯期權等。默頓在模型中將紅利處理成一個連續的年紅

利收益 q。只需將初始布萊克-舒爾斯公式中的股票即期價格 S 用 S exp(-qT)替代就行了,d 1

和 d 2 的運算式也作相應的修改。

在風險中性條件下,沒有紅利收入的股票只能得到無風險收益 r。如果股票有紅利,它
的總收益仍然為 r,但是該收益被分為兩部分,(r-q)為股票價格收益,q 為紅利收益。紅利
將降低看漲期權的價值,因為在執行時,部分資產(紅利)已經流失掉了。相反地,紅利會
增加看跌期權的價值,因為在執行時已損耗了資產的一部分價值。

9.8 美式期權的特徵

美式期權能夠在到期日或到期日前的任何一天執行。這使得二叉樹方法更能滿足實際需
要,因為它可以很方便地處理期權提前執行的問題。而布萊克-舒爾斯公式則只能給歐式期
權定價,因為它處理不了提前執行的問題。
提前執行是否能提高期權的價值,這取決於紅利。例如,即使標的股票沒有紅利,提前
執行美式看跌期權也是合理的。這種看跌期權一般會在股價大幅度下跌或利率上漲之後被執
行。而對於沒有紅利的看漲期權,提前執行則是不明智的;但對於有紅利的股票,提前執行
期權則可能會獲得較多的紅利收入。
二叉樹方法在每一個節點上拿歐式期權的價格與立即執行期權所得的回報作比較,這樣
就可以得到美式期權的價格了。因此,二叉樹方法為美式期權提供了一個最理想的執行策
略,關於美式期權定價將在第 10 章的後半部分介紹。

9.9 數值方法

計算統計期望值是所有期權定價數值方法的核心。隨著二叉樹期數的增加,正態分佈與
二項分佈會越來越接近,正是利用這一點,二叉樹方法為揭示布萊克-舒爾斯公式背後的原
理作出了重要貢獻。利用二叉樹對股票價格運動過程建模,能夠計算期權有效期內所有中間
節點的收益。然後結合期權定價過程的“倒推(backward)”特性,就很容易為美式期權
定價了。實際上,二叉樹方法是準確並有效地為美式期權定價的基礎。第 10 章將集中介紹
二叉樹理論,包括構建樹的不同方法,如何利用二叉樹為期權定價,以及以布萊克-舒爾斯
公式為基準,測試不同樹的準確性。
二叉樹方法還可以看成是一種有效生成股票價格運動軌跡的方法。雖然,二叉樹丟失了
一些資訊(例如,丟失了一些特殊的運動軌跡),但大大提高了效率。
對於依賴路徑的期權,還可以用一些其他的數值方法,最典型的是蒙特卡羅模擬。對於
標準期權,蒙特卡羅模擬用服從正態分佈的隨機變數來生成到期日的股票價格。與標準期權
的二叉樹方法相比,蒙特卡羅模擬的效率較低,因為它需要用亂數類比大量路徑(為了提高
樹 的 精 確 度 )。 可 以 在 類 比 時 使 用 ‘ 對 偶 變 數 ( antithetic variates ) ’ 或 ‘ 准 隨 機
(quasi-random)’數來提高效率,後者尤其有效。而對於更加複雜的期權,蒙特卡羅類
比需要記錄所有路徑上的中間股票價格,這樣就可以為奇異期權(此類期權的收益由標的資
產價格運動的特殊路徑決定)定價。第 12 章將集中討論蒙特卡羅模擬。
數值方法將布萊克-舒爾斯分析的應用範圍從歐式期權定價擴展到美式期權定價(用二
叉樹方法) ,並進一步到路徑依賴期權定價(用蒙特卡羅模擬) 。自 80 年代中期以來,個人
電腦的處理能力得到迅猛發展,使得試算表如 Excel 能夠利用內嵌函數計算累積正態分佈的
概率。第 10 至 13 章中試算表的所有分析解幾乎都能立即算出。例如,第 10 章的二叉樹定
價(即使有 1000 期)結果能夠在 15 秒內得出,而一個計算標準期權價格的蒙特卡羅模擬
(10000 次試驗)使用 Excel 也不到 45 秒。對絕大多數標準期權來說,二叉樹方法(特別
是使用萊森和賴默方法)和蒙特卡羅模擬都能為其準確而有效地定價。

9.10 波動率和非正態股票收益

有關期權定價的最後一章(第 13 章)將集中討論波動率,它是定價時要考慮的最重要
因素,還將討論當前處理非正態分佈的方法。
布萊克-舒爾斯公式中,唯一沒有直接給出的參數是股價未來的波動率。儘管可以用股
價的歷史資料給出未來波動率的一個預測值,但未來波動率的資訊應該隱含在期權的市場價
值中。因此可以通過布萊克-舒爾斯公式反推得到。隱含波動性是指能使布萊克-舒爾斯期權
價格與期權市場價格相等的波動水準。因此,期權交易與波動率關係密切。如果交易者認為
真實波動率將大於隱含波動率,那麼他會認為期權價格被市場低估了(反之亦然) 。
布萊克-舒爾斯公式建立在股票對數收益服從正態分佈的基礎上。但由於偏度和峰度的
存在,實際股票收益的分佈與嚴格的正態分佈有所偏離。這會影響二叉樹定價的精度。第
13 章將提出一些方法來解決非正態分佈的問題,特別是魯賓斯坦方法,它採取標準二叉樹
來處理非正態問題。

小結

看漲期權是一種以協議執行價買入資產的權利。而看跌期權則是一種以協議執行價出售
資產的權利。歐式期權只能在到期日執行,而美式期權可以在到期日及到期日之前的任意時
刻執行。
股票期權的價格取決於標的股票的當前價格、執行價格、到期日、股價波動率,以及無
風險利率(和期權到期前的紅利)。
單期二叉樹模型是最簡單的期權定價方法。採用複製投資組合的方法,可以得到對沖比
率和期權價值。無須對股價上漲或下跌的概率作任何假設。
布萊克-舒爾斯定價公式給出了歐式期權定價的解析解,它假設股票的對數收益服從正
態分佈。
在布萊克-舒爾斯分析中,需定價的期權與一定數量的股票構成對沖投資組合。對沖比
率確保該組合是無風險的,期權價值的變化將完全抵消股票價格的變化。
布萊克-舒爾斯期權定價分析同樣可以用來計算‘隱含’或‘風險中性’概率,從而使
風險中性定價成為可能。利用這些概率,期權的價值等於它期望收益(在風險中性條件下)
用無風險利率折現的現值。

參考文獻
Black.F.,1989,”How We Came Up With The Option Formula”, Journal of Portfolio
Management,Winter,4-8.
Bodie,Z.,A.Kane and A.J.Marcus,1996,Investment,3rd edition,Richard D.Irwin,Englewood
Cliffs,NJ.Hull,J.C.,2000,Options,Futures and Other Derivatives,Prentice Hall,New Jersey.
第 10 章 二叉樹

最初引入二叉樹是為了提供一種簡單的方式來理解布萊克-舒爾斯分析。在布萊克-舒爾
斯分析中,通過用二項分佈近似對數收益的正態分佈,可以方便地利用二叉樹給股價過程建
模。
在風險中性的條件下,可以通過構建對沖組合來為期權定價。這時需要計算期權收益的
期望值。用三種不同的方法來構建二叉樹(使用不同的參數),並將它們作對比(用提出者
的名字命名:JR 樹,Jarrow 和拉德;CRR 樹,考克斯,羅斯和魯賓斯坦;LR 樹,萊森和
賴默) 。每種方法的價格相對變化量及其概率都是不同的。先以歐式期權為例,用 JR 樹給
其定價,然後介紹有名的 CRR 樹。在討論完二叉樹定價計算的值近似收斂於布萊克-舒爾斯
期權價格後,再簡要介紹 LR 樹。選擇不同的參數組合似乎很困難,但選擇最佳參數會比其
他參數有效的多。通過用不同模型對歐式期權定價發現,利用 LR 樹計算出的價格與由布萊
克-舒爾斯公式得出的值很接近(即使在期數很少的情況下)。
二叉樹因能為美式期權定價而出名,美式期權可以在到期日前(包括到期日)的任意中
間時刻執行。這裏將演示怎樣改進 CRR 樹使之能對美式期權定價。赫爾(2000)教科書在
第 9 章以及第 16 章前面部分介紹了用二叉樹方法給歐式和美式期權定價的相關背景知識。
但是它完全基於 CRR 樹。

10.1 二叉樹介紹

二叉樹是前面介紹的單期二叉樹的擴展。例如,如果一個樹有九期,在每一期股價都有
向上或向下運動兩種可能,則它的最終位置將由這些向上或向下運動的序列決定。股價從最

( )
初值到終值,共有 512 = 2 條路徑,雖然只有一條路徑到達股價的極值節點(即股票最高
9

或最低價) ,但到達中間兩個終值節點的路徑則有 126 條。儘管最後有十個不同的終值,但


到達中間終值節點的概率要比到達極值節點的概率大的多。經由各種路徑到達每個終值節點
的概率近似服從正態分佈。另外,這種採用不同路徑來得到終期價格的二叉樹方法比模擬方
法更有效率。
再來考慮期權定價,該樹可以看成是一個有 512 條路徑的樣本空間,每條路徑末端的
期權收益都用到達末端節點的概率加權。如果期權不能提前執行,則將末端節點的價格按概
率加權求和,從而得到期權的期望收益。將其折現即可得到期權的價值(即現值)。由於使
用了風險中性定價,因此折現因數由無風險利率以及到期時間決定。
選取不同的向上(向下)運動概率以及期間長度,就可以構成不同的二叉樹方法。其中
有兩種參數選擇方法我們很熟悉。JR 樹假設股價向上和向下運動的概率相同(即 p=0.5);
CRR 樹則假設股價向上與向下運動概率的乘積為 1,即 d=1/u。不同的參數能夠產生不同的
價格樹,但期權執行價格對其沒有影響。
第三種參數選擇方法比較少見,但卻獲得很高的讚譽。LR 樹使用了布萊克-舒爾斯中

N (d1 ) 和 N (d 2 ) 的精確二項估計值。因此在到期日股票價格樹總是以執行價為中心,並且
消除了在其他兩種方法中,隨著期數的增加,期權價值不完全收斂的問題。因此,LR 樹可
以看作是樹方法中的布萊克-舒爾斯分析。
OPTION1.xls 工作簿中包含了二叉樹方法的實現過程。通過一些小型價格樹例子來演
示三種方法的計算過程。這些實現都是基於 VBA 函數的,它們還可以為那些不需要在表格
中顯示中間節點的大型樹定價。

10.2 簡化的二叉樹

OPTION1.xls 工作簿的第一張表(名為 JRBinomial)中,顯示了在價格上下運動概率


相等,期間長度相同的情況下,一個九期二叉樹的終值及其概率。樹的結構很簡單,主要是
為了展示試算表的版式設計,需要用到的主要公式,以及如何計算二叉樹終值的均值和方
差。這個例子還解釋了怎樣利用一個九期二叉樹來近似標準正態分佈。
圖 10.1 中的 JR 二叉樹表明,九期二叉樹的價格是從初始值 0(單格 B18)開始運動的。

在每一期,股票價格以相同的概率向上或向下運動 1/3(= 1 9 ),見 C5。K 列中存放的是股

價經過九期變化得到的 10 個不同終值。這些值是用前面的九期價格變化量相加得到,每期
變化量都是 1/3。每個終值的實際概率可以用二項分佈計算得到。參數的選擇(股價變化幅

度為 1/ 9 ,p=1/2)要確保終值分佈的均值為 0,方差為 1(要使之近似服從標準正態分

佈)。這樣,就可以用一個簡單的離散二項隨機遊走模型的極限——連續隨機過程來對股票
價格進行建模了。

Adapted JR Binomial Distribution:合適的 JR 二叉樹分佈

【參照書中第 169 頁的圖 10.1】

圖 10.1 工作表 JRBinomial 中的九期二叉樹

為了能將樹放入一個方格中,樹的版面被壓縮了,這樣能夠利用單格 C18 中的簡單公


式(在 B18 中已給出初值)產生樹的其他部分。價格的上升將沿著對角線方向移動,價格
的下降將沿著特定的行向左移動。因此在第 18 行中,每個資料都比前一期資料要少 1/3,
而沿著對角線的方向,每個資料都比前一期資料要多 1/3。單格 C18 中的公式使用了條件語
句 IF 來判斷單格是否在對角線上。如果在對角線上,該單格的值就等於對角線上前一單格
的值加 1/3;如果不在對角線上,該單格的值就等於左邊單格的值減 1/3。價格單格的相對
位置由 OFFSET 函數來處理。單格 C18 中的公式為:

= IF ($ A18 < C $8, OFFSET (C18, 0, −1) − $C $5, OFFSET (C18,1, −1) + $C $5)
在條件運算式之後,第一個運算式表示如果價格下跌,將比它最近的左單格(同一行中)的
數值少 1/3(在單格 C5 中)
,如果價格上漲,那麼將比其相鄰對角線上的值多 1/3。OFFSET
函數指向相對位移的(先沿行,後沿列)的單格。
既然價格上漲和下跌的概率相等(因此,所有上升下降序列出現的概率相等) ,那麼基
於二叉樹的概率分佈可以由到達終值節點的路徑數決定。在單格 C22 中,給出了路徑的數
量(見圖 10.2),所用的公式為=COMBIN($C$4,C22),其中$C$4 是二叉樹的期數,C22
是價格向上運動的期數。在單格 I22 中給出了其概率,公式為=G22*($C$6^$C$4), $C$6

則是價格向上運動的概率,因為所有路徑出現的概率都相同,都為 1 29 = 1 512 。這個分佈


的均值為 0,方差為 1(見單格 I33 和 I34)。

【參照書中第 170 頁的圖 10.2】

圖 10.2 工作表 JRBinomial 中的股價終值概率分佈

這個例子是為下一節的 JR 樹打基礎,它為股票價格運動過程建模,從而得到期權的收
益。這裏有兩點需要修正:首先股票價格的變化量是一個乘數,而不是一個加數,另外,需
要重新調節終值節點的範圍(在此均值為 0,方差為 1),使之匹配股票收益的要求回報率
和波動率。

10.3 JR 二叉樹

本節用 Jarrow 和拉德(JR)參數來構造一個九期二叉樹,並用它來為期權定價。首先,


需要一個股票價格樹來確定股票的終值,然後計算期權的價值,最後對期權的期望收益折現
得到現值。期權的知識前面已經學過,二叉樹參數的選擇下面將要討論,最後介紹怎樣構建
相應的 Excel 公式。
假設股票的現值 S 為 100,波動率 σ 為 20%(按年計算),期權為歐式看漲期權,它
的執行價為 95,有效期為 0.5 年。還假設股票每年有 3%的紅利,無風險連續複利為 8%(相
。由於是九期模型,所以每期的時間長度是 0.5/9=0.0566(用 δt 表示)。
當於年利率為 8.33%)
為了便於比較不同的二叉樹,在以下的章節中將使用相同的例子。工作表 JREuro 的上半部
中列出這些細節資訊,以及生成樹所需的參數,如圖 10.3 所示。
作為簡化的二叉樹,JR 樹中股價上漲和下跌的概率相等,也就是 p=0.5。每一期上漲
或下跌的幅度取決於股票價格變化乘數 u 和 d,調整這兩個值,直到 n 期後的均值與方差與
股價收益的要求值相等。

JR European Option Value:JR 歐式期權價格

【參照書中第 171 頁的圖 10.3】

圖 10.3 期權資訊及 JR 樹的有關參數(表 JREuro)

在 JR 樹中,股價運動過程兩項組成,第一項是風險中性的漂移項(drift term),第二項
則是基於簡單二叉樹波動率(volatility)的波動項。漂移項已由 Jarrow 和拉德決定,並且股價
上漲和下跌的概率相等,這能夠確保在風險中性的世界中股票具有(r-q)的期望回報率。

在每一期,價格乘數的期望值是 exp[(r − q )δt ] ,因此上漲與下跌的幅度不再相等。年波動

率 σ 是一個標準差,它與期間長度的平方根相乘得到波動項 σ (δt ) 。波動項確保每一期對


數股票價格的方差為 σ δt ,因此在經過 n 期(或時間 T)後,對數股票價格的方差為 σ 2T 。
2

JR 樹的參數可以表示為:

ln u = (r − q − 0.5σ 2 ) + σ δt 或者 u = exp[( r − q − 0.5σ 2 )δt + σ δt ]

ln u = (r − q − 0.5σ 2 ) − σ δt 或者 u = exp[( r − q − 0.5σ 2 )δt − σ δt ]


對於對數股票價格,其上漲或下跌(ln u 和 ln d)的幅度是一個加數,並構成一個對數股價
樹。而對於股價樹,每一期的變化量都是用乘數因數 u 或 d 來計算。
在 Excel 中,計算價格上漲乘數因數 u(在單格 G9 中)的公式為:

= EXP(( D 6 − D8 − 0.5 * D13^ 2) * G 6 + D13 * SQRT (G 6))


它包含漂移項和波動項兩個部分。
計算價格下跌乘數因數 d(在單格 G10 中)的公式中,波動項前用負號替代上式中的
正號。

【參照書中第 171 頁的圖 10.4】

圖 10.4 使用 JR 參數的九期股票價格樹(表 JREuro)

在圖 10.4 所以的股價樹中,列號表示股價向上運動的次數(用 i 表示,範圍從 0 到 9),

行號代表期數(用 j 表示,從 0 到 9)。那麼,第 j 期第 i 種狀態下的股價 S i , j 就等於初始股

價 S,乘以相應次數的股價上漲和下跌乘數,例如: S 0, 0 = S = 100 ,在一期後有兩種可能

的價格變化: S 0 ,1 = dS 0 , 0 = 95.55, S1,1 = uS 0, 0 = 105.00 ,等等。因此,在 n 期後:

S i , n = u i d n −i S
這個公式具有遞迴性。因此,每一期的新股價僅僅依賴於前一期的股票價格和價格變化乘

數,例如, S i , j +1 = dS i , j ,這種遞迴性在 Excel 中很容易實現,只需拷貝單格 C30 中的如

下公式:
=IF($A30<C$20,$G$10*OFFSET(C30,0,-1),IF($A30=C$20,$G$9*OFFSET(C30,1,-1),""))
這個公式與上一節使用的公式非常相似,只是價格運動乘數 G10(下跌)和 G9(上漲)是與
前項相乘的。由於在單格中使用了嵌套條件語句 IF,因此公式可以處理第三種可能性,將
對角線上方的單格($A30>C$20)填充為空值“”。拷貝 C30 中的公式就可生成餘下的樹
節點(並能擴展為更大的樹) 。通過觀察偶數期的中間單格(D29,F28……) ,你能看到 JR

樹中股票價格隨時間的漂移。[嚴格地說,這種情況僅僅在 ( r − q − 0.5σ ) 大於 0 時才成立,


2

但這個條件通常滿足]
由於討論的是歐式期權,因此僅僅需要關心股價的終值,即 K 列中的數值。可以用下
面的公式得到看漲期權對應於每個終期價格的收益:

Vi ,9 = max[S i ,9 − X ,0] i=0,1……9

其中,X 是期權的執行價格。結果放在 K49 到 K58 中,其範圍從 60.16 到 0。注意,凡是


收益大於 0 的,股票價格上漲的次數一定大於或等於 4 次:如果小於 4 次,期權將不會執
行。
下一步是計算看漲期權收益的期望值,並將其用無風險利率折現。因此需要看漲期權每
一種收益發生的概率,這些概率與前面簡單二叉樹中的概率一樣。它們放在 K35:K44 中,
K44 中的公式為:
=COMBIN($D$15,A44)*$G$11^$D$15

最後兩項給出了任一序列的概率( 1 2 9 )
,COMBIN 函數給出了每一個看漲期權收益的路徑

數。於是 10 個終期收益及其相關概率如下:

狀態 9 8 7 6 5 4 3 2 1 0
期權收益 60.1646.2033.4921.93 11.41 1.84 0 0 0 0
概率 0.0020,0180.0700.1640.2460.2460.164 0.0700.018 0.002

期權收益的期望值是各個收益的加權平均,並用無風險利率折現得到風險中性定價。因
此,單格 G15 中折現後期權價格的公式為:
=EXP(-D6*D12)*SUMPRODUCT(K35:K44,K49:K58)
其中,EXP(-D6*D12)是基於 0.5 年無風險利率的折現因數。
因此,用九期 JR 樹得到的看漲期權價格為 9.75(比較圖 10.3 中單格 G17,由布萊克-
舒爾斯公式得到的價格為 9.73)。幸運的是,隨著期數的增加,由 JR 樹得到的期權價格收
斂於布萊克-舒爾斯價格(這部分內容將在 10.6 中討論)。順便說一句,G17 中的布萊克-
舒爾斯價格是通過用戶定義 VBA 函數 BSOptionValue 得到的,代碼放在 Module1 模組中。
關於程式的解釋將在第 11 章提到,那時將詳細討論布萊克-舒爾斯公式的細節問題。
期權標的股票的 JR 價格樹由以下的 10 個值組成,並附有其相關概率:

狀態 9 8 7 6 5 4 3 2 1 0
股票價
155.16141.20128.49116.93106.41 96.84 88.12 80.20 72.98 66.41

概率 0.002 0,018 0.070 0.164 0.246 0.246 0.164 0.070 0.018 0.002
股票收益近似服從對數正態分佈。利用表中的價格和概率,很容易算出分佈的一階矩 M1 和
二階矩 M2(見單格 K9 和 K10)。通過 M1 和 M2,可以利用公式(見 7.7 節)計算股票對
數價格(服從正態分佈)的均值和方差(M 和 V)。這些矩的值放在圖 10.3 的 K 列中,M1
和 M2 是用區域 K21:K30 中的股票終期價格計算得到的,而 M 和 V 則利用公式計算得到。
可以將 JR 樹得到的結果與布萊克-舒爾斯公式要求的股票對數價格的均值和方差作比較。
可以看到,理論價格與利用二叉樹方法得到的價格相當吻合。
通過驗證可以知道,M1(股票價格的均值)是從 S=100 開始,以增長因數 1.02531
增長的,這個增長因數等於 exp[(r-q)T]。
JREuro 模型同樣能為看跌期權定價。只要將 D16 中“iopt”參數賦值為-1,那麼看漲
期權就會變成看跌期權。股價樹與原來的一樣。但期權收益在股價跌倒執行價 X 以下的情
況下才等於 0。通過引入一個參數(iopt=1 代表看漲期權,iopt=-1 代表看跌期權)
,可以將
看漲期權和看跌期權的收益公式合併為同一個運算式:

Vi ,9 = max[iopt * ( S i ,9 − X ),0] i=0,1,2……9

JR 樹在 Wilmott etc al.(1996)中有介紹。

10.4 CRR 樹

工作簿 OPTION1 中還有兩個表使用 CRR 樹。正如 CRREuro 表所示,它的版面與 JR


樹相同,只是樹中使用的股票價格以及相關概率不同。CRRTheory 表演示了二叉樹定價的
核心理論,即二項分佈函數與正態分佈函數相似。表中的公式能夠演示,CRR 樹的歐式期
權定價是如何隨著期數的增加而收斂的。
考克斯,羅斯和魯賓斯坦(CRR)提出了參數的可選擇性,從而創建了一個風險中性
的環境。價格乘數 u 和 d 只依賴於波動率 σ 和 δt ,而與漂流項無關:

ln u = σ δt ln u = −σ δt
這些參數反映期間 δt 內的股票價格變化波動率,但不是整個期間的變化波動率。在圖 10.5
的單格 G9 中,計算 u 的公式為:
=EXP(D13*SQRT(G6))
在 G10 中,d 的計算公式為 1/u。

CRR European Option Value:CRR 歐式期權價格

【參照書中第 174 頁的圖 10.5】

圖 10.5 期權資訊及 CRR 樹中相關參數(表 CRREuro)

觀察圖 10.6 中的股價樹,能明顯看到中間的股票價格是沒有漂移項的,如偶數期單格(D29,


F28,……)所示。由圖中可知,CRR 樹是以股價現值 S 為中心的。
【參照書中第 174 頁的圖 10.6】

圖 10.6 使用 CRR 參數的九期股價樹(表 CRREuro)


為了彌補 u 和 d 中缺少的漂移項,CRR 樹中的上漲概率一般大於 0.5,以保證股票價

格期望值在每一期以乘數因數 exp[( r − q )δt ] 增加。p 的計算公式為:

p = (b − d ) /(u − d ) ,其中 b = exp[( r − q )δt ]

例子中,價格上漲的概率為 0.5177(G11),因此,下降的概率為 0.4823(G12),價格期望值


的變化因數為 1.0028(G8)。
CRR 樹計算期權收益的方法與 JR 樹相同。在看漲期權最後一步定價時,G15 中用於
對期望收益折現的關鍵公式與 JR 樹相同。經過九期變化,CRR 樹得到的期權價格為 9.63,
而 JR 樹計算的價格為 9.75,布萊克-舒爾斯期權價格則為 9.73。
與 JR 樹一樣,可以將參數 iopt 的值(D16)改為-1 可以計算看跌期權的價格。注意,
紅利只影響 CRR 模型中的股票變化概率,而不影響股票價格,這與 JR 模型正好相反。

10.5 二項分佈近似與布萊克-舒爾斯公式
二項分佈近似與布萊克 舒爾斯公式

迄今為止我們注意到,在試算表中,使用二叉樹和布萊克-舒爾斯得出的期權價格非常
接近。CRRTheory 表進一步揭示兩者之間的關係,它顯示了怎樣用一個離散的二項分佈來
替代連續的正態分佈 N(d)。這種分佈近似可應用于歐式期權。其中要用到一個‘互補的
(complementary)’二項分佈函數 Φ ,它等於 1 減去通常的二項分佈函數。布萊克-舒爾
斯公式中的每一格 N(d)都可以用互補二項分佈函數 Φ 替代。
圖 10.7 中顯示的是與前一章相同的歐式看漲期權,但定義了兩個新的參數。資料 a
(E14)表示為使股票價格最後處於‘實值狀態’的最小上漲次數,也就是最終股價應大於
X 的次數。在圖 10.6 中(特別是單格 K26) ,可以清楚地看到四次上漲可以得到最終股價
95.40,它大於執行價 95。實際上,E14 中的數值 4 由考克斯和魯賓斯坦給出的公式計算得
到。

Theory behind Binomial Trees:二叉樹背後的理論

【參照書中第 175 頁的圖 10.7】

圖 10.7 表 CRRTheory 中 N(d)的二項分佈近似

另一個新參數 p ' (單格 E12 中)是一個修正概率,計算公式為:

p ' = pu exp [ (r − q )δ t ]
其中 exp[( r − q )δt ] 的值在單格 E8 中給出。

簡明的 CRR 二項分佈期權定價公式如下:

c = S exp(− qT )Φ[α : n, p '] − X exp(− rT )Φ[α : n, p ]


分佈函數通常定義為分佈左尾概率,而互補分佈函數則是指右尾概率。因此,在
CRRTheory 表的單格 E16 中,計算互補分佈的概率值時應該用(α-1)

=1-BINOMDIST(E14-1,B15,E12,TRUE)
為了檢測近似程度,可以用該公式計算出的期權價格 9.63(CRRTheory 表的 B17 中)與表
CRREuro 的 G15 中的的數值作比較。

10.6 CRR 二叉樹的收斂性

到現在為止,所有的二叉樹都限制在九期範圍內(考慮到空間的大小)。但我們感興趣
的是,當到期時間固定而期數增加時,由二叉樹得到的期權價格是否更準確。在不重新建立
大型二叉樹的情況下,一個簡單的方法是使用前面提到的,並在表 CRRTheory 中演示過的
簡單期權定價公式。在期數不斷增加的情況下,將這個公式計算的結果與布萊克-舒爾斯期
權價格作比較,從而研究這個模型的收斂性。
下面用一張模擬運算表來說明,分別用不同期數(B15)的簡單 CRR 期權定價公式(B17)
和布萊克-舒爾斯公式(B20)來計算期權的價格,然後用圖形將結果顯示出來。如圖 10.8
所示。
在區域 J4:L12 中建立模擬運算表的具體操作如下。例如,在 K4 中輸入公式=B20,
在 L4 中輸入公式=B17。在單格 J5 至 J12 中輸入不同的期數,從 16 到 128,增量為 16。
然後建立類比運算表,表格區域設為 J5:J12,列輸入單格設為 B5,於是就得到表格資料。
然後在 XY 圖中畫出模擬運算表的輸出結果,就能看出隨著期數的增加,CRR 二叉樹計算
出的期權價格在布萊克-舒爾斯期權價格附近振盪。
期權價格隨著期數的增加而上下振盪,這種情況在 JR 樹中也能看到,其產生的原因是
二叉樹的參數沒有與期權執行價相聯繫。而當執行價格和初期股票價格一致時(也就是 B5
變為 100),就不再是振盪了,而是單調收斂。單這僅僅是一個特例。

Convergence of CRR formula:CRR 公式的收斂性


Option value:期權價格
Binomial steps:二叉樹期數

【參照書中第 177 頁的圖 10.8】

圖 10.8 隨期數增加 CRR 樹與 BS 期權定價比較

對於任意給定的期數,存在唯一的二叉樹來描述股價運動過程。隨著期數的增加,執行
價格相對節點位置會不斷變化。這將改變二叉樹近似價格和真實布萊克-舒爾斯價格之間誤
差項的符號。
10.7 LR 樹

第三類產生股價樹的參數是由 Leinsen 和賴默提出的。相對於 JR 樹和 CRR 樹選擇的


參數來說,他們選擇的參數有兩個主要優點。首先,分別估計了布萊克-舒爾斯公式中的

N (d1 ) 和 N (d 2 ) 。其次,將到期日的股票價格集中在執行價周圍,從而消除了 JR 和 CRR


樹收斂過程中的振盪現象。建立 LR 樹以及對期權定價的有關計算見圖 10.9 中的 LREuro
表。

LR European Option Value:LR 歐式期權價格

【參照書中第 177 頁的圖 10.9】

圖 10.9 期權資訊及 LR 樹相關參數(表 LREuro)

在 LR 模型中,參數的選擇順序與 JR 和 CRR 模型剛好相反的,它首先確定概率,然後再


確定股價運動。概率由一個反向公式得到,由此保證用二項分佈來估計正態分佈的精確性。

概率 p 與布萊克-舒爾斯公式中的 d 2 項相聯繫,概率 p ' 與 d1 項相聯繫。例如,G9 中 p 的

計算公式為:
=PPNormInv(G8,D15)

其中,G8 為布萊克-舒爾斯公式中的 d 2 值。估計 N (d 2 ) 的精確度可以用 K15 中 Φ[ a : n, p ]

值與 K16 中的實際 N (d 2 ) 值比較得出。 N (d1 ) 估計值的精確度是相似的。注意,在 LR 樹中 a


的值為(n+1)/2,這能確保股價樹以執行價為中心。
在股價運動的過程中,上漲和下跌的相關乘數如下所示:

u = bp ' p 其中 b = exp[( r − q )δt ]

d = b(1 − p ') (1 − p )
改變執行價格 D5,並檢驗試算表中修正後的樹,可以看到股價樹在到期日確實以 X 為中心。
選定參數後,LR 的定價過程就與其他二叉樹模型一樣了(見圖 10.10) 。先計算期權收
益,然後對其折現並求期望值,就得到期權的價格。在本例中,LR 樹給出了歐式看漲期權
的價格 9.724(G15),這個結果與布萊克-舒爾斯期權價格 0.726(G17)非常相似。
【參照書中第 178 頁的圖 10.10】

圖 10.10 LR 股票價格樹(表 LREuro)

10.8 CRR 樹與 LR 樹的比較

工作簿 OPTION1 的另一張工作表中,利用期權定價的 VBA 函數,在期數增加的情況


下,比較 CRR 期權價格,LR 期權價格與布萊克-舒爾斯期權價格的差異。圖 10.11 列出了
期數從 16 到 128 時估計值的變化。F 列是布萊克-舒爾斯期權價格(用戶定義函數
。它在本章被作為一個基準來使用,且與期數無關。
BSOptionValue)
在相鄰的兩列 G 和 H 中,另一個用戶定義函數 BinOptionValue 返回以二叉樹方法計算
的期權價格,輸入的參數有二叉樹的類型,期權類型,二叉樹的期數等等。例如,函數的第
一個參數 imod 設為 1 時為 CRR 樹,2 則為 LR 樹。這些二叉樹期權價格將與布萊克-舒爾
斯期權價格作比較。對於給定的歐式看漲期權,LR 樹在期數為 48 時計算出的期權價格與
布萊克-舒爾斯期權價格非常接近,實際上已經精確到小數點的第四位。

Euro Binomial Tree:歐式二叉樹

【參照書中第 179 頁的圖 10.11】

圖 10.11 不同二叉樹定價與 BS 定價的比較


函數 BinOptionValue 的相關代碼放在工作簿的 Module0 模組中,該模組中還有其他一
些函數,這些函數能使二叉樹定價理論實現起來更加直接。代碼的特點將在 10.10 中討論。
比較不同理論得出的股價樹統計量也是非常有意義的。圖 10.12 列出了三種不同股價樹
終值分佈的一階矩(M1)和二階矩(M2) ,並分別計算出它們的期望(M)和方差值(V)。
這些統計量都是本章用到的九期歐式期權定價的統計量,它們已經分別在圖 10.3,圖 10.5
和圖 10.9 中給出。
【參照書中第 179 頁的圖 10.12】

圖 10.12 不同類型二叉樹股價以及 BS 價格的統計量比較

有一個很有趣的現象:儘管 LR 樹對於期權價格的估計更加精確,但 JR 樹和 CRR 樹


與假定股價波動率的吻合程度要比 LR 樹好。在到期日,股價樹以執行價為中心是 LR 樹的
關鍵改進之處。

10.9 美式期權和 CRR 美式二叉樹

由於二叉樹定價模型不僅可以處理在到期日執行的情況,也可以處理在中間節點執行的
情況,因此,它是為美式期權定價的重要數值方法。對於美式看跌期權來說,提前執行常常
會增加看跌期權的價值。表 CRRTree 既可以為歐式期權(不能提前執行)定價,也可以為
美式期權(可以提前執行)定價。計算結果很容易作比較。
為了演示,假設 CRRTree 表中的期權是看跌期權,也就是給 D16 賦值-1。圖 10.13 顯
示,不能提前執行的看跌期權價格為 2.40(H15),而可以提前執行的期權價格為 2.54(H17)。
即使在沒有紅利的情況下,能夠提前執行仍然對看跌期權有好處。由於布萊克-舒爾斯公式
只適用于歐式期權,因此它只能作為歐式期權定價的基準。

CRR American Binomial Tree:CRR 美式二叉樹

【參照書中第 180 頁的圖 10.13】

圖 10.13 表 CRRTree 中看跌期權提前和不提前執行情況下的定價

歐式和美式看跌期權的價格都能夠從 CRR 股價樹中得到,無論在哪一期執行,都能夠


根據當時的股價計算出期權的收益。

Option Payoff:期權收益

【參照書中第 180 頁的圖 10.14】


圖 10.14 表 CRRTree 中看跌期權的期權收益樹

圖 10.14 中 49 行到 58 行給出了這些期權收益。假設不能提前執行,相關的期權收益
都在第九期實現(K49 到 K58 中) 。通過計算期權的期望收益,並用無風險利率折現得到的
價格,就得到這種歐式看跌期權的價格。如前所述,歐式看跌期權的價格為 2.40(H15) (見
圖 10.13)。
為了給美式期權定價,不僅需要知道在第九期執行時收益,還需要知道中間任一階段的
期權收益。可以用終期期權收益(K 列,圖 10.15)計算第 8 期的期望期權價格,記住要用
無風險利率對其折現。計算期望值時使用 CRR 概率以確保風險中性的假設成立。將第 9 期

第 i 種狀態下的期權收益表示為 Vi , 9 ,則在第 8 期第(i-1)種狀態下的期望收益為:

Vi −1,8 = [ pVi ,9 + (1 − p )Vi −1,9 ] exp( rδt )

上式先計算期權收益的期望值,然後將其折現到前一期。這種計算期望收益並將其折現的過
程被稱為“逐期倒推(stepping back)”過程。

European Option Value:歐式期權價格

【參照書中第 181 頁的圖 10.15】

圖 10.15 表 CRRTree 中作為歐式期權的看跌期權價格

經過九期運動後的期權收益放在 K63:K72 種,Excel 中的逐期倒推過程可以通過將 J72 中


的公式拷貝中整個期權價格樹區域(即 B63 到 J72)來實現:
=IF($A72<=J$62,($G$11*K71+$G$12*K72)/$G$7,"")
條件語句 IF 確保只有在對角線上或對角線以下的單格才有值,這使得輸出版面與股價
樹相似。這個帶條件語句的公式計算出了期權收益在每個節點的概率加權期望值,並用單期
無風險折現因數(G7)將其折現。
採用逐期倒推方法計算的九期 CRR 樹看跌期權價格為 2.40(B72),它與我們通過終
期收益分佈折現得到的期望值很相似。過程如圖 10.15 所示。
但對美式期權而言,期權在每一期都有被執行的可能。在圖 10.16 中,觀察單格 J72,
看跌期權的期望值為 26.42,並不是圖 10.15 中單格 J72 裏的 26.11。這是因為提前執行的
可能性會帶來一個較大的收益。因此 J86 中的公式將期權的期望收益與提前執行情況下的
收益作比較,並選取較大值。這個比較過程用 Excel 函數 MAX 來實現:
=IF($A86<=J$76,MAX(($G$11*K85+$G$12*K86)/$G$7,J58),"")
該公式選取收益期望值(如同計算歐式期權)與執行期權情況下所得收益(在 J44 中給出)
之間選擇一個較大值,反復運用該公式計算得到的結果如圖 10.16 所示,美式看跌期權的最
終價格為 2.54(與圖 10.13 中單格 F17 裏顯示的一樣)。

American Option Value:美式期權價格

【參照書中第 182 頁的圖 10.16】

圖 10.16 表 CRRTree 中作為美式期權的看跌期權價格

雖然對於美式期權而言提前執行是可能的,但實際上,如果股票的紅利為 0,對於看漲
期權來說是不值得提前執行的。然而,如果看漲期權的標的股票有紅利,則提前執行是可能
的。作為練習,將上面的看跌期權改為看漲期權,然後求出在紅利為多大時,提前執行才有
價值。可以發現,只有在紅利相當大的情況下,美式看漲期權和歐式看漲期權的價格才會出
現明顯的差異。

10.10 Module0 和 Module1 中的用戶定義函數

OPTION1 中有一些用戶定義函數的代碼,它們實現了本章討論的大多數二叉樹期權定
價計算。採用 CRR 樹和 LR 樹為期權定價的主要函數放在 Module0 中。其中最重要的公式
有 CRRTheory 表 中 用 到 的 BinEuroOptionValue 函 數 , 以 及 Compare 表 中 用 到 的
BinOptionValue 函數。
在二叉樹用於存放期權收益的陣列中,我們讓陣列元素從 0 開始編號(而不是常用的
1),二叉樹的起始期數也是從 0 開始的,這些規則通過 VBA 模組頂部的 Option Base 0 語
句中設定。另外,我們將模組頁命名為 Module0。
BinOptionValue 函數可以分別用 CRR 二叉樹(imod=1)和 LR 二叉樹(imod=2)為
美式或歐式期權定價。代碼很容易讀懂,只需設定期權的類型(如果是歐式看漲期權,則 iopt
=1,iea=1)以及定價方法(如 CRREuro 表中演示的 CRR 樹)就可以了。定價過程中反
復將向量陣列 vvec()定義成有十個元素的 Variant 類型,元素從 vvec(0)到 vvec(9),並用語
句 ReDim(nstep)來設定維數。
股價樹的終期期權收益通過下面公式得到:

max[ S (u i d n −i ) − X ,0] i=0,1,2……9


在 VBA 語句中用一個迴圈得到:
For i=0 to nstep
vvec(i)=Application.Max(iop*(S*(u^i)*(d^(nstep-i))-X,0)
Next i
隨後的五行代碼通過二叉樹執行逐期倒推過程,每一期都計算期權收益期望的折現值,並最
終得到期權價格:
For j=nstep-1 To 0 Step -1
For i=0 To J
vvec(i)=(p*vvec(i+1)+pstar*vvec(i))/erdt
Next i
Next j
在 VBA 代碼中有兩點需要注意。在定價過程中,可以用新值來替代 vvec 陣列中的舊值,
這樣可以節省存儲空間,只需一個(n+1)×1 的向量即可。還有一點是,對於美式期權(iea=2) ,
我們還需一行代碼來從歐式期權價格和立即執行所得收益之間選取一個最大值。
下一章將詳細討論對沖參數問題,因此,在這裏先不介紹 BinOptionGreeks 函數。其
中 5 個參數中的 3 個可以通過一個擴展的二叉樹獲得,其他兩個參數則需建立兩個分開的
二叉樹得到。函數將使用更加有效的 LR 樹。
Module1 中附有 BSOptionValue 函數的代碼,它用來計算布萊克-舒爾斯公式。詳細的
解釋將下一章的 11.7 節給出。

小結

二叉樹提供了一種實用的方法來為股價運動過程建模。終期價格的離散分佈可以用布萊
克-舒爾斯分析中假設的連續對數正態分佈來近似。
用二叉樹為股票期權定價,先要計算期權的收益期望值(用風險中性概率為每個期權收
益加權),然後利用無風險利率對其折現。
二叉樹定價的高效性(相對于蒙特卡羅模擬)來自於股價樹中多條路徑的重組。
通過選擇不同的參數構建不同類型的二叉樹(例如 JR 樹,CRR 樹,LR 樹)。JR 樹中
股價向上和向下運動的概率相等,每一期變化的幅度中包含有漂移項和波動項。CRR 樹的
變化幅度可以反映波動率,但沒有與均值有關的漂移項。為了反映股價的漂移項,需將股價
上漲和下跌的概率設置成不同值,而從保證價格向上漂移(通常情況下) 。LR 樹的終期價格
是以期權執行價為中心的,它的概率和變化幅度參數都很複雜。
用三種不同類型的二叉樹方法對歐式期權定價,其結果表明,LR 二叉樹只需較少的期
數就可以得到與布萊克-舒爾斯期權價格很接近的估計值。
二叉樹方法很容易處理期權提前執行的情況,因此可以用其為美式期權定價。

參考文獻
Cox,J. ,S. Ross and M. Rubinstein, 1979, “Option Pricing: A Simplified Approach”, Journal
of Financial Economics, 7, 229-264
Cox, J. and M. Rubinstein, 1985, Options Markets, Prentice Hall, New Jersey.
Hull, J. C., 2000, Option, Futures and Other derivatives, Prentice Hall, New jersey
Jarrow, R. A. and A. Rudd,1983,Option Pricing, Richard D. Irwin,Englewood Cliffs,NJ
Leisen, D. R. J. and M. Reimer, 1996, “binomial Models for Option Valuation-Examining
and Improving Convergence”, Applied Mathematical Finance,3,319-343
Wilmott, P., S. Howison and J. Dewynne, 1996, The Mathematics of financial Derivatives,
Cambridge University Press, Cambridge.
第 11 章 布萊克-舒爾斯公式
布萊克 舒爾斯公式

儘管二叉樹提供了一種容易理解期權定價原理的方法,但有解析解的布萊克-舒爾斯公
式仍然是歐式期權定價理論的中心內容。它的強大之處在於它是用一個公式來為期權定價,
而且它可以確定複製組合的對沖比率(hedge ratio)。本章將推導布萊克-舒爾斯公式,並將其
擴展到有連續紅利的情況,由此可以為外匯期權和期貨期權定價。還將推導出對沖參數
(hedge parameter),因此,可以創建出一個在股價變化條件下價值不變的對沖組合。
赫爾教科書(2000)的期權部分是第 11 章內容的最好參考教材(第 11 章推導並解釋
布萊克-舒爾斯公式,第 12 章討論在存在連續紅利情況下對布萊克-舒爾斯公式的修正,並
用其對外匯期權和期貨期權定價,第 13 章討論‘希臘參數(greeks)’和 delta 對沖係數)

演示不同布萊克-舒爾斯定價公式的模型放在工作簿 OPTION.xls 中,並附有許多有用的定
價函數。

11.1 布萊克-舒爾斯公式
布萊克 舒爾斯公式

9.2 節已經介紹過布萊克-舒爾斯公式,9.7 節還簡要介紹了存在紅利情況下的期權定價


問題。本節利用默頓方法對 9.2 節中的公式進行擴展,使之適用于存在連續紅利的情況。
默頓擴展方法將不存在紅利和每年有 q%連續紅利收益的情況作比較。在風險中性的世
界裏,這兩種股票應該具有相同的總收益,即紅利和資本增長。如果有紅利收益的股票在時

間段 T 內從初始價格 S 增長到 S T ,那麼對於無紅利股票,就應該從 S 增長到 S T exp(qT ) ,

也可以說,從 S exp(-qT)增長到 S T 。因此, S T 的概率分佈可以適用於以下兩種情況:

(a) 初試價格為 S,並有 q%的連續紅利收益


(b) 初試價格為 S exp(-qT),但沒有紅利收益
因此,如果一個歐式期權的標的股票以連續收益率 q 來支付紅利,那麼在為它定價時,可
以用 S exp(-qT)代替原來的初試值 S,然後將該股票看作不支付紅利的股票。
於是,對一個支付紅利的歐式看漲期權來說,其布萊克-舒爾斯公式為:

c = S exp(− qT ) N (d1 ) − X exp(− rT ) N (d 2 )


其中 q 是連續紅利收益率,N(d)是累積的標準正態分佈函數,並有:

[ ]
d 1 = ln( S / X ) + (r − q + 0.5σ 2 σ T

[ ]
d 1 = ln( S / X ) + (r − q − 0.5σ 2 σ T
為了便於解釋布萊克-舒爾斯公式各項內容的意義,可以聯想到看漲期權的複製組合形式,

c=hS-B。公式第一項是乘數 S(也就是‘對沖比率’),等於 exp(− qT ) N ( d1 ) 。第二項則

是執行價格的現值與 N ( d 2 ) 的乘積。因此, N ( d 2 ) 可以看成是在風險中性世界裏看漲期權

被執行的概率。
利用期權平價關係,看跌期權在支付連續紅利情況下的布萊克-舒爾斯定價公式為:

p = − S exp(− qT ) N (− d 1 ) + X exp(−rT ) N (− d 2 )
它可以寫成如下形式:

p = −[ S exp(−qT ) N (− d1 ) − X exp(− rT ) N (−d 2 )]


如果沒有公式前的負號以及累積正態分佈函數內的負號上,則該式與看漲期權定價公式完全
一樣。

11.2 在 Excel 中運用布萊克-舒爾斯公式


中運用布萊克 舒爾斯公式

圖 11.1 中是前面用過的看漲期權實例,以及布萊克-舒爾斯定價所需的計算。最初計算
時,常用多項式來近似累積正態分佈概率。現在,可以用 Excel 的 NORMSDIST 函數直接

得到。得出 d 1 和 d 2 後,就可以計算相應的 N ( d1 ) 和 N ( d 2 ) 了,它們分別放在 E11 和 E16

中。由於它們都是概率值,所以取值範圍介於 0 和 1 之間。

Black-Scholes Formula(extended to allow for continuous dividends):


布萊克-舒爾斯公式(考慮了連續紅利情況下的擴展型)

【參照書中第 186 頁的圖 11.1】

圖 11.1 表 BS 中的布萊克-舒爾斯期權定價過程
單格 E5 中的布萊克-舒爾斯公式為:
=B4*B16*E11-B5*B15*E16
其中,B15 和 B16 中的是兩個折現因數,而 E11 和 E16 中的則是累積正態分佈值,它們都
是計算過程的中間值。E5 中看漲期權的價格為 9.73。也可以用用戶定義函數 BSOptionValue
計算布萊克-舒爾斯期權價格,結果放在 E8 中,相關代碼將在 11.7 中討論。

從前面的討論中可知,對沖比率是 exp(-qT)與 N ( d1 ) 的乘積。在這裏等於 0.718(也就

是 0.9851*0.7291)。期權在風險中性世界裏被執行的概率為 N ( d 2 ) ,即 0.680。

對於相同標的股票的看跌期權,H5 中的布萊克-舒爾斯定價公式為:
=B4*B16*(E11-1)-B5*B15*(E16-1)

看漲期權定價公式的第一項是 N ( d1 ) ,由於正態分佈的對稱性,看跌期權定價公式的第一
項則為 − N ( − d1 ) = N ( d1 ) − 1 。因此看漲期權公式中的 E11 被(E11-1)代替。用同樣的方法

處理第二項。H5 中看跌期權的價格為 2.49。同樣,在 H8 中存放用戶定義函數 BSOptionValue


計算出來的看跌期權價格。這個函數有個重要的參數 iopt,取值為 1 代表看漲期權,取-1
則代表看跌期權,這樣就可以用一個通用函數來代替兩個分開的函數(分別計算看漲期權和
看跌期權的價格)。可以看出,看漲期權和看跌期權定價的代數運算式非常相似,僅在一些
符號上有差異。
為了研究期權價格的影響因素,首先必須弄清楚期權與標的股票之間的因果關係。你將
發現期權價格對標的股票的波動率變化非常敏感。前面已經提到過(第 2.7 節),這種敏感性
分析用一個或多個模擬運算表(Data Table)很容易實現。

11.3 外匯(
外匯(Currencies)
)和商品(
和商品(Commodities)
)期權

到目前為止,所有的討論都集中在股票期權方面。事實上,基於連續紅利收益的布萊克
-舒爾斯分析框架同樣可以用於為外匯和商品期貨期權定價。我們已經知道,對於連續紅利
收益率為 q 的股票看漲期權,布萊克-舒爾斯定價公式為:

c = S exp(− qT ) N (d1 ) − X exp(− rT ) N (d 2 )


可以將外匯看成是一個支付連續紅利的股票,外匯利率 R 則看成是布萊克-舒爾斯公式中連
續紅利收益率 q。本國利率即為無風險利率 r。因此,外匯看漲期權的定價公式為:

c = S exp(− RT ) N (d 1 ) − X exp(−rT ) N (d 2 )
這就是加曼-科爾哈根公式(加曼和科爾哈根,1983)。圖 11.2 顯示的是 Currency 表中的一
個外匯看漲期權定價例子,它的外匯利率為 4%。期權價格為 0.0044(E11) 。這個例子由
用戶定義函數 BSOptionValue 通過適當的參數計算得到。

Valuing Options on Currency Forwards(As shares with a continuous dividend yield):


為外匯遠期期權定價(如同股票帶有連續紅利的情況)

【參照書中第 188 頁的圖 11.2】

圖 11.2 表 Currency 中的外匯期權定價

圖 11.2 還演示了一種由布萊克(1976)提出的代替方法。他建議將外匯期權的價格用遠期

匯率 F 表示,而不是即期匯率 S。由利率平價理論 S = F exp[ −( r − R )T ] 可知,在定價公

式中可以用 F 來替代 S。因此,布萊克給出的看漲期權定價公式為:


c = exp(− rT )[ FN (d1 ) − XN (d 2 )]

如果用 F/X 表示,則 d 1 和 d 2 的運算式被都很簡單。單格 E13 中用布萊克方法計算出的結果

為 0.0044。已經編寫了一個用戶定義函數 BlackOptionValue 來實現布萊克方法(看單格


E14)。
布萊克公式同樣適用於為商品期貨期權定價,圖 11.3 中的表 Commodities 演示了這種
方法。注意,‘看跌期權-看漲期權-遠期合約(put-call-forward)’的平價關係也是成立
的。因此,當遠期或期貨的價格 F 等於期權的執行價格時,看漲期權的價格等於看跌期權
的價格。(圖 11.3 說明了這點)

Valuing Options on Commodity Futures(As shares with a continuous dividend yield):


為商品期貨期權定價(如同股票帶有連續紅利的情況)

【參照書中第 188 頁的圖 11.3】

圖 11.3 表 Commondities 中的商品期貨期權定價

11.4 計算期權的
計算期權的‘
期權的‘希臘’
希臘’參數

布萊克-舒爾斯的輸入參數有股票現值 S,利率 r,期權有效期,波動率 σ ,及其他一些


因素。研究輸入變數變化對期權價值的影響時,一種辦法是計算期權的所謂“希臘”參數,
或對沖參數。經常計算的對沖參數是一些一階偏導值:delta(描述股價變化的影響),rho
(描述利率變化的影響),theta(描述期權有效期變化的影響),vega(描述波動率變化的
影響);也經常計算股價的二階偏導值 gamma。除了 theta 外,所有的對沖參數都由公式直
接給出。布萊克-舒爾斯偏微分方程將 thera 與期權價格,delta 值,gamma 值聯繫起來。

Option Greeks and Hedging:期權的‘希臘’參數以及對沖

【參照書中第 189 頁的圖 11.4】


圖 11.4 表 Hedge 中的‘希臘(greeks)’參數計算

圖 11.4 顯示的是常用看漲期權的有關“希臘”參數 見表 Hedge。圖中,看漲期權的


delta 值為 0.72。這就是說,當股價發生微小變動,期權價格的變化幅度是股價變化量的 72

%。由於它是基於 N ( d1 ) 的,所以看漲期權多頭(long)的 delta 值總是處於 0,1 之間。

相應地,看跌期權多頭的 delta 值則依賴於 [ N ( d1 ) − 1] ,因此它總是負值。

公式給出的 delta 值是股價為 100 時期權價值的暫態變化率。可以通過試算表來觀察股


價 S 發生微小變化時,期權價值的實際變化量。例如,當股價為 101 時,看漲期權的價格
是 10.46,暗示實際 delta 值為 0.73;當 S 值為 110 時,看漲期權的價格為 17.85,暗示實
際 delta 為 0.81。如果股價變化,對沖比率也將發生變化,對沖組合也需要重新構建。
gamma 值等於股價變化時 delta 值的變化率(也就是看漲期權價格對股價的二階偏
導)。它的計算公式對看漲期權和看跌期權都是一樣的。如果 gamma 值較小,delta 的變化
量也就非常小,如圖 11.4 所示。
對於看漲期權和看跌期權而言,theta 都是負值。它度量期權價格隨時間流失(即期權
有效期減少)的變化率。當期權有效期減小時,期權價格也會減小。
另一方面,隨著波動率的增加,期權的價格也會隨之增加。Vega 用來度量期權價格相
對於波動率的變化率,它是一個正值。而且,計算 vega 的公式對於看漲期權和看跌期權來
說是一樣的。
投資銀行常常構造對沖組合來抵消他們面臨的期權風險。他們感興趣的是,在股票價值
以及波動率等因素變化時,整個頭寸價值將如何變化。期權相對於股價以及其他因素變化的
敏感度(也就是‘希臘’參數)常用來來構造對沖組合,具體情況將在下一節演示。

11.5 對沖組合

計算對沖參數是構造對沖組合必不可少的一步。利用前面用於計算‘希臘’參數的看漲
期權,我們來構造兩個零投資對沖組合(zero-investment hedge portfolios)。所謂零投資組
合,是指相對於股價的變化,組合價值的變化非常微小。第一個是 delta 對沖組合,也就是
說,它可以對沖掉股票價格的微小變化(被稱為 delta 風險)。另一個是 delta-gamma 對沖
組合,它用於對沖股票價格的較大變化,此時 gamma 值會發生改變(被稱為 gamma 風險) 。
將看漲期權定價公式(c=hS-B)寫成 0=hS-B-c 的形式,由此可以得到一個零投資組合,
它包括一些借入資金,用來購買一定數量的股票並出售一份看漲期權。由於這個組合是零投
資組合,因此在每一期股價 S 發生微小變化時,這種數量關係必須保持平衡。在 delta 中性
(delta-neutral)的情況下,購買的股票數量必須等於組合中看漲期權的 delta 值。構造 delta
中性組合的目的在於用期權價值的變化來抵消股票價值的變化。

Creating a delta-neutral portfolio :構建一個 delta 中性組合

【參照書中第 190 頁的圖 11.5】


圖 11.5 表 Hedge 中的 delta 中性組合

圖 11.5 顯示了一個由股票和看漲期權空頭構成的 delta 中性組合,標的股票和期權的資


訊在圖 11.4 中給出,對沖比率也在圖中給出。組合顯示在圖 11.5 的單格區域 E25:E27 中,
它包括買入 0.72 份股票(E22 中)和賣出 1 份看漲期權,所需的現金為 62.10(股票支出
71.83 減去賣出看漲期權所得 9.73)
。當未來股價在一周的時間裏不斷變化(E21 中 S1)時,
我們來觀察初始 delta 中性組合的價值是如何變化的。如果下一周的股價 S1 等於 102,組
合仍包含 0.72 份股票,股票的價值為 73.26,借入的資金為 62.20(包含利息),此時看漲
期權的價值為 11.07(期權有效期變短帶來的價值變化抵消了股價的變化)。對於股價的這
種小幅變化,不需要新的投資就可保持近似的 delta 中性。但如果股價發生了較大變化,則
期權的 delta 值將會改變,此時組合中的股票份數也需要調整,以使組合達到新的平衡。
為了構造一個更好的對沖投資組合以面對更大的未來股價變化,可以在組合中加入另一
種看漲期權,從而構造出一個 delta-gamma 組合以滿足 delta 中性,形式為:

0 = hS − c1 + nc 2

其中 c1 和 c 2 為兩種看漲期權的價值。假設第二種期權的有效期為 9 個月,執行價為 100,

如 圖 11.6 所 示 。 看 漲 期 權 的 gamma 值 在 E37 中 計 算

( k = [ gamma (call1) / gamma (call 2)] )得到。當第二種看漲期權的數量為 k 時,即可消

除組合的 gamma 風險。另外,通過選擇適當的股票係數 h(在單格 E36 中計算得到),就


可以組合的消除 delta 風險。借入或貸出資金的數量(在 E38 中)可以保證該組合為一零投
資組合。同樣,我們可以觀察這個 delta-gamma 中性組合的價值在一周內隨股價(E21 中
S1)的變化情況。

Creating a delta-gamma neutral position :構建一個 delta-gamma 中性頭寸

【參照書中第 191 頁的圖 11.6】

圖 11.6 表 Hedge 中的 delta-gamma 中性組合

如果一周後的股票價格為 S=102,對比 delta 和 delta-gamma 兩個組合,會發現這兩


個組合都是零價值組合,也就是說,它們都不需要追加投資來保持平衡。但如果股價的變化
較大,如從 90 到 110,則圖 11.7 顯示,在這種情況下 delta 值需要不斷調整以使組合達到
平衡,這遠比 delta-gamma 組合要複雜。

Hedge performance:對沖表現
Portfolio value:投資組合價值
Share price:股票價格
【參照書中第 192 頁的圖 11.7】

圖 11.7 delta 對沖組合和 delta-gamma 對沖組合的結果比較

11.6 布萊克-舒爾斯公式的正式推導
布萊克 舒爾斯公式的正式推導

由於布萊克-舒爾斯公式在本章中處於中心地位,因此有必要對它的推導(採用尼爾森
方法,1992)作一個簡要的說明。前面已經提到,有連續紅利收益的股票看漲期權定價公
式為:

c = S exp(− qT ) N (d1 ) − X exp(− rT ) N (d 2 )

要得到這個公式,必須假設股票在到期日 T 的對數收益服從正態分佈。這意味著隨機變數 S T

可以寫成一個隨機方程的形式: S T = S exp(YT ) ,其中 YT 是均值為 µ T ,方差為 σ T 正態分

佈變數。
在風險中性概率測度 Q 下,看漲期權的價值等於其期望收益的折現值,即:

c = exp( − rT ) E Q [max(S T − X ,0)]


這個運算式能寫成以下兩項之和:

c = exp( − rT ) E Q [ S T | S T > X ] − exp( − rT ) E Q [ X | S T > X ]

由於 Pr ob[ S T > X ] = Pr ob[ S exp(YT > X ] = Pr ob[YT > ln( X / S )],因此可以將第二項的

期望值表示為 X Pr o[YT > ln( X / S )]。這個簡化運算式說明,期權只有在 YT 的值大於 ln(X/S)

的情況下才會被執行。由於 YT 服從均值為 µ T 方差為 σ T 的正態分佈,並且:

µ T = (r − q − 0.5σ 2 )T σT = σ T

可以將 YT 轉換成一個標準正態分佈變數 Z T ,只需減去它的均值然後除以它的標準差即可,

即:

Z T = [YT − µ T ] σ T

因此 Z T ~N(0,1)。

累積正態分佈函數 N(d)給出了分佈左尾概率值,也就是 Pr ob[ Z T < d ] 。如果是右尾概

率,即 Pr ob[ Z T > d ] ,則可以根據正態分佈的對稱性用 N(-d)計算得到。


於是可以將 Pr o[YT > ln( X / S )] 轉換成 Pr ob{Z T > [ln( X / S ) − µ T ] / σ T } 的形式:

= Pr ob{Z T < −[ln( X / S ) − µ T ] / σ T }


= Pr ob{Z T < [ln(S / X ) + µ T ] / σ T }
= Pr ob{Z T < [ln(S / X ) + (r − q − 0.5σ 2 )T ] / σ T }

這與 N ( d 2 ) 的運算式相同,由此得到布萊克-舒爾斯公式的第二項。

布萊克-舒爾斯公式第一項的期望值則比較複雜,因為條件期望的兩側都有隨即變數

S T 。要推導布萊克-舒爾斯公式,需要用到關於對數正態和正態變數的兩個結論,一個大家
很熟悉,另一個則比較陌生。

第一個結論是:如果 log S T 服從正態分佈,其均值為 M,方差為 V,那麼:

E[ S T | S T > X ] = E[ S T ]N (d ) d = V − [ln( X ) − M ] / V
其中 X 是一個數值,N()是累積標準正態分佈函數。條件期望被一個普通期望值和一

個正態分佈函數的乘積代替。由於 log S T 的均值 M = ln( S ) + ( r − q − 0.5σ 2 )T ,方差為

V = σ 2T ,因此:

E Q [ S T | S T > X ] = E Q [ S T ]N { V − [ln( X ) − M ] / V }
= E Q [ S T ]N {σ T − [ln( X / S ) − (r − q − 0.5σ 2 )T ] / σ T }
= E Q [ S T ]N (σ T + d 2 )
= E Q [ S T ] N ( d1 )

下一步使用大家比較熟悉的關於對數正態分佈的一個結論:如果 YT 是一個服從正態分

佈的變數,均值為 M,方差為 V,那麼 E[exp(YT )] = exp( M + 0.5V ) 。這裏, YT 是一個正

態變數,其參數為: M = ( r − q − 0.5σ 2 )T , σ T = σ T ,因此:

E Q [ S T ] = SE Q [exp(YT )]
= S exp( M + 0.5V )
= S exp[( r − q )T ]

由此可得到布萊克-舒爾斯公式的第一項 S exp( − qT ) N ( d 1 ) 。

在以上的推導中,能夠看出 d1 ( = d 2 + σ T )和 d 2 間的關係。由於期權僅在股價大於執

行價 X 的條件下才會執行,所以這種關係是反映股價分佈被截尾情況下的一種調整,且調
整幅度與股價增量的標準差有關。
11.7 Module1 中的用戶定義函數

該模組頁中存放著用於計算布萊克-舒爾斯歐式期權價值的 VBA 函數代碼,及相關的


‘中間’函數 BSDOne 和 BSDTwo 代碼。

函數 BSDOne 返回期權公式中的 d 1 值,它的輸入參數有:股票現值 S,期權執行價格

。函數 BSDTwo 返回 d 2 值,
X,利率 r,紅利率 q,以年計的有效期(tyr)及波動率(sigma)

輸入參數與前者類似。
將這些‘中間’函數與 BSOptionValue 函數分開編寫的目的,是為了使計算過程更加

簡潔清晰。NDOne 使用了 Excel 函數 NORMSDIST,其中 d 1 由函數 BSDOne 計算得出。

還有一些語句用來確保程式能夠識別並截獲一些不合理的資料(如負的股價) ,返回一個錯
誤值(在此為-1) 。
BSOptionValue 函數通過參數‘iopt’來區別看漲期權和看跌期權,值為 1 時處理看漲
期權,值為-1 時處理看跌期權。由於存在期權平價關係,看漲期權和看跌期權的定價公式
除了在符號上有區別外,其他地方都是一樣的。分別為看漲期權和看跌期權定價時,變數
NDOne 和 NDTwo 的符號須作改變,就像定價公式那樣。相關代碼如下所示:
Function BSOptionValue(iopt,S,X,r,q,tyr,sigma)
’ returns the Black-Scholes value(iopt=1 for call,-1 for put;q=div yld)
’ uses BSDOne fn
’ uses BSDTwo fn
Dim eqt,ert,NDOne,NDTwo
eqt=Exp(-q*tyr)
ert=Exp(-r*tyr)
if S>0 And X>0 And tyr>0 And sigma>0 Then
NDOne=Application.NormaSDist(iopt*BSDOne(S,X,r,q,tyr,sigma))
NDTwo=Application.NormaSDist(iopt*BSDTwo(S,X,r,q,tyr,sigma))
BSOptionValue=iopt*(S*eqt*NDOne-X*ert*NDTwo)
Else
BSOptionValue=-1
Endif
End Function
為遠期和期貨期權定價的函數只是 BSOptionValue 函數的改進版本,它需要用變數 rfgn 表
示外匯利率:
Function BlackOptionValue(iopt,F,X,r,rfgn,tyr,sigma)
’ returns Black option value for forwards
’ uses BSOptionValue fn
Dim S
S=F*Exp((rfgn-r)*tyr)
BlackOptionValue=BSOptionValue(iopt,S,X,r,rfgn,tyr,sigma)
End Function
計算每個對沖參數的函數可以直接複製試算表中的公式。有一個複合函數 BSOptionGreeks
可以用來計算所有的對沖參數,以避免一些不必要的重複代碼。它通過 IF 語句來判斷整型
變數 igreek 要求返回的是哪一個參數:
Function BSOptionGreeks(greek,iopt,S,X,r,q,tyr,sigma)
’ returns BS option greeks (depends on value of igreek)
’ returns delta(1),gamm(2),rho(3),theta(4) or vega(5)
’ iopt=1 for call,-1 for put; q=div yld
’ uses BSOptionValue fn
’ uses BSDOne fn
’ uses BSDTwo fn
’ uses BSNdashDone fn
Dim eqt,c,c1,c1d,c2,d,g,v
eqt=Exp(-q*tyr)
c=BSOptionValue(iopt,S,X,r,q,tyr,sigma)
c1=Application.NormaSDist(iopt*BSDOne(S,X,r,q,tyr,sigma))
c1d=BSNdashiDOne(S,X,r,q,tyr,sigma)
c2=Application.NormaSDist(iopt*BSDTwo(S,X,r,q,tyr,sigma))
d=iopt*eqt*c1
g=c1d*eqt/(S*sigma*Sqr(tyr))
v=-1
if igreek=1 Then v=d
if igreek=2 Then v=g
if igreek=3 Then v=iopt*X*tyr*Exp(-r*tyr)*c2
if igreek=4 Then v=r*c-(r-q)*S*d-0.5*(sigma*S)^2*g
if igreek=5 Then v=S*Sqr(tyr)*c1d*eqt
BSOptionGreeks=v
End Function

小結

為歐式期權定價的布萊克-舒爾斯公式可以擴展用來處理有連續紅利收益情況下的期權
定價問題。只需在公式中用 S exp(-qT)代替 S 即可。在實際中,股票並不能提供連續的紅
利收益。但可將其他一些類型的資產近似作為支付連續紅利的股票看待,因此,這種修改後
的版本擴大了布萊克-舒爾斯公式的應用範圍。布萊克-舒爾斯框架同樣適用於為外匯和期貨
期權定價。
期權的 delta 值是期權價格相對於股價的變化率。通過 delta 值,可以構造短期的 delta
中性投資組合。但由於組合的 delta 值會隨時間變化,因此組合中標的股票的頭寸需要不斷
調整以達到新的平衡。
期權價格相對於其他因素的敏感度(如波動率,有效期和收益率等)同樣可以計算得到。
它們統稱為‘希臘’參數,它們對構建對沖組合很重要。

參考文獻
Black,F., 1976, “The Pricing of Commodity Contracts,” Journal of Financial Economics, 3,
167-179.
Garman, M. B. and S. W. Kohlhagen, 1983, “Foreign Currency Option Value,” Journal of
International Money and Finance, 2, 231-237
Hull, J. C., 2000, Options, Futures and Other Derivatives, Prentice Hall, New York.
Nielsen, L. T., 1992, “Understanding N(d1) and N(d2): Risk-Adjusted Probabilities in the
Black-Scholes Model,” INSEAD Working Paper 92/71/FIN.
第 12 章 歐式期權定價的其他數值方法

本章將討論兩種用於為歐式期權定價的數值方法(蒙特卡羅模擬和數值積分(numerical
integration))
。它們可以代替二叉樹方法來計算期望值。但對美式期權,仍建議用二叉樹方
法給標準期權定價。
蒙特卡羅模擬是一種非常成熟的技術,它廣泛運用於各種領域。但對於期權定價來說,
期權定價時, 普通隨機抽樣蒙特卡羅模擬的效率相對較低(特別是與二叉樹方法相比較)。
例如,為了使抽樣誤差減少一半就需要 4 倍數的類比試驗。因此,最近在金融領域出現的
准隨機序列技術(quasi-random number sequences),以及電腦性能的提高,大大推進了
蒙特卡羅模擬的應用。類比方法被認為是為路徑依賴(path-dependent)期權定價的最好數
值方法。關於類比的相關背景資料請閱讀赫爾(2000)書中的期權部分(第 16 章) 。
本章首先用普通蒙特卡羅模擬為歐式看漲期權定價,然後使用對偶變數(antithetic
variates)類比,最後使用准隨機序列進行模擬,並將它們作比較。使用對偶變數的目的是
通過減小類比結果的標準差來提高估計的效率。准隨機抽樣能進一步有效控制模擬結果的隨
機性。這三種方法在 OPTION3.xls 的不同表中實現,第四張表中給出結果比較。
接下來演示數值積分方法。前面已經間接提到過,布萊克-舒爾斯期權定價公式來源於
連續積分。 (正如在第九章中提到的,該公式是通過解一個偏微分方程得到的) 。二叉樹提供
了一種離散近似方法,而在此將使用中值定律更直接地進行數值積分。

12.1 蒙特卡羅模擬介紹
蒙特卡羅模擬介紹

蒙特卡羅模擬進行期權定價的核心在於生成股票價格的隨機過程。9.2 節中,在期權到
期的 T 時刻,標的股票價格的隨機方程為:

ST = S exp(YT ) = S exp( µT + εσ T )

其中,隨機變數 ε 服從標準正態分佈,即服從 N(0,1),隨機變數 YT 服從正態分佈,其均值

為 µ T = ( µ − 0.5σ 2 )T ,方差為 σ T = σ T , µ 為股票的收益率, σ 為股票的波動率。期

權的收益依賴於 ST 在風險中性世界裏的期望值,因此對於風險中性定價,股票的收益率

( µ )可以用無風險利率 r 減去連續紅利收益率 q 代替,也就是(r-q)


。於是風險中性定價

的 ST 隨機方程為:

S T = S exp[( r − q − 0.5σ 2 )T + εσ T ]
其中 ε 服從標準正態分佈。上式中的股價運動過程與前面二叉樹定價中的一樣。

蒙特卡羅模擬隨機產生一組股價終值 ST 的樣本值,即類比試驗。然後為每一個樣本值

計算期權收益並記錄下來。產生足夠多的樣本值後,就可以得到期權收益的分佈,通常需要
計算分佈的均值和標準差。模擬試驗的代數平均值常用來估計期權收益分佈的期望值,然後
用無風險利率對其折現來得到看漲期權的價格。
圖 12.1 為 OPTION.xls 工作簿中 MC1 表的一部分,表中歐式期權的有效期是六個月,
其標的資產是連續紅利收益率為 3%的股票。表中有 36 個期權收益的模擬試驗,用它們可
以估計出期權收益期望值的折現。

Using Monte Carlo Simulation to Value BS Call Option:


利用蒙特卡羅模擬來為布萊克-舒爾斯看漲期權定價

【參照書中第 198 頁的圖 12.1】

圖 12.1 期權資訊及 5 個(從 36 個類比資料得到)期權收益模擬結果(表 MC1)

每個模擬試驗產生一個終值股價( ST 的一個樣本值)和一個期權收益值。在 B 列中用 Excel

的 RAND 函數來產生服從均勻分佈的亂數,然後在 C 列用標準正態分佈函數 NORMSINV


將其轉換成隨機樣本。RAND 函數產生[0,1]間服從均勻分佈的亂數。將其作為累積概率值(值
在 0 到 1 之間)
,用 NORMSINV 即可得到服從標準正態分佈的隨機變數值,其結果大部分
處在-3 與 3 之間。例如,第一次模擬試驗 C22 中的公式為:
=NORMSINV(B22)
其輸入值為 0.1032(大約 10%),產生的標準正態變數的值則為-1.2634。
得到隨機樣本值( ε ),就可以用下面公式計算期權到期日的股票價格:

S T = S exp[( r − q − 0.5σ 2 )T + εσ T ]
為了將其轉換為單格公式的形式,有必要先計算出 T 時刻的風險中性漂移項和波動率,也

就是 ( r − q − 0.5σ )T 和 εσ T (分別處於 B16 和 B17 中)


2
。因此,E22 中的公式為:

=$B$4*EXP($B$16+C22*$B$17)
相應的期權收益為(H22)

=MAX($E$4*(E22-$B$5),0)
E4 中存放的是參數 iopt,它用來區分看漲期權和看跌期權。
計算模擬出的 36 個期權收益的平均值,然後折現即可得到看漲期權價值的估計量
(E9)。用於折現的風險中性因數(exp(-rT))放在 B18 中。
圖 12.1 顯示,期權價格的蒙特卡羅估計值(12.85)與布萊克-舒爾斯期權價格有較大
的差異。E10 中,期權價值估計值的標準差(模擬期權收益的標準差除以模擬次數的平方根)
相對較大(這就是蒙特卡羅估計值與布萊克-舒爾斯期權價格有較大差異的原因) 。為了提高
蒙特卡羅估計的準確度,有必要增加模擬試驗的次數。
在 Excel 中按下 F9,就可以產生另外 36 個模擬值,並得到一個不同的蒙特卡羅期權價
格以及相應的估值標準差。對於看跌期權,單格公式同樣適用。將參數 iopt(E4 中)改為
-1,就可以計算看跌期權的蒙特卡羅估計值,可將它與布萊克-舒爾斯期權價格作比較。

12.2 對偶變數(
對偶變數(Antithetic Variables)
)類比

除了增加模擬試驗的次數,另一個提高蒙特卡羅估計精度的方法是使用所謂的‘對偶’
變數。對偶變數方法用一對負相關變數來生成一對負相關類比樣本。如果將每對結果取平均
值,則模擬結果的可變性將比普通隨機樣本小。

圖 12.2 顯示了表 MC2 中的一些模擬結果,正態隨機樣本(C22 中的 ε 1 )用來生成兩

個股票價格,其中 D22 中的值來自服從 N(0,1)分佈的 ε 1(C 列中)


,E22 中則來自其相反數

- ε 1。由於這一對股票價格是嚴格負相關的,因此模擬的期權收益 payoff1 和 payoff2 也是趨

於負相關。H22 由二者的平均得到。可以看出,用這種技術得到的模擬結果(H 列中)的


可變性要明顯小的多。

【參照書中第 200 頁的圖 12.2】

圖 12.2 表 MC2 中運用對偶變數方法的 5 次期權收益模擬結果

將 H 列中的 36 個模擬結果取平均值,然後用無風險利率折現即可得到看漲期權的價值
(B18),如表 MC1 中所示。
MC2 中的情況基本與普通蒙特卡羅模擬一樣。但應該注意,MC2 中蒙特卡羅類比(使
用對偶變數)估值的標準差要比 MC1 表中的小的多。

12.3 准隨機抽樣(
准隨機抽樣(Quasi-Random Sampling)
)模擬

實際應用中,不加控制的隨機變數顯得過於隨機。例如,一個均勻分佈的隨機序列經常
聚在一堆。解決這種聚集現象的方式之一是產生一個隨機序列,使之均勻的分佈於單位間隔
中。准隨機序列以確定的方式提前設定一組數,從而消除亂數的聚集現象。唯一的技巧是在
選擇新數時不要選擇已經入選的資料。用准隨機抽樣意味著樣本估計值的誤差與 1 / n 而不是
1 / n 成比例,n 為樣本容量。QMC 表(用 QMC 表示 Quasi-蒙特卡羅)中顯示了生成准
隨機序列的結果,並介紹一種將其轉化為標準正態變數的改進方法。該方法使用福勒序列而
不是均勻隨序列,並使用了由莫羅提出的修正轉化方法。莫羅將傳統的博克斯-馬勒轉換方
法做了改進,因為一些正態分佈函數的反函數容易打亂福勒序列的均勻間隔。生成福勒序列
並將其轉化為正態分佈變數是通過 VBA 用戶定義函數實現的。這些函數的代碼,以及
Module1 模組頁中的其他用戶定義函數將在 12.7 節解釋。關於福勒序列,需要特別說明的
4
是,為了與實際相符合,福勒序列是從 2 (16)開始的,以避免初始值問題(start-up


problem)
在圖 12.3 中,第 22 行的資料為第一次類比試驗的結果,其中 B22 為第一個准亂數,
它在 FaureBase2 函數輸入值為 16 的情況下產生。C22 使用 MoroNormSInv 函數將其轉化
為標準正態變數。股票價格(E22)和期權收益(H22)的計算與 MC1 表中相同,E9 中給
出了期權價值,其標記為‘QMC value’。該估計值為 8.95(標準差為 1.69,見 E10) ,它
與布萊克-舒爾斯公式得到的 9.73 並不是很接近。但在 12.4 節,將看到使用准隨機抽樣方
法的最大好處是,隨著模擬次數的增加,所得的結果收斂於真實資料的速度是最快的。

Using Monte Carlo Simulation to Value BS Call Option(Quasi-Random Numbers):


利用蒙特卡羅模擬來為布萊克-舒爾斯看漲期權定價(准亂數)

【參照書中第 201 頁的圖 12.3】

圖 12.3 期權資訊及 5 個(從 36 個類比資料得到)期權收益模擬結果(表 QMC)

注意,按下 F9 重新計算時,表中資料沒有變化。福勒序列是完全確定的,而不是隨機
的,因此,名稱‘准隨機’在此顯得並不恰當。因此有必要用不同次數的模擬試驗來得到不
同的 QMC 價格和標準差。
與前面的表類似,該定價同樣適用於看跌期權。只需改變參數 iopt 的值(-1)即可得到
看跌期權的 QMC 估計值,可以將估計值與布萊克-舒爾斯公式所得值進行比較。
准隨機抽樣可以看作是分層抽樣(stratified sampling)的發展。對分層抽樣來說,間
隔將分的更細,並有一定數量的樣本隨機分佈在每個間隔中,故在小間隔內會存在資料聚集
現象。而在准亂數序列中卻沒有任何隨機因素,因為對序列中的每一個值,它的相對位置已
經預先確定。
12.4 模擬方法比較

對於前面提到的三種抽樣方法,隨著模擬試驗次數的增加,觀察看漲期權價值的收斂性
是很有必要的。圖 12.4 列出了模擬次數從 100 增加到 2000 時的對比結果。布萊克-舒爾斯
價格提供了一個基準值(由函數 BSOptionValue 計算得到,位於 F 列)
。G 列中的看漲期權
價值是用控制抽樣法(通過對偶變數)由函數 MCOptionValue 計算得到的。H 列中的資料
則是用准隨機抽樣方法用函數 QMCOptionValue 計算得到的。

Comparing Monte Carlo Simulation Methods to Value BS Call Option:


比較為布萊克-舒爾斯看漲期權定價的不同蒙特卡羅模擬方法

【參照書中第 202 頁的圖 12.4】

圖 12.4 蒙特卡羅隨機和准隨機抽樣的估計值與 BS 價值的比較

如果將區間 E6:H17 中的資料用折現圖表示(如圖 12.5 所示)


,可以發現,QMC 估
計值的收斂性相對於 MC 估計值有較大的改進。當模擬次數增加時,QMC 估計值以‘二次’
速率收斂,這與第 10 章提到的 LR 二叉樹的收斂特性相似。

Convergence of MC estimates to BS value:BS 價值蒙特卡羅估計值的收斂情況


Call value:看漲期權價值;
Number of simulations:模擬次數

【參照書中第 203 頁的圖 12.5】

圖 12.5 MC 和 QMC 抽樣估計值相對於 BS 價值的收斂性


12.5 蒙特卡羅 模擬中的希臘參數計算

大多數教科書都認為估計對沖參數的最好方法是使用有限差分近似(finite difference
approximations),每次近似,輸入參數的一個微小改變,都需要一個額外的類比試驗。這
種方法得到的是一個有偏估計,並且消耗時間。
布羅迪和格拉瑟曼(1996)提出了怎樣在一次模擬試驗下得到直接的順向估計值。這
種估計是無偏的, 且比有限差分近似更快得到結果。用戶定義函數 QMCOptionGreek135
(參數為 igreek)中包含有這些公式的代碼,存放於 Module1 中。函數使用准隨機正態變
數(-qrandns),並調用 FaureBase2 函數以及 MoroNormSInv 函數。可返回 delta 值
(igreek=1),rho 值(igreek=3)或者 vega 值(igreek=5)。

12.6 數值積分

數值積分是另一種眾所周知的可用于期權定價的數值方法。在此只介紹最簡單一種積分
程式,即擴展的中值定律(midpoint rule)。該方法將區間分為一組等寬的間隔(假設寬度

為 h),並用間隔的中值 z i 對函數進行積分,然後估計 S T 及相應的期權收益。 S T 每一個值

的概率用間隔 h 與該間隔中值的標準正態密度函數值的乘積來近似。用該概率對期權收益
加權平均,就可以得到期權的期望收益。由此可以看出,數值積分的這種形式與二叉樹中期
望值的計算非常相似,只是在這裏使用的是正態分佈函數。

圖 12.6 顯示了 NI 表中的部分內容。表中, S T 的可能取值範圍被分成 36 個等寬區間,

跨度從-6 倍的標準差到+6 倍的標準差(偏離均值的距離),因此每個區間的寬度為 1/3


倍的標準差(因此 h=0.33)
。每個區間的中值放在 B 列中,用偏離均值的標準差倍數表示,
相應的到期日風險中性股票價格放在 C 列中,C21 中第一個值的計算公式為:
=$D$4*EXP($D$15+$D$17*B21)

Using Numerical Integration to Value BS options:利用數值積分方法來為 BS 期權定價

【參照書中第 204 頁的圖 12.6】

圖 12.6 用中值定理計算數值積分(表 NI)

相應的期權收益放在 E 列中。F 列存放的是概率,F21 中的公式為:


=$H$17*NORMDIST(B21,0,1,FALSE)
參數 FALSE 表示該函數返回的是概率密度值,即,均值左邊 5.83 倍標準差距離處的正態
曲線高度。用概率密度乘以區間寬度 h,即可得到一個近似的概率。這個概率用來計算期權
收益的期望值,就像前面二叉樹中用到的節點概率一樣。在 H 列中存放的是收益值與對應
概率的乘積,對其求和並用無風險折現因數折現即可得到期權價值。單格 H9 中的所謂‘NI
value’為 9.71,它比較接近布萊克-舒爾斯公式所得值。
對於圖 12.6 中顯示的 z 值,當概率為 0 時,H 列中得到的乘積也為 0。但當 i 從 17 到
30 時,這個乘積就不為 0 了。圖 12.6 確認了這一點,用偏離均值不同距離的 S T 概率和相

應的期權價值,這兩者的乘積可以期權收益的期望值。

Components of Expected Value:期望收益的組成部分

【參照書中第 205 頁的圖 12.7】

圖 12.7 概率及收益值,二者構成期望收益

上面的例子只是用數值積分方法為簡單的期權定價,它相當的簡單。數值積分真正盛行
的原因是它可以為收益依賴於多種資產的期權定價。

12.7 Module1 中的用戶定義函數

為了方便試算表計算,已經編寫好了用戶定義函數來實現本章討論所有數值方法。12.4
節中已經見過 MCOptionValue 函數和 QMCOptionValue 函數,還比較了兩者的相對收斂速
度。以下主要討論它們的代碼。
MC2 表中的 MCOptionValue 函數使用了一個迴圈結構來進行一系列類比試驗。變數
‘sum’用來存儲期權收益的和,這裏使用對偶變數方法得到兩個股票價格。股票價格依賴
於時間‘tyr’內的漂移項(用變數‘rnmut’表示),以及波動率(用‘sigt’表示)。直接
類比股票對數價格可能速度更快,但為了清楚起見,我們仍然模擬股票價格。代碼的關鍵部
分如下所示:

Rnmut=(r-q-0.5*sigma^2)*tyr
sig=sigma*Sqr(tyr)
sum=0
For i=1 To nism
Randns=Application.NormSlnv(Rnd)
S1=S*Exp(rnmut+randns*sigt)
S2=S*Exp(rnmut-randns*sigt)
payoff1=Application.Max(iopt*(S1-X),0)
payoff2= Application.Max(iopt*(S2-X),0)

QMCOptionValue 函數代碼中除了調用 FarueBase2 函數和 MoroNormSInv 函數的語句


外,其他部分與上面的代碼相似,這兩個函數替代了 Excel 和 VBA 函數的功能(在
MCOptionValue 中用到)
,用來生成隨機樣本。主要代碼如下:

sum=0
For i=1 To nsim
qrandns=MoroNormSlnv(Faure1Base2(i+iskip))
S1=S*Exp(rnmut+qrandns*sign)
sum=sum+Application.Max(iopt*(S1-X),0)
Next i
QMCOptionValue=Exp(-r*tyr)*sum/nsim

福勒序列需要將 10 進制整數轉換成其他進制的數。在此選擇 2 進制。將 2 進制數反轉,


最終得到一個由 1/2 冪表示的分數。

Function FaureBase2(n) Double


’ returns the equivalent first Faure sequence number
Dim f As Double, sb As Double
Dim i As Integer, n1 As Integer, n2 As integer
n1=n
f=0
sb=1/2
Do While n1>0
n2=Int(n1/2)
i=n1-n2*2
f=f+sb*i
sb=sb/2
n1=n2
Loop
FaureBase2=f
End Function

QMCOptionGreek135 函數使用布羅迪和格拉瑟曼公式計算三個希臘參數(delta,rho,
vega )。 Gamma 不 是 一 個 亂 數 , 它 是 確 定 的 , 可 以 用 前 面 BSOptionGamma 函 數
(OPTION2.xls 工作簿中)中的相同公式計算得到。正如前面提到的,用模擬出的期權價
值,以及 delta 和 gamma 估計值,就可以計算出 theta 參數:

ert=Exp(-r*tyr)
rumut=(r-q-0.5*sigma^2)*tyr
sigt=sigma*Sqr(tyr)
r1=(r-q+0.5*sigma^2)*tyr
iskip=(2^4)-1
greek=0
vg=-1
For i=1 To nsim
Qrandns=MoroNormSlnv(Faure1Base2(i+iskip))
S1=S*Exp(rnmut+qrandns*sigt)
If(igreek=1 And Sgn(iopt*(S1-X))=1)Then greek=greek+S1
If(igreek=3 A nd Sgn(iopt*(S1-X))>=1)Then greek=greek+S1
If(igreek=5 A nd Sgn(iopt*(S1-X))>=1)Then greek=greek+S1*(Log(S1/S)-r1)
Next i
If igreek=1 Then vg=ert*(greek/S)/nsim
If igreek=3 Then vg=ert*X*tyr*greek/nsim
If igreek=5 Then vg=ert*(greek/sigma)/nsim
QMCOptionGreek135=vg

NIOptionValue 函數在一個迴圈內建立股價運動過程,並計算數值積分的和。注意在迴圈後
兩個成份(S 和 h)是如何插入的。

Function NIOptinValue(iopt,S,X,r,q,tyr,sigma,msd,nint)
’ values option using numerical integration
Dim rnmut,sigt,h,sum,zi,payi
Dim i As integer
rumut=(r-q-0.5*sigma^2)*tyr
sigt=sigma*Sqr(tyr)
h=2*msd/nint
sum=0
For i=0 To nint -1
zi=-msd+(i+0.5)*h
payi=Application.Max(iopt*(Exp(rnmut+zi*sigt)-X/S),0)
sum=sum+payi*Application.NormDist(zi,0,1,False)
Next i
NIOptionValue=Exp(-r*tyr)*h*S*sum
End Function

小結

本章以布萊克-舒爾斯歐式期權定價公式為基礎,介紹了另外兩種用於計算期權價值期
望值的方法。
蒙特卡羅模擬從風險中性世界裏的股價運動路徑中抽樣。計算每一條路徑的期權收益,
然後求其代數平均值,最後用無風險利率折現來對估計期權價值。
與二叉樹定價方法相比,蒙特卡羅模擬法得到的估計值誤差較大。蒙特卡羅抽樣必須生
成很多路徑,因為與二叉樹不同,它的路徑不能重組。
可以用減少方差的技術來控制隨機抽樣,如用對偶變數來減少估計誤差。准隨機抽樣以
確定的方式預先設定序列中的數值,它消除了隨機變數中的聚集現象。取樣的方式就像這些

值總是填充在已存在的樣本之間。這意味著估計的誤差與 1/n 成比例而不是 1 / n ,其中 n

為類比樣本個數。
數值積分法是可用于對期權定價的另外一種方法,當期權的收益依賴于多種資產時,這
種定價方法尤其有效。
參考文獻
Broadie, M. and P. Glasserman, 1996, “Estimating Security Prices Using Simulation”,
Management Science, 42(2), 269-285.
Hull, J. C., 2000, “Options, Futures and Other Derivatives”, Prentice Hall, New Jersey.
Moro, B. 1995, “The Full Monte”, Risk, 8(2), 57-58
第 13 章 非正態分佈和隱含波動率

布萊克-舒爾斯期權定價公式假設對數股價收益服從正態分佈。首先,再次強調該假設
的重要性,即利用對數股價收益正態分佈的均值和方差,可以給出布萊克-舒爾斯公式的另
外一種表達形式。布萊克-舒爾斯公式也可以用對數正態分佈(股價的分佈)的前兩階距
(monments)表示。
應用布萊克-舒爾斯公式時,除了期權有效期內股票收益的波動率外,其他參數都是已
知的。給定波動率一個具體數值,通過公式得出一個期權價值,同樣,對該過程可以進行反
向計算。即,給定一個期權價格的市場觀測值,可以計算布萊克-舒爾斯公式中的隱含波動
率。找隱含波動率(或者 ISD,表示隱含標準差)的過程可以通過手工反復試驗得出,改進
的方法就是讓該試驗過程自動化。這裏將討論確定初值的不同方法,以及通過牛頓-拉夫森
迭代尋找一個較佳的 ISD(隱含標準差)估計值。
理論界常常對期權定價中怎樣允許偏離嚴格正態分佈的情況比較感興趣。我們在此討論
兩種修正,一種是可選擇的分析公式,另一種是可選擇的二叉樹。第一種情況通常設定股價
服從一個逆 gamma(RG)分佈,而不是常見的對數正態分佈;第二種情況保持了股價的
對數正態分佈,但允許對數收益的高階矩(偏度和峰度)與嚴格正態分佈有差異。試驗表明,
對數股價收益是典型的肥尾(峰度大於 3)和偏度現象。
本章最後介紹由期權市場價格產生的隱含波動率曲線,它用於反映對數收益分佈在不同
假設下的波動情況, 而不是用於預測波動率。
除了赫爾(第 17 章)關於波動率曲線的討論外,標準文獻並不沒有本章所討論的專題。
更詳細的內容需要查閱相關的專業論文。然而,工作簿 OPTION4.xls 中的所有計算過程都
編成了用戶定義函數程式。

13.1 非正態分佈假設下的布萊克-舒爾斯
非正態分佈假設下的布萊克 舒爾斯 公式

在強調股價收益分佈假設的前提下,OPTION4.xls 中表 Dist 描述了其他分佈條件下布


萊克-舒爾斯期權定價過程。首先,強調對數股價滿足正態分佈,可以計算出均值和方差,
並用這兩種矩重新表述布萊克-舒爾斯公式。

由 於 M = ln( S ) + ( r − q − 0.5σ )T , V = σ T , 故 exp( M + 0.5V ) 能 夠 簡 寫 成


2 2

S exp[(r − q )T ] ,因此關於歐式看漲期權的布萊克-舒爾斯公式可以寫成:

c( LN ) = exp(− rT )[exp( M + 0.5V ) N (d1 ) − XN (d 2 )]

d 2 = [ M − ln( X )] / V = d 1 − V

符號 c( LN ) 表示公式中使用了分佈的矩。

在圖 13.1 中,對數股價正態分佈的矩分別在 E4(M)和 E5(V)中,其中,M 的計算


公式為=LN(B4)+(B6-B8-0.5*B12^2)*B11,關於 V 的計算公式為=(B12^2)*B11。E13 中用
矩運算式得出的期權價格為 9.73,和布萊克-舒爾斯公式所得值(B17)完全一致。
Option Values using the LN and RG distributions:
對數正態分佈和逆 gamma 分佈條件下的布萊克-舒爾斯定價

【參照書中第 210 頁的圖 13.1】

圖 13.1 對數正態分佈或逆 gamma 分佈條件下的布萊克-舒爾斯定價

定價公式(對數正態情況下的布萊克-舒爾斯公式)同樣能表示成股價對數正態分佈的矩形
式,即:

c( LN ) = exp(−rT )[ M 1N (d1 ) − XN (d 2 )]

d1 和 d 2 能分別通過 M1 和 M2 的形式表述,對數正態分佈的矩(M1 在 H4 中,M2 在 H5


中)能通過正態分佈的矩 M,V 計算得到:
M1=exp(M+0.5V), M2=exp(2M+2V)
關於矩的計算公式見 7.7 節。H17 中得到的期權期權價值利用 M1 和 M2 作為用戶定義函數
LNOptionValue(相關代碼見 13.5)的輸入參數,在圖 13.1 中,LN value 值為 9.73,與布
萊克-舒爾斯值完全一致,儘管輸入參數不一樣。
由矩 M1 和 M2 出發,可以給出另外一種期權定價方法,該期權定價方法用股票價格服
從 RG 分佈(逆 gamm)來替代對數正態分佈的假設。Milevsky 和波斯納(1998)提出,
此分佈適合於對所謂籃子期權(basket options)的定價,在此,將其用於普通期權定價。
稱隨機變數 Z 服從逆 gamma 分佈是指它的倒數(1/Z)服從 gamma 分佈。可以用逆
gamma 分佈代替正態分佈[N(d)]對期權定價。gmma 分佈依賴期權執行價的倒數(1/X)和
另外兩個參數 alpha(H7)和 beta(H8)。 輸入參數可以用 M1 和 M2 計算得到。
RG 看漲期權定價公式為:

c( RG ) = exp( − rT )[ M 1g1 − Xg 2]

其中,g1 和 g2 取代了正態分佈函數 N ( d1 ) 和 N ( d 2 ) 。在圖 13.1 中,由 RG 定價公式給出

的值為 9.64(H3)
,於布萊克-舒爾斯定價值 9.73 相比。RG 和布萊克-舒爾斯定價之間的差
距只有在期權出現虛值(out of the money),即 S 相對較小時才會比較明顯。為了驗證這
點,可以將 B4 中的股價由 100 降到 75,並注意得出的期權價格。這裏,B17,H17,E20
和 F20 值都需要重新計算,每次計算可通過 F2 和回車鍵實現。

13.2 隱含波動率(
隱含波動率(Implied Volatility)

下面,利用布萊克-舒爾斯公式估計市場中不同期權價格的隱含波動率。簡單依靠反復
試驗就可以得到與觀察期權價格相匹配的隱含波動率。有多種不同的實現方法:Excel 的單
變數求解,柯拉多和米勒(1996)近似,馬納斯特和凱勒法(1982)或用戶定義函數,分
別介紹如下。
圖 13.2 中,標準看漲期權的詳細資訊都已列出(B4 到 B12),由用戶定義函數
BSOptionValue 計算的期權價值為 9.73。假設觀測到的該期權市場價值為 15.00, 接下來的
任務是通過一系列 B12 的估計值找到一個與布萊克-舒爾斯定價為 15.00 相匹配的隱含波動
率。可以手工完成,也可以通過 Excel 功能表工具中的單變數求解完成,用單變數求解命令
時,目標單格為 B15,目標值為 15,可變單格為 B12,解得實際的隱含波動率為 41.28%。
以上的單變數求解法可以用一個用戶定義函數 BSOptionISDGoalSeekNR 來複製。該
函數記下每次波動率估計值的當前誤差(運用該估計值得到的期權價格與實際價格的差)和
定價函數相對於波動率的斜率。定價函數相對於波動率的斜率(一階倒數 dc/d σ )與 vega
的作用相同(在 11.4 中討論的一個期權希臘參數) 。使用斜率來提高後續猜測的精確性,此
方法被稱為牛頓-拉夫森方法。在一定的精度要求下,很容易由一個迴圈完成牛頓-拉夫森方
法的編程,直至得到期權價格的觀測值 。BSOptionISDGoalSeekNR 的具體代碼將在 13.5
節中介紹。

Estimating Implied Volatility(or ISD) in BS Option Values:


在 BS 定價過程中估計隱含波動率(或隱含標準差)

【參照書中第 212 頁的圖 13.2】

圖 13.2 通過市場價格與 BS 定價結果相匹配來估計隱含波動率

柯拉多和米勒(1996)給出了一個用於近似計算隱含波動率的解析公式。首先,把 N(d)
近似地表示成線形函數,並將這個近似的線形函數代入布萊克-舒爾斯公式,與看漲期權價
格觀測值一起得到一個二次方程式。在保持布萊克-舒爾斯公式輸入參數和觀測看漲期權價
格的情況下,解上述方程即可得到一個關於隱含波動率的近似值。我們用柯拉多和米勒方法
解的近似值作為 BSOptionISDGoalSeekNR 函數中牛頓-拉夫森迭代的初試值。
在期權執行價格和股票當前價格比較接近的情況下,這種估計是比較精確的。如果執行
價為 95,期權觀測值為 15,由柯拉多和米勒法得出的值為 41.10%(H4),同樣情況下,
由 BSOptionISDGoalSeekNR 公式得到的結果為 41.28%。然而,對於一些極端的情況,這
種線形近似的方法將失去作用。例中,設置 B12 等於 20%,觀測期權價格 B17 為 7.7。calc1
的值(柯拉多和米勒法的一個中間結果)在這種情況下為負(單格 H9),該近似法無效。
對於這種情況,馬納斯特和凱勒(1982)提出了一種方法,用於給單變數求解(Goal Seek

提供一個有效的初值。這些初值(稱為種子值)是這樣選擇的,要滿足 N ( d1 ) 或 N ( d 2 ) 等

於 0.5,並指出,在有解的條件下,從這個種子值開始計算一定能得到正確的隱含波動率。
對於上述柯拉多和米勒法失效的情況(觀測的期權價格為 7.7)
,可以使用 55.24%作為馬納
斯特和凱勒的種子值,用此作為初值,通過牛頓-拉夫森迭代,可以產生連續改進的隱含波
動率估計值,最終達到正確的結果 9.9%。

13.3 調整偏度(
調整偏度(Skewness)
)和峰度(
和峰度(Kurtosis)

研究人員特別關心對數收益比布萊克-舒爾斯公式中假設正態分佈具有更大的高階矩時
的期權定價問題。魯賓斯坦(1998)給出怎樣調整二叉樹,使其產生給定偏度和峰度的分
佈。該方法實現起來分兩步,這裏用圖 13.3(Edge 表的一部分)中關於歐式期權的例子來
說明。首先,利用所謂的埃奇沃思因數產生一個離散分佈(調整後的二項分佈),此分佈具
有給定的偏度和峰度。第二步,利用股價分佈(調整後的二項分佈)和埃奇沃思概率計算期
權收益的期望值。

Generating an Edgeworth distribution:


生成一個埃奇沃思分佈

【參照書中第 213 頁的圖 13.3】

圖 13.3 在給定偏度和峰度條件下產生埃奇沃思分佈

在工作簿 OPTION1.xls 的表 JRBinomial 中,我們說明了怎樣用一個離散的二叉樹來近


似一個連續的標準正態分佈;同樣,在 JREuro 中說明期權價值是一個離散的期望值,此期
望值由期權在各結點的收益與相應的概率值加權得到。
如圖 13.3 所示,埃奇沃思分佈由一些列節點與相應的概率構成。由於這裏選擇的是 16
期二叉樹模型,因此初始的節點範圍為小於均值 4 倍標準差到大於均值的 4 倍標準差,即
區間[均值-4*標準差,均值+4*標準差]。用二叉樹節點的分佈概率(D 列,實際上是 n=16,
p=0.5 的二項分佈的概率)乘以埃奇沃思擴展式(E 列)即可得到調節後的概率分佈(F 列) 。
將 F 列調整為概率之和為 1 的 H 列。這時,埃奇沃思分佈有 3 階(H6)和 4 階矩(H7),它
們的值應該接近於給定的 B6 和 B7 中的值。最後,為了保證埃奇沃思分佈均值為 0,標準
差為 1,將 B 列中的初始節點值變換為 J 列值。以上完成了魯賓斯坦方法的第一步。
對於一個峰度偏大的對稱分佈(在此,偏度為 0.0,峰度為 5.4) ,埃奇沃思調節增大了
兩端情況(大於均值 2 個標準差)的概率。圖 13.4 為效果圖。由於將中間概率的一部分調
整給了兩端,相對於布萊克-舒爾斯定價,這裏得到的期權價值會底些。

Edgeworth distribution(v.standard):Edgeworth 分佈與標準正態分佈的比較


Standard deviations from mean:標準差

【參照書中第 214 頁的圖 13.4】

圖 13.4 峰度為 5.4 的埃奇沃思分佈與標準正態分佈的比較


到此,我們一直在使用均值為 0,方差為 1 的標準分佈。還需要對它進行調整,使得股價分
佈具有適當的風險中性均值和方差。當對數股價服從正態分佈,按年計算均值的漂流量為

r − q − 0.5σ 2 ,在此等於 0.03(見圖 13.5 的單格 D44)。由於與嚴格正態分佈存在一定的


偏差,因此,將單格 D45 計算的值 0.0299 稱為 埃奇沃思風險中性漂移或者 RNdrift E。
下面,進行期權定價的第二步計算,見圖 13.5,將第一步計算的節點複製到單格 D49
到 D65,第一步計算的概率仍然在單格 H49 到 H65。股票價格的離散分佈在 E 列,相關看
漲期權收益在 F 列,使用埃奇沃思分佈計算得到期望值在 J 列。最終得到的看漲期權價值
為 9.37(單格 J35)
,正如前面所預料那樣,小於布萊克-舒爾斯 公式的結果 9.73。
在嚴格正態分佈的假設下檢驗一下前面的結果,設定偏度值(B6)為 0.0,峰度值(B7)
為 3.0,那麼由埃奇沃思得以的期權價值將非常接近布萊克-舒爾斯公式所得值。微小差別是
由於在定價模型中僅僅使用了 16 期二叉樹來近似連續的對數正態分佈引起的。

Valuing an Option based on Edgeworth Distribution:


基於埃奇沃思分佈的期權定價

【參照書中第 215 頁的圖 13.5】

圖 13.5 Edge 表中對股價服從埃奇沃思分佈的看漲期權進行定價

由於篇幅原因,這裏僅用一個 16 期的二叉樹來說明埃奇沃思期權定價方法。魯賓斯坦建議,
為了達到精確結果,至少需要 100 期。將期數定義為輸入參數,使用用戶定義函數
EdgeworthEuroOption,很容易對期權進行定價。該函數的使用見單元 J36。

13.4 波動率曲線(
波動率曲線(The Volatility Smile)

如果將埃奇沃思分佈定價法得到的看漲期權價值與布萊克-舒爾斯定價法得到的價值進
行比較,其結果可以用於說明所謂的“波動率曲線”。波動率曲線是指期權的隱含波動率與
執行價格的函數圖。如果布萊克-舒爾斯公式中關於分佈的假定完全成立,那麼,觀測到的
波動率曲線應該是一條直線。工作簿 OPTION.xls 中的表 Smile 是對該方法的說明,圖 13.6
為 Smile 表的部分內容。
上一節中,利用 16 期埃奇沃思定價法,在峰度偏大,波動率為 20%的情況下得到看漲
期權定價為 9.37。定價結果存於表 Smile 的單格 J10 中,取名 EDGE(S,X, σ )用以標識定
價方法和參數。如圖 13.6 中的單格 J13 所示,在波動率為 18.45%的情況下,布萊克-舒爾
斯公式得到事實上價結果也是 9.37。此隱含波動率(即 18.45%,標識為 EDGE ISD)是在
將期權價格設定為埃奇沃思定價結果值的條件下,由函數 BSOptionISDGoalSeekNR 計算
得到的(單格 J12) 。
因此,兩種不同的假設條件得到了相同的定價結果:服從嚴格正態分佈股價波動率為
18.45%,或對數收益的峰度偏大時,相應的股價波動率為 20.00%。因此,期權觀測值的差
異不僅僅反映了未來波動率估計的差異程度,更多反映了對數股價收益偏離嚴格正態分佈的
程度。

Estimating Implied Volatility( or ISD) in Edgeworth Option Values:


在埃奇沃思期權定價過程中估計隱含波動率(或隱含標準差)

【參照書中第 216 頁的圖 13.6】


圖 13.6 表 Smile 中對數正態和非對數正態條件下的看漲期權價值

對於一定範圍執行價(見圖 13.7,列 E) ,重複計算埃奇沃思期權價值和隱含波動率,


就可以得到在給定偏度和峰度條件下的波動率曲線。選擇平值執行價,即選擇以 X 的折現
值(單格 B22 中的 92.65)為中心。選擇範圍為期權平值執行價左右 2.5 倍標準差的區間。

Illustrating the Volatility Smile:演示波動率曲線

【參照書中第 216 頁的圖 13.7】

圖 13.7 BS 和埃奇沃思假設條件下的波動率比較

利用埃奇沃思分佈計算不同執行價格下的看漲期權價值(列 G) ,相應的隱含波動率通
過函數 BSOptionISDGoalSeekNR 求得(列 J)
。圖 13.8 即為隱含波動率與執行價格的函數
圖,即波動率曲線。

Implied volatility smiles:隱含波動率曲線


Implied volatility:隱含波動率
Exercise price:執行價格

【參照書中第 217 頁的圖 13.8】

圖 13.8 表 Smile 中的波動率曲線

如圖 13.6 所示,通過選擇適當的偏度和峰度參數值,利用埃奇沃思期權定價法,就能
畫出如圖 13.8 所示的波動率曲線圖。選擇不同的參數值,利用埃奇沃思期權定價法可以畫
出不同形狀的波動率曲線圖。

13.5 Module1 中的用戶定義函數

這裏有兩個函數,強調了布萊克-舒爾斯公式中假設股票收益服從對數正態分佈的重要
性 。 第 一 個 函 數 名 為 LNOptionValue0 , 使 用 正 態 分 佈 的 矩 。 第 二 個 函 數 名 為
LNOptionValue,使用對數正態分佈的矩。

Function LNOptionValue 0(iopt,M,V,X,r,tyr)


’ returns lognormal option value(iopt=1 for call,-1 for put)
Dim d1,d2,Nd1,Nd2
d2=(M-Log(X))/Sqr(V)
d1=d2+Sqr(V)
Nd1=Application.NormalSDist(iopt*d1)
Nd2=Application.NormalSDist(iopt*d2)
LNOptionValue0=Exp(-r*tyr)*iopt*(Exp(M+0.5*V)*Nd1-X*Nd2)
End function

Function LNOptionValue(iopt,M1,M2,r,tyr)
’ returns lognormal option value(iopt=1 for call,-1 for put)
’ uses LNOptionValue0 fn
Dim M,V
M=2*Log(M1)-0.5*Log(M2)
V=Log(M2)-2*Log(M1)
LNOptionValue=LNOptionValue0(iopt,M,V,X,tyr)
End Function

RGOptionValue 函數在結構上與上述函數相同,最大的差別就是用逆 gamma 分佈函數


代替了對數正態分佈(程式中使用到 Excel 的 GAMMDIST 函數,輸入參數 TRUE 時返回
累積概率值)

Function RGOptionValue 0(iopt,M1,M2,X,r,tyr)


’ returns reciprocal gamma option value(iopt=1 for call,-1 for put)
Dim alpha,beta,g1,g2
alpha=(2*M2-M1^2)/(M2-M1^2)
beta=(M2-M1^2)/(M1*m2)
g1=Application.GammaDist(1/X,alpha-1,beta,True)
g2= Application.GammaDist(1/X,alpha,beta,True)
if iopt=-1 then g2=1-g2
RGOptionValue=Exp(-r*tyr)*iopt*(M1*g1-X*g2)
End Function

BSOptionISDGoalSeekNR 函數使用柯拉多和米勒估計值作為初始點進行牛頓-拉夫森
迭代(下面程式中用 sigmanow 表示)。當柯拉多和米勒方法失效(sigmanow=-1)時,使
用馬納斯特和凱勒給出的種子值進行計算:

atol=0.0001
sigmanow=BSOptionSDEstimate(iopt,S,X,r,q,tyr,optprice)
’ when above fails,start from Manaster & Koehler seed value
if sigmanow<=0 Then sigmanow=Sqr(2*Abs(Log(S/X)+(r-q)*tyr)/tyr)
Do
fval=BSOptionValue(iopt,S,X,r,q,tyr,sigmanow)-optprice
fdashval= BSOptionValue(iopt,S,X,r,q,tyr,sigmanow)
sigmanow=sigmanow-(fval/fdashval)
Loop While Abs(fval)>atoll
BSOptionISDGoalSeekNR=sigmanow
函數 EdgeworthEuroOptionValue 相對於表 Edge 來說是一個比較綜合的函數,附加了
對概率密度函數的非負(由 PDFnonneg 標識)和單眾數(由 PDFmodes 標識)檢驗。不
滿足時,用格拉姆-查利展開替代埃奇沃思展開。如果檢驗仍不能通過,就返回值-1。

For j=1 To n
xvec(j)=(2*(j-1)-nstep)/Sqr(nstep)
bvec(j)=Application.combin(nstep,j-1)*((0.5)^nstep)
Next j
’ Edgeworth expansion used for pdf
For j=1 To n
xj=xvec(j)
c=1+skewco*(xj^3-3*xj)/6+(kurtco-3)*(xj^4-6*xj^2+3)/24
c=c+skewco^2*(xj^6-15*xj^4+45*xj^2-15)/72
fvec(j)=c*bvec(j)
Next j
it1=PDFnonneg(fvec)
it2=PDFmodes(fvec)
if it1<0 Or it2>1.5 Then
’ use Gram-Charlier expansion for pdf instead
For j=1 To n
xj=xvec(j)
c=1+skewco*(xj^3-3*xj)/6+(kurtco-3)*(xj^4-6*xj^2+3)/24
fvec(j)=c*bvec(j)
Next j
it1=PDFnonneg(fvec)
it2=PDFmodes(fvec)
End if
if it1=<0 Or it2>1.5 Or kurtco<3 Then
’ method fails as pdf has non-negative entries or is not unimodal
ve=-1
Else
’ minor adjustments to fvec and xvec
frvec=PDFrescale(fvec)
xsvec=Xvecstd(xvec,frvec)

另外,還要調整密度函數,並將期權收益期望的折現值作為計算出的二叉樹期權價值。
魯賓斯坦指出二叉樹期數應在 100 以上才能滿足期權定價需要。

’ now start option value


sum=0
For j=1 To n
sum=sum +frvec(j)*Exp(xsvec(j)*sigma*Sqr(tyr))
Next j
’ now calculate mmu,risk-neutral expectation of ln(Sj/s)
mmu=r-q-(Log(sum))/tyr
ve=0
’ option valu depengs on share price (Sj) and risk neutral pdf(frvec)
For j=1 To n
Sj=s*Exp(mmu*tyr+xsvec(j)*sigma*Sqr(tyr))
ve=ve+frvec(j)*Application.Max(iopt*(Sj-X),0)
Next j
ve=Exp(-r*tyr)*ve
End if
EdgeworthEuroOptionValue=ve

小結

在布萊克-舒爾斯期權定價公式中,只有波動率是不能直接測量的。然而,我們可以計
算隱含波動率,即,利用該公式得出期權市場觀測價格時的隱含波動率。可以使用 Excel
提供的單變數求解工具,但更好的方法是直接利用這裏給出的用戶定義函數。

布萊克-舒爾斯公式假設股票價格 S T 服從對數正態分佈,事實上,實證研究表明,該分

佈存在厚尾和不對稱性(即,存在過大的峰度和偏度)現象。魯賓斯坦給出一種方法,即調
整二叉樹法,使之產生具有給定偏度和峰度的分佈。用此方法,可以產生不同的關於股價樹
的離散概率分佈(埃奇沃思分佈),且前 4 階矩相匹配。
雖然正態分佈是期權定價的基礎,但期權交易中仍存在偏離正態的情況。因此,有必要

繪製波動率曲線圖。當股票價格 S T 不服從對數正態分佈時,隱含波動率將偏離由布萊克-

舒爾斯公式給出的值。將波動率作為期權執行價格函數進行作圖,得到的就是波動率曲線圖。

參考文獻
Corrado, C. J. and T. W. Miller, 1996, “A Note on a Simple, Accurate Formula to Compute
Implied Standard Deviations”, Journal of Banking and Finance, 20, 595-603.
Manaster, S. and G. Koehler, 1982, “The Calculation of Implied Variances from the
Black-Scholes Model”, journal of Finance, 37(1), 227-230.
Milevsky, M. A. and S. E. Posner, 1998, “Asian Options: The Sum of Lognormals and the
Reciprocal Gamma Distribution”, Journal of Financial and Quantitative Analysis, 33(3),
409-422.
Rubinsten, M., 1998, “Edgeworth Binomial Trees”, Journal of Derivatives, 5(3), 20-27,
(also see correcton: 5(4), 6).
第 14 章 債券期權定價介紹

由於要處理利率期限結構問題,債券期權定價要比股票衍生證券定價複雜。利率期限結
構描述了利率與債券到期期限之間的關係。利率期限結構是根據市場上不同到期期限債券的
價格估計出來的。這個估計過程比較複雜,因為大部分債券含有一系列的利息支付(一般是
每年兩次)並在到期時支付本金。但是也有一部分債券在發行期間不支付票息,這就是我們
熟知的零息票債券。
在為債券期權定價時,有三種處理利率期限結構的方法:(i)忽略期限結構;(ii)對期限
結構進行建模;(iii)擬合期限結構。債券期權定價從嘗試採用布萊克-舒爾斯公式(第一種方
法)發展到連續利率模型(第二種方法) ,現在更受關注的是擬合期限結構的離散利率模型
(第三種方法) 。
本章內容分為三部分,首先討論利率期限結構以及如何選擇適當的貼現因數為附息債
券現金流定價,然後介紹如何利用一個簡單的利率二叉樹來模擬零息票債券的價格,最後介
紹布萊克債券期權定價公式,此公式忽略利率期限結構,並假設債券未來的價格服從對數正
態分佈。
第 15 章介紹利率模型,主要是 Vasicek 與考克斯,英格索爾和羅斯(CIR)的暫態利
率模型。這些隨機模型產生一組利率,根據這些利率就可以為不同到期期限的零息票債券定
價。這些模型的優點是它們給出了零息票債券期權價值的解析解,由此可以為附息債券期權
定價。
最簡單的形式 Vasicek 模型和 CIR 模型就是一個可能的期限結構,但是這個期限結構
往往跟市場中能觀察的期限結構不一致。第 16 章有關擬合期限結構方面的內容展示了如何
利用二叉樹對利率分佈進行建模,從而正確地給零息票債券定價(也搭建了波動率的期限結
構)。構建了兩個簡單的二叉樹,其中一個假設利率服從對數正態分佈,而另外一個假設服
從正態分佈。構建一個簡單的布萊克,德曼和托伊(BDT)樹。BDT 樹是在簡單的對數正
態樹的基礎上發展而來,並廣受從業者的歡迎,因此可以用它來說明零息票債券期權的定價。
儘管為債券期權定價是一個複雜的過程,但剛開始應該熟悉期權定價。定價的過程中
有兩個重要的部分:根據期權在執行時的收入計算風險中性期望值以及使用數值方法(例如
二叉樹)。
為了使說明更簡單,這裏將期限結構模型局限于單因數模型,並只採用市場上可觀測
的零息票債券收益率和波動率。除了在 BDT 樹的例子中引入離散的利息支付以外,一般假
設利息支付是連續的。
這些模型可以在 Excel 檔 BOND1 和 BOND2 中實現。所用到的 Excel 技巧大部分都是
我們熟悉的,同時還會在附息債券期權定價和構造利率樹的過程中使用單變數求解。由於大
部分公式都比較複雜,因此使用用戶定義函數來實現會更簡單有效,讀者可以在工作簿的
Module 表中找到這些用戶定義函數。
相關內容可參見 Bodie 等人(1996),關於第 13,14 章可以閱讀《債券價格和收益》
以及《利率期限結構》等書籍,還可以參考赫爾(2000)的文章以及《利率衍生品》第 21
章。另外一篇期權的參考文章是克盧洛和斯特裏克蘭(1998)。書中還有部分較新的內容,
包括利用 CIR 模型為債券期權定價(涉及到非中心卡方分佈) 。
14.1 利率期限結構

圖 14.1 列出了到期期限從一年到十年的零息票債券價格,讀者可以在 BOND 檔中的 Intro


工作表找到這些價格資訊。

Term Structure of Interest Rates:利率期限結構

【書中 224 頁的圖】

圖 14.1 零息票債券價格,相應的到期收益率和遠期利率

零息票債券價格可以轉換為相應的零息票債券的連續複利收益率,它們之間有以下的
關係:

p=(1) exp ( − rt )
其中 p 是零息票債券價格, t 是債券的到期期限,債券的面值為 1, r 則是相應的零息收益
率。(這裏用零息收益率代表零息票債券價格暗含的各個期限的利率水準,從 0 時刻到 t 時
刻。)單格公式在 F5 單格中。一系列不同到期期限的收益率組成了所謂的利率期限結構。
例如,一年期的零息收益率為 6.08%,而 10 年期的零息收益率為 6.89%。與一年期的零息
收益率不同,其他的零息收益率跨越了多個時期。
期限結構中的資訊也可以用一系列的遠期利率來表示,如 H 列所示。H6 單格中 6.14 %
的遠期利率表示暗含的第二年的借債利率(一年期) ,它是根據一年期和兩年起的零息票債
券價格算出來的。零息收益率和遠期利率的關係展示在圖 14.2 中(見工作簿的圖表 1) 。這
樣,利率期限結構中的資訊可以通過三種途徑來顯示:利用零息票債券價格,零息收益率和
遠期利率。

Term Structure of Interest Rates:利率期限結構

Maturity:到期日

【書中 225 頁的圖】

圖 14.2 零息票債券價格暗含的零息收益率和遠期利率(圖 1)
14.2 附息債券的現金流和到期收益率

大部分交易的債券都有規範的利息支付和到期的本金支付。例如,圖 14.3 列出了面值


為 1,10 年後到期,票面利率為 5%的債券的現金流(在 Intro 工作表的 H25:H34 單格中)。

Valuing Coupon Bonds:附息債券定價

【書中 225 頁的圖】

圖 14.3 根據零息票債券價格給附息債券定價並計算到期收益率
利用零息票債券價格(D 列)可計算現金流的現值,而債券的現值是這些單個現金流現
值的簡單加總(在 F 列) 。總和是 0.857(在 F20 單格)
,這一數值應該等於債券的市場價
格。
根據市場價格(H24 中的初始現金支出)和一系列的現金流入(如 H 列所示) ,可以直
接計算附息債券的到期收益率。到期收益率的定義是所有債券現金流(包括初始現金流出)
的內部收益率。它可以用 Excel 中的 IRR 函數直接計算。實際上,IRR 函數返回離散情況
下的債券利率收益率。這個收益率可以轉換為連續複利收益率,如單格 H20 中所列的公式:

= LN(1+IRR(H24:H34))
在 J 列,債券的現金流都是用到期收益率進行折現的,如單格 J20 所示,總和仍然是
0.857。
計算到期收益率並不複雜。但問題是,它是否適合於為債券的現金流定價。當使用到
期收益率的時候,假設不同時刻收到的現金支付都可以用同一個利率進行折現。而且,對於
市場上不同的附息債券,會估計出不同的到期收益率(儘管它們的到期期限一樣)。因此,
最好使用隨期限改變而改變的利率,而這就是所謂的利率期限結構。

14.3 二叉樹

由於債券定價非常依賴於不確定的利率,因此就需要能夠描述利率未來狀況的模型。
和在股票期權定價過程中使用二叉樹描述股票價格的隨機性質一樣,可以構造二叉樹模型來
描述利率的不確定性。債券期權可以通過利率樹來定價。該方法可由圖 14.4 說明。利率樹
中的短期利率(B46:E49 單格)反映了零息收益率在未來四年的情況。第一個時期的利率
為 6.08%(即一年期債券的零息收益率) ,在第二個時期,利率被假設為 7.17%或者 5.11%,
出現這兩種情況的概率相等。如此類推。目標是使得四年期零息票債券的理論價格(A52
單格)與四年期零息票債券的市場價格(D8 單格)對應起來。
在這個簡化的例子當中,二叉樹中的短期利率被假設是已知的,在同一時點以相同的
概率向上或者向下變動(B39 和 B40 單格) 。與股票期權定價的過程相似,這些利率也可以
為現金流定價。 (第 16 章將討論這些利率如何包含了零息收益率波動的假設。這裏假設這
部分分析過程已經完成。)
在第四年年末,四年期零息票債券現金流的價值等於它的面值,無論到時的短期利率
是多少。最終的現金流(在單格 E52 到 E56 中,對應著每一個路徑)在二叉樹相應路徑的
利率下,被折現回原點。
例如,折現到前一個時期,計算公式在單格 D52 中:這裏利用了一個依賴於相應單格
所示利率的折現率(E46)而不像在股票期權定價中使用固定的折現率。複製這個公式,順
著二叉樹往前倒推,就得到四年期零息票債券的價格 0.777。

Valuing Zero-Coupon Bonds using Binomial Trees:

利用二叉樹為零息票債券定價

【書中 227 頁的圖】


圖 14.4 利用短期利率的二叉樹為零息票債券定價(參見 Intro 工作表)

這個例子的關鍵點在於:可以構建一個能與期限結構(這裏表現為零息收益率)對應
的利率二叉樹。

14.4 布萊克的債券期權定價公式

第一個對零息票債券期權進行定價的方法是由布萊克(1976)提出的。在期貨期權定
價的章節中(11.3 節)已經提到過這個公式。布萊克假設在期權到期時,這期債券價格服
從對數正態分佈。這使得修正的布萊克-舒爾斯公式可以應用。
在圖 14.5 中,布萊克公式用於為一個四年期的期權(T=4)定價,期權的標的物是面
值為 1,剩餘到期期限為 10 年(s=10)的零息票債券。在單格 B64 中,債券未來的理論價
格是用面值乘上 10 年期與 4 年期零息票債券價格的比值得到的,單格中的公式是:
=B61*(B63/B62)。

期權的執行價格為 0.6,短期利率假設為 6%,其波動率假設為 3%。 d1 和 d 2 的公式與

期貨期權中的公式是一致的,這樣可以計算得到看漲期權的價值為 0.038。
這裏所說明的布萊克公式只是債券期權定價的一種最簡單的方法,並且它只適用於執
行期限相對於債券到期期限比較短的情況。接下的兩章中,將會介紹更多債券期權定價的複
雜方法。

Valuing European Options on Zero-Coupon Bonds:


零息票債券的歐式期權定價

【書中 228 頁的第一個圖】


圖 14.5 Intro 工作表中的布萊克零息票債券期權定價方法

14.5 久期和凸性

零息票債券把債券價值和到期收益率聯繫起來,因為對於這種特殊的情況,債券的到
期期限與債券現金流的重心恰好對應。久期,即現金流(利息支付和本金支付)現值的加權
平均,代表了債券現金流的重心位置(以年來表示)。對於附息債券來說,債券價值和到期
收益率之間再沒有直接的聯繫。但是,可以通過久期(這裏作斜率或者價值與收益率的一階
導數)和凸性(看作曲率或者價值和收益率的二階導數)去衡量由於債券收益率變化一個單
位所引起的債券價值發生的變化程度。

Calculating Duration of Coupon Bonds:計算附息債券的久期

【書中 228 頁第二個圖】

圖 14.6 計算久期

但是有一點要提醒讀者的是,這種分析假設利率期限結構是平行移動的,但實際的情
況往往不是這樣的,這也是這種估計方法的重要缺陷。儘管存在這樣的問題,但是久期和凸
性仍然被從業人員廣泛使用,這也是本章介紹它們的原因。例如,債券的到期期限為 10 年,
票面利率為 5%,現在的到期收益率為 7.04%(離散利息支付) ,其計算列在表 14.6 中。麥
考利(Macaulay)久期的計算是單個現金流現值(在 I91 單格中)的總和除以債券的現值
(H91 單格中)。也可以通過 VBA 用戶定義函數中 Chua 的債券久期公式 Chua Bond
Duration (Chua,1984)進行計算。而從業人員一般使用修正久期,即麥考利久期除以 1 與
到期收益率的和。當參數 imod 取 1 時 Chua Bond Duration 函數返回修正久期的值(見 B95
單格) 。
下面,我們利用修正久期(B95 單格)和凸性(B97 單格)說明如何估算當到期收益
率發生一定變化時債券價值所發生的變化,見表 14.7。債券凸性的計算比久期要複雜,但
是可以通過用戶定義函數 Black Orszag Convexity(布萊克和 Orszag,1996)進行計算。
B101 單格中的公式假設債券價值變化的百分比等於到期收益率的變化乘上修正久期的負數
後,再加上到期收益率變化的平方與凸性一半的乘積。如果到期收益率增加 0.01(B99 單
格),債券價格會下降 7.06%,到 0.7962(單格 H110,即到期收益率變化為 8.04%後債券
現金流的現值之和) 。這樣,當假設收益率曲線發生平行移動的情況下,久期和凸性能夠很
好的估計債券價值發生的變化。

Using Duration and Convexiry to Estimate Impact of Change in YTM:


利用久期和凸性來估計到期收益率變化的影響

【書中 229 頁的圖】


圖 14.7 估計收益率變化對債券價值的影響

14.6 符號

到目前為止,在 Intro 工作表中介紹的簡單模型並不需要新的符號。但是,在第 15 章


和 BOND1 檔的其他工作表中需要引入簡化的符號。特別是涉及到債券到期期限和債券期權
執行期限的時間結構時,更需要引入符號。
一般地,假設現在是 0 時刻,即 t=0,而期權執行的時刻為 t=T,債券到期時刻為 t=s。

P ( 0, s ) 代表 s 時刻到期的零息票債券在 0 時刻的價格(在 s 時刻支付 1 元),也可以

稱作零息票債券價格。注意, P ( 0, s ) 也可以看作一個折現因數,這個折現因數等於

exp(− rs ) ,假設利息是連續支付並且利率 r 不變。

R (0, s ) 表示從 0 時刻到 s 時刻的零息票債券收益率。沒有特別說明的情況下,這個利


率一般為連續複利年利率。

小結

本章中,用‘收益率’這個詞描述了一個時間段的年利率。還通過例子說明如何根據
零息票債券的市場價格來計算其收益率。這些收益率又稱為‘零息收益率’,為利率期限結
構估計值。
通常,債券是有中間利息支付的,而它們現在的市場價格反映了預期現金流(包括每
期的利息支付和最後的本金)的價值。過去,現金流的到期收益率(內部收益率)被看作是
一種定價的手段。但是在現在看來,現金流的折現率應該使用零息收益率而不是帶有武斷性
質的到期收益率。
最早的債券期權定價方法是布萊克提出的,這個方法中使用的公式中含有債券未來的
價格,是在原來布萊克-舒爾斯公式的基礎上擴展而來的。然而,這種方法暗含的假設是不
傾向於持有債券,特別是在某些限制的情況下。
為了給第 16 章做準備,我們展示了利率二叉樹如何對應一個給定的期限結構。假設這
樣的利率樹可以建立,那麼它們就是我們所熟悉的數值方法,從而可以為債券期權定價。

參考文獻
Black, F., 1976, “The Pricing of Commodity Contracts”, Journal of Financial Economics, 3,
167-179.
Blake, D. and J. M. Orszag, 1996, “A Closed-Form Formula for Calculating Bond
Convexity”, Journal of Fixed Income, June, 88-91.
Bodie, Z., A. Kane and A. Marcus, 1996, Investments, 3rd edition, Richard D. Irwin,
Englewood Cliffs, Nj. Chua, J. H., 1984, “A Closed-Form formula for Calculating Bond
Duration”, Financial Analysts Journal, May/June, 76-78.
Clewlow, L. and C. Strickland, 1998, Implementing Derivatives Models, John Wiley &
Sons, Chichester.
Hull, J. C., 2000, Options, Futures and Other Derivatives, Prentice Hall, New Jersey.
第 15 章 利率模型

本章主要內容是通過利率模型給零息票債券定價。此方法假定,短期利率的變化可以
通過隨機模型來描述,此隨機模型產生一個零息票債券價格的期限結構。通過利率模型,可
以得到一個零息票債券價格的解析解。Jamshidian(1989)給出了零息票債券價格如何被
用於為零息票債券期權定價,從而進一步為附息債券期權定價。
本章將重點放在兩個主流模型上,分別是 Vasicek(1977)模型與考克斯,英格索爾和
羅斯(CIR;1985)模型。這兩個模型都假設(暫態)短期利率 r 的風險中性過程是隨機的,
並只有一個不確定性來源(單因數)。隨機過程包括漂移和波動率兩個參數,它們只與短期
利率 r 有關,與時間無關。短期利率模型包括好幾個參數,不同參數組合能產生不同的利率
期限結構形狀。
兩個利率模型都有所謂的均值回復性質,即短期利率有回復到潛在利率水準的趨勢。
這個性質是根據市場利率變動形式歸納出來的。兩個模型的不同之處在於對波動率的方法
上。先從 Vasicek 模型開始,然後考慮 CIR 模型。BOND1 檔中的試算表(Vasicek 和 CIR
工作表)有相同的格式,使用同一數值例子。

15.1 Vasicek 利率期限結構模型

Vasicek 模型中,短期利率 r 的變動為以下形式的隨機過程:

dr = a (b − r )dt + σ r dz
這樣,在時間增量 dt 過程中,短期利率的微小變動 dr 以 a 的速率回復到均值水準 b 。
第二項波動項包含了不確定性, dz 代表了一個正態分佈,期均值為 0,方差是 dt 。短期利

率 r (嚴格來說是 r ( t ) )被假設為 t 時刻的連續複利暫態利率。

在給股票期權定價時,基本的方法就是獲得風險中性世界中期權未來收益的期望折現
值。同樣的,股票現在的價格可以對等的看作風險中性世界中它未來價值的期望折現值。將
同樣的原則應用到債券和債券期權未來的收益上。在一個零息票債券期權的例子中,在 s
時刻等於 1 元的價值,其在 t 時刻的對應值可以表示為:

( )
P ( t , s ) = E Q exp − ∫ r ( u )du 1
 
Q
這裏積分的時間間隔是從下限 t 到上限 s,符號 E 表示風險中性期望。

對於股票期權來說,利率被假設為固定的,因此短期利率積分一項可以拿到期望括弧

的外邊。這樣,上式就變為一個折現因數 exp  −r ( s − t )  。因此,對於股票期權來說,定

價決定于計算未來收益的風險中性期望值,而 exp  −r ( s − t )  可以作為一個固定的折現因

數。
對於零息票債券期權來說,模型描述的短期利率公式必須包含在 P ( t , s ) 的期望運算式

中。由於短期利率的不確定性,因此它不能被提到期望括弧的外邊。
在 Vasicek 模型假定下,可以解出積分的解析解,從而給出零息票債券的價格,即:

P ( t , s ) = A ( t , s ) exp  − B ( t , s ) r ( t ) 

這裏 r ( t ) 是短期利率在 t 時刻的值

{ }
B ( t , s ) = 1 − exp  − a ( s − t )  / a

({ ( )}
A ( t , s ) = exp ( B ( t , s ) − ( s − t ) )  a 2b − σ r / 2 / a 2 − σ r B ( t , s ) / 4a
2 2 2
)
在 a = 0 的特殊情況中,A 和 B 的運算式可以簡化為:

B ( t , s ) = ( s − t ) 和 A(t , s ) = exp σ r2 ( s − t ) / 6 
3
 
這些數值在試算表中都很容易計算。表 15.1 為從 BOND1 文件的 Vasicek 工作表中摘
錄了部分內容。

Vasicek Model:Vasicek 模型

【書中 232 頁的圖】

圖 15.1 零息票債券價格,零息收益率和 Vasicek 模型中的波動率

Vasicek 模型中要求短期利率 r 的三個參數( a ,b 和 σ r )必須根據歷史資料估算出來。

在上面例子中,所使用的參數 a , b 和 σ r 是由 Chan 等人在 1992 年根據 1964 年到 1989

年的美國一月期國庫券收益率資料估算出來的。
在圖 15.1 的例子中,短期利率的初始值為 6%,而潛在的利率回復水準為 0.0866
(8.66%)
,列在 B6 單格中。模型可以給出相應的零息票債券的價格,從現在到 10 年末的

任意一個時刻。單格 B13 和 B14 分別是 B ( 0, s ) 和 A ( 0, s ) 的公式,根據這兩個公式,到期

期限為 s 的零息票債券的幾個 P ( 0, s ) 就可以計算出來(列在 E6 單格中)。這說明通過

Vasicek 模型的計算,在 s 時刻(現在 s=10 年)收到的每單位價值的現值為 0.4867。根據


零息票債券的價格,可以計算出零息收益率,這裏是 7.20%。

一個無限期債券的到期收益率,這裏用 R ( ∞ ) 表示(E14 單格)


,為 8.02%。這個數值

比所選的參數 b (短期利率均值回復水準)更小。這個短期利率波動率的公式列在單格 E17


中,表明 10 年期零息收益率的波動率為 0.93%,而我們選擇的波動率參數為 2%。
可以建立一個模擬運算表
模擬運算表,計算不同的
模擬運算表 s 值(從 0 到 30)所對應的零息收益率和它的
波動率。表中所列出的零息收益率代表利率期限結構,對應圖 15.2 中最下方的曲線(也可
參見工作簿的圖 2)

Vasicek-Possible Shapes for Term Structure: Vasicek-利率期限的可能結構


Bond Maturity:債券到期日

【書中 233 頁的圖】

圖 15.2 不同的 r 值所對應的利率期限結構

如圖 15.2 所示,零息收益率的期限結構可以出現三種可能的形狀,主要依賴於 B7 單

格中短期利率的現值。可能出現的形狀包括單調上升(當 r 比 R ( ∞ ) 小時),駝峰和單調下

降(當 r 比 b 大時)
。可以通過改變工作簿中 r 的值來檢驗以上的關係。例如,當調整 B7 的
值為 9%時,這個圖形會顯示單調下降的期限結構,而將 B7 改為 8.05%時,會產生一個駝
峰狀的期限結構。
Vasicek 利率模型的一個缺陷是有時候它會產生負的利率。見圖 15.3 中顯示的例子,
此圖是 B5 單格 a = 0.3 情況下 Vasicek 模型類比的情況。這個問題在 CIR 模型中不會出現。
但是,在轉入 CIR 模型之前,先來看看如何利用 Vasicek 模型為零息票債券期權定價。

Short rate:短期利率

【書中 234 頁的圖】

圖 15.3 Vasicek 模型類比的短期利率

15.2 Vasicek 模型對零息票債券歐式期權定價

Vasicek 工作表中的零息票債券期權定價公式由 Jamshidian(1989)給出的。Jamshidian


公式可以看作 13.1 節中提到的對數正態期權定價公式的應用。 (唯一所不同的是對數正態期

權公式中的折現因數 exp( − rT ) 換成了零息票債券價格 P ( 0, T ) 。)Jamshidian 的貢獻在於

給出了 M 和 V 的具體公式,這兩個公式在債券期權定價中與債券未來的價格有密切的聯繫。
一個歐式看漲期權,其執行價格為 X,執行日期為 T,標的物為 s 年到期本金為 L 的零
息票債券。在 0 時刻,這個期權的價格可以用以下公式來表示:

c = P ( 0, T ) exp ( M + 0.5V ) N ( d1 ) − XN ( d 2 ) 

其中: M = ln  LP ( 0, s ) / P ( 0, T )  − 0.5σ P2
V = σ P2

d 2 =  M − ln ( X )  / V

d1 = d 2 + V

σ P = v ( 0, T ) B (T , s )

v ( 0, T ) = σ r {1 − exp ( −2aT ) / 2a}


{ }
B (T , s ) = 1 − exp  − a ( s − T )  / a

注意當 a = 0 是時,波動率部分的 v ( 0, T ) 簡化為 σ r T 而 B (T , s ) 簡化為 s − T 。

圖 15.4 展示了期權價值的計算過程。兩個零息票債券價格 P ( 0, T ) 和 P ( 0, s ) 分別在

E27 和 E28 中計算,這裏是通過用戶定義函數 VasicekCIRZero Value 計算的(也可以通

。而計算波動率 σ P ,M 和 V 需要一些中間的計算
過在 E6 單格改變相應的到期期限來計算)

過程。經計算,執行期限為 4 年,標的物為 10 年期零息票債券的看漲期權價格為 0.037,


列在 H26 單格中。同樣通過一個用戶定義函數也可以計算出上述結果。

Valuing European Options on Zero-Coupon Bonds: 零息票債券的歐式期權定價

【書中 235 頁的圖】

圖 15.4 Jamshidian 的零息票債券期權定價方法


將短期利率波動性(B11 單格)從 2%增加到 4%時,期權的價值提升到 0.076。

15.3 Vasicek 模型對附息債券歐式期權定價

Jamshidian 也推導出一個更一般的模型為附息債券期權定價。重要的思路就是根據期
權執行期之後的附息債券現金流,將附息債券期權分拆為多個零息票債券期權。對於一個執
行期限為四年,標的物為 10 年期附息債券的期權來說,需要考慮第 5 年到第 10 年的利息
支付以及最後到期的本金支付。在圖 15.5 中,相關的現金流列在 E51 到 E56 的單格中,總

。現在需要找到一個折現利率(比如 r * )
量是 1.30(面值加上執行期之後的六次利息支付)

使得這些現金流的現值之和與期權的執行價格(0.6,見 E43)對應起來。計算 r * 的過程比

較麻煩需要採用試錯法,這裏利用一個名為 Jamshidianrstar 的用戶定義函數完成。


Valuing European Options on Coupon-Bearing Bonds:
附息債券的歐式期權定價

【書中 236 頁的圖】

圖 15.5 用 Jamshidian 方法對附息債券期權定價

*
讀者可以確認一下所計算出來的 r (18.30%,見 E46 單格)確實使得債券支付的現值

總和(E47 單格)等於期權的執行價格(見 E43)。而附息債券期權的價值只是單個零息票


債券期權價值的簡單加總,而單個的零息票債券期權的債券面值、執行價格和到期期限為別

為 Lj , Xj 和 sj ,其價值使用 VasicekZero Option 函數計算。注意,計算這些單個期權價

*
值時使用的是原來的短期利率(這裏是 6%),而不是 r 。

15.4 CIR 利率期限結構模型

Vasicek 模型與 CIR 模型的主要不同之處就是短期利率波動性的表達形式不一樣。在


CIR 模型中,波動率還取決於短期利率的開方,這樣模型保證了短期利率不會出現負數。
在 CIR 模型中,短期利率的風險中性過程是隨機過程,其形式如下:

dr = a ( b − r ) dt + σ rdz

這裏的短期利率的波動率 σ r = σ r  隨著短期利率開方的增加而增加。這個模型防止
 

了負利率的出現(只要參數值滿足關係式 2ab ≥ σ )。
2

圖 15.6 展示了利用 CIR 模型對零息票債券的定價,見 CIR 工作表。可以看到此表的佈


局跟前面 Vasicek 工作表是相似的。

【書中 237 頁的圖】

圖 15.6 CIR 模型下的零息票債券價格,零息收益率和波動率

考克斯,英格索爾和羅斯證明了債券價格跟 Vasicek 模型一樣存在一般形式。在 s 時刻


支付 1 單位的零息票債券價格公式如下:

P ( t , s ) = A ( t , s ) exp  − B ( t , s ) r ( t ) 
這裏 r ( t ) 是 r 在 t 時刻的值。函數 B ( 0, s ) 和 A ( 0, s ) 的形式稍微有些不同,包含了一個新

參數 γ 。根據 CIR 利率模型,10 年期零息票債券的價值為 0.4926,10 年期零息收益率為


7.08%。同樣的,可以通過改變在試算表中 s 的值來獲得利率期限結構,如工作簿中的圖 3。
並且會得到與 Vasicek 模型一致的幾種利率期限結構形狀。

15.5 CIR 模型對零息票債券歐式期權定價

為了計算 CIR 模型下零息票債券期權的價值,需要利用非中心卡方分佈函數(取代布


萊克-舒爾斯公式和 Vasicek 公式中的正態分佈)
。由於 CIR 公式非常複雜,因此在本書中不
作具體描述,這裏的主要任務是確保試算表中的公式和相應的函數返回正確的數值。在 CIR
模型原文基礎上的進一步研究很多,包括施羅德(1989)的論文,這篇論文給出了原文中
分佈函數的近似形式。圖 15.7 展示了零息票債券期權定價的過程,執行期限為 4 年,標的
物為 10 年期零息票債券的看漲期權的價格為 0.040(H26 單格中)。通過用戶定義函數可以
得到相同的結果(H27 單格中) 。

Valuing European Options on Zero-Coupon Bonds:


零息票債券的歐式期權定價

【書中 238 頁圖一】

圖 15.7 利用 CIR 模型為零息票債券期權定價

15.6 CIR 模型附息債券歐式期權定價

利用 CIR 模型和 Jamshidian 創立的方法(在 Vasicek 模型中出現過)對附息債券期權


定價。同樣的,根據期權執行期之後的附息債券現金流,可以將附息債券期權分拆為多個零

息票債券期權。Jamshidian 的貢獻是找到了一個利率 r * ,使得單個期權執行價格的總和與

附息債券期權執行價格一致。
圖 15.8 展示了定價過程。單格 E47 中的利率是 20.31%,是根據 Jamshidianrstar 函數
計算的。附息債券期權的價值是單個零息票債券期權價值的總和,最後得到的數值是 0.212
(單格 H44 中)。(在 Vasicek 模型中,期權的價值稍微低一點,為 0.206,見圖 15.5。)

Valuing European Options on Coupon-Bearing Bonds:


附息債券的歐式期權定價
【書中 238 頁圖二】

圖 15.8 利用 Jamshidian 方法對附息債券期權定價

15.7 Module 1 中的用戶定義函數

由於 Vasicek 模型和 CIR 模型有相同的元素,因此合理的做法是寫一個函數同時允許


Vasicek(imod=1)和 CIR(imod=2)使用。和試算表一樣,函數也允許在 a=0 的情況下
使用:

Function VasicekCIRZero Value(imod,a,b,r,nowyr,zeroyr,sigma)


‘ returns the Vasicek(imod=1) or CIR(imod=2) zero-coupon bond value
Dim syr,sig2,Asyr,Bsyr,rinf,gamma,c1,c2
syr=zeroyr-nowyr
sig2=sigma^2
If imod=1 Then
If a=0 Then
Bsyr=syr
Asyr=Exp((sig2*syr^3)/6)
Else
Bsyr=(1-Exp(-a*syr))/a
rinf=b-0.5*sig/(a^2)
Asyr=Exp((Bsyr-syr)*rinf-((sig2*Bsyr^2)/(4*a)))
End If
Else If imod=2 Then
gamma=Aqr(a^2+2*sig2)
c1=0.5*(a+gamma)
c2=c1*(Exp(gamma*syr)-1)+gamma
Bsyr=(Exp(gamma*syr)-1)/c2
Asyr=((gamma*Exp(c1*syr))/c2)^(2*a*b/sig2)
End If
VasicekCIRZero Value=Asyr*Exp(-Bsyr*r)
End Function

下面的函數用到以上函數計算出來的零息票債券價格,計算對數正態參數 M 和 V。後
邊幾行代碼與 OPTION2 檔中的 LNOption Value0 函數相同,零息票價格替換折現因數。
Function VasicekZeroOption Value(iopt,L,X,a,b,rnowyr,optyr,zeroyr,sigma)
‘ returns the Vasicek zero-coupon bond option value
‘ uses VasicekCIRZero Value fn
Dim P0T,P0s,voT,BTs,sigmao,M,V,d2,d1,Nd1,Nd2
P0T=VasicekCIRZero Value (1,a, b, r, nowyr, optyr, sigma)
P0s=VasicekCIRZero Value (1,a, b, r, nowyr, zeroyr, sigma)
If a=0 Then
v0T=sigma*Sqr(optyr-nowyr)
BTs=zeroyr-optyr
Else
v0T=Sqr(sigma^2*(1-Exp(-2*a*(optyr-nowyr)))/(2*a))
BTs=(1-Exp(-a*(zeroyr-optyr)))/a
End If
sigmap=v0T*BTs
M=Log(L*P0s/P0T)-0.5*sigmap*2
V=sigmap^2
d2=(M-Log(X))/Sqr(V)
d1=d2+Sqr(V)
Nd1=Application.NorSDist(iopt*d1)
Nd2=Application.NormSDist(iopt*d2)
VasicekZeroOption Value=P0T*iopt*(Exp(M+0.5*V)*Nd1-X*Nd2)
End Function

下面的函數試圖通過試數法來找出折現利率,使得期權到期後的債券支付現值總和等於
期權的執行價格。由於缺少斜率的計算公式,這裏用另外一個公式代替斜率:
Function Jamshidianstar (imod,L,cL,X,a,b,rtest,optyr,zeroyr,coupyr,sigma,radj)
‘ replicates Goal Seek to find rstar in Vasicek or CIR coupon option value
‘ uses VasicekCIRBondnpv fn
DIM atol, rnow, fr1, fr, fdashr
atol=0.0000001
rnow=rtest
Do
fr1=VasicekCIRBondnpv(imod,L,cL,a,b,rnow+radj,optyr,zeroyr,coupyr,sigma)-X
fr=VasicekCIRBondnpv(imod,L,cL,a,b,rnow,optyr,zeroyr,coupyr,sigma)-X
fdashr=(fr1-fr)/radj
rnow=rnow-(fr/fdashr)
Loop While Abs(fr)>atol
Jamshidianrstar=rnow
End Function

下面的公式給出了非中心卡方分佈的近似形式,可參見施羅德(1989)的論文。
(注意,
在他的論文中,公式(10)中列出了 c3,正確的情況應該是 N(c3))

Function CIRSankaranQ(z,nu,kappa)
‘ component for CIR Option Valuation(see Schroder)
Dim n,k,h,p,m,c1,c2,c3
n=nu
k=kappa
h=1-(2/3)*(n+k)*(n+3*k)/(n+2*k)^2
p=(n+2*k)/(n+k)^2
m=(h-1)*(1-3*h)
c1=1-h+0.5*(2-h)*m*p
c2=1-h*p*c1-(z/(n+k))^h
c3=c2/(h*Sqr(2*p*(1+m*p)))
CIRSankaranQ=Application.NormSDist(c3)
End Function

小結

Vasicek 和 CIR 利率模型是最早用於類比利率並產生相應期限結構的模型。目的是為零


息票債券定價提供一個解析解法,並改進忽略期限結構的布萊克-舒爾斯擴展方法。通過改
變參數,這兩個模型都能產生不同形狀的期限結構。CIR 模型將利率波動率與利率水準掛
鈎,這是 Vasicek 模型所不具備的性質。Jamshidian 說明了如何利用零息票債券期權定價
公式為附息債券期權定價。由於存在解析解,這些模型仍然非常重要,但是後來被擬合利率
期限結構方法所取代,見下一章詳細分析。

參考文獻

Chan, K.C., G. A. and Karolyi, F. A. Longstaff and A. B. Sander, 1992, “An Empirical
Comparison of Alternative Models of the Short-Term Interest Rate”, Journal of Finance,
47, 1209-1227.
Cox, J. C., J. E. Ingersoll and S. A. Ross, 1985, “A Theory of the Term Structure of Interest
Rates”, Econometrica, 53, 385-407.
Jamshidian, F., 1989, “Computing the Constant Elasticity of Variance Option Pricing
Formula”, Journal of Finance, 44, 211-219.
Vasicek, O. A., 1977, “An Equilibrium Characterization of the Term Structure”, Journal of
Financial Economics, 5,177-188.
第 16 章 擬合利率期限結構

前一章的出發點是 Vasicek 與考克斯,英格索爾和羅斯(CIR)的短期利率連續隨機模


型。根據這些模型,可以得到零息票債券價格的解析解,在此基礎上發展了幾種債券期權定
價的方法。本章作為一個對比,將使用離散的二叉樹為短期利率建模。這麼做的目的是根據
零息票債券的價格,擬合(或者說對應)當前的期限結構,並根據這個模型為債券期權定價。
14.3 節中,我們曾舉過一個利率二叉樹的例子,例中,允許利率跟當前的零息票債券
價格對應起來。本章將說明這種利率樹是如何計算出來的,並使得利率對應當前的期限結構
和相應的利率波動率。這時,不存在解析解,需要利用迭代方法產生利率二叉樹。
在股票期權一章中,我們構造二叉樹的出發點是兩個已知量,股票現在的價格 S 和(無
風險)利率 r,根據這兩個量,就可以得到期權執行日股票價格的分佈。因此,二叉樹被用
於期權定價,或者任何由二叉樹節點產生的現金流定價。
而在債券期權二叉樹中,兩個已知量為零息票債券價格 P 和債券到期時的現金流(等
於 1),根據這兩個已知量就可以構造一個利率二叉樹。二叉樹從現在的短期利率出發,在
以後的每一個時間點上,迭代過程保證了利率能跟市場上觀察到的零息票債券價格對應起
來。在二叉樹的每個時間點上,處於節點的利率都與一個反映利率波動性的公式聯繫起來。
通過保證利率樹正確地為每個時間點的零息票債券定價,就可以解出剩下未知的利率。這
樣,利率二叉樹與股票價格二叉樹不同,有一個隨時間變化的漂移項。整個模擬過程就是不
斷的延長時間點,直到債券到期。
相應的模型可以見工作簿檔 BOND2.xls 文件。檔中有兩個相關的簡單例子(LnNormal
和 Normal)
,還有兩個關於複雜的布萊克,德曼和托伊(BDT)樹的應用(一個描述了整個
樹過程是如何建立的,另外一個利用這個模擬樹為零息票債券期權定價)。簡單例子中採用
了連續複利利率,而 BDT 樹採用離散複利利率。

16.1 對數正態分佈利率樹

圖 16.1 展示了不同期限的零息票債券價格(還有由此得到的當前的利率期限結構)和
波動性。計算出來的利率樹與零息票債券價格和利率波動性一致,列在 B48:E51 單格中。
實際上,為了示範這種一致性,H 和 J 列中的債券價格和波動性是根據利率樹反推出來的。
下面說明利率樹是如何被構建的。

【書中 244 頁圖一】

圖 16.1 最終的利率樹,與零息票債券價格和波動性一致
圖 16.2 展示了與圖 16.1 相同的市場訊息,包括零息票債券價格和短期利率的波動性。
同時表中還有一個兩期的利率樹和一個兩期的價格樹,標的物是兩年期的債券,面值為 1。
每一個時期都為一年。

【書中 244 頁圖二】

圖 16.2 零息票債券價格和收益率,以及短期利率的波動率

在對數正態樹中,每一個時間點 i 上,臨近的兩個利率(往上和往下)之間有以下的關
係:

ln(ru / rd ) = 2σ (i )

這個關係也可以寫成 rd = ru exp [ −2σ (i ) ] ,單格 C13 對這個公式進行了說明。然後,

就可以利用兩期的短期利率樹對兩期的零息票債券的現金流進行定價。債券的定價在零息票
債券樹中進行,這裏假設利率往上和往下的概率是一樣的,而折現因數就是短期利率樹中的
利率。
例如,假設現在的一年期利率為 6.08%(B12 單格中)
,短期利率在下一期以相同的概

率上升到 ru 或下降到 rd 。我們嘗試給出 ru 的值為 7%(C12 單格中)


, rd 的計算公式在 C13

中,公式中採用了 C12 中的利率和 H7 中的利率波動率,得到 rd 的結果是 4.98%。通過這

些利率對兩期利率樹進行折現,得到兩年期的零息票債券價格為 0.886。注意 C16 中的公


式,其計算的結果是到期前一年債券的期望價格(當利率上升時,用 7%作為折現率)。
現在問題涉及到一個未知的元素(C12,現在是 7%)和一個已知的債券價格(這裏兩
年期零息票債券的價格為 0.885,在 D7 單格中)。為了達到一致,單格 C12 中的數值需要
進行修改使得 B16 單格的公式值等於 0.885,或者,一種更好的方法是使得 B18 的檢驗值
(兩年期零息票債券價格與 B16 的差再乘上 100)等於 0。為了達到這個目的,在債券價格
樹中使用單變數求解函數,將 B18 中的值設為 0,然後改變利率樹中 C12 的值。如圖 16.3
所示,C12 的值從 7%改變到 7.17%。價格樹將往上和往下變動的概率看成是相等的,而每
個節點上的公式與前面介紹的股票期權定價的二叉樹十分相似。
利率樹是建立在未來的時間點上的,從第 2 個時間點開始(因為開始的零息票收益率
可以應用在第 1 個時間點上)直到期權標的債券到期的時刻,在每一個時間點上,都採用
單變數求解函數。單變數求解函數保證了節點的漂移與市場價格暗含的漂移對應起來。

【書中 245 頁圖一】

圖 16.3 用 Goal Seek 函數尋找短期利率樹,使其產生正確的零息票債券價格 0.885

而一個四期的利率樹,見圖 16.4,可以通過同樣的方法獲得。使用 BinZeroRate Tree


函數會使過程變得更加簡單,見圖 16.1。根據利率樹得到的零息票債券價格(H48:H51)
和短期利率波動率(在 J48:J50 單格中)與前面使用的價格和波動率一致。

【書中 245 頁圖二】

圖 16.4 用單變數求解函數完成短期利率樹,並保證與零息票債券價格一致

通過兩個向量的表示,可以更加簡便地描述短期利率樹。X 向量代表每個時刻短期利率

樹節點上的最高利率。K 向量代表與此對應的往下變動的利率,通過 exp [ −2σ (i ) ] 來計算。

如果計算一種稱為阿羅-德布勒的價格樹來代替對應債券價格而建立利率樹模型,其效
率將會更高。但是,重複使用單變數求解函數是一種更容易地理解建立樹過程的方法。
到此,得到了一個短期利率二叉樹(對應現在的零息票債券期限結構和利率波動率),
可以對債券期權進行定價。

16.2 正態利率二叉樹

剛介紹的 LnNormal 工作表與下面將要介紹的 Normal 工作表的唯一區別在於二叉數短


期利率的波動率計算上。在正態樹中的每一個時刻 i,節點連接的兩個短期利率有以下的關
係:

ru − rd = 2σ (i )

這個式子可以改寫成 rd = ru − 2σ (i ) ,單格 C13 中應用到了這個公式。注意,對應短

期利率的波動率(H7:H9 單格)
。在此之後,建立利率樹的過程與前面的工作表完全相同
(參見圖 16.5)

【書中 246 頁圖一】

圖 16.5 在利率服從正態分佈的假設基礎上建立短期利率樹

建立利率樹的結果如圖 16.6。這裏採用了 BinZeroRate Tree 用戶定義函數。(函數中


的第一個參數用來決定利率到底是服從對數正態還是正態分佈的。)

【246 頁圖二】

圖 16.6 正態分佈假設下的利率樹
16.3 BDT 樹

下面介紹的布萊克,德曼和托伊(BDT)樹是在簡化的對數正態樹基礎上發展而來的。
但有一點不同,利率樹對應的是零息票收益率的波動性而不是對數短期利率的波動性。
在 LnNormal 工作表中有以下關係式:

ln(ru / rd ) = 2σ (i )
這個公式通過短期利率的波動性連結了二叉樹節點上的兩個短期利率。在 BDT 工作表中,
建立了 BDT 模式的對數正態樹,並有以下關係式:

ln( yu / yd ) = 2σ R (i )
這個關係式將 BDT 樹中的收益率和零息票收益率的波動性連接起來了。
這裏有兩點要注意的:第一,在前面的例子中,先給定短期利率的波動率然後將利率
與利率漂移項對應起來,現在這個過程被一個最優化過程取代了,最優化過程嘗試同時對應
波動率和漂移項;第二,這個最優化過程所給出的結果不一定與零息票債券價格嚴格對應。
在圖 16.7 中,我們說明了如何利用 Jamshidian(1991)方法去對應 BDT 樹中的零息
收益率和波動率。BDT 工作表中有兩個不同的部分:E 列到 H 列對應零息票收益率,而 K
到 N 列既對應零息收益率也對應收益率波動率。在這個工作表中,利率是在離散複利形式
下計算的。

【書中 247 頁圖】

圖 16.7 BDT 方法下的短期利率

克盧洛和 Stricklan(1998)通過阿羅-德布勒狀態價格對樹的構建過程給出了一個更詳
細的結果。首先最關心的是明確 BDT 樹和簡單的對數正態樹之間的區別,其次才確保所構
建的樹與零息票債券價格和收益率波動率嚴格對應。
利用圖 16.7 的佈局,建立了一個四期的 BDT 樹,對應零息票債券的價格 0.7770(H7

單格)
。對比之下,初始狀態的二叉樹(通過猜測 Pu 的初始值區域 F9:H11)給 4 年期零息

票債券的定價為 0.7837(E38 單格)而通過 Jamshidian 方法給出的價格為 0.7776(L38


單格)

Pu 和 Pd 向量是對應零息票債券價格和收益率波動率的充分必要條件。 Pu 和 Pd 向量代

表了零息票債券在 1 時刻(債券還有 3 年到期)向上和向下狀態下的價格。這裏 Pu 和 Pd 的

精確值是 0.8029 和 0.8486(O9 和 O10 單格)


,相比於 Jamshidian 樹中的 0.8036 和 0.8491
(M38 和 M39 單格) 。
將注意力集中到第一部分的 F 到 H 列,注意到第 7 行零息票債券價格的精確值(根據

第 5 行的零息收益率推導)與第 12 行的估計價格(根據第 9 行的 Pu 值推導)一致。但是第


20 行估計的收益率波動性與 15 行的零息收益率的精確值並不對應。可以使用單變數求解函

數三次(F,G 和 H 列),通過改變第 9 行的 Pu 值,將 22 行的檢驗值設定為 0。這樣就能

保證與收益率波動性保持一致。短期利率和零息票債券價格的二叉樹結果在 32 到 42 行,L
到 P 列的表格中列出。
通過 Jamshidian 方法和時間間隔為 1 年的所構造的零息票債券價格樹與 4 年期的零息

票債券的價格(0.7770,H7 單格)並不完全一致,通過初始的 Pu 值,其得到的債券當前價

格為 0.7837(E38)而解法給出的結果是 0.7776(L38)。Bjerksund 和 Stensland(1996)分析


了通過進一步迭代能夠達到的精確度。

16.4 用 BDT 樹為債券期權定價

建立短期利率二叉樹的目的是為了建立零息票債券價格二叉樹,從而為零息票債券期
權定價。ZCBOption 工作表中使用了 BDT 樹,為一個四年期的歐式和美式看跌期權定價,
其標的物為一個 10 年期的零息票債券。
如圖 16.8 所示,使用一系列零息票債券收益率(第 8 行的 zvec)和收益率波動率(第
9 行 sigvec)直到第 10 年。通過用戶定義陣列函數 BDTKvec(第 15 行)和 BDTXvec(第
16 行)獲得短期利率樹。從第 0 到第 3 步的數值與前面 BDT 工作表的短期利率樹的結果一
致。然後,用短期利率樹建立一個期權標的債券的價格樹(圖 16.9) 。二叉樹給出債券的價
值為 0.5042(B36 單格)對應於 0.5020(L13)的市場價格。
之後,期權的定價過程與股票期權相似。在執行日當天,期權的收益狀況通過零息票
債券價格和執行價格計算得出,然後順著二叉樹倒推到現在就可以得到期權的價值。二叉樹
中假設往上和往下變化的概率都為 0.5,使用利率二叉樹中的相應利率作為折現率。

【書中 249 頁圖一】

圖 16.8-ZCBOption 工作表中債券期權定價的短期利率樹

【書中 249 頁圖二】

圖 16.9 -ZCBOption 工作表中通過零息票債券價格樹為債券期權定價

執行價格為 0.8 的歐式看跌期權的價值為 0.1179(B51 單格中)


,美式期權的價格稍微高一
些,為 0.2958(B62 單格)。
BDT 樹建立在簡單對數正態樹基礎之上,它受歡迎的原因是通過市場價格可以容易地
得到零息票債券價格的期限結構和收益率波動率。根據 Bjerksund 和 Stensland 的建議,只
需增加少數的幾步迭代,就可以更準確地對應當前的期限結構。
16.5 Module 1 中的用戶定義函數

帶參數 imod 的函數允許在即期利率服從正態和對數正態兩種情況下使用。牛頓-拉夫


森(NR)搜尋法採用了一個近似法去求解:
Function BinZeroRate Tree (inorm,zpvec,volvec,L,delt)
' generates binomial spot rate tree
' inorm=1 for normal rates,2 for in-normality
' continuous interest rates only
' uses BinZeroPrice fn
Dim radj,atol,zpk,vkd,rk,fr1,fr,fdashr
Dim i As Integer, j As Integer, k As Integer,n As Integer
Dim RTmat() As Variant
n=Application.Count(zpvec)
ReDim RTmat(n,n)
radj=0.001
atol=0.0000001
RTmat(1,1)=-(Log(zpvec(1)/L))/delt
' solve for RTmat column-by-column
For k=1 To n
zpk=zpvec(k)
vkd=2*volvec(k-1)*Sqr(delt)
' use NR search to solve for rk,with finite difference fr1
rk=RTmat(1,k-1)
Do
RTmat(1,k)=rk+radj
For i=2 To k
If inorm=1 Then RTmat(i,k)=RTmat(i-1,k)-vkd
If inorm=2 Then RTmat(i,k)=RTmat(i-1,k)*Exp(-vkd)
Next i
fr1=BinZeroPrice(L,RTmat,k,delt)-zpk
RTmat(1,k)=rk
For i=2 To k
If inorm=1 Then RTmat(i,k)=RTmat(i-1,k)-vkd
If inorm=2 Then RTmat(i,k)=RTmat(i-1,k)*Exp(-vkd)
Next i
fr=BinZeroPrice(L,RTmat,k,delt)-zpk
' finite difference approximation to derivative
fdashr=(fr1-fr)/radj
rk=rk-(fr/fdashr)
Loop While Abs(fr)>atol
Next k
BinZeroRate=RTmat
End Function
這裏 NR 搜尋法用一個解析公式去求解
Function BDTPUvec(z0,zvec,sigvec,delt)
' replicates Goal Seek to find initial PU vector in BDT
' discrete interest rates only
' see Jamshidian(1991)
Dim atol,r0,jdt,zpj,puj,sigi,pdj,fval,fdashval
Dim j As Integer, n As Integer
n=Application.Count(zvec)
ReDim puvec(n)
atol=0.0000001
r0=(1+z0)^(delt)-1
For j=1 To n
jdt=j*delt
zpj=(1+zvec(j))^-((j+1)*delt)
puj=zpj*(1+r0)
sigi=sigvec(j)
Do
pdj=2*zpj*(1+r0)-puj
yuj=(puj^(-1/jdt))-1
ydj=(pdj^(-1/jdt))-1
fval=0.5*Log(yuj/ydj)-sigi*Sqr(delt)
fdashval=-(0.5/jdt)*((puj^-(1/jdt+1))/yuj+(pdj^-(1/jdt+1))/ydj)
puj=puj-(fval/fdashval)
Loop While Abs(fval)>atol
puvec(j)=puj
Next j
BDTPUvec=puvec
End Function

PU 向量被用於產生 K 和 X 向量,從而給出短期利率樹:
Function BDTKvec(pucvec,pdvec)
' from Pu and Pd vectors to approximation vector k in BDT
' see Jamshidian(1991)
Dim i As Integer, n As Integer
Dim kvec() As Integer
n=Application.Count(puvec)
ReDim kvec(n)
kvec(1)=((1/puvec(1))-1)/((1/pdvec(1))-1)
For i=2 To n
kvec(i)=((puvec(i-1)/puvec(i)-1)/((pdvec(i-1)/pdvec(i)-1)
Next i
BDTKvec=kvec
End function
Function BDTXvec(puvec,pdvec,kvec)
' from Pu and Pd vectors to approximation vector X in BDT
' see Jamshidian(1991)
Dim Prvec0
Dim i As Integer, n As Integer
Dim xvec() As Variant
n=Application.Count(puvec)
ReDim Xvec(n)
Xvec(1)=((1/0.5*(puvec(1)+pdvec(1))))-1)/(0.5*(1+1/kvec(1)))
For i=2 To n
xvec(i)=(((puvec(i-1)+pdvec(i-1)))/(puvec(i)+pdvec(i)))-1)/((0.5*(1+1/kvec(i)))^i)
Next i
BDTXvec=xvec
End Function

小結

建立二叉樹的過程解釋了為什麼債券期權定價比股票期權定價複雜得多。但是,對應
利率期限結構已經成為金融市場債券期權定價實務中的先決條件。幸運的是,在股票期權定
價中我們已經廣泛的使用風險中性定價和二叉樹。本章的重點是推導利率二叉樹的迭代方法
上。用於說明如何為零息票債券期權定價的 BDT 樹方法是深受從業者歡迎的。

參考文獻

Bjerksund, P. and G.Stensland, 1996, “Implementation of the Black-Derman-Toy Interest


Rate Model”, Journal of Fixed Income, 6, 67-75.
Black, F., E.Derman and W.Toy, 1990, “A One-Factor Model of Interest Rates and its
Application To Treasury Bond Option”, Financial Analysts Journal, 46, 33-39.
Clewlow, L. and C.Strickland, 1998, Implementing Derivatives Models, John Wiley & Sons,
Chichester.
Jamshidian, F., 1991, “Forward Induction Construction of Yield Curve Diffusion Models”,
Journal of Fixed Income, 1, 62-74.
附錄 其他 VBA 函數

本附錄提供了另外一些用戶定義函數,這些函數用於短期預測、ARIMA 建模、樣條、
特徵值和特徵向量計算。每個應用部分都有簡要的介紹。在本附錄中,相應的 VBA 函數比
試 算 表 本 身 更 重 要 , 這 些 程 式 可 以 在 VBE 代 碼 視 窗 運 行 。 本 章 相 應 的 工 作 簿 叫
OTHERFNS.xls。

預測

在 4Cast 工作表中的函數都是基於時間序列分析的,特別是用於分析產品以往的月銷
售資料。時間序列預測方法假設現在的銷售模型在將來繼續有效,因此這些模型在短期預測
中比長期預測更有效。銷售資料通過不同的方法進行“平均”,即保證最近的資料比很早以
前的資料賦予更大的權重。短期預測就是將最近的平均值作為下一期的資料。
首先,可以通過目測和其他的技巧來檢驗資料服從什麼模型。如果資料是圍繞一個平均
“水準”進行波動,那麼這個模型假設有以下形式:
data=level+error (A 類)
如果資料表現出一種趨勢(平均水準隨時間變動) ,那麼模型有以下形式:
data=level+trend+error (B 類)
如果資料圍繞一個跟季節有關的固定因素變動,那麼模型假設有以下形式:
data=(level+trend)×seasonal_factor+error (C 類)
這裏季節因素的均值為 1。
在決定了資料適用的模型以後,就可以選擇方法和參數來進行逐期的預測。根據歷史
資料,可以預測下一期資料的平均值。對於 A 類資料來說,可以通過移動平均的方法進行
預測,而另外一種方法就是用指數加權平均。指數加權平滑方法在這三類模型中都可以採
用。用戶定義函數 Esvec,ESHoltvec 和 ESWintervec 返回各類資料類型的指數平滑預測
值。每個函數都需要輸入資料(指 dvec)和不同的參數值。
指數平滑預測所採用的公式如下:
新預測值= α *data+(1- α )*(舊預測)
平滑常數 α (在 0 與 1 之間)決定了預測值隨新資料改變的速度。
4Cast 工作表包含了三個不同類型的銷售資料(A 類在 B 列中,B 類在 I 列中,C 類在
O 列中) 。
首先觀測 A 類銷售資料, D 列給出了銷售的六期移動平均預測值,在 F 列給出平滑常
數 α =0.1 的指數移動平均預測值。函數 MAvec 根據輸入值(B11:B34)給出計算結果
(D11:D34) ,這個過程中使用了轉置函數對輸出結構進行了轉置。F 列中的輸出結果是根
據 Esvec 函數計算的,輸入資料在 B11:B34,F5,F3 單格中,同樣使用了轉置函數。
用戶定義函數(如 Mavec,ESvec 等等)的代碼從變數的初始值開始計算,然後通過
不斷更新數列的平均值進行預測。代碼中的主要變數都含有 vec——fvec 代表預測,lvec 代
表每期的平均值(level) ,tvec 代表每期的趨勢值(trend) 。每個向量都是 n 維的。對於季
節性資料,需要將第 i 期轉換為相應的季節,並用用戶定義函數中的 MMod 指明。
所有這些模型都假設未來銷售水準可以根據過去的資料進行預測。例如,移動平均是
一個有限資料點的等權重平均方法。指數平滑中資料的權重是一個呈幾何級數變化的數列。
在上述兩種方法中,都是通過對歷史資料的組合來預測未來,而權重則依賴於相應的方法。
與之成對比的是,博克斯-詹金斯的方法(下一節介紹)通過決定最優的權重來進行預測。

ARIMA 模型

一些簡單的 ARIMA 模型(Autorogressive integrated Moving Average)可以在 Excel


中應用,同時使用規劃求解最優化過程。通常這些模型的估計值都是在一個黑箱子中計算出
來的——在軟體中輸入資料,等待,然後得到結果。很少知道軟體的電腦理是什麼。為了發
展對 Excel 的應用,有必要更進一步地分析這些計算,通過第一階段產生的參數估計量,可
以確保第二階段(使用規劃求解)進行得更順利。第一階段的估計量可以通過 VBA 函數計
算,而第二階段需要使用規劃求解,這都能通過宏自動執行。
下面介紹的 ARIMA 建模過程是根據博克斯和詹金斯的方法進行的(Pecer,1994)。
第一步要檢驗資料是否平穩。如果資料不是平穩的,就必須進行一定的變換(通常是差分)
獲得平穩的資料。對變換後的平穩資料選擇相應的 ARIMA 模型。第二步估計 ARMA 模型

。ARMA 模型的階數 ( p, q ) 通常是根據資料


中的參數,通常使用非線性最小二乘法(NLS)

的自相關和偏自相關函數決定的。第三步通過適當的檢驗方法(通常是 Q 檢驗)檢驗 ARMA


模型的殘差項是否服從白雜訊過程。第二和第三步可以重複進行直到所有的 p 和 q 組合都
嘗試過。儘管有其他一些方法幫助我們選擇最好的模型,但是這個過程仍然需要藝術和經
驗。在工作簿中提供了部分的診斷工具,包括計算樣本自相關函數和偏自相關函數的計算函
數,以及 Q 檢驗函數。
Excel 中應用 ARIMA 模型的第一步是通過畫圖和差分來檢驗資料是否是平穩序列。在
第二步中,通過用戶定義函數 ACFk 和 PACFk(返回滯後階數為 k 的自相關和偏相關係數)
畫出自相關函數和偏自相關函數圖。通過觀察這些圖,可以直接決定 ARMA 模型中 AR 和
MA 項的參數。在 ARMA 工作表中,有三種不同序列(D,G 和 N,34 行及以下)的模型
估計過程。通過檢驗這三個序列的 AC 和 PAC 函數(第 7 到第 18 行) ,可以看出序列 1 適
用 AR 模型,序列 2 適用 MA 模型,序列 3 適用 ARMA 模型。通過使用函數和巨集,逐一
說明一階自回歸模型(AR(1)) 、二階移動平均模型(MA(2) )和 ARMA(1,1)模型。
另外有一個返回 ARMA 模型參數估計量的用戶定義函數。
只有自回歸項(AR)的 ARMA 模型的估計需要用普通最小二乘回歸,參數的精確估計
量可以在一步計算中獲得。函數 Arpvec 中使用 LINEST 函數,並返回資料序列與其滯後值
的多元線性回歸的結果。在 ARMA 工作表中,Arpvec 函數用於估計 AR(1)過程的參數。
包含移動平均項(MA)ARMA 模型的參數估計過程有兩步,用初始估計量作為最優化
過程的輸入量,並產生最後的估計量。博克斯和詹金斯(1984)說明了如何找出 MA 參數
的初始估計量,他們的想法可以由 Maqvec0 函數實現。計算資料的(q+1)自協方差開始,
然後通過一個迭代過程(將模型的參數估計量設為 0)使得殘差方差最小進行估計。在試算
表中,這些初始估計量(在 G26:G28 單格中)用於給出 MA(2)過程的一系列殘差(誤
差)。注意,一定時期的殘差項不依賴於資料,而依賴於之前兩期的殘差(見 I34 單格的公
式)。在選擇初始估計量之後,得到殘差的平方和(G30 單格)的值為 1.067。現在使用規
劃求解去尋找新的參數組合,使得殘差平方和最小。可以通過 Excel 命令或者 VBA 宏來實
現。副程式(MA2qvec)的代碼可以參見 BM 模組。迭代以後得到的參數估計量在 I26:I28
單格中,而模型的殘差平方和也減少到 1.053。
對於 ARMA 模型,需要 AR 參數的初始估計量,這些估計量可以通過尤爾-沃克方程式
獲得。AR 的參數初始估計量已經計算出來(使用 ARMApqvec0 函數) (見 N26:N28 單格)。
在試算表中,這些參數初始估計量被用於給出 ARMA(1,1)過程的一系列殘差。注意,
對於 ARMA(1,1)模型來說,殘差既依賴於資料序列也依賴於前一期的殘差(如 P35 單
格中的公式所示) 。通過參數初始估計量算得的殘差平方和為 27.047(N30) 。如同 MA(2)
模型一樣,規劃求解最優化過程被用於計算最後的參數估計量(P26:P28 單格) 。規劃求
解最優化可以通過副程式 ARMA11pqvec 來控制,並需要使用 Ctrl+Shift+C 鍵盤按鈕組合。

樣條

樣條法是一個根據 x-y 資料點產生平滑曲線的有效方法。採用樣條法的目的可能是為


了插值(曲線需要通過所有數據點)或者是一個更一般的擬合過程(曲線要達到最優擬合效
果,而不一定通過所有的資料點) 。對比于擬合高階多項式的方法,樣條法的一個優點是只
需要少量的參數。低階多項式用於分段擬合連續資料點。通過選擇多項式的參數,可以產生
平滑的曲線與資料點對應起來。這裏將集中分析三次多項式,這樣可以保證函數的一階和二
階導數連續。模組(Module C1)中使用的函數可以計算標準的三次多項式樣條。另外,還
列舉了一個能產生一系列多項式樣條的函數,通過這個函數可以找出最優的多項式樣條。
先從資料點開始。在樣條的術語中,x 值表示節點,y 值是節點相應的函數值。擬合樣
條就是用三次多項式連接相鄰的節點,並且使得曲線光滑。對於三次樣條來說,可以通過保
證節點兩邊的二階導數連續而獲得光滑的曲線。CubicSplinezvec 函數返回每個節點的二階
導數(稱 zvec),用節點向量(kvec)和函數值(ykvec)作為輸入變數。函數計算兩個陣
列,一個對角矩陣(Tmat)和一個向量(vvec) ,然後通過矩陣相乘產生一個二階導數向量
(zvec)。通過 CubicSplinezvec 函數返回的導數值用於第二個函數 CubicSplineValue。這
個函數用於對其他 x 值(非節點)進行插值,產生一組新的 y 值。對於一個自然的三次樣條
函數來說,樣條的二階導數在每一段 x 值的末端一定為 0。對於特殊的 x 值來說,第一步就
是要確定它落在哪兩個節點之間,然後選擇適當的樣條來計算其對應的函數值。樣條值的計
算用到了一階(br)和二階(nzvec)導數。
CubicSplineValuey 函數返回 x 值對應的樣條值。作為一個鞏固練習,讀者可以思考如
何寫一個函數,計算在一系列節點範圍內的 x 值的對應樣條值。
標準的樣條非常有用,但是一個潛在的問題就是當改變某一個樣本點時,會對整個樣
條的估計結果產生影響。例如,改變單格 C20(Spline 工作表)中的數值,從 1.59 改為
5.00,注意到二階導數向量發生了改變。從圖一中,還可以發現修改以後的樣條函數仍然保
持平滑性。
相比之下,基本樣條法(B 樣條)的一個好處就是當一個資料點發生變化時,樣條函數
能夠在局部適應這種變化,而不會發生全局的變動。這個方法是通過定義一組“基本樣條”
來實現的。所謂基本樣條就是函數值在兩個相鄰節點區間內取正值,而在其他範圍取 0。每
一段基本樣條對應一個不同的節點。通過建立一系列的基本樣條,造一個函數,將這些不同
節點的樣條值聯繫起來。用戶可以選擇要估計的節點位置(包括落在樣本點之外的範圍) ,
並通過回歸方法計算出最佳擬合的參數,從而計算出相應的樣條值。可以看到,儘管三次多
項式樣條對資料的擬合程度不錯,但是基本樣條法(B 樣條法)是一個更為一般的擬合方法
(對所有數據點的最佳擬合)。基本樣條是擬合利率期限結構的一個常用方法。
在標準樣條方面,這裏只是說明了三次多項式樣條形式,而每一段樣條在相應的區間
上都取正值。對於一個給定的 x 值,我們需要估計出每一段樣條的參數,然後求出相應的樣
條值。而函數 CubicBSplineValuey,將矩陣(包含節點值)作為輸入變數,通過迴圈關係
產生基本樣條值。所謂迴圈關係是指在第一步計算三個基本樣條,在第二步計算兩個,在第
三步計算單個的樣條。

特徵值和特徵向量

儘管特徵值在物理和工程學中扮演著重要角色,但是他們在金融領域的主成分估計中
也是相當重要的。一個典型的應用就是將風險(通過資產收益的方差和協方差矩陣來表示)
分解為一系列的線性獨立變數(主成分或者特徵向量)。特徵值反映了不同特徵向量所引起
的風險比例。
儘管對於大型的矩陣有更好的方法,但雅各比方法在計算實對稱矩陣方面簡單有效。
這種方法可以將輸入矩陣(實對稱)經過一輪變換以後轉換為對角陣。每一次變化都保持對
角元素(最後會變為特徵值)的和不變,同時減少非對角元素的平方和。這個過程直到平方
和低於某個數值時停止(這個值為 10-19,稱為容忍水準) 。
函數 Eigenvaluesevec(在 Module D1 中)是主要的程式,而中間的函數都是進行雅
各比轉換。首先,計算轉換角(通過 Jacobivec 函數) ,然後建立轉換矩陣(在 JacobiPmat
函數中),最後得到更新後的輸入矩陣(JacobiAmat 函數) 。主程序的每一次迴圈產生一個
新的輸入矩陣,並計算非對角元素的平方和。當達到容忍水準時,輸入矩陣的對角元素被作
為特徵值。
相應的特徵向量的計算(在 EigenvectorsEmat 函數中)有相似的過程,但還需要另外
一個矩陣(開始時為一個單位陣)進行更新。當達到容忍水準時,特徵向量就是這個矩陣的
列向量。

參考文獻

Box, G.E.P. and G.M.Jenkins, 1984, Time Series Analysis: Forecasting and Control,
Molden Day, San Francisco, CA
Pecar, B., 1994, Business Forecasting for Management, McGraw-Hill, Maidenhead

You might also like