feat(quant): QlibEngine v1 — 本地行情落盘 QlibDataset → D.features 读取 → 因子回测
- qlib_adapter/provider.py:SQLite 行情按 qlib 0.9.8 二进制格式落盘(起始索引头 + 逐日 float32、instruments 3 列、小写 instrument、晚上市 offset)
- qlib_adapter/dataset.py:qlib.init 幂等({'day': uri})+ D.features 读取 close 面板
- qlib_adapter/engine.py:QlibEngine(QuantEngine)v1 —— Qlib 数据管线回测与 LocalEngine 同记账规则(无未来函数/成本/涨跌停标注),factor_test 复用共享实现;Alpha158+LightGBM 为 TODO
- 真实 20 股验证:qlib 落盘 142 文件→读取→回测(-12.81%,Local 对照 -12.97%,差异为 qlib float32 存储)
- tests/test_qlib_engine.py 5 项(格式/roundtrip/晚上市 offset/回测/因子测试)→ pytest 86 passed / ruff clean
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
"""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()
|
||||
Reference in New Issue
Block a user