QuantLib 金融計算——案例之普通歐式期權分析


如果未做特別說明,文中的程序都是 python3 代碼。

QuantLib 金融計算——案例之普通歐式期權分析

載入 QuantLib 和其他包:

import QuantLib as ql
import numpy as np
import pandas as pd

print(ql.__version__)
1.15

概述

從金融工程中最簡單的案例——“普通歐式期權公式法定價”入手,介紹 QuantLib 中期權分析的基本組件,以及如何將這些組件拼接成為一個完整的計算流程。

普通歐式期權公式法定價

采用《期權、期貨及其他衍生產品(第 7 版)》第 17 章中的例子:

  • 類型:普通歐式看漲期權
  • 當前價格:49$
  • 敲定價格:50$
  • 無風險利率:5%
  • 年化波動率:20%
  • 期限:20 周

使用 BS 公式為上述期權定價,並計算希臘值。

1. 配置期權合約條款

# 配置日期計算條款
calendar = ql.UnitedStates(ql.UnitedStates.NYSE)
dayCounter = ql.Actual365Fixed(ql.Actual365Fixed.Standard)

todayDate = ql.Date(11, ql.July, 2019)
maturity = todayDate + ql.Period(20, ql.Weeks)
settlementDate = todayDate

# 配置期權參數
stock = 49
strike = 50
riskFreeRate = 0.05
volatility = 0.2

# 配置全局估值日期
ql.Settings.instance().evaluationDate = todayDate

2. 構建期權對象

# 配置行權條款
europeanExercise = ql.EuropeanExercise(maturity)
optionType = ql.Option.Call
payoff = ql.PlainVanillaPayoff(
    type=optionType, strike=strike)

# 構建期權對象
europeanOption = ql.VanillaOption(
    payoff=payoff,
    exercise=europeanExercise)

3. 配置定價引擎

underlying = ql.SimpleQuote(stock)
underlyingH = ql.QuoteHandle(underlying)

# 無風險利率的期限結構
flatRiskFreeTS = ql.YieldTermStructureHandle(
    ql.FlatForward(
        settlementDate, riskFreeRate, dayCounter))

# 波動率的期限結構
flatVolTS = ql.BlackVolTermStructureHandle(
    ql.BlackConstantVol(
        settlementDate, calendar,
        volatility, dayCounter))

# 構建 BS 過程
bsProcess = ql.BlackScholesProcess(
    s0=underlyingH,
    riskFreeTS=flatRiskFreeTS,
    volTS=flatVolTS)

# 基於 BS 過程的公式定價引擎
pricingEngine = ql.AnalyticEuropeanEngine(
    bsProcess)

europeanOption.setPricingEngine(pricingEngine)

4. 計算

# RESULTS

print("Option value =", europeanOption.NPV())
print("Delta value  =", europeanOption.delta())
print("Theta value  =", europeanOption.theta())
print("Theta perday =", europeanOption.thetaPerDay())
print("Gamma value  =", europeanOption.gamma())
print("Vega value   =", europeanOption.vega())
print("Rho value    =", europeanOption.rho())
Option value = 2.395988448539984
Delta value  = 0.5213970624832108
Theta value  = -4.309457134907618
Theta perday = -0.011806731876459226
Gamma value  = 0.06563585494066533
Vega value   = 12.089225358769994
Rho value    = 8.88039853654583

題外話:天數計算規則

上述例子中的計算結果和書中給出的結果略有出入,依經驗判斷,最有可能造成計算不一致的原因是“天數計算規則的不一致”。

詳細來說,書中期權的期限是 20 周,作者認為 20 周等於 0.3846 年,可能的依據有:

  • \(20 \times 7 / 364(\text{not } 365) \approx 0.3846\) (即 Actual/364)或
  • \(20 \times 5(\text{weekday}) / [52(\approx 365/7)\times 5(\text{weekday})] \approx 0.3846\)

目前,QuantLib 中並不支持這兩種天數計算規則。例子中出現的規則 Actual365Fixed(Actual365Fixed.Standard) 認為 20 周等於 0.38356 年:

print(dayCounter.yearFraction(settlementDate, maturity))
# 0.3835616438356164

對於期權來說,天數計算規則的影響可能微不足道,但是對於固定收益類金融工具及其衍生品來說,天數計算規則的選擇至關重要,“失之毫厘,謬以千里”。

Quote 帶來的便利

QuantLib 中有相當多的組件接受 Handle 類型的參數,而這些參數通常持有一個 Quote 類型的變量。借助“觀察者模式”,用戶修改 Quote 類型變量的值將會自動通知相關組件,並使其重新進行性計算,而無需再次構建一遍計算流程。對於某些用途來講,這帶來了相當大的便利。

# USE QUOTE

stock_array = np.arange(
    start=30, stop=70, step=0.01)

NPV = np.array([np.nan] * len(stock_array))
delta = np.array([np.nan] * len(stock_array))
theta = np.array([np.nan] * len(stock_array))
# thetaPerDay = np.array([np.nan] * len(stock_array))
gamma = np.array([np.nan] * len(stock_array))
vega = np.array([np.nan] * len(stock_array))
rho = np.array([np.nan] * len(stock_array))

for i, v in enumerate(stock_array):
    # 重置 Quote 對象的值
    underlying.setValue(v)

    # 無須再次配置計算流程,直接計算
    NPV[i] = europeanOption.NPV()
    delta[i] = europeanOption.delta()
    theta[i] = europeanOption.theta()
    # thetaPerDay[i] = europeanOption.thetaPerDay()
    gamma[i] = europeanOption.gamma()
    vega[i] = europeanOption.vega()
    rho[i] = europeanOption.rho()

result = pd.DataFrame(
    data=dict(
        NPV=NPV,
        delta=delta,
        theta=theta,
        # thetaPerDay=thetaPerDay,
        gamma=gamma,
        vega=vega, rho=rho),
    index=stock_array)

result.plot(subplots=True)

總結

下面用一副圖顯示上述例子中的若干變量如何匯聚成一個計算流程:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM