GitHub Actions
Sync from GitHub: 343ddcfde906230ae5167ac2575a3e9d05d7fb84
9845f2b
"""
utils/calendar.py
NYSE calendar utilities:
- Next trading day for signal display
- Market open check
- EST time helper
"""
from datetime import datetime, timedelta
import pytz
try:
import pandas_market_calendars as mcal
NYSE_CAL_AVAILABLE = True
except ImportError:
NYSE_CAL_AVAILABLE = False
def get_est_time() -> datetime:
"""Return current datetime in US/Eastern timezone."""
return datetime.now(pytz.timezone("US/Eastern"))
def is_market_open_today() -> bool:
"""Return True if today is a NYSE trading day."""
today = get_est_time().date()
if NYSE_CAL_AVAILABLE:
try:
nyse = mcal.get_calendar("NYSE")
schedule = nyse.schedule(start_date=today, end_date=today)
return len(schedule) > 0
except Exception:
pass
return today.weekday() < 5
def get_next_signal_date() -> datetime.date:
"""
Determine the date for which the model's signal applies.
Rules:
- If today is a NYSE trading day AND it is before 09:30 EST
→ signal applies to TODAY (market hasn't opened yet)
- Otherwise
→ signal applies to the NEXT NYSE trading day
"""
now_est = get_est_time()
today = now_est.date()
market_not_open_yet = (
now_est.hour < 9 or
(now_est.hour == 9 and now_est.minute < 30)
)
if NYSE_CAL_AVAILABLE:
try:
nyse = mcal.get_calendar("NYSE")
schedule = nyse.schedule(
start_date=today,
end_date=today + timedelta(days=10),
)
if len(schedule) == 0:
return today # fallback
first_day = schedule.index[0].date()
# Today is a trading day and market hasn't opened → today
if first_day == today and market_not_open_yet:
return today
# Otherwise find first trading day strictly after today
for ts in schedule.index:
d = ts.date()
if d > today:
return d
return schedule.index[-1].date()
except Exception:
pass
# Fallback: simple weekend skip
candidate = today if market_not_open_yet else today + timedelta(days=1)
while candidate.weekday() >= 5:
candidate += timedelta(days=1)
return candidate
def is_sync_window() -> bool:
"""True if current EST time is in the 07:00-08:00 or 19:00-20:00 window."""
now = get_est_time()
return (7 <= now.hour < 8) or (19 <= now.hour < 20)