43 lines
1.3 KiB
Python
43 lines
1.3 KiB
Python
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import json
|
|
from datetime import datetime
|
|
from typing import Any
|
|
from zoneinfo import ZoneInfo
|
|
|
|
from backend.features.screener.cross_section import finalize_factor_rows
|
|
from backend.features.screener.engine import FACTOR_MINIMUM_COVERAGE
|
|
from backend.features.screener.technical import build_technical_rows
|
|
|
|
SHANGHAI = ZoneInfo("Asia/Shanghai")
|
|
|
|
|
|
def build_factor_snapshot(
|
|
trade_date: str,
|
|
inputs: dict[str, Any],
|
|
coverage: dict[str, float],
|
|
sources: list[str],
|
|
) -> dict[str, Any]:
|
|
ready = {
|
|
dataset: coverage.get(dataset, 0) >= minimum
|
|
for dataset, minimum in FACTOR_MINIMUM_COVERAGE.items()
|
|
}
|
|
ready["limit_events"] = coverage.get("limit_events", 0) >= 1
|
|
rows = finalize_factor_rows(build_technical_rows(trade_date, inputs, ready), ready)
|
|
canonical = json.dumps(
|
|
{"trade_date": trade_date, "coverage": coverage, "rows": rows},
|
|
ensure_ascii=False,
|
|
separators=(",", ":"),
|
|
sort_keys=True,
|
|
)
|
|
version = hashlib.sha256(canonical.encode("utf-8")).hexdigest()[:16]
|
|
return {
|
|
"trade_date": trade_date,
|
|
"version": version,
|
|
"observed_at": datetime.now(SHANGHAI).isoformat(timespec="seconds"),
|
|
"coverage": coverage,
|
|
"sources": sorted(set(sources)),
|
|
"rows": rows,
|
|
}
|