Skip to content

Changelog

Unreleased

  • Python wheel packaging: gb-python now builds as a CPython 3.10+ abi3 extension, ships a checked-in ./scripts/python_sdk_wheel_smoke.sh installer validation path, and has a dedicated python-wheels.yml workflow that builds Linux/macOS wheel artifacts plus an sdist and smoke-installs each wheel before upload.
  • Paper broker parity + audit trail: gb-live::PaperBroker now keeps an append-only audit log for broker events, inventories rejection reasons for sell-over-inventory attempts, and ships a replay test that feeds a backtest order stream back through the paper broker to prove cash/position parity on the sample buy-and-hold path.
  • Data quality summaries + strict mode: gb-data now validates fetched datasets, persists per-symbol validation summaries in the catalog, records dataset provenance/price-adjustment metadata, and exposes those summaries through run manifests/result metadata. DataSettings.data_quality_mode defaults to warn and can be set to fail to reject datasets with critical issues before a backtest starts.
  • Execution realism: gb-engine now records order lifecycle events, respects time-in-force semantics for day/IOC/FOK orders, and caps fills by a configurable max_volume_participation setting so oversized orders can partially fill instead of always executing in one shot.
  • Python SDK quickstart: GlowBack now ships a checked-in Python SDK smoke path (./scripts/python_sdk_quickstart.sh) plus a companion example (examples/python_sdk_quickstart.py) that builds gb-python in an isolated virtualenv, validates the documented public surface, and runs both helper-style and engine-style backtests against sample data.
  • Replay-manifest tutorial: GlowBack now ships ./scripts/replay_manifest_tutorial.sh plus examples/replay_manifest_tutorial.py, giving the reproducibility docs a checked-in smoke path that generates a sample-data result, validates the emitted manifest, replays it locally, and proves the replayed metrics stay within tolerance.
  • CSV data tutorial: GlowBack now ships ./scripts/csv_data_tutorial.sh plus examples/csv_data_tutorial.py and a checked-in examples/data/AAPL_1d.csv fixture, so the CSV-ingestion docs exercise a real provider-compatible dataset and a CSV-backed backtest instead of hand-wavy pseudo-code.
  • Run manifests + replayability: Engine-backed API backtests now emit a typed manifest contract with dataset lineage, execution settings, replay-ready request payloads, and headline metric snapshots; Python/runtime helpers can replay the manifest locally and compare results against the captured metrics.
  • Experiment durability: GlowBack now persists Streamlit strategy snapshots, completed UI backtest runs, and API backtest history in a shared SQLite-backed experiment registry so saved strategies, comparison runs, and historical /v1/backtests listings survive restarts and remain exportable/deletable intentionally.
  • Engine scaling: gb-engine now keeps per-symbol StrategyContext market buffers incrementally, reuses the live context across hot-path callbacks, and ships a Criterion benchmark covering representative 10-symbol/6-month and 50-symbol/1-year workloads instead of rebuilding full-history buffers on every callback.
  • Catalog durability: gb-data now reloads persisted symbol_metadata rows when DataCatalog starts, so symbol listings, metadata lookups, and catalog stats survive process restarts instead of disappearing from the in-memory cache.
  • UI backtest correctness: The Streamlit backtester now keeps last-known prices for every held symbol, analytics derive returns from the equity curve instead of pct_change() on cumulative return percentages, the dashboard no longer mutates the shared equity DataFrame in-place, and win rate is computed from realized closed trades (or shown as unavailable when nothing has closed yet).
  • Portfolio correctness: gb-types::Portfolio now marks positions with signed market value after every fill, so short books no longer inflate equity and trade-to-trade snapshots stay self-consistent; added a dedicated accounting invariants suite covering long-only, short, fractional, multi-asset, and deterministic randomized order streams.
  • Portfolio correctness: Position::apply_fill now preserves the residual leg when a fill crosses through flat, so long→short and short→long reversals keep the reopened position with the crossing fill's basis; added reversal and exact-close regression coverage in gb-types.
  • Live risk safety: Total exposure checks in gb-live now price each held symbol from its own latest mark instead of reusing the incoming order's price across the whole book; added multi-symbol regression tests for both false-approve and false-reject cases.
  • CI stability: Sample/demo backtests now use isolated ephemeral data directories, preventing concurrent test runs from sharing one on-disk catalog/parquet store and intermittently failing multi-symbol crypto tests.
  • Optimization workflow: /v1/optimizations now runs real engine-backed optimization trials for built-in strategies via gb-python, supports grid/random/Bayesian search, adds holdout or walk-forward validation, returns replayable best-trial backtest payloads, emits explicit overfit diagnostics, and records an optimization manifest with seed/trial lineage for the run.
  • CI coverage: Normal PR CI now includes gb-live, gb-risk, and gb-optimizer in the Rust test matrix, adds lightweight API/UI Python validation, and gates release artifacts on those checks passing.
  • Breaking (build only): Replaced DuckDB with SQLite (rusqlite) for catalog metadata storage. No schema or behavior changes — same SQL, dramatically faster builds (~20 min → ~47s) and smaller artifacts (~3.5 GB → ~1.1 GB).
  • Added [profile.dev] debug = "line-tables-only" to reduce debug build size.
  • Docs site created and expanded
  • CI and workflow improvements
  • Added a manual GitHub release workflow that publishes versioned releases from a previously built CI artifact.
  • Fixed Parquet storage writes to merge existing and incoming bar history by timestamp instead of truncating previously stored data on refresh.