fix: calibrate dynamic model symbols
This commit is contained in:
@@ -8,6 +8,7 @@ from tools.calibrate_torch_thresholds import (
|
|||||||
_average_selected_predictions,
|
_average_selected_predictions,
|
||||||
_apply_platt_calibration,
|
_apply_platt_calibration,
|
||||||
_build_torch_model,
|
_build_torch_model,
|
||||||
|
_calibration_symbols,
|
||||||
_choose_recommendation,
|
_choose_recommendation,
|
||||||
_full_backtest,
|
_full_backtest,
|
||||||
_fit_platt_calibration,
|
_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:
|
def test_calibration_does_not_fallback_to_too_few_trades() -> None:
|
||||||
selected = _choose_recommendation(
|
selected = _choose_recommendation(
|
||||||
[_result(trades=1, average=2.0, total=2.0, profit_factor=999.0)],
|
[_result(trades=1, average=2.0, total=2.0, profit_factor=999.0)],
|
||||||
|
|||||||
@@ -88,13 +88,13 @@ def main() -> None:
|
|||||||
if torch is not None and args.threads > 0:
|
if torch is not None and args.threads > 0:
|
||||||
torch.set_num_threads(args.threads)
|
torch.set_num_threads(args.threads)
|
||||||
settings = load_settings(args.env)
|
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_path = Path(args.artifact or settings.time_series_lstm_model_path)
|
||||||
artifact_bytes = artifact_path.read_bytes()
|
artifact_bytes = artifact_path.read_bytes()
|
||||||
artifact_sha256 = hashlib.sha256(artifact_bytes).hexdigest()
|
artifact_sha256 = hashlib.sha256(artifact_bytes).hexdigest()
|
||||||
artifact = json.loads(artifact_bytes.decode("utf-8"))
|
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
|
horizon = args.horizon if args.horizon > 0 else settings.time_series_forecast_horizon
|
||||||
round_trip_cost = _artifact_round_trip_cost(artifact, settings)
|
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 = argparse.ArgumentParser(description="Calibrate TradeBot Torch forecast entry thresholds.")
|
||||||
parser.add_argument("--env", default=None, help="Path to .env file.")
|
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("--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("--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("--limit", type=int, default=2000, help="Hourly candles per symbol.")
|
||||||
parser.add_argument("--trend-limit", type=int, default=320, help="Daily 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]
|
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(
|
def _forecast_records(
|
||||||
*,
|
*,
|
||||||
symbol: str,
|
symbol: str,
|
||||||
|
|||||||
Reference in New Issue
Block a user