Files

35 lines
1.3 KiB
Python

# sanguo_data/datawriter.py
import os
import pandas as pd
from pathlib import Path
from vnpy.trader.object import BarData
from vnpy.trader.constant import Interval
from sanguo_data.datareader import _row_to_bar
from sanguo_data.config import DataConfig
def atomic_write_parquet(path: str, df: pd.DataFrame) -> None:
p = Path(path)
p.parent.mkdir(parents=True, exist_ok=True)
tmp = str(p) + ".tmp"
df.to_parquet(tmp)
os.replace(tmp, str(p)) # 原子替换
def write_daily(symbol: str, df: pd.DataFrame, cfg: DataConfig) -> None:
# 1) parquet 增量合并(按年分区,去重保留最新)
for year, group in df.groupby(df["date"].str[:4]):
f = Path(cfg.data_paths["daily_dir"]) / year / f"{symbol}.parquet"
if f.exists():
old = pd.read_parquet(f)
combined = pd.concat([old, group]).drop_duplicates("date", keep="last")
else:
combined = group
atomic_write_parquet(str(f), combined)
# 2) vnpy SQLite
bars = [_row_to_bar(symbol, row, Interval.DAILY) for _, row in df.iterrows()]
_save_to_vnpy_db(bars, cfg)
def _save_to_vnpy_db(bars: list[BarData], cfg: DataConfig) -> None:
from vnpy.trader.database import get_database
db = get_database()
db.save_bar_data(bars) # spike 验证签名