Swap Curve Construction

来源:https://uqer.io/community/share/55c2d440f9f06c91fc18c648

在这个示例中,我们将指导用户如何使用平台的功能,完成从利率互换的市场报价完成收益率曲线的构造。

  1. from CAL.PyCAL import *
  2. SetEvaluationDate(Date(2015, 8, 6))

1. 构造收益率曲线

我们从一组市场标准化互换的市场报价中获取收益率曲线的信息:

  • swap_rates:标准互换对应的固定端利率
  • swap_tenor:标准互换对应的期限
  1. swap_rates = [0.02, 0.03, 0.04 ,0.05, 0.055, 0.06, 0.065, 0.07]
  2. swap_tenor = ['6M', '1Y', '2Y', '3Y', '4Y', '5Y', '7Y', '10Y']
  3. shiborIndex = Shibor('3M')
  4. instruments = []
  5. for rate, tenor in zip(swap_rates, swap_tenor):
  6. print('{0:3s} benchmark Shibor Swap fixed at: {1:.2f}%'.format(tenor, rate*100))
  7. rateHelper = ShiborSwapRateHelper(rate, Period(tenor), Frequency.Quarterly, shiborIndex)
  8. instruments.append(rateHelper)
  9. 6M benchmark Shibor Swap fixed at: 2.00%
  10. 1Y benchmark Shibor Swap fixed at: 3.00%
  11. 2Y benchmark Shibor Swap fixed at: 4.00%
  12. 3Y benchmark Shibor Swap fixed at: 5.00%
  13. 4Y benchmark Shibor Swap fixed at: 5.50%
  14. 5Y benchmark Shibor Swap fixed at: 6.00%
  15. 7Y benchmark Shibor Swap fixed at: 6.50%
  16. 10Y benchmark Shibor Swap fixed at: 7.00%

通过标准互换校正(calibration)收益率曲线:

  1. calibratedCurve = CalibratedYieldCurve(EvaluationDate(), instruments, 'Actual/365 (Fixed)')

收益率曲线的基本信息:

  • discount:折现因子
  • forward(%):远期利率
  • zero(%):零息利率
  1. calibratedCurve.curveProfile().head(10)
datediscountforward(%)zero(%)
2015-08-062015-08-061.0000001.9949472.014979
2015-09-062015-09-060.9983071.9949472.014979
2015-10-062015-10-060.9966721.9949472.014979
2015-11-062015-11-060.9949841.9949472.014979
2015-12-062015-12-060.9933541.9949472.014979
2016-01-062016-01-060.9916721.9949472.014979
2016-02-062016-02-060.9899941.9949472.014979
2016-03-062016-03-060.9869504.0143042.276446
2016-04-062016-04-060.9835914.0143042.505840
2016-05-062016-05-060.9803514.0143042.678750

我们可以画图来看:

  1. calibratedCurve.curveProfile()['zero(%)'].plot(figsize=(16,8))
  2. <matplotlib.axes.AxesSubplot at 0x6bbabd0>

Swap Curve Construction - 图1

2. 测试

首先可以看这条收益率曲线是否真的可以完美定价基准互换(perfectly pricing):

  1. cal = Calendar('China.IB')
  2. startDate = cal.advanceDate(Date(2015, 8, 6), '1B', BizDayConvention.Following)
  3. shiborIndex = Shibor('3M', calibratedCurve)
  4. nominal = 100000000.
  5. pricingEngine = DiscountingSwapEngine(calibratedCurve)
  6. for rate, tenor in zip(swap_rates, swap_tenor):
  7. benchmarkSwap = ShiborSwap(SwapLegType.Payer, nominal, startDate, Period(tenor), Period('3M'), rate, shiborIndex)
  8. benchmarkSwap.setPricingEngine(pricingEngine)
  9. print('{0:3s} benchmark Shibor Swap NPV: {1:>8.4f}'.format(tenor, benchmarkSwap.NPV()))
  10. 6M benchmark Shibor Swap NPV: 0.0000
  11. 1Y benchmark Shibor Swap NPV: -0.0000
  12. 2Y benchmark Shibor Swap NPV: 0.0000
  13. 3Y benchmark Shibor Swap NPV: 0.0000
  14. 4Y benchmark Shibor Swap NPV: -0.0000
  15. 5Y benchmark Shibor Swap NPV: 0.0000
  16. 7Y benchmark Shibor Swap NPV: 0.0000
  17. 10Y benchmark Shibor Swap NPV: 0.0000

然后我们取一个假设已经存在的互换(seasoned swap),通过这条收益率曲线估计它的现值:

  1. startDate = Date(2015, 7, 15)
  2. shiborIndex.addFixing(Date(2015, 7, 14), 0.045)
  3. customizeSwap = ShiborSwap(SwapLegType.Receiver, nominal, startDate, Period('9Y'), Period('3M'), 0.06, shiborIndex)
  4. customizeSwap.setPricingEngine(pricingEngine)
  5. print('{0:3s} Shibor Swap fixed at {1:.2f}% NPV: {2:15.4f}'.format('9Y',6.00, customizeSwap.NPV()))
  6. 9Y Shibor Swap fixed at 6.00% NPV: -6308510.5573
  1. customizeSwap.legAnalysis(0).head(10)
AMOUNTNOMINALACCRUAL_START_DATEACCRUAL_END_DATEACCRUAL_DAYSINDEXFIXING_DAYSFIXING_DATESINDEX_FIXINGDAY_COUNTERACCRUAL_PERIODEFFECTIVE_RATE
PAYMENT_DATE
2015-10-1515123291e+082015-07-152015-10-1592#NA#NA#NA#NAActual/365 (Fixed)0.25205480.06
2016-01-1515123291e+082015-10-152016-01-1592#NA#NA#NA#NAActual/365 (Fixed)0.25205480.06
2016-04-1514958901e+082016-01-152016-04-1591#NA#NA#NA#NAActual/365 (Fixed)0.24931510.06
2016-07-1514958901e+082016-04-152016-07-1591#NA#NA#NA#NAActual/365 (Fixed)0.24931510.06
2016-10-1715452051e+082016-07-152016-10-1794#NA#NA#NA#NAActual/365 (Fixed)0.25753420.06
2017-01-1614958901e+082016-10-172017-01-1691#NA#NA#NA#NAActual/365 (Fixed)0.24931510.06
2017-04-1714958901e+082017-01-162017-04-1791#NA#NA#NA#NAActual/365 (Fixed)0.24931510.06
2017-07-1714958901e+082017-04-172017-07-1791#NA#NA#NA#NAActual/365 (Fixed)0.24931510.06
2017-10-1614958901e+082017-07-172017-10-1691#NA#NA#NA#NAActual/365 (Fixed)0.24931510.06
2018-01-1514958901e+082017-10-162018-01-1591#NA#NA#NA#NAActual/365 (Fixed)0.24931510.06
  1. customizeSwap.legAnalysis(1).head(10)
AMOUNTNOMINALACCRUAL_START_DATEACCRUAL_END_DATEACCRUAL_DAYSINDEXFIXING_DAYSFIXING_DATESINDEX_FIXINGDAY_COUNTERACCRUAL_PERIODEFFECTIVE_RATE
PAYMENT_DATE
2015-10-1511500001e+082015-07-152015-10-1592Shibor3M Actual/36012015-07-140.045Actual/3600.25555560.045
2016-01-15504102.31e+082015-10-152016-01-1592Shibor3M Actual/36012015-10-140.01972574Actual/3600.25555560.01972574
2016-04-15871825.41e+082016-01-152016-04-1591Shibor3M Actual/36012016-01-140.03448979Actual/3600.25277780.03448979
2016-07-1510058521e+082016-04-152016-07-1591Shibor3M Actual/36012016-04-140.03979193Actual/3600.25277780.03979193
2016-10-1712348641e+082016-07-152016-10-1794Shibor3M Actual/36012016-07-140.04729266Actual/3600.26111110.04729266
2017-01-1612602271e+082016-10-172017-01-1691Shibor3M Actual/36012016-10-140.04985512Actual/3600.25277780.04985512
2017-04-1712602271e+082017-01-162017-04-1791Shibor3M Actual/36012017-01-130.04985512Actual/3600.25277780.04985512
2017-07-1712602271e+082017-04-172017-07-1791Shibor3M Actual/36012017-04-140.04985512Actual/3600.25277780.04985512
2017-10-1616680561e+082017-07-172017-10-1691Shibor3M Actual/36012017-07-140.06598904Actual/3600.25277780.06598904
2018-01-1517907251e+082017-10-162018-01-1591Shibor3M Actual/36012017-10-130.07084187Actual/3600.25277780.07084187