Files
eventflow/backend/fastapi_app/services/market_moves.py

69 lines
1.9 KiB
Python

import json
import os
import subprocess
from typing import Any
WATCHLIST_DEFAULT = [
# A-share ETF proxies for indices (QFR raw data uses ETF parquets)
# HS300
"510300.SH",
# ZZ500
"510500.SH",
# ChiNext
"159915.SZ",
# SSE50 proxy (may not exist in rawdir unless downloaded)
"510050.SH",
# Futures placeholders (not in QFR rawdir by default; will show as errors until sourced)
"AU.SHF",
"CU.SHF",
"M.DCE",
"TA.CZCE",
"SC.INE",
]
def fetch_moves_via_qfr(*, trade_date: str | None = None, symbols: list[str] | None = None) -> dict[str, Any]:
"""Fetch day-level moves by shelling out to the existing qfr conda env.
Reason: eventflow env is kept minimal; qfr env already has pandas/pyarrow.
"""
sym_list = symbols or WATCHLIST_DEFAULT
rawdir = os.environ.get("QFR_RAWDIR", "/home/openclaw/projects/quant-factor-research/data/raw")
env = os.environ.copy()
env["QFR_RAWDIR"] = rawdir
env["QFR_SYMBOLS"] = ",".join(sym_list)
if trade_date:
env["QFR_TRADE_DATE"] = trade_date
conda = os.environ.get("CONDA_BIN", "/home/openclaw/miniconda3/bin/conda")
script = os.path.join(os.path.dirname(__file__), "market_moves_qfr.py")
cmd = [conda, "run", "-n", "qfr", "python", script]
proc = subprocess.run(cmd, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if proc.returncode != 0:
return {
"ok": False,
"error": "qfr_subprocess_failed",
"returncode": proc.returncode,
"stderr": proc.stderr[-4000:],
}
try:
data = json.loads(proc.stdout)
except json.JSONDecodeError:
return {
"ok": False,
"error": "invalid_json_from_qfr",
"stdout": proc.stdout[-2000:],
"stderr": proc.stderr[-2000:],
}
data["ok"] = True
data["symbols"] = sym_list
return data