Skip to content

feat(Notebooks): Implement the four use-case notebooks from #34 - #35

Closed
szemyd wants to merge 4 commits into
mainfrom
claude/notebook-specs-pr34-ga30w4
Closed

feat(Notebooks): Implement the four use-case notebooks from #34#35
szemyd wants to merge 4 commits into
mainfrom
claude/notebook-specs-pr34-ga30w4

Conversation

@szemyd

@szemyd szemyd commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements the four outline specifications from #34 as polished, preview-runnable
percent-format .py notebooks. Each analyses Binance BTC perpetuals
(perpetual-BTC-USDT:USDT) at 5-minute resolution over May 2025 — the
window served by the shared DEMO-KEY preview slice — and every one-month
statistic is labelled illustrative.

Notebook Use case What it does
backtest-slippage Improve your backtest Builds a half-spread + impact cost model from l1_price, impact and slippage, validates it against measured slippage_bps_mean, and compares zero / flat / dynamic-cost momentum backtests.
backtest-funding Improve your backtest Accrues realised funding at its discrete prints and compares price-only, price + funding, and price + funding + cost backtests, plus a fade-funding diagnostic.
execution-liquidity-timing Execute smarter Spread/depth/toxicity seasonality across the tier-3 L2 datasets, a transparent liquidity score, and best/uniform/worst-hour execution schedules priced with the slippage cost model.
risk-positioning Read positioning & risk A trailing rolling-percentile crowding score from funding, basis and open-interest change, with a decile event study and an in-window threshold calibration table.

How the specs were met

  • Authored as percent-format .py, jupytext-synced; .ipynb and html/ are left for CI to generate (no hand-edited notebooks or committed exports).
  • API key resolves "..."APERIODIC_API_KEY"DEMO-KEY"; USE_PREVIEW = API_KEY == "DEMO-KEY". No load_dotenv, no printed secrets, no UUID-shaped example keys.
  • Every call passes the common arguments (api_key, preview, timestamp, interval, exchange, symbol, start_date, end_date, output="pandas", show_progress=False).
  • Reuse the intro-notebook theme/rcParams, clip_window, format_time_axis, the shared run_position_backtest (5-minute annualisation) and the alpha-discovery rolling-rank transform; uppercase config constants; numbered ## Chart N — sections, ## Takeaways, ## Further reading.
  • Marked as preview-data in notebooks/preview-notebooks.json and listed in the README.

Validation

  • Each notebook was executed end-to-end via nbconvert (the same step CI runs) against a synthetic stand-in for the aperiodic SDK using the exact spec column names, since the live endpoint is not reachable from the authoring sandbox. All four run clean with sensible outputs (cost curves rise with order size; funding sign is correct; the scheduler ranks hours; crowding deciles order forward drawdowns).
  • Each notebook prints a schema audit of every fetched frame immediately after fetching and fails loudly (listing the real columns) if a required field is absent, so CI execution against live data confirms the field names.
  • ruff format . / ruff check . clean; jupytext py → ipynb → py round-trip is stable.

Implements #34.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HVxnJZYNRifP6pgJ5D13bz


Generated by Claude Code

claude and others added 4 commits July 14, 2026 13:53
Author percent-format .py notebooks implementing the outline specs in #34:

- backtest-slippage: builds a half-spread + impact cost model from l1_price,
  impact and slippage metrics, validates it against measured slippage_bps_mean,
  and compares zero / flat / dynamic-cost momentum backtests.
- backtest-funding: isolates realised-funding PnL by accruing funding at its
  discrete prints and comparing price-only, price+funding and
  price+funding+cost backtests; adds a fade-funding diagnostic.
- execution-liquidity-timing: spread/depth/toxicity seasonality across the
  tier-3 L2 datasets, a transparent liquidity score, and best/uniform/worst
  hour execution schedules priced with the slippage cost model.
- risk-positioning: a trailing rolling-percentile crowding score from funding,
  basis and open-interest change, with a decile event study and an in-window
  threshold calibration table.

All four run end-to-end on the DEMO-KEY preview slice (Binance BTC perpetuals,
5-minute, May 2025), reuse the intro-notebook theme/helpers and the shared
run_position_backtest, resolve the key via ... -> APERIODIC_API_KEY -> DEMO-KEY,
label one-month statistics as illustrative, and never call load_dotenv or print
secrets. .ipynb and HTML are left for CI to generate.

Also mark the four notebooks as preview-data in preview-notebooks.json and list
them in the README.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HVxnJZYNRifP6pgJ5D13bz
…display from real-data review

Reviewing the CI-executed notebooks against real May 2025 data surfaced three
issues fixed here:

- backtest-funding: the reported funding_rate updates on (nearly) every 5-minute
  bar, so change-detection was counting thousands of "prints" and inflating a
  constant long's realised funding to ~-29% for the month. Accrue funding only at
  the Binance 8-hour settlement schedule (00:00/08:00/16:00 UTC, with a
  change-detection fallback), which restores a realistic ~-1% and correct
  per-strategy funding contributions.
- execution-liquidity-timing: rank the best/uniform/worst schedules by the
  spread-plus-impact cost model (what the desk minimises) instead of the holistic
  liquidity score, so the cheapest hours are genuinely cheapest; on BTC the score
  and the cost model diverge, which is now framed explicitly and is the subject of
  Chart 4. Also fold the fetched L2 imbalance into the Chart 3 adverse-move
  diagnostic (previously fetched but unused).
- backtest-slippage: report the impact coefficient per $1M notional so it no longer
  rounds to 0.0000 next to a non-zero modelled cost.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HVxnJZYNRifP6pgJ5D13bz

szemyd commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

Superseded — split into one PR per notebook as requested:

Each carries the same notebook source that ran green here (executed end-to-end against real May 2025 data via CI, with .ipynb and HTML generated by the export workflow). Closing this combined PR in favour of the four above.


Generated by Claude Code

@szemyd szemyd closed this Jul 14, 2026
szemyd added a commit that referenced this pull request Jul 28, 2026
## Summary

Adds `notebooks/backtest-slippage.py`, implementing the
**backtest-slippage** outline from #34 (use case: *Improve your
backtest*).

Builds a **microstructure** transaction-cost model — half-spread plus
market impact — from Aperiodic's `l1_price`, `impact` and `slippage`
metrics, and shows how different cost assumptions reshape a simple
momentum backtest.

- Binance BTC perpetuals, 5-minute, May 2025 preview slice; runs
end-to-end on `DEMO-KEY`.
- **Fees are excluded by design** and disclaimed prominently (a Binance
taker fee ~5 bps one-way is cited as the dominant real cost); the flat
benchmark is a comparable ~1 bps so the equity chart stays readable.
- Section 6 **checks the impact model against measured per-trade
`slippage_bps_mean` at the actual average trade size** (`volume_notional
/ taker trade count`). The result is reported straight: the model
**under-predicts** measured slippage by roughly an **order of
magnitude** at the average trade size, with **~zero per-bar
correlation** — `impact_per_notional` (net-flow-based) is an
order-of-magnitude proxy, not a per-trade predictor. The notebook prints
the notional at which the model mean would equal measured slippage to
make the size dependence explicit.
- Reuses the intro-notebook theme/helpers and the shared
`run_position_backtest`.

`.ipynb` and HTML are generated by CI. Adds one README row and one
`preview-notebooks.json` slug (also touched by the sibling notebook PRs,
so whichever merges last needs a trivial rebase).

Part of splitting #35 into one PR per notebook. Implements #34.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
szemyd added a commit that referenced this pull request Jul 28, 2026
## Summary

Adds `notebooks/backtest-funding.py`, implementing the
**backtest-funding** outline from #34 (use case: *Improve your
backtest*).

Isolates how **realised** funding changes strategy PnL and shows where
it binds.

- Binance BTC perpetuals, 5-minute, May 2025 preview slice; runs
end-to-end on `DEMO-KEY`.
- Funding is accrued at the Binance **8-hour settlements** to the
**position held into** each settlement, priced at the last rate observed
before it (per the catalogue's "last rate in interval" feed) — not
smeared across 5-minute bars. A cadence cross-check prints (settlements
~8 h apart; the first in-window settlement has no pre-window rate and is
excluded, so detected = expected − 1).
- The headline comparison is **price-only vs price + funding** on two
positions: a **constant long** (funding binds — ~−0.43%/month on a
+10.9% buy-and-hold) and a **1h momentum** signal (direction-neutral,
funding nets out). Turnover costs are delegated to
`backtest-slippage.py`.
- The fade-funding diagnostic is backtested **with its own funding leg**
(price-only vs price + funding — the gap is the carry), noting the
position is ~constantly short this month.
- Reuses the shared `run_position_backtest`.

`.ipynb` and HTML are generated by CI. Adds one README row and one
`preview-notebooks.json` slug (sibling PRs touch these too — whichever
merges last needs a trivial rebase).

Part of splitting #35 into one PR per notebook. Implements #34.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
szemyd added a commit that referenced this pull request Jul 28, 2026
…38)

## Summary

Adds `notebooks/execution-liquidity-timing.py`, implementing the
**execution-liquidity-timing** outline from #34 (use case: *Execute
smarter*).

Measures spread / depth / **|toxicity|** seasonality across the tier-3
multi-level **L2** datasets and tests a time-of-day execution schedule
**out-of-sample**.

- Binance BTC perpetuals, 5-minute, May 2025 preview slice; runs
end-to-end on `DEMO-KEY` (tier-3 L2 is in the preview slice; full L2
history needs Prime).
- Hours are **calibrated on the first 15 days and evaluated on the
held-out remainder**, ranked on the robust **median** cost (the
distribution is heavy-tailed), with per-hour IQR bars, rank-persistence,
and validation against **measured** slippage. In this month the hour
ranking **does not persist** (Spearman −0.07) and the eval medians show
no separation — so the notebook demonstrates the *method* and reports
the honest one-month verdict, rather than the by-construction
monotonicity a same-window ranking would produce.
- `flow_toxicity_score` is signed (catalogue), so `|toxicity|` is used
throughout; depth is in BTC with `ORDER_NOTIONAL` ≈ 2.2% of level-20
dollar depth; Chart 4 shows why the cheapest hours are not always the
safest.

`.ipynb` and HTML are generated by CI. Adds one README row and one
`preview-notebooks.json` slug (sibling PRs touch these too — whichever
merges last needs a trivial rebase).

Part of splitting #35 into one PR per notebook. Implements #34.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants