用 QuantLib 给国债估值

定义固定利率国债
import QuantLib as ql
# 22附息国债19 - 220019.IB
# 债券期限 - 10年
# 债券起息日 - 2022-09-01

# 日历
calendar = ql.China(ql.China.IB)

# T+1 结算
settlementDays = 1

# 面值(元) - 100.00
faceAmount = 100.0

# 债券发行日 - 2022-08-31
issueDate = ql.Date(31, ql.August, 2022)

# 到期兑付日 - 2032-09-01
maturityDate = ql.Date(1, ql.September, 2032)

# 付息频率 - 半年
coupon_period = ql.Period(ql.Semiannual)

# 节假日调整规则
holidayConvention = ql.Unadjusted
terminationDateConvention = ql.Unadjusted
# 日期规则(?)
dateGenRule = ql.DateGeneration.Backward
# 是否月末(?)
endOfMonth = False

schedule = ql.Schedule(
    issueDate,
    maturityDate,
    coupon_period,
    calendar,
    holidayConvention,
    terminationDateConvention,
    dateGenRule,
    endOfMonth)

# print(list(schedule))

# 票面利率(%) - 2.6000
coupons = [2.60 / 100.0]
# 在构造 ActualActual 对象时要附加上债券现金流支付的日期表 schedule 对象)
# 见 https://quant.stackexchange.com/questions/12707/pricing-a-fixedratebond-in-quantlib-yield-vs-termstructure
# ql.ActualActual.Bond/ISMA 差异多大,怎么用?
accrualDayCounter = ql.ActualActual(ql.ActualActual.ISMA, schedule)
paymentConvention = ql.Unadjusted

bond = ql.FixedRateBond(
    settlementDays,
    faceAmount,
    schedule,
    coupons,
    accrualDayCounter,
    paymentConvention)
定义利率曲线
# 可以调整此数值看估值结果有何不同
bondYield = 2.7652 / 100.0

compounding = ql.Compounded
# 试验发现要与coupon period一致
frequency = ql.Semiannual

termStructure = ql.YieldTermStructureHandle(
    ql.FlatForward(
        settlementDays,
        calendar,
        bondYield,
        ql.Thirty360(),  # 这里是一个大坑,参考 https://www.youtube.com/watch?v=dQjd3hAshj4
        compounding,
        frequency))

engine = ql.DiscountingBondEngine(termStructure)
bond.setPricingEngine(engine)

注意利率曲线 day count 用的是 ql.Thirty360(),原因参考这里:QuantLib notebooks: dangerous day count conventions

估值、与上清所估值对比
import prettytable as pt

cleanPrice = bond.cleanPrice()
dirtyPrice = bond.dirtyPrice()
accruedAmount = bond.accruedAmount()

duration = ql.BondFunctions.duration(
    bond,
    bondYield,
    accrualDayCounter,
    compounding,
    frequency)

convexity = ql.BondFunctions.convexity(
    bond,
    bondYield,
    accrualDayCounter,
    compounding,
    frequency)

bps = ql.BondFunctions.basisPointValue(
    bond,
    bondYield,
    accrualDayCounter,
    compounding,
    frequency)

tab = pt.PrettyTable(['item', 'QuantLib', 'ShClearing'])
tab.add_row(['clean price', cleanPrice, 98.5787])
tab.add_row(['dirty price', dirtyPrice, 98.8516])
tab.add_row(['accrued amount', accruedAmount, 0.2729])
tab.add_row(['duration', duration, 8.6352])
tab.add_row(['convexity', convexity, 84.9296])
tab.add_row(['bps', abs(bps), 0.0854])

tab.float_format = '.4'
print(tab)
  • 上清所估值结果
    在这里插入图片描述
比较结果
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值