§01學習重點
- 用「曲線+衍生品+風險因子」這套共同骨架,一次看懂利率、信用、外匯、股商四個市場的結構
- 解釋殖利率曲線為什麼不能用單一到期殖利率代替,並親手從票息債價格 bootstrap 出零息曲線
- 白話說出久期與凸性各自量什麼、久期近似何時夠用何時失靈,並用全重評價實測誤差
- 拆解信用利差在補償什麼:違約機率×違約損失率之外,還有一大塊流動性與風險溢酬
- 描述 CDS 的保費腿與保護腿,用 credit triangle 在利差、危險率、回收率三者之間換算
- 寫出拋補利率平價(CIP)的兩條等價路徑,說明遠期匯率為何由利差決定而非預測,以及 CIP 偏離為什麼能存在
- 說出外匯選擇權「以 delta 報價」的特殊慣例,以及股票與商品市場的期貨曲線由什麼決定
§02課程內容
一、一套骨架看四個市場
課程走到這裡,工具箱已經齊了:第 14 章的風險中性定價、第 15 章的選擇權定價實務、第 16 章的 Greeks 與波動率曲面。但前三章的例子多半住在「某一個標的資產」上。真實的量化金融從業者不是這樣分工的——他們按市場分工:利率檯、信用檯、外匯檯、股票與商品檯。每個市場有自己的術語、報價慣例與交易文化,隔行如隔山。
本章的野心是把這座山剷平。方法是抓住一條貫穿所有市場的共同骨架:每個市場都是「一條曲線、一族衍生品、一組風險因子」。利率市場的曲線是殖利率曲線,衍生品是交換與交換選擇權,風險因子是水平、斜率、曲率;信用市場的曲線是危險率期限結構,衍生品是 CDS,風險因子是利差與違約;外匯市場的曲線是遠期點期限結構,衍生品是以 delta 報價的選擇權,風險因子是匯率與兩地利差;股商市場的曲線是期貨曲線,風險因子是現貨、股利與便利收益率。學會在一個市場裡辨認這三件東西,到另一個市場就只是換名詞。
深度先說清楚:這是一章市場結構總覽,不是四本教科書。目標是讓你懂結構、知術語,日後把機器學習接上任何一個市場時,知道特徵從哪裡來、標籤是什麼、風險藏在哪。每個市場只取核心機制,篇幅按利率、信用、外匯、股商遞減——因為前面的機制會被後面反覆重用。
二、殖利率曲線:把「錢的時間價格」畫成一條線
利率市場的一切從一個問題開始:一年後的 100 元,今天值多少?答案是折現因子 \(d(T)\)——今天付出 \(d(T)\) 元,換到 \(T\) 年後確定收到的 1 元。整條 \(d(T)\) 隨 \(T\) 變化的函數,換個座標畫出來就是殖利率曲線:
逐項拆解:\(z_T\) 是 \(T\) 年期的零息利率——把錢鎖 \(T\) 年、中途沒有任何現金流的年化報酬;\((1+z_T)^T\) 是複利滾 \(T\) 年的倍數;倒數就是把未來 1 元折回今天的價格。曲線上每個期限一個 \(z_T\),短天期通常貼著央行政策利率,長天期反映市場對未來利率與風險的定價。
麻煩在於:市場上直接交易的多半不是零息債,而是票息債——每年發利息、到期還本金,一張債券是一串現金流的組合。你會看到報價系統顯示每檔債券的「到期殖利率」(YTM):讓現值等於市價的那個單一折現率。YTM 好懂,卻有個結構性缺陷——它對同一時點的現金流用了不同的折現率。兩檔都在第 3 年付息的債券,若 YTM 不同,同一天的 1 元被折成不同價格,這在邏輯上說不通,也讓不同債券之間無法比價。出路是反過來:從一組票息債價格裡,解出一條對每個時點只有一個折現因子的零息曲線。這個程序叫 bootstrapping。
比喻: 像用天平校準一組砝碼。你手上只有「一包包混裝的砝碼」(票息債=多筆現金流的混裝包),沒有單顆的標準砝碼(零息債)。怎麼辦?先拿只含一顆砝碼的最小包(一年期債,只剩一筆到期現金流)上天平,稱出第一顆的重量;接著拿兩顆裝的包,扣掉已知的第一顆,秤出第二顆;三顆裝的扣掉前兩顆,秤出第三顆。每一步都靠前面已校準的砝碼,才能秤出下一顆——這就是 bootstrapping:由短到長、一次解一個折現因子。
親手做一次。四檔年付息公債(面額 100),由短到長依序求解:
import numpy as np
bonds = [ # (到期年, 年息票率, 市價)
(1, 0.020, 99.52),
(2, 0.025, 99.05),
(3, 0.030, 99.30),
(4, 0.032, 98.90),
]
d = {} # 折現因子 d[T]
for T, c, price in bonds:
coupon = 100 * c
known = sum(coupon * d[t] for t in range(1, T)) # 用已解出的短期折現因子
d[T] = (price - known) / (100 + coupon) # 解最後一筆現金流
z = d[T] ** (-1 / T) - 1 # 換算年複利零息利率
print(f"T={T}y 已知現值={known:7.4f} d={d[T]:.6f} zero={z*100:.4f}%")
# 輸出:
# T=1y 已知現值= 0.0000 d=0.975686 zero=2.4920%
# T=2y 已知現值= 2.4392 d=0.942544 zero=3.0028%
# T=3y 已知現值= 5.7547 d=0.908207 zero=3.2615%
# T=4y 已知現值= 9.0446 d=0.870692 zero=3.5223%
# 驗證:用解出的曲線重新定價,每檔都精確收回市價(誤差 < 1e-13)
for T, c, price in bonds:
pv = sum(100 * c * d[t] for t in range(1, T + 1)) + 100 * d[T]
assert abs(pv - price) < 1e-10四步解完,曲線向上傾斜:一年期 2.49%、四年期 3.52%。注意第 4 檔債的 YTM 是 3.4995%,與四年期零息利率 3.5223% 並不相等——YTM 是整串現金流的「加權平均折現率」,被前面較低的短期利率拉低了。這正是為什麼定價要用曲線、不能用 YTM。
曲線一旦在手,還附贈一件強大的東西:遠期利率。既然 \(d(1)\) 是「今天到一年後」的價格、\(d(2)\) 是「今天到兩年後」的價格,那「一年後起算、為期一年」的利率已經被隱含決定:
逐項拆解:\(f(1,2)\) 是第 1 到第 2 年的隱含遠期利率;等式說的是「先鎖一年、再按遠期利率續鎖一年」必須等於「直接鎖兩年」,否則兩條路徑之間就有套利。用上面的數字算:\(f(1,2)=3.52\%\)、\(f(2,3)=3.78\%\)、\(f(3,4)=4.31\%\)——曲線向上傾斜時,遠期利率比零息利率爬得更陡。遠期利率是市場「用價格寫下的對未來的看法」(混著風險溢酬),也是利率衍生品定價的原料。
實務註記:真實世界的曲線不是從四檔債券解出來的,而是從存款利率、利率期貨、交換利率等一整組工具聯合校準,且自 2008 年後業界改用「多曲線框架」——折現用有擔保的隔夜利率曲線(如美元的 SOFR),預測浮動指標另建一條曲線。機制與本節相同,只是工程更繁複。
三、久期與凸性:曲線動一下,你的債券痛多少
有了曲線,下一個問題是風險:利率動了,債券價格動多少?第一階答案叫久期(duration),第二階修正叫凸性(convexity):
逐項拆解:\(\Delta y\) 是殖利率的變動(例如升息一碼=0.25 個百分點);\(D\) 是修正久期——殖利率每升 1 個百分點,價格約跌 \(D\%\),負號捕捉「利率升、債價跌」的反向關係;\(C\) 是凸性——價格對殖利率的曲線彎度,因為折現是指數函數、不是直線,跌的時候跌得比直線少、漲的時候漲得比直線多,凸性項把這個「對持有人有利的彎」補回來。
比喻: 久期是債券現金流在時間軸上的重心。把每筆現金流的現值當成砝碼、擺在時間軸這根蹺蹺板上,重心落在哪一年,久期大約就是幾年。零息債的砝碼全在最遠端,重心=到期日,利率一動它晃得最兇;高票息債沿路都有砝碼,重心被拉近,晃動較小。這也解釋了為什麼久期同時是「敏感度」與「加權平均回收時間」——蹺蹺板離支點越遠的重量,對翹動的貢獻越大。
久期是一階線性近似,天生只在「小幅度」內可靠。多小算小?用全重評價實測(10 年期、3% 票息、殖利率 3% 起跳):
import numpy as np
def bond_price(y, T, c):
return sum(100 * c / (1 + y) ** t for t in range(1, T + 1)) + 100 / (1 + y) ** T
T, c, y0 = 10, 0.03, 0.03
times = np.arange(1, T + 1)
cfs = np.full(T, 100 * c); cfs[-1] += 100.0
disc = (1 + y0) ** (-times.astype(float))
P0 = (cfs * disc).sum()
D = (times * cfs * disc).sum() / P0 / (1 + y0) # 修正久期 8.53
C = (times * (times + 1) * cfs * disc).sum() / P0 / (1 + y0)**2 # 凸性 87.07
for dy_bp in (10, 100, 200):
dy = dy_bp / 10000
dP_true = bond_price(y0 + dy, T, c) - P0
dP_dur = -D * P0 * dy
dP_dc = dP_dur + 0.5 * C * P0 * dy ** 2
print(f"升 {dy_bp:>3}bp|實際 {dP_true:8.4f}|久期 {dP_dur:8.4f}|久期+凸性 {dP_dc:8.4f}")
# 輸出:
# 升 10bp|實際 -0.8487|久期 -0.8530|久期+凸性 -0.8487
# 升 100bp|實際 -8.1109|久期 -8.5302|久期+凸性 -8.0949
# 升 200bp|實際 -15.4435|久期 -17.0604|久期+凸性 -15.3191升 10 個基點時久期近似幾乎完美;升 200 個基點(八碼)時,久期高估跌幅 1.62 元——因為直線切線一路往下探,忽略了價格曲線往上彎;加上凸性修正後誤差縮到 0.12 元。作業二會讓你把到期拉到 30 年、幅度拉到 300 個基點,看近似怎麼一路崩壞。台灣的對照很直觀:2022 年 3 月到 2023 年 3 月台灣央行連續升息 3 碼(0.75 個百分點),同期美國聯準會升了 19 碼——持有長天期美債部位的台灣壽險業,帳上未實現損失以兆元計,那就是「久期 × 升息幅度」在真實資產負債表上的樣子。
最後把整條曲線的風險收攏:曲線有十幾個期限,難道要對每個期限各算一個敏感度?第 6 章的答案在這裡接上——對曲線變動做 PCA,幾乎總是得到水平、斜率、曲率三個因子,前三個主成分吃掉九成九的變異。利率風險管理因此從「十幾維」壓縮成「三維」:對沖掉水平與斜率,就對沖掉了絕大部分曲線風險。這也是機器學習接上利率市場的第一個入口:曲線因子是天然的特徵。
四、利率交換:把浮動換成固定
利率衍生品成交量最大的品種不是選擇權,是利率交換(interest rate swap)。機制樸素:甲方付固定利率、乙方付浮動利率(掛鉤某個短期指標利率,如今日的 SOFR),雙方按同一個名目本金、每期互換利息,本金不換手。誰需要它?背著浮動利率負債的企業想鎖住成本、持有固定收益資產的壽險想調整久期、交易員想表達「利率會往哪走」的看法——swap 是利率市場的瑞士刀。
定價的核心概念一個就夠:交換利率(swap rate)是讓合約在成交當下價值為零的那個固定利率。浮動腿的現值可以用曲線上的遠期利率逐期折現,固定腿是一串已知現金流;交換利率就是讓兩腿現值打平的固定率。這帶來一個漂亮的閉環:swap 報價本身又是 bootstrapping 曲線的輸入——市場用曲線給 swap 定價,又用 swap 的成交價回頭校準曲線,兩者互為鏡像。
再往上一層是利率市場的選擇權家族:利率上限(cap)是「對未來每一期浮動利率的買權串」,付浮動利率的借款人拿它當保險;交換選擇權(swaption)是「未來某天進場做 swap 的權利」,是利率波動率交易的主戰場。它們的報價匯成利率波動率曲面——第 16 章那套波動率曲面語言,在利率市場原樣重演,只是座標軸從「行使價×到期」換成「行使價×選擇權到期×標的年期」的三維立方。深入定價需要短率模型與市場模型,本章不展開(原書對照節有地圖)。
五、信用市場:利差在補償什麼
把場景換到公司債。同樣是 5 年期債券,公司債的殖利率比公債高出一截,這一截叫信用利差。天真的解讀是「利差=違約風險的保費」,但拆開看會發現事情有趣得多。
先建模「違約什麼時候發生」。信用市場的主流語言是危險率(hazard rate)\(\lambda\):在還沒違約的前提下,下一小段時間違約的機率密度。危險率固定時,存活機率呈指數衰減:
逐項拆解:\(\tau\) 是違約時點,\(Q(\tau>T)\) 是撐過 \(T\) 年的機率;\(\lambda\) 越大衰減越快。這跟「燈泡壽命」的建模一模一樣——不問「為什麼壞」,只用一個強度參數描述「多常壞」。違約發生時,債權人不是血本無歸:每 1 元面額平均收回 \(R\)(回收率,投資級公司債歷史經驗約四成),損失部分是 \(1-R\)(違約損失率,LGD)。
於是有了信用市場最好用的一條速算式——credit triangle:
逐項拆解:\(s\) 是信用利差(年化);右邊是「每年違約的機率 × 違約時的損失比例」=年化期望損失。利差、危險率、回收率三個角,知道兩個就能解第三個。例:市場上某公司 5 年期 CDS 利差 150 個基點、假設回收率 40%,隱含危險率 \(\lambda = 0.015/0.6 = 2.5\%\),五年累積違約機率 \(1-e^{-0.125}=11.75\%\)。
現在是本節的重點:把市場隱含的違約機率跟歷史實證的違約率擺在一起,兩者長期兜不攏。同一評級的公司,市場利差隱含的違約機率,普遍比評等機構統計的歷史違約率高出一大截。用上面的例子:若這家公司的實證年違約率其實只有 1.2%,違約補償只值 \(0.012 \times 0.6 = 72\) 個基點——觀察到的 150 個基點裡,有 78 個基點在補償別的東西:公司債的流動性遠差於公債(想賣的時候買賣價差大、甚至找不到對手)、違約損失集中在景氣最壞的時刻(壞時刻的錢更貴,要求更高溢酬)、以及評級遷移的風險。這就是文獻裡的「信用利差之謎」:利差不是違約機率的乾淨讀數,它是違約、流動性、風險厭惡的混合訊號。對機器學習從業者這是一句重要的警語——拿利差當「違約機率標籤」訓練模型,等於把三種訊號混進一個標籤裡。
建模違約還有另一條路。上面的危險率方法叫縮減式模型(reduced-form):不問違約的原因,把違約當外生的隨機事件,用市場價格校準強度——定價與對沖的主流。另一派叫結構式模型(structural):把違約講成有經濟結構的故事——公司資產價值是隨機過程,跌破負債門檻就違約,股權因此是「以資產為標的、負債為行使價的買權」(Merton 的洞見)。結構式模型把股價、財報跟違約機率接起來,是基本面信用分析與「用股市訊號預警債市」的理論骨架;縮減式模型放棄解釋、換取校準的精確。兩派分工明確:講故事用結構式,定價用縮減式。第 1 章的房貸建模縮影其實是第三條路——用逐筆貸款特徵訓練狀態轉移模型,那是機器學習直接下場建模信用的樣子;而第 5 章講的可解釋性工具,正是這類授信模型能被監管接受的前提。
六、CDS:可以單獨交易的違約保險
信用利差要成為可交易、可對沖的東西,需要一個乾淨的載體——信用違約交換(CDS)。機制用一句話講完:買方每季付保費(報價就是年化利差,例如 150 個基點),換取「參考實體若違約,賣方賠付 \(1-R\)」的保障。付保費的現金流叫保費腿,賠付叫保護腿;讓兩腿現值相等的保費率,就是 CDS 的公平利差。
比喻: 台灣民間借貸的「保人」制度把 CDS 的兩條腿演得很清楚。朋友向銀行借錢,你當保人——他跑路你代償,這是保護腿;差別在傳統保人是無償的人情,CDS 把它變成明碼標價的生意:想找人作保,每季付酬勞,市場上自然形成「幫這個人作保該收多少」的行情價。行情價本身就是資訊——當市場對某公司的「作保費」從 150 個基點跳到 400 個基點,等於全市場的保人們在說:這位的跑路風險變高了。而且你不必真的借錢給他,也可以單純去「賣作保」或「買作保」——這就是 CDS 讓信用風險脫離債券、單獨交易的意義。
公平利差可以嚴格算:保護腿現值 \(=\mathbb{E}[e^{-r\tau}(1-R)\,\mathbf{1}_{\tau\le T}]\),保費腿現值 \(=s\times\) 風險年金(每期折現×屆時存活機率的加總)。用蒙地卡羅驗證 credit triangle 這條速算式有多準:
import numpy as np
rng = np.random.default_rng(17)
lam, R, r, T = 0.02, 0.40, 0.03, 5.0 # 危險率2%、回收率40%、無風險3%、5年
tau = rng.exponential(1 / lam, 2_000_000) # 模擬違約時點
# 保護腿:T 內違約 → 收 1-R,按違約時點折現
prot = np.where(tau <= T, (1 - R) * np.exp(-r * tau), 0.0).mean()
# 保費腿(風險年金):季付,只在「還活著」的期數付
dt = 0.25
grid = np.arange(dt, T + 1e-9, dt)
alive = (tau[None, :] > grid[:, None]).mean(axis=1) # 各期存活機率
annuity = (alive * np.exp(-r * grid) * dt).sum()
print(f"損益兩平利差 = {prot / annuity * 10000:.1f} bp")
print(f"credit triangle λ(1−R) = {lam * (1 - R) * 10000:.1f} bp")
# 輸出:
# 損益兩平利差 = 121.4 bp
# credit triangle λ(1−R) = 120.0 bp完整定價 121.4 個基點、三角速算 120 個基點——差 1 個基點出頭,來源是速算忽略了折現與保費在違約當期的應計細節。日常心算用三角,正式定價用兩腿。
CDS 對不同到期(1、3、5、7、10 年)各有報價,這組報價又能玩一次第二節的把戲:由短到長 bootstrap 出存活曲線——分段常數的危險率期限結構。同一套「由短到長逐段求解」的邏輯,在利率市場解折現因子、在信用市場解存活機率,骨架完全同構,這正是第一節那句「換市場只是換名詞」的第一個兌現。台灣的對照:台灣沒有活躍的公司 CDS 市場,但「中華民國主權 CDS」在離岸市場有報價,長年是亞洲最低的一檔之一,約在兩位數基點的量級——它被市場當成兩岸地緣風險的溫度計,跳動的時點比幅度更有資訊量。(⚠️ 具體報價隨時間變動,引用當下數字前需查證。)
七、外匯市場:兩種錢的相對價格
外匯是全球成交量最大的市場,日成交以兆美元計。它的特殊性在於標的不是「一個資產」,而是兩種貨幣的相對價格——你做多一邊,必然做空另一邊;持有部位期間,兩邊各自生息。這個「雙邊都有利率」的結構,決定了外匯市場最核心的一條定價關係。
問題:即期美元兌台幣 32.00,一年期遠期匯率該是多少?直覺會想「看市場預期美元漲還是跌」——錯。遠期匯率不是預測出來的,是套利套出來的。手上 100 萬台幣、一年後要用台幣,有兩條路:
S, r_twd, r_usd = 32.00, 0.016, 0.053 # 即期、台幣利率、美元利率
F = S * (1 + r_twd) / (1 + r_usd) # CIP 遠期匯率
print(f"CIP 遠期 = {F:.4f}(遠期點 {F - S:+.4f})")
capital = 1_000_000
pathA = capital * (1 + r_twd) # 路徑A:台幣定存
usd_end = capital / S * (1 + r_usd) # 路徑B:換美元、存美元
pathB = usd_end * F # 期初就用遠期鎖定換回匯率
print(f"路徑A {pathA:,.0f} vs 路徑B {pathB:,.0f},差 {pathB - pathA:.6f}")
# 輸出:
# CIP 遠期 = 30.8756(遠期點 -1.1244)
# 路徑A 1,016,000 vs 路徑B 1,016,000,差 0.000000路徑 A:台幣定存 1.6%,期末 101.6 萬。路徑 B:先換成 31,250 美元、存美元 5.3%、期初就簽好遠期合約鎖定一年後換回的匯率。兩條路都沒有承擔任何匯率風險,終點必須一模一樣——否則所有人湧向高的那條,價差瞬間被吃掉。由此解出遠期匯率:
這就是拋補利率平價(Covered Interest Parity, CIP)。逐項拆解:\(S\) 是即期匯率(1 單位外幣值多少本幣);分子分母是兩邊各自的利息倍數;「拋補」指匯率風險已被遠期合約蓋住。注意結論的反直覺處:美元利率比台幣高 3.7 個百分點,遠期匯率反而是美元貶值(30.88 < 32.00)——高息貨幣在遠期市場必然折價,否則「借低息、存高息、遠期鎖匯」就是無風險印鈔機。遠期點位純粹是利差的鏡像,與「市場看漲看跌」無關。
比喻: CIP 是連通管原理。兩個水槽(台幣資金池、美元資金池)底部有管子相通(換匯+遠期市場),水位(無風險報酬)必然拉平——哪邊高,水就流過去,直到平了為止。教科書時代大家以為管子永遠暢通;2008 年金融危機後,管子開始淤塞:監管新規讓銀行的資產負債表變貴,跨貨幣套利要占用資本額度,搬水的人變少了。於是水位差可以持續存在——這就是「交叉貨幣基差」(cross-currency basis):實測遠期匯率對 CIP 理論值的系統性偏離,美元荒的季末、年底特別明顯。水位差沒消失不是因為沒人看見,而是因為搬水本身有了成本。
CIP 偏離對量化從業者是雙重身分:對套利者是訊號(偏離超過交易成本門檻才動手,作業三會做一個偵測器),對其他所有人是成本——台灣壽險業把大量資產配置在美債、再用換匯交易避險,基差走闊時避險成本可以吃掉大半利差,這是台灣金融業每季財報都要面對的變數。另一個台灣在地細節:台幣是有資本管制的貨幣,離岸市場因此發展出 NDF(無本金交割遠期)——到期不真的交割兩種貨幣,只按「約定匯率 vs 屆時即期」的差額用美元結算。NDF 不受在岸管制束縛,它與在岸遠期的價差,本身就是資本管制鬆緊與投機壓力的溫度計。
最後講外匯選擇權市場一個獨有的慣例,第 16 章的波動率曲面在這裡換了座標系。股票選擇權的報價軸是行使價;外匯選擇權市場不報行使價,報 delta——報價單上的三大件是:ATM 波動率(平價)、25-delta risk reversal(同 delta 的買權與賣權隱含波動率之差,量曲面的偏斜)、25-delta butterfly(兩翼平均相對 ATM 高出多少,量曲面的翅膀)。要還原出「某個行使價對應的波動率」,得先用 Black–Scholes 的 delta 公式反解行使價——但 delta 本身又依賴波動率,所以還原曲面是一個小小的迭代校準問題。為什麼這樣設計?因為即期匯率整天在動,用 delta 標定的點「跟著即期走」,同一張報價單能活得更久。對做資料的人這是一課:外匯波動率資料的原始格式是 (delta, 期限) 網格,不是 (行使價, 期限) 網格——直接把它當行使價餵進模型,是新手常見的資料工程錯誤。
八、股票與商品:同一套骨架的最後兩塊
四塊拼圖剩最後兩塊,而你其實已經會了——考驗骨架的時候到了。
股票的期貨曲線是 CIP 的孿生兄弟。持有股指期貨 vs 借錢買現股抱到期:兩條路徑終點相同,所以 \(F = S(1+r) - \text{預期股利}\)——利率是持有成本、股利是持有收益,期貨價高於或低於現貨,完全由「利率 vs 股利率」的相對大小決定。台指期每月結算前的「正價差、逆價差」,多數時候就是這條算式在說話(除息旺季逆價差放大),只有極端行情下才摻入情緒的成分。
商品把這條式子推到極限。黃金可以低成本儲存,期貨曲線乖乖服從持有成本邏輯;原油、天然氣儲存又貴又危險,現貨與期貨之間的套利鏈條斷裂,曲線開始「有自己的想法」:實體用家願意為「手上有貨」付出的隱含溢價叫便利收益率(convenience yield)——庫存吃緊時飆高,把曲線壓成近高遠低(backwardation);儲存過剩時歸零,曲線回到近低遠高(contango)。最極端的是 VIX:它的「現貨」(即時指數)根本不可交易,期貨曲線完全由供需與風險溢酬決定,長期處於 contango——持有 VIX 期貨避險的人,每個月把部位往前滾動都在「高買低賣」,這個系統性的滾動損耗(roll yield)正是波動率賣方策略長年有利可圖、也偶爾一夜歸零的結構原因。
收束全章,把骨架攤開成一張對照表:
| | 曲線 | 核心衍生品 | 主風險因子 | |---|---|---|---| | 利率 | 殖利率曲線 | swap、cap、swaption | 水平/斜率/曲率 | | 信用 | 危險率期限結構 | CDS、指數 CDS | 利差、違約、回收率 | | 外匯 | 遠期點曲線 | 遠期、delta 報價選擇權 | 匯率、兩地利差、基差 | | 股商 | 期貨曲線 | 期貨、指數選擇權 | 現貨、股利/便利收益率 |
每一列都是「一條曲線描述時間維度的價格、一族衍生品讓風險可交易、一組因子把風險降維」。對機器學習從業者,這張表是特徵工程的地圖:曲線因子(水平、斜率、曲率)、利差拆解(違約 vs 流動性)、基差(CIP 偏離、NDF 價差)、期貨曲線形狀(contango 深度、滾動收益)——全是跨市場可比、經濟意義清楚的特徵原料。下一章把這些原料裝進投資組合建構與風險管理的框架;到那裡你會看到,本章的「因子」正是組合風險模型的積木。
§03原書對照
本章以四合一的方式重組了原書第 13 至 16 章(Section III「不同市場的量化建模」)的骨架,以下內容原書有、但本課未展開,供進階讀者按頁碼深入。利率章:各市場開場都有一節「市場設定」,交代參與者結構與交易動機(p.317);日算慣例、FRA 與歐洲美元期貨作為曲線建構工具的細節(pp.320–324);bootstrapping 與最佳化兩種建曲線方法的優劣比較——前者精確收回市價但曲線前端有鋸齒、後者平滑但帶擬合誤差(pp.328–331);Libor 向 OIS 折現轉換的多曲線框架註記(p.328);曲線的實證觀察與聯準會政策如何塑形曲線的討論(p.332);cap/floor 以 Black 模型逐期定價與波動率剝離(pp.336–339);swaption 以 Bachelier 模型定價、以 SABR 擬合偏斜、以及三維波動率立方的組織方式(pp.339–341);短率模型家族的系統性推進——Ho-Lee、Vasicek、CIR、Hull-White 到雙因子高斯模型,各模型的均值回歸與分布性質逐一對照(pp.341–348);Libor 市場模型與其下的 swaption 定價(pp.349–351);百慕達交換選擇權等奇異品(pp.352–353);投資視角的交易結構——carry 收割、交換對公債的基差交易、條件變陡交易、蝶式(pp.354–360);歐洲與日本引入負利率後模型如何調整的案例研究(pp.361–362)。信用章:風險債券與無風險債券的久期行為對比(p.369);CDS 兩腿的逐項估值、風險年金與利率年金之別、部位的市值評價(pp.370–374);CDS 與現券之間的基差及其驅動因素(pp.375–376);指數 CDS 的估值、指數對單名的基差,以及從投資級與高收益指數報價實作提取危險率(pp.378–381);市場隱含與實證違約機率的直接對照(p.382);CDS 選擇權與指數選擇權(pp.383–385);CDO 的分券償付結構、單因子大池同質模型與相關性偏斜(pp.386–391);連接股權與信用的 Merton 模型與 Hirsa-Madan 方法(pp.392–394);不動產抵押證券的提前還款風險(pp.394–396)與信用市場的交易結構(pp.396–400)。外匯章:十大工業國與新興市場貨幣的分野、主要參與者(pp.401–404);遠期匯率事後是否實現的 carry 實證——這是外匯 carry 策略的根基(pp.407–410);可交割與不可交割遠期(p.410);外匯三角與交叉匯率的一致性(p.411);delta 報價慣例下曲面校準的完整流程(pp.412–415);數位、單觸碰、亞式、障礙等奇異選擇權在外匯市場的角色(pp.416–422);避險與 carry 之外的貨幣三角離差交易、偏斜交易(pp.427–429);2015 年瑞士央行放棄匯率下限、瑞郎單日暴漲的案例研究(pp.429–431)。股商章:難儲存資產的期貨曲線、VIX 與天然氣的超額 contango 實證(pp.434–439);股商波動率曲面的持續性特徵(pp.440–441);回顧型與一籃子選擇權(pp.442–443);單一個股動量、滾動收益收割、指數對成分股的離差交易、槓桿 ETF 的長期損耗(pp.444–450);天然氣軋空與 2018 年波動率商品崩盤的兩個案例研究(pp.451–457)。原書四章合計對應印刷頁 pp.317–457。
§04作業和解答
作業一:從票息債 bootstrap 零息曲線,並抓出「同 YTM 定價」的錯
給定五檔年付息公債(面額 100):1 年期息票 1.5% 價 98.86、2 年期 2.0% 價 97.97、3 年期 2.5% 價 97.85、4 年期 2.75% 價 97.42、5 年期 3.0% 價 97.20。(1) bootstrap 出五個折現因子與零息利率;(2) 用曲線為一檔新發行的 5 年期、息票 4.5% 的債券定價;(3) 換一種常見的偷懶做法——直接套用 5 年期舊債的 YTM 為新債定價——兩者差多少?誤差從哪來?
解答 SOLUTION
import numpy as np
bonds = [(1, 0.0150, 98.86), (2, 0.0200, 97.97), (3, 0.0250, 97.85),
(4, 0.0275, 97.42), (5, 0.0300, 97.20)]
d = {}
for T, c, price in bonds:
coupon = 100 * c
known = sum(coupon * d[t] for t in range(1, T))
d[T] = (price - known) / (100 + coupon)
print(f"T={T}y d={d[T]:.6f} zero={(d[T] ** (-1/T) - 1)*100:.4f}%")
# 輸出:d 依序 0.973990 / 0.941392 / 0.907918 / 0.872564 / 0.836043
# zero 依序 2.6704% / 3.0658% / 3.2725% / 3.4667% / 3.6464%
# (2) 曲線定價新債(5y、4.5% 息票)
pv = sum(100 * 0.045 * d[t] for t in range(1, 6)) + 100 * d[5]
print(f"曲線定價 = {pv:.4f}") # 103.9979
# (3) 偷懶做法:套 5 年舊債 YTM(二分法解 3.6223%)
def bond_price(y, T, c):
return sum(100 * c / (1 + y) ** t for t in range(1, T + 1)) + 100 / (1 + y) ** T
lo, hi = 0.0, 0.2
for _ in range(100):
mid = (lo + hi) / 2
lo, hi = (mid, hi) if bond_price(mid, 5, 0.030) > 97.20 else (lo, mid)
print(f"同 YTM 定價 = {bond_price(mid, 5, 0.045):.4f}") # 103.9492,低估 0.0487解讀:兩種定價差了約 4.9 分(每百元面額)。誤差來源:曲線向上傾斜時,高息票債有更多現金流落在「短年期、低折現率」的區段,其正確的加權平均折現率應該更低(價格更高);直接套用低息票舊債的 YTM,等於用「重心偏遠端」的折現率去折「重心偏近端」的現金流,把新債的近端現金流折得太兇。每百元 4.9 分看似微小,對以十億計的部位就是實打實的定價誤差——這正是專業定價一律走曲線、YTM 只當溝通工具的原因。
作業二:久期近似誤差的實測地圖
沿用課文的債券設定(3% 息票、殖利率 3% 起跳),對到期 2、10、30 年 × 升息 25、100、300 個基點的九宮格,實測:實際價格變動百分比、久期近似、久期+凸性近似。整理誤差表,回答:(1) 誤差隨到期與幅度各怎麼放大?(2) 凸性修正在哪些格子仍然不夠?(3) 給利率風險系統一條務實建議。
解答 SOLUTION
import numpy as np
def bond_price(y, T, c):
return sum(100 * c / (1 + y) ** t for t in range(1, T + 1)) + 100 / (1 + y) ** T
def dur_conv(T, c, y):
times = np.arange(1, T + 1)
cfs = np.full(T, 100 * c); cfs[-1] += 100.0
disc = (1 + y) ** (-times.astype(float))
P = (cfs * disc).sum()
D = (times * cfs * disc).sum() / P / (1 + y)
C = (times * (times + 1) * cfs * disc).sum() / P / (1 + y) ** 2
return P, D, C
y0 = 0.03
for T in (2, 10, 30):
P0, D, C = dur_conv(T, 0.03, y0)
for bp in (25, 100, 300):
dy = bp / 10000
truth = (bond_price(y0 + dy, T, 0.03) - P0) / P0 * 100
a1 = -D * dy * 100
a2 = (-D * dy + 0.5 * C * dy * dy) * 100
print(f"T={T:>2} +{bp:>3}bp 實際{truth:9.4f}% 久期誤差{a1-truth:8.4f} 凸性後{a2-truth:7.4f}")
# 關鍵輸出:
# T= 2 +300bp 實際 -5.5002% 久期誤差 -0.2402 凸性後 0.0093
# T=10 +300bp 實際 -22.0803% 久期誤差 -3.5103 凸性後 0.4076
# T=30 +100bp 實際 -17.2920% 久期誤差 -2.3084 凸性後 0.2252
# T=30 +300bp 實際 -41.2945% 久期誤差-17.5068 凸性後 5.2957解讀:(1) 誤差沿兩個軸同時放大——幅度軸上按 \((\Delta y)^2\) 的速度成長(300 個基點的誤差約是 100 個基點的九倍),到期軸上隨久期與凸性本身變大而放大。(2) 30 年 × 300 個基點的格子裡,連凸性修正後仍差 5.3 個百分點——泰勒展開的三階以上項已經不可忽略,任何固定階數的近似都會在「長久期 × 大變動」的角落失守。(3) 務實建議:日常小幅波動用久期+凸性夠了,但風險系統的壓力測試(監管情境動輒 200 到 400 個基點)必須全重評價——把情境利率直接代入定價函數重算,不走任何近似。2022 年那輪全球升息(美國一年內升逾 400 個基點)正好落在近似最失真的區域,是活生生的教材。
作業三:CIP 偏離偵測器
模擬 500 個交易日的市場:即期匯率隨機漫步(自 32.0 起、日波動 0.3%)、兩地利率緩慢漂移(台幣約 1.6%、美元約 5.3%);市場遠期=CIP 理論值 ×(1+basis),平時 basis 為零均值、標準差 4 個基點的雜訊,但在第 300–339 天插入一段 −35 個基點的錯位(模擬美元荒)。寫一個偵測器:|偏離| 超過來回交易成本 15 個基點才觸發,統計觸發天數、誤報數,並以名目 100 萬美元估算每筆淨套利。
解答 SOLUTION
import numpy as np
rng = np.random.default_rng(2017)
days = 500
S = 32.0 * np.exp(np.cumsum(rng.normal(0, 0.003, days)))
r_twd = 0.016 + 0.002 * np.sin(np.arange(days) / 80)
r_usd = 0.053 + 0.003 * np.cos(np.arange(days) / 100)
F_cip = S * (1 + r_twd) / (1 + r_usd)
basis_bp = rng.normal(0, 4, days)
basis_bp[300:340] -= 35 # 壓力事件
F_mkt = F_cip * (1 + basis_bp / 10000)
dev_bp = (F_mkt / F_cip - 1) * 10000 # 實務上用市場遠期、即期與利率直接算
cost_bp = 15.0
flag = np.abs(dev_bp) > cost_bp
net = (np.abs(dev_bp[flag]) - cost_bp) / 10000 * 1_000_000
print(f"平時段 |dev| 均值 = {np.abs(dev_bp[:300]).mean():.1f} bp")
print(f"壓力段 dev 均值 = {dev_bp[300:340].mean():.1f} bp")
print(f"觸發 {flag.sum()} 天(壓力段內 {flag[300:340].sum()} 天)→ 誤報 0")
print(f"平均每筆淨套利 = {net.mean():,.0f} 美元/百萬名目,最大 {net.max():,.0f}")
# 輸出:
# 平時段 |dev| 均值 = 3.2 bp
# 壓力段 dev 均值 = -34.9 bp
# 觸發 40 天(壓力段內 40 天)→ 誤報 0
# 平均每筆淨套利 = 1,992 美元/百萬名目,最大 2,761解讀:門檻設在成本之上,平時的 4 個基點雜訊完全不觸發(500 天零誤報),40 個壓力日全數捕捉——偵測器的功力全在門檻與成本的相對位置:門檻低於真實成本會把雜訊當機會(吃進負期望值的交易),太高則錯過整段錯位。每筆約 2,000 美元/百萬名目的淨利貌似微薄,但 CIP 套利近乎無市場風險、可以上規模——這正是它專屬於「資產負債表便宜」的大型銀行的原因,也解釋了為何監管讓資產負債表變貴之後,基差可以持續不收斂。進一步的真實世界複雜度:遠期報價的買賣價差、換匯交易的保證金、季末資本計提高峰——都在把「理論套利」削成「有條件的套利」。
作業四:從 CDS 期限結構讀出違約機率
某公司 CDS 報價:3 年期 35、5 年期 58、7 年期 80、10 年期 100(單位:基點),假設回收率 40%。(1) 用 credit triangle 的分段版(\(s_T \cdot T = \sum_k \lambda_k (1-R)\, \Delta t_k\),忽略折現)bootstrap 出四段危險率;(2) 算各節點的累積違約機率;(3) 說明這條期限結構「往上傾斜」透露了什麼,以及市場隱含機率為何不能直接當歷史違約率用。
解答 SOLUTION
import numpy as np
tenors, spreads_bp, R = [3, 5, 7, 10], [35, 58, 80, 100], 0.40
lam, prev_T, acc = [], 0.0, 0.0
for T, s in zip(tenors, spreads_bp):
s /= 10000
lam_k = (s * T - acc) / ((T - prev_T) * (1 - R)) # 解本段危險率
lam.append(lam_k)
acc += lam_k * (1 - R) * (T - prev_T)
prev_T = T
surv, prev_T = 1.0, 0.0
for (T, s), l in zip(zip(tenors, spreads_bp), lam):
surv *= np.exp(-l * (T - prev_T))
print(f"{prev_T:.0f}-{T:.0f} 年段 λ={l*100:.3f}%/年 累積違約率={100*(1-surv):.2f}%")
prev_T = T
# 輸出:
# 0-3 年段 λ=0.583%/年 累積違約率= 1.73%
# 3-5 年段 λ=1.542%/年 累積違約率= 4.72%
# 5-7 年段 λ=2.250%/年 累積違約率= 8.91%
# 7-10 年段 λ=2.444%/年 累積違約率=15.35%解讀:(1)(2) 分段危險率從 0.58% 一路爬到 2.44%——注意 10 年期利差雖只有 100 個基點,遠端的邊際危險率已是近端的四倍多,因為長天期利差是整段期間的平均,遠端要把前面低的部分「補回來」。(3) 上傾的期限結構是投資級公司的典型長相:近期違約風險低(手上有現金、債務結構清楚),遠期不確定性大。反過來,陷入困境的公司常出現倒掛——市場認為「撐過眼前這關就沒事」,1 年期利差反而比 5 年期貴。至於能不能把 15.35% 當成「這家公司十年內的真實違約機率」——不能。第五節說過,市場隱含的是風險中性機率,混著流動性與風險溢酬,系統性高於實證違約率;它是定價與對沖的正確輸入,卻是精算與統計問題的有偏估計。兩套機率各司其職,混用是信用建模最常見的概念錯誤。
§05參考資料
- BIS (2016). Covered interest parity lost: understanding the cross-currency basis. BIS Quarterly Review — 國際清算銀行對 CIP 偏離與交叉貨幣基差成因的權威分析,第七節的深化讀物。
- Du, W., Tepper, A., & Verdelhan, A. (2018). Deviations from Covered Interest Rate Parity. NBER Working Paper 23170 — 記錄 2008 年後 CIP 系統性失效的代表性學術研究。
- Gilchrist, S., & Zakrajšek, E. (2012). Credit Spreads and Business Cycle Fluctuations. NBER Working Paper 17021 — 把信用利差拆成期望違約成分與「超額債券溢酬」,第五節利差拆解的實證基礎。
- U.S. Department of the Treasury — Daily Treasury Par Yield Curve Rates — 美國財政部每日公布的殖利率曲線,親手練習曲線因子分析的免費資料源。
- Federal Reserve — H.15 Selected Interest Rates — 聯準會利率統計,涵蓋國庫券、SOFR 等本章討論的市場利率。
- 中華民國中央銀行全球資訊網 — 台灣政策利率、匯率與金融統計的官方來源,本章台灣在地對照的查證入口。
- CBOE — VIX Index — VIX 指數官方頁面,第八節「現貨不可交易的期貨曲線」的第一手資訊。
- Kelliher, C. (2022). Quantitative Finance with Python: A Practical Guide to Investment Management, Trading and Financial Engineering. CRC Press(Taylor & Francis 官方頁) — 本章對照之原書,第 13–16 章 pp.317–457。