ChartnautDocs

Volume

The Volume indicator from the public library (volume), written against the current DSL. The library row's source emits with ctx.plot and never reads downColor. This version uses ctx.bar so the histogram draws, and colours down bars.

What it plots

A histogram of each bar's volume along the bottom of the price pane, green on up bars and red on down bars.

Key decisions

Piece

Why it matters

scale({ id: "vol", margins: { top: 0.8, bottom: 0 } })

Gives the bars their own invisible axis in the bottom fifth of the price pane, so volume does not squash the candles.

priceFormat: { type: "volume" }

Labels read 1.2K and 12.67M instead of raw numbers.

ctx.bar("volume", ctx.volume, color)

A histogram takes ctx.bar, not ctx.plot. The third argument colours this bar only.

No ctx.accum, no warmup

The script keeps no state, so it declares no warmup.

Full script

meta({
  shortName: "Volume",
  kind: "overlay",
  dataSource: "candles",
  category: "custom",
});

dialog({
  title: "Volume Configuration",
  description: "Configure Volume indicator settings",
  width: 400,
  height: 300,
  resizable: false,
  showEnabledCheckbox: true,
  resetToDefaults: {
    enabled: true,
    confirmationMessage: "Are you sure you want to reset all Volume settings to their default values?",
  },
});

const upColor = input.color({
  id: "upColor",
  label: "Up Color",
  default: "#26a69a",
  allowAlpha: true,
});

const downColor = input.color({
  id: "downColor",
  label: "Down Color",
  default: "#ef5350",
  allowAlpha: true,
});

const labelsEnabled = input.boolean({
  id: "labelsEnabled",
  label: "Show Labels",
  description: "Display volume values on chart",
  default: true,
});

layout(
  tab({ id: "appearance", title: "Appearance" },
    section({ id: "colors", title: "Colors", columns: 2 }, upColor, downColor),
    section({ id: "display", title: "Display Options" }, labelsEnabled),
  ),
);

// Volume on its own invisible axis along the bottom fifth of the price pane, so it neither
// squashes the candles nor changes how price autoscales.
const volScale = scale({
  id: "vol",
  margins: { top: 0.8, bottom: 0 },
  priceFormat: { type: "volume" },
});

output.histogram({
  id: "volume",
  scale: volScale,
  colorFrom: upColor,
  labelFrom: labelsEnabled,
  titleWhenLabeled: "Volume",
});

/** @param {ScriptedCtx} ctx */
export function onBar(ctx) {
  const color = ctx.close >= ctx.open ? ctx.params.upColor : ctx.params.downColor;
  ctx.bar("volume", ctx.volume, color);
}

Series types for the histogram, and Build your own indicator to have the Agent write one.