MM Flow

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.

React usage
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.

Example syntax
fast = ema(close, 9)
slow = ema(close, 21)
plot fast
plot slow

plot rsi(close, 14) as "RSI 14"
plot 70
plot 30
Invalid scripts fail safely
while true {}
fetch("https://example.com")
eval(close)
plot unknownThing(close)
plot sma(close, -5)
myfunc(x) = x + 1

Compile API

compileChartScript returns diagnostics for invalid scripts and a directly usable IndicatorInstance for valid scripts. validateChartScript only returns diagnostics.

Public API
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.