vike

Authoring

4 offline tools — compile a Rhai strategy, list its param() knobs, read the starter templates, and see which indicators the script host actually binds.

Four tools for writing a strategy, and none of them touches a server: they run entirely inside the vike-cli process, so they work with no --addr, no --node and no keys. Two compile a script (validate_strategy, discover_params), two answer "what may I write" (list_templates, list_indicators).

Strategies are Rhai scripts. Tunable knobs are declared with param(name, default) at the top level; the trading logic lives in fn on_bar().

validate_strategy

Compile a Rhai strategy — compile is validation. The check runs through crates/vike-script/src/strategy.rs's discover_params, which compiles the script and runs its top level exactly once, with no broker attached. That is the same error surface you get from mounting the strategy for real: the daemon mounts through RhaiStrategy::compile_with_params (resolve_script in crates/vike-tradehub/src/config.rs is the call site), and that performs the same one-time top-level run.

discover_params is a public entry point, so the same broker-free check is callable from your own Rust code and not only through this tool.

ParameterTypeRequiredNotes
scriptstringyesRhai strategy source

Returns ok: true, or ok: false with the compiler's error string. A bad script is an answer, not a tool failure — the agent reads the error and fixes the script. Only a missing script argument is an isError result.

Does this strategy compile?

discover_params

Read back the tunable param(name, default) knobs a script declares — the exact keys a profile's [strategy.params] or a [sweep] table can override, in declaration order.

ParameterTypeRequiredNotes
scriptstringyesRhai strategy source

Returns params, one row per knob: name and its default.

Note the deliberate asymmetry with the tool above: both call the same compile path, but a compile error here is a tool error (rhai compile error: …), because there are no parameters to report.

Call it on a script you just wrote, not only on one you were handed. validate_strategy answers ok: true and says nothing about params, and this tool runs the top level only — so a param() reached from inside on_bar() is reported by neither, which makes it exactly as invisible to the author as to a reader. The tool's own description says so now (tools_spec in crates/vike-cli/src/cmd/mcp.rs), because an agent that skipped this step and answered from its own authorship is what the change was measured against.

What knobs does this strategy expose, and what are their defaults?

list_templates

The starter strategies, as {name, code} rows: SMA cross, RSI reversion and Donchian breakout. Each is parameterized via param(), so a template drops straight into run_sweep without editing. The sources are static data in crates/vike-cli/src/cmd/mcp.rs's TEMPLATES, copied verbatim from vike_studio_core::templates.

That is a hand copy, not a shared import, and there is no cross-crate drift gate — the two copies must be edited together. They are identical today, and nothing but that convention keeps them so; each side carries its own execution gate over its own copy instead.

This tool takes no arguments.

Two tests stand behind the list, and the second is the one that matters: one compiles every template, and every_shipped_template_reaches_the_broker runs each one over 80 bars against a broker double and asserts an order actually arrives. Compiling is the wrong bar for a surface an agent copies from — a strategy whose every call sits inside fn on_bar() compiles perfectly and can still fail on every single bar (see the callout below).

Read the Donchian starter's body before trusting its name

It stands in with sma, symmetrically, because a bare donchian(len) is not bound. bare_name_binds in crates/vike-script/src/engine.rs binds a bare name when the indicator has one output or when its first line is the namesake, and donchian's first line is upper. Its per-line accessors — donchian_upper(), donchian_mid(), donchian_lower() — are all callable, so the bare call is a function-not-found on the first bar rather than a silent upper-band read. The template's own comment says "multi-output indicators are not bound", which is wider than the rule the host applies.

Show me the vike strategy templates and explain what each one trades.

list_indicators

The host-bound callable set — what the Rhai engine actually registers, joined onto the indicator catalogue's own metadata (vike_indicators::registry()). This is deliberately not the whole catalogue: it is filtered to what a script can really call.

That question is vike_script::is_callable, and it has two arms — an indicator qualifies under its bare name or through at least one per-line accessor. bollinger has no bare call and three accessors, so it is listed and you reach it as bollinger_mid(20).

The filter and the rows both live in crates/vike-cli/src/cmd/indicators.rs, which also feeds the human vike-cli indicators listing, so the two surfaces cannot disagree about the built-in catalogue. An indicator installed from user_data/indicators shows up in that listing and in no answer this tool gives.

The answer is tiered, because the bound set is now most of the catalogue and a full dump would spend an agent's context on indicators it will never use.

ParameterTypeDefaultNotes
namestringomitOne indicator in full: its parameters with defaults and the value it returns
categorystringomitOne family in full; matched case-insensitively
(neither)——The compact roster: name + category per indicator

Returns indicators plus a count. The compact roster also carries a note explaining how to pull detail. A name or category nobody can serve is an isError result, not an empty list — an empty answer reads as "that family is empty in this build" and sends the reader hunting through a config. For a catalogued indicator the host deliberately holds back, the error quotes the host's own reason (vike_script::unbound_reason) verbatim rather than paraphrasing it. That arm fires only for a name callable under NO spelling — a Rhai reserved word, a host-function collision, a batch-only indicator, or one with more parameters than the host binds. A name whose bare call is refused but whose accessors work, like bollinger, never reaches it: it comes back as an ordinary catalogue row.

An unbound name compiles and then fails on every bar

Rhai resolves a registered function when the line runs, not at compile time, and the compile path only runs a script's top level. So a misspelled indicator or a wrong arity compiles cleanly, then raises ErrorFunctionNotFound on every bar. Argument type is the exception: register_arity_forms binds every arity with rhai::Dynamic parameters, so sma(5.0) resolves just like sma(5), and only a non-numeric argument (sma("20")) fails — as a named runtime error rather than function-not-found. crates/vike-script/src/strategy.rs's RhaiStrategy swallows each one fail-safe (zero orders that bar) and, after 10 consecutive errors, disables the strategy outright. It looks mounted and never trades. Check names against this tool, not against memory.

Which indicators can a vike Rhai strategy call, and what parameters does rsi take?

On this page