주식 차트

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

프레임워크 빠른 시작

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

명령형 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 툴팁과 크로스헤어 콜백에 대한 표시 정밀도를 제한합니다. 애플리케이션에서 명시적 통화, 단위, 소수점 또는 축약 형식이 필요할 경우 priceUnitvolumeUnit을 제공하세요.

호스트 소유 시간 범위

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개의 타입화된 열을 직접 전송하세요.