run_sweep
Expand a profile's parameter grid on the datahub and get every point back ranked best-first, each with its own report.
Runs a parameter-grid sweep on the remote vike-datahub server and returns the ranked
SweepReport. Same input as run_backtest — a profile TOML,
optionally with a Rhai script injected — plus one grid table and one ranking knob.
Input
| Field | Type | Required | Meaning |
|---|---|---|---|
profile | string | yes | Profile TOML with [data], [strategy] and [sweep] (plus optional [engine]) |
script | string | no | Rhai source, injected as [strategy.params].src |
rank_by | string | no | sharpe (default), return, max_dd or equity — applied server-side |
The [sweep] table is the whole grid: each key names a strategy.params field and each value is
an array to cross-product over. expand_sweep turns the profile into that cartesian product of
single-run profiles, each with its params overridden per point and its own sweep field cleared —
so every expanded point is itself a plain, runnable single-backtest profile. A profile with no
[sweep] table comes back as a server-side error that quotes the fix.
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"run_sweep","arguments":{
"profile": "[data]\nvenue = \"binance\"\nsymbols = [\"BTCUSDT\"]\nkind = \"bar\"\nfrom = \"0\"\nto = \"100000\"\n\n[strategy]\nname = \"buy_hold\"\n\n[sweep]\nfast = [5, 10]\n",
"rank_by": "sharpe"
}}}run_tools_reject_a_missing_profile_arg_before_any_connect pins the local half: a missing
profile, or a script injection into unparsable TOML, errors before a socket is opened.
Everything else is the server's answer, because the TOML ships verbatim and
BacktestProfile::from_toml_str is the only parser.
Ranking happens on the server
rank_by is resolved by the canonical harness::RankMetric::from_str_ci. An unrecognized value is
a clean error naming the valid set — never a silent fallback to the default — and an omitted one
ranks by Sharpe, matching the shipped backtest bin. Direction is folded in: sharpe, return
and equity sort descending, max_dd ascending, because a smaller drawdown is better. A NaN key
— a Sharpe over a zero-variance curve, say — sorts last among the successes, so a degenerate point
can never rank first, and rows whose run failed always sort behind every success.
No client re-implements a metric. The ranking runs over real BacktestReports with the canonical
comparator, which is the same rule that took sharpe and max-drawdown out of the vike-cli sweep
verb: nothing outside vike-backtest computes them.
What comes back
{ "sweep": … } wrapping a SweepReport: rows plus the rank_by it was ranked under. Each
SweepRow carries
overrides— the(key, value)pairs that produced this point,reportorerror— never both; a point that failed records its error string and is not dropped,score— stamped only by the objective path, and skipped on serialization otherwise, so a default sweep's JSON is unchanged by the seam's existence.
Read the head of rows as the winner and the tail for what broke.
Sweeps documents the expansion,
objectives the pluggable scalar the score field belongs to,
and search the successive-halving and TPE lanes that fold through
the same per-point plumbing.
Determinism, and the memory shape
Points run on a rayon pool, and the ordering does not depend on scheduling: the collect is
order-preserving and the ranking sort is stable over that input, so a parallel sweep's bytes equal
the one-at-a-time loop's — parallel_and_sequential_sweeps_are_byte_identical is the pin.
Parallelism multiplies the data slice, not just the CPU
The shared store handle is shared; the data is not. Every point independently re-scans and
fully materializes its own slice, so peak memory and store I/O are N_threads x slice. The pool
is therefore bounded rather than one worker per core — min(4, available_parallelism()) by
default, raised by VIKE_SWEEP_THREADS on the server, and pinned back to one at a time by
VIKE_SWEEP_SEQUENTIAL=1. On a large recorded tick slice an uncapped sweep is an OOM shape, and
these sweeps often run on a box that also hosts live trading. Size the multiplier against the
slice, not against the core count.
The keyed-datahub and unreachable-server behaviour is identical to
run_backtest's: every Run* verb is control scope because it
compiles client-supplied Rhai, and a connect failure is a clean tool error.
The prompt
Sweep
fastover 5, 10 and 20 againstslowover 50 and 100, rank by Sharpe, and show me the top three rows with their parameters.
A grid returns its best row whether or not the edge survives out of sample — follow it with
run_walk_forward. The human twin is
vike-cli sweep; the guide is Run a sweep on the data
service.