from app.config.config_loader import get_signal_weights from app.core.factor_scoring import FactorScorer def test_factor_scorer_eliminates_zero_weight_factor(): scorer = FactorScorer(weights={"vp_fly_1h_current": 0}) delta = scorer.delta("vp_fly_1h_current", 8, evidence="unit") assert delta == 0 assert scorer.summary()["items"][0]["source"] == "review_weight" def test_factor_scorer_promotes_reviewed_factor(): scorer = FactorScorer(weights={"vp_fly_1h_current": 7.5}) delta = scorer.delta("vp_fly_1h_current", 5, evidence="unit") assert delta == 7.5 assert scorer.summary()["items"][0]["multiplier"] == 1.5 def test_factor_scorer_caps_repeated_same_group_signals(): scorer = FactorScorer(weights={}) first = scorer.delta("vp_fly_1h_current", 10, evidence="first momentum") second = scorer.delta("ignition_1h_current", 10, evidence="second momentum") summary = scorer.summary() assert first == 10 assert second == 6 assert summary["groups"]["momentum"]["score_delta"] == 16 assert summary["opportunity_score"] == 16 def test_factor_scorer_records_negative_risk_as_risk_score(): scorer = FactorScorer(weights={}) delta = scorer.delta("false_breakout", -5, evidence="unit risk") summary = scorer.summary() assert delta == -5 assert summary["groups"]["risk"]["score_delta"] == -5 assert summary["risk_score"] == 5 def test_signal_weight_alias_keeps_legacy_chinese_keys_available(monkeypatch): monkeypatch.setattr("app.config.config_loader._load_yaml_baseline", lambda: {"signal_weights": {"量价齐飞": 5}}) monkeypatch.setattr("app.db.altcoin_db.get_signal_weights", lambda: {}) weights = get_signal_weights() assert weights["vp_fly_1h_current"] == 5 assert weights["量价齐飞"] == 5 def test_signal_weight_ignores_thin_dynamic_samples(monkeypatch): monkeypatch.setattr( "app.config.config_loader._load_yaml_baseline", lambda: {"signal_weights": {"量价齐飞": 5}}, ) monkeypatch.setattr( "app.config.config_loader.load_rules", lambda: { "review": { "min_samples_for_weight": 12, "signal_deprecation": {"min_samples": 20}, }, }, ) monkeypatch.setattr( "app.db.altcoin_db.get_signal_weights", lambda: { "vp_fly_1h_current": { "weight": 0, "total_count": 3, "hit_rate": 0, "avg_pnl": -1, } }, ) weights = get_signal_weights() assert weights["vp_fly_1h_current"] == 5