fa45d8aa5f
- health_checklist.json: 192.168.1.122→node122
- ocr_client.py: docstring IP→node122
- docs/market-data-requirements.md: IP→node122
- 所有API调用通过ProxyHandler({})绕过系统代理
Privoxy对node122:18003返回500,直连正常
366 lines
8.8 KiB
Python
366 lines
8.8 KiB
Python
#
|
|
# Copyright 2019 Quantopian, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
|
|
import datetime
|
|
from itertools import chain
|
|
from zoneinfo import ZoneInfo
|
|
|
|
import pandas as pd
|
|
from pandas.tseries.holiday import MO, Easter, GoodFriday, Holiday
|
|
from pandas.tseries.offsets import Day
|
|
|
|
from .common_holidays import (
|
|
christmas,
|
|
christmas_eve,
|
|
european_labour_day,
|
|
immaculate_conception,
|
|
maundy_thursday,
|
|
new_years_day,
|
|
)
|
|
from .exchange_calendar import (
|
|
MONDAY,
|
|
TUESDAY,
|
|
WEDNESDAY,
|
|
WEEKDAYS,
|
|
HolidayCalendar,
|
|
ExchangeCalendar,
|
|
)
|
|
|
|
|
|
def nearest_monday(dt: datetime.datetime) -> datetime.datetime:
|
|
"""
|
|
If a holiday falls on Tuesday or Wednesday, it is observed on the
|
|
previous Monday. If it falls on Thursday, Friday or a weekend,
|
|
it is observed on the following Monday.
|
|
"""
|
|
day = dt.weekday()
|
|
|
|
if day in (MONDAY, TUESDAY, WEDNESDAY):
|
|
return dt - datetime.timedelta(day)
|
|
|
|
while dt.weekday() != MONDAY:
|
|
dt += datetime.timedelta(1)
|
|
|
|
return dt
|
|
|
|
|
|
def cultural_diversity_observance(dt: datetime.datetime) -> datetime.datetime | None:
|
|
"""
|
|
Apply the nearest monday rule, and also exclude 2012 (Day of
|
|
Respect for Cultural Diversity breaks the nearest monday rule
|
|
in 2012).
|
|
"""
|
|
hol = nearest_monday(dt)
|
|
return hol if hol.year != 2012 else None
|
|
|
|
|
|
def not_2018(dt: datetime.datetime) -> datetime.datetime | None:
|
|
"""
|
|
Exclude the year 2018 from the holiday list.
|
|
"""
|
|
return dt if dt.year != 2018 else None
|
|
|
|
|
|
NewYearsDay = new_years_day()
|
|
|
|
CarnivalMonday = Holiday(
|
|
"Carnival Monday",
|
|
month=1,
|
|
day=1,
|
|
start_date="2011",
|
|
offset=[Easter(), -Day(48)],
|
|
)
|
|
|
|
CarnivalTuesday = Holiday(
|
|
"Carnival Tuesday",
|
|
month=1,
|
|
day=1,
|
|
start_date="2011",
|
|
offset=[Easter(), -Day(47)],
|
|
)
|
|
|
|
TruthAndJusticeMemorialDay = Holiday(
|
|
"Truth and Justice Memorial Day",
|
|
month=3,
|
|
day=24,
|
|
start_date="2005",
|
|
)
|
|
|
|
MalvinasDayTo2004 = Holiday(
|
|
"Malvinas Day (up to 2004)",
|
|
month=3,
|
|
day=31,
|
|
end_date="2005",
|
|
offset=pd.DateOffset(weekday=MO(1)),
|
|
)
|
|
|
|
MalvinasDayFrom2005 = Holiday(
|
|
"Malvinas Day (2005-present)", month=4, day=2, start_date="2005"
|
|
)
|
|
|
|
MaundyThursday = maundy_thursday()
|
|
|
|
LabourDay = european_labour_day()
|
|
|
|
MayDayRevolution = Holiday(
|
|
"May Day Revolution",
|
|
month=5,
|
|
day=25,
|
|
)
|
|
|
|
MartinMiguelDeGuemesDay = Holiday(
|
|
"Martin Miguel de Guemes Day",
|
|
month=6,
|
|
day=17,
|
|
start_date="2016",
|
|
)
|
|
|
|
NationalFlagDayTo2010 = Holiday(
|
|
"National Flag Day (up to 2010)",
|
|
month=6,
|
|
day=1,
|
|
end_date="2011",
|
|
offset=pd.DateOffset(weekday=MO(3)),
|
|
)
|
|
|
|
NationalFlagDayFrom2011 = Holiday(
|
|
"National Flag Day (2011-present)",
|
|
month=6,
|
|
day=20,
|
|
start_date="2011",
|
|
)
|
|
|
|
IndependenceDay = Holiday(
|
|
"Independence Day",
|
|
month=7,
|
|
day=9,
|
|
)
|
|
|
|
SanMartinsDayTo2010 = Holiday(
|
|
"San Martin's Day",
|
|
month=8,
|
|
day=1,
|
|
end_date="2011",
|
|
offset=pd.DateOffset(weekday=MO(3)),
|
|
)
|
|
|
|
SanMartinsDayFrom2012 = Holiday(
|
|
"San Martin's Day",
|
|
month=8,
|
|
day=1,
|
|
start_date="2012",
|
|
offset=pd.DateOffset(weekday=MO(3)),
|
|
)
|
|
|
|
DayOfRespectForCulturalDiversity = Holiday(
|
|
"Day of Respect for Cultural Diversity",
|
|
month=10,
|
|
day=12,
|
|
observance=cultural_diversity_observance,
|
|
)
|
|
|
|
BankHoliday = Holiday(
|
|
"Bank Holiday",
|
|
month=11,
|
|
day=6,
|
|
end_date="2018",
|
|
)
|
|
|
|
DayOfNationalSovereigntyTo2014 = Holiday(
|
|
"Day of National Sovereignty (2010-2014)",
|
|
month=11,
|
|
day=1,
|
|
start_date="2010",
|
|
end_date="2015",
|
|
offset=pd.DateOffset(weekday=MO(4)),
|
|
)
|
|
|
|
DayOfNationalSovereigntyFrom2017 = Holiday(
|
|
"Day of National Sovereignty (2017-present)",
|
|
month=11,
|
|
day=17,
|
|
start_date="2017",
|
|
offset=pd.DateOffset(weekday=MO(1)),
|
|
)
|
|
|
|
ImmaculateConception = immaculate_conception()
|
|
|
|
ChristmasEve = christmas_eve(
|
|
days_of_week=WEEKDAYS,
|
|
observance=not_2018,
|
|
)
|
|
|
|
ChristmasDay = christmas()
|
|
|
|
NewYearsEve = Holiday(
|
|
"New Year's Eve",
|
|
month=12,
|
|
day=31,
|
|
days_of_week=WEEKDAYS,
|
|
observance=not_2018,
|
|
)
|
|
|
|
|
|
class XBUEExchangeCalendar(ExchangeCalendar):
|
|
"""
|
|
Exchange calendar for the Buenos Aires Stock Exchange (XBUE).
|
|
|
|
Open Time: 11:00 AM, AST
|
|
Close Time: 5:00 PM, AST
|
|
|
|
Regularly-Observed Holidays:
|
|
- New Year's Day
|
|
- Carnival Monday (48 days before Easter)
|
|
- Carnival Tuesday (47 days before Easter)
|
|
- Truth and Justice Memorial Day (Mar 24)
|
|
- Malvinas Day (until 2004 first Monday after Mar 31, 2005-present Apr 2)
|
|
- Good Friday
|
|
- Labour Day
|
|
- May Day Revolution (May 25)
|
|
- Martin Miguel de Guemes Day (Jun 17, 2016-present)
|
|
- National Flag Day (until 2010 3rd Monday in Jun, 2011-present Jun 20)
|
|
- Independence Day (Jul 9)
|
|
- San Martin's Day (3rd Monday in Aug)
|
|
- Day of Respect for Cultural Diversity (2nd Monday in Oct)
|
|
- Bank Holiday (Nov 6)
|
|
- Day of National Sovereignty (4th Monday in Nov)
|
|
- Immaculate Conception
|
|
- Christmas Eve (2005-present)
|
|
- Christmas Day
|
|
- Last Trading Day of Year (2005-present)
|
|
|
|
|
|
Early Closes:
|
|
Note - we are unsure if these are early closes or holidays
|
|
- Christmas Eve
|
|
- New Year's Eve
|
|
"""
|
|
|
|
name = "XBUE"
|
|
|
|
tz = ZoneInfo("America/Argentina/Buenos_Aires")
|
|
|
|
open_times = ((None, datetime.time(11)),)
|
|
|
|
close_times = ((None, datetime.time(17, 00)),)
|
|
|
|
# TODO: Verify early close time
|
|
regular_early_close = datetime.time(13)
|
|
|
|
@property
|
|
def regular_holidays(self):
|
|
return HolidayCalendar(
|
|
[
|
|
NewYearsDay,
|
|
CarnivalMonday,
|
|
CarnivalTuesday,
|
|
TruthAndJusticeMemorialDay,
|
|
MalvinasDayTo2004,
|
|
MalvinasDayFrom2005,
|
|
MaundyThursday,
|
|
GoodFriday,
|
|
LabourDay,
|
|
MayDayRevolution,
|
|
MartinMiguelDeGuemesDay,
|
|
NationalFlagDayTo2010,
|
|
NationalFlagDayFrom2011,
|
|
IndependenceDay,
|
|
SanMartinsDayTo2010,
|
|
SanMartinsDayFrom2012,
|
|
DayOfRespectForCulturalDiversity,
|
|
BankHoliday,
|
|
DayOfNationalSovereigntyTo2014,
|
|
DayOfNationalSovereigntyFrom2017,
|
|
ImmaculateConception,
|
|
ChristmasDay,
|
|
]
|
|
)
|
|
|
|
@property
|
|
def adhoc_holidays(self):
|
|
misc_adhocs = [
|
|
"2009-07-10",
|
|
"2010-05-24",
|
|
"2010-10-27",
|
|
"2012-01-02",
|
|
"2012-02-27",
|
|
"2012-09-24",
|
|
"2013-01-31",
|
|
"2013-02-20",
|
|
"2018-11-30",
|
|
]
|
|
|
|
# There was a string of market closures in January, 2002
|
|
market_closures_2002_jan = [f"2002-01-{day:02d}" for day in range(7, 17)]
|
|
|
|
# There was a string of market closures in April, 2002
|
|
market_closures_2002_apr = [f"2002-04-{day:02d}" for day in range(22, 27)]
|
|
|
|
# There are occasionally "bridge days" that make long weekends when
|
|
# a holiday falls on a Tuesday/Thursday, but these days are chosen
|
|
# inconsistently.
|
|
bridge_days = [
|
|
"2011-03-25",
|
|
"2011-12-09",
|
|
"2012-04-30",
|
|
"2013-04-01",
|
|
"2013-06-21",
|
|
"2014-05-02",
|
|
"2014-12-26",
|
|
"2015-03-23",
|
|
"2015-12-07",
|
|
"2016-07-08",
|
|
"2016-12-09",
|
|
"2018-04-30",
|
|
"2018-12-24",
|
|
"2018-12-31",
|
|
"2019-07-08",
|
|
"2019-08-19",
|
|
"2019-10-14",
|
|
]
|
|
|
|
irregular_observances = [
|
|
"2012-10-08", # Cultural Diversity Day
|
|
"2011-08-22", # San Martin's Day
|
|
"2015-11-27", # Day of National Sovereignty
|
|
"2016-11-28", # Day of National Sovereignty
|
|
]
|
|
|
|
return [
|
|
pd.Timestamp(d)
|
|
for d in chain(
|
|
misc_adhocs,
|
|
market_closures_2002_jan,
|
|
market_closures_2002_apr,
|
|
bridge_days,
|
|
irregular_observances,
|
|
)
|
|
]
|
|
|
|
@property
|
|
def special_closes(self):
|
|
return [
|
|
(
|
|
self.regular_early_close,
|
|
HolidayCalendar(
|
|
[
|
|
ChristmasEve,
|
|
NewYearsEve,
|
|
]
|
|
),
|
|
),
|
|
]
|