Cheatsheet
Every host function a strategy script can call, every hook it can define, and the indicator call forms — one scannable page beside the full ones.
Everything below is registered by crates/vike-script/src/engine.rs's build_engine onto a resource-limited engine (the numbers are on Limits) and driven by crates/vike-script/src/strategy.rs's RhaiStrategy. The non-indicator names are pinned in engine.rs's HOST_FN_NAMES. The indicator names are derived from the registry at run time and are deliberately not listed here — vike-cli indicators prints the callable set (indicators).
Hooks
| hook | called | notes |
|---|---|---|
fn on_start() | before the first bar | position()/price() are not refreshed here — there is no symbol yet, so they read their initial 0.0 |
fn on_bar() | once per bar | the only place to read the bar and trade |
fn on_stop() | when the engine stops the strategy |
A hook is detected by name as a zero-argument fn; one the script never wrote is skipped, never attempted. There is no fill hook — a script observes its resulting position through position(). The top level (everything outside a fn) runs EXACTLY ONCE at compile: a top-level const is visible inside every hook, a top-level buy(1.0); is discarded, and a top-level indicator reference is cleared so the first real bar is the first bar any indicator sees. A hook's own let locals live for that one call; the script keeps no cross-bar mutable state of its own.
Context — the current bar
| function | returns |
|---|---|
close() open() high() low() volume() | f64, that field of the current bar |
index() | i64, the current step index — bars processed so far minus one |
now() | i64, engine time in epoch milliseconds |
All snapshotted before the hook runs (register_reads).
Account
| function | returns |
|---|---|
position() | f64, signed position size in the mounted symbol; 0.0 when flat |
price() | f64, the last mark — the engine's post-fill price in a backtest, the bar close live |
equity() | f64, account equity now |
The definitions are vike_model::Broker's own (crates/vike-model/src/strategy/mod.rs); the script reads a snapshot of them.
Orders
| verb | meaning |
|---|---|
buy(qty) | market, side +1 |
sell(qty) | market, side -1 |
market(side, qty) | market; side is 1 to buy, -1 to sell |
limit(side, qty, price) | limit at price |
qty is f64 in units; side is an integer. A verb records an Intent (crates/vike-script/src/ctx.rs); after the hook returns cleanly the intents are drained onto the broker in order, on the mounted symbol. A hook that errors drains nothing. The full page is The order vocabulary.
Parameters
let fast = param("fast", 5.0); // top level, so the one-time run bakes the value inparam(name, default) -> f64. The default may be written 5 or 5.0 — it is Dynamic, not f64, after a version that rejected the integer spelling. First-seen wins in the (name, default) list discovery reports; the call itself still returns its own default when nothing overrides it. A sweep injects overrides BEFORE the one-time top-level run, so a swept value holds for the strategy's whole life; discover_params lists the (name, default) pairs in declaration order for the sweep grid.
Indicators
| form | example | rule |
|---|---|---|
name() | psar() | every parameter at its registry default — the only spelling for a parameterless indicator, and the only way to reach a fractional default |
name(p1) … name(p1, p2, p3) | sma(20), rsi(14) | up to the indicator's own parameter count, at most 3; parameters left off the end take their defaults; one argument too many is a function-not-found |
name_line(...) | bollinger_mid(20, 2.0), macd_signal(12, 26, 9), stochastic_k(14) | one accessor per line of a multi-output indicator, same arguments as the bare name; all lines of one indicator share one streaming instance |
Arguments are int or float; a non-numeric argument is a runtime error, not NaN. A bare name binds when the indicator is single-output or its line 0 is the namesake line (macd(), adx()); bollinger, donchian, keltner, envelopes and std_error_bands are refused bare because their line 0 is upper — spell the line, bollinger_mid(). Never bound in any spelling: ichimoku, zigzag and williams_fractal (they read future bars), kst (nine parameters), and var (a Rhai reserved word — use stddev).
Call every indicator unconditionally, every bar
An indicator is fed the current bar the first time it is referenced in that bar; a second reference returns the cached value. One behind an if silently skips the bars it is not called on and desyncs from the series (crates/vike-script/src/lib.rs). NaN means warming up — the shipped templates open with if s.is_nan() { return; }.
A user indicator from user_data/indicators/<name>.rhai is called the same way: my_ema(), my_ema(20) for each param() it declares, my_bands_mid() for a declared line. Writing an indicator has the file contract; in short, fn on_bar(bar) is required, bar is a map of ts/open/high/low/close/volume, this is the state fn init() built, returning () means warm-up, and param() is the only host function that engine registers — an indicator cannot trade.
Diagnostics
print(...) and debug(...) go to the tracing target vike_script at INFO and DEBUG, never to the host's stdout (redirect_script_output). import is refused. A runtime error costs that bar's orders; ten in a row disable the strategy.
A whole strategy
The shipped SMA cross template (crates/vike-script/src/templates.rs's SMA_CROSS), which also uses Rhai's own to_int, is_nan and abs:
let fast = param("fast", 5.0);
let slow = param("slow", 20.0);
fn on_bar() {
let f = sma(fast.to_int()); let s = sma(slow.to_int());
if s.is_nan() { return; }
let target = if f > s { 1.0 } else { -1.0 };
let delta = target - position();
if abs(delta) > 1e-12 { market(if delta > 0.0 { 1 } else { -1 }, abs(delta)); }
}Limits
The resource ceilings build_engine sets on every strategy script, what trips each one, and what the strategy does when one trips.
Indicators
The built-in indicator catalog — 171 single-series indicators across nine categories plus 8 pair indicators — and the one guarantee every one of them carries.