File size: 2,383 Bytes
e610a2f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import pandas as pd
import pytest

from scripts.search_external_factor_weight_grid import (
    load_external_factor_scores,
    merge_external_scores,
)


def test_load_external_factor_scores_normalizes_and_combines_sources(tmp_path):
    chipk = tmp_path / "chipk.csv"
    crowd = tmp_path / "crowd.csv"
    chipk.write_text(
        "stock,date,bull_score,bear_score\n"
        "2330,2026/05/01,2,0\n"
        "50,2026-05-01,1,0\n",
        encoding="utf-8",
    )
    crowd.write_text(
        "stock,date,bull_score,bear_score\n"
        "2330.TW,2026-05-01,0.5,1\n",
        encoding="utf-8",
    )

    scores = load_external_factor_scores([chipk, crowd])

    row_2330 = scores[(scores["stock"] == "2330") & (scores["date"] == "2026-05-01")].iloc[0]
    row_0050 = scores[(scores["stock"] == "0050") & (scores["date"] == "2026-05-01")].iloc[0]
    assert row_2330["bull_score"] == 2.5
    assert row_2330["bear_score"] == 1.0
    assert row_2330["source_count"] == 2
    assert row_0050["bull_score"] == 1.0


def test_load_external_factor_scores_requires_configured_columns(tmp_path):
    path = tmp_path / "bad.csv"
    path.write_text("stock,date,bull_score\n2330,2026-05-01,1\n", encoding="utf-8")

    with pytest.raises(ValueError, match="missing required column"):
        load_external_factor_scores([path])


def test_merge_external_scores_replaces_generic_factor_scores():
    events = pd.DataFrame(
        {
            "stock": ["2330", "2330", "0050"],
            "date": ["2026-05-01", "2026-05-02", "2026-05-01"],
            "p_buy": [0.4, 0.4, 0.4],
            "p_hold": [0.5, 0.5, 0.5],
            "p_sell": [0.1, 0.1, 0.1],
            "y_true": [1, 0, 1],
            "base_pred": [0, 0, 0],
            "bull_score": [9.0, 9.0, 9.0],
            "bear_score": [9.0, 9.0, 9.0],
        }
    )
    external = pd.DataFrame(
        {
            "stock": ["2330"],
            "date": ["2026-05-01"],
            "bull_score": [3.0],
            "bear_score": [1.0],
            "source_count": [1],
        }
    )

    merged, summary = merge_external_scores(events, external)

    assert summary["matched_event_count"] == 1
    assert summary["coverage"] == 0.3333
    assert merged.loc[0, "bull_score"] == 3.0
    assert merged.loc[0, "bear_score"] == 1.0
    assert merged.loc[1, "bull_score"] == 0.0
    assert merged.loc[2, "bear_score"] == 0.0