如果未做特別說明,文中的程序都是 Python3 代碼。
QuantLib 金融計算——隨機過程之一般 Black Scholes 過程
載入模塊
import QuantLib as ql
import pandas as pd
import numpy as np
import seaborn as sn
print(ql.__version__)
1.12
一般 Black Scholes 過程
quantlib-python 中 Black Scholes 框架下常見的幾種隨機過程均派生自基類 GeneralizedBlackScholesProcess
,而 GeneralizedBlackScholesProcess
模擬下列 SDE 描述的一維隨機過程:
\[d \ln S_t = \left( r ( t ) - q ( t ) - \frac { \sigma \left( t , S_t \right)^2 } 2 \right) d t + \sigma d W_t \]
等式使用風險中性漂移而不是一般漂移 \(\mu\)。風險中性利率由股息率 \(q(t)\) 調整,並且相應的擴散項是 \(\sigma\)。
作為基類,GeneralizedBlackScholesProcess
的構造函數為
GeneralizedBlackScholesProcess(x0,
dividendTS,
riskFreeTS,
blackVolTS)
其中:
x0
:QuoteHandle
對象,表示 SDE 的起始值;dividendTS
:YieldTermStructureHandle
對象,表示股息率的期限結構riskFreeTS
:YieldTermStructureHandle
對象,表示無風險利率的期限結構blackVolTS
:BlackVolTermStructureHandle
對象,表示波動率的期限結構
GeneralizedBlackScholesProcess
提供了相應的檢查器,返回構造函數接受的關鍵參數:
stateVariable
;dividendYield
;riskFreeRate
;blackVolatility
從 StochasticProcess1D
繼承來的離散化函數 evolve
,描述 SDE 從 \(t\) 到 \(t + \Delta t\) 的變化。
QuantLib 提供了一些具體的派生類,這些類代表眾所周知的具體過程,如
BlackScholesProcess
:沒有股息率的一般 BS 過程;BlackScholesMertonProcess
:一般 BS 過程;BlackProcess
:一般 Black 過程;GarmanKohlagenProcess
:包含外匯利率的一般 BS 過程
這些派生類在構造和調用方式上大同小異,在下面的例子中,我們將建立一個具有平坦無風險利率、股息率和波動率期限結構的 Black-Scholes-Merton 過程,並畫出模擬結果。
def testingStochasticProcesses1():
refDate = ql.Date(27, ql.January, 2019)
riskFreeRate = 0.0321
dividendRate = 0.0128
spot = 52.0
vol = 0.2144
cal = ql.China()
dc = ql.ActualActual()
rdHandle = ql.YieldTermStructureHandle(
ql.FlatForward(refDate, riskFreeRate, dc))
rqHandle = ql.YieldTermStructureHandle(
ql.FlatForward(refDate, dividendRate, dc))
spotQuote = ql.SimpleQuote(spot)
spotHandle = ql.QuoteHandle(
ql.SimpleQuote(spot))
volHandle = ql.BlackVolTermStructureHandle(
ql.BlackConstantVol(refDate, cal, vol, dc))
bsmProcess = ql.BlackScholesMertonProcess(
spotHandle, rqHandle, rdHandle, volHandle)
seed = 1234
unifMt = ql.MersenneTwisterUniformRng(seed)
bmGauss = ql.BoxMullerMersenneTwisterGaussianRng(unifMt)
dt = 0.004
numVals = 250
bsm = pd.DataFrame()
for i in range(10):
bsmt = pd.DataFrame(
dict(
t=np.linspace(0, dt * numVals, numVals + 1),
path=np.nan,
n='p' + str(i)))
bsmt.loc[0, 'path'] = spotQuote.value()
x = spotQuote.value()
for j in range(1, numVals + 1):
dw = bmGauss.next().value()
x = bsmProcess.evolve(bsmt.loc[j, 't'], x, dt, dw)
bsmt.loc[j, 'path'] = x
bsm = pd.concat([bsm, bsmt])
sn.lineplot(
x='t', y='path',
data=bsm,
hue='n', legend=None)
testingStochasticProcesses1()