Skip to content

Features

Indicators and studies

Add the 71 built-in studies, pick input sources, and register your own custom studies.

Adding a study

Each study has its own method on the chart. It takes a source series and returns the study's output series, which you can style like any other series. Studies recalculate incrementally on every update, so the forming bar's value is always current.

Built-in studies
const ema = chart.add_ema(candles, 20);
const sma = chart.add_sma(candles, 50, { color: "#f7a600" });
const rsi = chart.add_rsi(candles, 14);

const [macd, signal, histogram] = chart.add_macd(candles, 12, 26, 9);
const [upper, middle, lower] = chart.add_bollinger(candles, 20, 2);

// Use a different input than the close.
chart.add_sma_with_source(candles, "hlc3", 20);

Input sources are open, high, low, close, hl2, hlc3, ohlc4, and hlcc4. Change the input of an existing study with set_indicator_input_source, and read a study's parameters with indicator_schema.

Built-in catalog

Built-in studies by category
CategoryStudies
Moving averagessma, ema, dema, tema, smma, hma, wma, vwma, alma, kama, mcginley, ema_ribbon, linear_regression
Bands and channelsbollinger, bollinger_metrics, envelopes, keltner, donchian, atr_bands, vwap_bands
Oscillatorsrsi, macd, stochastic, stochastic_rsi, cci, williams_r, momentum, roc, aroon, awesome_oscillator, dpo, chande_momentum, trix, kst, tsi, fisher_transform, ultimate_oscillator, coppock_curve
Trendadx_dmi, parabolic_sar, supertrend, ichimoku, vortex, zigzag, pivot_points, choppiness
Volatilityatr, standard_deviation, historical_volatility, mass_index
Volumevolume, vwap, obv, cmf, mfi, accumulation_distribution, price_volume_trend, chaikin_oscillator, klinger, relative_volume, volume_oscillator, elder_force, ease_of_movement
Structure and sessionswing_points, market_structure, fair_value_gaps, order_blocks, session_levels, previous_period_levels, opening_range

Session studies

Session highs and lows, previous period levels, and opening range use UTC boundaries by default. To follow an exchange's sessions instead, supply a calendar with set_study_calendar and remove it with clear_study_calendar.

Custom studies

Register a study type once, then bind it to any series. The engine owns scheduling, output validation, styles, and saved state; your callbacks only calculate. rebuild recalculates a range from scratch, and the optional update handles the live tail. Both receive Float64Array columns and write into ctx.outputs, which cover rows from to length.

Custom SMA
chart.register_custom_study({
  type: "acme.sma",
  version: 1,
  title: "Custom SMA",
  parameters: [{ name: "period", parameter_type: "integer", default: 20, min: 1, max: 500 }],
  outputs: [{ name: "average", plot: "line", pane: "price" }],
  init: (params) => ({ period: params.period }),
  rebuild: (state, ctx) => {
    for (let i = ctx.from; i < ctx.length; i++) {
      let sum = 0;
      for (let j = Math.max(0, i - state.period + 1); j <= i; j++) sum += ctx.close[j];
      ctx.outputs[0][i - ctx.from] = i >= state.period - 1 ? sum / state.period : NaN;
    }
  },
});

const [average] = chart.add_custom_study("acme.sma", candles, { period: 20 });

chart.subscribe_custom_study_fault(({ message }) => console.error(message));
Custom study definition
FieldDescription
type, version, titleA unique id, a schema version, and the display name.
parametersname, parameter_type (integer, number, boolean, source, series, choice), default, min, max, and options for choices.
outputs1 to 5 outputs, each with a name, plot (line, histogram, area, marker), and pane (price or dedicated).
uses_volumeSet when the calculation reads volume.
init(params)Returns your state for one binding.
rebuild(state, ctx)Recalculates rows from ctx.from to ctx.length.
update(state, ctx)Optional. Recalculates the live tail.

Limits

Up to 64 custom study types and 32 bindings per chart. Custom studies run on main-thread charts only, not worker charts.