The slice of the chart the runtime needs. Keeps this module testable alone.

interface IndicatorHost {
    addIndicatorFill(fill: IndicatorFill, paneIndex: number): void;
    addIndicatorLegend(
        opts: {
            color?: string;
            hasSource?: boolean;
            id: string;
            paneIndex: number;
            params: string;
            row: number;
            title: string;
        },
    ): PaneLegend;
    addIndicatorLevel(
        level: {
            color: string;
            dashed: boolean;
            id: string;
            label: string;
            lineStyle: IndicatorLineStyle;
            lineWidth: number;
            price: number;
        },
        paneIndex: number,
    ): PriceLine;
    addIndicatorPrimitive(primitive: IPrimitive, paneIndex: number): void;
    addIndicatorSeries(
        type: string,
        paneIndex: number,
        style: undefined | Record<string, unknown>,
        priceScaleId: undefined | string,
        priceFormat?: PriceFormat,
    ): SeriesApi;
    addIndicatorTable(paneIndex: number): ChartTable;
    assignIndicatorScale(
        id: string,
        series: readonly { api: SeriesApi; scaleId: PriceScaleId }[],
        primitives: readonly { primitive: IPrimitive; scaleId: PriceScaleId }[],
        commit: () => void,
    ): boolean;
    bindIndicatorPrimitiveScale(
        primitive: IPrimitive,
        scaleId: PriceScaleId,
    ): void;
    dataContext(): undefined | Readonly<ChartDataContext>;
    emit(event: string, payload: unknown): void;
    flushIndicators(): void;
    formatPrice(
        paneIndex: number,
        value: number,
        series?: SeriesApi,
    ): undefined | string;
    indicatorOutputChanged(id: string, refresh: boolean): void;
    indicatorRecompute(
        id: string,
        refresh: boolean,
        fallback: () => void,
    ): void;
    indicatorRemoved(instanceId: string, failedOwnedPane?: number): void;
    interval(): undefined | string;
    legendIndex(): undefined | number;
    legendRowsOn(paneIndex: number): number;
    nextPaneIndex(): number;
    now(): number;
    policyChanged(): void;
    primaryPaneIndex(): number;
    primarySeries(): null | SeriesApi;
    removeIndicatorFill(fill: IndicatorFill): void;
    removeIndicatorLegend(legend: PaneLegend): void;
    removeIndicatorLevel(line: PriceLine): void;
    removeIndicatorMarkers(markers: SeriesMarkers): void;
    removeIndicatorPrimitive(primitive: IPrimitive): void;
    removeIndicatorTable(table: ChartTable): void;
    requestBars(request: IndicatorBarsRequest): Promise<readonly Bar[]>;
    requestSnapshot(
        request: IndicatorSnapshotRequest,
    ): Promise<RequestedBarsSnapshot>;
    requestState(): Readonly<IndicatorRequestState>;
    resourcesChanged(): void;
    setBarColors(
        colors: null | readonly (null | string)[],
        owner: string,
    ): void;
    setIndicatorRange(
        id: string,
        paneIndex: number,
        scaleId: PriceScaleId,
        range: null | { max: number; min: number },
        series: readonly SeriesApi[],
    ): void;
    setIndicatorSeriesType(series: SeriesApi, type: string): boolean;
    setPaneRange(
        paneIndex: number,
        range: null | { max: number; min: number },
    ): void;
    sourceBars(): readonly Bar[];
    sourceState(): undefined | SeriesDataState;
    studyOutput(
        source: IndicatorStudySource,
    ): undefined | Readonly<IndicatorStudyOutput>;
    subscribeDataChanges(
        listener: (change: IndicatorDataChange) => void,
    ): () => void;
    subscribeRequestChanges(listener: () => void): () => void;
    symbol(): undefined | string;
    tickSize(paneIndex: number): undefined | number;
    timezone(): string;
    underlyingBars(): | null
    | { bars: readonly Bar[]; sourceIndex: null
    | readonly number[] };
    validateIndicatorSettings(
        id: string,
        descriptor: IndicatorDescriptor,
        settings: Readonly<IndicatorSettings>,
    ): void;
}

Methods

  • Add the pane-legend row (name + inline up/down/hide/maximize/close).

    Parameters

    • opts: {
          color?: string;
          hasSource?: boolean;
          id: string;
          paneIndex: number;
          params: string;
          row: number;
          title: string;
      }
      • Optionalcolor?: string
      • OptionalhasSource?: boolean

        The descriptor's hasSource, so the row can offer a source button.

      • id: string
      • paneIndex: number
      • params: string
      • row: number
      • title: string

    Returns PaneLegend

  • Add a reference level. One options object rather than seven positional arguments: the list grew a width and a dash style in 1.7.1, and a call site of seven bare values is where the next one gets passed in the wrong slot.

    Parameters

    • level: {
          color: string;
          dashed: boolean;
          id: string;
          label: string;
          lineStyle: IndicatorLineStyle;
          lineWidth: number;
          price: number;
      }
      • color: string
      • dashed: boolean

        Kept for hosts predating lineStyle; always lineStyle === 'dashed'.

        Removed in 3.0.0. Read lineStyle (since 1.7.1), which also carries 'dotted'. The instance resolves it before calling the host, so it is never absent.

      • id: string
      • label: string
      • lineStyle: IndicatorLineStyle
      • lineWidth: number
      • price: number
    • paneIndex: number

    Returns PriceLine

  • Attach an arbitrary primitive to a pane, and detach it again. Carries both the descriptor's drawing layer and whatever a Tier-2 attach lifecycle wants to paint, so those two do not need a host method each.

    Optional, like timezone, so a host predating it still satisfies this interface: an indicator that draws simply draws nothing there.

    Parameters

    Returns void

  • A series for one plot. The study writes it with setData for a whole pass and, from 2.5.8, with update for the points a live tick moved (older points included), so a host's own series must implement both as documented.

    Parameters

    • type: string
    • paneIndex: number
    • style: undefined | Record<string, unknown>
    • priceScaleId: undefined | string
    • OptionalpriceFormat: PriceFormat

      Axis/crosshair formatting for the scale this plot maps to.

    Returns SeriesApi

  • Emit on the chart's event bus (indicator alerts, and attach's own events).

    Parameters

    • event: string
    • payload: unknown

    Returns void

  • Recompute whatever the host has marked stale, before a caller reads a value.

    Optional, like timezone, so a host predating it still satisfies this interface: one that recomputes eagerly has nothing to flush.

    Returns void

  • Write a number the way the price axis of that pane writes it.

    The legend sits inches from the axis and names the same quantity, so the two disagreeing is the reading a user has to reconcile themselves. Deriving the format here from a tick got that wrong twice over: a study pane carries no tick at all, so a percentage read 0.618 beside an axis saying 0.62, and a price pane's tick alone misses the precision floor and the host's own formatter, so a volume study read seven digits where its axis said 1.20M.

    Asking the scale removes the second opinion. Optional so a host driving this module alone still works, falling back to the magnitude ladder.

    Parameters

    • paneIndex: number
    • value: number
    • Optionalseries: SeriesApi

    Returns undefined | string

  • Parameters

    • id: string
    • refresh: boolean
    • fallback: () => void

    Returns void

  • Forget a disposed instance, including disposal through its public handle.

    Parameters

    • instanceId: string
    • OptionalfailedOwnedPane: number

    Returns void

  • How many legends already sit on this pane, so rows stack.

    Parameters

    • paneIndex: number

    Returns number

  • Current slot of the chart's price pane, where an on-chart study and every overlay plot, band, table and price-anchored mark draws. Read at each use, since the price pane can be moved below the studies. Optional so a host predating it still satisfies this interface; absent means slot 0.

    Returns number

  • Detach a signal-marker layer. There is no matching add: the layer comes from series.createMarkers() on a plot's own series, or on the instrument's for marks sent to the candles, so it already lands in the right pane. Removing a series does not remove its primitives, hence this.

    Parameters

    Returns void

  • Restore the host's study stack after settings replace series or attached visuals. Also called from inside a calculation pass when that pass first creates a layer for an output target (see IndicatorOutputTarget), so the layer takes its study's place among the targeted layers instead of landing above every later study's. During that call the instances report their targeted layers alone, so nothing else moves. It must only restack: recomputing studies from it would run them in the middle of another study's pass.

    Returns void

  • Publish an indicator's per-bar colours onto the primary price series, or withdraw them with null. owner is the instance id: a host holds one overlay at a time and only lets its current owner withdraw it, so a second publisher taking over does not get cleared by the first one's teardown.

    Optional, like timezone: a host that does not implement it simply gives a barColors descriptor nowhere to publish, and the indicator's own plots are unaffected.

    Parameters

    • colors: null | readonly (null | string)[]
    • owner: string

    Returns void

  • Pin a pane's price scale to a fixed range, or release it with null.

    Parameters

    • paneIndex: number
    • range: null | { max: number; min: number }

    Returns void

  • The instrument and timeframe on screen, when the host knows them. The host can supply an explicit dataContext instead. Without either hook, a descriptor sees undefined rather than a guessed identity.

    Returns undefined | string

  • Tick size of the named pane's price scale, or undefined when none is set. Optional so a host predating it still satisfies this interface.

    Per pane, and the panes genuinely differ: a pane that does not quote the instrument has no tick to report. The price pane (primaryPaneIndex) is the one to ask for the instrument's own step.

    Parameters

    • paneIndex: number

    Returns undefined | number

  • The chart's configured IANA zone. Optional so a host predating the option still satisfies this interface; absent means the shipped default.

    A descriptor is handed bars and settings and never the chart, so this is how the calendar an anchor resets on (a VWAP session, a seasonality month) reaches the calculation. See IndicatorInstance._descriptorSettings.

    Returns string

  • The host's bars under a transformed primary series and the source bar each of sourceBars was completed on (null when they are one to one), or null when the chart draws its bars as given. Optional; without it a study on the underlying bars computes on sourceBars, and one on the chart's bars is never told they are transformed (IndicatorCalcContext.transformed).

    Returns null | { bars: readonly Bar[]; sourceIndex: null | readonly number[] }