Building a trading platform or financial dashboard shouldn’t require reinventing the charting wheel. Yet most developers face a tough choice: embed third-party charting solutions that lock you into their ecosystem, or build everything from scratch using low-level canvas APIs.
We built QFChart to eliminate that trade-off.
What is QFChart?
QFChart is a lightweight, high-performance financial charting library built on Apache ECharts. It provides an intuitive API specifically designed for OHLCV candlestick charts, technical indicators, and interactive drawing tools ; everything you need to build professional trading interfaces.
The library is open-source (Apache 2.0), written in TypeScript, and works seamlessly with PineTS for a complete Pine Script execution and visualization stack, though it’s fully independent and can be used with any data provider or technical indicator library.
Why We Built QFChart
When we created PineTS to run Pine Script outside TradingView, we faced an obvious next challenge: how do you visualize the results? General-purpose charting libraries like Chart.js and D3.js are powerful, but they’re not built for the specific needs of financial charting:
- Time-series with gaps: Markets close. Weekends happen. Financial charts need to handle non-continuous time series elegantly.
- Multi-pane layouts: Indicators like RSI and MACD need their own panes below the main chart, each with independent scaling.
- Overlay indicators: Moving averages and Bollinger Bands need to render directly on top of candlesticks.
- Real-time updates: Trading bots and dashboards need incremental updates without full chart re-renders.
- Drawing tools: Traders need trend lines, Fibonacci retracements, and measurement tools.
QFChart solves all of these problems with a clean, developer-friendly API.
Core Features
Professional Candlestick Charts
High-performance rendering of OHLCV data with customizable colors and automatic scaling:
import { QFChart } from '@qfo/qfchart';
const chart = new QFChart(container, {
title: 'BTC/USDT',
height: '600px',
backgroundColor: '#1e293b',
upColor: '#00da3c',
downColor: '#ec0000',
});
chart.setMarketData([
{
time: 1620000000000,
open: 50000,
high: 51000,
low: 49000,
close: 50500,
volume: 100000,
},
// ... more candles
]);
Multi-Pane Indicator Support
Stack indicators in separate panes with customizable heights and independent scaling:
const macdPlots = {
histogram: {
data: [
{ time: 1748217600000, value: 513.11, options: { color: '#26A69A' } },
// ...
],
options: { style: 'histogram', color: '#26A69A' },
},
macd: {
data: [/* ... */],
options: { style: 'line', color: '#2962FF' },
},
signal: {
data: [/* ... */],
options: { style: 'line', color: '#FF6D00' },
},
};
chart.addIndicator('MACD', macdPlots, {
isOverlay: false,
height: 15, // Percentage of chart height
controls: { collapse: true, maximize: true },
});
Overlay Indicators
Add indicators directly on top of the main chart:
const smaPlots = {
sma: {
data: [
{ time: 1620000000000, value: 50200 },
// ...
],
options: {
style: 'line',
color: '#2962FF',
linewidth: 2,
},
},
};
chart.addIndicator('SMA_20', smaPlots, {
isOverlay: true,
});
Rich Plot Styles
QFChart supports multiple visualization styles for rendering technical indicators:
- line: Classic line charts for moving averages and trends
- step: Step-line charts for discrete value changes
- histogram: Vertical bars for volume-like data
- columns: Grouped vertical bars
- circles: Scatter plots with circular markers
- cross: Cross-shaped markers for signals
- background: Fills background areas based on conditions (like
bgcolor()in Pine Script) - shape: Arrows, triangles, labels with custom positioning
- bar/candle: OHLC rendering for indicators like Heikin Ashi (equivalent to
plotbar()andplotcandle()) - barcolor: Colors main chart candlesticks based on conditions (equivalent to
barcolor()in Pine Script)
Each style supports per-point customization for advanced visualizations.
Real-Time Updates
For live trading applications, updateData() provides incremental updates without full re-renders:
// Keep reference to indicator
const macdIndicator = chart.addIndicator('MACD', macdPlots, {
isOverlay: false,
height: 15,
});
// WebSocket callback
function onNewTick(bar, indicators) {
// Update indicator data first
macdIndicator.updateData(indicators);
// Update chart data (triggers re-render)
chart.updateData([bar]);
}
This approach is significantly faster than calling setMarketData() and is essential for real-time trading dashboards.
Interactive Drawing Tools (Plugin System)
QFChart includes an extensible plugin system for adding interactive tools:
import { LineTool, FibonacciTool, MeasureTool } from '@qfo/qfchart';
chart.registerPlugin(new LineTool());
chart.registerPlugin(new FibonacciTool());
chart.registerPlugin(new MeasureTool());
Currently available plugins:
- Line Drawing: Draw trend lines and support/resistance levels
- Fibonacci Retracements: Interactive Fibonacci levels with automatic ratio calculations
- Measure Tool: Measure price and time distances between any two points
The plugin architecture makes it easy to build custom tools specific to your trading strategy.
Flexible Layouts
Configurable data displays that don’t obstruct the chart:
const chart = new QFChart(container, {
title: 'BTC/USDT',
databox: {
position: 'right', // or 'left', 'floating'
},
});
The databox displays current OHLCV values and can be positioned to fit your UI design.
Full Customization
Every visual aspect of the chart can be customized:
const chart = new QFChart(container, {
title: 'BTC/USDT',
backgroundColor: '#1e293b',
upColor: '#00da3c',
downColor: '#ec0000',
fontColor: '#cbd5e1',
fontFamily: 'sans-serif',
padding: 0.2, // Vertical padding for auto-scaling
dataZoom: {
visible: true,
position: 'top',
height: 6,
start: 0,
end: 100,
},
watermark: true, // Show "QFChart" watermark
controls: {
collapse: true,
maximize: true,
fullscreen: true,
},
});
Perfect Pairing: QFChart + PineTS
QFChart was designed to work seamlessly with PineTS. Together, they provide a complete solution for running and visualizing Pine Script indicators:
import { PineTS, Provider } from 'pinets';
import { QFChart } from '@qfo/qfchart';
// Execute Pine Script indicator
const pineTS = new PineTS(Provider.Binance, 'BTCUSDT', '1h', 500);
const pineScript = `
//@version=6
indicator("EMA Cross")
fast = ta.ema(close, 9)
slow = ta.ema(close, 21)
plot(fast, "Fast EMA", color.blue)
plot(slow, "Slow EMA", color.red)
`;
const { plots, marketData } = await pineTS.run(pineScript);
// Visualize with QFChart
const chart = new QFChart(container, { title: 'BTC/USDT' });
chart.setMarketData(marketData);
chart.addIndicator('EMA_Cross', plots, { isOverlay: true });
This combination gives you the power to run any Pine Script indicator and render it exactly as it would appear in TradingView—but in your own application, under your control.
Installation
NPM
npm install @qfo/qfchart echarts
Browser (UMD)
<!-- 1. Include ECharts (Required) -->
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
<!-- 2. Include QFChart -->
<script src="https://cdn.jsdelivr.net/npm/@qfo/qfchart/dist/qfchart.min.browser.js"></script>
Quick Start Example
Here’s a complete working example in less than 20 lines:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@qfo/qfchart/dist/qfchart.min.browser.js"></script>
</head>
<body>
<div id="chart" style="width: 100%; height: 600px;"></div>
<script>
const chart = new QFChart.QFChart(
document.getElementById('chart'),
{ title: 'BTC/USDT' }
);
const data = [
{ time: 1620000000000, open: 50000, high: 51000, low: 49000, close: 50500, volume: 100 },
// ... add more candles
];
chart.setMarketData(data);
</script>
</body>
</html>
Documentation & Resources
- Documentation: Complete API reference and guides
- GitHub Repository: Source code and examples
- NPM Package: Install via npm
- Interactive Demos: See QFChart in action
Use Cases
QFChart is perfect for:
- Trading Platforms: Build custom charting interfaces for your users
- Portfolio Dashboards: Visualize asset performance and indicators
- Backtesting Visualizations: Display strategy results with indicators overlaid
- Research Tools: Analyze market data with technical indicators
- Educational Platforms: Teach technical analysis with interactive charts
- Trading Bots: Monitor live strategy performance in real-time
What’s Next
We’re actively developing QFChart alongside PineTS. Upcoming features include:
- Additional drawing tools (trend channels, rectangles, text annotations)
- Enhanced customization options
- Performance optimizations for massive datasets
- More plugin examples and templates
Get Involved
QFChart is open-source and community-driven. We welcome contributions, bug reports, and feature requests:
The Complete Stack
QFChart is one piece of the QuantForge ecosystem:
- PineTS: Run Pine Script indicators in JavaScript/TypeScript
- QFChart: Visualize financial data and technical indicators
- Together: A complete solution for building professional trading platforms
Whether you’re building a trading bot, a portfolio dashboard, or a full-fledged trading platform, QFChart gives you the charting foundation you need—without the vendor lock-in.
QFChart is open-source software licensed under Apache 2.0. Built with ❤️ by QuantForge.

Leave a Reply