Open Net Worth
Open Net Worth is an open-source personal AI wealth assistant you run yourself: one ledger for your whole financial life, worked by an AI agent you control.
翻訳待ち
A simple, event-driven backtesting framework for algorithmic trading. Zero-config, real market data, no database server required.
翻訳待ち
Loading the full README. The saved excerpt is shown below.
A simple, event-driven backtesting framework for algorithmic trading strategies — zero-config, real market data out of the box, no database server required.
No install needed to try it — the live demo runs the real Python engine client-side via Pyodide (Python compiled to WASM), not a JS reimplementation. docs/quantdeck_src is kept in sync with src/quantdeck automatically (.github/workflows/sync-web-demo.yml), so that claim can't quietly go stale.Read the full README ↗The picture is real engine output (AAPL, SMA 10/30, bundled 2015-2024 prices, the same run the live demo does). It is a past simulation, not a prediction or financial advice.
A small, event-driven backtesting framework for single-symbol trading strategies. Write a Strategy class, replay it over OHLCV bars, get an equity curve, trade list and risk metrics. It runs offline on CSV files and needs no database server.
git clone https://github.com/heykav/quantdeck.git && cd quantdeck
python3 -m venv .venv && source .venv/bin/activate
pip install .
quantdeck backtest examples/sma_crossover.py --symbol SYN \
--start 2022-01-01 --end 2030-01-01 --csv examples/data/synthetic.csv
Expected output (deterministic; verified from a clean virtualenv):
Running backtest: SmaCrossoverStrategy on SYN (2022-01-01 → 2030-01-01)
Backtest Results
┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Metric ┃ Value ┃
┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Return │ -9.79% │
│ CAGR │ -5.07% │
│ Volatility (ann.) │ 12.00% │
│ Sharpe Ratio │ -0.37 │
│ Sortino Ratio │ -0.51 │
│ Calmar Ratio │ -0.29 │
│ Max Drawdown │ 17.31% │
│ Win Rate │ 30.00% │
│ Profit Factor │ 0.49 │
│ Number of Trades │ 10 │
│ Ending Equity │ $90,214.14 │
└───────────────────┴────────────┘
examples/data/synthetic.csv is a seeded random walk, not market data, so those numbers only show that the pipeline runs. To use Yahoo Finance data instead (needs network access), drop --csv: quantdeck backtest examples/sma_crossover.py --symbol AAPL --start 2023-01-01 --end 2023-12-31.
The same run from Python: python examples/offline_backtest.py. See the tutorial and the API reference.
These figures are generated by scripts/make_figures.py from one real run of python examples/offline_backtest.py on the same synthetic series. The data is a seeded random walk, not market data, so the results say nothing about real performance. That script uses a $1 commission per fill, so its total return is -9.81% versus -9.79% in the commission-free CLI table above.
A real slice of Bitcoin daily prices is committed in the repo, so this runs offline and gives the same numbers every time:
python examples/real_data_backtest.py
Real output (Binance BTCUSDT daily candles, 2021-01-01 to 2025-12-31, 1,826 bars, $100,000 start, 15 bps cost per fill):
| SMA 10/30 crossover | Buy and hold | |
|---|---|---|
| Total return | 32.69% | 196.68% |
| CAGR | 5.82% | 24.30% |
| Volatility (ann.) | 37.36% | 58.22% |
| Sharpe (rf 0) | 0.34 | 0.66 |
| Max drawdown | 62.25% | 76.34% |
| Round trips | 38 | 0 |
| Costs paid | $11,626.92 | $148.50 |
| Ending equity | $132,691.57 | $296,680.78 |
The strategy loses to simply holding. It made money, but gave up about $164,000 of ending equity against buy and hold, and paid roughly $11,600 in costs over 76 fills. It did cut the worst drawdown a little (62% against 76%). That is the point of printing a benchmark: a simple rule is not an edge. The numbers are one strategy, one asset and one five-year window that happened to include a huge bull run, so they say nothing about the future.
How to read the setup, honestly:
examples/data/BTCUSDT_1d_2021-2025.csv, downloaded from Binance's public market-data host, retrieved 2026-10-29. Source, checksum and terms note are in examples/data/PROVENANCE.md. Prices are raw spot prices in USDT (a stablecoin, not exactly one dollar).--periods-per-year 365 on the CLI), not 252.fractional = True), buy and hold invests 99%. Both are market orders that fill at the next open.Download fresh data yourself (public endpoint, no key, no account) and backtest it from the CLI:
quantdeck fetch ETHUSDT --start 2022-01-01 --end 2025-12-31 --out eth.csv
quantdeck backtest examples/sma_crossover.py --symbol ETHUSDT --start 2022-01-01 \
--end 2025-12-31 --csv eth.csv --slippage-bps 15 --periods-per-year 365
The CLI run above uses whole-coin sizing, which is coarse for assets priced in the tens of thousands, so its numbers differ from the table above (it is not the same run); for BTC prefer the Python example. From Python, BinanceFeed downloads once and caches the CSV, so reruns work offline:
from quantdeck.data.binance import BinanceFeed
feed = BinanceFeed(cache_dir=".quantdeck_cache") # plug into BacktestEngine(data_feed=feed, ...)
The data helper uses only the standard library and Binance's read-only data-api.binance.vision host. Check Binance's terms before building on the data. Stooq's CSV download now sits behind a captcha and an API key, so it is not used.
This is the beginning of the README. Read the rest at the original. Read the full README ↗