股票图表

开高低收量(OHLCV)蜡烛图、市场时间范围、指标、剖面、价格水平和标记。

框架快速入门

用六种方式渲染同一个股票图

选择命令式 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 事件常量。

指标

内置指标由原始 K 线计算,并在用于渲染与十字光标取值的活动聚合粒度上采样。

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 数据并不报告各笔交易在单个烛线范围内的具体发生位置。请勿将此图层描述为精确的逐价成交、足迹或订单流数据。

价格线是以数据为锚的水平水准。标记按时间戳排序并裁剪到可见范围;使用稀疏事件而非对每根烛线都放一个标记。

流式传输

在 initialize() 之后,创建一个具有正整数容量的流:

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

流式传输的时间戳必须是有限且严格递增的,包括跨调用、排队的标量蜡烛以及块边界。具有相同时间戳的追加不会更新现有蜡烛;请先对数据源进行去重。

对于列式数据源,请使用 addCandles 或 addCandleBatches,包含六列大小相等的 OHLCV 列。addCandleBatches 在任何传输之前验证完整的块列表。无效的时间戳顺序、非有限时间戳或不等长度将被拒绝,且不会刷新已排队的蜡烛或分离调用方缓冲区。有效的标量和批量调用将保留其顺序。Worker 模式会传输有效缓冲区,因此在追加之前请捕获应用所需的值。

initialTimeRange 可在与初始已转移批次相同的渲染回合中应用,避免在预期视口出现前呈现整个范围的帧。当新蜡烛改变推断节奏时,市时视口会保留其时间戳锚点。

静态 setData 具有不同的排序约定:接受单调升序或降序的历史记录(包括相等的时间戳),并标准化为升序。替换数据或重置流式处理会丢弃待处理样本并取消旧数据集的视口动画。

流式聚合层级在离屏快照基础上重建,并以原子方式替换活动层级。已完成的层级在追加继续时仍可使用;图表不会发布部分构建的替代层级。

正在加载 CSV

loadOHLCVFromCSV 适用于直接在浏览器中处理的数据集,并可选择提供进度回调。对于非常大的 Parquet 或专有数据流,请在 UI 线程之外解码,并将六个经验证的类型化列直接传输。