fix(ashare_engine): load_data 直查 dbbardata 绕 vnpy peewee(治 CTA 死算)
CI/CD / test (push) Successful in 11s
CI/CD / nas-deploy (push) Successful in 29s
CI/CD / nas-verify (push) Successful in 4m11s

根因:vnpy 父类 load_data 走 get_database().load_bar_data()(peewee ORM),
get_database init 时 create_indexes 对 26G dbbardata 库 → spawn 建 26G
索引 CPU 死算 1:27+ / web 并发 database is locked(2026-08-02 根因,
vnpy_db 指向 v2 大库 2cb2ab0 后触发)。load_data 读 0 bars → 回测空/卡。

修复:load_data 统一直查 dbbardata(原仅 5m/15m 走 _load_intraday_data,
扩展到日线 d),绕 vnpy peewee get_database。sqlite3 busy_timeout=30s
防并发锁。d → BarData(interval=Interval.DAILY)。

验证:日线 600519 2024H1 load_data 0.1s bars=116(was database locked
5.2s/0 bars) interval=DAILY;run_backtesting 5.6s(was 死算 1:27+);
000001 compute_metrics 完成 daily_df=(116,25) benchmark=116(5图metrics恢复)。
This commit is contained in:
2026-08-02 21:48:33 +08:00
parent c263aa14ab
commit b66a6c5958
+6 -6
View File
@@ -183,7 +183,7 @@ class AShareBacktestingEngine(BacktestingEngine):
)
def load_data(self) -> None:
"""覆写父类:支持 5m/15m 周期(绕 vnpy Interval enum 限制)。
"""覆写父类:直查 dbbardata(绕 vnpy peewee get_database 对大库锁/死算 + enum 限制)。
vnpy Interval enum 只有 MINUTE('1m')/HOUR('1h')/DAILY('d') 等,不认 '5m'/'15m'
父类 load_data 调 ``INTERVAL_DELTA_MAP[self.interval]`` 和
@@ -194,9 +194,8 @@ class AShareBacktestingEngine(BacktestingEngine):
时,直接 sqlite 查 dbbardata 表,把每行转 BarData(interval=Interval.MINUTE)
绕过 vnpy database_manager 的 enum 限制;其余周期(d/1m 等)走 vnpy 原生路径。
"""
if self.raw_interval not in ("5m", "15m"):
super().load_data()
return
# 统一直查 dbbardata(绕 vnpy peewee get_database 对大库 create_indexes 锁/死算;
# 2026-08-02 根因:vnpy_db 指向 v2 26G 库后 super().load_data 建 26G 索引 spawn 死算 1:27+
self._load_intraday_data()
def _load_intraday_data(self) -> None:
@@ -228,7 +227,8 @@ class AShareBacktestingEngine(BacktestingEngine):
symbol, exchange_str = self.vt_symbol.split(".")
# peewee DateTimeField 存的是 ISO 字符串;start/end 用 datetime 比较即可
# (SQLite 会把参数转成可比较的字符串形式)。
conn = sqlite3.connect(db_path)
conn = sqlite3.connect(db_path, timeout=30)
conn.execute("PRAGMA busy_timeout = 30000")
try:
cur = conn.execute(
"SELECT datetime, volume, turnover, open_interest, "
@@ -257,7 +257,7 @@ class AShareBacktestingEngine(BacktestingEngine):
symbol=symbol,
exchange=exchange,
datetime=dt,
interval=Interval.MINUTE, # 5m/15m 不在 enum,统一标 MINUTE
interval=(Interval.DAILY if self.raw_interval == "d" else Interval.MINUTE),
volume=float(vol or 0),
turnover=float(turnover or 0),
open_interest=float(oi or 0),