주식 차트

시가-고가-저가-종가-거래량 캔들, 시장 시간 범위, 지표, 프로필, 가격 레벨 및 마커.

프레임워크 빠른 시작

같은 주식 차트를 여섯 가지 방식으로 렌더링

명령형 TypeScript API 또는 얇은 프레임워크 어댑터를 선택하세요. 모든 탭은 같은 타입 배열 데이터와 차트 옵션을 사용합니다.
chart.ts@sixtyfold/stock
import { StockChart, type TimeRange } from "@sixtyfold/stock";

const data = {
  timestamp: new Float64Array([0, 60_000, 120_000, 180_000]),
  open: new Float64Array([100, 102, 101, 104]),
  high: new Float64Array([103, 104, 105, 107]),
  low: new Float64Array([99, 100, 100, 103]),
  close: new Float64Array([102, 101, 104, 106]),
  volume: new Float64Array([420, 510, 470, 630]),
  length: 4,
};

const canvas = document.querySelector<HTMLCanvasElement>("#chart")!;
const chart = new StockChart(canvas, {
  renderMode: "auto",
  timeScale: "market",
  showVolume: true,
  priceUnit: { prefix: "$", decimals: 2 },
});

await chart.initialize();
chart.setData(data);

// The application owns the controls: choose any labels and ranges, or none.
const controls = document.querySelector("#stock-ranges")!;
for (const range of ["1D", "1M", "ALL"] as const satisfies readonly TimeRange[]) {
  const button = document.createElement("button");
  button.type = "button";
  button.textContent = range;
  button.addEventListener("click", () => chart.setTimeRange(range));
  controls.append(button);
}


window.addEventListener("pagehide", () => chart.destroy(), { once: true });

@sixtyfold/stock은 시장별 분석 레이어와 함께 정렬된 시가, 고가, 저가, 종가 및 거래량(OHLCV) 열을 렌더링합니다. 상세도(LOD) 프로세스는 많은 가시 캔들을 자동으로 유효한 OHLCV 기간으로 결합한 다음 확대하면 더 세분된 캔들로 복원합니다.

정확한 구성 및 메서드 시그니처는 생성된 Stock options, StockChart methods, 및 OHLCV data types 참조에 있습니다.

StockChart는 라이프사이클, 뷰포트, 표시, 오버레이, 렌더러 및 배칭 메서드를 직접 노출합니다. 마켓-타임 모드에서는 뷰포트 메서드가 압축된 관찰-세션 좌표를 유지하는 반면 공개 값은 실제 타임스탬프로 남습니다.

캔들 및 거래량

filled, hollow 또는 ohlc 캔들 기하를 선택하세요. candleColors은 상승/하락 봉 몸통과 심지를 제어합니다. 거래량은 별도의 색상, 불투명도 및 패널-높이 비율을 가집니다.

렌더러는 OHLCV 툴팁과 크로스헤어 콜백에 대한 표시 정밀도를 제한합니다. 애플리케이션에서 명시적 통화, 단위, 소수점 또는 축약 형식이 필요할 경우 priceUnit 및 volumeUnit을 제공하세요.

호스트 소유 시간 범위

StockChart는 시간 범위 버튼을 생성하거나 스타일링하지 않습니다. 호스트 애플리케이션이 레이블, 개수, 순서, 레이아웃 및 접근성을 소유하거나 전혀 컨트롤을 렌더링하지 않을 수 있습니다.

버튼이 내보낸 편의 프리셋 중 하나에 매핑될 때 setTimeRange()를 호출하세요: 1D, 5D, 1M, 3M, 6M, YTD, 1Y, 5Y 또는 ALL. 로드된 히스토리를 벗어나는 프리셋은 사용 가능한 데이터에 맞춰 클램프됩니다.

const controls = document.querySelector<HTMLElement>("[data-stock-ranges]")!;
const ranges = [
  ["Day", "1D"],
  ["Six months", "6M"],
  ["Everything", "ALL"],
] as const;

for (const [label, range] of ranges) {
  const button = document.createElement("button");
  button.type = "button";
  button.textContent = label;
  button.dataset.range = range;
  button.addEventListener("click", () => chart.setTimeRange(range));
  controls.append(button);
}

canvas.addEventListener("sixtyfold:time-range-change", (event) => {
  const detail = (event as CustomEvent).detail;
  for (const button of controls.querySelectorAll("button")) {
    button.setAttribute(
      "aria-pressed",
      String(button.dataset.range === detail.range),
    );
  }
});

이름 있는 프리셋이 아닌 범위의 경우 일반 뷰포트 API를 통해 실제 타임스탬프를 전송하세요:

const twoWeeks = 14 * 24 * 60 * 60_000;
let latestDataTimestamp = 0;

const chart = new StockChart(canvas, {
  onVisibleRangeChange({ dataBounds }) {
    latestDataTimestamp = dataBounds.xMax;
  },
});

customButton.addEventListener("click", () => {
  chart.setViewport({
    xMin: latestDataTimestamp - twoWeeks,
    xMax: latestDataTimestamp,
  });
});

market 시간-스케일 모드에서 공개 뷰포트 값은 실제 타임스탬프로 남아 있으며 차트는 내부적으로 이를 압축된 관찰-세션 좌표로 변환합니다. 생성자 콜백은 onTimeRangeChange, onCrosshairMove, 및 onVisibleRangeChange를 제공합니다. 동일한 상태 변경에 대해 네임스페이스된 DOM-이벤트 상수가 내보내집니다.

지표

내장 지표는 원시 캔들에서 계산되며 렌더링 및 크로스헤어 값용으로 활성 집계에서 샘플링됩니다.

chart.setIndicators([
  { type: "sma", id: "sma-20", period: 20, color: "#ffd166" },
  { type: "ema", id: "ema-50", period: 50, color: "#64d8ff" },
  { type: "bollinger", id: "bb-20", period: 20, deviation: 2 },
  { type: "vwap", id: "vwap-day", reset: "day" },
]);

순수 함수는 @sixtyfold/stock/analytics에서 사용할 수 있습니다: calculateSMA, calculateEMA, calculateBollingerBands, calculateVWAP, 및 computeStockIndicator. 비유한 소스 값은 조용히 보간되는 대신 롤링 윈도를 중단시킵니다.

시장 레이어

chart.setVolumeProfile({ rows: 48, placement: "right", valueAreaPercent: 70 });
chart.setPriceLines([
  { id: "entry", price: 182.4, label: "Entry", showAxisLabel: true },
]);
chart.setMarkers([
  { id: "earnings", timestamp, position: "above", shape: "diamond", label: "E" },
]);

볼륨 프로필은 가격별 추정 볼륨 히스토그램으로, 개별 거래별 주문 흐름 재구성은 아닙니다. 보이는 가격 축을 행으로 나누고 각 OHLCV 캔들에 보고된 저가에서 고가 범위 전체에 캔들 볼륨을 균등하게 분배합니다. 가로 막대가 더 넓을수록 해당 가격 주변의 추정 볼륨이 더 큽니다. 강세와 약세 부분은 캔들의 방향을 사용하며, 포인트 오브 컨트롤은 추정 볼륨이 가장 큰 행을 표시하고, 밸류 에어리어는 인접 행을 통해 확장되어 구성된 가시 볼륨 비율을 포함할 때까지 확장됩니다.

프로필은 보이는 시간 및 가격 범위를 따릅니다. 긴 범위는 계산을 4,096 소스 캔들 이하로 유지하는 가장 세분화된 완료된 캔들 집계를 사용하고, 확대된 범위는 원시 캔들을 사용합니다. 이는 상호작용을 제한적으로 유지하지만 두 경로 모두 OHLCV 데이터가 각 캔들 범위 내부에서 개별 거래가 어디에서 발생했는지 보고하지 않기 때문에 캔들 유래 추정치로 남습니다. 이 레이어를 정확한 가격별 거래, 풋프린트 또는 주문 흐름 데이터라고 설명하지 마십시오.

가격 라인은 데이터에 고정된 수평 레벨입니다. 마커는 타임스탬프 순으로 정렬되고 가시 범위에 맞춰 삭제되며; 캔들당 하나의 마커 대신 희소 이벤트를 사용하십시오.

스트리밍

chart.initStreaming(250_000);
chart.addCandle(timestamp, open, high, low, close, volume);

컬럼형 피드의 경우 addCandles 또는 addCandleBatches을 사용하십시오. initialTimeRange는 초기 전송 배치로서 동일 렌더러 턴에서 적용할 수 있어 의도한 뷰포트가 나타나기 전 전체 범위 프레임을 방지합니다.

스트리밍 집계 계층은 화면 밖에서 재구성되어 활성 계층을 원자적으로 대체합니다. 대체 준비가 될 때까지 이전 계층은 계속 표시됩니다.

CSV 로드

loadOHLCVFromCSV는 선택적 진행 콜백과 함께 간단한 브라우저 데이터셋용으로 제공됩니다. 매우 큰 Parquet 또는 독점 피드의 경우 UI 스레드 밖에서 디코딩하고 검증된 6개의 타입화된 열을 직접 전송하세요.