vike
Getting started

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-datahub and backtest — from a release, or all three inside the container image.
  • No API keys. vike-cli opens the credential store for the trade, mcp and strategy-status verbs, which authenticate to a node, and for the surfaces that report on the store itself — secrets list, config show and config check; init, backtest, sweep, walkforward and indicators never open it. vike-datahub reads it only for its own node keys, and with none set it authenticates nothing on loopback; the backtest runner takes a profile and a store and nothing else.

1. Scaffold the examples

vike-cli init

This 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 inlined

2. Seed the demo tape

backtest --seed-demo

A 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-datahub

It 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.rhai

The 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 indicators

The 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.toml

The 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.toml

A [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

On this page