Oracle3
Open-source trading engine and MCP server for prediction markets. Fee-aware no-arbitrage trading across related contracts, live on Kalshi, Polymarket and Solana or on paper.
A simple, event-driven backtesting framework for algorithmic trading, running client-side via Pyodide — no server, no API key, real historical data.
FinancePythonGitHub @heykavOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
A simple, event-driven backtesting framework for algorithmic trading. Zero-config, real market data, no database server required.
Taken from the repository README
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.
Is:
on_bar(bar) sees bar t; orders fill at the open of bar t+1 plus slippage.Is not:
Strategy only talks to a small engine interface, so a live engine could be written, but that has not been done or tested. Alpaca support is a roadmap idea, not a feature.YFinanceFeed uses split/dividend-adjusted prices).Behaviours worth knowing: a buy you cannot afford at the fill price is rejected (see engine.rejected_orders); sells beyond your position are rejected unless allow_short=True; orders placed on the last bar never fill; commission is a flat amount per fill.
heykav.github.io/quantdeck — pick a symbol and SMA windows, click "Run backtest," and watch the real engine run in your browser (no install, no server, nothing sent anywhere). Every trade is logged too:
The demo uses a handful of bundled historical datasets (2015–2024) so it works instantly with no live network fetch — the same BacktestEngine, Strategy, and metrics code as the CLI, just fed pre-downloaded prices instead of a live yfinance call.
Algorithmic trading just means: instead of a person watching a stock chart and clicking "buy" or "sell" by hand, you write a small program with rules — like "buy 10 shares of Apple if its price rises above its 10-day average" — and let the computer follow those rules.
Before you'd ever trust such a program with real (or even fake) money, you want to know: if I had run this rule over the last year of real stock prices, would I have made money or lost it? That process — replaying your rule against historical prices to see how it would have performed — is called backtesting. That's what QuantDeck does.
Concretely, QuantDeck gives you three things:
Offline CSV data needs no account or API key. Yahoo Finance data is optional and needs network access.
You only need one thing installed: Python 3.10 or newer.
To check what you have, open a terminal and run:
python3 --version
Python 3.10.x, 3.11.x, or 3.12.x (or newer) — you're good, skip to Installation.3.9.x) or you get a "command not found" error, install a current Python first:
brew install [email protected] (install Homebrew first if you don't have it), or download from python.org.sudo apt install python3.12.You'll also want git installed to download this project (most Macs and Linux machines already have it).
Open a terminal and run these commands one at a time:
# 1. Download the project
git clone https://github.com/heykav/quantdeck.git
cd quantdeck
# 2. Create an isolated Python environment just for this project
# (this keeps QuantDeck's dependencies separate from everything else on your machine)
python3 -m venv .venv
# 3. Activate that environment
# On Mac/Linux:
source .venv/bin/activate
# On Windows (Command Prompt):
# .venv\Scripts\activate.bat
# 4. Install QuantDeck and its dependencies
pip install -e ".[dev]"
You'll know it worked if running quantdeck --help prints a list of commands instead of an error.
Note: every time you open a new terminal window to work on this project, you'll need to run step 3 (
source .venv/bin/activate) again first — that's what tells your terminal "use QuantDeck's Python environment."
QuantDeck ships with a ready-made example strategy at examples/sma_crossover.py. Try it right now:
quantdeck backtest examples/sma_crossover.py --symbol AAPL --start 2023-01-01 --end 2023-12-31
Here's what each part of that command means:
| Part | Meaning |
|---|---|
backtest | the CLI command that runs a backtest |
examples/sma_crossover.py | the file containing the strategy to test |
--symbol AAPL | the stock ticker to test against — Apple, in this case |
--start 2023-01-01 | the first day of historical data to include |
--end 2023-12-31 | the last day of historical data to include |
Behind the scenes, QuantDeck fetches AAPL's real daily prices for 2023 from Yahoo Finance (no account or API key needed), replays the strategy's rules day-by-day, and prints a results table. It takes a few seconds.
Running a backtest prints the table shown in the Quickstart. What each row means:
| Metric | What it tells you |
|---|---|
| Total Return | How much your money grew (or shrank) over the whole period, as a percentage. |
| CAGR | "Compound Annual Growth Rate" — the return re-stated as "if this rate continued for a full year, every year". Useful for comparing strategies tested over different time spans. |
| Sharpe Ratio | A measure of return relative to how bumpy the ride was. Roughly: above 1 is decent, above 2 is very good, below 0 means you'd have been better off not trading. It rewards steady gains and penalizes wild swings. |
| Max Drawdown | The single worst drop from a peak to a low point during the test, as a percentage. 17% means at some point your account fell 17% below its previous high. This is a key measure of "how bad could it get." |
| Win Rate | Of all the completed trades (a buy followed by a matching sell), what percentage made money. 30% means 3 out of 10 trades were profitable. Trade P&L is net of commission. |
| Number of Trades | How many completed round-trip trades the strategy made. |
| Ending Equity | The final dollar value of the account, starting from $100,000 by default. |
Results are also saved to a local file, quantdeck.db, so you can keep a history of every backtest you've run (a SQLite database — just a single file, no server needed; you can even open it with a free tool like DB Browser for SQLite if you want to poke around).
A strategy is just a Python class. Generate a starter template:
quantdeck init my_strategy.py
This creates:
"""A starter QuantDeck strategy — edit this to build your own."""
from quantdeck.strategy import Strategy
class MyStrategy(Strategy):
def on_bar(self, bar):
# Example: buy 10 shares if we have no position yet.
if self.position == 0:
self.buy(10)
A few things to know:
on_bar(self, bar) is called once for every day (or "bar") of historical data, in order. This is the only method you must implement — it's where your trading logic goes.bar is the current day's price data. It has bar.open, bar.high, bar.low, bar.close, bar.volume, and bar.timestamp.self.buy(qty) and self.sell(qty) place orders. Orders fill at the next bar's opening price (plus slippage) — never the price of the day you decided to trade, since in real life you can't buy at a price you've already seen close.self.position tells you how many shares you currently hold (0 if none).self.cash is how much uninvested cash you have; self.equity is your total account value (cash + the current value of anything you're holding).on_start(self) and on_end(self) are optional — override them to set up variables before the backtest begins, or to do something after it ends.Once you've edited it, run it just like the example:
quantdeck backtest my_strategy.py --symbol AAPL --start 2023-01-01 --end 2023-12-31
Want a slightly more advanced example? Look at examples/sma_crossover.py — it tracks a rolling average of recent prices to decide when to buy and sell, with comments explaining each step.
Strategy (your code)
│ on_bar(bar) → buy()/sell()
▼
BacktestEngine ──drives──▶ DataFeed (YFinanceFeed / CSVDataFeed)
│
▼
PaperBroker (simulated fills, slippage, commission)
│
▼
Storage (SQLite) + Metrics (return, CAGR, Sharpe, drawdown, win rate)
The same flow as a diagram, drawn from the code in engine.py, broker/paper.py, strategy.py and metrics.py (the SQLite step used by the CLI is left out):
In plain words: the engine is a loop that hands your strategy one day of prices at a time. Whenever your strategy calls buy() or sell(), the engine passes that order to a simulated broker, which fills it at a realistic price (accounting for typical trading costs) and updates your account. After every day, the engine records your total account value, building up an equity curve — and at the end, the metrics module turns that curve into the summary table you saw above.
Only this backtest path is implemented. Strategy calls a small engine surface (submit_order, cash, position_qty, equity), which a live engine could implement in future; no such engine exists today.
Terms you'll see throughout this project:
PaperBroker only simulates fills inside a backtest.| Command | What it does |
|---|---|
quantdeck init [path] | Creates a starter strategy file (defaults to strategy.py). |
quantdeck backtest <file> --symbol <TICKER> --start <YYYY-MM-DD> --end <YYYY-MM-DD> | Runs a backtest. Optional: --csv <file> (offline OHLCV data instead of Yahoo Finance), --cash, --slippage-bps (default 5), --commission (flat per fill), --risk-free-rate, --db (default quantdeck.db). |
quantdeck --help | Lists all commands. |
command not found: quantdeck — you probably haven't activated the virtual environment in this terminal. Run source .venv/bin/activate (Mac/Linux) from inside the quantdeck folder.No data returned for '<SYMBOL>' between ... — check the ticker symbol is correct and that the date range includes trading days (e.g., not entirely a weekend or a date range in the future).No Strategy subclass found in <file> — your strategy file needs a class that inherits from Strategy (e.g., class MyStrategy(Strategy):).python3 --version is 3.10 or newer (see Prerequisites), and make sure you created the virtual environment with that version.pip install -e ".[dev]"
pytest # tests (offline, deterministic)
ruff check . && ruff format --check src tests examples scripts
mypy # strict type check
python scripts/gen_api_docs.py # regenerate manual/api.md
python scripts/make_figures.py # regenerate the images in docs/img/ (needs matplotlib, a dev extra)
StrategyQuantDeck is an educational and research tool. Backtested performance does not guarantee future results — real markets involve costs, risks, and behavior that a simulation can't fully capture. Nothing in this project is financial advice. If you ever move from backtesting to trading with real money, start with a broker's paper-trading (fake money) mode first, and only risk money you can afford to lose.
MIT