### Comprehensive Plugin Registration Example Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/plugins.md A complete example demonstrating how to register individual tools alongside grouped Fibonacci and Pattern tool collections. ```javascript // Individual tools chart.registerPlugin(new MeasureTool()); chart.registerPlugin(new LineTool()); // Fibonacci group const fibGroup = new ToolGroup({ name: "Fibonacci Tools", icon: "..." }); fibGroup.add(new FibonacciTool()); fibGroup.add(new FibonacciChannelTool()); fibGroup.add(new FibSpeedResistanceFanTool()); fibGroup.add(new FibTrendExtensionTool()); chart.registerPlugin(fibGroup); // Pattern group const patternGroup = new ToolGroup({ name: "Patterns", icon: "..." }); patternGroup.add(new XABCDPatternTool()); patternGroup.add(new ABCDPatternTool()); patternGroup.add(new CypherPatternTool()); patternGroup.add(new HeadAndShouldersTool()); patternGroup.add(new TrianglePatternTool()); patternGroup.add(new ThreeDrivesPatternTool()); chart.registerPlugin(patternGroup); ``` -------------------------------- ### Installation - NPM Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/index.md Install QFChart and ECharts using npm for project integration. ```APIDOC ## Installation - NPM ### Description Install QFChart and ECharts using npm. ### Request Example ```bash npm install @qfo/qfchart echarts ``` ``` -------------------------------- ### Quick Start - Set Market Data Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/index.md Prepare and set the OHLCV market data for the chart. ```APIDOC ## Quick Start - Set Market Data ### Description Prepare your OHLCV data (Time, Open, High, Low, Close, Volume) and pass it to the chart. ### Method ```javascript chart.setMarketData(data) ``` ### Parameters #### Request Body - **data** (Array) - Required - An array of market data objects. - **time** (number) - Required - Timestamp of the data point. - **open** (number) - Required - Opening price. - **high** (number) - Required - High price. - **low** (number) - Required - Low price. - **close** (number) - Required - Closing price. - **volume** (number) - Required - Trading volume. ### Request Example ```javascript const marketData = [ { time: 1620000000000, open: 50000, high: 51000, low: 49000, close: 50500, volume: 100, }, // ... more data ]; chart.setMarketData(marketData); ``` ``` -------------------------------- ### Example: Bollinger Bands with Fill Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/plots.md A practical example showing how to configure Bollinger Bands with an upper, basis, lower line, and a fill between the upper and lower bands. ```APIDOC ## Example: Bollinger Bands with Fill ### Description This example demonstrates the creation of Bollinger Bands, including the 'fill' plot style to color the area between the upper and lower bands. ### Method POST ### Endpoint /api/indicators/BB_20 ### Parameters #### Request Body - **upper** (object) - Configuration for the upper Bollinger Band line. - **data** (array) - Array of data points. - **options** (object) - Plot styling options. - **style** (string) - 'line'. - **color** (string) - Line color. - **linewidth** (number) - Line width. - **basis** (object) - Configuration for the middle (basis) Bollinger Band line. - **data** (array) - Array of data points. - **options** (object) - Plot styling options. - **style** (string) - 'line'. - **color** (string) - Line color. - **linewidth** (number) - Line width. - **lower** (object) - Configuration for the lower Bollinger Band line. - **data** (array) - Array of data points. - **options** (object) - Plot styling options. - **style** (string) - 'line'. - **color** (string) - Line color. - **linewidth** (number) - Line width. - **fill** (object) - Configuration for the fill between upper and lower bands. - **plot1** (string) - Must be 'upper'. - **plot2** (string) - Must be 'lower'. - **options** (object) - Fill styling options. - **style** (string) - 'fill'. - **color** (string) - Fill color (e.g., 'rgba(33, 150, 243, 0.2)'). ### Request Example ```javascript const bbPlots = { upper: { data: [ { time: 1620000000000, value: 50500 }, { time: 1620086400000, value: 50700 }, { time: 1620172800000, value: 50900 }, ], options: { style: 'line', color: '#2196F3', linewidth: 1, }, }, basis: { data: [ { time: 1620000000000, value: 50000 }, { time: 1620086400000, value: 50200 }, { time: 1620172800000, value: 50400 }, ], options: { style: 'line', color: '#FFC107', linewidth: 2, }, }, lower: { data: [ { time: 1620000000000, value: 49500 }, { time: 1620086400000, value: 49700 }, { time: 1620172800000, value: 49900 }, ], options: { style: 'line', color: '#2196F3', linewidth: 1, }, }, fill: { plot1: 'upper', plot2: 'lower', options: { style: 'fill', color: 'rgba(33, 150, 243, 0.2)', // Semi-transparent blue }, }, }; chart.addIndicator('BB_20', bbPlots, { overlay: true }); ``` ### Response #### Success Response (200) - **indicatorId** (string) - The ID of the added indicator. #### Response Example ```json { "indicatorId": "BB_20" } ``` ``` -------------------------------- ### Install QFChart and ECharts Source: https://context7.com/quantforgeorg/qfchart/llms.txt Installs the QFChart library and its peer dependency, Apache ECharts, using npm. This command is essential for setting up the charting environment in a project. ```bash npm install @qfo/qfchart echarts ``` -------------------------------- ### Quick Start - Initialize Chart Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/index.md Initialize a new QFChart instance within the specified HTML container. ```APIDOC ## Quick Start - Initialize Chart ### Description Initialize the chart with configuration options. ### Method ```javascript new QFChart.QFChart(container, options) ``` ### Parameters #### Request Body - **container** (HTMLElement) - Required - The HTML element to render the chart in. - **options** (object) - Optional - Configuration for the chart, including title, height, and layout. - **title** (string) - Optional - The title of the chart. - **height** (string) - Optional - The height of the chart container. - **layout** (object) - Optional - Layout configurations. - **mainPaneHeight** (string) - Optional - Height of the main chart pane. - **gap** (number) - Optional - Gap between chart panes. ### Request Example ```javascript // Initialize the chart const container = document.getElementById('chart-container'); const chart = new QFChart.QFChart(container, { title: 'BTC/USDT', height: '600px', layout: { mainPaneHeight: '60%', gap: 20, }, }); ``` ``` -------------------------------- ### Quick Start - HTML Container Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/index.md Define an HTML container element with specified dimensions for the chart. ```APIDOC ## Quick Start - HTML Container ### Description Create a container element with a defined width and height for the chart. ### Request Example ```html
``` ``` -------------------------------- ### Quick Start - Add an Indicator Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/index.md Add a technical indicator, such as SMA, to the chart. ```APIDOC ## Quick Start - Add an Indicator ### Description Add a technical indicator to the chart, with options for overlaying or placing in separate panes. ### Method ```javascript chart.addIndicator(name, plots, options) ``` ### Parameters #### Path Parameters - **name** (string) - Required - The name of the indicator. #### Request Body - **plots** (object) - Required - An object defining the data and styling for the indicator plots. - **data** (Array) - Required - Data points for the indicator. - **time** (number) - Required - Timestamp. - **value** (number) - Required - Indicator value. - **options** (object) - Optional - Styling options for the plot. - **style** (string) - Optional - Plot style (e.g., 'line', 'histogram', 'circles'). - **color** (string) - Optional - Color of the plot. - **linewidth** (number) - Optional - Width of the line plot. #### Query Parameters - **plots** (object) - Required - An object defining the data and styling for the indicator plots. - **data** (Array) - Required - Data points for the indicator. - **time** (number) - Required - Timestamp. - **value** (number) - Required - Indicator value. - **options** (object) - Optional - Styling options for the plot. - **style** (string) - Optional - Plot style (e.g., 'line', 'histogram', 'circles'). - **color** (string) - Optional - Color of the plot. - **linewidth** (number) - Optional - Width of the line plot. - **options** (object) - Optional - Options for adding the indicator. - **overlay** (boolean) - Optional - Whether to overlay the indicator on the main chart. ### Request Example ```javascript const smaData = [ { time: 1620000000000, value: 50200 }, // ... ]; const plots = { SMA: { data: smaData, options: { style: 'line', color: '#ff9900', linewidth: 2, }, }, }; // Add as overlay on main chart chart.addIndicator('SMA_14', plots, { overlay: true }); ``` ``` -------------------------------- ### Installation - Browser (UMD) Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/index.md Include the ECharts library and QFChart in your HTML file for browser-based usage. ```APIDOC ## Installation - Browser (UMD) ### Description Include the ECharts library and QFChart in your HTML file. ### Request Example ```html ``` ``` -------------------------------- ### Example: Bollinger Bands with Fill Plot Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/plots.md Demonstrates how to implement Bollinger Bands using line plots for the upper, basis, and lower bands, and a fill plot to shade the area between the upper and lower bands. This example showcases the structure for defining multiple plots within an indicator configuration. ```javascript const bbPlots = { upper: { data: [ { time: 1620000000000, value: 50500 }, { time: 1620086400000, value: 50700 }, { time: 1620172800000, value: 50900 }, ], options: { style: 'line', color: '#2196F3', linewidth: 1, }, }, basis: { data: [ { time: 1620000000000, value: 50000 }, { time: 1620086400000, value: 50200 }, { time: 1620172800000, value: 50400 }, ], options: { style: 'line', color: '#FFC107', linewidth: 2, }, }, lower: { data: [ { time: 1620000000000, value: 49500 }, { time: 1620086400000, value: 49700 }, { time: 1620172800000, value: 49900 }, ], options: { style: 'line', color: '#2196F3', linewidth: 1, }, }, // Fill between upper and lower bands fill: { plot1: 'upper', plot2: 'lower', options: { style: 'fill', color: 'rgba(33, 150, 243, 0.2)', // Semi-transparent blue }, }, }; chart.addIndicator('BB_20', bbPlots, { overlay: true }); ``` -------------------------------- ### Registering Drawing Tools and Tool Groups Source: https://context7.com/quantforgeorg/qfchart/llms.txt This example shows how to register individual drawing tools or group them into dropdown menus for a more organized user interface in QFChart. ```APIDOC ## Plugin System - Drawing Tools Register interactive drawing tools for trend lines, Fibonacci analysis, and chart patterns. ### Method ```javascript import { QFChart, LineTool, MeasureTool, FibonacciTool, FibonacciChannelTool, FibSpeedResistanceFanTool, FibTrendExtensionTool, XABCDPatternTool, ABCDPatternTool, HeadAndShouldersTool, TrianglePatternTool, ToolGroup } from '@qfo/qfchart'; const chart = new QFChart(container, { title: 'BTC/USDT' }); // Individual tools chart.registerPlugin(new LineTool()); chart.registerPlugin(new MeasureTool()); // Grouped tools with dropdown menu const fibGroup = new ToolGroup({ name: 'Fibonacci Tools', icon: '' }); fibGroup.add(new FibonacciTool()); fibGroup.add(new FibonacciChannelTool()); fibGroup.add(new FibSpeedResistanceFanTool()); fibGroup.add(new FibTrendExtensionTool()); chart.registerPlugin(fibGroup); const patternGroup = new ToolGroup({ name: 'Patterns', icon: '...' }); patternGroup.add(new XABCDPatternTool()); patternGroup.add(new ABCDPatternTool()); patternGroup.add(new HeadAndShouldersTool()); patternGroup.add(new TrianglePatternTool()); chart.registerPlugin(patternGroup); // Note: Hold Ctrl/Cmd while drawing to snap to nearest candle OHLC values ``` ``` -------------------------------- ### Install QFChart and ECharts via Yarn Source: https://github.com/quantforgeorg/qfchart/blob/main/README.md Installs the QFChart library and its dependency, Apache ECharts, using the Yarn package manager. This is an alternative to NPM for managing project dependencies. ```bash yarn add @qfo/qfchart echarts ``` -------------------------------- ### Load Pine Script and Initialize QFChart with Indicators and Tools (JavaScript) Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/demos/pinescript.html This example shows a complete workflow for loading a Pine Script indicator from a file, fetching market data, preparing it for QFChart, initializing the chart, setting market data and indicators, and registering various interactive tools like Measure, Line, and Fibonacci tools. It assumes the existence of QFChart and PineTS libraries and specific Pine Script files. ```javascript // Data Loading Helper (Simulating what was in chart.js) const DATA_LENGTH = 500; async function getIndicatorData(inficatorCode, tickerId, timeframe = '1w', periods = 500, stime, etime) { const pineTS = new PineTS(PineTS.Provider.Binance, tickerId, timeframe, periods, stime, etime); const { result, plots, marketData } = await pineTS.run(inficatorCode); return { result, plots, marketData }; } // Load Pine Script source code from file async function loadPineScript(url) { const response = await fetch(url); return await response.text(); } // Initialize QFChart document.addEventListener('DOMContentLoaded', async () => { // Load the Pine Script source code const crossSignalSource = await loadPineScript('../data/cross-signal.pine'); const result = await getIndicatorData(crossSignalSource, 'BTCUSDT', 'W', DATA_LENGTH); const { marketData, plots: crossSignalPlots } = result; // Map Market Data to QFChart OHLCV format // marketData is array of objects: { openTime, open, high, low, close, volume } const ohlcvData = marketData.map((k) => ({ time: k.openTime, open: k.open, high: k.high, low: k.low, close: k.close, volume: k.volume, })); const isMobileDevice = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); // Initialize Chart const chartContainer = document.getElementById('main-chart'); window.chart = new QFChart.QFChart(chartContainer, { title: 'BTC/USDT', height: '600px', padding: 0.2, databox: { position: isMobileDevice ? 'floating' : 'right', }, dataZoom: { visible: true, position: 'top', height: 6, start: 50, end: 100, }, layout: { mainPaneHeight: '60%', gap: 5, }, controls: { collapse: true, maximize: true, fullscreen: true, }, }); // Set Market Data chart.setMarketData(ohlcvData); // Set Indicators chart.addIndicator('Cross Signal', crossSignalPlots, { isOverlay: true, titleColor: '#2962FF', }); // Register Measure Tool Plugin const measureTool = new QFChart.MeasureTool(); chart.registerPlugin(measureTool); // Register Line Tool Plugin const lineTool = new QFChart.LineTool(); chart.registerPlugin(lineTool); // Register Fibonacci Tool Plugin const fibTool = new QFChart.FibonacciTool(); chart.registerPlugin(fibTool); }); ``` -------------------------------- ### QFChart Initialization and Configuration Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/demos/full.html Demonstrates how to initialize QFChart, set market data, add indicators, and register plugins. ```APIDOC ## QFChart Initialization and Configuration ### Description This section covers the initialization of the QFChart instance, setting up market data, adding various indicators, and registering custom plugins like drawing tools. ### Initialization ```javascript document.addEventListener('DOMContentLoaded', async () => { // ... data fetching logic ... const chartContainer = document.getElementById('main-chart'); window.chart = new QFChart.QFChart(chartContainer, { title: 'BTC/USDT', height: '800px', padding: 0.2, databox: { position: isMobileDevice ? 'floating' : 'right' }, dataZoom: { visible: true, position: 'top', height: 6, start: 50, end: 100 }, layout: { mainPaneHeight: '60%', gap: 5 }, controls: { collapse: true, maximize: true, fullscreen: true } }); // ... indicator and plugin registration ... }); ``` ### Setting Market Data ```javascript // Assuming ohlcvData is an array of objects with time, open, high, low, close, volume properties chart.setMarketData(ohlcvData); ``` ### Adding Indicators ```javascript // Add an overlay indicator chart.addIndicator('Institutional Bias', institBiasPlots, { isOverlay: true, titleColor: '#2962FF' }); // Add a non-overlay indicator chart.addIndicator('MACD', macdPlots, { isOverlay: false, height: 14, titleColor: '#ff9900', controls: { collapse: true, maximize: true } }); chart.addIndicator('SQZMOM', sqzmomPlots, { isOverlay: false, height: 14, controls: { collapse: true, maximize: true } }); ``` ### Registering Plugins ```javascript // Register individual tools const measureTool = new QFChart.MeasureTool(); chart.registerPlugin(measureTool); const lineTool = new QFChart.LineTool(); chart.registerPlugin(lineTool); // Register a tool group const fibGroup = new QFChart.ToolGroup({ name: 'Fibonacci Tools', icon: `` }); fibGroup.add(new QFChart.FibonacciTool()); fibGroup.add(new QFChart.FibonacciChannelTool()); fibGroup.add(new QFChart.FibSpeedResistanceFanTool()); chart.registerPlugin(fibGroup); ``` ### Event Listeners for Drawing Tools ```javascript chart.events.on('drawing:hover', (payload) => console.log('Event: drawing:hover', payload)); chart.events.on('drawing:mouseout', (payload) => console.log('Event: drawing:mouseout', payload)); chart.events.on('drawing:mousedown', (payload) => console.log('Event: drawing:mousedown', payload)); chart.events.on('drawing:click', (payload) => console.log('Event: drawing:click', payload)); chart.events.on('drawing:point:hover', (payload) => console.log('Event: drawing:point:hover', payload)); chart.events.on('drawing:point:mouseout', (payload) => console.log('Event: drawing:point:mouseout', payload)); chart.events.on('drawing:point:mousedown', (payload) => console.log('Event: drawing:point:mousedown', payload)); chart.events.on('drawing:point:click', (payload) => console.log('Event: drawing:point:click', payload)); chart.events.on('drawing:selected', (payload) => console.log('Event: drawing:selected', payload)); chart.events.on('drawing:deselected', (payload) => console.log('Event: drawing:deselected', payload)); chart.events.on('drawing:deleted', (payload) => console.log('Event: drawing:deleted', payload)); ``` ``` -------------------------------- ### Step Plot Example in QFChart Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/plots.md Shows an example of configuring a step plot in QFChart. This plot style renders data as a staircase pattern. The example defines the data points and sets the `style` option to 'step', along with color and linewidth configurations. ```javascript const stepPlot = { data: [ { time: 1620000000000, value: 1 }, { time: 1620086400000, value: 1 }, { time: 1620172800000, value: 2 }, { time: 1620259200000, value: 2 }, ], options: { style: 'step', color: '#00bcd4', linewidth: 1, }, }; ``` -------------------------------- ### Initialize and Configure QFChart with Multiple Indicators Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/demos/full.html Demonstrates the process of loading indicator data in parallel using Promise.all, initializing the QFChart instance, and adding multiple technical indicators with specific layout configurations. It also shows how to register interactive drawing tools as plugins. ```javascript // 1. Load all indicators in parallel const promises = [ getIndicatorData(sqzmomIndicator, 'BTCUSDT', 'W', 500), getIndicatorData(macdIndicator, 'BTCUSDT', 'W', 500), getIndicatorData(institBiasIndicator, 'BTCUSDT', 'W', 500), ]; const results = await Promise.all(promises); // 2. Extract market data and plots const { marketData, plots: sqzmomPlots } = results[0]; const { plots: macdPlots } = results[1]; const { plots: institBiasPlots } = results[2]; // 3. Initialize chart const chart = new QFChart.QFChart(container, { title: 'BTC/USDT', height: '800px', layout: { mainPaneHeight: '60%', gap: 5 }, controls: { collapse: true, maximize: true, fullscreen: true } }); // 4. Set data and add indicators chart.setMarketData(ohlcvData); chart.addIndicator('Institutional Bias', institBiasPlots, { isOverlay: true }); chart.addIndicator('MACD', macdPlots, { isOverlay: false, height: 14 }); chart.addIndicator('SQZMOM', sqzmomPlots, { isOverlay: false, height: 14 }); // 5. Register drawing tools chart.registerPlugin(new QFChart.MeasureTool()); chart.registerPlugin(new QFChart.LineTool()); chart.registerPlugin(new QFChart.FibonacciTool()); ``` -------------------------------- ### Initialize QFChart Instance Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/api.md Demonstrates how to instantiate the QFChart class by providing a target DOM container and optional configuration settings. ```typescript new QFChart(container: HTMLElement, options?: QFChartOptions) ``` -------------------------------- ### Example: Keltner Channels with Fill Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/plots.md An example demonstrating Keltner Channels, using two 'fill' plots to color the areas between the middle band and the upper/lower bands respectively. ```APIDOC ## Example: Keltner Channels with Fill ### Description This example illustrates the setup for Keltner Channels, utilizing two 'fill' plot configurations to shade the regions between the middle band and the upper band, and between the middle band and the lower band. ### Method POST ### Endpoint /api/indicators/KC_20 ### Parameters #### Request Body - **upper** (object) - Configuration for the upper Keltner Channel line. - **data** (array) - Array of data points. - **options** (object) - Plot styling options. - **style** (string) - 'line'. - **color** (string) - Line color. - **linewidth** (number) - Line width. - **middle** (object) - Configuration for the middle Keltner Channel line. - **data** (array) - Array of data points. - **options** (object) - Plot styling options. - **style** (string) - 'line'. - **color** (string) - Line color. - **linewidth** (number) - Line width. - **lower** (object) - Configuration for the lower Keltner Channel line. - **data** (array) - Array of data points. - **options** (object) - Plot styling options. - **style** (string) - 'line'. - **color** (string) - Line color. - **linewidth** (number) - Line width. - **fill1** (object) - Configuration for the fill between the middle and upper bands. - **plot1** (string) - Must be 'middle'. - **plot2** (string) - Must be 'upper'. - **options** (object) - Fill styling options. - **style** (string) - 'fill'. - **color** (string) - Fill color (e.g., 'rgba(76, 175, 80, 0.15)'). - **fill2** (object) - Configuration for the fill between the middle and lower bands. - **plot1** (string) - Must be 'middle'. - **plot2** (string) - Must be 'lower'. - **options** (object) - Fill styling options. - **style** (string) - 'fill'. - **color** (string) - Fill color (e.g., 'rgba(244, 67, 54, 0.15)'). ### Request Example ```javascript const kcPlots = { upper: { data: upperData, options: { style: 'line', color: '#4CAF50', linewidth: 1 }, }, middle: { data: middleData, options: { style: 'line', color: '#FFC107', linewidth: 2 }, }, lower: { data: lowerData, options: { style: 'line', color: '#F44336', linewidth: 1 }, }, fill1: { plot1: 'middle', plot2: 'upper', options: { style: 'fill', color: 'rgba(76, 175, 80, 0.15)' }, }, fill2: { plot1: 'middle', plot2: 'lower', options: { style: 'fill', color: 'rgba(244, 67, 54, 0.15)' }, }, }; chart.addIndicator('KC_20', kcPlots, { overlay: true }); ``` ### Response #### Success Response (200) - **indicatorId** (string) - The ID of the added indicator. #### Response Example ```json { "indicatorId": "KC_20" } ``` ``` -------------------------------- ### Initialize QFChart with PineTS Live Stream Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/demos/live-macd-1min.html This script initializes a QFChart instance within a browser environment, fetches historical data via PineTS, and sets up a live stream to update the chart with new MACD plots and market candles. ```javascript document.addEventListener('DOMContentLoaded', async () => { const DATA_LENGTH = 1000; const TIMEFRAME = '1'; const TICKER = 'BTCUSDC'; const macdPineTS = new PineTS(PineTS.Provider.Binance, TICKER, TIMEFRAME, DATA_LENGTH); let historicalMarketData = null; let historicalMacdPlots = null; let macdChartIndicator = null; let chart = null; let isChartInitialized = false; function initializeChart() { if (isChartInitialized || !historicalMarketData || !historicalMacdPlots) return; const ohlcvData = historicalMarketData.map((k) => ({ time: k.openTime, open: k.open, high: k.high, low: k.low, close: k.close, volume: k.volume })); const chartContainer = document.getElementById('main-chart'); chart = new QFChart.QFChart(chartContainer, { title: 'BTC/USDC - 1m - Live', height: '600px' }); chart.setMarketData(ohlcvData); macdChartIndicator = chart.addIndicator('MACD', historicalMacdPlots, { isOverlay: false }); chart.registerPlugin(new QFChart.MeasureTool()); isChartInitialized = true; } const macdStream = macdPineTS.stream(macdIndicator, { pageSize: 100, live: true, interval: 3000 }); macdStream.on('data', (ctx) => { if (!isChartInitialized) { historicalMarketData = ctx.marketData; historicalMacdPlots = ctx.fullContext ? ctx.fullContext.plots : ctx.plots; initializeChart(); } else { if (macdChartIndicator) macdChartIndicator.updateData(ctx.plots); const lastBar = ctx.marketData[ctx.marketData.length - 1]; chart.updateData([lastBar]); } }); }); ``` -------------------------------- ### Line Plot Example in QFChart Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/plots.md Provides an example of configuring a line plot in QFChart. It illustrates how to define the data points, including overriding per-point colors and creating gaps by setting values to null. The `options` object specifies the plot style as 'line' with color, linewidth, and smooth curve settings. ```javascript const smaPlot = { data: [ { time: 1620000000000, value: 50200 }, { time: 1620086400000, value: 50300, options: { color: 'red' } }, // Override color { time: 1620172800000, value: null }, // Break line { time: 1620259200000, value: 50400 }, ], options: { style: 'line', color: '#ff9900', linewidth: 2, smooth: true, }, }; ``` -------------------------------- ### Initialize and Stream Squeeze Momentum Indicator Data (JavaScript) Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/demos/live-sqzmom-1min.html This snippet demonstrates how to create a PineTS instance for Binance, stream Squeeze Momentum indicator data, and handle live updates by initializing or updating a QFChart instance. It requires PineTS and QFChart libraries. ```javascript // Create PineTS instance const pineTS = new PineTS(PineTS.Provider.Binance, 'BTCUSDC', '15m', 500); // Stream indicator data const stream = pineTS.stream(sqzmomIndicator, { pageSize: 100, live: true, interval: 3000 }); // Handle live updates stream.on('data', (ctx) => { if (!chart) { // Initialize chart with historical data chart = new QFChart.QFChart(container, { /* options */ }); chart.setMarketData(ctx.marketData); indicator = chart.addIndicator('SQZMOM', ctx.plots, { isOverlay: false, height: 25 }); } else { // Update with live data indicator.updateData(ctx.plots); chart.updateData([latestBar]); } }); ``` ```javascript // Initialize QFChart document.addEventListener('DOMContentLoaded', async () => { const DATA_LENGTH = 1000; const TIMEFRAME = '1'; const TICKER = 'BTCUSDC'; // Create PineTS instance const sqzmomPineTS = new PineTS(PineTS.Provider.Binance, TICKER, TIMEFRAME, DATA_LENGTH); // Storage for accumulated historical data let historicalMarketData = null; let historicalSqzmomPlots = null; // Chart indicator references for live updates let sqzmomChartIndicator = null; // Chart instance let chart = null; let isChartInitialized = false; // Initialize chart once we have initial historical data function initializeChart() { if (isChartInitialized || !historicalMarketData || !historicalSqzmomPlots) { return; } const ohlcvData = historicalMarketData.map((k) => ({ time: k.openTime, open: k.open, high: k.high, low: k.low, close: k.close, volume: k.volume, })); const isMobileDevice = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); const chartContainer = document.getElementById('main-chart'); chart = new QFChart.QFChart(chartContainer, { title: 'BTC/USDC - 1m - Live', height: '600px', padding: 0.2, databox: { position: isMobileDevice ? 'floating' : 'right', }, dataZoom: { visible: true, position: 'top', height: 6, start: 90, end: 101, }, layout: { mainPaneHeight: '60%', gap: 5, }, controls: { collapse: true, maximize: true, fullscreen: true, }, lastPriceLine: { visible: true, showCountdown: true, }, interval: 60 * 1000, // 1 minute }); chart.setMarketData(ohlcvData); // Add Squeeze Momentum indicator sqzmomChartIndicator = chart.addIndicator('SQZMOM', historicalSqzmomPlots, { isOverlay: false, height: 25, controls: { collapse: true, maximize: true }, }); // Register plugins chart.registerPlugin(new QFChart.MeasureTool()); chart.registerPlugin(new QFChart.LineTool()); chart.registerPlugin(new QFChart.FibonacciTool()); isChartInitialized = true; console.log('✅ Chart initialized with', historicalMarketData.length, 'historical candles'); } // Stream SQZMOM const sqzmomStream = sqzmomPineTS.stream(sqzmomIndicator, { pageSize: 100, live: true, interval: 3000, }); sqzmomStream.on('data', (ctx) => { if (!isChartInitialized) { // Store market data and plots from full context historicalMarketData = ctx.marketData; historicalSqzmomPlots = ctx.fullContext ? ctx.fullContext.plots : ctx.plots; initializeChart(); } else { // Live update - update indicator first, then chart data if (sqzmomChartIndicator) { sqzmomChartIndicator.updateData(ctx.plots); } // Update chart with latest candle const lastBar = ctx.marketData[ctx.marketData.length - 1]; const updateBar = { time: lastBar.openTime, open: lastBar.open, high: lastBar.high, low: lastBar.low, close: lastBar.close, volume: lastBar.volume, }; chart.updateData([updateBar]); } }); // Error handling sqzmomStream.on('error', (err) => console.error('SQZMOM stream error:', err)); }); ``` -------------------------------- ### QFChart Initialization and Data Management Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/api.md Methods for initializing the QFChart instance and managing market data updates. ```APIDOC ## Constructor: new QFChart(container, options) ### Description Initializes a new QFChart instance within the specified DOM element. ### Parameters - **container** (HTMLElement) - Required - The DOM element where the chart will be rendered. - **options** (QFChartOptions) - Optional - Configuration object for the chart. ## Method: setMarketData(data) ### Description Sets the main OHLCV data for the candlestick chart. Performs a full chart re-render. ### Parameters - **data** (OHLCV[]) - Required - Array of OHLCV objects. ## Method: updateData(data) ### Description Incrementally updates market data without a full re-render for optimal performance. Merges data by timestamp. ### Parameters - **data** (OHLCV[]) - Required - Array of OHLCV objects to merge. ``` -------------------------------- ### Initialize and Stream QFChart with PineTS Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/demos/live.html This script initializes the QFChart instance and sets up streaming data connections for technical indicators like SQZMOM, MACD, and Institutional Bias. It handles the initial data loading phase to populate the chart and provides real-time updates as new market data arrives. ```javascript document.addEventListener('DOMContentLoaded', async () => { const DATA_LENGTH = 1000; const TIMEFRAME = '1'; const TICKER = 'BTCUSDC'; const sqzmomPineTS = new PineTS(PineTS.Provider.Binance, TICKER, TIMEFRAME, DATA_LENGTH); const macdPineTS = new PineTS(PineTS.Provider.Binance, TICKER, TIMEFRAME, DATA_LENGTH); const institBiasPineTS = new PineTS(PineTS.Provider.Binance, TICKER, TIMEFRAME, DATA_LENGTH); let historicalMarketData = null, historicalSqzmomPlots = null, historicalMacdPlots = null, historicalInstitBiasPlots = null; let sqzmomChartIndicator = null, macdChartIndicator = null, institBiasChartIndicator = null; let chart = null, isChartInitialized = false; function initializeChart() { if (isChartInitialized || !historicalMarketData || !historicalSqzmomPlots || !historicalMacdPlots || !historicalInstitBiasPlots) return; const ohlcvData = historicalMarketData.map((k) => ({ time: k.openTime, open: k.open, high: k.high, low: k.low, close: k.close, volume: k.volume })); const chartContainer = document.getElementById('main-chart'); chart = new QFChart.QFChart(chartContainer, { title: 'BTC/USDT (Live)', height: '800px' }); chart.setMarketData(ohlcvData); institBiasChartIndicator = chart.addIndicator('Institutional Bias', historicalInstitBiasPlots, { isOverlay: true }); macdChartIndicator = chart.addIndicator('MACD', historicalMacdPlots, { isOverlay: false }); sqzmomChartIndicator = chart.addIndicator('SQZMOM', historicalSqzmomPlots, { isOverlay: false }); isChartInitialized = true; } const sqzmomStream = sqzmomPineTS.stream(sqzmomIndicator, { pageSize: 100, live: true, interval: 5000 }); sqzmomStream.on('data', (ctx) => { if (!isChartInitialized) { historicalSqzmomPlots = ctx.fullContext ? ctx.fullContext.plots : ctx.plots; initializeChart(); } else if (sqzmomChartIndicator) { sqzmomChartIndicator.updateData(ctx.plots); } }); }); ``` -------------------------------- ### Add Bollinger Bands with Filled Area using JavaScript Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/examples/fill-plot-example.md This JavaScript example demonstrates how to configure Bollinger Bands with a filled area between the upper and lower bands using the 'fill' plot style. It defines indicator plots and adds them to the chart, specifying colors and line styles. Dependencies include chart object and pre-defined data arrays. ```javascript const bbIndicator = { id: 'BB', plots: { upper: { data: upperBandData, options: { style: 'line', color: '#2196F3', linewidth: 1, }, }, basis: { data: basisData, options: { style: 'line', color: '#FFC107', linewidth: 2, }, }, lower: { data: lowerBandData, options: { style: 'line', color: '#2196F3', linewidth: 1, }, }, // Fill between upper and lower bands fill: { plot1: 'upper', // Reference to upper plot plot2: 'lower', // Reference to lower plot options: { style: 'fill', color: 'rgba(33, 150, 243, 0.2)', // Semi-transparent blue }, }, }, }; chart.addIndicator('BB', bbIndicator.plots, { overlay: true, titleColor: '#2196F3', }); ``` -------------------------------- ### Initialize QFChart with Market Data and Indicator (JavaScript) Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/demos/basic-01.html This JavaScript snippet shows the minimal code required to initialize QFChart. It demonstrates parsing pre-loaded data, setting market data (candlesticks), and adding a custom indicator to a separate pane. This is suitable for developers new to QFChart. ```javascript // 1. Parse pre-loaded data (in production, fetch from API) const indicatorData = JSON.parse(/* MACD data */); const ohlcvData = JSON.parse(/* BTC/USDT market data */); // 2. Initialize chart with default options const chart = new QFChart.QFChart(container, { title: 'BTC/USDT' }); // 3. Set market data (candlesticks) chart.setMarketData(ohlcvData); // 4. Add indicator to separate pane chart.addIndicator('Indicator', indicatorData, { overlay: false, height: 20, titleColor: '#ffffff' }); ``` -------------------------------- ### Get QFChart Drawing Source: https://github.com/quantforgeorg/qfchart/blob/main/docs/api.md Retrieves a drawing from the chart by its ID. Returns the `DrawingElement` object if found, otherwise returns `undefined`. ```typescript getDrawing(id: string): DrawingElement | undefined ``` -------------------------------- ### Manage Persistent Chart Drawings Source: https://context7.com/quantforgeorg/qfchart/llms.txt Provides examples for programmatically adding, updating, and removing drawings on the chart. It also shows how to snap coordinates to candle data. ```javascript chart.addDrawing({ id: 'trend-line-1', type: 'line', points: [{ timeIndex: 0, value: 50000, paneIndex: 0 }, { timeIndex: 10, value: 55000, paneIndex: 0 }], style: { color: '#3b82f6', lineWidth: 2 } }); const drawing = chart.getDrawing('trend-line-1'); if (drawing) { drawing.points[1].value = 56000; chart.updateDrawing(drawing); } chart.removeDrawing('trend-line-1'); const snapped = chart.snapToCandle({ x: pixelX, y: pixelY }); ```