86 lines
2.6 KiB
Python
86 lines
2.6 KiB
Python
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
|