feat: add selectable daily backtest cadence
This commit is contained in:
+37
-10
@@ -37,8 +37,10 @@ from app.services import fundamental_service, ingestion_service, sentiment_servi
|
||||
from app.services.alert_service import dispatch_alerts
|
||||
from app.services.backtest_service import (
|
||||
BACKTEST_TARGET_MODELS,
|
||||
DEFAULT_BACKTEST_CADENCE,
|
||||
PRODUCTION_GTL_TARGET_MODEL,
|
||||
run_and_store as run_backtest_and_store,
|
||||
validate_backtest_cadence,
|
||||
validate_backtest_target_model,
|
||||
)
|
||||
from app.services.benchmark_service import refresh_benchmark_prices
|
||||
@@ -112,6 +114,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
|
||||
_next_backtest_cadence = DEFAULT_BACKTEST_CADENCE
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -119,23 +122,44 @@ _next_backtest_target_model = PRODUCTION_GTL_TARGET_MODEL
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def queue_backtest_target_model(target_model: str | None) -> str:
|
||||
"""Select the model for the next manual backtest run only.
|
||||
def queue_backtest_options(
|
||||
target_model: str | None,
|
||||
cadence: str | None,
|
||||
) -> tuple[str, str]:
|
||||
"""Select model and cadence for the next manual backtest run only.
|
||||
|
||||
Scheduled runs and subsequent manual runs return to the production GTL.
|
||||
Scheduled and subsequent manual runs return to production GTL at the
|
||||
resource-safe weekly cadence.
|
||||
"""
|
||||
global _next_backtest_target_model
|
||||
selected = validate_backtest_target_model(
|
||||
global _next_backtest_target_model, _next_backtest_cadence
|
||||
selected_model = validate_backtest_target_model(
|
||||
target_model or PRODUCTION_GTL_TARGET_MODEL
|
||||
)
|
||||
_next_backtest_target_model = selected
|
||||
selected_cadence = validate_backtest_cadence(
|
||||
cadence or DEFAULT_BACKTEST_CADENCE
|
||||
)
|
||||
_next_backtest_target_model = selected_model
|
||||
_next_backtest_cadence = selected_cadence
|
||||
return selected_model, selected_cadence
|
||||
|
||||
|
||||
def queue_backtest_target_model(target_model: str | None) -> str:
|
||||
"""Compatibility wrapper for callers selecting only the target model."""
|
||||
selected, _ = queue_backtest_options(target_model, DEFAULT_BACKTEST_CADENCE)
|
||||
return selected
|
||||
|
||||
|
||||
def _consume_backtest_options() -> tuple[str, str]:
|
||||
global _next_backtest_target_model, _next_backtest_cadence
|
||||
selected = (_next_backtest_target_model, _next_backtest_cadence)
|
||||
_next_backtest_target_model = PRODUCTION_GTL_TARGET_MODEL
|
||||
_next_backtest_cadence = DEFAULT_BACKTEST_CADENCE
|
||||
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
|
||||
"""Compatibility wrapper consuming all queued one-run options."""
|
||||
selected, _ = _consume_backtest_options()
|
||||
return selected
|
||||
|
||||
|
||||
@@ -1028,12 +1052,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"
|
||||
target_model = _consume_backtest_target_model()
|
||||
target_model, cadence = _consume_backtest_options()
|
||||
_log_event(
|
||||
logging.INFO,
|
||||
"job_start",
|
||||
job=job_name,
|
||||
target_model=target_model,
|
||||
cadence=cadence,
|
||||
)
|
||||
_runtime_start(job_name)
|
||||
|
||||
@@ -1051,6 +1076,7 @@ async def run_backtest_job() -> None:
|
||||
db,
|
||||
_on_progress,
|
||||
target_model=target_model,
|
||||
cadence=cadence,
|
||||
)
|
||||
|
||||
_runtime_finish(
|
||||
@@ -1058,6 +1084,7 @@ async def run_backtest_job() -> None:
|
||||
processed=report.get("tickers", 0), total=report.get("tickers", 0),
|
||||
message=(
|
||||
f"{BACKTEST_TARGET_MODELS[target_model]}: "
|
||||
f"{cadence} cadence, "
|
||||
f"{report.get('candidates', 0)} setups, "
|
||||
f"{report.get('qualified', 0)} qualified"
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user