Skip to content

오버레이 지표

가격과 같은 축을 쓰는 지표들 — MA(20)·EMA(50)·볼린저·VWAP·SAR·SuperTrend가 mainPane에 얹힌다. 밴드 채우기는 zIndex −1로 캔들 밑에 깔리고, SuperTrend는 상승 지지선과 하락 저항선 두 갈래가 번갈아 나타난다(반대 구간은 null이라 선이 끊긴다).

소스

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

ts
import { PlotBuilder, browserDeps } from "@finchart/dom";
import type { OHLC } from "@finchart/core";
import { candleSeries, priceFormat, timeTicks } from "@finchart/core";
import { legend } from "@finchart/dom";
import {
  attachBollingerBands,
  attachMovingAverage,
  attachParabolicSar,
  attachSuperTrend,
  attachVwap,
} from "@finchart/indicators";
import { fixtureCandles } from "./fixture";
import { chartHost } from "./stage";

export const title = "오버레이 지표";
export const description =
  "가격과 같은 축을 쓰는 지표들 — MA(20)·EMA(50)·볼린저·VWAP·SAR·SuperTrend가 mainPane에 얹힌다. 밴드 채우기는 zIndex −1로 캔들 밑에 깔리고, SuperTrend는 상승 지지선과 하락 저항선 두 갈래가 번갈아 나타난다(반대 구간은 null이라 선이 끊긴다).";

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 price = plot.mainPane.addSeries({
    series: candleSeries(),
    data: fixtureCandles(),
    name: "가격",
  });

  plot.mainPane.use(attachMovingAverage({ source: price, period: 20, color: "#f59e0b" }));
  plot.mainPane.use(
    attachMovingAverage({ source: price, period: 50, type: "ema", color: "#8b5cf6" }),
  );
  plot.mainPane.use(attachBollingerBands({ source: price, period: 20 }));
  plot.mainPane.use(attachVwap({ source: price, color: "#0ea5e9" }));
  plot.mainPane.use(attachParabolicSar({ source: price, color: "#ef4444" }));
  plot.mainPane.use(attachSuperTrend({ source: price }));

  plot.use(legend({}));

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