Harden `.ib.venues` against unknown exchange cals
Deats, - catch `InvalidCalendarName` in `has_holiday()` so venues without an `exchange_calendars` entry (eg. `IDEALPRO` for forex, `PAXOS` for crypto) gracefully return `False` instead of raising. - add `log` via `get_logger()` to emit a warning when skipping the holiday check for an unmapped venue. - fix `std_exch` type annot from `dict` -> `str`. - guard `is_expired()` against empty `.realExpirationDate` strings. - fill in `is_expired()` docstring. (this patch was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-coderepair_tests
parent
26aaec2e0c
commit
79be47635f
|
|
@ -33,6 +33,9 @@ from typing import (
|
|||
)
|
||||
|
||||
import exchange_calendars as xcals
|
||||
from exchange_calendars.errors import (
|
||||
InvalidCalendarName,
|
||||
)
|
||||
from pendulum import (
|
||||
parse,
|
||||
now,
|
||||
|
|
@ -41,6 +44,10 @@ from pendulum import (
|
|||
Time,
|
||||
)
|
||||
|
||||
from piker.log import get_logger
|
||||
|
||||
log = get_logger(__name__)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ib_async import (
|
||||
TradingSession,
|
||||
|
|
@ -61,10 +68,15 @@ def is_expired(
|
|||
con_deats: ContractDetails,
|
||||
) -> bool:
|
||||
'''
|
||||
Predicate
|
||||
Simple predicate whether the provided contract-deats match and
|
||||
already lifetime-terminated instrument.
|
||||
|
||||
'''
|
||||
expiry_dt: datetime = parse(con_deats.realExpirationDate)
|
||||
expiry_str: str = con_deats.realExpirationDate
|
||||
if not expiry_str:
|
||||
return False
|
||||
|
||||
expiry_dt: datetime = parse(expiry_str)
|
||||
return expiry_dt.date() >= now().date()
|
||||
|
||||
|
||||
|
|
@ -102,13 +114,28 @@ def has_holiday(
|
|||
con.exchange
|
||||
)
|
||||
|
||||
# XXX, ad-hoc handle any IB exchange which are non-std
|
||||
# via lookup table..
|
||||
std_exch: dict = {
|
||||
# XXX, ad-hoc handle any IB exchange which are
|
||||
# non-std via lookup table..
|
||||
std_exch: str = {
|
||||
'ARCA': 'ARCX',
|
||||
}.get(exch, exch)
|
||||
|
||||
cal: ExchangeCalendar = xcals.get_calendar(std_exch)
|
||||
try:
|
||||
cal: ExchangeCalendar = xcals.get_calendar(
|
||||
std_exch
|
||||
)
|
||||
except InvalidCalendarName:
|
||||
# venue has no `exchange_calendars` entry
|
||||
# (eg. IDEALPRO for forex, PAXOS for
|
||||
# crypto) -> not a holiday by default since
|
||||
# weekends are already handled by
|
||||
# `has_weekend()`.
|
||||
log.warning(
|
||||
f'No exchange cal for {std_exch!r},'
|
||||
f' skipping holiday check..\n'
|
||||
)
|
||||
return False
|
||||
|
||||
end: datetime = period.end
|
||||
# _start: datetime = period.start
|
||||
# ?TODO, can rm ya?
|
||||
|
|
|
|||
Loading…
Reference in New Issue