期限结构
收益率期限结构
FlatForward
平坦利率曲线。
- ql.FlatForward(date, quote, dayCounter, compounding, frequency)
- ql.FlatForward(integer, Calendar, quote, dayCounter, compounding, frequency)
- ql.FlatForward(integer, rate, dayCounter)
示例:
ql.FlatForward(ql.Date(15,6,2020), ql.QuoteHandle(ql.SimpleQuote(0.05)), ql.Actual360(), ql.Compounded, ql.Annual)
ql.FlatForward(ql.Date(15,6,2020), ql.QuoteHandle(ql.SimpleQuote(0.05)), ql.Actual360(), ql.Compounded)
ql.FlatForward(ql.Date(15,6,2020), ql.QuoteHandle(ql.SimpleQuote(0.05)), ql.Actual360())
ql.FlatForward(2, ql.TARGET(), ql.QuoteHandle(ql.SimpleQuote(0.05)), ql.Actual360())
ql.FlatForward(2, ql.TARGET(), 0.05, ql.Actual360())
DiscountCurve
基于贴现因子对数线性插值的期限结构。
- ql.DiscountCurve(dates, dfs, dayCounter, cal=ql.NullCalendar())
示例:
dates = [ql.Date(7,5,2019), ql.Date(7,5,2020), ql.Date(7,5,2021)]
dfs = [1, 0.99, 0.98]
dayCounter = ql.Actual360()
curve = ql.DiscountCurve(dates, dfs, dayCounter)
零息曲线
零息曲线
对数线性零息曲线
三次零息曲线
自然三次零息曲线
对数三次零息曲线
单调三次零息曲线
- ql.ZeroCurve(dates, yields, dayCounter, cal, i, comp, freq)
日期 |
日期序列,即与零利率对应的到期日。注意:第一个日期必须是曲线的基准日期,例如收益率为0.0的日期。 |
收益率 |
一系列浮点数,表示零息债券收益率 |
dayCounter |
DayCounter对象,天数计算规则 |
cal |
日历对象,calendar |
i |
线性对象,线性插值方法 |
comp 和 freq |
是预设整数,表示支付方式和支付频率 |
dates = [ql.Date(31,12,2019), ql.Date(31,12,2020), ql.Date(31,12,2021)]
zeros = [0.01, 0.02, 0.03]
ql.ZeroCurve(dates, zeros, ql.ActualActual(), ql.TARGET())
ql.LogLinearZeroCurve(dates, zeros, ql.ActualActual(), ql.TARGET())
ql.CubicZeroCurve(dates, zeros, ql.ActualActual(), ql.TARGET())
ql.NaturalCubicZeroCurve(dates, zeros, ql.ActualActual(), ql.TARGET())
ql.LogCubicZeroCurve(dates, zeros, ql.ActualActual(), ql.TARGET())
ql.MonotonicCubicZeroCurve(dates, zeros, ql.ActualActual(), ql.TARGET())
ForwardCurve
基于远期利率平坦插值的期限结构。
- ql.ForwardCurve(dates, rates, dayCounter)
- ql.ForwardCurve(dates, rates, dayCounter, calendar, BackwardFlat)
- ql.ForwardCurve(dates, date, rates, rate, dayCounter, calendar)
- ql.ForwardCurve(dates, date, rates, rate, dayCounter)
dates = [ql.Date(15,6,2020), ql.Date(15,6,2022), ql.Date(15,6,2023)]
rates = [0.02, 0.03, 0.04]
ql.ForwardCurve(dates, rates, ql.Actual360(), ql.TARGET())
ql.ForwardCurve(dates, rates, ql.Actual360())
分段
分段收益率期限结构。该期限结构基于一系列利率工具进行自举计算,这些工具以RateHelper实例的向量形式传入。它们的到期日标记了插值区间的边界。
每个分段按从最早到最近的顺序依次确定,选择的标准是使到期日标记该分段末尾的金融工具能在曲线上正确重新定价。
分段对数线性贴现
分段对数三次贴现
分段线性零
分段三次零
分段线性远期
分段样条三次折扣
- ql.Piecewise(referenceDate, helpers, dayCounter)
helpers = []
helpers.append( ql.DepositRateHelper(0.05, ql.Euribor6M()) )
helpers.append(
ql.SwapRateHelper(0.06, ql.EuriborSwapIsdaFixA(ql.Period('1y')))
)
curve = ql.PiecewiseLogLinearDiscount(ql.Date(15,6,2020), helpers, ql.Actual360())
- ql.PiecewiseYieldCurve(referenceDate, instruments, dayCounter, jumps, jumpDate, i=Interpolator(), bootstrap=bootstrap_type())
referenceDate = ql.Date(15,6,2020)
ql.PiecewiseLogLinearDiscount(referenceDate, helpers, ql.ActualActual())
jumps = [ql.QuoteHandle(ql.SimpleQuote(0.01))]
ql.PiecewiseLogLinearDiscount(referenceDate, helpers, ql.ActualActual(), jumps)
jumpDates = [ql.Date(15,9,2020)]
ql.PiecewiseLogLinearDiscount(referenceDate, helpers, ql.ActualActual(), jumps, jumpDates)
import pandas as pd
pgbs = pd.DataFrame(
{'maturity': ['15-06-2020', '15-04-2021', '17-10-2022', '25-10-2023',
'15-02-2024', '15-10-2025', '21-07-2026', '14-04-2027',
'17-10-2028', '15-06-2029', '15-02-2030', '18-04-2034',
'15-04-2037', '15-02-2045'],
'coupon': [4.8, 3.85, 2.2, 4.95, 5.65, 2.875, 2.875, 4.125,
2.125, 1.95, 3.875, 2.25, 4.1, 4.1],
'px': [102.532, 105.839, 107.247, 119.824, 124.005, 116.215, 117.708,
128.027, 115.301, 114.261, 133.621, 119.879, 149.427, 159.177]})
calendar = ql.TARGET()
today = calendar.adjust(ql.Date(19, 12, 2019))
ql.Settings.instance().evaluationDate = today
bondSettlementDays = 2
bondSettlementDate = calendar.advance(
today,
ql.Period(bondSettlementDays, ql.Days))
frequency = ql.Annual
dc = ql.ActualActual(ql.ActualActual.ISMA)
accrualConvention = ql.ModifiedFollowing
convention = ql.ModifiedFollowing
redemption = 100.0
instruments = []
for idx, row in pgbs.iterrows():
maturity = ql.Date(row.maturity, '%d-%m-%Y')
schedule = ql.Schedule(
bondSettlementDate,
maturity,
ql.Period(frequency),
calendar,
accrualConvention,
accrualConvention,
ql.DateGeneration.Backward,
False)
helper = ql.FixedRateBondHelper(
ql.QuoteHandle(ql.SimpleQuote(row.px)),
bondSettlementDays,
100.0,
schedule,
[row.coupon / 100],
dc,
convention,
redemption)
instruments.append(helper)
params = [bondSettlementDate, instruments, dc]
piecewiseMethods = {
'logLinearDiscount': ql.PiecewiseLogLinearDiscount(*params),
'logCubicDiscount': ql.PiecewiseLogCubicDiscount(*params),
'linearZero': ql.PiecewiseLinearZero(*params),
'cubicZero': ql.PiecewiseCubicZero(*params),
'linearForward': ql.PiecewiseLinearForward(*params),
'splineCubicDiscount': ql.PiecewiseSplineCubicDiscount(*params),
}
隐含期限结构
未来给定日期的隐含期限结构
- ql.ImpliedTermStructure(YieldTermStructure, date)
crv = ql.FlatForward(ql.Date(10,1,2020),0.04875825,ql.Actual365Fixed())
yts = ql.YieldTermStructureHandle(crv)
ql.ImpliedTermStructure(yts, ql.Date(20,9,2020))
ForwardSpreadedTermStructure
在瞬时远期利率基础上添加利差的期限结构。
- ql.ForwardSpreadedTermStructure(YieldTermStructure, spread)
crv = ql.FlatForward(ql.Date(10,1,2020),0.04875825,ql.Actual365Fixed())
yts = ql.YieldTermStructureHandle(crv)
spread = ql.QuoteHandle(ql.SimpleQuote(0.005))
ql.ForwardSpreadedTermStructure(yts, spread)
ZeroSpreadedTermStructure
在零收益率基础上添加利差的期限结构
- ql.ZeroSpreadedTermStructure(YieldTermStructure, spread)
crv = ql.FlatForward(ql.Date(10,1,2020),0.04875825,ql.Actual365Fixed())
yts = ql.YieldTermStructureHandle(crv)
spread = ql.QuoteHandle(ql.SimpleQuote(0.005))
ql.ZeroSpreadedTermStructure(yts, spread)
SpreadedLinearZeroInterpolatedTermStructure
- ql.SpreadedLinearZeroInterpolatedTermStructure(YieldTermStructure, quotes, dates, compounding, frequency, dayCounter, linear)
crv = ql.FlatForward(settlement,0.04875825,ql.Actual365Fixed())
yts = ql.YieldTermStructureHandle(crv)
calendar = ql.TARGET()
spread21 = ql.SimpleQuote(0.0050)
spread22 = ql.SimpleQuote(0.0050)
startDate = ql.Date().todaysDate()
endDate = calendar.advance(startDate, ql.Period(50, ql.Years))
tsSpread = ql.SpreadedLinearZeroInterpolatedTermStructure(
yts,
[ql.QuoteHandle(spread21), ql.QuoteHandle(spread22)],
[startDate, endDate]
)
FittedBondCurve
- ql.FittedBondDiscountCurve(bondSettlementDate, helpers, dc, method, accuracy=1.0e-10, maxEvaluations=10000, guess=Array(), simplexLambda=1.0)
方法:
三次B样条拟合
指数样条拟合
NelsonSiegel拟合
简单多项式拟合
Svensson拟合
pgbs = pd.DataFrame(
{'maturity': ['15-06-2020', '15-04-2021', '17-10-2022', '25-10-2023',
'15-02-2024', '15-10-2025', '21-07-2026', '14-04-2027',
'17-10-2028', '15-06-2029', '15-02-2030', '18-04-2034',
'15-04-2037', '15-02-2045'],
'coupon': [4.8, 3.85, 2.2, 4.95, 5.65, 2.875, 2.875, 4.125,
2.125, 1.95, 3.875, 2.25, 4.1, 4.1],
'px': [102.532, 105.839, 107.247, 119.824, 124.005, 116.215, 117.708,
128.027, 115.301, 114.261, 133.621, 119.879, 149.427, 159.177]})
calendar = ql.TARGET()
today = calendar.adjust(ql.Date(19, 12, 2019))
ql.Settings.instance().evaluationDate = today
bondSettlementDays = 2
bondSettlementDate = calendar.advance(
today,
ql.Period(bondSettlementDays, ql.Days))
frequency = ql.Annual
dc = ql.ActualActual(ql.ActualActual.ISMA)
accrualConvention = ql.ModifiedFollowing
convention = ql.ModifiedFollowing
redemption = 100.0
instruments = []
for idx, row in pgbs.iterrows():
maturity = ql.Date(row.maturity, '%d-%m-%Y')
schedule = ql.Schedule(
bondSettlementDate,
maturity,
ql.Period(frequency),
calendar,
accrualConvention,
accrualConvention,
ql.DateGeneration.Backward,
False)
helper = ql.FixedRateBondHelper(
ql.QuoteHandle(ql.SimpleQuote(row.px)),
bondSettlementDays,
100.0,
schedule,
[row.coupon / 100],
dc,
convention,
redemption)
instruments.append(helper)
params = [bondSettlementDate, instruments, dc]
cubicNots = [-30.0, -20.0, 0.0, 5.0, 10.0, 15.0,20.0, 25.0, 30.0, 40.0, 50.0]
fittingMethods = {
'NelsonSiegelFitting': ql.NelsonSiegelFitting(),
'SvenssonFitting': ql.SvenssonFitting(),
'SimplePolynomialFitting': ql.SimplePolynomialFitting(2),
'ExponentialSplinesFitting': ql.ExponentialSplinesFitting(),
'CubicBSplinesFitting': ql.CubicBSplinesFitting(cubicNots),
}
fittedBondCurveMethods = {
label: ql.FittedBondDiscountCurve(*params, method)
for label, method in fittingMethods.items()
}
curve = fittedBondCurveMethods.get('NelsonSiegelFitting')
FX隐含曲线
波动率
BlackConstantVol
- ql.BlackConstantVol(date, calendar, volatility, dayCounter)
- ql.BlackConstantVol(date, calendar, volatilityHandle, dayCounter)
- ql.BlackConstantVol(days, calendar, volatility, dayCounter)
- ql.BlackConstantVol(days, calendar, volatilityHandle, dayCounter)
date = ql.Date().todaysDate()
settlementDays = 2
calendar = ql.TARGET()
volatility = 0.2
volHandle = ql.QuoteHandle(ql.SimpleQuote(volatility))
dayCounter = ql.Actual360()
ql.BlackConstantVol(date, calendar, volatility, dayCounter)
ql.BlackConstantVol(date, calendar, volHandle, dayCounter)
ql.BlackConstantVol(settlementDays, calendar, volatility, dayCounter)
ql.BlackConstantVol(settlementDays, calendar, volHandle, dayCounter)
BlackVarianceCurve
- ql.BlackVarianceCurve(referenceDate, expirations, volatilities, dayCounter)
referenceDate = ql.Date(30, 9, 2013)
expirations = [ql.Date(20, 12, 2013), ql.Date(17, 1, 2014), ql.Date(21, 3, 2014)]
volatilities = [.145, .156, .165]
volatilityCurve = ql.BlackVarianceCurve(referenceDate, expirations, volatilities, ql.Actual360())
BlackVarianceSurface
- ql.BlackVarianceSurface(referenceDate, calendar, expirations, strikes, volMatrix, dayCounter)
referenceDate = ql.Date(30, 9, 2013)
ql.Settings.instance().evaluationDate = referenceDate;
calendar = ql.TARGET()
dayCounter = ql.ActualActual()
strikes = [1650.0, 1660.0, 1670.0]
expirations = [ql.Date(20, 12, 2013), ql.Date(17, 1, 2014), ql.Date(21, 3, 2014)]
volMatrix = ql.Matrix(len(strikes), len(expirations))
#1650 - Dec, Jan, Mar
volMatrix[0][0] = .15640; volMatrix[0][1] = .15433; volMatrix[0][2] = .16079;
#1660 - Dec, Jan, Mar
volMatrix[1][0] = .15343; volMatrix[1][1] = .15240; volMatrix[1][2] = .15804;
#1670 - Dec, Jan, Mar
volMatrix[2][0] = .15128; volMatrix[2][1] = .14888; volMatrix[2][2] = .15512;
volatilitySurface = ql.BlackVarianceSurface(
referenceDate,
calendar,
expirations,
strikes,
volMatrix,
dayCounter
)
volatilitySurface.enableExtrapolation()
HestonBlackVolSurface
- ql.HestonBlackVolSurface(hestonModelHandle)
flatTs = ql.YieldTermStructureHandle(
ql.FlatForward(ql.Date().todaysDate(), 0.05, ql.Actual365Fixed())
)
dividendTs = ql.YieldTermStructureHandle(
ql.FlatForward(ql.Date().todaysDate(), 0.02, ql.Actual365Fixed())
)
v0 = 0.01; kappa = 0.01; theta = 0.01; rho = 0.0; sigma = 0.01
spot = 100
process = ql.HestonProcess(flatTs, dividendTs,
ql.QuoteHandle(ql.SimpleQuote(spot)),
v0, kappa, theta, sigma, rho
)
hestonModel = ql.HestonModel(process)
hestonHandle = ql.HestonModelHandle(hestonModel)
hestonVolSurface = ql.HestonBlackVolSurface(hestonHandle)
AndreasenHuge波动率适配器
实现了"Andreasen J., Huge B., 2010. Volatility Interpolation"(https://ssrn.com/abstract=1694972)中描述的无套利Andreasen-Huge波动率插值方法。该方法的优势在于能够处理非矩形网格的期权报价数据。
- ql.AndreasenHugeVolatilityAdapter(AndreasenHugeVolatilityInterpl)
today = ql.Date().todaysDate()
calendar = ql.NullCalendar()
dayCounter = ql.Actual365Fixed()
spot = 100
r, q = 0.02, 0.05
spotQuote = ql.QuoteHandle(ql.SimpleQuote(spot))
ratesTs = ql.YieldTermStructureHandle(ql.FlatForward(today, r, dayCounter))
dividendTs = ql.YieldTermStructureHandle(ql.FlatForward(today, q, dayCounter))
# Market options price quotes
optionStrikes = [95, 97.5, 100, 102.5, 105, 90, 95, 100, 105, 110, 80, 90, 100, 110, 120]
optionMaturities = ["3M", "3M", "3M", "3M", "3M", "6M", "6M", "6M", "6M", "6M", "1Y", "1Y", "1Y", "1Y", "1Y"]
optionQuotedVols = [0.11, 0.105, 0.1, 0.095, 0.095, 0.12, 0.11, 0.105, 0.1, 0.105, 0.12, 0.115, 0.11, 0.11, 0.115]
calibrationSet = ql.CalibrationSet()
for strike, expiry, impliedVol in zip(optionStrikes, optionMaturities, optionQuotedVols):
payoff = ql.PlainVanillaPayoff(ql.Option.Call, strike)
exercise = ql.EuropeanExercise(calendar.advance(today, ql.Period(expiry)))
calibrationSet.push_back((ql.VanillaOption(payoff, exercise), ql.SimpleQuote(impliedVol)))
ahInterpolation = ql.AndreasenHugeVolatilityInterpl(calibrationSet, spotQuote, ratesTs, dividendTs)
ahSurface = ql.AndreasenHugeVolatilityAdapter(ahInterpolation)
BlackVolTermStructureHandle
- ql.BlackVolTermStructureHandle(blackVolTermStructure)
ql.BlackVolTermStructureHandle(constantVol)
ql.BlackVolTermStructureHandle(volatilityCurve)
ql.BlackVolTermStructureHandle(volatilitySurface)
可重链接Black波动率期限结构句柄
- ql.RelinkableBlackVolTermStructureHandle()
- ql.RelinkableBlackVolTermStructureHandle(blackVolTermStructure)
blackTSHandle = ql.RelinkableBlackVolTermStructureHandle(volatilitySurface)
blackTSHandle = ql.RelinkableBlackVolTermStructureHandle()
blackTSHandle.linkTo(volatilitySurface)
LocalConstantVol
- ql.LocalConstantVol(date, volatility, dayCounter)
date = ql.Date().todaysDate()
volatility = 0.2
dayCounter = ql.Actual360()
ql.LocalConstantVol(date, volatility, dayCounter)
LocalVolSurface
- ql.LocalVolSurface(blackVolTs, ratesTs, dividendsTs, spot)
today = ql.Date().todaysDate()
calendar = ql.NullCalendar()
dayCounter = ql.Actual365Fixed()
volatility = 0.2
r, q = 0.02, 0.05
blackVolTs = ql.BlackVolTermStructureHandle(ql.BlackConstantVol(today, calendar, volatility, dayCounter))
ratesTs = ql.YieldTermStructureHandle(ql.FlatForward(today, r, dayCounter))
dividendTs = ql.YieldTermStructureHandle(ql.FlatForward(today, q, dayCounter))
spot = 100
ql.LocalVolSurface(blackVolTs, ratesTs, dividendTs, spot)
NoExceptLocalVolSurface
这个功能强大但危险的曲面会吞没所有异常,并在异常发生时返回指定的覆盖值。如果您的波动率曲面校准良好,它可以保护您免受由于局部波动率曲面上非常远的不流动点导致的崩溃。但如果您的波动率曲面质量不佳,它可能会掩盖真正的错误。建议谨慎使用。
- ql.NoExceptLocalVolSurface(blackVolTs, ratesTs, dividendsTs, spot, illegalVolOverride)
today = ql.Date().todaysDate()
calendar = ql.NullCalendar()
dayCounter = ql.Actual365Fixed()
r, q = 0.02, 0.05
volatility = 0.2
illegalVolOverride = 0.25
blackVolTs = ql.BlackVolTermStructureHandle(ql.BlackConstantVol(today, calendar, volatility, dayCounter))
ratesTs = ql.YieldTermStructureHandle(ql.FlatForward(today, r, dayCounter))
dividendTs = ql.YieldTermStructureHandle(ql.FlatForward(today, q, dayCounter))
spot = 100
ql.NoExceptLocalVolSurface(blackVolTs, ratesTs, dividendTs, spot, illegalVolOverride)
AndreasenHugeLocalVolAdapter
- ql.AndreasenHugeLocalVolAdapter(AndreasenHugeVolatilityInterpl)
today = ql.Date().todaysDate()
calendar = ql.NullCalendar()
dayCounter = ql.Actual365Fixed()
spot = 100
r, q = 0.02, 0.05
spotQuote = ql.QuoteHandle(ql.SimpleQuote(spot))
ratesTs = ql.YieldTermStructureHandle(ql.FlatForward(today, r, dayCounter))
dividendTs = ql.YieldTermStructureHandle(ql.FlatForward(today, q, dayCounter))
# Market options price quotes
optionStrikes = [95, 97.5, 100, 102.5, 105, 90, 95, 100, 105, 110, 80, 90, 100, 110, 120]
optionMaturities = ["3M", "3M", "3M", "3M", "3M", "6M", "6M", "6M", "6M", "6M", "1Y", "1Y", "1Y", "1Y", "1Y"]
optionQuotedVols = [0.11, 0.105, 0.1, 0.095, 0.095, 0.12, 0.11, 0.105, 0.1, 0.105, 0.12, 0.115, 0.11, 0.11, 0.115]
calibrationSet = ql.CalibrationSet()
for strike, expiry, impliedVol in zip(optionStrikes, optionMaturities, optionQuotedVols):
payoff = ql.PlainVanillaPayoff(ql.Option.Call, strike)
exercise = ql.EuropeanExercise(calendar.advance(today, ql.Period(expiry)))
calibrationSet.push_back((ql.VanillaOption(payoff, exercise), ql.SimpleQuote(impliedVol)))
ahInterpolation = ql.AndreasenHugeVolatilityInterpl(calibrationSet, spotQuote, ratesTs, dividendTs)
ahLocalSurface = ql.AndreasenHugeLocalVolAdapter(ahInterpolation)
LocalVolTermStructureHandle
利率上限波动率
ConstantOptionletVolatility
浮动参考日期,浮动市场数据
- ql.ConstantOptionletVolatility(settlementDays, cal, bdc, volatility (Quote), dc, type=ShiftedLognormal, displacement=0.0)
固定参考日期,浮动市场数据
- ql.ConstantOptionletVolatility(settlementDate, cal, bdc, volatility (Quote), dc, type=ShiftedLognormal, displacement=0.0)
浮动参考日期,固定市场数据
- ql.ConstantOptionletVolatility(settlementDays, cal, bdc, volatility (value), dc, type=ShiftedLognormal, displacement=0.0)
固定参考日期,固定市场数据
- ql.ConstantOptionletVolatility(settlementDate, cal, bdc, volatility (value), dc, type=ShiftedLognormal, displacement=0.0)
settlementDays = 2
settlementDate = ql.Date().todaysDate()
cal = ql.TARGET()
bdc = ql.ModifiedFollowing
volatility = 0.55
vol_quote = ql.QuoteHandle(ql.SimpleQuote(volatility))
dc = ql.Actual365Fixed()
#floating reference date, floating market data
c1 = ql.ConstantOptionletVolatility(settlementDays, cal, bdc, vol_quote, dc, ql.Normal)
#fixed reference date, floating market data
c2 = ql.ConstantOptionletVolatility(settlementDate, cal, bdc, vol_quote, dc)
#floating reference date, fixed market data
c3 = ql.ConstantOptionletVolatility(settlementDays, cal, bdc, volatility, dc)
#fixed reference date, fixed market data
c4 = ql.ConstantOptionletVolatility(settlementDate, cal, bdc, volatility, dc)
CapFloorTermVolCurve
平价利率上限/下限的期限波动率向量。
浮动参考日期,浮动市场数据
- ql.CapFloorTermVolCurve(settlementDays, calendar, bdc, optionTenors, vols (Quotes), dc=Actual365Fixed)
固定参考日期,浮动市场数据
- ql.CapFloorTermVolCurve(settlementDate, calendar, bdc, optionTenors, vols (Quotes), dc=Actual365Fixed)
固定参考日期,固定市场数据
- ql.CapFloorTermVolCurve(settlementDate, calendar, bdc, optionTenors, vols (vector), dc=Actual365Fixed)
浮动参考日期,固定市场数据
- ql.CapFloorTermVolCurve(settlementDays, calendar, bdc, optionTenors, vols (vector), dc=Actual365Fixed)
settlementDate = ql.Date().todaysDate()
settlementDays = 2
calendar = ql.TARGET()
bdc = ql.ModifiedFollowing
optionTenors = [ql.Period('1y'), ql.Period('2y'), ql.Period('3y')]
vols = [0.55, 0.60, 0.65]
# fixed reference date, fixed market data
c3 = ql.CapFloorTermVolCurve(settlementDate, calendar, bdc, optionTenors, vols)
# floating reference date, fixed market data
c4 = ql.CapFloorTermVolCurve(settlementDays, calendar, bdc, optionTenors, vols)
CapFloorTermVolSurface
浮动参考日期,浮动市场数据
- ql.CapFloorTermVolSurface(settlementDays, calendar, bdc, expiries, strikes, vol_data (Handle), daycount=ql.Actual365Fixed)
固定参考日期,浮动市场数据
- ql.CapFloorTermVolSurface(settlementDate, calendar, bdc, expiries, strikes, vol_data (Handle), daycount=ql.Actual365Fixed)
固定参考日期,固定市场数据
- ql.CapFloorTermVolSurface(settlementDate, calendar, bdc, expiries, strikes, vol_data (Matrix), daycount=ql.Actual365Fixed)
浮动参考日期,固定市场数据
- ql.CapFloorTermVolSurface(settlementDays, calendar, bdc, expiries, strikes, vol_data (Matrix), daycount=ql.Actual365Fixed)
settlementDate = ql.Date().todaysDate()
settlementDays = 2
calendar = ql.TARGET()
bdc = ql.ModifiedFollowing
expiries = [ql.Period('9y'), ql.Period('10y'), ql.Period('12y')]
strikes = [0.015, 0.02, 0.025]
black_vols = [
[1. , 0.792 , 0.6873],
[0.9301, 0.7401, 0.6403],
[0.7926, 0.6424, 0.5602]]
# fixed reference date, fixed market data
s3 = ql.CapFloorTermVolSurface(settlementDate, calendar, bdc, expiries, strikes, black_vols)
# floating reference date, fixed market data
s4 = ql.CapFloorTermVolSurface(settlementDays, calendar, bdc, expiries, strikes, black_vols)
OptionletStripper1
- ql.OptionletStripper1(CapFloorTermVolSurface, index, switchStrikes=Null, accuracy=1.0e-6, maxIter=100, discount=YieldTermStructure, type=ShiftedLognormal, displacement=0.0, dontThrow=false)
index = ql.Euribor6M()
optionlet_surf = ql.OptionletStripper1(s3, index, type=ql.Normal)
StrippedOptionletAdapter
- ql.StrippedOptionletAdapter(StrippedOptionletBase)
Optionlet波动率结构句柄
- ql.OptionletVolatilityStructureHandle(OptionletVolatilityStructure)
ovs_handle = ql.OptionletVolatilityStructureHandle(
ql.StrippedOptionletAdapter(optionlet_surf)
)
可重新链接的Optionlet波动率结构句柄
- ql.RelinkableOptionletVolatilityStructureHandle()
ovs_handle = ql.RelinkableOptionletVolatilityStructureHandle()
ovs_handle.linkTo(ql.StrippedOptionletAdapter(optionlet_surf))
掉期期权波动率
恒定互换期权波动率
恒定的互换期权波动率,无时间-行权价依赖性。
浮动参考日期,浮动市场数据
- ql.ConstantSwaptionVolatility(settlementDays, cal, bdc, volatility, dc, type=ql.ShiftedLognormal, shift=0.0)
固定参考日期,浮动市场数据
- ql.ConstantSwaptionVolatility(settlementDate, cal, bdc, volatility, dc, type=ql.ShiftedLognormal, shift=0.0)
浮动参考日期,固定市场数据
- ql.ConstantSwaptionVolatility(settlementDays, cal, bdc, volatilityQuote, dc, type=ql.ShiftedLognormal, shift=0.0)
固定参考日期,固定市场数据
- ql.ConstantSwaptionVolatility(settlementDate, cal, bdc, volatilityQuote, dc, type=ql.ShiftedLognormal, shift=0.0)
constantSwaptionVol = ql.ConstantSwaptionVolatility(2, ql.TARGET(), ql.ModifiedFollowing, ql.QuoteHandle(ql.SimpleQuote(0.55)), ql.ActualActual())
Swaption波动率矩阵
平价掉期期权波动率矩阵。
浮动参考日期,浮动市场数据
- ql.SwaptionVolatilityMatrix(calendar, bdc, optionTenors, swapTenors, vols (Handles), dayCounter, flatExtrapolation=false, type=ShiftedLognormal, shifts (vector))
固定参考日期,浮动市场数据
- ql.SwaptionVolatilityMatrix(referenceDate, calendar, bdc, optionTenors, swapTenors, vols (Handles), dayCounter, flatExtrapolation=false, type=ShiftedLognormal, shifts (vector))
浮动参考日期,固定市场数据
- ql.SwaptionVolatilityMatrix(calendar, bdc, optionTenors, swapTenors, vols (matrix), dayCounter, flatExtrapolation=false, type=ShiftedLognormal, shifts (matrix))
固定参考日期,固定市场数据
- ql.SwaptionVolatilityMatrix(referenceDate, calendar, bdc, optionTenors, swapTenors, vols (matrix), dayCounter, flatExtrapolation=false, type=ShiftedLognormal, shifts (matrix))
固定参考日期和固定市场数据,期权日期
- ql.SwaptionVolatilityMatrix(referenceDate, calendar, bdc, optionDates, swapTenors, vols (matrix), dayCounter, flatExtrapolation=false, type=ShiftedLognormal, shifts (matrix))
# market Data 07.01.2020
swapTenors = [
'1Y', '2Y', '3Y', '4Y', '5Y',
'6Y', '7Y', '8Y', '9Y', '10Y',
'15Y', '20Y', '25Y', '30Y']
optionTenors = [
'1M', '2M', '3M', '6M', '9M', '1Y',
'18M', '2Y', '3Y', '4Y', '5Y', '7Y',
'10Y', '15Y', '20Y', '25Y', '30Y']
normal_vols = [
[8.6, 12.8, 19.5, 26.9, 32.7, 36.1, 38.7, 40.9, 42.7, 44.3, 48.8, 50.4, 50.8, 50.4],
[9.2, 13.4, 19.7, 26.4, 31.9, 35.2, 38.3, 40.2, 41.9, 43.1, 47.8, 49.9, 50.7, 50.3],
[11.2, 15.3, 21.0, 27.6, 32.7, 35.3, 38.4, 40.8, 42.6, 44.5, 48.6, 50.5, 50.9, 51.0],
[12.9, 17.1, 22.6, 28.8, 33.5, 36.0, 38.8, 41.0, 43.0, 44.6, 48.7, 50.6, 51.1, 51.0],
[14.6, 18.7, 24.6, 30.1, 34.2, 36.9, 39.3, 41.3, 43.2, 44.9, 48.9, 51.0, 51.3, 51.5],
[16.5, 20.9, 26.3, 31.3, 35.0, 37.6, 40.0, 42.0, 43.7, 45.3, 48.8, 50.9, 51.4, 51.7],
[20.9, 25.3, 30.0, 34.0, 37.0, 39.5, 41.9, 43.4, 45.0, 46.4, 49.3, 51.0, 51.3, 51.9],
[25.1, 28.9, 33.2, 36.2, 39.2, 41.2, 43.2, 44.7, 46.0, 47.3, 49.6, 51.0, 51.3, 51.6],
[34.0, 36.6, 39.2, 41.1, 43.2, 44.5, 46.1, 47.2, 48.0, 49.0, 50.3, 51.3, 51.3, 51.2],
[40.3, 41.8, 43.6, 44.9, 46.1, 47.1, 48.2, 49.2, 49.9, 50.5, 51.2, 51.3, 50.9, 50.7],
[44.0, 44.8, 46.0, 47.1, 48.4, 49.1, 49.9, 50.7, 51.4, 51.9, 51.6, 51.4, 50.6, 50.2],
[49.6, 49.7, 50.4, 51.2, 51.8, 52.2, 52.6, 52.9, 53.3, 53.8, 52.6, 51.7, 50.4, 49.6],
[53.9, 53.7, 54.0, 54.2, 54.4, 54.5, 54.5, 54.4, 54.4, 54.9, 53.1, 51.8, 50.1, 49.1],
[54.0, 53.7, 53.8, 53.7, 53.5, 53.6, 53.5, 53.3, 53.5, 53.7, 51.4, 49.8, 47.9, 46.6],
[52.8, 52.4, 52.6, 52.3, 52.2, 52.3, 52.0, 51.9, 51.8, 51.8, 49.5, 47.4, 45.4, 43.8],
[51.4, 51.2, 51.3, 51.0, 50.8, 50.7, 50.3, 49.9, 49.8, 49.7, 47.6, 45.3, 43.1, 41.4],
[49.6, 49.6, 49.7, 49.5, 49.5, 49.2, 48.6, 47.9, 47.4, 47.1, 45.1, 42.9, 40.8, 39.2]
]
swapTenors = [ql.Period(tenor) for tenor in swapTenors]
optionTenors = [ql.Period(tenor) for tenor in optionTenors]
normal_vols = [[vol / 10000 for vol in row] for row in normal_vols]
calendar = ql.TARGET()
bdc = ql.ModifiedFollowing
dayCounter = ql.ActualActual()
swaptionVolMatrix = ql.SwaptionVolatilityMatrix(
calendar, bdc,
optionTenors, swapTenors, ql.Matrix(normal_vols),
dayCounter, False, ql.Normal)
SwaptionVolCube1
SwaptionVolCube2
- ql.SwaptionVolCube2(atmVolStructure, optionTenors, swapTenors, strikeSpreads, volSpreads, swapIndex, shortSwapIndex, vegaWeightedSmileFit)
optionTenors = ['1y', '2y', '3y']
swapTenors = [ '5Y', '10Y']
strikeSpreads = [ -0.01, 0.0, 0.01]
volSpreads = [
[0.5, 0.55, 0.6],
[0.5, 0.55, 0.6],
[0.5, 0.55, 0.6],
[0.5, 0.55, 0.6],
[0.5, 0.55, 0.6],
[0.5, 0.55, 0.6],
]
optionTenors = [ql.Period(tenor) for tenor in optionTenors]
swapTenors = [ql.Period(tenor) for tenor in swapTenors]
volSpreads = [[ql.QuoteHandle(ql.SimpleQuote(v)) for v in row] for row in volSpreads]
swapIndexBase = ql.EuriborSwapIsdaFixA(ql.Period(1, ql.Years), e6m_yts, ois_yts)
shortSwapIndexBase = ql.EuriborSwapIsdaFixA(ql.Period(1, ql.Years), e6m_yts, ois_yts)
vegaWeightedSmileFit = False
volCube = ql.SwaptionVolatilityStructureHandle(
ql.SwaptionVolCube2(
ql.SwaptionVolatilityStructureHandle(swaptionVolMatrix),
optionTenors,
swapTenors,
strikeSpreads,
volSpreads,
swapIndexBase,
shortSwapIndexBase,
vegaWeightedSmileFit)
)
volCube.enableExtrapolation()
Swaption波动率结构句柄
- ql.SwaptionVolatilityStructureHandle(swaptionVolStructure)
swaptionVolHandle = ql.SwaptionVolatilityStructureHandle(swaptionVolMatrix)
可重链接的掉期期权波动率结构句柄
- ql.RelinkableSwaptionVolatilityStructureHandle()
handle = ql.RelinkableSwaptionVolatilityStructureHandle()
handle.linkTo(swaptionVolMatrix)
SABR
SabrSmileSection
- ql.SabrSmileSection(date, fwd, [alpha, beta, nu, rho, ]dayCounter, Real)
- ql.SabrSmileSection(time, fwd, [alpha, beta, nu, rho, ]dayCounter, Real)
alpha = 1.63
beta = 0.6
nu = 3.3
rho = 0.00002
ql.SabrSmileSection(17/365, 120, [alpha, beta, nu, rho])
sabr波动率
- ql.sabrVolatility(strike, forward, expiryTime, alpha, beta, nu, rho)
alpha = 1.63
beta = 0.6
nu = 3.3
rho = 0.00002
ql.sabrVolatility(106, 120, 17/365, alpha, beta, nu, rho)
shiftedSabrVolatility
- ql.shiftedSabrVolatility(strike, forward, expiryTime, alpha, beta, nu, rho, shift)
alpha = 1.63
beta = 0.6
nu = 3.3
rho = 0.00002
shift = 50
ql.shiftedSabrVolatility(106, 120, 17/365, alpha, beta, nu, rho, shift)
sabrFlochKennedy波动率
- ql.sabrFlochKennedyVolatility(strike, forward, expiryTime, alpha, beta, nu, rho)
alpha = 0.01
beta = 0.01
nu = 0.01
rho = 0.01
ql.sabrFlochKennedyVolatility(0.01,0.01, 5, alpha, beta, nu, rho)
信用期限结构
FlatHazardRate
平坦的违约率曲线。
- ql.FlatHazardRate(settlementDays, calendar, Quote, dayCounter)
- ql.FlatHazardRate(settelementDate, Quote, dayCounter)
pd_curve = ql.FlatHazardRate(2, ql.TARGET(), ql.QuoteHandle(ql.SimpleQuote(0.05)), ql.Actual360())
pd_curve = ql.FlatHazardRate(ql.Date().todaysDate(), ql.QuoteHandle(ql.SimpleQuote(0.05)), ql.Actual360())
分段平坦风险率
分段违约概率期限结构。
- ql.PiecewiseFlatHazardRate(settlementDate, helpers, dayCounter)
recoveryRate = 0.4
settlementDate = ql.Date().todaysDate()
yts = ql.FlatForward(2, ql.TARGET(), 0.05, ql.Actual360())
CDS_tenors = [ql.Period(6, ql.Months), ql.Period(1, ql.Years), ql.Period(2, ql.Years), ql.Period(3, ql.Years), \
ql.Period(4, ql.Years), ql.Period(5, ql.Years), ql.Period(7, ql.Years), ql.Period(10, ql.Years), ql.Period(50, ql.Years)]
CDS_ctpy = [26.65, 37.22, 53.17, 65.79, 77.39, 91.14, 116.84, 136.67, 136.67]
CDSHelpers_ctpy = [ql.SpreadCdsHelper((CDS_spread / 10000.0), CDS_tenor, 0, ql.TARGET(), ql.Quarterly, ql.Following, \
ql.DateGeneration.TwentiethIMM, ql.Actual360(), recoveryRate, ql.YieldTermStructureHandle(yts))
for CDS_spread, CDS_tenor in zip(CDS_ctpy, CDS_tenors)]
pd_curve = ql.PiecewiseFlatHazardRate(settlementDate, CDSHelpers_ctpy, ql.Thirty360())
生存概率曲线
- ql.SurvivalProbabilityCurve(dates, survivalProbabilities, dayCounter, calendar)
today = ql.Date().todaysDate()
dates = [today + ql.Period(n , ql.Years) for n in range(11)]
sp = [1.0, 0.9941, 0.9826, 0.9674, 0.9488, 0.9246, 0.8945, 0.8645, 0.83484, 0.80614, 0.7784]
crv = ql.SurvivalProbabilityCurve(dates, sp, ql.Actual360(), ql.TARGET())
crv.enableExtrapolation()
通胀期限结构
零通胀曲线
- ql.PiecewiseZeroInflation(referenceDate, calendar, dayCounter, observationLag, frequency, bool indexIsInterpolated, baseZeroRate, nominalTS, helpers, accuracy=1.0e-12, interpolator=ql.Linear())