fix(ashare_engine): load_data 直查 dbbardata 绕 vnpy peewee(治 CTA 死算)
根因: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:
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user