Skip to content

Volume Profile — 보이는 구간의 분포

보이는 x-구간의 거래량을 가격 구간별 가로 막대로 — pan·zoom하면 분포가 그 자리에서 다시 선다(TradingView Visible Range 계보). 가장 두꺼운 구간(POC)만 색이 다르다. 시리즈가 아니라 장식이라 addDecoration 한 줄이고, 막대는 전부 drawShape rect라 headless로 단언된다.

소스

apps/examples/src/cases/volume-profile.ts — CI가 타입체크하는 실물이다.

ts
import { PlotBuilder, browserDeps } from "@finchart/dom";
import type { OHLC } from "@finchart/core";
import { candleSeries, priceFormat, timeTicks } from "@finchart/core";
import { volumeProfile } from "@finchart/indicators";
import { fixtureCandles } from "./fixture";
import { chartHost } from "./stage";

export const title = "Volume Profile — 보이는 구간의 분포";
export const description =
  "보이는 x-구간의 거래량을 가격 구간별 가로 막대로 — pan·zoom하면 분포가 그 자리에서 다시 선다(TradingView Visible Range 계보). " +
  "가장 두꺼운 구간(POC)만 색이 다르다. 시리즈가 아니라 장식이라 addDecoration 한 줄이고, 막대는 전부 drawShape rect라 headless로 단언된다.";

export function mount(container: HTMLElement): () => void {
  const host = chartHost(container, 480);
  const plot = PlotBuilder.create<OHLC>(browserDeps({ autoSize: true }))
    .setSize(container.clientWidth || 900, 480)
    .setAxis({
      x: { ticks: timeTicks({ timeZone: "UTC", locale: "ko" }) },
      y: { position: "right", format: priceFormat({ compact: true, locale: "ko" }) },
    })
    .build(host);

  const data = fixtureCandles();
  const price = plot.mainPane.addSeries({
    series: candleSeries(),
    data,
    name: "가격",
  });

  const remove = plot.mainPane.addDecoration(
    volumeProfile({ source: price }),
  );

  return Object.assign(
    () => {
      remove();
      plot.destroy();
      host.remove();
    },
    { requestRender: () => plot.requestRender() },
  );
}