refactor: establish standalone application boundary

This commit is contained in:
leefer
2026-08-03 21:42:25 +08:00
parent cc5fb8d73e
commit e1e76cd51e
324 changed files with 63090 additions and 44743 deletions
+138
View File
@@ -0,0 +1,138 @@
from __future__ import annotations
from datetime import datetime
from typing import Any
from backend.bootstrap.config import display_compact_date as _display_date
from backend.features.screener.backtest import BacktestRunner
from backend.features.screener.catalog import REGIMES
from backend.features.screener.factors import FactorBuilder
from backend.features.screener.formula import FormulaEvaluator
from database import ReviewDatabase
class SelectionRunner:
def __init__(
self,
database: ReviewDatabase,
factor_builder: FactorBuilder,
formula_evaluator: FormulaEvaluator,
backtest_runner: BacktestRunner,
) -> None:
self.database = database
self.factor_builder = factor_builder
self.formula_evaluator = formula_evaluator
self.backtest_runner = backtest_runner
def validate_formula(self, formula: dict[str, Any]) -> dict[str, Any]:
return self.formula_evaluator.validate_formula(formula)
def build_factors(
self,
trade_date: str,
realtime_snapshot: dict[str, Any] | None,
history_days: int,
) -> tuple[list[dict[str, Any]], str]:
return self.factor_builder.build_factors(
trade_date, realtime_snapshot, history_days
)
def apply_formula(
self, rows: list[dict[str, Any]], formula: dict[str, Any], regime: str
) -> list[dict[str, Any]]:
return self.formula_evaluator.apply_formula(rows, formula, regime)
def backtest(self, trade_date: str, formula: dict[str, Any]) -> dict[str, Any]:
return self.backtest_runner.backtest(trade_date, formula)
def screen(
self, user_id: int, trade_date: str, formula: dict[str, Any], regime: str,
strategy_name: str, run_backtest: bool = True,
realtime_snapshot: dict[str, Any] | None = None,
mode: str = "smart",
prepared_factors: list[dict[str, Any]] | None = None,
prepared_date: str = "",
) -> dict[str, Any]:
mode = mode if mode in {"smart", "curated", "quant"} else "smart"
formula = self.validate_formula(formula)
if prepared_factors is None:
history_days = int((formula.get("meta") or {}).get("history_days") or 80)
factors, actual_date = self.build_factors(
trade_date, realtime_snapshot, history_days
)
else:
factors = prepared_factors
actual_date = prepared_date or trade_date
candidates = self.apply_formula(factors, formula, regime)
backtest = self.backtest(actual_date, formula) if run_backtest else None
required_fields = sorted({
str(item.get("field") or "")
for item in list(formula.get("filters") or []) + list(formula.get("score") or [])
if item.get("field")
})
complete_rows = sum(
1 for row in factors
if all(row.get(field) is not None for field in required_fields)
)
coverage = round(complete_rows / len(factors) * 100, 1) if factors else 0.0
health_status = "normal" if candidates else "no_signal"
if backtest and backtest["samples"] >= 20:
for candidate in candidates:
estimate = backtest["win_rate"] * 0.65 + candidate["score"] * 100 * 0.35
candidate["historical_probability"] = round(min(95, max(5, estimate)), 1)
candidate["probability_samples"] = backtest["samples"]
else:
for candidate in candidates:
candidate["historical_probability"] = None
candidate["probability_samples"] = backtest["samples"] if backtest else 0
result = {
"meta": {
"trade_date": _display_date(actual_date),
"regime": regime,
"regime_label": REGIMES.get(regime, regime),
"strategy_name": strategy_name,
"mode": mode,
"library_version": int(
(formula.get("meta") or {}).get("library_version") or 0
),
"universe_count": len(factors),
"candidate_count": len(candidates),
"updated_at": datetime.now().astimezone().isoformat(timespec="seconds"),
"health": {
"status": health_status,
"required_field_count": len(required_fields),
"complete_rows": complete_rows,
"universe_rows": len(factors),
"coverage": coverage,
"signal_count": len(candidates),
},
"selection_source": (
"tushare_rt_k+history" if realtime_snapshot else "historical_eod"
),
"realtime": bool(realtime_snapshot),
"history_cutoff": (
str(realtime_snapshot.get("previous_trade_date") or "")
if realtime_snapshot else actual_date
),
"factor_freshness": {
"realtime": [
"价格", "涨跌幅", "成交量", "成交额", "换手率",
"均线位置", "5/10日动量", "板块强度", "开盘竞价",
] if realtime_snapshot else [],
"historical": ["历史波动率", "流通市值", "资金流", "竞价因子", "回测"],
},
},
"formula": formula,
"candidates": candidates,
"backtest": backtest,
"disclaimer": (
"候选仅由策略条件与当日数据计算;历史统计不代表未来收益。"
if mode == "curated"
else "概率为历史条件估计,不代表未来收益;退潮或样本不足时允许无候选。"
),
}
run_id = self.database.save_screener_run(
user_id, actual_date, regime, strategy_name, formula, result, mode
)
result["meta"]["run_id"] = run_id
return result