import os from typing import Optional import pandas as pd import tushare as ts def _init_api(): token = os.environ.get("TUSHARE_TOKEN") if not token: raise RuntimeError("TUSHARE_TOKEN 环境变量未设置") ts.set_token(token) return ts.pro_api() def fetch_contract(ts_code: str, limit: int = 100) -> pd.DataFrame: """拉取指定期货合约的日线数据,返回按 trade_date 升序排列的 DataFrame。""" pro = _init_api() df = pro.fut_daily(ts_code=ts_code) if df.empty: raise RuntimeError(f"未返回 {ts_code} 的任何数据,可能合约代码错误或 token 积分不足") cols = [ "ts_code", "trade_date", "open", "high", "low", "close", "vol", "amount", "oi", "oi_chg", "pre_close", ] df = df[[c for c in cols if c in df.columns]].copy() numeric = ["open", "high", "low", "close", "vol", "amount", "oi", "oi_chg", "pre_close"] for c in numeric: if c in df.columns: df[c] = pd.to_numeric(df[c], errors="coerce") df = df.sort_values("trade_date").reset_index(drop=True) return df