Files
Chan/datasvc/app/storage.py
T
2025-08-14 02:29:27 +08:00

58 lines
1.8 KiB
Python

import os
import threading
from typing import List, Optional
import pandas as pd
_lock = threading.Lock()
def ensure_storage(base_dir: str):
os.makedirs(base_dir, exist_ok=True)
def _path(base_dir: str, symbol: str, timeframe: str) -> str:
safe_symbol = symbol.replace("/", "_").replace(":", "_")
d = os.path.join(base_dir, timeframe)
os.makedirs(d, exist_ok=True)
return os.path.join(d, f"{safe_symbol}.parquet")
def read_candles(base_dir: str, symbol: str, timeframe: str, start: Optional[int], end: Optional[int]) -> pd.DataFrame:
p = _path(base_dir, symbol, timeframe)
if not os.path.exists(p):
return pd.DataFrame(columns=["timestamp", "open", "high", "low", "close", "volume"]) # empty
df = pd.read_parquet(p)
if start is not None:
df = df[df["timestamp"] >= int(start)]
if end is not None:
df = df[df["timestamp"] <= int(end)]
df = df.sort_values("timestamp")
return df
def upsert_candles(base_dir: str, symbol: str, timeframe: str, candles: List[List[float]]):
p = _path(base_dir, symbol, timeframe)
new_df = pd.DataFrame(candles, columns=["timestamp", "open", "high", "low", "close", "volume"])
with _lock:
if os.path.exists(p):
old = pd.read_parquet(p)
merged = pd.concat([old, new_df], ignore_index=True)
merged = merged.drop_duplicates(subset=["timestamp"], keep="last").sort_values("timestamp")
else:
merged = new_df.sort_values("timestamp")
merged.to_parquet(p, index=False)
def get_last_timestamp(base_dir: str, symbol: str, timeframe: str) -> Optional[int]:
p = _path(base_dir, symbol, timeframe)
if not os.path.exists(p):
return None
df = pd.read_parquet(p)
if df.empty:
return None
return int(df["timestamp"].iloc[-1])