first commit

This commit is contained in:
2026-08-07 16:08:34 +08:00
commit e0b5228008
51 changed files with 5175 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
"""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 时 DEMO 仍可用
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():
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 单位为手 -> 股
)
)
return bars