Files
Grid_Trading/tests/test_tencent_quotes.py
2026-07-08 22:09:17 +08:00

99 lines
3.2 KiB
Python

from decimal import Decimal
import pytest
from grid_trading.domain.models import Instrument
from grid_trading.market.tencent import (
QuoteFetchError,
TencentQuoteProvider,
infer_tencent_symbol,
parse_tencent_response,
)
def test_infer_tencent_symbol_from_a_share_code():
assert infer_tencent_symbol("000001") == "sz000001"
assert infer_tencent_symbol("600000") == "sh600000"
assert infer_tencent_symbol("510300") == "sh510300"
assert infer_tencent_symbol("sz000001") == "sz000001"
def test_parse_tencent_response_extracts_realtime_fields():
raw = (
'v_sz000001="51~平安银行~000001~10.60~10.47~10.44~0~0~0~'
'10.60~0~10.59~0~10.58~0~10.57~0~10.56~0~10.61~0~10.62~0~'
'10.63~0~10.64~0~10.65~0~~20260708161430~0.13~1.24~10.63~10.34";'
).encode("gbk")
[quote] = parse_tencent_response(raw)
assert quote.symbol == "sz000001"
assert quote.code == "000001"
assert quote.name == "平安银行"
assert quote.price == Decimal("10.60")
assert quote.previous_close == Decimal("10.47")
assert quote.open_price == Decimal("10.44")
assert quote.change == Decimal("0.13")
assert quote.change_percent == Decimal("1.24")
assert quote.high == Decimal("10.63")
assert quote.low == Decimal("10.34")
assert quote.quote_time == "20260708161430"
assert quote.source == "tencent"
def test_parse_tencent_response_rejects_missing_price():
raw = 'v_sz000001="51~平安银行~000001~~~";'.encode("gbk")
with pytest.raises(QuoteFetchError, match="price"):
parse_tencent_response(raw)
def test_provider_builds_batch_query_and_maps_by_code():
calls: list[str] = []
raw = (
'v_sz000001="51~平安银行~000001~10.60~10.47~10.44~0~0~0~'
'0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~~20260708161430~0.13~1.24~10.63~10.34";'
).encode("gbk")
def fake_fetch(url: str, timeout: float) -> bytes:
calls.append(url)
return raw
provider = TencentQuoteProvider(fetcher=fake_fetch)
quotes = provider.fetch_quotes([Instrument(id=1, code="000001", name="平安银行")])
assert "q=sz000001" in calls[0]
assert quotes["000001"].price == Decimal("10.60")
def test_provider_wraps_fetch_errors():
def failing_fetch(url: str, timeout: float) -> bytes:
raise OSError("bad gateway")
provider = TencentQuoteProvider(fetcher=failing_fetch)
with pytest.raises(QuoteFetchError, match="Tencent quote request failed"):
provider.fetch_quotes([Instrument(id=1, code="000001", name="平安银行")])
def test_provider_retries_once_after_transient_fetch_error():
raw = (
'v_sz000001="51~平安银行~000001~10.60~10.47~10.44~0~0~0~'
'0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~~20260708161430~0.13~1.24~10.63~10.34";'
).encode("gbk")
calls = 0
def flaky_fetch(url: str, timeout: float) -> bytes:
nonlocal calls
calls += 1
if calls == 1:
raise OSError("bad gateway")
return raw
provider = TencentQuoteProvider(fetcher=flaky_fetch, retries=1)
quotes = provider.fetch_quotes([Instrument(id=1, code="000001", name="平安银行")])
assert calls == 2
assert quotes["000001"].price == Decimal("10.60")