程式

通過在 Python 中實現 QuantLib,無法使用顯式有限差分法找到亞洲期權的價格

  • September 3, 2020

我正在嘗試使用 QuantLib Python 中的有限差分方法來查找連續幾何平均亞洲期權的價格。我無法這樣做。但是,我可以使用封閉式解決方案找到相同選項的價格。這是程式碼:

import QuantLib as ql
today = ql.Settings.instance().evaluationDate

averageType = ql.Average.Geometric
option_type = ql.Option.Call

strike = 100.0
exerciseDate = ql.TARGET().advance(today, 90, ql.Days)

payoff = ql.PlainVanillaPayoff(option_type, strike)
exercise = ql.EuropeanExercise(exerciseDate)
option = ql.ContinuousAveragingAsianOption(averageType, payoff, exercise)

initialValue = ql.QuoteHandle(ql.SimpleQuote(100))
sigma = 0.3
riskFreeTS = ql.YieldTermStructureHandle(ql.FlatForward(today, 0.03, ql.Actual365Fixed()))
volTS = ql.BlackVolTermStructureHandle(ql.BlackConstantVol(today, ql.NullCalendar(), sigma, ql.Actual365Fixed()))
stochProcess = ql.BlackScholesProcess(initialValue, riskFreeTS, volTS)

engine = ql.AnalyticContinuousGeometricAveragePriceAsianEngine(stochProcess)

option.setPricingEngine(engine)
price = option.NPV()

print(f"Option price: {price}")

任何幫助/建議將不勝感激!!

QuantLib 確實有一個亞洲期權的 FD 定價引擎ql.FdBlackScholesAsianEngine(stochProcess, tGrid=100, xGrid=100, aGrid=50),但我剛剛發現它只為離散的算術收益定價!

如果您每天傳遞諸如 which samples之類的內容,則從 Continuous 到 Discrete(在此處記錄)不會對選項的價格產生太大影響。asianFixingDates = [ql.TARGET().advance(today, x, ql.Days) for x in range(1,91)]當然,這有點不切實際,但我們可以從分析定價器中恢復該限制內的連續價格(當我進行此更改時,我從原始程式碼中得到 4.187 與 4.184)。

不幸的是,在這個選項上執行 FD 定價器會給我這個錯誤:RuntimeError: Arithmetic averaging supported only

轉向算術平均選項確實會顯著影響定價。但是,如果這對您有任何用處,我已在此答案的底部包含對您的程式碼所需的更改(將平均值更改為ql.Average.Arithmetic,並使用離散選項)

作為替代方案,如果您需要數值求解器,您可以考慮ql.MCDiscreteGeometricAPEngine在此處記錄)使用 Monte Carlo 來代替幾何選項定價。您仍然需要為離散平均選項定價,但價格非常接近使用以下方法的分析解決方案:

rng = "lowdiscrepancy" # could use "pseudorandom"
numPaths = 100000

engine = ql.MCDiscreteGeometricAPEngine(stochProcess, rng, requiredSamples=numPaths)

option.setPricingEngine(engine)
price = option.NPV()

print(f"Option price: {price}")

在 QL 中使用 FD 對離散平均算術亞洲進行定價:

import QuantLib as ql
today = ql.Settings.instance().evaluationDate

averageType = ql.Average.Arithmetic
option_type = ql.Option.Call

strike = 100.0
exerciseDate = ql.TARGET().advance(today, 90, ql.Days)

pastFixings = 0 # Empty because this is a new contract
asianFixingDates = [ql.TARGET().advance(today, x, ql.Days) for x in range(1,91)]

payoff = ql.PlainVanillaPayoff(option_type, strike)
exercise = ql.EuropeanExercise(exerciseDate)
option = ql.DiscreteAveragingAsianOption(averageType, 0.0, pastFixings, asianFixingDates, payoff, exercise)

initialValue = ql.QuoteHandle(ql.SimpleQuote(100))
sigma = 0.3
riskFreeTS = ql.YieldTermStructureHandle(ql.FlatForward(today, 0.03, ql.Actual365Fixed()))
volTS = ql.BlackVolTermStructureHandle(ql.BlackConstantVol(today, ql.NullCalendar(), sigma, ql.Actual365Fixed()))
stochProcess = ql.BlackScholesProcess(initialValue, riskFreeTS, volTS)

engine = ql.FdBlackScholesAsianEngine(stochProcess, tGrid=100, xGrid=100, aGrid=50)

option.setPricingEngine(engine)
price = option.NPV()

print(f"Option price: {price}")

引用自:https://quant.stackexchange.com/questions/57751