Referencia de la API
Superficie pública de las clases de nivel superior: Chart, ChartWidget, ChartWidgetGrid y ChartGrid.
Chart
Renderizador sin interfaz. Tú pones la UI, te suscribes a los eventos y modificas el estado de forma imperativa.
Creación
new Chart(host: HTMLElement, options?: ChartOptions) Datos
| Método | Función |
|---|---|
setData(data) | Sustituye la serie completa. |
appendBar(bar) | Añade una barra nueva; se desplaza automáticamente si está activado. |
appendBars(bars) | Añade en lote; recalcula los indicadores una sola vez. |
updateLastBar(bar) | Modifica la barra en formación. |
updateLastBarFromTick(tick) | Fusiona un tick en la última barra. |
getData() | Lee la serie OHLC sin procesar. |
Tipo de gráfico y tema
| Método | Función |
|---|---|
setChartType(type) | Uno de los 18 tipos; consulta Tipos de gráfico. |
setTheme(name) | Cambia entre los temas integrados. |
setTimeframe(tf) | Cambia la temporalidad activa; reconecta el flujo en vivo. |
Renderizador
| Método | Propósito |
|---|---|
Opción renderer | 'canvas' (predeterminado), 'webgl' o 'auto' (WebGL solo con una GPU de hardware). |
setRenderer(mode) | Cambia en tiempo de ejecución. Devuelve lo que dibuja ahora: 'canvas' si no hay WebGL 2. |
getRenderer() | 'canvas' o 'webgl'. |
Qué dibuja la GPU, y las cifras: Rendimiento → Renderizador WebGL.
Indicadores
| Método | Función |
|---|---|
addIndicator(id, params?, position?) | Añade un indicador superpuesto o en panel. Devuelve el id de la instancia. |
updateIndicator(instanceId, params) | Modifica un indicador activo. |
removeIndicator(instanceId) | Lo quita y libera sus recursos. |
Ejes y escala
El eje de precio (franja derecha) y el eje de tiempo (franja inferior) admiten interacción directa con el puntero, con los gestos que los traders ya conocen:
| Gesto | Efecto |
|---|---|
| Arrastrar el eje de precio arriba / abajo | Comprime / expande el rango vertical de precios (desactiva la escala automática). |
| Arrastrar el eje de tiempo a izquierda / derecha | Acerca / aleja el eje de tiempo. |
| Doble clic en el eje de precio | Reactiva la escala automática. |
| Doble clic en el eje de tiempo | Ajusta todos los datos a la vista. |
Zona horaria. Las etiquetas del eje de tiempo y la etiqueta de hora de la cruz siguen por defecto la zona local del navegador; cambia a un desfase UTC fijo (o vuelve a la hora local) desde la hoja de configuración o directamente:
chart.setTimezoneOffset(-300) // EST (UTC-5), in minutes
chart.setTimezoneOffset(330) // IST (UTC+5:30)
chart.setTimezoneOffset(null) // back to browser-local Los mismos efectos también están disponibles por código:
chart.setAutoScale(false) // freeze the current price range
chart.setLogScale(true) // switch to logarithmic price scale
chart.setInvertScale(true) // upside down (Alt+I in the widget)
chart.fitContent() // zoom out to all data
chart.scrollToEnd()
chart.setVisibleRangePreset('3M') // 1D 5D 1M 3M 6M YTD 1Y 5Y All
chart.goToTime(Date.UTC(2025, 0, 1)) // centre that bar (Alt+G in the widget) Modos de la escala de precio. Además de normal y logarítmica,
el eje puede recalcular sus etiquetas respecto a la primera barra visible: percentage muestra el cambio en %, indexedTo100 fija
la base en 100. Los modos normal, porcentaje e indexado comparten la misma
geometría lineal; solo cambian las etiquetas. Se configura desde el panel de
configuración del gráfico o directamente:
chart.setScaleMode('percentage') // axis labels: +12.34% from first visible bar
chart.setScaleMode('indexedTo100') // first visible bar reads as 100
chart.setScaleMode('logarithmic')
chart.getScaleMode() Formatos de precio y de hora
Los precios pueden mostrarse a tu manera, o en fracciones de punto, como se cotizan los bonos y sus
futuros (101'16 es 101 y 16/32). El formato llega a todo lo que muestra un precio en la
escala de precio: eje, cruz, etiqueta del último precio, leyenda, información emergente, órdenes,
alertas y etiquetas de los dibujos; el eje coloca sus marcas en fracciones enteras y roundPrice redondea a ellas. Los paneles de indicadores conservan sus propios números.
Las horas también pueden mostrarse a tu manera; al formateador se le indica qué tipo de etiqueta es.
new Chart(host, { priceFormat: { denominator: 32 } }) // 101'16
chart.setPriceFormat({ denominator: 32, subDenominator: 2 }) // 101'165: 16½ 32nds
chart.setPriceFormat((p) => '$' + p.toFixed(2))
chart.setPriceFormat(null) // decimals again
chart.setTimeFormatter((time, { kind, timeZone }) =>
// kind: 'date' (a daily bar), 'day' (a new day), 'time' (within a day), 'crosshair'
new Intl.DateTimeFormat('en-GB', { timeZone: timeZone ?? undefined, hour: '2-digit', minute: '2-digit' }).format(time)) Comparar símbolos
El cambio porcentual de otro símbolo en la escala de precio (addCompareSymbol), o su
precio en una escala propia, en un panel propio, o el diferencial o el ratio entre el cierre del
gráfico y ese símbolo; estos últimos son indicadores (compareSymbol, spread), con leyenda, etiquetas de valor, alertas y diseños guardados como cualquier
otro. Las barras del otro símbolo se alinean con las del gráfico por tiempo. El gráfico pide las
barras que necesita; vuelve a dárselas tras un cambio de temporalidad.
chart.addCompareSymbol('eth', 'ETHUSDT', ethBars, '#7c4dff') // percent change, on this scale
chart.addIndicator('compareSymbol', { symbol: 'ETHUSDT' }, 'bottom', { scale: 'left' }) // own scale
chart.addIndicator('spread', { symbol: 'ETHUSDT', mode: 'ratio' }) // own pane
chart.on('symbolSeriesRequest', async ({ payload }) =>
chart.setSymbolSeries(payload.symbol, await adapter.fetchHistory(payload.symbol, '1h', 1000)))
chart.getRequiredSymbols() // what to fetch again on a new interval
chart.setPaneScale(spreadId, { percent: true }) // a pane in percent of its first value En ChartWidget, el botón de comparar del árbol de objetos pide un símbolo y luego cómo mostrarlo: cambio porcentual, escala propia, panel propio, diferencial o ratio.
Exportar datos
Las barras en CSV o JSON, con cada línea de indicador en su propia columna y con el nombre que le da la leyenda. ChartWidget tiene Exportar datos (CSV) en el menú del clic derecho del gráfico.
chart.exportAllData('csv', 'btc-1h.csv') // every bar loaded
chart.exportVisibleData('json', undefined, { indicators: false })
const text = chart.getExportText('csv', { range: 'visible' })
const { bars, columns } = chart.getExportData() // columns: { name, values }[] Perfil de volumen
Histograma horizontal del volumen negociado, agrupado por precio, sobre el rango visible. Desactivado por defecto; actívalo por código o desde la hoja de configuración del widget:
chart.setVolumeProfileVisible(true)
chart.setVolumeProfileConfig({
buckets: 48, // resolution of the histogram
widthRatio: 0.18, // % of chart width
opacity: 0.32,
highlightPoC: true, // mark the highest-volume bucket
}) Marcadores de swing (pivotes)
Marca los máximos y mínimos de swing fractales con pequeños triángulos (▼ sobre un pivote alto confirmado, ▲ bajo un pivote bajo). La fuerza indica cuántas barras deben quedar por debajo a cada lado. Actívalo desde la hoja de configuración o así:
chart.setPivotMarkersVisible(true)
chart.setPivotMarkersConfig({ left: 5, right: 5, showLabels: true })
// market-structure labels (HH / HL / LH / LL) instead of price
chart.setPivotMarkersConfig({ structureLabels: true })
// pure detection + classification are exported
import { findPivots, classifyPivots } from '@tradecanvas/core'
const pivots = findPivots(bars, 5, 5) // [{ index, price, type }]
const structure = classifyPivots(pivots) // adds label: 'HH'|'LH'|'HL'|'LL' Sombreado de sesión (horario regular de negociación)
Atenúa las barras fuera de la sesión regular (preapertura, poscierre o la pausa nocturna) para que la sesión principal destaque. Por defecto usa el horario regular de la renta variable de EE. UU. (09:30–16:00, hora de Nueva York, con horario de verano incluido); configura la ventana en minutos del día y la zona horaria del mercado. Un símbolo cuya fuente de datos informa de sus sesiones las configura por sí mismo.
chart.setSessionShadingVisible(true)
chart.setSessionShadingConfig({
startMinute: 9 * 60 + 30, // 09:30
endMinute: 16 * 60, // 16:00 (end-exclusive; end < start wraps midnight)
timeZone: 'America/New_York', // or tzOffsetMinutes: -300 for a fixed offset
}) Horario extendido. Al desactivarlo, las barras fuera del horario regular del
símbolo (SymbolInfo.sessions en su timezone) salen del gráfico; se guardan
aparte, también las barras en vivo y las páginas del historial, y vuelven al activarlo. Las barras de
un día o más se quedan como están.
chart.setSymbolInfo({ symbol: 'AAPL', timezone: 'America/New_York', sessions: [{ start: '09:30', end: '16:00' }] })
chart.setExtendedHours(false) // or new Chart(host, { extendedHours: false })
chart.isExtendedHoursVisible() Niveles del periodo anterior (PDH / PDL / PDC)
Dibuja el máximo, el mínimo y el cierre del día (o la semana) anterior, más la apertura del periodo actual, como líneas horizontales con etiqueta: los niveles de soporte y resistencia que vigilan los traders intradía. Actívalo desde la hoja de configuración o directamente:
chart.setPeriodLevelsVisible(true)
chart.setPeriodLevelsPeriod('week') // 'day' (PDH/PDL/PDC) | 'week' (PWH/PWL/PWC)
// pure computation is exported
import { computePeriodLevels } from '@tradecanvas/core'
const levels = computePeriodLevels(bars, 'day') // [{ id, label, price }] Perfil de mercado (TPO)
Un histograma de tiempo por precio: cada barra aporta un TPO a cada tramo de precio que tocó su rango, lo que revela el punto de control (el precio más concurrido) y el área de valor (≈70% de los TPO). Es distinto del perfil de volumen —pondera por tiempo, no por volumen— y se ancla a la izquierda para que ambos puedan mostrarse a la vez. Desactivado por defecto; actívalo desde la hoja de configuración o directamente:
chart.setMarketProfileVisible(true)
chart.setMarketProfileConfig({
buckets: 48,
widthRatio: 0.18,
opacity: 0.32,
valueAreaPct: 0.7, // fraction of TPOs in the value area
highlightPoC: true, // dashed line at the point of control
})
// split into one mini-profile per calendar-day session
chart.setMarketProfileConfig({ splitBySession: true })
// classic TPO letters per session (when zoomed in enough to be legible)
chart.setMarketProfileConfig({ splitBySession: true, letters: true })
// pure computation is exported too
import { computeMarketProfile, computeSessionProfiles } from '@tradecanvas/core'
const profile = computeMarketProfile(bars, priceMin, priceMax, { buckets: 48 })
const sessions = computeSessionProfiles(bars, priceMin, priceMax) // per-day TPO Táctil y móvil
| Gesto | Acción |
|---|---|
| Arrastrar con 1 dedo (área del gráfico) | Desplazar y mover la cruz |
| Pellizcar con 2 dedos | Zoom alrededor del punto medio |
| Mantener pulsado (~500 ms) | Fija la información OHLC en la barra (el equivalente móvil de Alt + clic) |
| Arrastrar con 1 dedo dentro de la franja del eje de precio / tiempo | Escala el eje correspondiente |
Los cuadros modales (configuración, hoja de atajos, paleta de comandos, búsqueda de símbolos) pasan automáticamente a una hoja inferior con asa de arrastre y márgenes que respetan el área segura en pantallas de menos de 640 px.
Herramienta de medición
Mantén pulsado Shift y arrastra sobre el gráfico para medir barras × precio entre dos puntos: la capa muestra el Δ de precio (absoluto y %), el número de barras y el intervalo de tiempo. La capa desaparece en cuanto sueltas el ratón; no se guarda en el estado persistido.
Eventos
Todos los eventos están tipados mediante ChartEventMap:
chart.on('orderPlace', e => /* OrderPlacePayload */)
chart.on('orderModify', e => /* OrderModifyPayload */)
chart.on('signalMarkerAdd', e => /* { marker } */)
chart.on('tradeZoneAdd', e => /* { zone } */)
chart.on('dataUpdate', e => /* { length } */)
chart.on('ordersChange', e => /* { orders } */)
chart.on('positionsChange', e => /* { positions } */)
chart.on('executionFill', e => /* { side, price, quantity, reason, pnl } */)
chart.on('chartContextMenu', e => /* { area, x, y, price, time } */)
chart.on('stateChange', () => /* pueden haber cambiado los dibujos, indicadores, alertas, el tipo de gráfico o el tema */)
chart.on('paneChange', e => /* { instanceId, change: 'collapsed' | 'maximized' | 'order' } */)
chart.on('chartTypeChange', e => /* { type, previous } */)
chart.on('symbolChange', e => /* { symbol, previous } */)
chart.on('timeframeChange', e => /* { timeframe, previous } */)
chart.on('historyChange', e => /* { canUndo, canRedo } */)
chart.on('drawingSelect', e => /* { ids, primary } */)
chart.on('rendererChange', e => /* { renderer: 'canvas' | 'webgl', reason?: 'unsupported' | 'contextLost' } */) Deshacer tus propios cambios
recordUndo pone un cambio tuyo en el historial de deshacer del gráfico, junto con sus dibujos e
indicadores: Ctrl/Cmd+Z llama a undo y rehacer llama a redo. Los cambios sobre el mismo subject hechos seguidos cuentan como un solo paso. ChartWidget registra así su configuración y su tipo de gráfico.
const before = panel.color
panel.color = 'red'
chart.recordUndo({ subject: 'panel-color', undo: () => (panel.color = before), redo: () => (panel.color = 'red') }) Teclado y lectores de pantalla
Un gráfico con el foco se desplaza con las flechas (Mayús para diez barras), hace zoom con ↑/↓ o +/− y va al
principio y al final con Inicio y Fin. Para los lectores de pantalla es una aplicación con un resumen
(símbolo, tipo, temporalidad, último precio); cuando las teclas mueven la vista, dice lo que hay en pantalla, y
la coma y el punto leen las barras una a una. a11y.labels lo pone en tu idioma; a11y: false lo quita. scrollBars(n) y selectDrawing(id) hacen desde el código lo que hacen las teclas y un clic.
new Chart(host, { a11y: { labels: { role: 'gráfico', summary: '{what}. Último precio {close}.' } } }) Los precios que vienen del puntero se pueden ajustar a la cuadrícula del mercado con chart.roundPrice(price): a un múltiplo del minTick del símbolo o,
si no lo tiene, a su precisión. Los menús y el ticket de orden de ChartWidget lo hacen.
ChartWidget
Envuelve Chart en una interfaz completa. La misma instancia está disponible en widget.chart.
import { ChartWidget } from '@tradecanvas/chart/widget'
const widget = new ChartWidget(host, {
symbol: 'BTCUSDT',
timeframe: '5m',
theme: 'dark',
adapter: new BinanceAdapter(),
historyLimit: 500,
trading: true,
features: { drawings: true, indicators: true },
onReady: (chart) => { /* ... */ },
})
widget.chart.setData(...)
widget.destroy() Atajos de teclado del widget
| Atajo | Acción |
|---|---|
| Ctrl / ⌘ + K | Paleta de comandos (indicadores, tipos de gráfico, dibujos…) |
| Ctrl / ⌘ + P | Búsqueda de símbolos: selector difuso sobre la lista de símbolos configurada |
| Ctrl / ⌘ + S | Guarda el diseño (pide un nombre la primera vez) |
| 0–9 | Escribe una temporalidad (5, 15m, 1h, 1D) y pulsa Enter (intervalTyping: false lo desactiva) |
| Alt + T / H / J / V / C / F | Línea de tendencia, línea horizontal, rayo horizontal, línea vertical, línea en cruz, retroceso de Fibonacci |
| ? | Muestra la hoja de atajos de teclado |
| Alt + clic en el gráfico | Fija la información OHLC en la barra bajo el cursor (muestra la diferencia con la cruz en vivo) |
| Esc | Desfija la información / cancela el dibujo |
| Clic en el símbolo de la barra de herramientas | Abre el cuadro de búsqueda de símbolos |
| Clic en reproducir en la barra de herramientas | Abre el control de repetición de barras (reproducir/avanzar/buscar/velocidad) |
Actualiza el catálogo de búsqueda en tiempo de ejecución con widget.setSymbols(['BTCUSDT', 'ETHUSDT', …]).
Ventana de datos
Un panel flotante con los valores exactos de O/H/L/C/V, el cambio de la barra y el valor de cada indicador activo en la barra bajo el cursor; se actualiza en vivo al mover la cruz. Actívalo desde la paleta de comandos (Ctrl/⌘ K → "Mostrar/ocultar ventana de datos").
Vista compartible (enlaces profundos)
Codifica la vista completa —símbolo, temporalidad, tipo de gráfico, escala de
precio, indicadores (con sus parámetros) y dibujos— en una cadena compacta y
apta para URL, para crear enlaces profundos. Con shareUrl: true el
widget restaura un hash #tcw=… al cargar, y la acción "Compartir
vista" de la paleta de comandos copia un enlace al portapapeles.
const widget = new ChartWidget(host, { shareUrl: true })
const token = widget.exportState() // portable string
await widget.importState(token) // restore a view
await widget.copyShareLink() // copy "<url>#tcw=<token>" Diseños con nombre
El botón de diseño de la barra de herramientas guarda el gráfico con un nombre:
símbolo, temporalidad, escala de precio, tipo de gráfico, indicadores, dibujos y
alertas (no el tema, que sigue siendo el de quien mira). Abre, renombra y elimina
diseños desde su menú; el diseño abierto se guarda solo a medida que cambia, y Ctrl/⌘ S lo guarda. Los diseños viven en el localStorage de
este navegador salvo que indiques un storage: cuatro llamadas, y cada
una puede devolver una promesa.
import { ChartWidget, type LayoutStorage } from '@tradecanvas/chart/widget'
const server: LayoutStorage = {
list: () => api.get('/layouts'), // [{ id, name, symbol, timeframe, updatedAt }]
load: (id) => api.get(`/layouts/${id}`), // { ...summary, content } o null
save: (layout) => api.put(`/layouts/${layout.id}`, layout),
remove: (id) => api.delete(`/layouts/${id}`),
}
const widget = new ChartWidget(host, {
layouts: { storage: server, autoSave: true, openLast: true }, // o false para ninguno
})
const layouts = widget.getLayoutSession()!
await layouts.saveAs('Swing BTC')
await layouts.open(id)
layouts.current() // { id, name, … } o null
layouts.setAutoSave(false)
// Solo el contenido, para guardarlo donde quieras
const json = widget.getLayoutContent()
await widget.applyLayoutContent(json) localStorageLayouts(prefix) y memoryLayouts() son los dos
almacenamientos incluidos. El contenido guardado se lee de forma defensiva: un
diseño que no se puede interpretar se rechaza, en lugar de aplicarse a medias. Cada
diseño registra su kind ('chart' o 'grid'), así
que un widget y una cuadrícula pueden compartir un mismo almacenamiento y cada uno
lista solo los suyos. Guardar, abrir y el guardado automático se ejecutan de uno en
uno, así que un guardado nunca acaba en un diseño abierto después de él.
Diseños por símbolo
Por separado, guarda automáticamente en localStorage, por símbolo, los
indicadores, dibujos, alertas y el tipo de gráfico:
new ChartWidget(host, {
symbol: 'BTCUSDT',
symbols: ['BTCUSDT', 'ETHUSDT', 'SOLUSDT'],
adapter: new BinanceAdapter(),
persistLayouts: true, // or { keyPrefix: 'myapp:', debounceMs: 2000 }
})
// Reset a single symbol's layout
widget.clearSavedLayout('BTCUSDT') Los diseños se guardan al cambiar de símbolo y al destruir el widget, así que no se pierde nada cuando el usuario sale de la página.
Importación de datos con arrastrar y soltar
Suelta un archivo CSV o JSON sobre el gráfico para cargarlo al instante.
Activado por defecto; desactívalo con dragDropImport: false. El
analizador reconoce las disposiciones de columnas habituales
(time, open, high, low, close, volume), las marcas de tiempo
ISO 8601 y los segundos/ms de Unix.
// Programmatic use
import { parseOHLCV } from '@tradecanvas/chart'
const { data, rowCount, skipped } = parseOHLCV(csvText)
chart.setData(data) Remuestreo de temporalidades
Pasa al widget tu serie de mayor resolución con widget.setData() y los botones de temporalidad de la barra de herramientas la agregan en el
cliente: un solo conjunto de datos alimenta todas las resoluciones, sin volver
a descargar nada. Está activo siempre que no haya un adaptador en vivo
conectado; desactívalo con resampleTimeframes: false. Los tramos
semanales empiezan el lunes por defecto (weekStartsOn: 0 para el
domingo).
const widget = new ChartWidget(host, {
symbol: 'BTCUSDT',
timeframe: '1h',
timeframes: ['5m', '15m', '1h', '4h', '1d', '1w'],
})
widget.setData(oneMinuteBars) // base series; clicking 4h/1d/1w resamples it
// Or use the pure function directly
import { resampleOHLCV, inferTimeframeMs } from '@tradecanvas/chart'
const hourly = resampleOHLCV(oneMinuteBars, '1h') // OHLC merged, volume summed
const fourHour = resampleOHLCV(oneMinuteBars, '4h', { weekStartsOn: 1 }) Agrupación según el calendario: las temporalidades intradía y diarias se alinean con los límites de la época UTC, las semanas con el inicio de semana configurado y los meses / trimestres / años con los límites del calendario. Las barras de entrada nunca se modifican.
Listas de seguimiento
Un panel a la derecha con listas de símbolos; cada fila lleva el último precio, el % de cambio y un minigráfico. Las
listas se cambian, crean, renombran y borran desde su menú; los símbolos se añaden desde la búsqueda de símbolos
(+), se quitan y se reordenan arrastrando o con Alt+↑/↓. Las filas toman las cotizaciones del subscribeQuotes del adaptador, de una fuente de cotizaciones tuya o de lo que tú envíes.
const widget = new ChartWidget(host, {
symbol: 'BTCUSDT',
adapter: new BinanceAdapter(), // its quotes fill the rows
watchlist: {
lists: [
{ id: 'majors', name: 'Majors', symbols: ['BTCUSDT', 'ETHUSDT'] },
{ id: 'alts', name: 'Alts', symbols: ['SOLUSDT', 'ADAUSDT'] },
],
persist: true, // kept in this browser
onChange: (lists, active) => save(lists), // or keep them yourself
},
})
widget.addToWatchlist('BNBUSDT', 'alts')
widget.setActiveWatchlist('alts')
widget.setQuotes([{ symbol: 'AAPL', last: 190.2, prevClose: 188.1 }]) // from your own feed
widget.getQuote('AAPL') watchlist: true muestra una sola lista de symbols, como antes; setWatchlistEntry sigue enviando el precio, la variación y el minigráfico de una fila.
Información del símbolo
Un panel que se abre con el botón ⓘ de la barra de herramientas (o desde la paleta de comandos): los nombres del símbolo, el último precio y su variación, el estado del mercado con la cuenta atrás hasta la próxima apertura o cierre, la apertura del día, el rango, el volumen, el cierre anterior, compra y venta, el tamaño del tick, la moneda, la zona y el horario de negociación, y noticias. La barra de estado indica cuándo el mercado está cerrado.
new ChartWidget(host, {
symbol: 'AAPL',
news: (symbol, limit) => api.headlines(symbol, limit), // or the adapter's fetchNews
})
widget.toggleSymbolInfo(true) Navegación, deshacer y dirección
Los botones sobre el gráfico (alejar y acercar, desplazarse hacia atrás y hacia delante, que siguen mientras los
mantienes pulsados, y restablecer) aparecen mientras el ratón está encima (navigation: false los quita).
Los cambios de configuración y de tipo de gráfico se deshacen con Ctrl/Cmd+Z, junto con los dibujos y los indicadores.
En árabe, hebreo, persa o urdu el widget se refleja (dir: 'auto'; o 'rtl' / 'ltr');
el gráfico mantiene el tiempo de izquierda a derecha.
Herramientas de dibujo favoritas
Fija las herramientas de dibujo que más usas en una franja en la parte superior
de la barra lateral. Haz clic derecho en cualquier herramienta (en el menú de su
grupo o en la propia franja) para fijarla o desfijarla; la selección se guarda
en localStorage. Define los favoritos iniciales con drawingFavorites:
new ChartWidget(host, {
drawingFavorites: ['trendLine', 'horizontalLine', 'fibRetracement', 'rectangle'],
}) Estilo de dibujo y plantillas
El botón de paleta de la barra lateral de dibujo abre un menú de estilo: elige el color, el grosor y el estilo de línea del próximo dibujo (y del seleccionado), y guarda plantillas con nombre en localStorage para reutilizarlas con un clic. Equivalentes por código:
chart.setDrawingStyle({ color: '#e8505b', lineWidth: 2, lineStyle: 'dashed' })
chart.getDrawingStyle()
chart.setSelectedDrawingStyle({ color: '#1fa874' }) // restyle the selected drawing Árbol de objetos
El botón de capas de la barra de herramientas abre un panel con el árbol de
objetos, que lista todos los indicadores y dibujos activos. Los indicadores se
pueden quitar; cada dibujo se puede mostrar / ocultar, bloquear / desbloquear,
configurar y eliminar, y los grupos aparecen con sus dibujos debajo. Activado
por defecto; desactívalo con objectTree: false.
Los controles de dibujo corresponden a:
chart.getDrawings() // DrawingState[] (id, type, visible, locked)
chart.setDrawingVisible(id, false) // hide a single drawing
chart.setDrawingLocked(id, true) // lock it from edits
chart.removeDrawing(id)
chart.groupDrawings(ids, 'Weekly levels') // se ocultan, bloquean y seleccionan juntos
chart.renameDrawingGroup(groupId, 'Old highs')
chart.getActiveIndicators() // active indicator instances
chart.updateIndicator(instanceId, { period: 50 }) // re-tune params live
chart.removeIndicator(instanceId) Configuración y menú del dibujo
Haz doble clic en un dibujo, o usa su engranaje en el árbol de objetos, para abrir su configuración: el estilo, la configuración propia de la herramienta (niveles de Fibonacci, extensiones, etiquetas…) y sus puntos en la zona horaria del gráfico. Haz clic derecho en un dibujo para ver su menú: configuración, una alerta en su línea, orden, agrupar, bloquear, ocultar, duplicar y eliminar. La barra lateral también tiene un borrador, una herramienta de zoom y un imán que puede estar desactivado, débil o fuerte. Consulta Herramientas de dibujo para ver la API que hay debajo.
El botón de engranaje de cada fila de indicador abre un cuadro de
configuración que examina los parámetros del indicador (números,
interruptores, colores) y aplica los cambios en vivo mediante updateIndicator: no hace falta quitarlo y volver a añadirlo para
cambiar un periodo o un color.
La sección Comparar del árbol de objetos superpone otros
símbolos como líneas normalizadas. Con un adaptador en vivo, el botón + abre el
selector de símbolos, descarga el historial de ese símbolo mediante adapter.fetchHistory y lo añade en modo porcentaje (para que
símbolos con precios muy distintos compartan un eje). Las comparaciones se
vuelven a descargar automáticamente al cambiar de temporalidad. Equivalentes
por código:
widget.addCompareSymbol('ETHUSDT') // fetches + overlays (needs an adapter)
// or drive the chart directly with your own data
chart.addCompareSymbol('ETHUSDT', 'ETH', ethBars, '#627eea')
chart.setCompareMode('percent') // 'percent' | 'absolute'
chart.removeCompareSymbol('ETHUSDT') Alertas de precio
Además de un nivel, una alerta puede comparar una línea con otra (el precio cruzando una
media móvil, el MACD cruzando su señal), saltar con un movimiento de cierto porcentaje en
cierto número de barras (de 2 a 500), mirar solo las barras cerradas (sin saltar por una
mecha que vuelve) y vencer. El panel de alertas del widget tiene todo esto; desde código
son el último argumento de addAlert. Las alertas se comprueban con cada
precio, venga de setCurrentPrice o de una fuente conectada, junto con las
líneas que vigilan:
const ema = chart.addIndicator('ema', { period: 50 })
const rsi = chart.addIndicator('rsi')
chart.addAlert(NaN, 'crossingUp', 'above the 50 EMA', 'price', undefined, { target: `${ema}:value` })
chart.addAlert(NaN, 'movesUp', 'pump', 'price', undefined, { percent: 5, bars: 12 })
chart.addAlert(70, 'greaterThan', 'RSI closed above 70', `${rsi}:value`, 'RSI', { onBarClose: true })
chart.addAlert(64_000, 'crossing', 'today only', 'price', undefined, { expiresAt: Date.now() + 86_400_000 })
chart.on('alertExpired', (e) => e.payload) // it reached its time without firing
chart.on('alertTriggered', (e) => e.payload) // { id, condition, channel, target?, percent?, bars?, … } La campana de la barra de herramientas abre un panel flotante para añadir,
listar y eliminar alertas de precio; cuando una se activa aparece un aviso.
Las líneas de alerta también se pueden arrastrar: toma una en
el gráfico y deslízala para cambiar su precio (al mover una alerta se vuelve a
armar). Activado por defecto; desactívalo con alerts: false.
Contrólalo por código con la API de Chart y los eventos de alerta
tipados:
// Add from code (condition: 'crossing' | 'crossingUp' | 'crossingDown'
// | 'greaterThan' | 'lessThan')
const id = chart.addAlert(64200, 'crossingUp', 'breakout')
chart.removeAlert(id)
chart.getAlerts() // PriceAlert[]
chart.saveAlerts('tcw:alerts:BTCUSDT') // localStorage persistence
chart.loadAlerts('tcw:alerts:BTCUSDT')
// React to triggers
chart.on('alertTriggered', (e) => {
console.log('hit', e.payload.price, e.payload.message)
})
// also: 'alertAdd' / 'alertRemove' / 'alertUpdate' (fired on drag)
// Indicator alerts: bind to an indicator line via channel '<instanceId>:<key>'.
// In the widget, the alerts panel's source dropdown lists every active line.
const ema = chart.addIndicator('rsi')
chart.addAlert(70, 'crossingUp', 'RSI overbought', `${ema}:rsi`, 'RSI') Activa un sonido y/o una notificación de escritorio cuando salte una alerta
(ambos desactivados por defecto). sound: true reproduce un pitido
integrado; pasa una URL para usar uno propio. desktop: true usa la
Notification API y pide permiso la primera vez.
new ChartWidget(host, {
alertNotifications: { sound: true, desktop: true },
}) Tus propios botones y entradas de menú
Añade botones a la barra de herramientas (un icono integrado o un elemento tuyo, texto, un interruptor) y entradas a los menús del clic derecho del gráfico, después de las del propio widget.
const news = widget.addToolbarButton({
id: 'news',
label: 'News',
icon: 'bell', // o un elemento <svg>; o text: 'News'
side: 'right', // 'left' se coloca junto a los controles del gráfico
toggle: true,
onClick: () => news?.setActive(togglePanel()),
})
news?.setText('3')
news?.remove()
new ChartWidget(host, {
chartMenuItems: ({ area, price, time }) => area === 'plot' && price !== undefined
? [{ label: `Copy ${price.toFixed(2)}`, icon: 'check', onSelect: () => copy(price) }]
: [],
}) ChartWidgetGrid
Varios widgets de gráfico uno junto a otro, cada uno con su propio símbolo, temporalidad, indicadores y dibujos. Una barra encima de ellos elige la disposición, vincula los gráficos y guarda toda la cuadrícula como un diseño con nombre. El último gráfico pulsado es el activo (con contorno).
import { ChartWidgetGrid } from '@tradecanvas/chart/widget'
const grid = new ChartWidgetGrid(host, {
layout: '2x2', // '1x1' '1x2' '2x1' '2x2' '1x3' '3x1' '2x3' '3x2'
widget: { timeframe: '1h' }, // todos los gráficos
adapter: () => new BinanceAdapter(), // uno por gráfico: un adaptador mantiene un único flujo
cells: [{ symbol: 'BTCUSDT' }, { symbol: 'ETHUSDT' }, { symbol: 'SOLUSDT' }, { symbol: 'BNBUSDT' }],
sync: { crosshair: true, time: false, symbol: false, interval: false, drawings: false, replay: false },
})
grid.setLayout('1x2')
grid.setSync({ interval: true }) // alinea los demás con el gráfico activo
grid.getActiveWidget().getChart()
grid.getLayoutSession()?.saveAs('Majors')
// Cada gráfico según se crea (al inicio y al crecer la cuadrícula)
new ChartWidgetGrid(host, {
onChartAdd: (widget, index) => widget.getChart().addIndicator('ema', { period: 21 }),
}) La sincronización de la cruz muestra en todos los gráficos la hora bajo el puntero; la del tiempo desplaza y amplía los demás junto con el gráfico que se está usando; los dibujos se copian a los gráficos que muestran el mismo símbolo (al activarla se juntan sus dibujos, sin perder ninguno); la de la repetición lleva a los demás a la misma hora que el gráfico que se está repitiendo (un gráfico con barras más largas que los pasos de la repetición muestra entera la barra que contiene esa hora). Los gráficos que sobran cuando la cuadrícula se reduce se guardan aparte, se conservan en el diseño guardado y vuelven tal como estaban cuando crece de nuevo; un gráfico totalmente nuevo se abre con el símbolo y la temporalidad del gráfico activo cuando estos están sincronizados.
ChartGrid
Disposiciones de varios gráficos sin interfaz (sin barra de herramientas) sincronizados; consulta ChartWidgetGrid para la interfaz completa.
import { ChartGrid } from '@tradecanvas/chart'
const grid = new ChartGrid(host, { layout: '2x2', theme: 'dark' })
// Un adaptador por gráfico: un adaptador mantiene un único flujo
await grid.connectAll(() => new BinanceAdapter(), ['BTCUSDT','ETHUSDT','SOLUSDT','BNBUSDT'], '5m')
grid.setLayout('1x2') Disposiciones: '1x1', '1x2', '2x1', '2x2', '1x3', '3x1', '2x3', '3x2'.