You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
71 lines
3.0 KiB
Python
71 lines
3.0 KiB
Python
from __future__ import annotations
|
|
|
|
import datetime as dt
|
|
|
|
from libs.export.continuation_snapshot import _build_continuation_rows_from_bars
|
|
|
|
|
|
def test_build_continuation_rows_reanchors_event_and_labels() -> None:
|
|
base_rows = [
|
|
{
|
|
"event_id": "EVT::AAPL::1",
|
|
"ticker": "AAPL",
|
|
"event_type": "earnings_release",
|
|
"event_date": "2026-01-05",
|
|
"reaction_date": "2026-01-05",
|
|
"entry_date": "2026-01-06",
|
|
"event_close": 100.0,
|
|
"parse_confidence_overall": 0.8,
|
|
"oneoff_penalty": 0.1,
|
|
}
|
|
]
|
|
bars_by_symbol = {
|
|
"AAPL": {
|
|
dt.date(2026, 1, 6): {"open": 101.0, "high": 103.0, "low": 100.0, "close": 102.0, "volume": 1000},
|
|
dt.date(2026, 1, 7): {"open": 102.0, "high": 104.0, "low": 101.0, "close": 103.0, "volume": 1100},
|
|
dt.date(2026, 1, 8): {"open": 103.0, "high": 105.0, "low": 102.0, "close": 104.0, "volume": 1200},
|
|
dt.date(2026, 1, 9): {"open": 104.0, "high": 108.0, "low": 103.0, "close": 107.0, "volume": 1400},
|
|
dt.date(2026, 1, 12): {"open": 108.0, "high": 110.0, "low": 107.0, "close": 109.0, "volume": 1500},
|
|
dt.date(2026, 1, 13): {"open": 109.0, "high": 111.0, "low": 108.0, "close": 110.0, "volume": 1600},
|
|
dt.date(2026, 1, 14): {"open": 110.0, "high": 112.0, "low": 109.0, "close": 111.0, "volume": 1700},
|
|
dt.date(2026, 1, 15): {"open": 111.0, "high": 113.0, "low": 110.0, "close": 112.0, "volume": 1800},
|
|
dt.date(2026, 1, 16): {"open": 112.0, "high": 114.0, "low": 111.0, "close": 113.0, "volume": 1900},
|
|
}
|
|
}
|
|
|
|
rows = _build_continuation_rows_from_bars(base_rows, bars_by_symbol, lookback_days=3)
|
|
assert len(rows) == 1
|
|
|
|
row = rows[0]
|
|
assert row["event_id"] == "EVT::AAPL::1::cont_d3"
|
|
assert row["original_event_id"] == "EVT::AAPL::1"
|
|
assert row["event_date"] == "2026-01-09"
|
|
assert row["reaction_date"] == "2026-01-09"
|
|
assert row["entry_date"] == "2026-01-12"
|
|
assert abs(row["continuation_anchor_drift_pct"] - 0.07) < 1e-9
|
|
assert row["entry_convention"] == "next_open_after_continuation_signal"
|
|
assert row["fwd_return_3d"] is not None
|
|
|
|
|
|
def test_build_continuation_rows_skips_when_not_enough_bars() -> None:
|
|
base_rows = [
|
|
{
|
|
"event_id": "EVT::AAPL::2",
|
|
"ticker": "AAPL",
|
|
"event_type": "earnings_release",
|
|
"event_date": "2026-01-05",
|
|
"reaction_date": "2026-01-05",
|
|
"entry_date": "2026-01-06",
|
|
"event_close": 100.0,
|
|
}
|
|
]
|
|
bars_by_symbol = {
|
|
"AAPL": {
|
|
dt.date(2026, 1, 6): {"open": 101.0, "high": 103.0, "low": 100.0, "close": 102.0, "volume": 1000},
|
|
dt.date(2026, 1, 7): {"open": 102.0, "high": 104.0, "low": 101.0, "close": 103.0, "volume": 1100},
|
|
dt.date(2026, 1, 8): {"open": 103.0, "high": 105.0, "low": 102.0, "close": 104.0, "volume": 1200},
|
|
}
|
|
}
|
|
assert _build_continuation_rows_from_bars(base_rows, bars_by_symbol, lookback_days=3) == []
|
|
|