Files
sanguo_vnpy_v2/tests/factor/test_challenger_lgbm.py
T

39 lines
1.5 KiB
Python

"""LGBM challenger 三路对拍(spec §4.4 2026-10-10):数据层."""
import json
import numpy as np
import pandas as pd
import pytest
from sanguo_factor.challenger_lgbm import build_label, cs_rank_norm, load_pool
def test_load_pool_twelve_sources():
pool = load_pool()
assert len(pool) == 12
assert pool["vma_60"]["direction"] == "+"
assert pool["vol_ma5"]["direction"] == "-"
assert 0.0 < pool["alpha16"]["weight"] < 0.2
def test_build_label_gap_proof():
idx = pd.date_range("2025-01-01", periods=4, freq="D")
close = pd.DataFrame({"a": [10.0, 11.0, 12.0, 13.0], "b": [20.0, 20.0, 21.0, 22.0]}, index=idx)
lab = build_label(close)
# label[t]=close[t+2]/close[t+1]-1:t0 行=12/11-1
assert lab.iloc[0]["a"] == pytest.approx(12.0 / 11.0 - 1)
# 末两行无可成交区间=NaN
assert lab.iloc[-1].isna().all() and lab.iloc[-2].isna().all()
def test_cs_rank_norm_nan_passthrough_and_centered():
df = pd.DataFrame({"a": [1.0, 2.0, 3.0, np.nan],
"b": [4.0, 3.0, 2.0, 1.0]})
out = cs_rank_norm(df)
# 行2截面 [a=3.0, b=2.0]: a 为最大, rank pct 1.0 - 0.5 = 0.5
# (plan 原断言 0.75 与其自身注释"rank pct 1.0 - 0.5"矛盾, 按权威实现修正)
assert out.loc[2, "a"] == pytest.approx(0.5)
assert np.isnan(out.loc[3, "a"]) # NaN 透传不占截面
row0 = out.loc[0, ["a", "b"]].tolist()
assert row0 == [pytest.approx(0.0), pytest.approx(0.5)] # 截面最小/最大