"""Qlib 数据读取(dataset):qlib.init 幂等 + 从 provider_uri 读行情面板。""" from __future__ import annotations from datetime import date from pathlib import Path import pandas as pd _init_state: dict = {"uri": None} def ensure_qlib_init(provider_uri: Path) -> None: """初始化 qlib(进程内同 uri 幂等;不同 uri 会重新 init)。""" if _init_state["uri"] == str(provider_uri): return import qlib from qlib.config import REG_CN qlib.init(provider_uri={"day": str(provider_uri)}, region=REG_CN) _init_state["uri"] = str(provider_uri) def load_close_panel( provider_uri: Path, symbols: list[str], start: date, end: date, ) -> pd.DataFrame: """经 qlib D.features 读取 $close,返回 date×symbol 面板(index datetime)。""" ensure_qlib_init(provider_uri) from qlib.data import D lower = [s.lower() for s in symbols] df = D.features( lower, ["$close"], start_time=start.strftime("%Y-%m-%d"), end_time=end.strftime("%Y-%m-%d"), freq="day", ) if df.empty: return pd.DataFrame() close = df["$close"].unstack(level="instrument") close.index = pd.to_datetime(close.index) close.columns = [c.upper() for c in close.columns] return close.sort_index()