Skip to content

Commit c6cce6a

Browse files
committed
docs(readme): add Backtest Storage Layer feature + workflow example
- New feature bullet linking the storage_layer_demo - New '<details>' section explaining Tier-1 SQLite index, Tier-2 BacktestStore adapters (LocalDirStore / LocalTieredStore) and Tier-3 content-addressed OHLCV chunks - Python + CLI workflow showing the canonical pattern: build_index -> rank_index -> store.open(handle) -> BacktestReport(backtests=[...]).save(...) - Links to examples/storage_layer_demo/ for the runnable end-to-end
1 parent 1655a44 commit c6cce6a

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ This framework is built around the full loop: **create strategies → vector bac
8484
- 📉 **[Benchmark Comparison](https://coding-kitties.github.io/investing-algorithm-framework/Getting%20Started/backtest-reports)** — Beat-rate analysis vs Buy & Hold, DCA, risk-free & custom benchmarks
8585
- 📄 **[One-Click HTML Report](https://coding-kitties.github.io/investing-algorithm-framework/Getting%20Started/backtest-reports)** — Self-contained file, no server, dark & light theme, shareable
8686
- 📦 **[Custom `.iafbt` Backtest Bundle Format](https://coding-kitties.github.io/investing-algorithm-framework/Data/backtest_data)** — An explicit, versioned, compressed, language-portable container (zstd + msgpack with magic-byte header) plus a separate parquet index for fast filtering without loading. ~21× smaller and ~27× fewer files than standard filebased directory layouts, with parallel I/O for fast load/save of large amounts of backtests.
87+
- 🗄️ **[Tiered Backtest Storage Layer](examples/storage_layer_demo/README.md)** — Manage thousands of `.iafbt` bundles with a Tier-1 SQLite index (sub-100 ms ranks/filters over 10k+ backtests), a swappable `BacktestStore` protocol (`LocalDirStore`, `LocalTieredStore`), content-addressed Tier-3 OHLCV deduplication, and a CLI (`iaf index` / `iaf list` / `iaf rank` / `iaf migrate-store`) that plugs straight into the HTML dashboard.
8788
- 🌐 **[Load External Data](https://coding-kitties.github.io/investing-algorithm-framework/Data/external-data)** — Fetch CSV, JSON, or Parquet from any URL with caching and auto-refresh
8889
-**[Per-Market Deposit Schedules & Portfolio Sync](https://coding-kitties.github.io/investing-algorithm-framework/Advanced%20Concepts/portfolio-sync)** — Declare recurring or one-shot external cash flows on a market with `deposit_schedule=` / `auto_sync=True`. Backtests simulate the deposits; live mode reconciles with the broker — same `context.sync_portfolio()` API in both modes.
8990
- �📝 **[Record Custom Variables](https://coding-kitties.github.io/investing-algorithm-framework/Advanced%20Concepts/recording-variables)** — Track any indicator or metric during backtests with `context.record()`
@@ -145,6 +146,63 @@ Every backtest produces a **self-contained HTML dashboard** — open it in any b
145146

146147
</details>
147148

149+
<details open>
150+
<summary>
151+
<strong>Backtest Storage Layer — scale to thousands of backtests</strong>
152+
</summary> <br>
153+
154+
Once you start sweeping parameter grids and walk-forward windows, a flat folder of `.iafbt` bundles stops scaling: every comparison re-decodes multi-MB Parquet metric blobs just to read a Sharpe number. The storage layer fixes that with three tiers behind a single `BacktestStore` protocol:
155+
156+
- **Tier-1 — SQLite index (`index.sqlite`)**: one row per bundle with every scalar from `BacktestSummaryMetrics` promoted to its own column. Ranking 10k+ bundles becomes a sub-100 ms SQL query — no `.iafbt` is opened.
157+
- **Tier-2 — `BacktestStore` adapters**: `LocalDirStore` (flat folder of bundles) or `LocalTieredStore` (hive-partitioned layout). Same handle-based API, swap the implementation without touching call sites.
158+
- **Tier-3 — content-addressed OHLCV chunks**: SHA-256 deduped per-symbol OHLCV blobs shared across every bundle that references them. `garbage_collect_ohlcv()` reclaims orphans.
159+
160+
A CLI ties it all together: `iaf index` builds/refreshes the Tier-1 SQLite, `iaf list` / `iaf rank` query it, and `iaf migrate-store` moves a whole collection between store kinds in one command.
161+
162+
#### Typical workflow
163+
164+
```python
165+
from investing_algorithm_framework import BacktestReport
166+
from investing_algorithm_framework.cli.index_command import (
167+
build_index, rank_index,
168+
)
169+
from investing_algorithm_framework.services.backtest_store import (
170+
LocalDirStore,
171+
)
172+
173+
# 1. Build (or refresh) the Tier-1 SQLite index over a folder of .iafbt bundles.
174+
build_index("./my-backtests/") # equivalent to: iaf index ./my-backtests/
175+
176+
# 2. Pick the top 20 by Sharpe straight from SQLite — no Parquet decoded.
177+
top = rank_index(
178+
"./my-backtests/",
179+
by="sharpe_ratio",
180+
where="summary_number_of_trades > 50",
181+
limit=20,
182+
)
183+
184+
# 3. Materialise just those 20 bundles through the BacktestStore protocol.
185+
store = LocalDirStore("./my-backtests/")
186+
backtests = [store.open(row["bundle_path"]) for row in top]
187+
188+
# 4. Feed them straight into the HTML dashboard.
189+
BacktestReport(backtests=backtests).save("top20.html")
190+
```
191+
192+
Or from the shell:
193+
194+
```bash
195+
iaf index ./my-backtests/
196+
iaf rank ./my-backtests/ --by sharpe_ratio --where "summary_number_of_trades > 50" -n 20
197+
iaf list ./my-backtests/ --sort calmar_ratio --json
198+
iaf migrate-store --from local-dir --src ./my-backtests/ \
199+
--to local-tiered --dst ./tiered/
200+
```
201+
202+
→ End-to-end runnable example: [`examples/storage_layer_demo/`](examples/storage_layer_demo/README.md)
203+
204+
</details>
205+
148206
<details open>
149207
<summary>
150208
<strong>Live Trading</strong>

0 commit comments

Comments
 (0)