Finalize GTL and retire S/R research harness
This commit is contained in:
+44
-4
@@ -35,7 +35,12 @@ from app.providers.fundamentals_chain import build_fundamental_provider_chain
|
||||
from app.providers.protocol import SentimentData
|
||||
from app.services import fundamental_service, ingestion_service, sentiment_service, settings_store
|
||||
from app.services.alert_service import dispatch_alerts
|
||||
from app.services.backtest_service import run_and_store as run_backtest_and_store
|
||||
from app.services.backtest_service import (
|
||||
BACKTEST_TARGET_MODELS,
|
||||
PRODUCTION_GTL_TARGET_MODEL,
|
||||
run_and_store as run_backtest_and_store,
|
||||
validate_backtest_target_model,
|
||||
)
|
||||
from app.services.benchmark_service import refresh_benchmark_prices
|
||||
from app.services.market_regime_service import update_market_regime
|
||||
from app.services.regime_monitor_service import update_regime_monitor
|
||||
@@ -106,6 +111,7 @@ def _idle_runtime() -> dict[str, object]:
|
||||
|
||||
|
||||
_job_runtime: dict[str, dict[str, object]] = {name: _idle_runtime() for name in _JOB_NAMES}
|
||||
_next_backtest_target_model = PRODUCTION_GTL_TARGET_MODEL
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -113,6 +119,26 @@ _job_runtime: dict[str, dict[str, object]] = {name: _idle_runtime() for name in
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def queue_backtest_target_model(target_model: str | None) -> str:
|
||||
"""Select the model for the next manual backtest run only.
|
||||
|
||||
Scheduled runs and subsequent manual runs return to the production GTL.
|
||||
"""
|
||||
global _next_backtest_target_model
|
||||
selected = validate_backtest_target_model(
|
||||
target_model or PRODUCTION_GTL_TARGET_MODEL
|
||||
)
|
||||
_next_backtest_target_model = selected
|
||||
return selected
|
||||
|
||||
|
||||
def _consume_backtest_target_model() -> str:
|
||||
global _next_backtest_target_model
|
||||
selected = _next_backtest_target_model
|
||||
_next_backtest_target_model = PRODUCTION_GTL_TARGET_MODEL
|
||||
return selected
|
||||
|
||||
|
||||
def _log_event(level: int, event: str, **fields: object) -> None:
|
||||
"""Emit a structured JSON log line: {"event": ..., **fields}."""
|
||||
logger.log(level, json.dumps({"event": event, **fields}))
|
||||
@@ -939,7 +965,13 @@ async def compute_regime_monitor() -> None:
|
||||
async def run_backtest_job() -> None:
|
||||
"""Replay the price-derived engine over history and cache the report."""
|
||||
job_name = "backtest"
|
||||
_log_event(logging.INFO, "job_start", job=job_name)
|
||||
target_model = _consume_backtest_target_model()
|
||||
_log_event(
|
||||
logging.INFO,
|
||||
"job_start",
|
||||
job=job_name,
|
||||
target_model=target_model,
|
||||
)
|
||||
_runtime_start(job_name)
|
||||
|
||||
def _on_progress(done: int, count: int, symbol: str) -> None:
|
||||
@@ -952,12 +984,20 @@ async def run_backtest_job() -> None:
|
||||
_runtime_finish(job_name, "skipped", processed=0, total=0, message="Disabled")
|
||||
return
|
||||
|
||||
report = await run_backtest_and_store(db, _on_progress)
|
||||
report = await run_backtest_and_store(
|
||||
db,
|
||||
_on_progress,
|
||||
target_model=target_model,
|
||||
)
|
||||
|
||||
_runtime_finish(
|
||||
job_name, "completed",
|
||||
processed=report.get("tickers", 0), total=report.get("tickers", 0),
|
||||
message=f"{report.get('candidates', 0)} setups, {report.get('qualified', 0)} qualified",
|
||||
message=(
|
||||
f"{BACKTEST_TARGET_MODELS[target_model]}: "
|
||||
f"{report.get('candidates', 0)} setups, "
|
||||
f"{report.get('qualified', 0)} qualified"
|
||||
),
|
||||
)
|
||||
_log_event(logging.INFO, "job_complete", job=job_name, candidates=report.get("candidates"))
|
||||
except Exception as exc:
|
||||
|
||||
Reference in New Issue
Block a user