Add Torch probe entries and Pi artifact sync
This commit is contained in:
@@ -118,6 +118,10 @@ class Settings:
|
||||
time_series_max_adjustment: float
|
||||
time_series_lstm_enabled: bool
|
||||
time_series_lstm_model_path: Path
|
||||
time_series_probe_enabled: bool
|
||||
time_series_probe_min_edge_percent: float
|
||||
time_series_probe_min_probability_up: float
|
||||
time_series_probe_size_multiplier: float
|
||||
stop_loss_percent: float
|
||||
take_profit_percent: float
|
||||
trailing_stop_percent: float
|
||||
@@ -266,6 +270,10 @@ def load_settings(env_file: str | Path | None = None) -> Settings:
|
||||
time_series_max_adjustment=_float_env("TIME_SERIES_MAX_ADJUSTMENT", 0.08),
|
||||
time_series_lstm_enabled=_bool_env("TIME_SERIES_LSTM_ENABLED", True),
|
||||
time_series_lstm_model_path=Path(os.getenv("TIME_SERIES_LSTM_MODEL_PATH", "runtime/lstm_forecaster.json")),
|
||||
time_series_probe_enabled=_bool_env("TIME_SERIES_PROBE_ENABLED", True),
|
||||
time_series_probe_min_edge_percent=_float_env("TIME_SERIES_PROBE_MIN_EDGE_PERCENT", 0.02),
|
||||
time_series_probe_min_probability_up=_float_env("TIME_SERIES_PROBE_MIN_PROBABILITY_UP", 0.55),
|
||||
time_series_probe_size_multiplier=_float_env("TIME_SERIES_PROBE_SIZE_MULTIPLIER", 0.40),
|
||||
stop_loss_percent=_float_env("STOP_LOSS_PERCENT", 0.04),
|
||||
take_profit_percent=_float_env("TAKE_PROFIT_PERCENT", 0.035),
|
||||
trailing_stop_percent=_float_env("TRAILING_STOP_PERCENT", 0.015),
|
||||
|
||||
@@ -261,6 +261,10 @@ def _safe_config(settings: Settings) -> dict[str, Any]:
|
||||
"time_series_max_adjustment": settings.time_series_max_adjustment,
|
||||
"time_series_lstm_enabled": settings.time_series_lstm_enabled,
|
||||
"time_series_lstm_model_path": str(settings.time_series_lstm_model_path),
|
||||
"time_series_probe_enabled": settings.time_series_probe_enabled,
|
||||
"time_series_probe_min_edge_percent": settings.time_series_probe_min_edge_percent,
|
||||
"time_series_probe_min_probability_up": settings.time_series_probe_min_probability_up,
|
||||
"time_series_probe_size_multiplier": settings.time_series_probe_size_multiplier,
|
||||
"time_series_model_artifact": _time_series_model_artifact(settings),
|
||||
"stop_loss_percent": settings.stop_loss_percent,
|
||||
"take_profit_percent": settings.take_profit_percent,
|
||||
@@ -678,7 +682,8 @@ HTML = r"""
|
||||
['Horizon', String(artifact.target_horizon ?? '')],
|
||||
['Min edge', `${num(config?.time_series_min_edge_percent, 3)}%`],
|
||||
['Min P(up)', `${num((config?.time_series_min_probability_up || 0) * 100, 1)}%`],
|
||||
['Min confidence', num(config?.time_series_min_confidence, 3)]
|
||||
['Min confidence', num(config?.time_series_min_confidence, 3)],
|
||||
['Probe entry', config?.time_series_probe_enabled ? `${num(config?.time_series_probe_min_edge_percent, 3)}% / P ${num((config?.time_series_probe_min_probability_up || 0) * 100, 1)}% / size ${num((config?.time_series_probe_size_multiplier || 0) * 100, 0)}%` : 'off']
|
||||
]))}
|
||||
</div>
|
||||
${positionsPanel()}
|
||||
@@ -699,6 +704,9 @@ HTML = r"""
|
||||
const quality = market.quality || {};
|
||||
const signal = latestSignals[symbol] || {};
|
||||
const minEdge = state.data.config?.time_series_min_edge_percent ?? 0;
|
||||
const probeEnabled = Boolean(state.data.config?.time_series_probe_enabled);
|
||||
const probeEdge = state.data.config?.time_series_probe_min_edge_percent ?? 0;
|
||||
const probeProbability = state.data.config?.time_series_probe_min_probability_up ?? 0;
|
||||
const minConfidence = state.data.config?.time_series_min_confidence ?? 0;
|
||||
const diagnostics = parseDiagnostics(signal);
|
||||
const failed = Object.entries(diagnostics.checks || {}).filter(([, ok]) => !ok).map(([key]) => key);
|
||||
@@ -716,6 +724,7 @@ HTML = r"""
|
||||
['Model', modelName(forecast.model)],
|
||||
['Edge', `${signed(forecast.expected_return_percent, 4)}% / min ${num(minEdge, 3)}%`],
|
||||
['P(up)', num((forecast.probability_up || 0) * 100, 2) + '%'],
|
||||
['Probe', probeEnabled ? `${num(probeEdge, 3)}% / P ${num(probeProbability * 100, 1)}% / ${diagnostics.edge_mode || 'n/a'}` : 'off'],
|
||||
['Confidence', `${num(signal.confidence, 4)} / min ${num(minConfidence, 2)}`],
|
||||
['Q10/Q50/Q90', `${signed(forecast.quantile_10_percent, 2)} / ${signed(forecast.quantile_50_percent, 2)} / ${signed(forecast.quantile_90_percent, 2)}`],
|
||||
['Blocked', forecast.block_entry ? 'yes' : 'no']
|
||||
|
||||
@@ -633,6 +633,34 @@ def _torch_forecast_entry_signal(
|
||||
skill = _safe_float(forecast.get("skill"), 0.0)
|
||||
min_edge = max(0.0, settings.time_series_min_edge_percent)
|
||||
min_probability = _torch_min_probability(settings)
|
||||
probe_min_edge = max(0.0, min(settings.time_series_probe_min_edge_percent, min_edge))
|
||||
probe_min_probability = round(
|
||||
_clamp(settings.time_series_probe_min_probability_up, min_probability, 0.85),
|
||||
4,
|
||||
)
|
||||
full_edge_ok = expected_return >= min_edge
|
||||
probe_edge_ok = bool(
|
||||
settings.time_series_probe_enabled
|
||||
and not full_edge_ok
|
||||
and expected_return >= probe_min_edge
|
||||
and probability_up >= probe_min_probability
|
||||
)
|
||||
edge_mode = "full" if full_edge_ok else ("probe" if probe_edge_ok else "blocked")
|
||||
if probe_edge_ok and position_notional > 0:
|
||||
probe_multiplier = _clamp(settings.time_series_probe_size_multiplier, 0.05, 1.0)
|
||||
position_notional = round(
|
||||
min(
|
||||
settings.max_position_usdt,
|
||||
max(settings.min_position_usdt, position_notional * probe_multiplier),
|
||||
),
|
||||
2,
|
||||
)
|
||||
sizing = {
|
||||
**sizing,
|
||||
"notional_usdt": position_notional,
|
||||
"probe_size_multiplier": round(probe_multiplier, 4),
|
||||
"edge_mode": "probe",
|
||||
}
|
||||
confidence = _torch_forecast_confidence(settings, forecast)
|
||||
spread_ok = ticker.spread_percent <= settings.max_spread_percent
|
||||
liquidity_ok = ticker.turnover_24h >= settings.min_24h_turnover_usdt
|
||||
@@ -641,7 +669,7 @@ def _torch_forecast_entry_signal(
|
||||
"torch_model_ok": model_ok,
|
||||
"forecast_usable": bool(forecast.get("usable", False)),
|
||||
"forecast_not_blocked": not bool(forecast.get("block_entry", False)),
|
||||
"expected_edge_ok": expected_return >= min_edge,
|
||||
"expected_edge_ok": full_edge_ok or probe_edge_ok,
|
||||
"probability_ok": probability_up >= min_probability,
|
||||
"skill_ok": skill > 0.0,
|
||||
"confidence_ok": confidence >= settings.time_series_min_confidence,
|
||||
@@ -659,6 +687,10 @@ def _torch_forecast_entry_signal(
|
||||
"atr_trailing_multiplier": _clamp(settings.atr_trailing_multiplier, 0.5, 10.0),
|
||||
"expected_return_percent": expected_return,
|
||||
"min_edge_percent": min_edge,
|
||||
"probe_enabled": settings.time_series_probe_enabled,
|
||||
"probe_min_edge_percent": probe_min_edge,
|
||||
"probe_min_probability_up": probe_min_probability,
|
||||
"edge_mode": edge_mode,
|
||||
"probability_up": probability_up,
|
||||
"min_probability_up": min_probability,
|
||||
"min_confidence": settings.time_series_min_confidence,
|
||||
@@ -679,7 +711,8 @@ def _torch_forecast_entry_signal(
|
||||
(
|
||||
"torch_forecast: PyTorch edge confirmed; "
|
||||
f"model={forecast.get('model')}, p_up={probability_up:.3f}, "
|
||||
f"expected={expected_return:.4f}%, size={position_notional:.2f} USDT"
|
||||
f"expected={expected_return:.4f}%, edge_mode={edge_mode}, "
|
||||
f"size={position_notional:.2f} USDT"
|
||||
),
|
||||
diagnostics,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user