日付処理(○営業日後の日付、月末・月初日、第○金曜日の取得)

金融工学を使う実務(雑用)では、小難しい数式よりも「月末日付」や「○○営業日後」などをコーディングする機会が非常に多いのでその辺をまとめておく。
RよりもPythonの方が日付処理周りが充実している気がする&作業自体がpythonに移行しつつあることもあり、pythonでの処理をまとめる。

準備

まずdateutil、workdaysパッケージを導入する。
http://pypi.python.org/pypi/python-dateutil/
http://pypi.python.org/pypi/workdays/
dateutilは日付処理を大幅に簡素化&拡張できるライブラリであり、workdaysはExcelのworkday関数同様、N営業日後を求める関数等が実装されたパッケージである。

N営業日後の取得

workdayパッケージを使ってN営業日後を計算してみる。

# -*- coding: utf-8 -*-
import datetime
import workdays
#基準日と祝日の設定
today    = datetime.date(2009,12,30)
holidays = [datetime.date(2009,12,31),datetime.date(2010,1,1)]
#基準日から1営業日だけずらした日付を求める(2010/01/04)
dayAfterOneBusinessDay  = workdays.workday(today,1,holidays)
print dayAfterOneBusinessDay
#基準日から-1営業日だけずらした日付を求める(2010/12/29)
dayBeforeOneBusinessDay = workdays.workday(today,-1,holidays)
print dayBeforeOneBusinessDay

月末・月初日の取得

月末・月初日を求める関数を作成した。
workday関数を利用することで、土日祝日を考慮した月末・月初日取得が可能。

# -*- coding: utf-8 -*-
from datetime import *
from workdays import *
from dateutil.relativedelta import *
#xxxIncludeHolidays : 土日祝日込みの日付で返却
#xxxExcludeHolidays : 土日祝日を除外した日付で返却
def endOfMonthIncludeHolidays(date_,months_=0):
    return(date_ + relativedelta(months=months_,day=31))
def endOfMonthExcludeHolidays(date_,months_=0,holidays_=[]):
    nextStartOfMonth = date_ + relativedelta(months=months_+1,day=1)
    return(workday(nextStartOfMonth,-1,holidays_))
def startOfMonthIncludeHolidays(date_,months_=0):
    return(date_ + relativedelta(months=months_,day=1))
def startOfMonthExcludeHolidays(date_,months_=0,holidays_=[]):
    lastEndOfMonth = date_ + relativedelta(months=months_-1,day=31)
    return(workday(lastEndOfMonth,1,holidays))
if __name__ == '__main__':
    #大晦日と元旦を祝日とする。
    holidays = [datetime(2009,12,31),datetime(2010,1,1)]
    #月末日を求める(2009/12/30/,2009/12/31)    
    basedate = datetime(2009,12,15)
    print endOfMonthExcludeHolidays(basedate,0,holidays)
    print endOfMonthIncludeHolidays(basedate)
    #月初日を求める(2010/1/4,2010/1/1)
    basedate =datetime(2010,1,15)
    print startOfMonthExcludeHolidays(basedate,0,holidays)
    print startOfMonthIncludeHolidays(basedate)
    #一ヶ月後・前の月初日をもとめる(2010/01/01,2009/11/01)
    basedate = datetime(2009,12,15)
    print startOfMonthIncludeHolidays(basedate,1)
    print startOfMonthIncludeHolidays(basedate,-1)

第○金曜日の取得

dateutilパッケージ群に入っているrrule関数は強力で以下のようなことができる。

# -*- coding: utf-8 -*-
from datetime import *
from dateutil.rrule import *
firstFridayByMonth = list(rrule(MONTHLY,count=3,byweekday=FR(1),dtstart=date.today()))
print firstFridayByMonth

こんなかんじで今日から三カ月分の各月の第一金曜日のみ抽出等の処理を書くこともできる。

他にも上で書いたような月末・月初日、さらに連続する平日(月〜金)を取得することもできる。

# -*- coding: utf-8 -*-
from datetime import *
from dateutil.rrule import *
#3ヶ月分の月初日の取得
print list(rrule(MONTHLY,count=3,bymonthday=1 ,dtstart=date.today()))
#3ヶ月分の月末日の取得
print list(rrule(MONTHLY,count=3,bymonthday=-1 ,dtstart=date.today()))
#10日分の平日取得
print list(rrule(DAILY,count=10,byweekday=(MO,TU,WE,TH,FR),bysetpos= 1,dtstart=date.today()))