mmflow Charts
ChartScript
Write small, safe indicator formulas that compile into the same IndicatorInstance shape used by the mmflow Charts SDK.
Quickstart
One ChartScript source compiles to one chart indicator value. Each plot statement becomes one output line inside that indicator, so React users pass the result directly to the existing indicators prop.
import { Chart } from "@mmflow/react";
import { compileChartScript } from "@mmflow/charts";
import { createMmflowFeed } from "@mmflow/sdk";
const script = `
basis = sma(close, 20)
dev = stdev(close, 20) * 2
plot basis
plot basis + dev
plot basis - dev
`;
const compiled = compileChartScript(script, {
name: "Bands",
overlay: true,
});
export function ScriptedChart() {
return (
<Chart
feed={createMmflowFeed({ transport: "sse" })}
symbol="BTC"
resolution="1m"
volume
indicators={compiled.ok ? [compiled.indicator] : []}
style={{ height: 520 }}
/>
);
}Language MVP
ChartScript accepts only the grammar below. It does not execute JavaScript, import modules, fetch URLs, access the DOM, or call localStorage.
Statements
Use name = expression assignments and plot expression statements. A script must have at least one plot and may have up to eight.
Series
open, high, low, close, volume, hl2, hlc3, ohlc4, and time are built in. Assignments may not shadow built-in names.
Operators
+, -, *, /, %, ^, parentheses, unary minus, and numeric comparisons are supported. Comparisons return 1 or 0.
Functions
abs, min, max, sqrt, log, pow, round, floor, ceil, sma, ema, stdev, highest, lowest, change, roc, rsi, vwap, and macdLine are available.
fast = ema(close, 9)
slow = ema(close, 21)
plot fast
plot slow
plot rsi(close, 14) as "RSI 14"
plot 70
plot 30while true {}
fetch("https://example.com")
eval(close)
plot unknownThing(close)
plot sma(close, -5)
myfunc(x) = x + 1Compile API
compileChartScript returns diagnostics for invalid scripts and a directly usable IndicatorInstance for valid scripts. validateChartScript only returns diagnostics.
import {
compileChartScript,
validateChartScript,
type ChartScriptCompileResult,
} from "@mmflow/charts";
const diagnostics = validateChartScript("plot sma(close, -5)");
const result: ChartScriptCompileResult = compileChartScript(
"plot sma(close, 20)",
{ name: "SMA 20", overlay: true },
);
if (result.ok) {
// result.indicator is accepted directly by <Chart indicators={...} />.
console.log(result.meta.plots);
}Runtime behavior
The evaluator works over the chart candle arrays and sanitizes output before it reaches the renderer.
Scalar and series math
series + series, series + scalar, scalar + series, and scalar + scalar all work. A scalar plot becomes a constant line.
Missing values
Short rolling windows and non-finite values become the chart engine's missing-value convention instead of crashing render.
Script-level pane choice
Use compileChartScript(source, { overlay }) to choose price overlay or sub-pane behavior for the whole script.
Current limitations
Phase 6 is a formula-language MVP, not Pine Script or a strategy engine.
No alerts
alert, crossover alerts, and webhook behavior are not part of this phase.
No strategies
Order placement, broker integration, and backtesting remain out of scope.
No user functions
Loops, recursion, imports, and user-defined function declarations are rejected.
No persistence
Cloud saves, sharing, marketplace flows, and AI script generation are later product phases.
Repo starter template
Copy frontend/examples/chartscript-indicator for a ChartScript bands example with compile/validate diagnostics and a chart-ready indicator.
Continue building
Move through the chart SDK docs without leaving the developer flow.