Compute the last trading day by CustomBusinessDay class
from itertools import chain
from datetime import datetime
from datetime import date
from pandas.tseries.offsets import CustomBusinessDay
import pandas as pd
import yaml
import requests
QuantLibに日本の祝日があるが、情報が古い
Japanese holiday in QuantLib is too old
import QuantLib as ql
calender = ql.Japan()
calender.isHoliday(ql.Date(11, 8, 2016))
False
# No "Mountain day"
# https://github.com/k1LoW/holiday_jp
try:
holiday_jp_yaml = yaml.load(requests.get('https://raw.githubusercontent.com/k1LoW/holiday_jp/master/holidays.yml').text)
except Exception:
with open('data/holidays.yml', 'rb') as f:
holiday_jp_yaml = yaml.load(f)
holiday_jp = list(holiday_jp_yaml.keys())
sorted(holiday_jp)[:5]
[datetime.date(1970, 1, 1), datetime.date(1970, 1, 15), datetime.date(1970, 2, 11), datetime.date(1970, 3, 21), datetime.date(1970, 4, 29)]
Add "The First Three Days of the New Year" and "new years eve" as holidays
holiday_newyear = chain.from_iterable(
[[date(y, 1, 2), date(y, 1, 3), date(y, 12, 31)]
for y in range(sorted(holiday_jp)[0].year, sorted(holiday_jp)[-1].year + 1)])
holiday_jpx = chain(holiday_jp, holiday_newyear)
create CustomBusinessDay instance
bday_jpx = CustomBusinessDay(holidays=holiday_jpx)
Create "date_range" same as case2-1
freq='WOM-2FRI'を指定することで毎月の第二金曜日を指定できる
to specify "The 2nd Friday of every month" by freq='WOM-2FRI'
sq_date = pd.date_range(datetime(2017, 1, 1), datetime(2017, 12, 31), freq='WOM-2FRI')
sq_date
DatetimeIndex(['2017-01-13', '2017-02-10', '2017-03-10', '2017-04-14', '2017-05-12', '2017-06-09', '2017-07-14', '2017-08-11', '2017-09-08', '2017-10-13', '2017-11-10', '2017-12-08'], dtype='datetime64[ns]', freq='WOM-2FRI')
If the 2nd Friday is holiday, Set the day before as the last trading day
def shift_bday(dt):
if dt.date() in bday_jpx.holidays:
return (dt - bday_jpx)
else:
return dt
sq_date = sq_date.map(shift_bday)
sq_date
array([Timestamp('2017-01-13 00:00:00', offset='WOM-2FRI'), Timestamp('2017-02-10 00:00:00', offset='WOM-2FRI'), Timestamp('2017-03-10 00:00:00', offset='WOM-2FRI'), Timestamp('2017-04-14 00:00:00', offset='WOM-2FRI'), Timestamp('2017-05-12 00:00:00', offset='WOM-2FRI'), Timestamp('2017-06-09 00:00:00', offset='WOM-2FRI'), Timestamp('2017-07-14 00:00:00', offset='WOM-2FRI'), Timestamp('2017-08-10 00:00:00'), Timestamp('2017-09-08 00:00:00', offset='WOM-2FRI'), Timestamp('2017-10-13 00:00:00', offset='WOM-2FRI'), Timestamp('2017-11-10 00:00:00', offset='WOM-2FRI'), Timestamp('2017-12-08 00:00:00', offset='WOM-2FRI')], dtype=object)
8月11日が祝日なので、一日前倒しされる
11th of Aug is holiday, so Set the day before as the last trading day
Business day from 1 May ,2017 to contract expires
pd.date_range(datetime(2017, 5, 1), sq_date[4], freq=bday_jpx)
DatetimeIndex(['2017-05-01', '2017-05-02', '2017-05-08', '2017-05-09', '2017-05-10', '2017-05-11', '2017-05-12'], dtype='datetime64[ns]', freq='C')
Count the number of business day
len(pd.date_range(datetime(2017, 5, 1), sq_date[4], freq=bday_jpx))
7
pandas 0.18.1からCustomBusinessHourが使えるように
Possible to use "CustomBusinessHour" from pandas 0.18.1
http://pandas.pydata.org/pandas-docs/version/0.18.1/whatsnew.html#custom-business-hour
from pandas.tseries.offsets import CustomBusinessHour
Set JPX trading hours
bhour_jpx = CustomBusinessHour(start='9:00', end='15:00', holidays=bday_jpx.holidays)
adding or subtracting business hours
datetime(2016, 9, 21, 13) + bhour_jpx * 2
Timestamp('2016-09-23 09:00:00')