Spaces:
Running on Zero
Running on Zero
File size: 8,674 Bytes
d8478d9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | # Backtest Lab v1.0.0 β Handoff
Built end-to-end and deployed. Everything below was verified against the **live
Space**, not just locally.
## Live URLs
| What | URL |
|---|---|
| **Backtest Lab** (Space) | https://huggingface.co/spaces/Bit-Trading-Company/bit-backtest-lab |
| Direct app | https://bit-trading-company-bit-backtest-lab.hf.space |
| **Signal store** (Dataset) | https://huggingface.co/datasets/The-Bit-Trading-Company/bit-signal-store |
Both tagged `v1.0.0`. Space stage: **RUNNING** on **`zero-a10g` (ZeroGPU)**.
## Deployment status
| Check | Result |
|---|---|
| Build | β
142s build + ~30s app start |
| Cold start (app boot) | β
~30s, under the 60s budget |
| HTTP response | β
200 in 0.74s |
| Hardware | β
ZeroGPU (`zero-a10g`) **granted** β no billing escalation needed |
| Example config end-to-end | β
`/load_example` returns the design's worked example |
| Backtest on live Space | β
+33.2%, 12 trades, $486 costs β **bit-identical to local** |
| Warm run time | β
**0.1s** engine time for a 3-year daily run (budget: <2s) |
| Coverage map from live manifest | β
18 rows, all labelled `real` |
| Login button | β
present; `/login/huggingface` returns 302 |
| ZeroGPU detected in-app | β
"ZEROGPU AVAILABLE Β· EXTENSION RUNS ON YOUR OWN QUOTA" |
## Tests: all green
`bash tests/run_all.sh --slow` β **191 passed**, run with `-W error::FutureWarning`.
Verified on **both** Python 3.11 (dev) and **Python 3.10** (what the ZeroGPU
image actually provides) β 190 offline + 1 real-model test.
### The six known-answer tests
| # | Test | Status |
|---|---|---|
| 1 | Buy & Hold, zero costs, reproduces the asset return (tol 1e-9) | β
|
| 2 | Deliberately lookahead-biased strategy is caught structurally | β
|
| 3 | Zero-cost vs costed run differ by exactly the modelled costs | β
|
| 4 | Zero-signal strategy β flat equity, zero trades | β
|
| 5 | Walk-forward train/test never overlap; holdout untouched by selection | β
|
| 6 | Same config + same data β bit-identical results | β
|
31 tests cover these six directly. Test 2 catches three distinct cheats:
reading bar `t+1`, a centred rolling window, and full-sample normalisation.
## Spec compliance
- β
**No lookahead paths.** Enforced two ways: the engine applies the one-bar
shift itself (a strategy cannot bypass it), and `assert_causal` proves it by
perturbing future prices up *and* down and requiring earlier outputs to be
bit-identical. All seven shipped presets pass.
- β
**Fills at next bar open.** `fill` accepts only `next_open`; anything else
raises. A test asserts the entry price equals bar 1's open, not bar 0's.
- β
**Costs default ON.** `Costs().enabled is True`. `gross β costs = net` holds
to 1e-9 on every trade row. Costs-off runs are labelled "these numbers are
not achievable" in the UI.
- β
**Every displayed metric traceable to engine output.** The stat band, trade
table and report are asserted against `metrics.py` values in `test_ui.py`.
- β
**No placeholder slices remain.** All 18 signal slices are real
Chronos-Bolt output. The `PLACEHOLDER` labelling machinery is still present
and tested for contributors on weaker hardware.
- β
**No arbitrary code execution.** Adapter families are allow-listed, model
ids are validated, `trust_remote_code` is never set, and the design's
`Custom (code)` preset is rendered disabled with an explanation.
- β
**Token hygiene.** Scanned every file in both repos: the token appears in
none of them. It exists only in the local gitignored `key.txt` and as the
`HF_WRITE_TOKEN` Space secret.
## What shipped
**Signal store** β 18 signal slices / **60,375 real rows** across
`chronos-bolt-small` + `chronos-bolt-base`, 6 assets (BTC, ETH, SOL, SPY, QQQ,
NVDA) Γ 3 timeframes (1d, 1h, 15m); 15 price slices; 4 precomputed comparison
tables (model performance, calibration, directional accuracy, strategyΓtimeframe
heatmap).
**Derived data worth reading**: Chronos-Bolt is consistently **over-dispersed** β
its nominal 80% q10βq90 band actually covers 83β89% of outcomes across every
slice. Worth knowing before trusting a q10 stop level.
**Engine** β vectorbt, next-bar-open fills, commission + fixed/volume-scaled
slippage, SL/TP/trailing stops, fixed-% and vol-target sizing, three validation
modes with a locked holdout, full IS/OOS/holdout metric split, trade list with
R-multiple, MAE/MFE and per-trade trigger reasons.
**UI** β the design implemented in Gradio Blocks with the Bit design system
vendored verbatim (tokens + Styrene/Mac Minecraft fonts): Strategy Builder
(5 numbered sections), Results Canvas (Overview / Trades / Comparison /
Robustness / Report / Coverage), Run Manager, pinned disclaimer footer.
## β οΈ Human-verify checklist
These need a real human with a real account β I cannot complete them:
1. **OAuth login end-to-end.** The button renders and `/login/huggingface`
redirects correctly, but I cannot complete a real sign-in. Click
*Sign in with Hugging Face* and confirm you land back signed in.
If it fails, check Space settings β the `hf_oauth: true` header is set in
`README.md` and may need the owner to approve the OAuth app once.
2. **ZeroGPU extension with a real account.** Sign in, open the **Coverage**
tab, pick an uncovered range, press *Estimate* then *Extend coverage*.
Confirm: progress stages appear, the commit lands in the dataset repo, and
the toast reads "Coverage extended by @you". This is the only path that
spends real GPU quota, so it is untested against real hardware.
3. **Add-model flow** with a real Hub model id, same reason.
4. **Torch version difference.** The Space runs torch **2.11.0** (ZeroGPU only
accepts 2.11/2.10/2.9.1/2.8); my adapter smoke test ran locally on 2.13.0.
The first real ZeroGPU extension doubles as the check that Chronos inference
behaves identically on 2.11.
5. **Visual pass on a real screen.** I verified the UI functionally and via
screenshots, but the in-app browser stalled before I could click through
every tab at full size. Worth a human eye on the Comparison and Robustness
tabs with several runs loaded.
## Open items from DECISIONS.md
- **D-001 β Space is under the personal namespace.** Gradio Spaces under an org
need a paid Team/Enterprise plan (402). You chose the personal namespace; the
dataset stays under the org. To move it later, subscribe and re-point
`BIT_SPACE_REPO`.
- **D-006 β Binance is geo-blocked (451)** from the seeding machine; crypto came
from Coinbase via the fallback chain. **Stooq now serves an HTML block page**,
so the equity chain effectively runs on yfinance alone. Tiingo is wired but
needs a `TIINGO_KEY` secret to join the chain.
- **Sentiment is a stub.** `Sentiment-Gated Momentum` runs on a labelled,
deterministic price-derived proxy behind a `SentimentSource` interface β not
news sentiment. Wiring a real feed is the obvious next task.
- **Pairs Trading** is in the design's preset list but not runnable in v1
(needs a second leg). It is shown disabled with that reason.
- **Equity intraday depth** is provider-capped (~730d hourly, ~60d 15m) and
recorded in the manifest as `provider_max_days`, not hidden.
## Things I'd flag as genuinely uncertain
- The **example strategy loses money on the locked holdout** (β5.2%, Sharpe
β0.38). That is the system working: the holdout is doing its job and the app
reports it rather than burying it. Don't read the headline +33.2% as a result.
- **Walk-forward on short ranges produces no OOS windows at all.** The app now
says so explicitly instead of printing `0.00`, but it is easy to configure a
run that looks complete and has no out-of-sample content. Watch for the red
note.
- **`vectorbt` is pinned to 1.0.0**, not the 1.1.0 I developed against, because
1.1.0 requires Python β₯3.11 and the ZeroGPU image is 3.10. The full suite
passes on both, but that is a real version skew between dev and prod.
## Repo layout
```
hugging-face/
key.txt local only, gitignored, never committed
DECISIONS.md 15 logged decisions across all phases
HANDOFF.md this file
ops/ provisioning scripts (local only, not deployed)
store_stage/ dataset card staging
space/ β pushed to the Space
app.py src/{store,data,engine,strategies,adapters,charts,metrics,
comparisons,runtime,extension,config,ui/theme}.py
scripts/seed_store.py tests/ (191) assets/ (vendored design system)
DESIGN_NOTES.md the extracted design contract Phase 3 was built against
```
|