Getting started
Requirements
Backtestx Charts™ is a client-side rendering library designed for high-performance financial graphics, operating within browsers and lightweight web runtimes.
The library code targets the ES2020 language specification. Therefore, the browsers you work with should support this language revision. Consider the following table to ensure the browser compatibility.
| Browser | Minimum Version |
|---|---|
| Chrome | 87 |
| Firefox | 78 |
| Safari | 14 |
| Edge | 88 |
| Opera | 73 |
If you need to support previous browser versions, you can transpile the library bundle scripts using tools such as Babel. If you encounter any bugs, open a technical ticket in our GitHub issues.
Installation
The library is distributed as a series of optimized bundle modules. Include the core scripting bundles in your HTML file:
<!-- Charting Library Loader Bundles -->
<script src="./src/charting_library/bundles/0.d72fc8a0.js"></script>
<script src="./src/charting_library/bundles/29.59c1212b.js"></script>
<script src="./src/charting_library/bundles/37.3a5c00b5.js"></script>
<!-- Developer Customizations & App Code -->
<script src="./datafeed.js"></script>
<script src="./App.js"></script>
Alternatively, if you're installing via package managers for bundling:
License and attribution
Backtestx Charts is licensed under the Apache License 2.0. You are free to use it for both commercial and non-commercial products without royalties.
Creating a chart
Initialize the data feed and pass it to the BacktestxChart constructor along with options like the target container element ID, default symbol, and timeframe resolution:
// 1. Initialize datafeed helper
const datafeed = new window.Datafeed();
// 2. Create the chart mount inside element ID "chart-mount"
const chart = new window.BacktestxChart('chart-mount', {
symbol: 'BTCUSD',
resolution: '30m',
datafeed: datafeed
});
// Expose globally for toolbar access
window.chart = chart;
Customizing renderers
Assign custom candle render engines to chart.customDrawCandles to switch between style configurations:
// Apply Heikin-Ashi candle rendering style
chart.customDrawCandles = window.ChartingAPI.getCandleRenderer('heikin_ashi');
chart.render();
// Apply OHLC Bars rendering style
chart.customDrawCandles = window.ChartingAPI.getCandleRenderer('bar');
chart.render();
// Reset back to standard high-performance candlestick rendering
chart.customDrawCandles = null;
chart.render();
Register custom rendering functions dynamically by extending ChartingAPI.registerCandleType in custom-candle-type.js:
window.ChartingAPI.registerCandleType('my_custom_candles', function(ctx, visibleBars, slot, bodyW, chartH, priceToY, themeColors, xOffset, chartInstance) {
ctx.save();
ctx.strokeStyle = '#ff9800';
ctx.lineWidth = 1.5;
visibleBars.forEach((bar, index) => {
const x = xOffset + index * slot + slot / 2;
const yOpen = priceToY(bar.open);
const yClose = priceToY(bar.close);
ctx.beginPath();
ctx.moveTo(x, yOpen);
ctx.lineTo(x, yClose);
ctx.stroke();
});
ctx.restore();
});
Datafeed architecture
The data layer communicates through a provider implementing four lifecycle methods:
resolveSymbol(symbolName)- Resolves configuration parameters (exchange, minmov, price precision).getBars(symbolName, resolution, from, to, onResult)- Loads historical pricing candlesticks.subscribeBars(symbolName, resolution, onTick, subscriberUID)- Connects live tick streams (e.g. WebSockets).unsubscribeBars(subscriberUID)- Disconnects live streams when chart shifts.
Custom drawing tools
Extend default charting vectors by registering new shapes inside custom-drawings.js. Define drawing coordinates, canvas strokes, and click target regions:
window.ChartingAPI.registerCustomDrawing('buy_marker', {
clicks: 1,
render: function(chart, ctx, d, minPrice, maxPrice, isSelected) {
const x = chart.barToX(d.p1.idx);
const y = chart.priceToY(d.p1.price, minPrice, maxPrice);
ctx.save();
ctx.fillStyle = isSelected ? '#ff9800' : '#26a69a';
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x - 8, y + 12);
ctx.lineTo(x + 8, y + 12);
ctx.closePath();
ctx.fill();
ctx.restore();
},
hitTest: function(chart, mouseX, mouseY, d, minPrice, maxPrice) {
const x = chart.barToX(d.p1.idx);
const y = chart.priceToY(d.p1.price, minPrice, maxPrice);
if (mouseX >= x - 8 && mouseX <= x + 8 && mouseY >= y && mouseY <= y + 12) {
return 'p1';
}
return null;
}
});
Custom intervals
Register new chart candle time resolutions inside custom-interval.js:
// Register custom resolutions (suffix matches s/m/H/D/W/M)
window.ChartingAPI.registerCustomInterval('2m');
window.ChartingAPI.registerCustomInterval('3m');
window.ChartingAPI.registerCustomInterval('17m');
Custom watermarks
Format dynamic ticker background graphics inside custom-watermark.js:
window.ChartingAPI.setWatermark({
show: true,
watermarkMode: 'always',
showWatermarkTicker: true,
showWatermarkDescription: true,
showWatermarkInterval: true,
showWatermarkReplay: true,
symbol: 'BTC',
description: 'Bitcoin / U.S. Dollar',
interval: '3m'
});