rebuild(screener): add controlled formulas and rolling backtests

This commit is contained in:
leefer
2026-07-30 10:45:40 +08:00
parent 08f69b0641
commit b79b4ba280
21 changed files with 616 additions and 37 deletions
+48
View File
@@ -1,5 +1,7 @@
from __future__ import annotations
import json
import httpx
from backend.bootstrap.application import create_application
@@ -24,6 +26,23 @@ def _formula() -> dict:
}
class FormulaProvider:
def stream(self, _profile, _messages):
yield json.dumps(
{
"universe": {"exclude_st": True, "listed_days_min": 120},
"filters": [{"field": "amount_billion", "op": ">=", "value": 3}],
"score": [
{"field": "return_20d", "weight": 60, "direction": "desc"},
{"field": "sector_strength", "weight": 40, "direction": "desc"},
],
"limit": 20,
"min_score": 55,
},
ensure_ascii=False,
)
def test_screener_catalog_lock_and_custom_strategy_boundary(tmp_path) -> None:
application = create_application(Settings.for_test(tmp_path))
@@ -45,8 +64,37 @@ def test_screener_catalog_lock_and_custom_strategy_boundary(tmp_path) -> None:
json={"name": "越权策略", "formula": _formula()},
)
assert rejected.status_code == 403
denied_compile = await client.post(
"/api/screener/formula/compile",
headers=csrf_headers(regular),
json={"description": "选择成交活跃且趋势较强的股票"},
)
assert denied_compile.status_code == 403
use_session(client, admin)
model = await client.post(
"/api/admin/models",
headers=csrf_headers(admin),
json={
"display_name": "公式模型",
"base_url": "https://model.example.com/v1",
"model_identifier": "formula-model",
"api_key": "formula-secret",
},
)
assert model.status_code == 201
application.state.container.llm._provider = FormulaProvider()
compiled = await client.post(
"/api/screener/formula/compile",
headers=csrf_headers(admin),
json={"description": "成交额至少3亿元,偏重20日走势和板块强度"},
)
assert compiled.status_code == 200
assert [item["weight"] for item in compiled.json()["formula"]["score"]] == [
0.6,
0.4,
]
assert compiled.json()["formula"]["min_score"] == 0.55
workspace = await client.get("/api/screener?date=2026-07-30")
assert workspace.status_code == 200
assert workspace.json()["trade_date"] is None