"""Phase 1 BarData → vnpy.alpha AlphaLab polars 格式转换。""" import sys import os _VNPY_SRC = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "vnpy_v4.4.0")) if _VNPY_SRC not in sys.path: sys.path.insert(0, _VNPY_SRC) import polars as pl from pathlib import Path from vnpy.trader.object import BarData def convert_bars_to_alpha_df(bars: list[BarData]) -> pl.DataFrame: """ Convert vnpy BarData list to AlphaLab polars DataFrame format. Args: bars: List of BarData objects from Phase 1 read_db_daily Returns: polars DataFrame with columns: vt_symbol, datetime, open, high, low, close, volume, turnover, open_interest Note: SPIKE CORRECTION: AlphaLab.save_bar_data stores parquet columns as datetime, vt_symbol, open, high, low, close, volume, turnover, open_interest (NOT open_price, close_price - this was corrected in S1 spike testing) """ if not bars: return pl.DataFrame(schema={ "vt_symbol": pl.Utf8, "datetime": pl.Datetime, "open": pl.Float64, "high": pl.Float64, "low": pl.Float64, "close": pl.Float64, "volume": pl.Float64, "turnover": pl.Float64, "open_interest": pl.Float64, }) return pl.DataFrame({ "vt_symbol": [b.vt_symbol for b in bars], "datetime": [b.datetime for b in bars], "open": [b.open_price for b in bars], "high": [b.high_price for b in bars], "low": [b.low_price for b in bars], "close": [b.close_price for b in bars], "volume": [float(b.volume) for b in bars], "turnover": [float(b.turnover) if b.turnover is not None else 0.0 for b in bars], "open_interest": [float(b.open_interest) if b.open_interest is not None else 0.0 for b in bars], }) def save_alpha_lab_data(bars: list[BarData], lab_path: str) -> Path: """ Save BarData to AlphaLab format for vnpy.alpha usage. Args: bars: List of BarData objects lab_path: Path to AlphaLab directory Returns: Path to the saved daily data file """ from vnpy.alpha.lab import AlphaLab lab = AlphaLab(lab_path) lab.save_bar_data(bars) return lab.daily_path