A first session
One end-to-end pass at the command line — scaffold the project, prove which settings and store are being read, list what a strategy may call, and get a backtest report back from a data service.
This page is one session, start to finish, on a machine that has just unpacked a release. Nothing here needs a venue credential. Each step says what it proves as well as what it does, because half of a first session is establishing that the binary is reading the files you think it is.
Which binary is this
vike-cli --versionprints <name> <version> (<build identity>) — the shape every --version on the box already
prints, with this build's provenance appended by vike_buildinfo::version_line. The parenthesised
half answers the question a bare version number cannot: which commit is this? A release binary
was once built from a clone four commits behind and nearly installed on a live recorder, which is
why every --version in this workspace answers it.
vike-cli --help lists the ten verbs. Both exit 0 and print to stdout, which is not a given
— four verbs used to route --help through their usage-error arm and exit 1 with help requested
on stderr. crates/vike-cli/src/cmd/args.rs's exit_for_parse_error is now the one place that
decision is made.
Scaffold the project
vike-cli initinit creates <project>/user_data — the half of the project a program must never author — fills
every folder with a runnable example, and prints the map:
user_data: /srv/vike/user_data
user_data/ your work — nothing here is ever overwritten once you have edited it
strategies/rhai/ interpreted strategies: edit, save, backtest. No toolchain needed.
strategies/rust/ compiled strategies. SOURCE CHECKOUT ONLY — a release binary cannot build them.
indicators/ your own indicators, one <name>.rhai each. Callable from any strategy.
profiles/ run profiles: which data, which costs, which strategy
backtest_results/ saved reports. One sample ships, so the notebooks work before your first run.
notebooks/ analysis over the results above
logs/ compile.log — every strategy load, pass and fail. Look here first.
create strategies/rhai/sma_cross/sma_cross.rhai
...The map is printed on every run, including one that changed nothing, because this command is also how you ask what is in here again? — and an answer that only appears the first time is an answer nobody sees twice. Files that were already in place are counted rather than listed, so on a re-run the one line that changed is not buried.
Re-running is the ordinary case: a new version ships new examples, so the default writes only what
is absent and never touches a file you edited. --dry-run performs every comparison and writes
nothing.
--reset is the one loaded flag, and its boundary is narrower than "restore the samples" sounds.
It restores every shipped sample that is missing or edited — so it does overwrite your
changes to a shipped example, which is exactly what it is for. What it can never touch is a file
you created: --reset compares against one table of shipped files and writes nothing outside
it, and a strategy you wrote is not in that table, so no combination of flags here can delete it.
Reach for --dry-run first if you are unsure which of your files are shipped samples — it prints
the same report, marking each one created, restored or kept, and writes nothing. The
init reference argues that boundary precisely.
Prove which files are being read
Two commands, and running them now saves an hour later. Both report on the same settings directory the dispatcher resolved once at startup, taken as a parameter rather than re-derived, so neither can name a file that nothing else opens.
vike-cli secrets pathstore: /srv/vike/settings/secrets.env (present)There is exactly one credential store and this is where it is. If it is absent, the command prints
the three lines that create one — a mkdir -p, an $EDITOR, and a
chmod 600 … # it is plaintext credentials — because creating that file is a person's job with an
editor, never a command's. If its mode grants anything to group or other, a warning goes to stderr;
a finding is never a refusal, so the exit code does not change.
vike-cli config show --section filesprints the settings directory, one line per settings file with whether it was read, and then a
table of every setting with its effective value, the layer that set it, the compiled-in default,
and a READ column saying whether anything actually reads it. --section files is worth typing:
the environment half is several hundred rows, and the question that motivated the files half —
did my policy.toml get read? — should not require scrolling past them.
Provenance here is exact rather than inferred: an origin is decided by a key's presence in a
parsed layer, so a file that sets a key to the same number as the code default still reports the
file. Until this existed, nothing anywhere printed whether a policy.toml had been read at all,
and a typo'd filename produced a silently uncapped node.
Ask what a strategy may call
vike-cli indicators
vike-cli indicators --name rsiThis prints the indicators a Rhai strategy can actually call — every row is a name the script host binds, joined onto its catalog metadata for the label, the parameters and the output lines. The distinction matters more than it sounds: Rhai resolves a function name when the line runs, so a script naming an unbound indicator compiles cleanly, raises on every bar, and self-disables after the consecutive-error cap. It looks mounted and silently never trades. A name absent from this listing is a name that fails exactly that way.
Your own user_data/indicators/*.rhai appear in their own block, under their own heading, with no
category — they are a different kind of thing, authored on this box with a file behind them, and
listing only the built-ins told an author their own indicator did not exist. The verb is offline: no
store, no settings, no credential.
Run a backtest
A backtest needs no keys. What it needs is a vike-datahub server with a history store behind it —
that is the whole compute-to-data trade: the profile's text crosses the wire and the tape never
does.
vike-cli backtest --list-params --script user_data/strategies/rhai/sma_cross/sma_cross.rhaiis the offline half — it compiles the script and prints one name = default line per
param(name, default) call it declares, with no profile, no connection and no server. A script
declaring none says so in one line rather than printing nothing.
Then the run:
vike-cli backtest --profile user_data/profiles/backtest.toml --addr 127.0.0.1:7878--addr defaults to 127.0.0.1:7878. The server binds loopback, so a remote one is reached over
ssh -L 7878:localhost:7878 <host> and the command line does not change. The profile is read
locally and shipped verbatim; the server parses and validates it, which is what keeps exactly
one profile parser in the workspace.
Two flags rewrite the profile on the way out, in a fixed order: --preset merges a flat table of
knobs into [strategy.params] first, then --script injects an authored script's source into
[strategy.params].src, so the file on disk always wins over a stale src left in the profile.
The report comes back as JSON, pretty-printed for a person. With --json the server's bytes are
printed exactly as they arrived — that is the shape a wrapper should consume, and
Scripting it is the page about consuming it. What each field means is on
the report; the profile's own tables are on
run profiles.
An empty store is not an error, and that is the trap
A profile naming a slice the store does not hold completes and reports no trades, which is
indistinguishable from a strategy that never fired. init's own closing lines say so and name the
fix — the backtest binary's --seed-demo writes a synthetic tape, --fetch-starter pulls a
published dataset that needs no venue. vike-cli cannot seed a store itself: writing one needs
DataFusion, and this binary has none by construction.
sweep and walkforward are the same offload over the same wire — a parameter grid and an
anchored out-of-sample validation, both ranked and stitched server-side. From here, the
trade REPL is the other half of the surface, and
Quickstart: first backtest is this same path written
as a tutorial with the data-seeding steps in line.
The command line
What vike-cli is, what it deliberately is not, the ten verbs it dispatches, and which of the three surfaces over the platform to reach for.
The trade REPL
What driving a live node from a terminal is actually like — the two connections, the preview before every write, what the local guardrail is and is not, and why each command reports its own outcome.