chart/tests/test_yahoo.py

60 lines
1.9 KiB
Python

import json
from pathlib import Path
import httpx
import pytest
from app.bars.models import Timeframe
from app.market.yahoo import MAX_1M_WINDOW_SECONDS, YahooSource, parse_chart
FIXTURE = Path(__file__).parent / "fixtures" / "yahoo_es_1h.json"
def test_parser_filters_null_ohlc_rows():
payload = json.loads(FIXTURE.read_text())
raw_count = len(payload["chart"]["result"][0]["timestamp"])
bars = parse_chart(payload, Timeframe.H1)
assert len(bars) == raw_count - 1
assert all(None not in (bar.o, bar.h, bar.l, bar.c) for bar in bars)
assert all(bar.source == "yahoo" and bar.symbol == "ES=F" for bar in bars)
@pytest.mark.asyncio
async def test_one_minute_history_is_windowed_and_deduplicated():
payload = json.loads(FIXTURE.read_text())
calls = []
async def handler(request: httpx.Request):
calls.append(request)
return httpx.Response(200, json=payload)
async with httpx.AsyncClient(transport=httpx.MockTransport(handler)) as client:
source = YahooSource(client=client)
bars = await source.history(
"ES=F", Timeframe.M1, 0, MAX_1M_WINDOW_SECONDS * 2 + 1
)
assert len(calls) == 3
assert len(bars) == len({bar.t for bar in parse_chart(payload, Timeframe.M1)})
@pytest.mark.asyncio
async def test_thirty_minute_history_uses_yahoos_native_interval():
payload = json.loads(FIXTURE.read_text())
calls = []
async def handler(request: httpx.Request):
calls.append(request)
return httpx.Response(200, json=payload)
async with httpx.AsyncClient(transport=httpx.MockTransport(handler)) as client:
bars = await YahooSource(client=client).history(
"ES=F", Timeframe.M30, range_="60d"
)
assert len(calls) == 1
assert calls[0].url.params["interval"] == "30m"
assert calls[0].url.params["range"] == "60d"
assert bars and all(bar.tf is Timeframe.M30 for bar in bars)