from __future__ import annotations from datetime import datetime import pandas as pd from web_core import data as data_module def _make_intraday_df(days: list[str]) -> pd.DataFrame: index_values: list[pd.Timestamp] = [] for day in days: index_values.append(pd.Timestamp(f"{day} 14:30:00", tz="UTC")) index_values.append(pd.Timestamp(f"{day} 15:30:00", tz="UTC")) index = pd.DatetimeIndex(index_values) return pd.DataFrame( { "Open": [100.0 + i for i in range(len(index))], "High": [101.0 + i for i in range(len(index))], "Low": [99.0 + i for i in range(len(index))], "Close": [100.5 + i for i in range(len(index))], "Volume": [1000 + i for i in range(len(index))], }, index=index, ) def test_fetch_ohlc_day_period_backfills_until_target_trading_days(monkeypatch) -> None: fixed_now = datetime(2026, 2, 17, 20, 0, 0) four_day_df = _make_intraday_df(["2026-02-12", "2026-02-13", "2026-02-14", "2026-02-17"]) five_day_df = _make_intraday_df(["2026-02-11", "2026-02-12", "2026-02-13", "2026-02-14", "2026-02-17"]) calls: list[dict[str, object]] = [] class FakeTicker: def history(self, **kwargs: object) -> pd.DataFrame: calls.append(kwargs) start = kwargs.get("start") if start is None: return four_day_df.copy() lookback_days = (fixed_now - pd.Timestamp(start).to_pydatetime()).days return five_day_df.copy() if lookback_days >= 12 else four_day_df.copy() monkeypatch.setattr(data_module.yf, "Ticker", lambda symbol: FakeTicker()) monkeypatch.setattr(data_module, "_utc_now", lambda: fixed_now) data_module.fetch_ohlc.clear() out = data_module.fetch_ohlc(symbol="TSLA", interval="2m", period="5d") session_days = pd.DatetimeIndex(out.index).normalize().unique() assert len(session_days) == 5 assert pd.Timestamp("2026-02-11", tz="UTC") in session_days assert len(calls) >= 2 assert all("start" in call and "end" in call for call in calls) def test_fetch_ohlc_non_day_period_uses_period_request(monkeypatch) -> None: calls: list[dict[str, object]] = [] month_df = _make_intraday_df(["2026-01-05", "2026-01-06", "2026-01-07"]) class FakeTicker: def history(self, **kwargs: object) -> pd.DataFrame: calls.append(kwargs) return month_df.copy() monkeypatch.setattr(data_module.yf, "Ticker", lambda symbol: FakeTicker()) data_module.fetch_ohlc.clear() out = data_module.fetch_ohlc(symbol="AAPL", interval="1h", period="1mo") assert len(out) == len(month_df) assert len(calls) == 1 assert calls[0].get("period") == "1mo" assert "start" not in calls[0] assert "end" not in calls[0]