SPB Git

spb/wp41_uqo

Public
2.6 KB · 53 lines python
1"""Synthetic bars in the exact FinData schema (license-free fixtures for tests and the release package)."""2from __future__ import annotations34import numpy as np5import polars as pl6import pyarrow as pa78from .calendar import sessions91011def synthetic_bars(symbol: str = "SYN", start: str = "2024-01-02", end: str = "2024-03-28", seed: int = 0,12                   p_missing: float = 0.02, split: tuple[str, float] | None = None, extended: bool = True,13                   sigma: float = 4e-4, asset_class: str = "stock") -> tuple[pl.DataFrame, list[dict]]:14    rng = np.random.default_rng(seed)15    rows = []16    price = 100.017    actions = []18    if split:19        actions.append({"action_type": "split", "ex_date": split[0], "value": split[1]})20    for s in sessions(start, end):21        n = s.n_slots22        # extended hours bars before the open (04:00 -> 09:29) and after (16:01 -> 19:59)23        slots = list(range(-330, 0)) + list(range(0, n)) + list(range(n, n + 239)) if extended else list(range(0, n))24        for k in slots:25            ts = s.open_utc + np.timedelta64(k, "m")26            is_regular = 0 <= k < n27            if is_regular and k != 0 and k != n - 1 and rng.random() < p_missing:28                continue29            if not is_regular and rng.random() < 0.85:30                continue31            r = rng.standard_t(4) * sigma * (1.6 if k < 30 or k > n - 30 else 1.0)32            o = price33            c = price * np.exp(r)34            h = max(o, c) * np.exp(abs(rng.normal(0, sigma / 2)))35            lo = min(o, c) * np.exp(-abs(rng.normal(0, sigma / 2)))36            v = float(rng.integers(100, 50_000)) * (10 if k == n - 1 else 1)37            price = c38            raw_factor = 1.039            if split and str(s.date.date()) < split[0]:40                raw_factor = split[1]   # raw prices before ex-date are "pre-split" (higher)41            rows.append({"instrument_id": f"firstrate:{asset_class}:{symbol}", "symbol_as_reported": symbol,42                         "asset_class": asset_class, "interval": "1m", "timestamp_utc": ts.to_pydatetime(),43                         "session_date": s.date.date(), "open": o * raw_factor, "high": h * raw_factor,44                         "low": lo * raw_factor, "close": c * raw_factor, "volume": v / raw_factor, "currency": "USD",45                         "adjustment_type": "raw", "source_id": "synthetic", "quality_flags": [], "revision_id": 1})46    df = pl.DataFrame(rows).with_columns(pl.col("timestamp_utc").dt.replace_time_zone("UTC"),47                                         pl.col("quality_flags").cast(pl.List(pl.Utf8)))48    return df, actions495051def to_arrow(df: pl.DataFrame) -> pa.Table:52    return df.to_arrow()53
Files · main
Menu

Theme