Files
stock/backend/app/data/tushare_provider.py
2026-08-15 15:36:11 +08:00

54 lines
1.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Tushare 数据源(主)。日线 + 前复权。
token 从 settings.tushare_token 读取(.env。免费版 pro.daily 与 ts.pro_bar 实测可用。
"""
from __future__ import annotations
from datetime import datetime
from ..config import settings
from ..domain import Bar
from .symbols import to_ts_code
def _parse(date_str: str) -> datetime:
return datetime.strptime(str(date_str), "%Y%m%d")
def fetch_daily(code: str, start: str = "20200101", end: str | None = None,
adjust: str = "qfq") -> list[Bar]:
import tushare as ts # 延迟导入:未装或无 token 时该数据源不可用
if not settings.tushare_token:
raise RuntimeError("未配置 TUSHARE_TOKEN")
ts.set_token(settings.tushare_token)
pro = ts.pro_api()
ts_code = to_ts_code(code)
end = end or datetime.now().strftime("%Y%m%d")
# 优先 pro_bar含复权积分不足则退化为 pro.daily不复权
df = None
try:
df = ts.pro_bar(ts_code=ts_code, adj=adjust, start_date=start, end_date=end, freq="D")
except Exception:
df = None
if df is None or df.empty:
df = pro.daily(ts_code=ts_code, start_date=start, end_date=end)
if df is None or df.empty:
raise RuntimeError(f"Tushare 无数据: {ts_code}")
df = df.sort_values("trade_date")
bars: list[Bar] = []
for _, r in df.iterrows():
amt = r.get("amount")
bars.append(
Bar(
ts=_parse(r["trade_date"]),
open=float(r["open"]), high=float(r["high"]),
low=float(r["low"]), close=float(r["close"]),
volume=float(r["vol"]) * 100.0, # Tushare vol 单位为手 -> 股
amount=float(amt) * 1000.0 if amt is not None and amt == amt else None, # 千元 -> 元
)
)
return bars