期限结构

收益率期限结构

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())

同比通胀曲线

分段零通胀