Skip to content

Commit

Permalink
Fix conflict between holidays and special dates (#39)
Browse files Browse the repository at this point in the history
* Regularize adhoc_holdiays as tz-naive

Previously mix of tz-naive, "UTC" and other timezones (sometimes mixed
within a specific calendar).

* Fix conflict between holidays and special dates

Fixes #33

* revisions
  • Loading branch information
maread99 committed Jul 16, 2021
1 parent 56836de commit 508d9fb
Show file tree
Hide file tree
Showing 25 changed files with 329 additions and 346 deletions.
13 changes: 11 additions & 2 deletions exchange_calendars/exchange_calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ def adhoc_holidays(self):
"""
Returns
-------
list: A list of timestamps representing unplanned closes.
list: A list of tz-naive timestamps representing unplanned closes.
"""
return []

Expand Down Expand Up @@ -1241,7 +1241,16 @@ def _special_dates(self, calendars, ad_hoc_dates, start_date, end_date):
return pd.Series([], dtype="datetime64[ns, UTC]")

result = pd.concat(merged).sort_index()
return result.loc[(result >= start_date) & (result <= end_date)]
result = result.loc[(result >= start_date) & (result <= end_date)]
# exclude any special date that conincides with a holiday
adhoc_holidays = pd.DatetimeIndex(self.adhoc_holidays, tz="UTC")
result = result[~result.index.isin(adhoc_holidays)]
reg_holidays = self.regular_holidays.holidays(
start_date.tz_convert(None), end_date.tz_convert(None)
)
if not reg_holidays.empty:
result = result[~result.index.isin(reg_holidays.tz_localize("UTC"))]
return result

def _calculate_special_opens(self, start, end):
return self._special_dates(
Expand Down
20 changes: 10 additions & 10 deletions exchange_calendars/exchange_calendar_asex.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import pandas as pd
from dateutil.easter import EASTER_ORTHODOX, easter
from pandas.tseries.holiday import EasterMonday, GoodFriday, Holiday
from pytz import UTC, timezone
from pytz import timezone

from .common_holidays import (
assumption_day,
Expand All @@ -43,7 +43,7 @@ def orthodox_easter(start_date="1980", end_date="2021"):
easter(year, method=EASTER_ORTHODOX)
for year in range(int(start_date), int(end_date))
]
).tz_localize(UTC)
)


NewYearsDay = new_years_day()
Expand Down Expand Up @@ -144,22 +144,22 @@ def regular_holidays(self):
def adhoc_holidays(self):
debt_crisis = pd.date_range("2015-06-29", "2015-07-31", freq="B")

debt_crisis_holidays = [pd.Timestamp(str(date), tz=UTC) for date in debt_crisis]
debt_crisis_holidays = [pd.Timestamp(str(date)) for date in debt_crisis]

misc_adhoc_holidays = [
# In 2002, market closed for unknown reason
pd.Timestamp("2002-05-07", tz=UTC),
pd.Timestamp("2002-05-07"),
# In 2004, Assumption Day fell on a sunday, observed on a Friday
pd.Timestamp("2004-08-13", tz=UTC),
pd.Timestamp("2004-08-13"),
# In 2008, worker strikes closed the market for 2 days in March
pd.Timestamp("2008-03-04", tz=UTC),
pd.Timestamp("2008-03-05", tz=UTC),
pd.Timestamp("2008-03-04"),
pd.Timestamp("2008-03-05"),
# In 2013, May Day strikes closed the market
pd.Timestamp("2013-05-07", tz=UTC),
pd.Timestamp("2013-05-07"),
# In 2014, New Year's Eve was observed as a holiday
pd.Timestamp("2014-12-31", tz=UTC),
pd.Timestamp("2014-12-31"),
# In 2016, Labour Day fell on a Sunday, observed on Tuesday
pd.Timestamp("2016-05-03", tz=UTC),
pd.Timestamp("2016-05-03"),
]

return list(
Expand Down
5 changes: 2 additions & 3 deletions exchange_calendars/exchange_calendar_bvmf.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,6 @@
day=31,
observance=previous_friday,
)
# Brazil hosted World Cup and played Croatia (and won 3-1!)
CopaDoMundo2014 = Holiday("Copa Do Mundo 2014", month=6, day=12, year=2014)


class BVMFExchangeCalendar(ExchangeCalendar):
Expand Down Expand Up @@ -170,7 +168,8 @@ class BVMFExchangeCalendar(ExchangeCalendar):

@property
def adhoc_holidays(self):
return [CopaDoMundo2014]
# CopaDoMundo2014 Brazil hosted World Cup and played Croatia (and won 3-1!)
return [pd.Timestamp("2014-06-12")]

@property
def regular_holidays(self):
Expand Down
4 changes: 2 additions & 2 deletions exchange_calendars/exchange_calendar_iepa.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
USPresidentsDay,
USThanksgivingDay,
)
from pytz import UTC, timezone
from pytz import timezone

from .exchange_calendar import ExchangeCalendar
from exchange_calendars.exchange_calendar import HolidayCalendar
Expand Down Expand Up @@ -69,7 +69,7 @@ def adhoc_holidays(self):
USNationalDaysofMourning,
# ICE was only closed on the first day of the Hurricane Sandy
# closings (was not closed on 2012-10-30)
[Timestamp("2012-10-29", tz=UTC)],
[Timestamp("2012-10-29")],
)
)

Expand Down
12 changes: 6 additions & 6 deletions exchange_calendars/exchange_calendar_xasx.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
sunday_to_monday,
weekend_to_monday,
)
from pytz import UTC, timezone
from pytz import timezone

from .common_holidays import (
anzac_day,
Expand Down Expand Up @@ -94,7 +94,7 @@
# also observed as a public holiday. Note that this isn't defined as a
# rule, because it will happen next in 2095 (and then in 2163), and
# there isn't a great way to tell how this will be handled at that point.
EasterTuesday2011AdHoc = Timestamp("2011-04-26", tz=UTC)
EasterTuesday2011AdHoc = Timestamp("2011-04-26")

QueensBirthday = Holiday(
"Queen's Birthday",
Expand Down Expand Up @@ -124,10 +124,10 @@
)

# additional ad-hoc holidays
NYEMonday1984AdHoc = Timestamp("1984-12-31", tz=UTC)
NYEMonday1990AdHoc = Timestamp("1990-12-31", tz=UTC)
Bicentennial1988 = Timestamp("1988-01-25", tz=UTC)
Y2KTesting = Timestamp("1999-12-31", tz=UTC)
NYEMonday1984AdHoc = Timestamp("1984-12-31")
NYEMonday1990AdHoc = Timestamp("1990-12-31")
Bicentennial1988 = Timestamp("1988-01-25")
Y2KTesting = Timestamp("1999-12-31")


class XASXExchangeCalendar(ExchangeCalendar):
Expand Down
3 changes: 2 additions & 1 deletion exchange_calendars/exchange_calendar_xdub.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@

# Ad hoc closes.
March1BadWeather = Timestamp("2018-03-01", tz=UTC)
March2BadWeather = Timestamp("2018-03-02", tz=UTC)
# Ad hoc holidays.
March2BadWeather = Timestamp("2018-03-02")


class XDUBExchangeCalendar(ExchangeCalendar):
Expand Down
6 changes: 3 additions & 3 deletions exchange_calendars/exchange_calendar_xetr.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

from pandas import Timestamp
from pandas.tseries.holiday import EasterMonday, GoodFriday, Holiday, previous_workday
from pytz import UTC, timezone
from pytz import timezone

from .common_holidays import (
boxing_day,
Expand All @@ -38,7 +38,7 @@

# Whit Monday observed in 2007, before it became regularly observed
# starting in 2015.
WhitMonday2007AdHoc = Timestamp("2007-05-28", tz=UTC)
WhitMonday2007AdHoc = Timestamp("2007-05-28")

WhitMonday = whit_monday(start_date="2015-01-01")

Expand All @@ -47,7 +47,7 @@
)

# Reformation Day was a German national holiday in 2017.
ReformationDay500thAnniversaryAdHoc = Timestamp("2017-10-31", tz=UTC)
ReformationDay500thAnniversaryAdHoc = Timestamp("2017-10-31")

ChristmasEve = christmas_eve()

Expand Down
6 changes: 3 additions & 3 deletions exchange_calendars/exchange_calendar_xfra.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

from pandas import Timestamp
from pandas.tseries.holiday import EasterMonday, GoodFriday, Holiday, previous_workday
from pytz import UTC, timezone
from pytz import timezone

from .common_holidays import (
boxing_day,
Expand All @@ -38,7 +38,7 @@

# Whit Monday observed in 2007, before it became regularly observed
# starting in 2015.
WhitMonday2007AdHoc = Timestamp("2007-05-28", tz=UTC)
WhitMonday2007AdHoc = Timestamp("2007-05-28")

WhitMonday = whit_monday(start_date="2015-01-01")

Expand All @@ -47,7 +47,7 @@
)

# Reformation Day was a German national holiday in 2017.
ReformationDay500thAnniversaryAdHoc = Timestamp("2017-10-31", tz=UTC)
ReformationDay500thAnniversaryAdHoc = Timestamp("2017-10-31")

ChristmasEve = christmas_eve()

Expand Down
160 changes: 80 additions & 80 deletions exchange_calendars/exchange_calendar_xhkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,87 +142,87 @@ def process_queen_birthday(dt):

HKAdhocClosures = [
# I dont know these days
pd.Timestamp("1970-07-01", tz="UTC"),
pd.Timestamp("1971-07-01", tz="UTC"),
pd.Timestamp("1973-07-02", tz="UTC"),
pd.Timestamp("1974-07-01", tz="UTC"),
pd.Timestamp("1975-07-01", tz="UTC"),
pd.Timestamp("1976-07-01", tz="UTC"),
pd.Timestamp("1977-07-01", tz="UTC"),
pd.Timestamp("1979-07-02", tz="UTC"),
pd.Timestamp("1980-07-01", tz="UTC"),
pd.Timestamp("1981-07-01", tz="UTC"),
pd.Timestamp("1982-07-01", tz="UTC"),
pd.Timestamp("1971-03-22", tz="UTC"),
pd.Timestamp("1971-12-06", tz="UTC"),
pd.Timestamp("1971-12-20", tz="UTC"),
pd.Timestamp("1975-07-28", tz="UTC"),
pd.Timestamp("1985-07-29", tz="UTC"),
pd.Timestamp("1970-07-01"),
pd.Timestamp("1971-07-01"),
pd.Timestamp("1973-07-02"),
pd.Timestamp("1974-07-01"),
pd.Timestamp("1975-07-01"),
pd.Timestamp("1976-07-01"),
pd.Timestamp("1977-07-01"),
pd.Timestamp("1979-07-02"),
pd.Timestamp("1980-07-01"),
pd.Timestamp("1981-07-01"),
pd.Timestamp("1982-07-01"),
pd.Timestamp("1971-03-22"),
pd.Timestamp("1971-12-06"),
pd.Timestamp("1971-12-20"),
pd.Timestamp("1975-07-28"),
pd.Timestamp("1985-07-29"),
# Weather related closures
pd.Timestamp("1970-07-16", tz="UTC"), # 台风Ruby7003
pd.Timestamp("1970-09-14", tz="UTC"), # 台风Georgia7011
pd.Timestamp("1971-07-22", tz="UTC"), # 台风Lucy7114
pd.Timestamp("1971-08-31", tz="UTC"), # 重光纪念日?
pd.Timestamp("1973-04-16", tz="UTC"), # 股灾休市?
pd.Timestamp("1973-07-17", tz="UTC"), # 台风Dot7304
pd.Timestamp("1974-04-25", tz="UTC"), # 英国女王生日
pd.Timestamp("1975-10-14", tz="UTC"), # 台风Elsie7514
pd.Timestamp("1978-07-26", tz="UTC"), # 台风Agnes7807
pd.Timestamp("1978-07-27", tz="UTC"),
pd.Timestamp("1979-01-26", tz="UTC"), # 春节补假
pd.Timestamp("1979-08-02", tz="UTC"), # 台风Hope7908
pd.Timestamp("1980-05-21", tz="UTC"), # 台风Georgia8004
pd.Timestamp("1980-07-22", tz="UTC"), # 台风Joy8007
pd.Timestamp("1981-04-27", tz="UTC"), # 英国女王生日
pd.Timestamp("1981-07-06", tz="UTC"), # 台风Lynn8106
pd.Timestamp("1981-07-07", tz="UTC"),
pd.Timestamp("1981-07-29", tz="UTC"), # 查理斯王子与戴安娜婚礼
pd.Timestamp("1983-09-09", tz="UTC"), # 台风Ellen8309
pd.Timestamp("1985-06-24", tz="UTC"), # 台风Hal8504
pd.Timestamp("1986-04-01", tz="UTC"), # 复活节星期一翌日
pd.Timestamp("1986-10-22", tz="UTC"), # 英女王伊丽莎白二世访港
pd.Timestamp("1987-10-20", tz="UTC"), # 黑色星期一后,休市4天
pd.Timestamp("1987-10-21", tz="UTC"),
pd.Timestamp("1987-10-22", tz="UTC"),
pd.Timestamp("1987-10-23", tz="UTC"),
pd.Timestamp("1988-04-05", tz="UTC"), # 清明节翌日
# Timestamp('1988-06-13', tz='UTC'), # 英国女王生日
pd.Timestamp("1991-06-18", tz="UTC"), # 英国女王生日翌日
pd.Timestamp("1992-07-22", tz="UTC"), # 台风Cary9207
# pd.Timestamp('1993-06-14', tz='UTC'), # 英国女王生日
pd.Timestamp("1993-09-17", tz="UTC"), # 台风Becky9316
pd.Timestamp("1994-06-14", tz="UTC"), # 英国女王生日翌日,端午节翌日
pd.Timestamp("1997-06-30", tz="UTC"), # 英国女王生日
pd.Timestamp("1997-07-02", tz="UTC"), # 香港回归纪念日翌日
pd.Timestamp("1997-08-18", tz="UTC"), # 抗战胜利纪念日
pd.Timestamp("1997-10-02", tz="UTC"), # 国庆节翌日
pd.Timestamp("1998-08-17", tz="UTC"), # 抗战胜利纪念日
pd.Timestamp("1998-10-02", tz="UTC"), # 国庆节翌日
pd.Timestamp("1999-04-06", tz="UTC"), # 清明节翌日
pd.Timestamp("1999-09-16", tz="UTC"), # 台风约克
pd.Timestamp("1999-12-31", tz="UTC"), # 千年虫
pd.Timestamp("2001-07-06", tz="UTC"), # 台风尤特0104
pd.Timestamp("2001-07-25", tz="UTC"), # 台风玉兔0107
# pd.Timestamp(2008-06-25', tz='UTC'), # 台风风神0806,上午休市
pd.Timestamp("2008-08-06", tz="UTC"), # 台风北冕0809
pd.Timestamp("2008-08-22", tz="UTC"), # 台风鹦鹉0810
# pd.Timestamp(2009-09-15', tz='UTC'), # 台风巨爵0915,上午休市
pd.Timestamp("2010-04-06", tz="UTC"), # 清明节翌日
pd.Timestamp("2011-09-29", tz="UTC"), # 台风纳沙1117
# pd.Timestamp(2012-07-24', tz='UTC'), # 台风韦森特1208,上午休市
pd.Timestamp("2012-10-02", tz="UTC"), # 中秋节补假
# pd.Timestamp(2013-05-22', tz='UTC'), # 暴雨,上午休市
pd.Timestamp("2013-08-14", tz="UTC"), # 台风尤特1311
# pd.Timestamp(2013-09-23', tz='UTC'), # 台风天兔1319,上午休市
# pd.Timestamp(2014-09-16', tz='UTC'), # 台风海鸥1415,上午休市
pd.Timestamp("2015-04-07", tz="UTC"), # 复活节+清明节补假
# pd.Timestamp(2015-07-09', tz='UTC'), # 台风莲花1520,期货夜盘休市
pd.Timestamp("2015-09-03", tz="UTC"), # 抗战70周年纪念
# pd.Timestamp(2016-08-01', tz='UTC'), # 台风妮妲1604,期货夜盘20:55收市
pd.Timestamp("2016-08-02", tz="UTC"), # 台风妮妲1604
pd.Timestamp("2016-10-21", tz="UTC"), # 台风海马1622
# pd.Timestamp(2017-06-12', tz='UTC'), # 台风苗柏1702,期货夜盘17:35休市
pd.Timestamp("2017-08-23", tz="UTC"), # 台风天鸽1713
pd.Timestamp("1970-07-16"), # 台风Ruby7003
pd.Timestamp("1970-09-14"), # 台风Georgia7011
pd.Timestamp("1971-07-22"), # 台风Lucy7114
pd.Timestamp("1971-08-31"), # 重光纪念日?
pd.Timestamp("1973-04-16"), # 股灾休市?
pd.Timestamp("1973-07-17"), # 台风Dot7304
pd.Timestamp("1974-04-25"), # 英国女王生日
pd.Timestamp("1975-10-14"), # 台风Elsie7514
pd.Timestamp("1978-07-26"), # 台风Agnes7807
pd.Timestamp("1978-07-27"),
pd.Timestamp("1979-01-26"), # 春节补假
pd.Timestamp("1979-08-02"), # 台风Hope7908
pd.Timestamp("1980-05-21"), # 台风Georgia8004
pd.Timestamp("1980-07-22"), # 台风Joy8007
pd.Timestamp("1981-04-27"), # 英国女王生日
pd.Timestamp("1981-07-06"), # 台风Lynn8106
pd.Timestamp("1981-07-07"),
pd.Timestamp("1981-07-29"), # 查理斯王子与戴安娜婚礼
pd.Timestamp("1983-09-09"), # 台风Ellen8309
pd.Timestamp("1985-06-24"), # 台风Hal8504
pd.Timestamp("1986-04-01"), # 复活节星期一翌日
pd.Timestamp("1986-10-22"), # 英女王伊丽莎白二世访港
pd.Timestamp("1987-10-20"), # 黑色星期一后,休市4天
pd.Timestamp("1987-10-21"),
pd.Timestamp("1987-10-22"),
pd.Timestamp("1987-10-23"),
pd.Timestamp("1988-04-05"), # 清明节翌日
# Timestamp('1988-06-13'), # 英国女王生日
pd.Timestamp("1991-06-18"), # 英国女王生日翌日
pd.Timestamp("1992-07-22"), # 台风Cary9207
# pd.Timestamp('1993-06-14'), # 英国女王生日
pd.Timestamp("1993-09-17"), # 台风Becky9316
pd.Timestamp("1994-06-14"), # 英国女王生日翌日,端午节翌日
pd.Timestamp("1997-06-30"), # 英国女王生日
pd.Timestamp("1997-07-02"), # 香港回归纪念日翌日
pd.Timestamp("1997-08-18"), # 抗战胜利纪念日
pd.Timestamp("1997-10-02"), # 国庆节翌日
pd.Timestamp("1998-08-17"), # 抗战胜利纪念日
pd.Timestamp("1998-10-02"), # 国庆节翌日
pd.Timestamp("1999-04-06"), # 清明节翌日
pd.Timestamp("1999-09-16"), # 台风约克
pd.Timestamp("1999-12-31"), # 千年虫
pd.Timestamp("2001-07-06"), # 台风尤特0104
pd.Timestamp("2001-07-25"), # 台风玉兔0107
# pd.Timestamp(2008-06-25'), # 台风风神0806,上午休市
pd.Timestamp("2008-08-06"), # 台风北冕0809
pd.Timestamp("2008-08-22"), # 台风鹦鹉0810
# pd.Timestamp(2009-09-15'), # 台风巨爵0915,上午休市
pd.Timestamp("2010-04-06"), # 清明节翌日
pd.Timestamp("2011-09-29"), # 台风纳沙1117
# pd.Timestamp(2012-07-24'), # 台风韦森特1208,上午休市
pd.Timestamp("2012-10-02"), # 中秋节补假
# pd.Timestamp(2013-05-22'), # 暴雨,上午休市
pd.Timestamp("2013-08-14"), # 台风尤特1311
# pd.Timestamp(2013-09-23'), # 台风天兔1319,上午休市
# pd.Timestamp(2014-09-16'), # 台风海鸥1415,上午休市
pd.Timestamp("2015-04-07"), # 复活节+清明节补假
# pd.Timestamp(2015-07-09'), # 台风莲花1520,期货夜盘休市
pd.Timestamp("2015-09-03"), # 抗战70周年纪念
# pd.Timestamp(2016-08-01'), # 台风妮妲1604,期货夜盘20:55收市
pd.Timestamp("2016-08-02"), # 台风妮妲1604
pd.Timestamp("2016-10-21"), # 台风海马1622
# pd.Timestamp(2017-06-12'), # 台风苗柏1702,期货夜盘17:35休市
pd.Timestamp("2017-08-23"), # 台风天鸽1713
]


Expand Down
Loading

0 comments on commit 508d9fb

Please sign in to comment.