from near_miss import effective_required_drop_pct
from strategy_registry import load_strategy_presets, preset_to_config


def test_candidate_v63_sweep_winner_is_registered() -> None:
    presets = load_strategy_presets()
    preset = presets["candidate_v63_loose_fast_decay"]

    assert preset.parameters["flash_crash_trigger_pct"] == 4.0
    assert preset.parameters["dead_fish_time_limit_mins"] == 25
    assert preset.parameters["v_shape_trail_dist_pct"] == 0.5
    assert "sweep-winner" in preset.tags


def test_candidate_v64_uses_pre_handover_survival_lessons() -> None:
    presets = load_strategy_presets()

    strict = presets["candidate_v64_squeeze_survival_strict"]
    wide = presets["candidate_v64_squeeze_survival_wide"]

    for preset in (strict, wide):
        assert "pre-handover-lessons" in preset.tags
        assert "paper-only" in preset.tags
        assert preset.parameters["dead_fish_time_limit_mins"] <= 15
        assert preset.parameters["max_hard_stop_pct"] <= 3.0
        assert 0.4 <= preset.parameters["break_even_activation_pct"] <= 0.75
        assert preset.parameters["trade_size_usd"] <= 50.0

    assert strict.parameters["flash_crash_trigger_pct"] >= wide.parameters["flash_crash_trigger_pct"]
    assert strict.parameters["v_shape_trail_dist_pct"] <= wide.parameters["v_shape_trail_dist_pct"]


def test_candidate_v65_signal_samplers_are_research_only() -> None:
    presets = load_strategy_presets()
    conservative = presets["candidate_v65_signal_sampler_conservative"]
    aggressive = presets["candidate_v65_signal_sampler_aggressive"]

    for preset in (conservative, aggressive):
        assert "paper-only" in preset.tags
        assert "research-sampler" in preset.tags
        assert "not-champion" in preset.tags
        assert preset.parameters["trade_size_usd"] <= 20.0
        assert preset.parameters["position_sizing_mode"] == "risk"
        assert preset.parameters["wallet_equity_usdc"] == 500.0
        assert preset.parameters["risk_per_trade_pct"] <= 0.5
        assert preset.parameters["max_position_margin_pct"] <= 10.0
        assert preset.parameters["max_total_trades"] <= 2
        assert preset.parameters["dead_fish_time_limit_mins"] <= 10
        assert preset.parameters["max_hard_stop_pct"] <= 2.0
        assert preset.parameters["break_even_activation_pct"] <= 0.35
        assert preset.parameters["cooldown_minutes"] <= 45

    assert conservative.parameters["flash_crash_trigger_pct"] == 3.0
    assert aggressive.parameters["flash_crash_trigger_pct"] == 2.5
    assert aggressive.parameters["trade_size_usd"] < conservative.parameters["trade_size_usd"]


def test_candidate_v65_sampler_roe_normalization_preserves_sampler_thresholds() -> None:
    presets = load_strategy_presets()
    conservative = preset_to_config(presets["candidate_v65_signal_sampler_conservative"])
    aggressive = preset_to_config(presets["candidate_v65_signal_sampler_aggressive"])

    assert effective_required_drop_pct(conservative, "WLD") == 3.0
    assert effective_required_drop_pct(conservative, "HYPE") == 3.0
    assert effective_required_drop_pct(aggressive, "WLD") == 2.5
    assert effective_required_drop_pct(aggressive, "HYPE") == 2.5


def test_candidate_v66_squeeze_breakout_sampler_is_research_only() -> None:
    presets = load_strategy_presets()
    preset = presets["candidate_v66_squeeze_breakout_sampler"]
    cfg = preset_to_config(preset)

    assert "paper-only" in preset.tags
    assert "research-sampler" in preset.tags
    assert "not-champion" in preset.tags
    assert "squeeze-breakout" in preset.tags
    assert cfg.strategy_family == "volatility_squeeze_breakout"
    assert cfg.position_sizing_mode == "risk"
    assert cfg.wallet_equity_usdc == 500.0
    assert cfg.risk_per_trade_pct == 0.75
    assert cfg.max_position_margin_pct == 20.0
    assert cfg.trade_size_usd <= 15.0
    assert cfg.max_total_trades <= 2
    assert cfg.squeeze_max_band_width_pct == 2.5
    assert cfg.squeeze_breakout_pct == 1.2
    assert cfg.dead_fish_time_limit_mins <= 12
    assert cfg.max_hard_stop_pct <= 2.0
