fix: calibrate dynamic model symbols

This commit is contained in:
Курнат Андрей
2026-07-14 23:28:53 +03:00
parent 1c7701c38e
commit 51a7833896
2 changed files with 41 additions and 4 deletions
+16
View File
@@ -8,6 +8,7 @@ from tools.calibrate_torch_thresholds import (
_average_selected_predictions,
_apply_platt_calibration,
_build_torch_model,
_calibration_symbols,
_choose_recommendation,
_full_backtest,
_fit_platt_calibration,
@@ -62,6 +63,21 @@ def _record(index: int, probability: float, future: float) -> ForecastRecord:
)
def test_calibration_symbols_follow_explicit_configured_artifact_precedence() -> None:
artifact = {"symbols": {"btcusdt": {}, "ethusdt": {}}}
assert _calibration_symbols("solusdt, xrpusdt", ("ADAUSDT",), artifact) == [
"SOLUSDT",
"XRPUSDT",
]
assert _calibration_symbols("", ("ADAUSDT",), artifact) == ["ADAUSDT"]
assert _calibration_symbols("", (), artifact) == ["BTCUSDT", "ETHUSDT"]
def test_calibration_symbols_reject_malformed_artifact_symbols() -> None:
assert _calibration_symbols("", (), {"symbols": []}) == []
def test_calibration_does_not_fallback_to_too_few_trades() -> None:
selected = _choose_recommendation(
[_result(trades=1, average=2.0, total=2.0, profit_factor=999.0)],
+25 -4
View File
@@ -88,13 +88,13 @@ def main() -> None:
if torch is not None and args.threads > 0:
torch.set_num_threads(args.threads)
settings = load_settings(args.env)
client = BybitClient(settings)
symbols = _symbols(args.symbols, settings.symbols)
context_symbols = sorted(set(symbols + _symbols(args.context_symbols, ())))
artifact_path = Path(args.artifact or settings.time_series_lstm_model_path)
artifact_bytes = artifact_path.read_bytes()
artifact_sha256 = hashlib.sha256(artifact_bytes).hexdigest()
artifact = json.loads(artifact_bytes.decode("utf-8"))
client = BybitClient(settings)
symbols = _calibration_symbols(args.symbols, settings.symbols, artifact)
context_symbols = sorted(set(symbols + _symbols(args.context_symbols, ())))
horizon = args.horizon if args.horizon > 0 else settings.time_series_forecast_horizon
round_trip_cost = _artifact_round_trip_cost(artifact, settings)
@@ -277,7 +277,11 @@ def _parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Calibrate TradeBot Torch forecast entry thresholds.")
parser.add_argument("--env", default=None, help="Path to .env file.")
parser.add_argument("--artifact", default="", help="Path to lstm_forecaster.json.")
parser.add_argument("--symbols", default="", help="Comma-separated symbols. Defaults to configured fixed symbols.")
parser.add_argument(
"--symbols",
default="",
help="Comma-separated symbols. Defaults to configured fixed symbols, then artifact symbols.",
)
parser.add_argument("--context-symbols", default="BTCUSDT,ETHUSDT", help="Cross-asset context symbols.")
parser.add_argument("--limit", type=int, default=2000, help="Hourly candles per symbol.")
parser.add_argument("--trend-limit", type=int, default=320, help="Daily candles per symbol.")
@@ -308,6 +312,23 @@ def _symbols(raw: str, fallback: tuple[str, ...] | list[str]) -> list[str]:
return [str(item).upper() for item in fallback]
def _calibration_symbols(
raw: str,
configured: tuple[str, ...] | list[str],
artifact: dict[str, Any],
) -> list[str]:
explicit = _symbols(raw, ())
if explicit:
return explicit
fixed = _symbols("", configured)
if fixed:
return fixed
artifact_symbols = artifact.get("symbols")
if not isinstance(artifact_symbols, dict):
return []
return [str(symbol).strip().upper() for symbol in artifact_symbols if str(symbol).strip()]
def _forecast_records(
*,
symbol: str,