Quickstart: first backtest
Zero credentials to a report — scaffold the examples, seed the demo tape, and run the shipped strategy through the data service or the standalone runner.
A backtest in Vike Trader needs no venue credentials. vike-cli backtest ships a small run-profile
TOML to a running vike-datahub, which runs the backtest next to the data and returns only a
compact report; the standalone backtest binary is the one-process path that opens the store
itself. This page takes you from an empty install to a report using the examples vike-cli init
ships and the demo tape backtest --seed-demo writes.
What you need
vike-cli,vike-datahubandbacktest— from a release, or all three inside the container image.- No API keys.
vike-cliopens the credential store for thetrade,mcpandstrategy-statusverbs, which authenticate to a node, and for the surfaces that report on the store itself —secrets list,config showandconfig check;init,backtest,sweep,walkforwardandindicatorsnever open it.vike-datahubreads it only for its own node keys, and with none set it authenticates nothing on loopback; thebacktestrunner takes a profile and a store and nothing else.
1. Scaffold the examples
vike-cli initThis creates <project>/user_data — strategies, profiles, results, notebooks, logs — with a
runnable example in every folder but logs/, where a committed sample would be fiction, and
prints the map before you open a file manager. Re-running is safe: it writes only what is absent.
The pieces this page uses:
user_data/
strategies/rhai/sma_cross/sma_cross.rhai two moving averages, always in the market
profiles/backtest.toml one run over the demo tape
profiles/sweep.toml a 3 x 3 parameter grid, script inlined
profiles/walkforward.toml four anchored out-of-sample windows, script inlined2. Seed the demo tape
backtest --seed-demoA clean install has an empty history store, and a profile naming a slice the store does not hold
completes and reports no trades — indistinguishable from a strategy that never fired. The demo
tape closes that: vike_data::demo writes six months of hourly BTCUSDT bars
(2025-01-01 to 2025-07-01) plus the last week at one minute, every bar a closed-form function of
its timestamp, under the venue id demo. The shipped profiles/backtest.toml names exactly that
slice, and a test holds the two in agreement. Re-seeding writes nothing and says so.
The demo tape is a curve, not market data
It exists so the tools have something to run. A result computed on it says nothing about any
market, and it is written under its own venue precisely so it can never be aggregated with rows a
recorder or a real fetch wrote. For real bars, backtest --fetch binance:BTCUSDT:1h --days 180
pulls public klines with no credentials, and backtest --fetch-starter downloads the published
starter dataset over plain HTTPS for a box that cannot reach a venue at all — Binance geoblocks
whole countries at the REST layer. Both land under the venue's real id.
3. Start the data service
vike-datahubIt listens on 127.0.0.1:7878 (VIKE_DATAHUB_ADDR) and opens the store VIKE_DATAHUB_STORE
names, falling through VIKE_HIST_STORE, a source checkout if the box has one, then this
project's own market_data/hist — the same precedence backtest --seed-demo used, so from the
same project folder the two agree. Both log hist store root resolved … store=<path>; check that
the two lines match. It refuses a non-loopback bind unless you both consent
(VIKE_DATAHUB_ALLOW_PUBLIC_BIND=1) and configure a node key, so a remote server is reached over
ssh -L 7878:localhost:7878 <box>.
4. Run the backtest
vike-cli backtest \
--profile user_data/profiles/backtest.toml \
--script user_data/strategies/rhai/sma_cross/sma_cross.rhaiThe profile is shipped as text, and unless you pass --script or --preset the server is the only
thing that parses it. --script injects the file's source into [strategy.params].src before it
goes, which is one of two cases where the client re-serialises the TOML rather than sending your
bytes untouched. --preset <p.toml> merges a flat table of knobs into [strategy.params] the same
way, and it is resolved locally for a reason: only the profile text crosses the wire, so a preset
named in the profile would resolve against the server's user_data/, not yours.
The report is pretty-printed JSON and deliberately compact — BacktestReport carries the profile
name, final equity, total return, trade count, win rate, Sharpe, max drawdown, profit factor,
funding paid and per-symbol PnL, and a ranked zero-trade diagnosis when a run closed no trade and
its equity never moved. It carries no equity curve. --json prints the server's bytes verbatim;
--addr <host:port> names another server.
Two offline helpers need no server at all:
vike-cli backtest --list-params --script user_data/strategies/rhai/sma_cross/sma_cross.rhai
vike-cli indicatorsThe first prints the param(name, default) knobs a script declares; the second prints every
indicator a script can call, off the same derived list the host binds from.
The one-process path
backtest --profile user_data/profiles/sweep.tomlThe standalone runner has no --script: a profile it runs must carry the script inline in
[strategy.params].src — as the shipped sweep and walk-forward profiles do — or name a compiled
strategy from backtest --list. The shipped sweep.toml covers the demo tape's dates but names
venue = "binance"; change it to demo to run it here. A single run also persists under
<project>/user_data/runs/<run_id>/ as manifest.json beside report.json; a sweep prints its
ranked table and writes nothing. --store DIR overrides the store root.
5. Search, then validate
vike-cli sweep --profile user_data/profiles/sweep.toml --rank-by sharpe
vike-cli walkforward --profile user_data/profiles/walkforward.tomlA [sweep] table overrides strategy.params.<key> across a value grid and the server returns one
row per point, ranked by sharpe, return, max_dd or equity — the ranking is the server's own
BacktestReport numbers, never a client re-implementation. A walk-forward is a stability check,
not a second optimiser: walk_forward_strategy runs one fixed parameter set over each anchored
out-of-sample window, rebases the windows into one stitched equity curve, and WalkForwardReport
returns that curve's return and Sharpe beside wf_consistency, the fraction of windows that were
profitable. Point both profiles' [data] at a slice your store holds first — the shipped
walk-forward spans 2024 to 2026 on binance.
Where to next
- Running a backtest and Run profiles.
- Walk-forward — why it never re-fits.
- Read a backtest report.
- Connect an agent — the same tools over MCP.
Updating
What a release is, how to tell which build is running, the order to update in, image tags, the runtime tools, and what a version bump does to a write-ahead journal.
Quickstart: first paper mount
A live Binance feed, every venue on the paper exchange, and a first order that cannot reach a real account.