How US Stock Market Hours Validation (9:30-16:00 ET) Works in AI-Trader
AI-Trader validates US stock trades against the official 9:30 AM to 4:00 PM Eastern Time window using minute-based arithmetic and Eastern Time zone conversions in service/server/routes_shared.py.
AI-Trader is an open-source trading system that enforces strict compliance with US equity market regulations. The repository implements precise market-hours validation to ensure trade orders are only accepted during official New York Stock Exchange hours, while allowing unrestricted 24/7 trading for cryptocurrency assets.
Core Validation Logic in routes_shared.py
The validation system centers on service/server/routes_shared.py, which contains the primary time-checking functions. The implementation uses mathematical conversion of time to minutes rather than string parsing, enabling efficient range comparisons.
Minute-Based Time Comparison
The is_us_market_open() function converts the current Eastern Time into total minutes since midnight to determine if the market is active. This approach simplifies the boundary check against the 9:30 AM (570 minutes) and 4:00 PM (960 minutes) thresholds.
from zoneinfo import ZoneInfo
from datetime import datetime
def is_us_market_open() -> bool:
et_tz = ZoneInfo('America/New_York')
now_et = datetime.now(et_tz)
day = now_et.weekday()
time_in_minutes = now_et.hour * 60 + now_et.minute
return day < 5 and 570 <= time_in_minutes < 960
This function returns True only when the day is a weekday (Monday through Friday, where weekday() returns 0-4) and the time falls within the 570-960 minute window.
The is_market_open() Router
The system delegates market status checks through is_market_open(), which acts as a central switch. According to the source code in routes_shared.py, this function bypasses time validation for crypto markets while routing US stock requests to the dedicated checker:
def is_market_open(market: str) -> bool:
if market in ('crypto', 'polymarket'):
return True
if market == 'us-stock':
return is_us_market_open()
return True
This design pattern ensures that US stock market hours validation is applied consistently across all equity trading routes while maintaining flexibility for non-traditional markets.
Validating Execution Timestamps
When processing trade requests, AI-Trader validates user-provided execution timestamps through validate_executed_at(). This function handles both immediate execution requests ("now") and specific datetime strings, converting all inputs to US Eastern Time before validation.
Handling "Now" Requests
For real-time trade validation, the function checks if the current moment falls within trading hours when the client specifies "now" as the execution time:
def validate_executed_at(executed_at: str, market: str) -> tuple[bool, str]:
# ... parsing logic ...
if executed_at.lower() == 'now':
if not is_market_open(market):
if market == 'us-stock':
et_tz = ZoneInfo('America/New_York')
now_et = datetime.now(et_tz)
return (
False,
'US market is closed. '
f"Current time (ET): {now_et.strftime('%Y-%m-%d %H:%M:%S')}. "
'Trading hours: Mon-Fri 9:30-16:00 ET',
)
return False, f'{market} is currently closed'
return True, ''
Validating Specific Timestamps
For historical or scheduled trades, the function parses the timestamp and applies the same weekday and minute-range logic:
# ... conversion to dt_et ...
if market == 'us-stock':
day = dt_et.weekday()
time_in_minutes = dt_et.hour * 60 + dt_et.minute
is_weekday = day < 5
is_market_hours = 570 <= time_in_minutes < 960
if not (is_weekday and is_market_hours):
day_names = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
return (
False,
f"US market is closed on {day_names[day]} at {dt_et.strftime('%H:%M')} ET. "
'Trading hours: Mon-Fri 9:30-16:00 ET',
)
This implementation generates descriptive error messages that include the specific day and time, making troubleshooting straightforward for API consumers.
Time Zone Handling and DST
AI-Trader utilizes Python's zoneinfo.ZoneInfo('America/New_York') to handle Eastern Time conversions. This approach automatically respects daylight saving time transitions, ensuring that the 9:30-16:00 window shifts appropriately between EST (UTC-5) and EDT (UTC-4) without requiring manual offset calculations. The validation logic remains consistent year-round because ZoneInfo abstracts the complexity of seasonal clock changes.
Integration in Trade Routes
The validation functions integrate directly with the trading API endpoints defined in service/server/routes_trading.py. When a client submits a trade creation payload, the route handler invokes validate_executed_at() before processing the order. This centralized validation gate ensures that every US stock order passes through the same 9:30 to 16:00 ET compliance check, regardless of which endpoint receives the request.
Summary
- Minute-based comparison: The system converts hours and minutes to total minutes since midnight (570-960 range) to validate the 9:30 AM to 4:00 PM window.
- Eastern Time enforcement: All timestamps are converted to
America/New_YorkusingZoneInfo, automatically handling daylight saving time. - Centralized routing:
is_market_open()inroutes_shared.pydirects validation logic while exempting crypto markets from time restrictions. - Descriptive error messages: Failed validations return specific feedback including current ET time and official trading hours.
- Dual validation paths: The system handles both immediate execution (
"now") and specific historical timestamps with the same underlying logic.
Frequently Asked Questions
How does AI-Trader handle daylight saving time changes?
AI-Trader uses Python's standard library ZoneInfo with the 'America/New_York' identifier rather than hardcoded UTC offsets. This implementation automatically adjusts for EST (UTC-5) and EDT (UTC-4) transitions, ensuring that the 9:30-16:00 validation window remains accurate regardless of the season.
What happens when a trade is submitted outside US market hours?
When validate_executed_at() detects a time outside the 570-960 minute window or a weekend day, it returns a tuple containing False and a descriptive error string. For example, a Saturday submission generates: "US market is closed on Sat at 08:15 ET. Trading hours: Mon-Fri 9:30-16:00 ET". This prevents order execution and informs the user of the exact reason for rejection.
Does the validation apply to all asset types?
No. The is_market_open() function explicitly returns True for crypto and polymarket assets without time checking. Only the us-stock market type triggers the is_us_market_open() validation, allowing cryptocurrency trades to execute 24/7 while restricting equities to official exchange hours.
Can I use is_us_market_open() in my own scripts?
Yes. The function is importable from service.server.routes_shared and can be used independently to check market status. Since it relies only on the system clock and ZoneInfo, it requires no database connections or API keys to function, making it suitable for standalone market monitoring tools.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →