Skip to main content

backtestchat

An open-source, local-first agentic strategy lab in your terminal. Chat with a LangGraph agent to fetch keyless Binance public market data, design and backtest long/flat crypto strategies, and run simulated paper trades. Charts render to self-contained plotly HTML that opens in your browser.

Paper-only by design. backtestchat simulates fills from closed bars. It never places real orders and never needs exchange API keys. Market data comes from the public, keyless Binance REST API. The only key you supply is your own model (BYOK) key, or a local Ollama endpoint.

backtestchat is a research and simulation tool and a portfolio/learning project. It is not financial advice and not a trading product. Do not use it to make investment decisions.

Quickstart

Requires uv.

uv tool install "backtestchat[openai]"   # CLI + OpenAI provider, in an isolated env
backtestchat init                        # save your OpenAI key + model (written 0600)
backtestchat chat                        # talk to the agent

backtestchat init prompts for your OpenAI API key (hidden) and model and writes them to ~/.config/backtestchat/config.toml. After that, backtestchat and its short alias btchat work from any directory. Market data needs zero keys; only the chat agent needs a model key.

From source (for development)

git clone https://github.com/barisarat/backtestchat
cd backtestchat
uv sync --extra openai              # deps + the OpenAI model provider
uv run backtestchat init            # or export BACKTESTCHAT_MODEL / OPENAI_API_KEY
uv run backtestchat chat

In a source checkout the backtestchat command lives in the project venv, so prefix commands with uv run (or activate the venv with source .venv/bin/activate). A plain uv sync drops extras - re-add yours with uv sync --extra openai. Other providers (Anthropic, Ollama, ...) are covered under Model setup.

What it does

  • Chat with a tool-calling agent (LangGraph) that maps your plain-English requests onto market-data, backtest, and paper-trade actions.
  • Backtest ~11 single-signal long/flat strategies (SMA/EMA crossover, MACD, RSI, Bollinger, Donchian, ROC, stochastic, ATR channel, price-vs-SMA, buy & hold) with CAGR, Sharpe, max drawdown, win rate, and trade count.
  • Compare several strategies at once, ranked, on one chart.
  • Paper-trade a strategy with simulated fills. Runs advance by replaying closed bars - no daemon, no scheduler. Any command can trigger a cheap sync.
  • Charts are deterministic plotly HTML written to ./artifacts. The model never writes HTML; it only triggers the tools that build the charts.

Supported intervals: 15m, 1h, 4h, 1d. Symbols: any Binance spot pair (BTCUSDT, ETHUSDT, SOLUSDT, XRPUSDT, DOGEUSDT, ...).

Model setup (BYOK)

The quickest path is backtestchat init, which stores an OpenAI key + model in your user-global config. Under the hood backtestchat talks to any provider via LangChain's init_chat_model, configured with a provider:model string in BACKTESTCHAT_MODEL.

For another provider, install its extra and point BACKTESTCHAT_MODEL at it:

# installed as a tool:
uv tool install "backtestchat[anthropic]"
export BACKTESTCHAT_MODEL=anthropic:claude-sonnet-4-5
export ANTHROPIC_API_KEY=...

# or in a source checkout:
uv sync --extra ollama
export BACKTESTCHAT_MODEL=ollama:llama3.1     # Ollama runs locally, no key

Environment variables override the config file, so you can switch models per-shell without editing anything. backtestchat config shows what resolved (the API key is masked). If no model is configured, backtestchat chat prints setup instructions and exits.

Usage

uv run backtestchat chat

Then talk to it naturally:

you > what's BTC trading at?
you > backtest an ma crossover 20/50 on BTCUSDT 1h over the last 3 months
you > compare that against buy and hold and rsi
you > save that strategy            # asks you to confirm in the terminal
you > start a paper run with 5000 usdt   # asks you to confirm
you > list my paper runs

Charts open automatically in your browser and are saved under ./artifacts. Saving a strategy and starting a paper run pause for a y/n confirmation (human-in-the-loop, implemented with LangGraph interrupts).

Commands

backtestchat init                         # save your OpenAI key + model to the global config
backtestchat chat [--new] [--thread ID]   # agent REPL (resumes the last thread by default)
backtestchat runs list [--status active]  # list paper runs (stored state)
backtestchat runs sync                    # advance all active runs to the latest closed bar
backtestchat show [last|FILE]             # open a rendered chart artifact
backtestchat config                       # print resolved configuration (key masked)

(btchat is a short alias for backtestchat.)

How paper runs work

A paper run does not backdate: the first simulated fill happens on the first bar that closes after you create the run, so a fresh run shows "waiting for first tick" until then. Advancing a run replays every closed bar since its last processed bar, one signal evaluation per bar. Because the already-processed-bar guard is the only cadence control, backtestchat runs sync is safe to run anytime and is idempotent.

LangSmith tracing (optional)

Set the standard env vars and traces appear in your LangSmith project - no code or flags required:

export LANGSMITH_TRACING=true
export LANGSMITH_API_KEY=...

Configuration

Resolved in order: environment variables > ./backtestchat.toml (project-local)

~/.config/backtestchat/config.toml (user-global, written by backtestchat init) > defaults.

Key Env var Default
model BACKTESTCHAT_MODEL (unset; required for chat)
OpenAI key OPENAI_API_KEY (unset; stored by backtestchat init)
data dir BACKTESTCHAT_DATA_DIR ./data
artifacts dir BACKTESTCHAT_ARTIFACTS_DIR ./artifacts

The user-global config is written with 0600 permissions and holds your model and OpenAI key; keep secrets out of any project-local ./backtestchat.toml. ./data holds the sqlite store (strategies, paper runs, trades) and the LangGraph checkpoint database. ./artifacts holds rendered chart HTML. Both are gitignored.

Development

uv sync --extra openai --group dev   # runtime + OpenAI provider + test deps
uv run --group dev pytest -q         # deterministic, offline, no model key

If uv run pytest ever reports pytest: not found, the local venv has been pruned back to defaults - uv run --group dev pytest -q re-materializes the test deps for that run.

The engine, signals, broker window logic, and paper runner are pure and tested against fixture bars. Market-data and agent layers are tested with mocked HTTP and a scripted fake model, so the whole suite runs offline.

License

MIT - see LICENSE.

Metadata

Release files for backtestchat 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for backtestchat 0.1.1
File Size Uploaded
backtestchat-0.1.1.tar.gz 135.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for backtestchat 0.1.1
File Interpreter ABI Platform
backtestchat-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 185.7 kB

Release files / backtestchat-0.1.1.tar.gz

Download URL backtestchat-0.1.1.tar.gz
Size 135.3 kB
Tags Source
SHA-256 checksum
How to use checksums
a029e3dc2543d3b47745eb2a2dd3a0ea1d50547c05aae35bea06149414f25600
BLAKE2b-256 checksum
How to use checksums
9a6ac0df53f8d5bcc460c2c06270f1e55287dda6cbeb939208c4497df6873e32
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 5, 2026.

Transparency log

Release files / backtestchat-0.1.1-py3-none-any.whl

Download URL backtestchat-0.1.1-py3-none-any.whl
Size 50.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e02065ed66ab0ea425cc5f98e98ee73fd95ee5f803013b9a896272495aad3ecd
BLAKE2b-256 checksum
How to use checksums
9cf066250aadf2d7424a777f53d92ea3cb6c7b3518384c869f5dfaaffd9f5d6a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page