SPB Git

spb/wp39_uqo

Public
2.1 KB · 37 lines python
1"""Splits and cash dividends (FinData `corporate_actions`, vendor meta files) -> per-symbol ex-date adjustment table.23The extract is produced once on the storage node (read-only `psql \\copy`, see docs/API_INTEGRATION.md) because the API4has no corporate-actions route; its SHA-256 is in artifacts/manifests/corporate_actions.json. Raw bars stay unadjusted;5adjustments are applied explicitly in features.daily_block (ex-date rule).6"""7from __future__ import annotations89from pathlib import Path1011import polars as pl121314def load_actions(path: Path) -> pl.DataFrame:15    """Raw Postgres copy: id, instrument_id, action_type (split|dividend), ex_date, value, ... .16    Vendor quirk: dividends are keyed `firstrate:stock:<SYM>_DIVS`; `value` = split ratio (new per old) or cash amount."""17    if not path.exists():18        return pl.DataFrame(schema={"symbol": pl.Utf8, "ex_date": pl.Date, "split_ratio": pl.Float64, "dividend": pl.Float64})19    a = pl.read_csv(path, try_parse_dates=True, infer_schema_length=10000)20    a = a.with_columns([21        pl.col("instrument_id").str.replace("^firstrate:[a-z]+:", "").str.replace("_DIVS$", "").alias("symbol"),22        pl.col("ex_date").cast(pl.Date), pl.col("value").cast(pl.Float64),23    ])24    splits = a.filter(pl.col("action_type") == "split").group_by(["symbol", "ex_date"]).agg(pl.col("value").product().alias("split_ratio"))25    divs = a.filter(pl.col("action_type") == "dividend").group_by(["symbol", "ex_date"]).agg(pl.col("value").sum().alias("dividend"))26    out = splits.join(divs, on=["symbol", "ex_date"], how="full", coalesce=True).with_columns([27        pl.col("split_ratio").fill_null(1.0), pl.col("dividend").fill_null(0.0)])28    out = out.filter((pl.col("split_ratio") > 0) & (pl.col("dividend") >= 0))29    return out.sort(["symbol", "ex_date"])303132def split_events_in_window(actions: pl.DataFrame, symbol: str, start, end) -> int:33    if actions.height == 0:34        return 035    return actions.filter((pl.col("symbol") == symbol) & (pl.col("ex_date") >= start) & (pl.col("ex_date") <= end)36                          & (pl.col("split_ratio") != 1.0)).height37
Files · main
Menu

Theme