Graphiques boursiers

Chandelles open-high-low-close-volume, plages en temps de marché, indicateurs, profils, niveaux de prix et marqueurs.

Démarrage par framework

Affichez le même graphique boursier de six façons

Choisissez l’API TypeScript impérative ou un adaptateur léger. Chaque onglet utilise les mêmes données typées et options.
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 rend des colonnes ordonnées open, high, low, close et volume (OHLCV) avec des couches analytiques spécifiques au marché. Son processus de niveau de détail (LOD) combine automatiquement de nombreuses chandelles visibles en périodes OHLCV valides, puis revient à des chandelles plus fines lorsque vous effectuez un zoom.

La configuration exacte et les signatures de méthodes se trouvent dans les références générées Options Stock, MéthodesStockChart, et Types de données OHLCV.

StockChart expose directement les méthodes de cycle de vie, de viewport, d'apparence, d'overlay, de renderer et de batching. En mode temps de marché, ses méthodes de viewport conservent des coordonnées de session observée compressées tandis que les valeurs publiques restent des timestamps réels.

Chandelles et volume

Choisissez la géométrie de chandelle filled, hollow ou ohlc. candleColors contrôle les corps et mèches haussiers et baissiers. Le volume dispose de couleurs, d'opacité et d'un ratio de hauteur de panneau indépendants.

Les limites du renderer affichent la précision pour les info-bulles OHLCV et les callbacks de crosshair. Fournissez priceUnit et volumeUnit lorsque l'application exige un formatage explicite de devise, d'unité, décimal ou compact.

Plages temporelles détenues par l'hôte

StockChart ne crée ni ne stylise de boutons de plage temporelle. L'application hôte possède les étiquettes, le nombre, l'ordre, la disposition et l'accessibilité de ses contrôles — ou peut ne rendre aucun contrôle.

Appelez setTimeRange() lorsqu'un bouton correspond à l'un des presets de commodité exportés : 1D, 5D, 1M, 3M, 6M, YTD, 1Y, 5Y ou ALL. Un preset s'étendant au-delà de l'historique chargé se bride sur les données disponibles.

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),
    );
  }
});

Pour une plage qui n'est pas un preset nommé, envoyez des timestamps réels via l'API de viewport ordinaire :

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,
  });
});

En mode d'échelle temporelle market, les valeurs publiques du viewport restent des timestamps réels ; le graphique les convertit en coordonnées de session observée compressées en interne. Les callbacks du constructeur fournissent onTimeRangeChange, onCrosshairMove et onVisibleRangeChange. Des constantes d'événement DOM namespacées sont exportées pour les mêmes changements d'état.

Indicateurs

Les indicateurs intégrés sont calculés à partir des chandelles brutes et échantillonnés à l'agrégation active pour le rendu et les valeurs du crosshair.

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" },
]);

Des fonctions pures sont disponibles depuis @sixtyfold/stock/analytics : calculateSMA, calculateEMA, calculateBollingerBands, calculateVWAP et computeStockIndicator. Les valeurs source non finies interrompent une fenêtre glissante au lieu d'être interpolées silencieusement.

Couches de marché

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" },
]);

Le profil de volume est un histogramme estimé du volume par prix, pas une reconstruction ordre-par-ordre du flux d'ordres. Il divise l'échelle de prix visible en rangées et répartit de manière uniforme le volume de chaque chandelle OHLCV sur l'intervalle low-to-high déclaré de cette chandelle. Des barres horizontales plus larges représentent plus de volume estimé autour d'un prix. Les portions haussières et baissières utilisent la direction de la chandelle, le point de contrôle marque la rangée avec le volume estimé le plus élevé, et la zone de valeur s'étend aux rangées adjacentes jusqu'à contenir le pourcentage configuré du volume visible.

Le profil suit la plage temporelle et de prix visible. Les plages longues utilisent l'agrégation de chandelles complétées la plus fine qui maintient le calcul à ou en dessous de 4 096 chandelles source ; les plages zoomées utilisent des chandelles brutes. Cela limite l'interaction, mais les deux chemins restent des approximations dérivées des chandelles car les données OHLCV ne rapportent pas où à l'intérieur de la plage de chaque chandelle les trades individuels ont eu lieu. Ne décrivez pas cette couche comme des trades-exacts-au-prix, un footprint ou des données de flux d'ordres.

Les lignes de prix sont des niveaux horizontaux ancrés aux données. Les marqueurs sont triés par timestamp et élagués selon la plage visible ; utilisez des événements rares plutôt qu'un marqueur par chandelle.

Streaming

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

Pour des flux en colonnes, utilisez addCandles ou addCandleBatches. initialTimeRange peut être appliqué dans le même tour de renderer qu'un lot initial transféré, évitant une frame sur toute la plage avant que le viewport prévu n'apparaisse.

Les hiérarchies d'agrégation streamées se reconstruisent hors écran et remplacent la hiérarchie active de façon atomique. La hiérarchie précédente reste visible jusqu'à ce que le remplaçant soit prêt.

Chargement de CSV

loadOHLCVFromCSV est fourni pour des jeux de données simples côté navigateur, avec un callback de progression optionnel. Pour des Parquet très volumineux ou des flux propriétaires, décodez hors du thread UI et transférez six colonnes typées validées directement.