Graphiques boursiers
Chandeliers open-high-low-close-volume, plages temporelles 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.@sixtyfold/stockimport { 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 nombreux chandeliers visibles en périodes OHLCV valides, puis revient à des chandeliers plus fins lorsque vous effectuez un zoom.
La configuration exacte et les signatures des méthodes se trouvent dans la documentation générée Stock options, StockChart methods, et la référence des OHLCV data types.
StockChart expose directement des méthodes de cycle de vie, de viewport, d'apparence, de superposition, de renderer et de batching. En mode market-time, ses méthodes de viewport conservent des coordonnées de session observée compressées tandis que les valeurs publiques restent des horodatages réels.
Bougies et volume
Choisissez filled, hollow ou ohlc pour la géométrie des bougies. candleColors contrôle les corps et mèches haussiers et baissiers. Le volume possède des couleurs, une opacité et un ratio de hauteur de panneau indépendants.
Le renderer limite la précision d'affichage pour les info-bulles OHLCV et les callbacks du crosshair. Fournissez priceUnit et volumeUnit lorsque l'application exige un formatage explicite de devise, d'unité, de décimales ou compact.
Plages temporelles gérées par l’hôte
StockChart ne crée pas et ne met pas en forme les boutons de plage temporelle. L’application hôte possède les libellés, 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 préréglages pratiques exportés : 1D, 5D, 1M, 3M, 6M, YTD, 1Y, 5Y ou ALL. Un préréglage qui dépasse l’historique chargé est contraint aux 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 préréglage nommé, envoyez des horodatages 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 horodatages 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énements DOM avec espace de noms sont exportées pour ces mêmes changements d'état.
Indicateurs
Les indicateurs intégrés sont calculés à partir des chandelles brutes et échantillonnés selon l'agrégation active pour le rendu et les valeurs du réticule.
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. Des 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, et non une reconstruction des flux d'ordres au détail par transaction. Il divise l'échelle de prix visible en lignes et répartit le volume de chaque chandelier OHLCV uniformément sur l'intervalle bas-haut déclaré de ce chandelier. Des barres horizontales plus larges représentent davantage de volume estimé autour d'un prix. Les portions haussières et baissières utilisent la direction du chandelier, le point de contrôle marque la ligne avec le volume estimé le plus élevé, et la zone de valeur s'étend par les lignes adjacentes jusqu'à contenir le pourcentage configuré du volume visible.
Le profil suit la plage de temps et de prix visible. Les plages longues utilisent l'agrégation de chandeliers complétés la plus fine qui maintient le calcul à ou en dessous de 4 096 chandeliers sources ; les plages fortement zoomées utilisent des chandeliers bruts. Cela limite la charge d'interaction, mais les deux approches restent des approximations dérivées des chandeliers parce que les données OHLCV ne rapportent pas où, à l'intérieur de l'intervalle de chaque chandelier, les transactions individuelles ont eu lieu. Ne décrivez pas cette couche comme des transactions exactes au prix, des footprints 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 horodatage et élagués à la plage visible ; utilisez des événements peu nombreux plutôt qu'un marqueur par chandelier.
Streaming
Après initialize(), créez un flux avec une capacité entière positive :
chart.initStreaming(250_000);
chart.addCandle(timestamp, open, high, low, close, volume);Les horodatages de streaming doivent être finis et strictement croissants, y compris entre les appels, les chandelles scalaires mises en file d’attente et les frontières de chunks. Un append avec le même horodatage ne met pas à jour une chandelle existante ; dédupliquez d’abord le flux.
Pour les flux en colonnes, utilisez addCandles ou addCandleBatches avec six colonnes OHLCV de taille égale. addCandleBatches valide la liste complète de chunks avant tout transfert. Un ordre d’horodatage invalide, des horodatages non finis ou des longueurs inégales sont rejetés sans vider les chandelles mises en file d’attente ni détacher les buffers de l’appelant. Les appels scalaires et en masse valides conservent leur ordre. En mode worker, les buffers valides sont transférés, donc capturez les valeurs nécessaires à l’application avant d’append.
initialTimeRange peut être appliqué dans le même tour de rendu qu’un lot transféré initial, évitant une image sur toute la plage avant que le viewport prévu n’apparaisse. Les viewports en temps de marché conservent leurs ancres temporelles lorsque de nouvelles chandelles modifient la cadence déduite.
Le setData statique suit un contrat d’ordre différent : une histoire monotone croissante ou décroissante est acceptée, y compris des timestamps égaux, et est normalisée en ordre croissant. Le remplacement de données ou la réinitialisation du streaming abandonne les échantillons en attente et annule l’animation du viewport de l’ancien jeu de données.
Les hiérarchies d’agrégation en streaming sont reconstruites à partir de snapshots hors écran et remplacent la hiérarchie active de manière atomique. Les niveaux complets restent utilisables pendant que des ajouts se poursuivent ; le graphique ne publie pas de remplacements partiellement construits.
Chargement CSV
loadOHLCVFromCSV est fourni pour des jeux de données simples dans le navigateur, avec un callback de progression optionnel. Pour des flux Parquet très volumineux ou propriétaires, décodez hors du thread principal et transférez six colonnes typées validées directement.