@backtestx/lightweight-chart
v1.0.0
Published
Performant financial charts built with HTML5 canvas based on Backtestx Charts
Maintainers
Readme
BacktestX Lightweight Chart
Performant financial charts built with HTML5 canvas based on Backtestx chart, loaded with custom drawing tools and programmable indicators.
Features
- Fully Standalone: Out of the box,
backtestxhandles its own HTML injection. You only need to provide a mounting element. - Custom Drawing Tools: Pre-loaded with extensive drawing capabilities including trendlines, horizontal/vertical lines, fibonacci retracements, text labels, and highly customizable UI markers.
- Programmable API: Extend the chart seamlessly by injecting your own visual custom indicators.
Installation
Install using npm:
npm install backtestxQuick Start
Creating a fully functioning interactive chart with drawing tools is incredibly simple. All you need is an empty div container.
1. HTML Container
<!-- The library will automatically inject its workspace and drawing toolbar around this mount -->
<div id="chart-mount" style="width: 100vw; height: 100vh;"></div>2. Include the Script
If you are loading it directly via a script tag:
<link rel="stylesheet" href="node_modules/backtestx/dist/backtestx.standalone.production.css">
<script src="node_modules/backtestx/dist/backtestx.standalone.production.js"></script>If you are using modern imports (Webpack, Vite, etc.):
import 'backtestx/dist/backtestx.standalone.production.css';
import 'backtestx'; // Auto-attaches and runsAdding Custom Indicators via API
You can easily register and render your own custom indicators using the global ChartingAPI.
Here is a quick example of how you can add an external custom VWAP indicator:
document.addEventListener('DOMContentLoaded', () => {
// Give the bundle a moment to fully initialize the ChartingAPI global
setTimeout(() => {
if (window.ChartingAPI && window.ChartingAPI.registerIndicator) {
window.ChartingAPI.registerIndicator('my_external_vwap', {
name: 'External VWAP Demo',
type: 'overlay',
params: {},
defaultColor: '#00E676',
calculate: function(bars, params) {
const vwap = new Array(bars.length).fill(null);
let cumulativeTypPriceVolume = 0;
let cumulativeVolume = 0;
for (let i = 0; i < bars.length; i++) {
const bar = bars[i];
const typPrice = (bar.high + bar.low + bar.close) / 3;
cumulativeTypPriceVolume += typPrice * bar.volume;
cumulativeVolume += bar.volume;
if (cumulativeVolume > 0) {
vwap[i] = cumulativeTypPriceVolume / cumulativeVolume;
}
}
return vwap;
},
render: function(ctx, chart, values, bounds, color) {
const { startIndex, endIndex } = bounds;
ctx.save();
ctx.beginPath();
ctx.strokeStyle = color || '#00E676';
ctx.lineWidth = 3;
ctx.setLineDash([5, 5]);
let started = false;
for (let i = startIndex; i <= endIndex; i++) {
if (i >= chart.bars.length) break;
const v = values[i];
if (v == null) continue;
const x = chart.barToX(i);
const y = chart.priceToY(v);
if (!started) {
ctx.moveTo(x, y);
started = true;
} else {
ctx.lineTo(x, y);
}
}
ctx.stroke();
ctx.restore();
}
});
}
}, 500);
});License
This project is licensed under the ISC License. See the LICENSE file for details.
