Skip to content

Renko — 시간을 버리고 가격만

가격이 brickSize만큼 움직일 때마다 벽돌 하나 — 브릭의 x는 시간이 아니라 서수다(그게 Renko의 정의다). 같은 방향은 한 칸, 반전은 두 칸(한 칸 갭 규칙). 결과가 OHLC 모양이라 candleSeries가 그대로 그리고, x축 라벨은 브릭의 closedAt(완성 시각)을 표기로 되찾는다 — 표기의 주인은 축이고 축은 소비자가 배선한다.

소스

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

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

export const title = "Renko — 시간을 버리고 가격만";
export const description =
  "가격이 brickSize만큼 움직일 때마다 벽돌 하나 — 브릭의 x는 시간이 아니라 서수다(그게 Renko의 정의다). " +
  "같은 방향은 한 칸, 반전은 두 칸(한 칸 갭 규칙). 결과가 OHLC 모양이라 candleSeries가 그대로 그리고, " +
  "x축 라벨은 브릭의 closedAt(완성 시각)을 표기로 되찾는다 — 표기의 주인은 축이고 축은 소비자가 배선한다.";

export function mount(container: HTMLElement): () => void {
  const host = chartHost(container, 480);

  const bricks = renko(fixtureCandles(), { brickSize: 400 });
  const timeLabel = new Intl.DateTimeFormat("ko", {
    timeZone: "UTC",
    hour: "2-digit",
    minute: "2-digit",
    hour12: false,
  });

  const plot = PlotBuilder.create<OHLC>(browserDeps({ autoSize: true }))
    .setSize(container.clientWidth || 900, 480)
    .setAxis({
      // 서수 x를 완성 시각으로 되찾는다 — Renko 축 표기의 정석.
      x: {
        format: (x) => {
          const brick = bricks[Math.round(x)];
          return brick ? timeLabel.format(brick.closedAt) : "";
        },
      },
      y: { position: "right", format: priceFormat({ compact: true, locale: "ko" }) },
    })
    .build(host);

  plot.mainPane.addSeries({
    series: candleSeries(),
    data: bricks,
    name: `Renko(400)`,
  });

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