QuantLib 金融計算——基本組件之 Calendar 類


如果未做特別說明,文中的程序都是 Python3 代碼。

QuantLib 金融計算——基本組件之 Calendar 類

針對相應國家編制一套日歷表用來推算假期、工作日和周末,這對於金融實務來說是一件基礎又非常重要的事。

載入 QuantLib:

import QuantLib as ql

print(ql.__version__)
1.10

Calendar 對象的構造

在 QuantLib 中可以很輕松的構造特定國家的日歷表。例如,通過 myCal = UnitedKingdom() 構造英國的日歷表,其他國家諸如美國、日本、加拿大等等也可以用類似的方式構造。在有些國家,不同的市場遵循不同的日歷表,例如在中國,銀行間市場和交易所市場遵循的日歷表是不一樣的(交易所市場在周六周日一定不開放,不管是否調休)。對於這一問題,可以通過配置特定參數將日歷表細化到具體的市場上,例如中國銀行間市場的日歷表可以通過 myCal = China(China.IB) 構造。China.IBChina.SSE 是 quantlib-python 的預留特殊變量,分別表示中國的銀行間市場和交易所市場。

一些常用的成員函數

下面是一些常用的成員函數:

  • isBusinessDay(d):布爾值,判斷 d 是不是工作日。
  • isHoliday(d):布爾值,判斷 d 是不是假期。
  • isWeekend(w):布爾值,判斷 w 是不是周末(在有些國家,周末沒有安排在周六周日)。
  • isEndOfMonth(d):布爾值,判斷 d 是不是月末最后一個工作日。
  • endOfMonth(d):日期,返回 d 所在月的最后一個工作日。

例子 1:

def CalendarTesting1():
    chinaCal = ql.China(ql.China.IB)
    saudiArabCal = ql.SaudiArabia()
    nyEve = ql.Date(3, ql.April, 2017)

    print('Is BD :', chinaCal.isBusinessDay(nyEve))
    print('Is Holiday :', chinaCal.isHoliday(nyEve))
    print('Is Weekend in SA :', saudiArabCal.isWeekend(ql.Friday))
    print('Is Weekend in CN :', chinaCal.isWeekend(ql.Friday))
    print('Is Last BD :',
          chinaCal.isEndOfMonth(ql.Date(5, ql.April, 2018)))
    print('Last BD :', chinaCal.endOfMonth(nyEve))
Is BD : False
Is Holiday : True
Is Weekend in SA : True
Is Weekend in CN : False
Is Last BD : False
Last BD : April 28th, 2017

注意,在沙特阿拉伯周五周六是“周末”,這和中國不一樣。

自定義假期列表

QuantLib 對中國市場的支持比較有限,目前的版本假期列表僅僅維護到 2004-2017 年,要想正確推算其他年份的日歷表,用戶需要自行配置假期。QuantLib 中的 Calendar 對象可以方便的實現自定義假期,通常僅僅需要借助下列兩個函數:

  • addHoliday(d):添加 d 為假期。
  • removeHoliday(d):從假期表中移除 d

將 2018 年清明節放假調休的安排配置到 Calendar 對象中。

例子 2:

def CalendarTesting2():
    chinaCal = ql.China(ql.China.IB)

    d1 = ql.Date(5, ql.April, 2018)
    d2 = ql.Date(6, ql.April, 2018)
    d3 = ql.Date(8, ql.April, 2018)

    print('Is Business Day : ', chinaCal.isBusinessDay(d1))
    print('Is Business Day : ', chinaCal.isBusinessDay(d2))
    print('Is Business Day : ', chinaCal.isBusinessDay(d3))

    chinaCal.addHoliday(d1)
    chinaCal.addHoliday(d2)
    chinaCal.removeHoliday(d3)

    print('Is Business Day : ', chinaCal.isBusinessDay(d1))
    print('Is Business Day : ', chinaCal.isBusinessDay(d2))
    print('Is Business Day : ', chinaCal.isBusinessDay(d3))
Is Business Day :  True
Is Business Day :  True
Is Business Day :  False
Is Business Day :  False
Is Business Day :  False
Is Business Day :  True

工作日修正

將某個日期修正為工作日是一項必要的工作,QuantLib 中支持如下工作日轉換模式:

  • Following:將日期修正為之后出現的第一個工作日。
  • ModifiedFollowing:將日期修正為之后出現的第一個工作日,除非這個工作日出現在次月;如果修正后的工作日出現在次月,就將日期修正為之前出現的最近一個工作日,保證原始日期和修正后的日期處在同一個月。
  • Preceding:將日期修正為之前出現的最近一個工作日。
  • ModifiedPreceding:將日期修正為之前出現的最近一個工作日,除非這個工作日出現在上一個月;如果修正后的工作日出現在上一個月,就將日期修正為之后出現的第一個工作日,保證原始日期和修正后的日期處在同一個月。
  • Unadjusted:不作調整。

Calendar 對象通過下列兩個函數實現修正日期的功能:

  • adjust(d, convention):日期,按照轉換模式 convention 修正 d
  • advance(d, period, convention, endOfMonth):日期,將日期 date 向后推移時間間隔 period 后再按照轉換模式 convention 修正;參數 endOfMonth 表示,如果 d 是月末的話,推移修正后的日期也要是在月末。

最后,可以通過下面的函數計算兩個日期間的工作日個數:

  • businessDaysBetween(from, to, includeFirst, includeLast):計算日期 fromto 之間的工作日個數(是否包括首尾日期)。

例子 3:

def CalendarTesting3():
    chinaCal = ql.China(ql.China.IB)

    firstDate = ql.Date(31, ql.January, 2018)
    secondDate = ql.Date(1, ql.April, 2018)

    print('Date 2 Adj :', chinaCal.adjust(secondDate, ql.Preceding))
    print('Date 2 Adj :', chinaCal.adjust(secondDate, ql.ModifiedPreceding))

    mat = ql.Period(2, ql.Months)

    print('Date 1 Month Adv :',
          chinaCal.advance(firstDate, mat, ql.Following, False))
    print('Date 1 Month Adv :',
          chinaCal.advance(firstDate, mat, ql.ModifiedFollowing, False))

    print('Business Days Between :',
          chinaCal.businessDaysBetween(
              ql.Date(5, ql.March, 2018), ql.Date(30, ql.March, 2018),
              True, True))
Date 2 Adj : March 30th, 2018
Date 2 Adj : April 2nd, 2018
Date 1 Month Adv : April 2nd, 2018
Date 1 Month Adv : March 30th, 2018
Business Days Between : 20


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM