Shift adaptive learning to growth sizing

This commit is contained in:
Codex
2026-06-21 08:16:03 +03:00
parent 7bbb721da1
commit 25651d7fa7
9 changed files with 144 additions and 42 deletions
+46 -9
View File
@@ -60,16 +60,18 @@ def test_trade_learner_builds_adaptive_rules_for_losing_ema_exit(make_settings,
state = learner.refresh()
rules = learner.rules_for("BTCUSDT", "нейтрально")
assert state.adaptive_rules["risk_mode"] == "defensive"
assert state.adaptive_rules["risk_mode"] == "selective"
assert state.adaptive_rules["trade_permission"] == "selective_growth"
assert state.adaptive_rules["reduce_exposure"] is False
assert rules["ema_exit_mode"] == "profit_only"
assert rules["effective_entry_threshold_adjustment"] > 0
assert rules["min_hold_seconds"] > settings.min_hold_seconds
assert rules["min_hold_seconds"] == settings.min_hold_seconds
def test_trade_learner_enters_capital_protection_and_validates_rules(make_settings, tmp_path) -> None:
def test_trade_learner_blocks_only_bad_symbol_pattern(make_settings, tmp_path) -> None:
settings = make_settings(tmp_path, learning_min_samples=3, starting_balance_usdt=100, max_total_exposure_usdt=80)
storage = Storage(settings.database_path)
for value in (-0.12, -0.10, -0.08):
for _ in range(9):
storage.insert_trade(
Trade(
id=None,
@@ -78,7 +80,7 @@ def test_trade_learner_enters_capital_protection_and_validates_rules(make_settin
qty=1,
entry_price=100,
exit_price=99,
net_pnl=value,
net_pnl=-0.10,
reason="краткосрочный тренд ослаб ниже EMA50",
entry_pattern="нейтрально",
entry_confidence=0.7,
@@ -91,9 +93,44 @@ def test_trade_learner_enters_capital_protection_and_validates_rules(make_settin
state = learner.refresh()
rules = state.adaptive_rules
assert rules["trade_permission"] == "capital_protection"
assert rules["reduce_exposure"] is True
assert rules["bad_market_entry_block"] is True
assert rules["target_total_exposure_usdt"] == 35.0
assert rules["trade_permission"] == "selective_growth"
assert rules["reduce_exposure"] is False
assert rules["bad_market_entry_block"] is False
assert rules["target_total_exposure_usdt"] == settings.max_total_exposure_usdt
assert rules["blocked_symbols"] == ["ETHUSDT"]
assert rules["blocked_patterns"] == ["нейтрально"]
assert rules["validation"]["status"] == "accepted"
assert rules["validation"]["avoided_loss_usdt"] > 0
def test_trade_learner_scales_positive_expectancy_setups(make_settings, tmp_path) -> None:
settings = make_settings(tmp_path, learning_min_samples=3, learning_max_position_multiplier=1.5)
storage = Storage(settings.database_path)
for _ in range(4):
storage.insert_trade(
Trade(
id=None,
symbol="SOLUSDT",
side="SELL",
qty=1,
entry_price=100,
exit_price=101,
net_pnl=0.08,
reason="test",
entry_pattern="пробой вверх",
entry_confidence=0.8,
opened_at=utc_now(),
closed_at=utc_now(),
)
)
learner = TradeLearner(settings, storage)
state = learner.refresh()
rules = learner.rules_for("SOLUSDT", "пробой вверх")
assert state.adaptive_rules["trade_permission"] == "positive_expectancy"
assert state.adaptive_rules["risk_mode"] == "growth"
assert rules["effective_entry_threshold_adjustment"] < 0
assert rules["symbol_position_size_multiplier"] > 1.0
assert rules["pattern_position_size_multiplier"] > 1.0
assert 1.0 < rules["effective_position_size_multiplier"] <= settings.learning_max_position_multiplier