Add multifeature direct horizon Torch forecaster

This commit is contained in:
Codex
2026-06-22 07:29:50 +03:00
parent 544b0f4409
commit 42f96f0a39
8 changed files with 537 additions and 93 deletions
+3
View File
@@ -46,4 +46,7 @@ def test_safe_config_summarizes_torch_forecast_artifact(make_settings, tmp_path)
"created_at": "2026-06-20T18:15:05+00:00",
"symbol_count": 2,
"models": ["PyTorch GRU", "PyTorch LSTM"],
"feature_count": 1,
"target_horizon": 0,
"direct_horizon": False,
}
+67
View File
@@ -77,6 +77,53 @@ def _write_torch_gru_artifact(
)
def _write_multifeature_torch_gru_artifact(path, *, head_bias: float) -> None:
hidden_size = 2
input_size = 2
path.write_text(
json.dumps(
{
"version": 3,
"type": "pytorch_recurrent_forecaster",
"target_horizon": 3,
"direct_horizon": True,
"feature_count": input_size,
"feature_names": ["return_1", "range_percent"],
"symbols": {
"BTCUSDT": {
"model": "torch_gru",
"architecture": "gru",
"lookback": 8,
"target_horizon": 3,
"direct_horizon": True,
"input_size": input_size,
"feature_names": ["return_1", "range_percent"],
"feature_means": [0.0, 0.0],
"feature_scales": [0.001, 0.001],
"target_mean": 0.0,
"target_scale": 0.001,
"hidden_size": hidden_size,
"num_layers": 1,
"clip": 8.0,
"validation_mae_percent": 0.01,
"baseline_mae_percent": 0.08,
"skill": 0.2,
"state_dict": {
"weight_ih_l0": [[0.0, 0.0] for _ in range(3 * hidden_size)],
"weight_hh_l0": [[0.0, 0.0] for _ in range(3 * hidden_size)],
"bias_ih_l0": [0.0 for _ in range(3 * hidden_size)],
"bias_hh_l0": [0.0 for _ in range(3 * hidden_size)],
},
"head_weight": [0.0, 0.0],
"head_bias": head_bias,
},
},
}
),
encoding="utf-8",
)
def test_time_series_forecaster_requires_torch_artifact(make_settings, tmp_path) -> None:
settings = make_settings(
tmp_path,
@@ -166,3 +213,23 @@ def test_time_series_forecaster_reads_torch_gru_artifact(make_settings, tmp_path
assert forecast.candidates == [{"model": "torch_gru", "mae_percent": 0.02}]
assert forecast.expected_return_percent > 0
assert forecast.probability_up > 0.5
def test_time_series_forecaster_reads_multifeature_direct_horizon_artifact(make_settings, tmp_path) -> None:
artifact_path = tmp_path / "lstm_forecaster.json"
_write_multifeature_torch_gru_artifact(artifact_path, head_bias=0.2)
settings = make_settings(
tmp_path,
time_series_min_candles=80,
time_series_forecast_horizon=3,
time_series_lstm_model_path=artifact_path,
)
returns = [0.00015 if index % 4 else -0.00005 for index in range(140)]
forecast = TimeSeriesForecaster(settings).forecast(_candles_from_returns(returns), symbol="BTCUSDT")
assert forecast.usable is True
assert forecast.model == "torch_gru"
assert forecast.horizon == 3
assert 0.015 <= forecast.expected_return_percent <= 0.025
assert forecast.volatility_model == "direct horizon validation MAE"