"""Alpaca fetch window / feed selection. Regression cover for the 2026-07-20 outage: the near-close scan silently ran on the previous session's close because ``end`` resolved to midnight on end_date, which is *before* that day's bar timestamp (04:00Z under EDT). Widening the window also has to stay clear of the delayed-data period, which rejects the whole request. """ from __future__ import annotations from datetime import date, datetime, timedelta, timezone import pytest from app.providers.alpaca import AlpacaOHLCVProvider class _CapturingClient: """Stands in for StockHistoricalDataClient, recording the request.""" def __init__(self) -> None: self.request = None def get_stock_bars(self, request): self.request = request return {"AAPL": []} def _provider() -> tuple[AlpacaOHLCVProvider, _CapturingClient]: provider = AlpacaOHLCVProvider("key", "secret") client = _CapturingClient() provider._client = client return provider, client def _midnight(day: date) -> datetime: """Naive-UTC midnight — the SDK strips tzinfo from request datetimes.""" return datetime.combine(day, datetime.min.time()) def _utcnow() -> datetime: return datetime.now(timezone.utc).replace(tzinfo=None) @pytest.mark.asyncio async def test_todays_in_progress_bar_is_inside_the_window(): """The whole near-close design depends on today's bar being fetchable.""" provider, client = _provider() today = date.today() await provider.fetch_ohlcv("AAPL", today - timedelta(days=5), today) # Daily bars are stamped at session start (04:00Z); a midnight end drops them. assert client.request.end > _midnight(today) @pytest.mark.asyncio async def test_window_stays_out_of_the_delayed_data_period(): """A window reaching the last ~15 minutes fails the entire request.""" provider, client = _provider() await provider.fetch_ohlcv("AAPL", date.today() - timedelta(days=5), date.today()) assert client.request.end <= _utcnow() - timedelta(minutes=15) @pytest.mark.asyncio async def test_completed_past_day_is_fully_covered(): """Clamping must not swallow the last day of a historical window.""" provider, client = _provider() end_date = date.today() - timedelta(days=3) await provider.fetch_ohlcv("AAPL", end_date - timedelta(days=5), end_date) assert client.request.end > _midnight(end_date) @pytest.mark.asyncio async def test_window_collapsing_to_nothing_skips_the_call(): """A start inside the delayed period yields no request at all, not an error.""" provider, client = _provider() tomorrow = date.today() + timedelta(days=1) records = await provider.fetch_ohlcv("AAPL", tomorrow, tomorrow) assert records == [] assert client.request is None