Language reference · live

MuseScript

A small, honest language for describing trading strategies — legible enough to hand-write, structured enough for an evolution engine to discover. Every example on this page is editable and runs in your browser on the same three-backend engine the desktop app ships. Nothing is uploaded; runs are seeded and reproducible.

Open the full Studio →Convert a Pine script

01

Anatomy of a strategy

A strategy declares params (tunable inputs with a type and a default), then a strategy block with event handlers. onBar runs once per bar with open, high, low, close, and volume in scope. You emit orders with long(), flat(), and short(); a guard fires with when condition: { … }.

MuseScript · live · js

The canonical dual-SMA crossover. Edit `fast`/`slow` in the params and re-run — the numbers change live. On a driftless random walk with no planted edge, expect an honest NO-GO.

02

Signals & control flow

Conditions are boolean expressions. The stateful edge-detectors — crossover(a, b), crossunder(a, b), rising(x, n), falling(x, n)— fire only on the bar the event happens, so a guard doesn't re-trigger every bar the condition stays true. Combine gates with &&/||, or the variadic all_of(…) / any_of(…).

MuseScript · live · js

A trend-plus-momentum gate: only go long when price is above its slow average AND RSI is rising. Exit when price loses the trend line.

03

Indicators

The usual toolbox is built in and incrementally computed (no O(n²) refolds): sma, ema, wma, rma, rsi, atr, mom, roc, stdev, highest, lowest, vwap. Multi-output indicators return a struct you read by field: macd(close).macd, bbands(close, 20, 2).upper, stoch(14, 3, 3).k, donchian(20).mid.

MuseScript · live · js

A Bollinger-band mean-reversion sketch: buy the lower band, exit at the midline. Reads two struct fields off one `bbands` call.

04

The candle-pattern DSL

A small vocabulary for describing candle shapes — designed to read cleanly by hand and to be discoverable by the evolution engine. Each takes i bars back (0 = current): candle_body(i), candle_body_abs(i), candle_upper_wick(i), candle_lower_wick(i), candle_dir(i) (+1/−1), and the ATR-normalized candle_range_atr(i, n) and candle_gap(i, n). Count how many recent bars satisfy a condition with count_true(…); measure recency with bars_since(cond).

MuseScript · live · js

A hammer-ish reversal: a long lower wick relative to a small body, after a run of down bars. Scale-free (wick vs body), so it transfers across instruments.

There's a whole candle-pattern cookbook — hammer, engulfing, doji, marubozu, pin bar, three soldiers and more, each runnable.

05

Position & risk

Inside onBar (and the optional onPosition handler) you can read live position state: position(), entry_price(), bars_in_trade(), return_since_entry(), unrealized_pnl_pct(). For exits, trail(dist) is a peak-following ratchet stop — pair it with atr for a volatility-scaled trail that follows a winner up and only exits on a real pullback.

MuseScript · live · js

Enter on a breakout of the 20-bar high; exit on a 2·ATR trailing stop or after a time limit. `trail()` is inert while flat, so it's safe to leave in an unconditional exit guard.

06

Multi-asset & portfolios

The same language scales to a universe. Gate per-instrument with asset_is("BTC") / symbol_is(…); read another symbol's series with close_of(sym, n), rsi_of(sym, n), sma_of(sym, n). Rank the universe with scan_top / scan_bottom or the composable bag_* family, then express a target book with rebalance_equal(…), target_weight(sym, w), or portfolio_apply(bag). These need a panel of symbols, so they run in the Studio and the desktop app rather than the single-tape sandbox here.

MuseScript · portfolio · panel-only
strategy XSMomentum {
  onBar {
    // rank the universe by 60-bar momentum, hold the top 5 equally
    winners = bag_rank_mom(60, 5, "mom60")
    rebalance_equal(bag_symbols(winners))
  }
}

07

The honesty layer

Every run comes back with a truthReport, and the reference deliberately shows it above the naked Sharpe. A high in-sample Sharpe is easy and usually a lie; the engine reports a verdict after a deflated Sharpe ratio (DSR), a null-Sharpe baseline (what a coin-flip on the same tape scores), a probability of backtest overfitting (PBO), and a minimum-trades gate. On a no-edge random walk the honest answer is NO-GO — and the tool says so.

MuseScript · live · js

Same crossover as §1, run longer. Watch the verdict and DSR, not the Sharpe. If you can edit this into a GO on a driftless walk without more trials, you've found a bug — tell us.

This is the whole posture of the product: the language and the engine make it easy to be honest and hard to fool yourself. That's what the verifier and the certified-calibration receipts are built on.

08

Builtin index

The core surface, grouped. This is the hand-writing and evolution vocabulary; the full runtime also ships numeric (np_*), dataframe (pd_*), graph, and program-synthesis (tune, walkforward, distill) families for advanced work in the Studio.

Indicators

sma(src, n)
Simple moving average.
ema(src, n)
Exponential moving average.
wma(src, n)
Weighted moving average.
rma(src, n)
Wilder's smoothing (RSI/ATR base).
rsi(src, n)
Relative strength index.
atr(src, n)
Average true range; atr(n) also accepts implicit OHLC.
mom(src, n)
Momentum: src − src[n].
roc(src, n)
Rate of change (%).
stdev(src, n)
Rolling standard deviation.
highest(src, n)
Highest value over n bars.
lowest(src, n)
Lowest value over n bars.
vwap()
Volume-weighted average price.
slope(src, n)
OLS per-bar slope — signed trend strength.
zscore_roll(src, n)
Rolling z-score of src vs its window.
percent_rank(src, n)
Percentile rank in [0,1] over n bars.

Multi-output indicators

Return a struct — read by field.

macd(src, f, s, sig).macd | .signal | .hist
MACD line, signal, histogram.
bbands(src, n, k).upper | .mid | .lower
Bollinger bands.
stoch(k, d, sm).k | .d
Stochastic oscillator.
donchian(n).upper | .mid | .lower
Donchian channel (`.middle` aliases `.mid`).

Signals & control flow

crossover(a, b)
True on the bar a crosses above b.
crossunder(a, b)
True on the bar a crosses below b.
rising(x, n)
x has risen for n bars.
falling(x, n)
x has fallen for n bars.
all_of(…) / any_of(…)
Variadic AND / OR over booleans.
count_true(…)
How many of the given conditions are true.
bars_since(cond)
Bars since cond was last true (0 = now).

Candle-pattern DSL

i = bars back (0 = current bar).

candle_body(i)
Signed close − open.
candle_body_abs(i)
Absolute body size.
candle_upper_wick(i)
Upper shadow length.
candle_lower_wick(i)
Lower shadow length.
candle_dir(i)
+1 up bar, −1 down bar.
candle_range_atr(i, n)
Bar range normalized by ATR(n).
candle_gap(i, n)
Open-vs-prior-close gap, ATR-normalized.

Orders

long() / short() / flat()
Go long, short, or close. Optional tag: flat("stop").
orders_pending()
Count of unfilled orders.
orders_cancel_all()
Cancel pending orders.

Position & risk

position()
Signed position size (0 = flat).
entry_price()
Average entry price of the open position.
bars_in_trade()
Bars since entry.
return_since_entry()
Return since entry.
unrealized_pnl() / _pct()
Open P&L, absolute or percent.
highest_since_entry(f) / lowest_since_entry(f)
Extreme of field f since entry.
trail(dist)
Peak-following ratchet stop; inert while flat.
cash() / equity()
Available cash / total equity.

Multi-asset

Panel/universe strategies (run in Studio & desktop).

asset_is(sym) / symbol_is(sym)
Gate logic to one instrument.
symbols() / sym_available(sym)
The live universe / membership test.
close_of / open_of / high_of / low_of / volume_of (sym, n)
Another symbol's OHLCV.
sma_of / ema_of / mom_of / rsi_of (sym, n)
Another symbol's indicators.
fund_of(sym, field, n)
Fundamental field lookup.
scan_top(dict, n) / scan_bottom(dict, n)
Top/bottom-n symbols by a scored dict.

Portfolio & bags

Composable target-book algebra.

bag_rank_mom / bag_rank_rsi / bag_rank_field
Rank the universe into a weighted bag.
bag_add / bag_sub / bag_mask / bag_scale / bag_norm
Combine and reshape bags.
rebalance_equal(syms)
Equal-weight a symbol list.
target_weight(sym, w)
Set a target weight for one symbol.
portfolio_apply / portfolio_add / portfolio_sub
Apply a bag as the target book.
pos(sym) / weight_of(sym) / holdings()
Inspect the current book.

Math & utility

min(…) / max(…)
Arity-aware: 1 arg reduces an iterable, 2+ is element-wise.
sum(xs) / avg(xs) / count(xs)
Reductions over an iterable.
clamp(x, lo, hi)
Constrain x to [lo, hi].
nz(x, fallback) / na(x)
Null-coalesce / is-not-available test.
window(src, n) / ohlcv_window(n)
Materialize the last n bars as a vector.

Honesty & diagnostics

truthReport
Per-run verdict, DSR, null-Sharpe, PBO, gates — returned by every run.
sharpe / sortino / max_drawdown (equity)
Risk-adjusted stats over an equity curve.
diag_drawdown / diag_underwater / diag_acf
Drawdown, underwater, autocorrelation diagnostics.
plot / plotshape / hline / bgcolor
Chart overlays for the Studio.

Keep going