Latest commit

History

839 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

High-performance financial chart library with a single-frame generation time of just 2ms, stable scrolling at 190–200fps in a 200Hz environment, native support for AI Agent control, full-link ResizeObserver-driven crisp rendering, and a pluggable architecture.

English | 简体中文

📈 KLineChartQuant

Crisp Rendering · High Performance · Optimized Interaction · Mobile-Friendly

npm versionnpm downloadslicensedemo

qqtg


A lightweight financial K-line charting library focused on quantitative trading scenarios. Agent is a first-class citizen — supports AI Agent direct control of chart operations, providing TradingView-level interaction experience.




✨ Core Features

  • Agent First / MCP Native - Supports AI Agent direct control of charts via the Model Context Protocol. Built-in WebSocket-bridged MCP server enables any MCP client (Inspector, Claude Desktop, Cursor, etc.) to zoom, pan, add/remove indicators, and change theme in real time
  • Crisp Rendering - Full-chain ResizeObserver driven, physical pixel alignment, K-lines, wicks, and lines are sharp and clear on all DPR screens
  • Plugin Architecture - Renderer plugin-based design, supporting dynamic registration, configuration, and lifecycle management
  • Custom Markers - Supports semantic configuration of custom markers and custom information
  • High Performance - Smoothly handles tens of thousands of data points, no lag during zoom or pan; supports 190-200fps on 200Hz displays with single-frame generation time as low as 2ms
  • Multi-Backend Rendering - Submit drawing primitives once, render via WebGPU, WebGL, or Canvas2D. WebGPU provides hybrid DOM canvas (no compositeTo copy), single-command-buffer-per-frame submission with 4x MSAA, and per-instance geometry caching via ResourceTable. Automatic fallback chain: WebGPU → WebGL → Canvas2D. Reaching 190fps on 200Hz displays with per-frame GPU time under 1ms
  • Optimized Interaction - Stable zoom anchor, precise crosshair cursor, smooth drag
  • Mobile-Optimized Interaction - Long-press crosshair for data exploration, tap to dismiss, slide to browse data without triggering chart scroll, gesture-based scroll mode
  • Multi-Symbol Comparison - Supports unlimited number of instruments for trend comparison
  • Multi-Source Aggregation - Supports aggregation and unification of multiple data sources
  • Batch Data Export - Select a date range and export multiple stocks' K-line data into a single CSV file, with progress indication
  • Custom Tooltip - Fully customizable tooltip via named slots (#kline-tooltip, #marker-tooltip), with engine-provided hover data, position, and styling

📐 System Architecture

KLineChartQuant is a pnpm monorepo. The framework-agnostic core engine exposes a unified ChartController (readonly signals + commands); Vue / React / Angular bindings only handle mounting, event forwarding, and reactivity bridging. AI Agents drive the chart directly through MCP over a WebSocket bridge.

flowchart TB
subgraph app["UI Layer / Framework Bindings"]
UI["UI Layer"]
VuePkg["@363045841yyt/klinechart<br/>Vue 3 components · useChart"]
ReactPkg["@363045841yyt/klinechart-react<br/>KLineChartWC (wraps Vue-built Web Component)"]
AngularPkg["@363045841yyt/klinechart-angular"]
Agent["AI Agent / MCP Client"]
AiRt["@363045841yyt/klinechart-ai-runtime"]
end
subgraph core["Core Engine @363045841yyt/klinechart-core"]
Ctl["ChartController<br/>signals + commands"]
Chart["Chart facade"]
Kernel["StateKernel<br/>Reactive SSOT"]
Data["Data Layer<br/>SeriesRepository · Buffers"]
Pipe["Rendering Pipeline<br/>FrameTransaction · Scene/Layer"]
GPU["WebGPU / WebGL2 / Canvas2D"]
Plugin["Plugin Subsystem<br/>PluginHost · RendererPlugin"]
Biz["Indicators · Markers · Drawing<br/>Timeshare · Compare · Components"]
end
subgraph conn["Market Data Backends"]
Go["GoTDX-Connecter<br/>gotdx :8080"]
Bn["GoTDX-Connecter<br/>Binance depth :8081"]
Bs["Baostock-Tradingview-Connecter<br/>BaoStock / TradingView :8000"]
end
UI --> VuePkg
UI --> ReactPkg
UI --> AngularPkg
VuePkg -->|"Web Component"| ReactPkg
Agent --> AiRt
VuePkg --> Ctl
ReactPkg --> Ctl
AngularPkg --> Ctl
AiRt -->|WebSocket / MCP| Ctl
Ctl --> Chart
Chart --> Kernel
Chart --> Data
Chart --> Pipe
Chart --> Plugin
Plugin --> Biz
Biz --> Pipe
Pipe --> GPU
Go -->|market data| Data
Bn -->|market data| Data
Bs -->|market data| Data
Kernel --> Data
Kernel --> Pipe
Loading
  • Core engine — headless chart engine + ChartController; depends on no UI framework.
  • StateKernel — single source of truth: readonly signals for reads, actions for writes, computed() for derivation, effect() for DOM side effects.
  • Rendering — submit primitives once, render via WebGPU / WebGL2 / Canvas2D with automatic fallback (WebGPU → WebGL → Canvas2D).
  • Data layer — unified SeriesRepository + incremental buffers + fetch scheduler; multi-source aggregation (gotdx / BaoStock / TradingView / mock) and Binance depth.
  • Plugin subsystem — PluginHost / HookSystem / EventBus / RendererPluginManager; indicators, markers and drawing tools plug in as Scene Layers.
  • React via Web Component@363045841yyt/klinechart-react's KLineChartWC renders the <kline-chart> Custom Element bundled from the Vue package (@363045841yyt/klinechart/web-component).
  • MCP / Agent@363045841yyt/klinechart-ai-runtime bridges AI tool calls to the controller over WebSocket.

See docs/architecture.md for the full architecture document.

📡 Data Sources

KLineChart requires a market data backend. Supported data sources:

Data SourceDescriptionDocs
gotdxTongdaxin (GOTDX) quotes: A-share / futures / MAC, served by GoTDX-ConnecterGoTDX-Connecter
baostockBaoStock A-share daily / weekly / monthly & minute K-lines, served by Baostock-Tradingview-ConnecterBaoStock
tradingviewTradingView global instruments, served by Baostock-Tradingview-ConnecterBaoStock
mockDebug only: local MOCK-100 / MOCK-10000 K-lines, no backend needed, always online

Backend repos live alongside this one (outside the monorepo).

One-Command Dev Startup

Clone the data-source backends first (idempotent: skips directories that already exist):

pnpm setup

Then run pnpm dev with a -c argument to start the frontend and the selected connecters together:

pnpm dev # frontend only (Vite dev server)
pnpm dev -c all # frontend + all backends (gotdx + binance + baostock)
pnpm dev -c gotdx baostock # frontend + selected backends
pnpm dev -c tdx # aliases supported (tdx / g / b / bnb / all)
pnpm dev -c all --lan # same, dev server bound to 0.0.0.0 (LAN accessible)

Common shorthands:

pnpm dev:all # frontend + all backends
pnpm dev:g # frontend + gotdx (Tongdaxin)
pnpm dev:b # frontend + BaoStock / TradingView
pnpm dev:bnb # frontend + Binance depth
pnpm dev:lan:all # frontend (0.0.0.0) + all backends

Parallel process logs stay in one terminal and are separated by colored source prefixes: [vite], [gotdx], [binance], and [baostock].

Backend only (no frontend):

pnpm connecter # all backends
pnpm connecter gotdx # gotdx (Tongdaxin) :8080
pnpm connecter baostock # BaoStock / TradingView :8000

After pnpm setup, no extra setup is needed. The dev server proxies /api/stock:8000 (Baostock-Tradingview-Connecter) and /api/public:8080 (GoTDX-Connecter).

🚀 Quick Start

3. Install and Use

npm install @363045841yyt/klinechart @363045841yyt/klinechart-core

Use the component:

<template>
<divclass="app-container":data-theme="currentTheme">
<KlineChartv-model:theme="currentTheme" :custom-data="customData" :settings="chartSettings" />
</div>
</template>
<script setup lang="ts">import { ref } from'vue'importtype { ChartSettings } from'@363045841yyt/klinechart-core'import { typeCustomDataSource, KlineChart } from'@363045841yyt/klinechart'importdemoDatafrom'./demo-data.json'const currentTheme =ref<'light'|'dark'>('dark')const customData =ref<CustomDataSource>(demoDataasCustomDataSource)const chartSettings:ChartSettings= { showGridLines: true, isAsiaMarket: true, showVolumePriceMarkers: false, mainLeftAxisDisplaySetting: 'none', theme: 'dark', colorPresetSettings: { dark: { candleUpBody: '#e85d04', candleDownBody: '#1b4332', crosshairLine: '#faa307', gridMajor: '#3e2723', }, }, }</script>
<style>.app-container {display: flex;flex-direction: column;height: 80vh; }.app-container[data-theme='dark'] {background: #000;color: #e5e7eb; }</style>

Import CSS in main.ts:

import'@363045841yyt/klinechart/style.css'import{createApp}from'vue'importAppfrom'./App.vue'createApp(App).mount('#app')

Slot Usage — Custom Tooltip:

<KlineChart><template#kline-tooltip="{ hoverData, upColor, downColor }"><divclass="custom-tooltip"><divclass="custom-tooltip__title"><span>{{ hoverData.stockCode }}</span><span>{{ formatTimestamp(hoverData.timestamp, { timeZone: 'Asia/Shanghai' }) }}</span></div><divclass="custom-tooltip__price"
:style="{ color: hoverData.close >= hoverData.open ? upColor : downColor }"
>
{{ hoverData.close.toFixed(2) }}
</div><divclass="custom-tooltip__detail">
O: {{ hoverData.open.toFixed(2) }}<br/>
H: {{ hoverData.high.toFixed(2) }}<br/>
L: {{ hoverData.low.toFixed(2) }}<br/>
C: {{ hoverData.close.toFixed(2) }}
</div></div></template></KlineChart>

Slot Usage — Custom Main-Pane Legend:

Providing #legend fully replaces the default Canvas legend. The slot scope is the full LegendTemplateContext (OHLC, timeshare, main indicators, comparisons, layout, colors).

<template #legend="{ index, currentBar, timeshare, indicators, comparisons, colors }">
<divclass="my-legend">
<!-- Custom fields added to KLineData[] for PR #98 are exposed through currentBar -->
<divv-if="currentBar"class="my-legend__row">
<span:style="{ color: currentBar.color }">
开盘 {{ currentBar.open.toFixed(2) }} 最高 {{ currentBar.high.toFixed(2) }} 最低
{{ currentBar.low.toFixed(2) }} 收盘 {{ currentBar.close.toFixed(2) }}
</span>
<spanv-if="currentBar.volumeText"> Vol {{ currentBar.volumeText }}</span>
</div>
<divv-if="timeshare"class="my-legend__row">
<span:style="{ color: timeshare.changeColor }">
现价 {{ timeshare.price.toFixed(2) }} 涨幅 {{ timeshare.changePercent.toFixed(2) }}%
</span>
</div>
<!-- Using main chart indicator legend data -->
<divv-for="indicator in indicators":key="indicator.name"class="my-legend__row">
<span>{{ indicator.name }}:</span>
<templatev-for="valueinindicator.values" :key="value.label">
<span:style="{ color: value.color }">
{{ value.label }} {{ value.value.toFixed(3) }}
</span>
</template>
</div>
<!-- Using comparison commodity data -->
<divv-for="comparison in comparisons":key="comparison.symbol"class="my-legend__row":style="{ color: comparison.percentColor }"
>
{{ comparison.symbol }}
{{ comparison.percent > 0 ? '+' : '' }}{{ comparison.percent.toFixed(2) }}%
</div>
</div>
</template>

4. (Optional) Enable MCP / AI Agent Control

npm install @363045841yyt/klinechart-ai-runtime
<template>
<divclass="app-container">
<KlineChart ref="chartRef" :mcp="mcpConfig" />
</div>
</template>
<script setup lang="ts">import { ref } from'vue'import { KlineChart } from'@363045841yyt/klinechart'import { executeTool } from'@363045841yyt/klinechart-ai-runtime'const chartRef =ref<InstanceType<typeofKlineChart> |null>(null)const mcpConfig = { wsUrl: 'ws://localhost:8080', autoReconnect: true,onToolCall: (call) => {const ctrl =chartRef.value?.getController?.()if (!ctrl) return { success: false, error: 'Controller not ready' }returnexecuteTool(ctrl, call) }, }</script>
<style>.app-container {height: 80vh; }</style>

Then start the MCP server:

cd packages/ai-runtime
pnpm inspect

Connect via MCP Inspector and call chart.zoomToLevel, indicators.add, etc.

📖 More Documentation

📋 Component Props

PropTypeDefaultDescription
semanticConfigSemanticChartConfigSemantic configuration (optional). When provided, drives chart data, indicators, markers and chart options
theme'light' | 'dark'Chart theme. Use v-model:theme for two-way binding
isFullscreenbooleanControlled fullscreen state. Leave unbound for internal (non-controlled) mode
timezonestring'Asia/Shanghai'Time zone for date/time display
yPaddingPxnumber20Y-axis padding in pixels
minKWidthnumber1Minimum K-line width (logical pixels)
maxKWidthnumber50Maximum K-line width (logical pixels)
rightAxisWidthnumber0Right price axis width
leftAxisWidthnumber0Left price axis width (0 = hidden)
bottomAxisHeightnumber24Bottom time axis height
priceLabelWidthnumber60Price label extra width for showing change percentage
zoomLevelsnumber20Total number of zoom levels
initialZoomLevelnumber3Initial zoom level (1 ~ zoomLevels)
customDataCustomDataSourceInline data bundle: { symbol?, period?, data, comparisons? }. Bypasses the fetcher pipeline entirely. See example above
teleportContainerstring | HTMLElementTeleport target for dropdowns/modals (CSS selector or element). Defaults to internal .chart-wrapper
mcpMcpConfigMCP/AI runtime bridge config: { wsUrl?, autoReconnect?, onToolCall? }. See @363045841yyt/klinechart-ai-runtime

🗺️ Roadmap

  • v0.10: AI-native chart support
  • K-line zoom anchor stability, improved zoom feel
  • Right axis detached from scroll container, completely solving clipping issues
  • Blank area drawing support
  • Limit vertical pan range to prevent viewport from leaving data
  • Drawing system
  • Right axis zoom
  • Latest price line and right axis label style optimization
  • Area primitive tools and rendering
  • More advanced drawing tools
  • Support for minute, multi-day, monthly, and yearly K-line display
  • Support convert the drawing to quant code

📦 Packages

PackageDescriptionnpm
@363045841yyt/klinechart-coreHeadless chart engine + controllersnpm
@363045841yyt/klinechartVue 3 bindingsnpm
@363045841yyt/klinechart-reactReact bindingsnpm
@363045841yyt/klinechart-angularAngular bindingsnpm
@363045841yyt/klinechart-ai-runtimeMCP server + AI tool schemas (optional)npm

🚀 What's New

  • v0.9.0 Self-developed Core-layer reactive state model migration, timing issues eliminated
  • v0.9.0 Single-path Scene renderer + WebGPU backend (hybrid DOM canvas, no compositeTo), FrameTransaction reactivity, device-lost recovery, auto-fallback WebGPU → WebGL → Canvas2D
  • v0.8 Symbol comparison, multi-source data aggregation
  • v0.7 Renderer registration chain AOP refactoring with decorator syntax, monorepo split, Vue/React bindings (experimental), standalone core package, tokenized color system
  • v0.6.10 Unified WebGL rendering context sharing for all panes, plus sub-pane lifecycle refactoring — centralized pane instance management via SubPaneManager with first-class paneId identity
  • v0.6.6 Comprehensive rendering optimizations: batched price-to-Y calculations, cached tick positions and geometry, optimized month-key operations; achieves stable 190-200fps on 200Hz displays with frame generation time down to 2ms
  • v0.6.3 WebGL rendering for K-lines, volume bars, and MACD bars; significant performance boost across the board
  • v0.6.1 Dual-layer canvas architecture: Main + Overlay separation with UpdateLevel filtering, achieves stable 180fps with low jitter on 200Hz displays
  • v0.6.0 Stateless indicator pipeline: MA/BOLL/EXPMA/ENE/RSI/CCI/STOCH/MOM/WMSR/KST/FASTK now use unified Calculator → Scheduler → StateStore → Renderer architecture for better performance and maintainability
  • v0.5.6 Logarithmic price axis with evenly distributed grid lines at pixel level
  • v0.5.2 Advanced drawing tools: parallel channel, regression channel, smooth top/bottom, and non-intersecting channel
  • v0.5.0 Complete drawing tool system, supporting line, rectangle, text drawing and style editing
  • v0.4 Modern UI, left toolbar, right axis optimization, TradingView-style zoom feel

📄 License

MIT

About

High-performance financial charting library with Canvas/WebGL/WebGPU hybrid rendering, delivering crisp multi-DPR visuals at 1-3ms GPU time per frame. Features plugin-based rendering and visual signal annotation. Exposes JSON semantic configuration for Agent-driven quantitative visualization. Works seamlessly across Vue, React, and Angular (soon).

Topics

Resources

Stars

22 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

839 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

High-performance financial chart library with a single-frame generation time of just 2ms, stable scrolling at 190–200fps in a 200Hz environment, native support for AI Agent control, full-link ResizeObserver-driven crisp rendering, and a pluggable architecture.

English | 简体中文

📈 KLineChartQuant

Crisp Rendering · High Performance · Optimized Interaction · Mobile-Friendly

npm versionnpm downloadslicensedemo

qqtg


A lightweight financial K-line charting library focused on quantitative trading scenarios. Agent is a first-class citizen — supports AI Agent direct control of chart operations, providing TradingView-level interaction experience.




✨ Core Features

  • Agent First / MCP Native - Supports AI Agent direct control of charts via the Model Context Protocol. Built-in WebSocket-bridged MCP server enables any MCP client (Inspector, Claude Desktop, Cursor, etc.) to zoom, pan, add/remove indicators, and change theme in real time
  • Crisp Rendering - Full-chain ResizeObserver driven, physical pixel alignment, K-lines, wicks, and lines are sharp and clear on all DPR screens
  • Plugin Architecture - Renderer plugin-based design, supporting dynamic registration, configuration, and lifecycle management
  • Custom Markers - Supports semantic configuration of custom markers and custom information
  • High Performance - Smoothly handles tens of thousands of data points, no lag during zoom or pan; supports 190-200fps on 200Hz displays with single-frame generation time as low as 2ms
  • Multi-Backend Rendering - Submit drawing primitives once, render via WebGPU, WebGL, or Canvas2D. WebGPU provides hybrid DOM canvas (no compositeTo copy), single-command-buffer-per-frame submission with 4x MSAA, and per-instance geometry caching via ResourceTable. Automatic fallback chain: WebGPU → WebGL → Canvas2D. Reaching 190fps on 200Hz displays with per-frame GPU time under 1ms
  • Optimized Interaction - Stable zoom anchor, precise crosshair cursor, smooth drag
  • Mobile-Optimized Interaction - Long-press crosshair for data exploration, tap to dismiss, slide to browse data without triggering chart scroll, gesture-based scroll mode
  • Multi-Symbol Comparison - Supports unlimited number of instruments for trend comparison
  • Multi-Source Aggregation - Supports aggregation and unification of multiple data sources
  • Batch Data Export - Select a date range and export multiple stocks' K-line data into a single CSV file, with progress indication
  • Custom Tooltip - Fully customizable tooltip via named slots (#kline-tooltip, #marker-tooltip), with engine-provided hover data, position, and styling

📐 System Architecture

KLineChartQuant is a pnpm monorepo. The framework-agnostic core engine exposes a unified ChartController (readonly signals + commands); Vue / React / Angular bindings only handle mounting, event forwarding, and reactivity bridging. AI Agents drive the chart directly through MCP over a WebSocket bridge.

flowchart TB
subgraph app["UI Layer / Framework Bindings"]
UI["UI Layer"]
VuePkg["@363045841yyt/klinechart<br/>Vue 3 components · useChart"]
ReactPkg["@363045841yyt/klinechart-react<br/>KLineChartWC (wraps Vue-built Web Component)"]
AngularPkg["@363045841yyt/klinechart-angular"]
Agent["AI Agent / MCP Client"]
AiRt["@363045841yyt/klinechart-ai-runtime"]
end
subgraph core["Core Engine @363045841yyt/klinechart-core"]
Ctl["ChartController<br/>signals + commands"]
Chart["Chart facade"]
Kernel["StateKernel<br/>Reactive SSOT"]
Data["Data Layer<br/>SeriesRepository · Buffers"]
Pipe["Rendering Pipeline<br/>FrameTransaction · Scene/Layer"]
GPU["WebGPU / WebGL2 / Canvas2D"]
Plugin["Plugin Subsystem<br/>PluginHost · RendererPlugin"]
Biz["Indicators · Markers · Drawing<br/>Timeshare · Compare · Components"]
end
subgraph conn["Market Data Backends"]
Go["GoTDX-Connecter<br/>gotdx :8080"]
Bn["GoTDX-Connecter<br/>Binance depth :8081"]
Bs["Baostock-Tradingview-Connecter<br/>BaoStock / TradingView :8000"]
end
UI --> VuePkg
UI --> ReactPkg
UI --> AngularPkg
VuePkg -->|"Web Component"| ReactPkg
Agent --> AiRt
VuePkg --> Ctl
ReactPkg --> Ctl
AngularPkg --> Ctl
AiRt -->|WebSocket / MCP| Ctl
Ctl --> Chart
Chart --> Kernel
Chart --> Data
Chart --> Pipe
Chart --> Plugin
Plugin --> Biz
Biz --> Pipe
Pipe --> GPU
Go -->|market data| Data
Bn -->|market data| Data
Bs -->|market data| Data
Kernel --> Data
Kernel --> Pipe
Loading
  • Core engine — headless chart engine + ChartController; depends on no UI framework.
  • StateKernel — single source of truth: readonly signals for reads, actions for writes, computed() for derivation, effect() for DOM side effects.
  • Rendering — submit primitives once, render via WebGPU / WebGL2 / Canvas2D with automatic fallback (WebGPU → WebGL → Canvas2D).
  • Data layer — unified SeriesRepository + incremental buffers + fetch scheduler; multi-source aggregation (gotdx / BaoStock / TradingView / mock) and Binance depth.
  • Plugin subsystem — PluginHost / HookSystem / EventBus / RendererPluginManager; indicators, markers and drawing tools plug in as Scene Layers.
  • React via Web Component@363045841yyt/klinechart-react's KLineChartWC renders the <kline-chart> Custom Element bundled from the Vue package (@363045841yyt/klinechart/web-component).
  • MCP / Agent@363045841yyt/klinechart-ai-runtime bridges AI tool calls to the controller over WebSocket.

See docs/architecture.md for the full architecture document.

📡 Data Sources

KLineChart requires a market data backend. Supported data sources:

Data SourceDescriptionDocs
gotdxTongdaxin (GOTDX) quotes: A-share / futures / MAC, served by GoTDX-ConnecterGoTDX-Connecter
baostockBaoStock A-share daily / weekly / monthly & minute K-lines, served by Baostock-Tradingview-ConnecterBaoStock
tradingviewTradingView global instruments, served by Baostock-Tradingview-ConnecterBaoStock
mockDebug only: local MOCK-100 / MOCK-10000 K-lines, no backend needed, always online

Backend repos live alongside this one (outside the monorepo).

One-Command Dev Startup

Clone the data-source backends first (idempotent: skips directories that already exist):

pnpm setup

Then run pnpm dev with a -c argument to start the frontend and the selected connecters together:

pnpm dev # frontend only (Vite dev server)
pnpm dev -c all # frontend + all backends (gotdx + binance + baostock)
pnpm dev -c gotdx baostock # frontend + selected backends
pnpm dev -c tdx # aliases supported (tdx / g / b / bnb / all)
pnpm dev -c all --lan # same, dev server bound to 0.0.0.0 (LAN accessible)

Common shorthands:

pnpm dev:all # frontend + all backends
pnpm dev:g # frontend + gotdx (Tongdaxin)
pnpm dev:b # frontend + BaoStock / TradingView
pnpm dev:bnb # frontend + Binance depth
pnpm dev:lan:all # frontend (0.0.0.0) + all backends

Parallel process logs stay in one terminal and are separated by colored source prefixes: [vite], [gotdx], [binance], and [baostock].

Backend only (no frontend):

pnpm connecter # all backends
pnpm connecter gotdx # gotdx (Tongdaxin) :8080
pnpm connecter baostock # BaoStock / TradingView :8000

After pnpm setup, no extra setup is needed. The dev server proxies /api/stock:8000 (Baostock-Tradingview-Connecter) and /api/public:8080 (GoTDX-Connecter).

🚀 Quick Start

3. Install and Use

npm install @363045841yyt/klinechart @363045841yyt/klinechart-core

Use the component:

<template>
<divclass="app-container":data-theme="currentTheme">
<KlineChartv-model:theme="currentTheme" :custom-data="customData" :settings="chartSettings" />
</div>
</template>
<script setup lang="ts">import { ref } from'vue'importtype { ChartSettings } from'@363045841yyt/klinechart-core'import { typeCustomDataSource, KlineChart } from'@363045841yyt/klinechart'importdemoDatafrom'./demo-data.json'const currentTheme =ref<'light'|'dark'>('dark')const customData =ref<CustomDataSource>(demoDataasCustomDataSource)const chartSettings:ChartSettings= { showGridLines: true, isAsiaMarket: true, showVolumePriceMarkers: false, mainLeftAxisDisplaySetting: 'none', theme: 'dark', colorPresetSettings: { dark: { candleUpBody: '#e85d04', candleDownBody: '#1b4332', crosshairLine: '#faa307', gridMajor: '#3e2723', }, }, }</script>
<style>.app-container {display: flex;flex-direction: column;height: 80vh; }.app-container[data-theme='dark'] {background: #000;color: #e5e7eb; }</style>

Import CSS in main.ts:

import'@363045841yyt/klinechart/style.css'import{createApp}from'vue'importAppfrom'./App.vue'createApp(App).mount('#app')

Slot Usage — Custom Tooltip:

<KlineChart><template#kline-tooltip="{ hoverData, upColor, downColor }"><divclass="custom-tooltip"><divclass="custom-tooltip__title"><span>{{ hoverData.stockCode }}</span><span>{{ formatTimestamp(hoverData.timestamp, { timeZone: 'Asia/Shanghai' }) }}</span></div><divclass="custom-tooltip__price"
:style="{ color: hoverData.close >= hoverData.open ? upColor : downColor }"
>
{{ hoverData.close.toFixed(2) }}
</div><divclass="custom-tooltip__detail">
O: {{ hoverData.open.toFixed(2) }}<br/>
H: {{ hoverData.high.toFixed(2) }}<br/>
L: {{ hoverData.low.toFixed(2) }}<br/>
C: {{ hoverData.close.toFixed(2) }}
</div></div></template></KlineChart>

Slot Usage — Custom Main-Pane Legend:

Providing #legend fully replaces the default Canvas legend. The slot scope is the full LegendTemplateContext (OHLC, timeshare, main indicators, comparisons, layout, colors).

<template #legend="{ index, currentBar, timeshare, indicators, comparisons, colors }">
<divclass="my-legend">
<!-- Custom fields added to KLineData[] for PR #98 are exposed through currentBar -->
<divv-if="currentBar"class="my-legend__row">
<span:style="{ color: currentBar.color }">
开盘 {{ currentBar.open.toFixed(2) }} 最高 {{ currentBar.high.toFixed(2) }} 最低
{{ currentBar.low.toFixed(2) }} 收盘 {{ currentBar.close.toFixed(2) }}
</span>
<spanv-if="currentBar.volumeText"> Vol {{ currentBar.volumeText }}</span>
</div>
<divv-if="timeshare"class="my-legend__row">
<span:style="{ color: timeshare.changeColor }">
现价 {{ timeshare.price.toFixed(2) }} 涨幅 {{ timeshare.changePercent.toFixed(2) }}%
</span>
</div>
<!-- Using main chart indicator legend data -->
<divv-for="indicator in indicators":key="indicator.name"class="my-legend__row">
<span>{{ indicator.name }}:</span>
<templatev-for="valueinindicator.values" :key="value.label">
<span:style="{ color: value.color }">
{{ value.label }} {{ value.value.toFixed(3) }}
</span>
</template>
</div>
<!-- Using comparison commodity data -->
<divv-for="comparison in comparisons":key="comparison.symbol"class="my-legend__row":style="{ color: comparison.percentColor }"
>
{{ comparison.symbol }}
{{ comparison.percent > 0 ? '+' : '' }}{{ comparison.percent.toFixed(2) }}%
</div>
</div>
</template>

4. (Optional) Enable MCP / AI Agent Control

npm install @363045841yyt/klinechart-ai-runtime
<template>
<divclass="app-container">
<KlineChart ref="chartRef" :mcp="mcpConfig" />
</div>
</template>
<script setup lang="ts">import { ref } from'vue'import { KlineChart } from'@363045841yyt/klinechart'import { executeTool } from'@363045841yyt/klinechart-ai-runtime'const chartRef =ref<InstanceType<typeofKlineChart> |null>(null)const mcpConfig = { wsUrl: 'ws://localhost:8080', autoReconnect: true,onToolCall: (call) => {const ctrl =chartRef.value?.getController?.()if (!ctrl) return { success: false, error: 'Controller not ready' }returnexecuteTool(ctrl, call) }, }</script>
<style>.app-container {height: 80vh; }</style>

Then start the MCP server:

cd packages/ai-runtime
pnpm inspect

Connect via MCP Inspector and call chart.zoomToLevel, indicators.add, etc.

📖 More Documentation

📋 Component Props

PropTypeDefaultDescription
semanticConfigSemanticChartConfigSemantic configuration (optional). When provided, drives chart data, indicators, markers and chart options
theme'light' | 'dark'Chart theme. Use v-model:theme for two-way binding
isFullscreenbooleanControlled fullscreen state. Leave unbound for internal (non-controlled) mode
timezonestring'Asia/Shanghai'Time zone for date/time display
yPaddingPxnumber20Y-axis padding in pixels
minKWidthnumber1Minimum K-line width (logical pixels)
maxKWidthnumber50Maximum K-line width (logical pixels)
rightAxisWidthnumber0Right price axis width
leftAxisWidthnumber0Left price axis width (0 = hidden)
bottomAxisHeightnumber24Bottom time axis height
priceLabelWidthnumber60Price label extra width for showing change percentage
zoomLevelsnumber20Total number of zoom levels
initialZoomLevelnumber3Initial zoom level (1 ~ zoomLevels)
customDataCustomDataSourceInline data bundle: { symbol?, period?, data, comparisons? }. Bypasses the fetcher pipeline entirely. See example above
teleportContainerstring | HTMLElementTeleport target for dropdowns/modals (CSS selector or element). Defaults to internal .chart-wrapper
mcpMcpConfigMCP/AI runtime bridge config: { wsUrl?, autoReconnect?, onToolCall? }. See @363045841yyt/klinechart-ai-runtime

🗺️ Roadmap

  • v0.10: AI-native chart support
  • K-line zoom anchor stability, improved zoom feel
  • Right axis detached from scroll container, completely solving clipping issues
  • Blank area drawing support
  • Limit vertical pan range to prevent viewport from leaving data
  • Drawing system
  • Right axis zoom
  • Latest price line and right axis label style optimization
  • Area primitive tools and rendering
  • More advanced drawing tools
  • Support for minute, multi-day, monthly, and yearly K-line display
  • Support convert the drawing to quant code

📦 Packages

PackageDescriptionnpm
@363045841yyt/klinechart-coreHeadless chart engine + controllersnpm
@363045841yyt/klinechartVue 3 bindingsnpm
@363045841yyt/klinechart-reactReact bindingsnpm
@363045841yyt/klinechart-angularAngular bindingsnpm
@363045841yyt/klinechart-ai-runtimeMCP server + AI tool schemas (optional)npm

🚀 What's New

  • v0.9.0 Self-developed Core-layer reactive state model migration, timing issues eliminated
  • v0.9.0 Single-path Scene renderer + WebGPU backend (hybrid DOM canvas, no compositeTo), FrameTransaction reactivity, device-lost recovery, auto-fallback WebGPU → WebGL → Canvas2D
  • v0.8 Symbol comparison, multi-source data aggregation
  • v0.7 Renderer registration chain AOP refactoring with decorator syntax, monorepo split, Vue/React bindings (experimental), standalone core package, tokenized color system
  • v0.6.10 Unified WebGL rendering context sharing for all panes, plus sub-pane lifecycle refactoring — centralized pane instance management via SubPaneManager with first-class paneId identity
  • v0.6.6 Comprehensive rendering optimizations: batched price-to-Y calculations, cached tick positions and geometry, optimized month-key operations; achieves stable 190-200fps on 200Hz displays with frame generation time down to 2ms
  • v0.6.3 WebGL rendering for K-lines, volume bars, and MACD bars; significant performance boost across the board
  • v0.6.1 Dual-layer canvas architecture: Main + Overlay separation with UpdateLevel filtering, achieves stable 180fps with low jitter on 200Hz displays
  • v0.6.0 Stateless indicator pipeline: MA/BOLL/EXPMA/ENE/RSI/CCI/STOCH/MOM/WMSR/KST/FASTK now use unified Calculator → Scheduler → StateStore → Renderer architecture for better performance and maintainability
  • v0.5.6 Logarithmic price axis with evenly distributed grid lines at pixel level
  • v0.5.2 Advanced drawing tools: parallel channel, regression channel, smooth top/bottom, and non-intersecting channel
  • v0.5.0 Complete drawing tool system, supporting line, rectangle, text drawing and style editing
  • v0.4 Modern UI, left toolbar, right axis optimization, TradingView-style zoom feel

📄 License

MIT

About

High-performance financial charting library with Canvas/WebGL/WebGPU hybrid rendering, delivering crisp multi-DPR visuals at 1-3ms GPU time per frame. Features plugin-based rendering and visual signal annotation. Exposes JSON semantic configuration for Agent-driven quantitative visualization. Works seamlessly across Vue, React, and Angular (soon).

Topics

Resources

Stars

22 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

839 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

High-performance financial chart library with a single-frame generation time of just 2ms, stable scrolling at 190–200fps in a 200Hz environment, native support for AI Agent control, full-link ResizeObserver-driven crisp rendering, and a pluggable architecture.

English | 简体中文

📈 KLineChartQuant

Crisp Rendering · High Performance · Optimized Interaction · Mobile-Friendly

npm versionnpm downloadslicensedemo

qqtg


A lightweight financial K-line charting library focused on quantitative trading scenarios. Agent is a first-class citizen — supports AI Agent direct control of chart operations, providing TradingView-level interaction experience.




✨ Core Features

  • Agent First / MCP Native - Supports AI Agent direct control of charts via the Model Context Protocol. Built-in WebSocket-bridged MCP server enables any MCP client (Inspector, Claude Desktop, Cursor, etc.) to zoom, pan, add/remove indicators, and change theme in real time
  • Crisp Rendering - Full-chain ResizeObserver driven, physical pixel alignment, K-lines, wicks, and lines are sharp and clear on all DPR screens
  • Plugin Architecture - Renderer plugin-based design, supporting dynamic registration, configuration, and lifecycle management
  • Custom Markers - Supports semantic configuration of custom markers and custom information
  • High Performance - Smoothly handles tens of thousands of data points, no lag during zoom or pan; supports 190-200fps on 200Hz displays with single-frame generation time as low as 2ms
  • Multi-Backend Rendering - Submit drawing primitives once, render via WebGPU, WebGL, or Canvas2D. WebGPU provides hybrid DOM canvas (no compositeTo copy), single-command-buffer-per-frame submission with 4x MSAA, and per-instance geometry caching via ResourceTable. Automatic fallback chain: WebGPU → WebGL → Canvas2D. Reaching 190fps on 200Hz displays with per-frame GPU time under 1ms
  • Optimized Interaction - Stable zoom anchor, precise crosshair cursor, smooth drag
  • Mobile-Optimized Interaction - Long-press crosshair for data exploration, tap to dismiss, slide to browse data without triggering chart scroll, gesture-based scroll mode
  • Multi-Symbol Comparison - Supports unlimited number of instruments for trend comparison
  • Multi-Source Aggregation - Supports aggregation and unification of multiple data sources
  • Batch Data Export - Select a date range and export multiple stocks' K-line data into a single CSV file, with progress indication
  • Custom Tooltip - Fully customizable tooltip via named slots (#kline-tooltip, #marker-tooltip), with engine-provided hover data, position, and styling

📐 System Architecture

KLineChartQuant is a pnpm monorepo. The framework-agnostic core engine exposes a unified ChartController (readonly signals + commands); Vue / React / Angular bindings only handle mounting, event forwarding, and reactivity bridging. AI Agents drive the chart directly through MCP over a WebSocket bridge.

flowchart TB
subgraph app["UI Layer / Framework Bindings"]
UI["UI Layer"]
VuePkg["@363045841yyt/klinechart<br/>Vue 3 components · useChart"]
ReactPkg["@363045841yyt/klinechart-react<br/>KLineChartWC (wraps Vue-built Web Component)"]
AngularPkg["@363045841yyt/klinechart-angular"]
Agent["AI Agent / MCP Client"]
AiRt["@363045841yyt/klinechart-ai-runtime"]
end
subgraph core["Core Engine @363045841yyt/klinechart-core"]
Ctl["ChartController<br/>signals + commands"]
Chart["Chart facade"]
Kernel["StateKernel<br/>Reactive SSOT"]
Data["Data Layer<br/>SeriesRepository · Buffers"]
Pipe["Rendering Pipeline<br/>FrameTransaction · Scene/Layer"]
GPU["WebGPU / WebGL2 / Canvas2D"]
Plugin["Plugin Subsystem<br/>PluginHost · RendererPlugin"]
Biz["Indicators · Markers · Drawing<br/>Timeshare · Compare · Components"]
end
subgraph conn["Market Data Backends"]
Go["GoTDX-Connecter<br/>gotdx :8080"]
Bn["GoTDX-Connecter<br/>Binance depth :8081"]
Bs["Baostock-Tradingview-Connecter<br/>BaoStock / TradingView :8000"]
end
UI --> VuePkg
UI --> ReactPkg
UI --> AngularPkg
VuePkg -->|"Web Component"| ReactPkg
Agent --> AiRt
VuePkg --> Ctl
ReactPkg --> Ctl
AngularPkg --> Ctl
AiRt -->|WebSocket / MCP| Ctl
Ctl --> Chart
Chart --> Kernel
Chart --> Data
Chart --> Pipe
Chart --> Plugin
Plugin --> Biz
Biz --> Pipe
Pipe --> GPU
Go -->|market data| Data
Bn -->|market data| Data
Bs -->|market data| Data
Kernel --> Data
Kernel --> Pipe
Loading
  • Core engine — headless chart engine + ChartController; depends on no UI framework.
  • StateKernel — single source of truth: readonly signals for reads, actions for writes, computed() for derivation, effect() for DOM side effects.
  • Rendering — submit primitives once, render via WebGPU / WebGL2 / Canvas2D with automatic fallback (WebGPU → WebGL → Canvas2D).
  • Data layer — unified SeriesRepository + incremental buffers + fetch scheduler; multi-source aggregation (gotdx / BaoStock / TradingView / mock) and Binance depth.
  • Plugin subsystem — PluginHost / HookSystem / EventBus / RendererPluginManager; indicators, markers and drawing tools plug in as Scene Layers.
  • React via Web Component@363045841yyt/klinechart-react's KLineChartWC renders the <kline-chart> Custom Element bundled from the Vue package (@363045841yyt/klinechart/web-component).
  • MCP / Agent@363045841yyt/klinechart-ai-runtime bridges AI tool calls to the controller over WebSocket.

See docs/architecture.md for the full architecture document.

📡 Data Sources

KLineChart requires a market data backend. Supported data sources:

Data SourceDescriptionDocs
gotdxTongdaxin (GOTDX) quotes: A-share / futures / MAC, served by GoTDX-ConnecterGoTDX-Connecter
baostockBaoStock A-share daily / weekly / monthly & minute K-lines, served by Baostock-Tradingview-ConnecterBaoStock
tradingviewTradingView global instruments, served by Baostock-Tradingview-ConnecterBaoStock
mockDebug only: local MOCK-100 / MOCK-10000 K-lines, no backend needed, always online

Backend repos live alongside this one (outside the monorepo).

One-Command Dev Startup

Clone the data-source backends first (idempotent: skips directories that already exist):

pnpm setup

Then run pnpm dev with a -c argument to start the frontend and the selected connecters together:

pnpm dev # frontend only (Vite dev server)
pnpm dev -c all # frontend + all backends (gotdx + binance + baostock)
pnpm dev -c gotdx baostock # frontend + selected backends
pnpm dev -c tdx # aliases supported (tdx / g / b / bnb / all)
pnpm dev -c all --lan # same, dev server bound to 0.0.0.0 (LAN accessible)

Common shorthands:

pnpm dev:all # frontend + all backends
pnpm dev:g # frontend + gotdx (Tongdaxin)
pnpm dev:b # frontend + BaoStock / TradingView
pnpm dev:bnb # frontend + Binance depth
pnpm dev:lan:all # frontend (0.0.0.0) + all backends

Parallel process logs stay in one terminal and are separated by colored source prefixes: [vite], [gotdx], [binance], and [baostock].

Backend only (no frontend):

pnpm connecter # all backends
pnpm connecter gotdx # gotdx (Tongdaxin) :8080
pnpm connecter baostock # BaoStock / TradingView :8000

After pnpm setup, no extra setup is needed. The dev server proxies /api/stock:8000 (Baostock-Tradingview-Connecter) and /api/public:8080 (GoTDX-Connecter).

🚀 Quick Start

3. Install and Use

npm install @363045841yyt/klinechart @363045841yyt/klinechart-core

Use the component:

<template>
<divclass="app-container":data-theme="currentTheme">
<KlineChartv-model:theme="currentTheme" :custom-data="customData" :settings="chartSettings" />
</div>
</template>
<script setup lang="ts">import { ref } from'vue'importtype { ChartSettings } from'@363045841yyt/klinechart-core'import { typeCustomDataSource, KlineChart } from'@363045841yyt/klinechart'importdemoDatafrom'./demo-data.json'const currentTheme =ref<'light'|'dark'>('dark')const customData =ref<CustomDataSource>(demoDataasCustomDataSource)const chartSettings:ChartSettings= { showGridLines: true, isAsiaMarket: true, showVolumePriceMarkers: false, mainLeftAxisDisplaySetting: 'none', theme: 'dark', colorPresetSettings: { dark: { candleUpBody: '#e85d04', candleDownBody: '#1b4332', crosshairLine: '#faa307', gridMajor: '#3e2723', }, }, }</script>
<style>.app-container {display: flex;flex-direction: column;height: 80vh; }.app-container[data-theme='dark'] {background: #000;color: #e5e7eb; }</style>

Import CSS in main.ts:

import'@363045841yyt/klinechart/style.css'import{createApp}from'vue'importAppfrom'./App.vue'createApp(App).mount('#app')

Slot Usage — Custom Tooltip:

<KlineChart><template#kline-tooltip="{ hoverData, upColor, downColor }"><divclass="custom-tooltip"><divclass="custom-tooltip__title"><span>{{ hoverData.stockCode }}</span><span>{{ formatTimestamp(hoverData.timestamp, { timeZone: 'Asia/Shanghai' }) }}</span></div><divclass="custom-tooltip__price"
:style="{ color: hoverData.close >= hoverData.open ? upColor : downColor }"
>
{{ hoverData.close.toFixed(2) }}
</div><divclass="custom-tooltip__detail">
O: {{ hoverData.open.toFixed(2) }}<br/>
H: {{ hoverData.high.toFixed(2) }}<br/>
L: {{ hoverData.low.toFixed(2) }}<br/>
C: {{ hoverData.close.toFixed(2) }}
</div></div></template></KlineChart>

Slot Usage — Custom Main-Pane Legend:

Providing #legend fully replaces the default Canvas legend. The slot scope is the full LegendTemplateContext (OHLC, timeshare, main indicators, comparisons, layout, colors).

<template #legend="{ index, currentBar, timeshare, indicators, comparisons, colors }">
<divclass="my-legend">
<!-- Custom fields added to KLineData[] for PR #98 are exposed through currentBar -->
<divv-if="currentBar"class="my-legend__row">
<span:style="{ color: currentBar.color }">
开盘 {{ currentBar.open.toFixed(2) }} 最高 {{ currentBar.high.toFixed(2) }} 最低
{{ currentBar.low.toFixed(2) }} 收盘 {{ currentBar.close.toFixed(2) }}
</span>
<spanv-if="currentBar.volumeText"> Vol {{ currentBar.volumeText }}</span>
</div>
<divv-if="timeshare"class="my-legend__row">
<span:style="{ color: timeshare.changeColor }">
现价 {{ timeshare.price.toFixed(2) }} 涨幅 {{ timeshare.changePercent.toFixed(2) }}%
</span>
</div>
<!-- Using main chart indicator legend data -->
<divv-for="indicator in indicators":key="indicator.name"class="my-legend__row">
<span>{{ indicator.name }}:</span>
<templatev-for="valueinindicator.values" :key="value.label">
<span:style="{ color: value.color }">
{{ value.label }} {{ value.value.toFixed(3) }}
</span>
</template>
</div>
<!-- Using comparison commodity data -->
<divv-for="comparison in comparisons":key="comparison.symbol"class="my-legend__row":style="{ color: comparison.percentColor }"
>
{{ comparison.symbol }}
{{ comparison.percent > 0 ? '+' : '' }}{{ comparison.percent.toFixed(2) }}%
</div>
</div>
</template>

4. (Optional) Enable MCP / AI Agent Control

npm install @363045841yyt/klinechart-ai-runtime
<template>
<divclass="app-container">
<KlineChart ref="chartRef" :mcp="mcpConfig" />
</div>
</template>
<script setup lang="ts">import { ref } from'vue'import { KlineChart } from'@363045841yyt/klinechart'import { executeTool } from'@363045841yyt/klinechart-ai-runtime'const chartRef =ref<InstanceType<typeofKlineChart> |null>(null)const mcpConfig = { wsUrl: 'ws://localhost:8080', autoReconnect: true,onToolCall: (call) => {const ctrl =chartRef.value?.getController?.()if (!ctrl) return { success: false, error: 'Controller not ready' }returnexecuteTool(ctrl, call) }, }</script>
<style>.app-container {height: 80vh; }</style>

Then start the MCP server:

cd packages/ai-runtime
pnpm inspect

Connect via MCP Inspector and call chart.zoomToLevel, indicators.add, etc.

📖 More Documentation

📋 Component Props

PropTypeDefaultDescription
semanticConfigSemanticChartConfigSemantic configuration (optional). When provided, drives chart data, indicators, markers and chart options
theme'light' | 'dark'Chart theme. Use v-model:theme for two-way binding
isFullscreenbooleanControlled fullscreen state. Leave unbound for internal (non-controlled) mode
timezonestring'Asia/Shanghai'Time zone for date/time display
yPaddingPxnumber20Y-axis padding in pixels
minKWidthnumber1Minimum K-line width (logical pixels)
maxKWidthnumber50Maximum K-line width (logical pixels)
rightAxisWidthnumber0Right price axis width
leftAxisWidthnumber0Left price axis width (0 = hidden)
bottomAxisHeightnumber24Bottom time axis height
priceLabelWidthnumber60Price label extra width for showing change percentage
zoomLevelsnumber20Total number of zoom levels
initialZoomLevelnumber3Initial zoom level (1 ~ zoomLevels)
customDataCustomDataSourceInline data bundle: { symbol?, period?, data, comparisons? }. Bypasses the fetcher pipeline entirely. See example above
teleportContainerstring | HTMLElementTeleport target for dropdowns/modals (CSS selector or element). Defaults to internal .chart-wrapper
mcpMcpConfigMCP/AI runtime bridge config: { wsUrl?, autoReconnect?, onToolCall? }. See @363045841yyt/klinechart-ai-runtime

🗺️ Roadmap

  • v0.10: AI-native chart support
  • K-line zoom anchor stability, improved zoom feel
  • Right axis detached from scroll container, completely solving clipping issues
  • Blank area drawing support
  • Limit vertical pan range to prevent viewport from leaving data
  • Drawing system
  • Right axis zoom
  • Latest price line and right axis label style optimization
  • Area primitive tools and rendering
  • More advanced drawing tools
  • Support for minute, multi-day, monthly, and yearly K-line display
  • Support convert the drawing to quant code

📦 Packages

PackageDescriptionnpm
@363045841yyt/klinechart-coreHeadless chart engine + controllersnpm
@363045841yyt/klinechartVue 3 bindingsnpm
@363045841yyt/klinechart-reactReact bindingsnpm
@363045841yyt/klinechart-angularAngular bindingsnpm
@363045841yyt/klinechart-ai-runtimeMCP server + AI tool schemas (optional)npm

🚀 What's New

  • v0.9.0 Self-developed Core-layer reactive state model migration, timing issues eliminated
  • v0.9.0 Single-path Scene renderer + WebGPU backend (hybrid DOM canvas, no compositeTo), FrameTransaction reactivity, device-lost recovery, auto-fallback WebGPU → WebGL → Canvas2D
  • v0.8 Symbol comparison, multi-source data aggregation
  • v0.7 Renderer registration chain AOP refactoring with decorator syntax, monorepo split, Vue/React bindings (experimental), standalone core package, tokenized color system
  • v0.6.10 Unified WebGL rendering context sharing for all panes, plus sub-pane lifecycle refactoring — centralized pane instance management via SubPaneManager with first-class paneId identity
  • v0.6.6 Comprehensive rendering optimizations: batched price-to-Y calculations, cached tick positions and geometry, optimized month-key operations; achieves stable 190-200fps on 200Hz displays with frame generation time down to 2ms
  • v0.6.3 WebGL rendering for K-lines, volume bars, and MACD bars; significant performance boost across the board
  • v0.6.1 Dual-layer canvas architecture: Main + Overlay separation with UpdateLevel filtering, achieves stable 180fps with low jitter on 200Hz displays
  • v0.6.0 Stateless indicator pipeline: MA/BOLL/EXPMA/ENE/RSI/CCI/STOCH/MOM/WMSR/KST/FASTK now use unified Calculator → Scheduler → StateStore → Renderer architecture for better performance and maintainability
  • v0.5.6 Logarithmic price axis with evenly distributed grid lines at pixel level
  • v0.5.2 Advanced drawing tools: parallel channel, regression channel, smooth top/bottom, and non-intersecting channel
  • v0.5.0 Complete drawing tool system, supporting line, rectangle, text drawing and style editing
  • v0.4 Modern UI, left toolbar, right axis optimization, TradingView-style zoom feel

📄 License

MIT

About

High-performance financial charting library with Canvas/WebGL/WebGPU hybrid rendering, delivering crisp multi-DPR visuals at 1-3ms GPU time per frame. Features plugin-based rendering and visual signal annotation. Exposes JSON semantic configuration for Agent-driven quantitative visualization. Works seamlessly across Vue, React, and Angular (soon).

Topics

Resources

Stars

22 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

839 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

High-performance financial chart library with a single-frame generation time of just 2ms, stable scrolling at 190–200fps in a 200Hz environment, native support for AI Agent control, full-link ResizeObserver-driven crisp rendering, and a pluggable architecture.

English | 简体中文

📈 KLineChartQuant

Crisp Rendering · High Performance · Optimized Interaction · Mobile-Friendly

npm versionnpm downloadslicensedemo

qqtg


A lightweight financial K-line charting library focused on quantitative trading scenarios. Agent is a first-class citizen — supports AI Agent direct control of chart operations, providing TradingView-level interaction experience.




✨ Core Features

  • Agent First / MCP Native - Supports AI Agent direct control of charts via the Model Context Protocol. Built-in WebSocket-bridged MCP server enables any MCP client (Inspector, Claude Desktop, Cursor, etc.) to zoom, pan, add/remove indicators, and change theme in real time
  • Crisp Rendering - Full-chain ResizeObserver driven, physical pixel alignment, K-lines, wicks, and lines are sharp and clear on all DPR screens
  • Plugin Architecture - Renderer plugin-based design, supporting dynamic registration, configuration, and lifecycle management
  • Custom Markers - Supports semantic configuration of custom markers and custom information
  • High Performance - Smoothly handles tens of thousands of data points, no lag during zoom or pan; supports 190-200fps on 200Hz displays with single-frame generation time as low as 2ms
  • Multi-Backend Rendering - Submit drawing primitives once, render via WebGPU, WebGL, or Canvas2D. WebGPU provides hybrid DOM canvas (no compositeTo copy), single-command-buffer-per-frame submission with 4x MSAA, and per-instance geometry caching via ResourceTable. Automatic fallback chain: WebGPU → WebGL → Canvas2D. Reaching 190fps on 200Hz displays with per-frame GPU time under 1ms
  • Optimized Interaction - Stable zoom anchor, precise crosshair cursor, smooth drag
  • Mobile-Optimized Interaction - Long-press crosshair for data exploration, tap to dismiss, slide to browse data without triggering chart scroll, gesture-based scroll mode
  • Multi-Symbol Comparison - Supports unlimited number of instruments for trend comparison
  • Multi-Source Aggregation - Supports aggregation and unification of multiple data sources
  • Batch Data Export - Select a date range and export multiple stocks' K-line data into a single CSV file, with progress indication
  • Custom Tooltip - Fully customizable tooltip via named slots (#kline-tooltip, #marker-tooltip), with engine-provided hover data, position, and styling

📐 System Architecture

KLineChartQuant is a pnpm monorepo. The framework-agnostic core engine exposes a unified ChartController (readonly signals + commands); Vue / React / Angular bindings only handle mounting, event forwarding, and reactivity bridging. AI Agents drive the chart directly through MCP over a WebSocket bridge.

flowchart TB
subgraph app["UI Layer / Framework Bindings"]
UI["UI Layer"]
VuePkg["@363045841yyt/klinechart<br/>Vue 3 components · useChart"]
ReactPkg["@363045841yyt/klinechart-react<br/>KLineChartWC (wraps Vue-built Web Component)"]
AngularPkg["@363045841yyt/klinechart-angular"]
Agent["AI Agent / MCP Client"]
AiRt["@363045841yyt/klinechart-ai-runtime"]
end
subgraph core["Core Engine @363045841yyt/klinechart-core"]
Ctl["ChartController<br/>signals + commands"]
Chart["Chart facade"]
Kernel["StateKernel<br/>Reactive SSOT"]
Data["Data Layer<br/>SeriesRepository · Buffers"]
Pipe["Rendering Pipeline<br/>FrameTransaction · Scene/Layer"]
GPU["WebGPU / WebGL2 / Canvas2D"]
Plugin["Plugin Subsystem<br/>PluginHost · RendererPlugin"]
Biz["Indicators · Markers · Drawing<br/>Timeshare · Compare · Components"]
end
subgraph conn["Market Data Backends"]
Go["GoTDX-Connecter<br/>gotdx :8080"]
Bn["GoTDX-Connecter<br/>Binance depth :8081"]
Bs["Baostock-Tradingview-Connecter<br/>BaoStock / TradingView :8000"]
end
UI --> VuePkg
UI --> ReactPkg
UI --> AngularPkg
VuePkg -->|"Web Component"| ReactPkg
Agent --> AiRt
VuePkg --> Ctl
ReactPkg --> Ctl
AngularPkg --> Ctl
AiRt -->|WebSocket / MCP| Ctl
Ctl --> Chart
Chart --> Kernel
Chart --> Data
Chart --> Pipe
Chart --> Plugin
Plugin --> Biz
Biz --> Pipe
Pipe --> GPU
Go -->|market data| Data
Bn -->|market data| Data
Bs -->|market data| Data
Kernel --> Data
Kernel --> Pipe
Loading
  • Core engine — headless chart engine + ChartController; depends on no UI framework.
  • StateKernel — single source of truth: readonly signals for reads, actions for writes, computed() for derivation, effect() for DOM side effects.
  • Rendering — submit primitives once, render via WebGPU / WebGL2 / Canvas2D with automatic fallback (WebGPU → WebGL → Canvas2D).
  • Data layer — unified SeriesRepository + incremental buffers + fetch scheduler; multi-source aggregation (gotdx / BaoStock / TradingView / mock) and Binance depth.
  • Plugin subsystem — PluginHost / HookSystem / EventBus / RendererPluginManager; indicators, markers and drawing tools plug in as Scene Layers.
  • React via Web Component@363045841yyt/klinechart-react's KLineChartWC renders the <kline-chart> Custom Element bundled from the Vue package (@363045841yyt/klinechart/web-component).
  • MCP / Agent@363045841yyt/klinechart-ai-runtime bridges AI tool calls to the controller over WebSocket.

See docs/architecture.md for the full architecture document.

📡 Data Sources

KLineChart requires a market data backend. Supported data sources:

Data SourceDescriptionDocs
gotdxTongdaxin (GOTDX) quotes: A-share / futures / MAC, served by GoTDX-ConnecterGoTDX-Connecter
baostockBaoStock A-share daily / weekly / monthly & minute K-lines, served by Baostock-Tradingview-ConnecterBaoStock
tradingviewTradingView global instruments, served by Baostock-Tradingview-ConnecterBaoStock
mockDebug only: local MOCK-100 / MOCK-10000 K-lines, no backend needed, always online

Backend repos live alongside this one (outside the monorepo).

One-Command Dev Startup

Clone the data-source backends first (idempotent: skips directories that already exist):

pnpm setup

Then run pnpm dev with a -c argument to start the frontend and the selected connecters together:

pnpm dev # frontend only (Vite dev server)
pnpm dev -c all # frontend + all backends (gotdx + binance + baostock)
pnpm dev -c gotdx baostock # frontend + selected backends
pnpm dev -c tdx # aliases supported (tdx / g / b / bnb / all)
pnpm dev -c all --lan # same, dev server bound to 0.0.0.0 (LAN accessible)

Common shorthands:

pnpm dev:all # frontend + all backends
pnpm dev:g # frontend + gotdx (Tongdaxin)
pnpm dev:b # frontend + BaoStock / TradingView
pnpm dev:bnb # frontend + Binance depth
pnpm dev:lan:all # frontend (0.0.0.0) + all backends

Parallel process logs stay in one terminal and are separated by colored source prefixes: [vite], [gotdx], [binance], and [baostock].

Backend only (no frontend):

pnpm connecter # all backends
pnpm connecter gotdx # gotdx (Tongdaxin) :8080
pnpm connecter baostock # BaoStock / TradingView :8000

After pnpm setup, no extra setup is needed. The dev server proxies /api/stock:8000 (Baostock-Tradingview-Connecter) and /api/public:8080 (GoTDX-Connecter).

🚀 Quick Start

3. Install and Use

npm install @363045841yyt/klinechart @363045841yyt/klinechart-core

Use the component:

<template>
<divclass="app-container":data-theme="currentTheme">
<KlineChartv-model:theme="currentTheme" :custom-data="customData" :settings="chartSettings" />
</div>
</template>
<script setup lang="ts">import { ref } from'vue'importtype { ChartSettings } from'@363045841yyt/klinechart-core'import { typeCustomDataSource, KlineChart } from'@363045841yyt/klinechart'importdemoDatafrom'./demo-data.json'const currentTheme =ref<'light'|'dark'>('dark')const customData =ref<CustomDataSource>(demoDataasCustomDataSource)const chartSettings:ChartSettings= { showGridLines: true, isAsiaMarket: true, showVolumePriceMarkers: false, mainLeftAxisDisplaySetting: 'none', theme: 'dark', colorPresetSettings: { dark: { candleUpBody: '#e85d04', candleDownBody: '#1b4332', crosshairLine: '#faa307', gridMajor: '#3e2723', }, }, }</script>
<style>.app-container {display: flex;flex-direction: column;height: 80vh; }.app-container[data-theme='dark'] {background: #000;color: #e5e7eb; }</style>

Import CSS in main.ts:

import'@363045841yyt/klinechart/style.css'import{createApp}from'vue'importAppfrom'./App.vue'createApp(App).mount('#app')

Slot Usage — Custom Tooltip:

<KlineChart><template#kline-tooltip="{ hoverData, upColor, downColor }"><divclass="custom-tooltip"><divclass="custom-tooltip__title"><span>{{ hoverData.stockCode }}</span><span>{{ formatTimestamp(hoverData.timestamp, { timeZone: 'Asia/Shanghai' }) }}</span></div><divclass="custom-tooltip__price"
:style="{ color: hoverData.close >= hoverData.open ? upColor : downColor }"
>
{{ hoverData.close.toFixed(2) }}
</div><divclass="custom-tooltip__detail">
O: {{ hoverData.open.toFixed(2) }}<br/>
H: {{ hoverData.high.toFixed(2) }}<br/>
L: {{ hoverData.low.toFixed(2) }}<br/>
C: {{ hoverData.close.toFixed(2) }}
</div></div></template></KlineChart>

Slot Usage — Custom Main-Pane Legend:

Providing #legend fully replaces the default Canvas legend. The slot scope is the full LegendTemplateContext (OHLC, timeshare, main indicators, comparisons, layout, colors).

<template #legend="{ index, currentBar, timeshare, indicators, comparisons, colors }">
<divclass="my-legend">
<!-- Custom fields added to KLineData[] for PR #98 are exposed through currentBar -->
<divv-if="currentBar"class="my-legend__row">
<span:style="{ color: currentBar.color }">
开盘 {{ currentBar.open.toFixed(2) }} 最高 {{ currentBar.high.toFixed(2) }} 最低
{{ currentBar.low.toFixed(2) }} 收盘 {{ currentBar.close.toFixed(2) }}
</span>
<spanv-if="currentBar.volumeText"> Vol {{ currentBar.volumeText }}</span>
</div>
<divv-if="timeshare"class="my-legend__row">
<span:style="{ color: timeshare.changeColor }">
现价 {{ timeshare.price.toFixed(2) }} 涨幅 {{ timeshare.changePercent.toFixed(2) }}%
</span>
</div>
<!-- Using main chart indicator legend data -->
<divv-for="indicator in indicators":key="indicator.name"class="my-legend__row">
<span>{{ indicator.name }}:</span>
<templatev-for="valueinindicator.values" :key="value.label">
<span:style="{ color: value.color }">
{{ value.label }} {{ value.value.toFixed(3) }}
</span>
</template>
</div>
<!-- Using comparison commodity data -->
<divv-for="comparison in comparisons":key="comparison.symbol"class="my-legend__row":style="{ color: comparison.percentColor }"
>
{{ comparison.symbol }}
{{ comparison.percent > 0 ? '+' : '' }}{{ comparison.percent.toFixed(2) }}%
</div>
</div>
</template>

4. (Optional) Enable MCP / AI Agent Control

npm install @363045841yyt/klinechart-ai-runtime
<template>
<divclass="app-container">
<KlineChart ref="chartRef" :mcp="mcpConfig" />
</div>
</template>
<script setup lang="ts">import { ref } from'vue'import { KlineChart } from'@363045841yyt/klinechart'import { executeTool } from'@363045841yyt/klinechart-ai-runtime'const chartRef =ref<InstanceType<typeofKlineChart> |null>(null)const mcpConfig = { wsUrl: 'ws://localhost:8080', autoReconnect: true,onToolCall: (call) => {const ctrl =chartRef.value?.getController?.()if (!ctrl) return { success: false, error: 'Controller not ready' }returnexecuteTool(ctrl, call) }, }</script>
<style>.app-container {height: 80vh; }</style>

Then start the MCP server:

cd packages/ai-runtime
pnpm inspect

Connect via MCP Inspector and call chart.zoomToLevel, indicators.add, etc.

📖 More Documentation

📋 Component Props

PropTypeDefaultDescription
semanticConfigSemanticChartConfigSemantic configuration (optional). When provided, drives chart data, indicators, markers and chart options
theme'light' | 'dark'Chart theme. Use v-model:theme for two-way binding
isFullscreenbooleanControlled fullscreen state. Leave unbound for internal (non-controlled) mode
timezonestring'Asia/Shanghai'Time zone for date/time display
yPaddingPxnumber20Y-axis padding in pixels
minKWidthnumber1Minimum K-line width (logical pixels)
maxKWidthnumber50Maximum K-line width (logical pixels)
rightAxisWidthnumber0Right price axis width
leftAxisWidthnumber0Left price axis width (0 = hidden)
bottomAxisHeightnumber24Bottom time axis height
priceLabelWidthnumber60Price label extra width for showing change percentage
zoomLevelsnumber20Total number of zoom levels
initialZoomLevelnumber3Initial zoom level (1 ~ zoomLevels)
customDataCustomDataSourceInline data bundle: { symbol?, period?, data, comparisons? }. Bypasses the fetcher pipeline entirely. See example above
teleportContainerstring | HTMLElementTeleport target for dropdowns/modals (CSS selector or element). Defaults to internal .chart-wrapper
mcpMcpConfigMCP/AI runtime bridge config: { wsUrl?, autoReconnect?, onToolCall? }. See @363045841yyt/klinechart-ai-runtime

🗺️ Roadmap

  • v0.10: AI-native chart support
  • K-line zoom anchor stability, improved zoom feel
  • Right axis detached from scroll container, completely solving clipping issues
  • Blank area drawing support
  • Limit vertical pan range to prevent viewport from leaving data
  • Drawing system
  • Right axis zoom
  • Latest price line and right axis label style optimization
  • Area primitive tools and rendering
  • More advanced drawing tools
  • Support for minute, multi-day, monthly, and yearly K-line display
  • Support convert the drawing to quant code

📦 Packages

PackageDescriptionnpm
@363045841yyt/klinechart-coreHeadless chart engine + controllersnpm
@363045841yyt/klinechartVue 3 bindingsnpm
@363045841yyt/klinechart-reactReact bindingsnpm
@363045841yyt/klinechart-angularAngular bindingsnpm
@363045841yyt/klinechart-ai-runtimeMCP server + AI tool schemas (optional)npm

🚀 What's New

  • v0.9.0 Self-developed Core-layer reactive state model migration, timing issues eliminated
  • v0.9.0 Single-path Scene renderer + WebGPU backend (hybrid DOM canvas, no compositeTo), FrameTransaction reactivity, device-lost recovery, auto-fallback WebGPU → WebGL → Canvas2D
  • v0.8 Symbol comparison, multi-source data aggregation
  • v0.7 Renderer registration chain AOP refactoring with decorator syntax, monorepo split, Vue/React bindings (experimental), standalone core package, tokenized color system
  • v0.6.10 Unified WebGL rendering context sharing for all panes, plus sub-pane lifecycle refactoring — centralized pane instance management via SubPaneManager with first-class paneId identity
  • v0.6.6 Comprehensive rendering optimizations: batched price-to-Y calculations, cached tick positions and geometry, optimized month-key operations; achieves stable 190-200fps on 200Hz displays with frame generation time down to 2ms
  • v0.6.3 WebGL rendering for K-lines, volume bars, and MACD bars; significant performance boost across the board
  • v0.6.1 Dual-layer canvas architecture: Main + Overlay separation with UpdateLevel filtering, achieves stable 180fps with low jitter on 200Hz displays
  • v0.6.0 Stateless indicator pipeline: MA/BOLL/EXPMA/ENE/RSI/CCI/STOCH/MOM/WMSR/KST/FASTK now use unified Calculator → Scheduler → StateStore → Renderer architecture for better performance and maintainability
  • v0.5.6 Logarithmic price axis with evenly distributed grid lines at pixel level
  • v0.5.2 Advanced drawing tools: parallel channel, regression channel, smooth top/bottom, and non-intersecting channel
  • v0.5.0 Complete drawing tool system, supporting line, rectangle, text drawing and style editing
  • v0.4 Modern UI, left toolbar, right axis optimization, TradingView-style zoom feel

📄 License

MIT

About

High-performance financial charting library with Canvas/WebGL/WebGPU hybrid rendering, delivering crisp multi-DPR visuals at 1-3ms GPU time per frame. Features plugin-based rendering and visual signal annotation. Exposes JSON semantic configuration for Agent-driven quantitative visualization. Works seamlessly across Vue, React, and Angular (soon).

Topics

Resources

Stars

22 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

839 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

High-performance financial chart library with a single-frame generation time of just 2ms, stable scrolling at 190–200fps in a 200Hz environment, native support for AI Agent control, full-link ResizeObserver-driven crisp rendering, and a pluggable architecture.

English | 简体中文

📈 KLineChartQuant

Crisp Rendering · High Performance · Optimized Interaction · Mobile-Friendly

npm versionnpm downloadslicensedemo

qqtg


A lightweight financial K-line charting library focused on quantitative trading scenarios. Agent is a first-class citizen — supports AI Agent direct control of chart operations, providing TradingView-level interaction experience.




✨ Core Features

  • Agent First / MCP Native - Supports AI Agent direct control of charts via the Model Context Protocol. Built-in WebSocket-bridged MCP server enables any MCP client (Inspector, Claude Desktop, Cursor, etc.) to zoom, pan, add/remove indicators, and change theme in real time
  • Crisp Rendering - Full-chain ResizeObserver driven, physical pixel alignment, K-lines, wicks, and lines are sharp and clear on all DPR screens
  • Plugin Architecture - Renderer plugin-based design, supporting dynamic registration, configuration, and lifecycle management
  • Custom Markers - Supports semantic configuration of custom markers and custom information
  • High Performance - Smoothly handles tens of thousands of data points, no lag during zoom or pan; supports 190-200fps on 200Hz displays with single-frame generation time as low as 2ms
  • Multi-Backend Rendering - Submit drawing primitives once, render via WebGPU, WebGL, or Canvas2D. WebGPU provides hybrid DOM canvas (no compositeTo copy), single-command-buffer-per-frame submission with 4x MSAA, and per-instance geometry caching via ResourceTable. Automatic fallback chain: WebGPU → WebGL → Canvas2D. Reaching 190fps on 200Hz displays with per-frame GPU time under 1ms
  • Optimized Interaction - Stable zoom anchor, precise crosshair cursor, smooth drag
  • Mobile-Optimized Interaction - Long-press crosshair for data exploration, tap to dismiss, slide to browse data without triggering chart scroll, gesture-based scroll mode
  • Multi-Symbol Comparison - Supports unlimited number of instruments for trend comparison
  • Multi-Source Aggregation - Supports aggregation and unification of multiple data sources
  • Batch Data Export - Select a date range and export multiple stocks' K-line data into a single CSV file, with progress indication
  • Custom Tooltip - Fully customizable tooltip via named slots (#kline-tooltip, #marker-tooltip), with engine-provided hover data, position, and styling

📐 System Architecture

KLineChartQuant is a pnpm monorepo. The framework-agnostic core engine exposes a unified ChartController (readonly signals + commands); Vue / React / Angular bindings only handle mounting, event forwarding, and reactivity bridging. AI Agents drive the chart directly through MCP over a WebSocket bridge.

flowchart TB
subgraph app["UI Layer / Framework Bindings"]
UI["UI Layer"]
VuePkg["@363045841yyt/klinechart<br/>Vue 3 components · useChart"]
ReactPkg["@363045841yyt/klinechart-react<br/>KLineChartWC (wraps Vue-built Web Component)"]
AngularPkg["@363045841yyt/klinechart-angular"]
Agent["AI Agent / MCP Client"]
AiRt["@363045841yyt/klinechart-ai-runtime"]
end
subgraph core["Core Engine @363045841yyt/klinechart-core"]
Ctl["ChartController<br/>signals + commands"]
Chart["Chart facade"]
Kernel["StateKernel<br/>Reactive SSOT"]
Data["Data Layer<br/>SeriesRepository · Buffers"]
Pipe["Rendering Pipeline<br/>FrameTransaction · Scene/Layer"]
GPU["WebGPU / WebGL2 / Canvas2D"]
Plugin["Plugin Subsystem<br/>PluginHost · RendererPlugin"]
Biz["Indicators · Markers · Drawing<br/>Timeshare · Compare · Components"]
end
subgraph conn["Market Data Backends"]
Go["GoTDX-Connecter<br/>gotdx :8080"]
Bn["GoTDX-Connecter<br/>Binance depth :8081"]
Bs["Baostock-Tradingview-Connecter<br/>BaoStock / TradingView :8000"]
end
UI --> VuePkg
UI --> ReactPkg
UI --> AngularPkg
VuePkg -->|"Web Component"| ReactPkg
Agent --> AiRt
VuePkg --> Ctl
ReactPkg --> Ctl
AngularPkg --> Ctl
AiRt -->|WebSocket / MCP| Ctl
Ctl --> Chart
Chart --> Kernel
Chart --> Data
Chart --> Pipe
Chart --> Plugin
Plugin --> Biz
Biz --> Pipe
Pipe --> GPU
Go -->|market data| Data
Bn -->|market data| Data
Bs -->|market data| Data
Kernel --> Data
Kernel --> Pipe
Loading
  • Core engine — headless chart engine + ChartController; depends on no UI framework.
  • StateKernel — single source of truth: readonly signals for reads, actions for writes, computed() for derivation, effect() for DOM side effects.
  • Rendering — submit primitives once, render via WebGPU / WebGL2 / Canvas2D with automatic fallback (WebGPU → WebGL → Canvas2D).
  • Data layer — unified SeriesRepository + incremental buffers + fetch scheduler; multi-source aggregation (gotdx / BaoStock / TradingView / mock) and Binance depth.
  • Plugin subsystem — PluginHost / HookSystem / EventBus / RendererPluginManager; indicators, markers and drawing tools plug in as Scene Layers.
  • React via Web Component@363045841yyt/klinechart-react's KLineChartWC renders the <kline-chart> Custom Element bundled from the Vue package (@363045841yyt/klinechart/web-component).
  • MCP / Agent@363045841yyt/klinechart-ai-runtime bridges AI tool calls to the controller over WebSocket.

See docs/architecture.md for the full architecture document.

📡 Data Sources

KLineChart requires a market data backend. Supported data sources:

Data SourceDescriptionDocs
gotdxTongdaxin (GOTDX) quotes: A-share / futures / MAC, served by GoTDX-ConnecterGoTDX-Connecter
baostockBaoStock A-share daily / weekly / monthly & minute K-lines, served by Baostock-Tradingview-ConnecterBaoStock
tradingviewTradingView global instruments, served by Baostock-Tradingview-ConnecterBaoStock
mockDebug only: local MOCK-100 / MOCK-10000 K-lines, no backend needed, always online

Backend repos live alongside this one (outside the monorepo).

One-Command Dev Startup

Clone the data-source backends first (idempotent: skips directories that already exist):

pnpm setup

Then run pnpm dev with a -c argument to start the frontend and the selected connecters together:

pnpm dev # frontend only (Vite dev server)
pnpm dev -c all # frontend + all backends (gotdx + binance + baostock)
pnpm dev -c gotdx baostock # frontend + selected backends
pnpm dev -c tdx # aliases supported (tdx / g / b / bnb / all)
pnpm dev -c all --lan # same, dev server bound to 0.0.0.0 (LAN accessible)

Common shorthands:

pnpm dev:all # frontend + all backends
pnpm dev:g # frontend + gotdx (Tongdaxin)
pnpm dev:b # frontend + BaoStock / TradingView
pnpm dev:bnb # frontend + Binance depth
pnpm dev:lan:all # frontend (0.0.0.0) + all backends

Parallel process logs stay in one terminal and are separated by colored source prefixes: [vite], [gotdx], [binance], and [baostock].

Backend only (no frontend):

pnpm connecter # all backends
pnpm connecter gotdx # gotdx (Tongdaxin) :8080
pnpm connecter baostock # BaoStock / TradingView :8000

After pnpm setup, no extra setup is needed. The dev server proxies /api/stock:8000 (Baostock-Tradingview-Connecter) and /api/public:8080 (GoTDX-Connecter).

🚀 Quick Start

3. Install and Use

npm install @363045841yyt/klinechart @363045841yyt/klinechart-core

Use the component:

<template>
<divclass="app-container":data-theme="currentTheme">
<KlineChartv-model:theme="currentTheme" :custom-data="customData" :settings="chartSettings" />
</div>
</template>
<script setup lang="ts">import { ref } from'vue'importtype { ChartSettings } from'@363045841yyt/klinechart-core'import { typeCustomDataSource, KlineChart } from'@363045841yyt/klinechart'importdemoDatafrom'./demo-data.json'const currentTheme =ref<'light'|'dark'>('dark')const customData =ref<CustomDataSource>(demoDataasCustomDataSource)const chartSettings:ChartSettings= { showGridLines: true, isAsiaMarket: true, showVolumePriceMarkers: false, mainLeftAxisDisplaySetting: 'none', theme: 'dark', colorPresetSettings: { dark: { candleUpBody: '#e85d04', candleDownBody: '#1b4332', crosshairLine: '#faa307', gridMajor: '#3e2723', }, }, }</script>
<style>.app-container {display: flex;flex-direction: column;height: 80vh; }.app-container[data-theme='dark'] {background: #000;color: #e5e7eb; }</style>

Import CSS in main.ts:

import'@363045841yyt/klinechart/style.css'import{createApp}from'vue'importAppfrom'./App.vue'createApp(App).mount('#app')

Slot Usage — Custom Tooltip:

<KlineChart><template#kline-tooltip="{ hoverData, upColor, downColor }"><divclass="custom-tooltip"><divclass="custom-tooltip__title"><span>{{ hoverData.stockCode }}</span><span>{{ formatTimestamp(hoverData.timestamp, { timeZone: 'Asia/Shanghai' }) }}</span></div><divclass="custom-tooltip__price"
:style="{ color: hoverData.close >= hoverData.open ? upColor : downColor }"
>
{{ hoverData.close.toFixed(2) }}
</div><divclass="custom-tooltip__detail">
O: {{ hoverData.open.toFixed(2) }}<br/>
H: {{ hoverData.high.toFixed(2) }}<br/>
L: {{ hoverData.low.toFixed(2) }}<br/>
C: {{ hoverData.close.toFixed(2) }}
</div></div></template></KlineChart>

Slot Usage — Custom Main-Pane Legend:

Providing #legend fully replaces the default Canvas legend. The slot scope is the full LegendTemplateContext (OHLC, timeshare, main indicators, comparisons, layout, colors).

<template #legend="{ index, currentBar, timeshare, indicators, comparisons, colors }">
<divclass="my-legend">
<!-- Custom fields added to KLineData[] for PR #98 are exposed through currentBar -->
<divv-if="currentBar"class="my-legend__row">
<span:style="{ color: currentBar.color }">
开盘 {{ currentBar.open.toFixed(2) }} 最高 {{ currentBar.high.toFixed(2) }} 最低
{{ currentBar.low.toFixed(2) }} 收盘 {{ currentBar.close.toFixed(2) }}
</span>
<spanv-if="currentBar.volumeText"> Vol {{ currentBar.volumeText }}</span>
</div>
<divv-if="timeshare"class="my-legend__row">
<span:style="{ color: timeshare.changeColor }">
现价 {{ timeshare.price.toFixed(2) }} 涨幅 {{ timeshare.changePercent.toFixed(2) }}%
</span>
</div>
<!-- Using main chart indicator legend data -->
<divv-for="indicator in indicators":key="indicator.name"class="my-legend__row">
<span>{{ indicator.name }}:</span>
<templatev-for="valueinindicator.values" :key="value.label">
<span:style="{ color: value.color }">
{{ value.label }} {{ value.value.toFixed(3) }}
</span>
</template>
</div>
<!-- Using comparison commodity data -->
<divv-for="comparison in comparisons":key="comparison.symbol"class="my-legend__row":style="{ color: comparison.percentColor }"
>
{{ comparison.symbol }}
{{ comparison.percent > 0 ? '+' : '' }}{{ comparison.percent.toFixed(2) }}%
</div>
</div>
</template>

4. (Optional) Enable MCP / AI Agent Control

npm install @363045841yyt/klinechart-ai-runtime
<template>
<divclass="app-container">
<KlineChart ref="chartRef" :mcp="mcpConfig" />
</div>
</template>
<script setup lang="ts">import { ref } from'vue'import { KlineChart } from'@363045841yyt/klinechart'import { executeTool } from'@363045841yyt/klinechart-ai-runtime'const chartRef =ref<InstanceType<typeofKlineChart> |null>(null)const mcpConfig = { wsUrl: 'ws://localhost:8080', autoReconnect: true,onToolCall: (call) => {const ctrl =chartRef.value?.getController?.()if (!ctrl) return { success: false, error: 'Controller not ready' }returnexecuteTool(ctrl, call) }, }</script>
<style>.app-container {height: 80vh; }</style>

Then start the MCP server:

cd packages/ai-runtime
pnpm inspect

Connect via MCP Inspector and call chart.zoomToLevel, indicators.add, etc.

📖 More Documentation

📋 Component Props

PropTypeDefaultDescription
semanticConfigSemanticChartConfigSemantic configuration (optional). When provided, drives chart data, indicators, markers and chart options
theme'light' | 'dark'Chart theme. Use v-model:theme for two-way binding
isFullscreenbooleanControlled fullscreen state. Leave unbound for internal (non-controlled) mode
timezonestring'Asia/Shanghai'Time zone for date/time display
yPaddingPxnumber20Y-axis padding in pixels
minKWidthnumber1Minimum K-line width (logical pixels)
maxKWidthnumber50Maximum K-line width (logical pixels)
rightAxisWidthnumber0Right price axis width
leftAxisWidthnumber0Left price axis width (0 = hidden)
bottomAxisHeightnumber24Bottom time axis height
priceLabelWidthnumber60Price label extra width for showing change percentage
zoomLevelsnumber20Total number of zoom levels
initialZoomLevelnumber3Initial zoom level (1 ~ zoomLevels)
customDataCustomDataSourceInline data bundle: { symbol?, period?, data, comparisons? }. Bypasses the fetcher pipeline entirely. See example above
teleportContainerstring | HTMLElementTeleport target for dropdowns/modals (CSS selector or element). Defaults to internal .chart-wrapper
mcpMcpConfigMCP/AI runtime bridge config: { wsUrl?, autoReconnect?, onToolCall? }. See @363045841yyt/klinechart-ai-runtime

🗺️ Roadmap

  • v0.10: AI-native chart support
  • K-line zoom anchor stability, improved zoom feel
  • Right axis detached from scroll container, completely solving clipping issues
  • Blank area drawing support
  • Limit vertical pan range to prevent viewport from leaving data
  • Drawing system
  • Right axis zoom
  • Latest price line and right axis label style optimization
  • Area primitive tools and rendering
  • More advanced drawing tools
  • Support for minute, multi-day, monthly, and yearly K-line display
  • Support convert the drawing to quant code

📦 Packages

PackageDescriptionnpm
@363045841yyt/klinechart-coreHeadless chart engine + controllersnpm
@363045841yyt/klinechartVue 3 bindingsnpm
@363045841yyt/klinechart-reactReact bindingsnpm
@363045841yyt/klinechart-angularAngular bindingsnpm
@363045841yyt/klinechart-ai-runtimeMCP server + AI tool schemas (optional)npm

🚀 What's New

  • v0.9.0 Self-developed Core-layer reactive state model migration, timing issues eliminated
  • v0.9.0 Single-path Scene renderer + WebGPU backend (hybrid DOM canvas, no compositeTo), FrameTransaction reactivity, device-lost recovery, auto-fallback WebGPU → WebGL → Canvas2D
  • v0.8 Symbol comparison, multi-source data aggregation
  • v0.7 Renderer registration chain AOP refactoring with decorator syntax, monorepo split, Vue/React bindings (experimental), standalone core package, tokenized color system
  • v0.6.10 Unified WebGL rendering context sharing for all panes, plus sub-pane lifecycle refactoring — centralized pane instance management via SubPaneManager with first-class paneId identity
  • v0.6.6 Comprehensive rendering optimizations: batched price-to-Y calculations, cached tick positions and geometry, optimized month-key operations; achieves stable 190-200fps on 200Hz displays with frame generation time down to 2ms
  • v0.6.3 WebGL rendering for K-lines, volume bars, and MACD bars; significant performance boost across the board
  • v0.6.1 Dual-layer canvas architecture: Main + Overlay separation with UpdateLevel filtering, achieves stable 180fps with low jitter on 200Hz displays
  • v0.6.0 Stateless indicator pipeline: MA/BOLL/EXPMA/ENE/RSI/CCI/STOCH/MOM/WMSR/KST/FASTK now use unified Calculator → Scheduler → StateStore → Renderer architecture for better performance and maintainability
  • v0.5.6 Logarithmic price axis with evenly distributed grid lines at pixel level
  • v0.5.2 Advanced drawing tools: parallel channel, regression channel, smooth top/bottom, and non-intersecting channel
  • v0.5.0 Complete drawing tool system, supporting line, rectangle, text drawing and style editing
  • v0.4 Modern UI, left toolbar, right axis optimization, TradingView-style zoom feel

📄 License

MIT

About

High-performance financial charting library with Canvas/WebGL/WebGPU hybrid rendering, delivering crisp multi-DPR visuals at 1-3ms GPU time per frame. Features plugin-based rendering and visual signal annotation. Exposes JSON semantic configuration for Agent-driven quantitative visualization. Works seamlessly across Vue, React, and Angular (soon).

Topics

Resources

Stars

22 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

839 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

High-performance financial chart library with a single-frame generation time of just 2ms, stable scrolling at 190–200fps in a 200Hz environment, native support for AI Agent control, full-link ResizeObserver-driven crisp rendering, and a pluggable architecture.

English | 简体中文

📈 KLineChartQuant

Crisp Rendering · High Performance · Optimized Interaction · Mobile-Friendly

npm versionnpm downloadslicensedemo

qqtg


A lightweight financial K-line charting library focused on quantitative trading scenarios. Agent is a first-class citizen — supports AI Agent direct control of chart operations, providing TradingView-level interaction experience.




✨ Core Features

  • Agent First / MCP Native - Supports AI Agent direct control of charts via the Model Context Protocol. Built-in WebSocket-bridged MCP server enables any MCP client (Inspector, Claude Desktop, Cursor, etc.) to zoom, pan, add/remove indicators, and change theme in real time
  • Crisp Rendering - Full-chain ResizeObserver driven, physical pixel alignment, K-lines, wicks, and lines are sharp and clear on all DPR screens
  • Plugin Architecture - Renderer plugin-based design, supporting dynamic registration, configuration, and lifecycle management
  • Custom Markers - Supports semantic configuration of custom markers and custom information
  • High Performance - Smoothly handles tens of thousands of data points, no lag during zoom or pan; supports 190-200fps on 200Hz displays with single-frame generation time as low as 2ms
  • Multi-Backend Rendering - Submit drawing primitives once, render via WebGPU, WebGL, or Canvas2D. WebGPU provides hybrid DOM canvas (no compositeTo copy), single-command-buffer-per-frame submission with 4x MSAA, and per-instance geometry caching via ResourceTable. Automatic fallback chain: WebGPU → WebGL → Canvas2D. Reaching 190fps on 200Hz displays with per-frame GPU time under 1ms
  • Optimized Interaction - Stable zoom anchor, precise crosshair cursor, smooth drag
  • Mobile-Optimized Interaction - Long-press crosshair for data exploration, tap to dismiss, slide to browse data without triggering chart scroll, gesture-based scroll mode
  • Multi-Symbol Comparison - Supports unlimited number of instruments for trend comparison
  • Multi-Source Aggregation - Supports aggregation and unification of multiple data sources
  • Batch Data Export - Select a date range and export multiple stocks' K-line data into a single CSV file, with progress indication
  • Custom Tooltip - Fully customizable tooltip via named slots (#kline-tooltip, #marker-tooltip), with engine-provided hover data, position, and styling

📐 System Architecture

KLineChartQuant is a pnpm monorepo. The framework-agnostic core engine exposes a unified ChartController (readonly signals + commands); Vue / React / Angular bindings only handle mounting, event forwarding, and reactivity bridging. AI Agents drive the chart directly through MCP over a WebSocket bridge.

flowchart TB
subgraph app["UI Layer / Framework Bindings"]
UI["UI Layer"]
VuePkg["@363045841yyt/klinechart<br/>Vue 3 components · useChart"]
ReactPkg["@363045841yyt/klinechart-react<br/>KLineChartWC (wraps Vue-built Web Component)"]
AngularPkg["@363045841yyt/klinechart-angular"]
Agent["AI Agent / MCP Client"]
AiRt["@363045841yyt/klinechart-ai-runtime"]
end
subgraph core["Core Engine @363045841yyt/klinechart-core"]
Ctl["ChartController<br/>signals + commands"]
Chart["Chart facade"]
Kernel["StateKernel<br/>Reactive SSOT"]
Data["Data Layer<br/>SeriesRepository · Buffers"]
Pipe["Rendering Pipeline<br/>FrameTransaction · Scene/Layer"]
GPU["WebGPU / WebGL2 / Canvas2D"]
Plugin["Plugin Subsystem<br/>PluginHost · RendererPlugin"]
Biz["Indicators · Markers · Drawing<br/>Timeshare · Compare · Components"]
end
subgraph conn["Market Data Backends"]
Go["GoTDX-Connecter<br/>gotdx :8080"]
Bn["GoTDX-Connecter<br/>Binance depth :8081"]
Bs["Baostock-Tradingview-Connecter<br/>BaoStock / TradingView :8000"]
end
UI --> VuePkg
UI --> ReactPkg
UI --> AngularPkg
VuePkg -->|"Web Component"| ReactPkg
Agent --> AiRt
VuePkg --> Ctl
ReactPkg --> Ctl
AngularPkg --> Ctl
AiRt -->|WebSocket / MCP| Ctl
Ctl --> Chart
Chart --> Kernel
Chart --> Data
Chart --> Pipe
Chart --> Plugin
Plugin --> Biz
Biz --> Pipe
Pipe --> GPU
Go -->|market data| Data
Bn -->|market data| Data
Bs -->|market data| Data
Kernel --> Data
Kernel --> Pipe
Loading
  • Core engine — headless chart engine + ChartController; depends on no UI framework.
  • StateKernel — single source of truth: readonly signals for reads, actions for writes, computed() for derivation, effect() for DOM side effects.
  • Rendering — submit primitives once, render via WebGPU / WebGL2 / Canvas2D with automatic fallback (WebGPU → WebGL → Canvas2D).
  • Data layer — unified SeriesRepository + incremental buffers + fetch scheduler; multi-source aggregation (gotdx / BaoStock / TradingView / mock) and Binance depth.
  • Plugin subsystem — PluginHost / HookSystem / EventBus / RendererPluginManager; indicators, markers and drawing tools plug in as Scene Layers.
  • React via Web Component@363045841yyt/klinechart-react's KLineChartWC renders the <kline-chart> Custom Element bundled from the Vue package (@363045841yyt/klinechart/web-component).
  • MCP / Agent@363045841yyt/klinechart-ai-runtime bridges AI tool calls to the controller over WebSocket.

See docs/architecture.md for the full architecture document.

📡 Data Sources

KLineChart requires a market data backend. Supported data sources:

Data SourceDescriptionDocs
gotdxTongdaxin (GOTDX) quotes: A-share / futures / MAC, served by GoTDX-ConnecterGoTDX-Connecter
baostockBaoStock A-share daily / weekly / monthly & minute K-lines, served by Baostock-Tradingview-ConnecterBaoStock
tradingviewTradingView global instruments, served by Baostock-Tradingview-ConnecterBaoStock
mockDebug only: local MOCK-100 / MOCK-10000 K-lines, no backend needed, always online

Backend repos live alongside this one (outside the monorepo).

One-Command Dev Startup

Clone the data-source backends first (idempotent: skips directories that already exist):

pnpm setup

Then run pnpm dev with a -c argument to start the frontend and the selected connecters together:

pnpm dev # frontend only (Vite dev server)
pnpm dev -c all # frontend + all backends (gotdx + binance + baostock)
pnpm dev -c gotdx baostock # frontend + selected backends
pnpm dev -c tdx # aliases supported (tdx / g / b / bnb / all)
pnpm dev -c all --lan # same, dev server bound to 0.0.0.0 (LAN accessible)

Common shorthands:

pnpm dev:all # frontend + all backends
pnpm dev:g # frontend + gotdx (Tongdaxin)
pnpm dev:b # frontend + BaoStock / TradingView
pnpm dev:bnb # frontend + Binance depth
pnpm dev:lan:all # frontend (0.0.0.0) + all backends

Parallel process logs stay in one terminal and are separated by colored source prefixes: [vite], [gotdx], [binance], and [baostock].

Backend only (no frontend):

pnpm connecter # all backends
pnpm connecter gotdx # gotdx (Tongdaxin) :8080
pnpm connecter baostock # BaoStock / TradingView :8000

After pnpm setup, no extra setup is needed. The dev server proxies /api/stock:8000 (Baostock-Tradingview-Connecter) and /api/public:8080 (GoTDX-Connecter).

🚀 Quick Start

3. Install and Use

npm install @363045841yyt/klinechart @363045841yyt/klinechart-core

Use the component:

<template>
<divclass="app-container":data-theme="currentTheme">
<KlineChartv-model:theme="currentTheme" :custom-data="customData" :settings="chartSettings" />
</div>
</template>
<script setup lang="ts">import { ref } from'vue'importtype { ChartSettings } from'@363045841yyt/klinechart-core'import { typeCustomDataSource, KlineChart } from'@363045841yyt/klinechart'importdemoDatafrom'./demo-data.json'const currentTheme =ref<'light'|'dark'>('dark')const customData =ref<CustomDataSource>(demoDataasCustomDataSource)const chartSettings:ChartSettings= { showGridLines: true, isAsiaMarket: true, showVolumePriceMarkers: false, mainLeftAxisDisplaySetting: 'none', theme: 'dark', colorPresetSettings: { dark: { candleUpBody: '#e85d04', candleDownBody: '#1b4332', crosshairLine: '#faa307', gridMajor: '#3e2723', }, }, }</script>
<style>.app-container {display: flex;flex-direction: column;height: 80vh; }.app-container[data-theme='dark'] {background: #000;color: #e5e7eb; }</style>

Import CSS in main.ts:

import'@363045841yyt/klinechart/style.css'import{createApp}from'vue'importAppfrom'./App.vue'createApp(App).mount('#app')

Slot Usage — Custom Tooltip:

<KlineChart><template#kline-tooltip="{ hoverData, upColor, downColor }"><divclass="custom-tooltip"><divclass="custom-tooltip__title"><span>{{ hoverData.stockCode }}</span><span>{{ formatTimestamp(hoverData.timestamp, { timeZone: 'Asia/Shanghai' }) }}</span></div><divclass="custom-tooltip__price"
:style="{ color: hoverData.close >= hoverData.open ? upColor : downColor }"
>
{{ hoverData.close.toFixed(2) }}
</div><divclass="custom-tooltip__detail">
O: {{ hoverData.open.toFixed(2) }}<br/>
H: {{ hoverData.high.toFixed(2) }}<br/>
L: {{ hoverData.low.toFixed(2) }}<br/>
C: {{ hoverData.close.toFixed(2) }}
</div></div></template></KlineChart>

Slot Usage — Custom Main-Pane Legend:

Providing #legend fully replaces the default Canvas legend. The slot scope is the full LegendTemplateContext (OHLC, timeshare, main indicators, comparisons, layout, colors).

<template #legend="{ index, currentBar, timeshare, indicators, comparisons, colors }">
<divclass="my-legend">
<!-- Custom fields added to KLineData[] for PR #98 are exposed through currentBar -->
<divv-if="currentBar"class="my-legend__row">
<span:style="{ color: currentBar.color }">
开盘 {{ currentBar.open.toFixed(2) }} 最高 {{ currentBar.high.toFixed(2) }} 最低
{{ currentBar.low.toFixed(2) }} 收盘 {{ currentBar.close.toFixed(2) }}
</span>
<spanv-if="currentBar.volumeText"> Vol {{ currentBar.volumeText }}</span>
</div>
<divv-if="timeshare"class="my-legend__row">
<span:style="{ color: timeshare.changeColor }">
现价 {{ timeshare.price.toFixed(2) }} 涨幅 {{ timeshare.changePercent.toFixed(2) }}%
</span>
</div>
<!-- Using main chart indicator legend data -->
<divv-for="indicator in indicators":key="indicator.name"class="my-legend__row">
<span>{{ indicator.name }}:</span>
<templatev-for="valueinindicator.values" :key="value.label">
<span:style="{ color: value.color }">
{{ value.label }} {{ value.value.toFixed(3) }}
</span>
</template>
</div>
<!-- Using comparison commodity data -->
<divv-for="comparison in comparisons":key="comparison.symbol"class="my-legend__row":style="{ color: comparison.percentColor }"
>
{{ comparison.symbol }}
{{ comparison.percent > 0 ? '+' : '' }}{{ comparison.percent.toFixed(2) }}%
</div>
</div>
</template>

4. (Optional) Enable MCP / AI Agent Control

npm install @363045841yyt/klinechart-ai-runtime
<template>
<divclass="app-container">
<KlineChart ref="chartRef" :mcp="mcpConfig" />
</div>
</template>
<script setup lang="ts">import { ref } from'vue'import { KlineChart } from'@363045841yyt/klinechart'import { executeTool } from'@363045841yyt/klinechart-ai-runtime'const chartRef =ref<InstanceType<typeofKlineChart> |null>(null)const mcpConfig = { wsUrl: 'ws://localhost:8080', autoReconnect: true,onToolCall: (call) => {const ctrl =chartRef.value?.getController?.()if (!ctrl) return { success: false, error: 'Controller not ready' }returnexecuteTool(ctrl, call) }, }</script>
<style>.app-container {height: 80vh; }</style>

Then start the MCP server:

cd packages/ai-runtime
pnpm inspect

Connect via MCP Inspector and call chart.zoomToLevel, indicators.add, etc.

📖 More Documentation

📋 Component Props

PropTypeDefaultDescription
semanticConfigSemanticChartConfigSemantic configuration (optional). When provided, drives chart data, indicators, markers and chart options
theme'light' | 'dark'Chart theme. Use v-model:theme for two-way binding
isFullscreenbooleanControlled fullscreen state. Leave unbound for internal (non-controlled) mode
timezonestring'Asia/Shanghai'Time zone for date/time display
yPaddingPxnumber20Y-axis padding in pixels
minKWidthnumber1Minimum K-line width (logical pixels)
maxKWidthnumber50Maximum K-line width (logical pixels)
rightAxisWidthnumber0Right price axis width
leftAxisWidthnumber0Left price axis width (0 = hidden)
bottomAxisHeightnumber24Bottom time axis height
priceLabelWidthnumber60Price label extra width for showing change percentage
zoomLevelsnumber20Total number of zoom levels
initialZoomLevelnumber3Initial zoom level (1 ~ zoomLevels)
customDataCustomDataSourceInline data bundle: { symbol?, period?, data, comparisons? }. Bypasses the fetcher pipeline entirely. See example above
teleportContainerstring | HTMLElementTeleport target for dropdowns/modals (CSS selector or element). Defaults to internal .chart-wrapper
mcpMcpConfigMCP/AI runtime bridge config: { wsUrl?, autoReconnect?, onToolCall? }. See @363045841yyt/klinechart-ai-runtime

🗺️ Roadmap

  • v0.10: AI-native chart support
  • K-line zoom anchor stability, improved zoom feel
  • Right axis detached from scroll container, completely solving clipping issues
  • Blank area drawing support
  • Limit vertical pan range to prevent viewport from leaving data
  • Drawing system
  • Right axis zoom
  • Latest price line and right axis label style optimization
  • Area primitive tools and rendering
  • More advanced drawing tools
  • Support for minute, multi-day, monthly, and yearly K-line display
  • Support convert the drawing to quant code

📦 Packages

PackageDescriptionnpm
@363045841yyt/klinechart-coreHeadless chart engine + controllersnpm
@363045841yyt/klinechartVue 3 bindingsnpm
@363045841yyt/klinechart-reactReact bindingsnpm
@363045841yyt/klinechart-angularAngular bindingsnpm
@363045841yyt/klinechart-ai-runtimeMCP server + AI tool schemas (optional)npm

🚀 What's New

  • v0.9.0 Self-developed Core-layer reactive state model migration, timing issues eliminated
  • v0.9.0 Single-path Scene renderer + WebGPU backend (hybrid DOM canvas, no compositeTo), FrameTransaction reactivity, device-lost recovery, auto-fallback WebGPU → WebGL → Canvas2D
  • v0.8 Symbol comparison, multi-source data aggregation
  • v0.7 Renderer registration chain AOP refactoring with decorator syntax, monorepo split, Vue/React bindings (experimental), standalone core package, tokenized color system
  • v0.6.10 Unified WebGL rendering context sharing for all panes, plus sub-pane lifecycle refactoring — centralized pane instance management via SubPaneManager with first-class paneId identity
  • v0.6.6 Comprehensive rendering optimizations: batched price-to-Y calculations, cached tick positions and geometry, optimized month-key operations; achieves stable 190-200fps on 200Hz displays with frame generation time down to 2ms
  • v0.6.3 WebGL rendering for K-lines, volume bars, and MACD bars; significant performance boost across the board
  • v0.6.1 Dual-layer canvas architecture: Main + Overlay separation with UpdateLevel filtering, achieves stable 180fps with low jitter on 200Hz displays
  • v0.6.0 Stateless indicator pipeline: MA/BOLL/EXPMA/ENE/RSI/CCI/STOCH/MOM/WMSR/KST/FASTK now use unified Calculator → Scheduler → StateStore → Renderer architecture for better performance and maintainability
  • v0.5.6 Logarithmic price axis with evenly distributed grid lines at pixel level
  • v0.5.2 Advanced drawing tools: parallel channel, regression channel, smooth top/bottom, and non-intersecting channel
  • v0.5.0 Complete drawing tool system, supporting line, rectangle, text drawing and style editing
  • v0.4 Modern UI, left toolbar, right axis optimization, TradingView-style zoom feel

📄 License

MIT

About

High-performance financial charting library with Canvas/WebGL/WebGPU hybrid rendering, delivering crisp multi-DPR visuals at 1-3ms GPU time per frame. Features plugin-based rendering and visual signal annotation. Exposes JSON semantic configuration for Agent-driven quantitative visualization. Works seamlessly across Vue, React, and Angular (soon).

Topics

Resources

Stars

22 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

839 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

High-performance financial chart library with a single-frame generation time of just 2ms, stable scrolling at 190–200fps in a 200Hz environment, native support for AI Agent control, full-link ResizeObserver-driven crisp rendering, and a pluggable architecture.

English | 简体中文

📈 KLineChartQuant

Crisp Rendering · High Performance · Optimized Interaction · Mobile-Friendly

npm versionnpm downloadslicensedemo

qqtg


A lightweight financial K-line charting library focused on quantitative trading scenarios. Agent is a first-class citizen — supports AI Agent direct control of chart operations, providing TradingView-level interaction experience.




✨ Core Features

  • Agent First / MCP Native - Supports AI Agent direct control of charts via the Model Context Protocol. Built-in WebSocket-bridged MCP server enables any MCP client (Inspector, Claude Desktop, Cursor, etc.) to zoom, pan, add/remove indicators, and change theme in real time
  • Crisp Rendering - Full-chain ResizeObserver driven, physical pixel alignment, K-lines, wicks, and lines are sharp and clear on all DPR screens
  • Plugin Architecture - Renderer plugin-based design, supporting dynamic registration, configuration, and lifecycle management
  • Custom Markers - Supports semantic configuration of custom markers and custom information
  • High Performance - Smoothly handles tens of thousands of data points, no lag during zoom or pan; supports 190-200fps on 200Hz displays with single-frame generation time as low as 2ms
  • Multi-Backend Rendering - Submit drawing primitives once, render via WebGPU, WebGL, or Canvas2D. WebGPU provides hybrid DOM canvas (no compositeTo copy), single-command-buffer-per-frame submission with 4x MSAA, and per-instance geometry caching via ResourceTable. Automatic fallback chain: WebGPU → WebGL → Canvas2D. Reaching 190fps on 200Hz displays with per-frame GPU time under 1ms
  • Optimized Interaction - Stable zoom anchor, precise crosshair cursor, smooth drag
  • Mobile-Optimized Interaction - Long-press crosshair for data exploration, tap to dismiss, slide to browse data without triggering chart scroll, gesture-based scroll mode
  • Multi-Symbol Comparison - Supports unlimited number of instruments for trend comparison
  • Multi-Source Aggregation - Supports aggregation and unification of multiple data sources
  • Batch Data Export - Select a date range and export multiple stocks' K-line data into a single CSV file, with progress indication
  • Custom Tooltip - Fully customizable tooltip via named slots (#kline-tooltip, #marker-tooltip), with engine-provided hover data, position, and styling

📐 System Architecture

KLineChartQuant is a pnpm monorepo. The framework-agnostic core engine exposes a unified ChartController (readonly signals + commands); Vue / React / Angular bindings only handle mounting, event forwarding, and reactivity bridging. AI Agents drive the chart directly through MCP over a WebSocket bridge.

flowchart TB
subgraph app["UI Layer / Framework Bindings"]
UI["UI Layer"]
VuePkg["@363045841yyt/klinechart<br/>Vue 3 components · useChart"]
ReactPkg["@363045841yyt/klinechart-react<br/>KLineChartWC (wraps Vue-built Web Component)"]
AngularPkg["@363045841yyt/klinechart-angular"]
Agent["AI Agent / MCP Client"]
AiRt["@363045841yyt/klinechart-ai-runtime"]
end
subgraph core["Core Engine @363045841yyt/klinechart-core"]
Ctl["ChartController<br/>signals + commands"]
Chart["Chart facade"]
Kernel["StateKernel<br/>Reactive SSOT"]
Data["Data Layer<br/>SeriesRepository · Buffers"]
Pipe["Rendering Pipeline<br/>FrameTransaction · Scene/Layer"]
GPU["WebGPU / WebGL2 / Canvas2D"]
Plugin["Plugin Subsystem<br/>PluginHost · RendererPlugin"]
Biz["Indicators · Markers · Drawing<br/>Timeshare · Compare · Components"]
end
subgraph conn["Market Data Backends"]
Go["GoTDX-Connecter<br/>gotdx :8080"]
Bn["GoTDX-Connecter<br/>Binance depth :8081"]
Bs["Baostock-Tradingview-Connecter<br/>BaoStock / TradingView :8000"]
end
UI --> VuePkg
UI --> ReactPkg
UI --> AngularPkg
VuePkg -->|"Web Component"| ReactPkg
Agent --> AiRt
VuePkg --> Ctl
ReactPkg --> Ctl
AngularPkg --> Ctl
AiRt -->|WebSocket / MCP| Ctl
Ctl --> Chart
Chart --> Kernel
Chart --> Data
Chart --> Pipe
Chart --> Plugin
Plugin --> Biz
Biz --> Pipe
Pipe --> GPU
Go -->|market data| Data
Bn -->|market data| Data
Bs -->|market data| Data
Kernel --> Data
Kernel --> Pipe
Loading
  • Core engine — headless chart engine + ChartController; depends on no UI framework.
  • StateKernel — single source of truth: readonly signals for reads, actions for writes, computed() for derivation, effect() for DOM side effects.
  • Rendering — submit primitives once, render via WebGPU / WebGL2 / Canvas2D with automatic fallback (WebGPU → WebGL → Canvas2D).
  • Data layer — unified SeriesRepository + incremental buffers + fetch scheduler; multi-source aggregation (gotdx / BaoStock / TradingView / mock) and Binance depth.
  • Plugin subsystem — PluginHost / HookSystem / EventBus / RendererPluginManager; indicators, markers and drawing tools plug in as Scene Layers.
  • React via Web Component@363045841yyt/klinechart-react's KLineChartWC renders the <kline-chart> Custom Element bundled from the Vue package (@363045841yyt/klinechart/web-component).
  • MCP / Agent@363045841yyt/klinechart-ai-runtime bridges AI tool calls to the controller over WebSocket.

See docs/architecture.md for the full architecture document.

📡 Data Sources

KLineChart requires a market data backend. Supported data sources:

Data SourceDescriptionDocs
gotdxTongdaxin (GOTDX) quotes: A-share / futures / MAC, served by GoTDX-ConnecterGoTDX-Connecter
baostockBaoStock A-share daily / weekly / monthly & minute K-lines, served by Baostock-Tradingview-ConnecterBaoStock
tradingviewTradingView global instruments, served by Baostock-Tradingview-ConnecterBaoStock
mockDebug only: local MOCK-100 / MOCK-10000 K-lines, no backend needed, always online

Backend repos live alongside this one (outside the monorepo).

One-Command Dev Startup

Clone the data-source backends first (idempotent: skips directories that already exist):

pnpm setup

Then run pnpm dev with a -c argument to start the frontend and the selected connecters together:

pnpm dev # frontend only (Vite dev server)
pnpm dev -c all # frontend + all backends (gotdx + binance + baostock)
pnpm dev -c gotdx baostock # frontend + selected backends
pnpm dev -c tdx # aliases supported (tdx / g / b / bnb / all)
pnpm dev -c all --lan # same, dev server bound to 0.0.0.0 (LAN accessible)

Common shorthands:

pnpm dev:all # frontend + all backends
pnpm dev:g # frontend + gotdx (Tongdaxin)
pnpm dev:b # frontend + BaoStock / TradingView
pnpm dev:bnb # frontend + Binance depth
pnpm dev:lan:all # frontend (0.0.0.0) + all backends

Parallel process logs stay in one terminal and are separated by colored source prefixes: [vite], [gotdx], [binance], and [baostock].

Backend only (no frontend):

pnpm connecter # all backends
pnpm connecter gotdx # gotdx (Tongdaxin) :8080
pnpm connecter baostock # BaoStock / TradingView :8000

After pnpm setup, no extra setup is needed. The dev server proxies /api/stock:8000 (Baostock-Tradingview-Connecter) and /api/public:8080 (GoTDX-Connecter).

🚀 Quick Start

3. Install and Use

npm install @363045841yyt/klinechart @363045841yyt/klinechart-core

Use the component:

<template>
<divclass="app-container":data-theme="currentTheme">
<KlineChartv-model:theme="currentTheme" :custom-data="customData" :settings="chartSettings" />
</div>
</template>
<script setup lang="ts">import { ref } from'vue'importtype { ChartSettings } from'@363045841yyt/klinechart-core'import { typeCustomDataSource, KlineChart } from'@363045841yyt/klinechart'importdemoDatafrom'./demo-data.json'const currentTheme =ref<'light'|'dark'>('dark')const customData =ref<CustomDataSource>(demoDataasCustomDataSource)const chartSettings:ChartSettings= { showGridLines: true, isAsiaMarket: true, showVolumePriceMarkers: false, mainLeftAxisDisplaySetting: 'none', theme: 'dark', colorPresetSettings: { dark: { candleUpBody: '#e85d04', candleDownBody: '#1b4332', crosshairLine: '#faa307', gridMajor: '#3e2723', }, }, }</script>
<style>.app-container {display: flex;flex-direction: column;height: 80vh; }.app-container[data-theme='dark'] {background: #000;color: #e5e7eb; }</style>

Import CSS in main.ts:

import'@363045841yyt/klinechart/style.css'import{createApp}from'vue'importAppfrom'./App.vue'createApp(App).mount('#app')

Slot Usage — Custom Tooltip:

<KlineChart><template#kline-tooltip="{ hoverData, upColor, downColor }"><divclass="custom-tooltip"><divclass="custom-tooltip__title"><span>{{ hoverData.stockCode }}</span><span>{{ formatTimestamp(hoverData.timestamp, { timeZone: 'Asia/Shanghai' }) }}</span></div><divclass="custom-tooltip__price"
:style="{ color: hoverData.close >= hoverData.open ? upColor : downColor }"
>
{{ hoverData.close.toFixed(2) }}
</div><divclass="custom-tooltip__detail">
O: {{ hoverData.open.toFixed(2) }}<br/>
H: {{ hoverData.high.toFixed(2) }}<br/>
L: {{ hoverData.low.toFixed(2) }}<br/>
C: {{ hoverData.close.toFixed(2) }}
</div></div></template></KlineChart>

Slot Usage — Custom Main-Pane Legend:

Providing #legend fully replaces the default Canvas legend. The slot scope is the full LegendTemplateContext (OHLC, timeshare, main indicators, comparisons, layout, colors).

<template #legend="{ index, currentBar, timeshare, indicators, comparisons, colors }">
<divclass="my-legend">
<!-- Custom fields added to KLineData[] for PR #98 are exposed through currentBar -->
<divv-if="currentBar"class="my-legend__row">
<span:style="{ color: currentBar.color }">
开盘 {{ currentBar.open.toFixed(2) }} 最高 {{ currentBar.high.toFixed(2) }} 最低
{{ currentBar.low.toFixed(2) }} 收盘 {{ currentBar.close.toFixed(2) }}
</span>
<spanv-if="currentBar.volumeText"> Vol {{ currentBar.volumeText }}</span>
</div>
<divv-if="timeshare"class="my-legend__row">
<span:style="{ color: timeshare.changeColor }">
现价 {{ timeshare.price.toFixed(2) }} 涨幅 {{ timeshare.changePercent.toFixed(2) }}%
</span>
</div>
<!-- Using main chart indicator legend data -->
<divv-for="indicator in indicators":key="indicator.name"class="my-legend__row">
<span>{{ indicator.name }}:</span>
<templatev-for="valueinindicator.values" :key="value.label">
<span:style="{ color: value.color }">
{{ value.label }} {{ value.value.toFixed(3) }}
</span>
</template>
</div>
<!-- Using comparison commodity data -->
<divv-for="comparison in comparisons":key="comparison.symbol"class="my-legend__row":style="{ color: comparison.percentColor }"
>
{{ comparison.symbol }}
{{ comparison.percent > 0 ? '+' : '' }}{{ comparison.percent.toFixed(2) }}%
</div>
</div>
</template>

4. (Optional) Enable MCP / AI Agent Control

npm install @363045841yyt/klinechart-ai-runtime
<template>
<divclass="app-container">
<KlineChart ref="chartRef" :mcp="mcpConfig" />
</div>
</template>
<script setup lang="ts">import { ref } from'vue'import { KlineChart } from'@363045841yyt/klinechart'import { executeTool } from'@363045841yyt/klinechart-ai-runtime'const chartRef =ref<InstanceType<typeofKlineChart> |null>(null)const mcpConfig = { wsUrl: 'ws://localhost:8080', autoReconnect: true,onToolCall: (call) => {const ctrl =chartRef.value?.getController?.()if (!ctrl) return { success: false, error: 'Controller not ready' }returnexecuteTool(ctrl, call) }, }</script>
<style>.app-container {height: 80vh; }</style>

Then start the MCP server:

cd packages/ai-runtime
pnpm inspect

Connect via MCP Inspector and call chart.zoomToLevel, indicators.add, etc.

📖 More Documentation

📋 Component Props

PropTypeDefaultDescription
semanticConfigSemanticChartConfigSemantic configuration (optional). When provided, drives chart data, indicators, markers and chart options
theme'light' | 'dark'Chart theme. Use v-model:theme for two-way binding
isFullscreenbooleanControlled fullscreen state. Leave unbound for internal (non-controlled) mode
timezonestring'Asia/Shanghai'Time zone for date/time display
yPaddingPxnumber20Y-axis padding in pixels
minKWidthnumber1Minimum K-line width (logical pixels)
maxKWidthnumber50Maximum K-line width (logical pixels)
rightAxisWidthnumber0Right price axis width
leftAxisWidthnumber0Left price axis width (0 = hidden)
bottomAxisHeightnumber24Bottom time axis height
priceLabelWidthnumber60Price label extra width for showing change percentage
zoomLevelsnumber20Total number of zoom levels
initialZoomLevelnumber3Initial zoom level (1 ~ zoomLevels)
customDataCustomDataSourceInline data bundle: { symbol?, period?, data, comparisons? }. Bypasses the fetcher pipeline entirely. See example above
teleportContainerstring | HTMLElementTeleport target for dropdowns/modals (CSS selector or element). Defaults to internal .chart-wrapper
mcpMcpConfigMCP/AI runtime bridge config: { wsUrl?, autoReconnect?, onToolCall? }. See @363045841yyt/klinechart-ai-runtime

🗺️ Roadmap

  • v0.10: AI-native chart support
  • K-line zoom anchor stability, improved zoom feel
  • Right axis detached from scroll container, completely solving clipping issues
  • Blank area drawing support
  • Limit vertical pan range to prevent viewport from leaving data
  • Drawing system
  • Right axis zoom
  • Latest price line and right axis label style optimization
  • Area primitive tools and rendering
  • More advanced drawing tools
  • Support for minute, multi-day, monthly, and yearly K-line display
  • Support convert the drawing to quant code

📦 Packages

PackageDescriptionnpm
@363045841yyt/klinechart-coreHeadless chart engine + controllersnpm
@363045841yyt/klinechartVue 3 bindingsnpm
@363045841yyt/klinechart-reactReact bindingsnpm
@363045841yyt/klinechart-angularAngular bindingsnpm
@363045841yyt/klinechart-ai-runtimeMCP server + AI tool schemas (optional)npm

🚀 What's New

  • v0.9.0 Self-developed Core-layer reactive state model migration, timing issues eliminated
  • v0.9.0 Single-path Scene renderer + WebGPU backend (hybrid DOM canvas, no compositeTo), FrameTransaction reactivity, device-lost recovery, auto-fallback WebGPU → WebGL → Canvas2D
  • v0.8 Symbol comparison, multi-source data aggregation
  • v0.7 Renderer registration chain AOP refactoring with decorator syntax, monorepo split, Vue/React bindings (experimental), standalone core package, tokenized color system
  • v0.6.10 Unified WebGL rendering context sharing for all panes, plus sub-pane lifecycle refactoring — centralized pane instance management via SubPaneManager with first-class paneId identity
  • v0.6.6 Comprehensive rendering optimizations: batched price-to-Y calculations, cached tick positions and geometry, optimized month-key operations; achieves stable 190-200fps on 200Hz displays with frame generation time down to 2ms
  • v0.6.3 WebGL rendering for K-lines, volume bars, and MACD bars; significant performance boost across the board
  • v0.6.1 Dual-layer canvas architecture: Main + Overlay separation with UpdateLevel filtering, achieves stable 180fps with low jitter on 200Hz displays
  • v0.6.0 Stateless indicator pipeline: MA/BOLL/EXPMA/ENE/RSI/CCI/STOCH/MOM/WMSR/KST/FASTK now use unified Calculator → Scheduler → StateStore → Renderer architecture for better performance and maintainability
  • v0.5.6 Logarithmic price axis with evenly distributed grid lines at pixel level
  • v0.5.2 Advanced drawing tools: parallel channel, regression channel, smooth top/bottom, and non-intersecting channel
  • v0.5.0 Complete drawing tool system, supporting line, rectangle, text drawing and style editing
  • v0.4 Modern UI, left toolbar, right axis optimization, TradingView-style zoom feel

📄 License

MIT

About

High-performance financial charting library with Canvas/WebGL/WebGPU hybrid rendering, delivering crisp multi-DPR visuals at 1-3ms GPU time per frame. Features plugin-based rendering and visual signal annotation. Exposes JSON semantic configuration for Agent-driven quantitative visualization. Works seamlessly across Vue, React, and Angular (soon).

Topics

Resources

Stars

22 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

839 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

High-performance financial chart library with a single-frame generation time of just 2ms, stable scrolling at 190–200fps in a 200Hz environment, native support for AI Agent control, full-link ResizeObserver-driven crisp rendering, and a pluggable architecture.

English | 简体中文

📈 KLineChartQuant

Crisp Rendering · High Performance · Optimized Interaction · Mobile-Friendly

npm versionnpm downloadslicensedemo

qqtg


A lightweight financial K-line charting library focused on quantitative trading scenarios. Agent is a first-class citizen — supports AI Agent direct control of chart operations, providing TradingView-level interaction experience.




✨ Core Features

  • Agent First / MCP Native - Supports AI Agent direct control of charts via the Model Context Protocol. Built-in WebSocket-bridged MCP server enables any MCP client (Inspector, Claude Desktop, Cursor, etc.) to zoom, pan, add/remove indicators, and change theme in real time
  • Crisp Rendering - Full-chain ResizeObserver driven, physical pixel alignment, K-lines, wicks, and lines are sharp and clear on all DPR screens
  • Plugin Architecture - Renderer plugin-based design, supporting dynamic registration, configuration, and lifecycle management
  • Custom Markers - Supports semantic configuration of custom markers and custom information
  • High Performance - Smoothly handles tens of thousands of data points, no lag during zoom or pan; supports 190-200fps on 200Hz displays with single-frame generation time as low as 2ms
  • Multi-Backend Rendering - Submit drawing primitives once, render via WebGPU, WebGL, or Canvas2D. WebGPU provides hybrid DOM canvas (no compositeTo copy), single-command-buffer-per-frame submission with 4x MSAA, and per-instance geometry caching via ResourceTable. Automatic fallback chain: WebGPU → WebGL → Canvas2D. Reaching 190fps on 200Hz displays with per-frame GPU time under 1ms
  • Optimized Interaction - Stable zoom anchor, precise crosshair cursor, smooth drag
  • Mobile-Optimized Interaction - Long-press crosshair for data exploration, tap to dismiss, slide to browse data without triggering chart scroll, gesture-based scroll mode
  • Multi-Symbol Comparison - Supports unlimited number of instruments for trend comparison
  • Multi-Source Aggregation - Supports aggregation and unification of multiple data sources
  • Batch Data Export - Select a date range and export multiple stocks' K-line data into a single CSV file, with progress indication
  • Custom Tooltip - Fully customizable tooltip via named slots (#kline-tooltip, #marker-tooltip), with engine-provided hover data, position, and styling

📐 System Architecture

KLineChartQuant is a pnpm monorepo. The framework-agnostic core engine exposes a unified ChartController (readonly signals + commands); Vue / React / Angular bindings only handle mounting, event forwarding, and reactivity bridging. AI Agents drive the chart directly through MCP over a WebSocket bridge.

flowchart TB
subgraph app["UI Layer / Framework Bindings"]
UI["UI Layer"]
VuePkg["@363045841yyt/klinechart<br/>Vue 3 components · useChart"]
ReactPkg["@363045841yyt/klinechart-react<br/>KLineChartWC (wraps Vue-built Web Component)"]
AngularPkg["@363045841yyt/klinechart-angular"]
Agent["AI Agent / MCP Client"]
AiRt["@363045841yyt/klinechart-ai-runtime"]
end
subgraph core["Core Engine @363045841yyt/klinechart-core"]
Ctl["ChartController<br/>signals + commands"]
Chart["Chart facade"]
Kernel["StateKernel<br/>Reactive SSOT"]
Data["Data Layer<br/>SeriesRepository · Buffers"]
Pipe["Rendering Pipeline<br/>FrameTransaction · Scene/Layer"]
GPU["WebGPU / WebGL2 / Canvas2D"]
Plugin["Plugin Subsystem<br/>PluginHost · RendererPlugin"]
Biz["Indicators · Markers · Drawing<br/>Timeshare · Compare · Components"]
end
subgraph conn["Market Data Backends"]
Go["GoTDX-Connecter<br/>gotdx :8080"]
Bn["GoTDX-Connecter<br/>Binance depth :8081"]
Bs["Baostock-Tradingview-Connecter<br/>BaoStock / TradingView :8000"]
end
UI --> VuePkg
UI --> ReactPkg
UI --> AngularPkg
VuePkg -->|"Web Component"| ReactPkg
Agent --> AiRt
VuePkg --> Ctl
ReactPkg --> Ctl
AngularPkg --> Ctl
AiRt -->|WebSocket / MCP| Ctl
Ctl --> Chart
Chart --> Kernel
Chart --> Data
Chart --> Pipe
Chart --> Plugin
Plugin --> Biz
Biz --> Pipe
Pipe --> GPU
Go -->|market data| Data
Bn -->|market data| Data
Bs -->|market data| Data
Kernel --> Data
Kernel --> Pipe
Loading
  • Core engine — headless chart engine + ChartController; depends on no UI framework.
  • StateKernel — single source of truth: readonly signals for reads, actions for writes, computed() for derivation, effect() for DOM side effects.
  • Rendering — submit primitives once, render via WebGPU / WebGL2 / Canvas2D with automatic fallback (WebGPU → WebGL → Canvas2D).
  • Data layer — unified SeriesRepository + incremental buffers + fetch scheduler; multi-source aggregation (gotdx / BaoStock / TradingView / mock) and Binance depth.
  • Plugin subsystem — PluginHost / HookSystem / EventBus / RendererPluginManager; indicators, markers and drawing tools plug in as Scene Layers.
  • React via Web Component@363045841yyt/klinechart-react's KLineChartWC renders the <kline-chart> Custom Element bundled from the Vue package (@363045841yyt/klinechart/web-component).
  • MCP / Agent@363045841yyt/klinechart-ai-runtime bridges AI tool calls to the controller over WebSocket.

See docs/architecture.md for the full architecture document.

📡 Data Sources

KLineChart requires a market data backend. Supported data sources:

Data SourceDescriptionDocs
gotdxTongdaxin (GOTDX) quotes: A-share / futures / MAC, served by GoTDX-ConnecterGoTDX-Connecter
baostockBaoStock A-share daily / weekly / monthly & minute K-lines, served by Baostock-Tradingview-ConnecterBaoStock
tradingviewTradingView global instruments, served by Baostock-Tradingview-ConnecterBaoStock
mockDebug only: local MOCK-100 / MOCK-10000 K-lines, no backend needed, always online

Backend repos live alongside this one (outside the monorepo).

One-Command Dev Startup

Clone the data-source backends first (idempotent: skips directories that already exist):

pnpm setup

Then run pnpm dev with a -c argument to start the frontend and the selected connecters together:

pnpm dev # frontend only (Vite dev server)
pnpm dev -c all # frontend + all backends (gotdx + binance + baostock)
pnpm dev -c gotdx baostock # frontend + selected backends
pnpm dev -c tdx # aliases supported (tdx / g / b / bnb / all)
pnpm dev -c all --lan # same, dev server bound to 0.0.0.0 (LAN accessible)

Common shorthands:

pnpm dev:all # frontend + all backends
pnpm dev:g # frontend + gotdx (Tongdaxin)
pnpm dev:b # frontend + BaoStock / TradingView
pnpm dev:bnb # frontend + Binance depth
pnpm dev:lan:all # frontend (0.0.0.0) + all backends

Parallel process logs stay in one terminal and are separated by colored source prefixes: [vite], [gotdx], [binance], and [baostock].

Backend only (no frontend):

pnpm connecter # all backends
pnpm connecter gotdx # gotdx (Tongdaxin) :8080
pnpm connecter baostock # BaoStock / TradingView :8000

After pnpm setup, no extra setup is needed. The dev server proxies /api/stock:8000 (Baostock-Tradingview-Connecter) and /api/public:8080 (GoTDX-Connecter).

🚀 Quick Start

3. Install and Use

npm install @363045841yyt/klinechart @363045841yyt/klinechart-core

Use the component:

<template>
<divclass="app-container":data-theme="currentTheme">
<KlineChartv-model:theme="currentTheme" :custom-data="customData" :settings="chartSettings" />
</div>
</template>
<script setup lang="ts">import { ref } from'vue'importtype { ChartSettings } from'@363045841yyt/klinechart-core'import { typeCustomDataSource, KlineChart } from'@363045841yyt/klinechart'importdemoDatafrom'./demo-data.json'const currentTheme =ref<'light'|'dark'>('dark')const customData =ref<CustomDataSource>(demoDataasCustomDataSource)const chartSettings:ChartSettings= { showGridLines: true, isAsiaMarket: true, showVolumePriceMarkers: false, mainLeftAxisDisplaySetting: 'none', theme: 'dark', colorPresetSettings: { dark: { candleUpBody: '#e85d04', candleDownBody: '#1b4332', crosshairLine: '#faa307', gridMajor: '#3e2723', }, }, }</script>
<style>.app-container {display: flex;flex-direction: column;height: 80vh; }.app-container[data-theme='dark'] {background: #000;color: #e5e7eb; }</style>

Import CSS in main.ts:

import'@363045841yyt/klinechart/style.css'import{createApp}from'vue'importAppfrom'./App.vue'createApp(App).mount('#app')

Slot Usage — Custom Tooltip:

<KlineChart><template#kline-tooltip="{ hoverData, upColor, downColor }"><divclass="custom-tooltip"><divclass="custom-tooltip__title"><span>{{ hoverData.stockCode }}</span><span>{{ formatTimestamp(hoverData.timestamp, { timeZone: 'Asia/Shanghai' }) }}</span></div><divclass="custom-tooltip__price"
:style="{ color: hoverData.close >= hoverData.open ? upColor : downColor }"
>
{{ hoverData.close.toFixed(2) }}
</div><divclass="custom-tooltip__detail">
O: {{ hoverData.open.toFixed(2) }}<br/>
H: {{ hoverData.high.toFixed(2) }}<br/>
L: {{ hoverData.low.toFixed(2) }}<br/>
C: {{ hoverData.close.toFixed(2) }}
</div></div></template></KlineChart>

Slot Usage — Custom Main-Pane Legend:

Providing #legend fully replaces the default Canvas legend. The slot scope is the full LegendTemplateContext (OHLC, timeshare, main indicators, comparisons, layout, colors).

<template #legend="{ index, currentBar, timeshare, indicators, comparisons, colors }">
<divclass="my-legend">
<!-- Custom fields added to KLineData[] for PR #98 are exposed through currentBar -->
<divv-if="currentBar"class="my-legend__row">
<span:style="{ color: currentBar.color }">
开盘 {{ currentBar.open.toFixed(2) }} 最高 {{ currentBar.high.toFixed(2) }} 最低
{{ currentBar.low.toFixed(2) }} 收盘 {{ currentBar.close.toFixed(2) }}
</span>
<spanv-if="currentBar.volumeText"> Vol {{ currentBar.volumeText }}</span>
</div>
<divv-if="timeshare"class="my-legend__row">
<span:style="{ color: timeshare.changeColor }">
现价 {{ timeshare.price.toFixed(2) }} 涨幅 {{ timeshare.changePercent.toFixed(2) }}%
</span>
</div>
<!-- Using main chart indicator legend data -->
<divv-for="indicator in indicators":key="indicator.name"class="my-legend__row">
<span>{{ indicator.name }}:</span>
<templatev-for="valueinindicator.values" :key="value.label">
<span:style="{ color: value.color }">
{{ value.label }} {{ value.value.toFixed(3) }}
</span>
</template>
</div>
<!-- Using comparison commodity data -->
<divv-for="comparison in comparisons":key="comparison.symbol"class="my-legend__row":style="{ color: comparison.percentColor }"
>
{{ comparison.symbol }}
{{ comparison.percent > 0 ? '+' : '' }}{{ comparison.percent.toFixed(2) }}%
</div>
</div>
</template>

4. (Optional) Enable MCP / AI Agent Control

npm install @363045841yyt/klinechart-ai-runtime
<template>
<divclass="app-container">
<KlineChart ref="chartRef" :mcp="mcpConfig" />
</div>
</template>
<script setup lang="ts">import { ref } from'vue'import { KlineChart } from'@363045841yyt/klinechart'import { executeTool } from'@363045841yyt/klinechart-ai-runtime'const chartRef =ref<InstanceType<typeofKlineChart> |null>(null)const mcpConfig = { wsUrl: 'ws://localhost:8080', autoReconnect: true,onToolCall: (call) => {const ctrl =chartRef.value?.getController?.()if (!ctrl) return { success: false, error: 'Controller not ready' }returnexecuteTool(ctrl, call) }, }</script>
<style>.app-container {height: 80vh; }</style>

Then start the MCP server:

cd packages/ai-runtime
pnpm inspect

Connect via MCP Inspector and call chart.zoomToLevel, indicators.add, etc.

📖 More Documentation

📋 Component Props

PropTypeDefaultDescription
semanticConfigSemanticChartConfigSemantic configuration (optional). When provided, drives chart data, indicators, markers and chart options
theme'light' | 'dark'Chart theme. Use v-model:theme for two-way binding
isFullscreenbooleanControlled fullscreen state. Leave unbound for internal (non-controlled) mode
timezonestring'Asia/Shanghai'Time zone for date/time display
yPaddingPxnumber20Y-axis padding in pixels
minKWidthnumber1Minimum K-line width (logical pixels)
maxKWidthnumber50Maximum K-line width (logical pixels)
rightAxisWidthnumber0Right price axis width
leftAxisWidthnumber0Left price axis width (0 = hidden)
bottomAxisHeightnumber24Bottom time axis height
priceLabelWidthnumber60Price label extra width for showing change percentage
zoomLevelsnumber20Total number of zoom levels
initialZoomLevelnumber3Initial zoom level (1 ~ zoomLevels)
customDataCustomDataSourceInline data bundle: { symbol?, period?, data, comparisons? }. Bypasses the fetcher pipeline entirely. See example above
teleportContainerstring | HTMLElementTeleport target for dropdowns/modals (CSS selector or element). Defaults to internal .chart-wrapper
mcpMcpConfigMCP/AI runtime bridge config: { wsUrl?, autoReconnect?, onToolCall? }. See @363045841yyt/klinechart-ai-runtime

🗺️ Roadmap

  • v0.10: AI-native chart support
  • K-line zoom anchor stability, improved zoom feel
  • Right axis detached from scroll container, completely solving clipping issues
  • Blank area drawing support
  • Limit vertical pan range to prevent viewport from leaving data
  • Drawing system
  • Right axis zoom
  • Latest price line and right axis label style optimization
  • Area primitive tools and rendering
  • More advanced drawing tools
  • Support for minute, multi-day, monthly, and yearly K-line display
  • Support convert the drawing to quant code

📦 Packages

PackageDescriptionnpm
@363045841yyt/klinechart-coreHeadless chart engine + controllersnpm
@363045841yyt/klinechartVue 3 bindingsnpm
@363045841yyt/klinechart-reactReact bindingsnpm
@363045841yyt/klinechart-angularAngular bindingsnpm
@363045841yyt/klinechart-ai-runtimeMCP server + AI tool schemas (optional)npm

🚀 What's New

  • v0.9.0 Self-developed Core-layer reactive state model migration, timing issues eliminated
  • v0.9.0 Single-path Scene renderer + WebGPU backend (hybrid DOM canvas, no compositeTo), FrameTransaction reactivity, device-lost recovery, auto-fallback WebGPU → WebGL → Canvas2D
  • v0.8 Symbol comparison, multi-source data aggregation
  • v0.7 Renderer registration chain AOP refactoring with decorator syntax, monorepo split, Vue/React bindings (experimental), standalone core package, tokenized color system
  • v0.6.10 Unified WebGL rendering context sharing for all panes, plus sub-pane lifecycle refactoring — centralized pane instance management via SubPaneManager with first-class paneId identity
  • v0.6.6 Comprehensive rendering optimizations: batched price-to-Y calculations, cached tick positions and geometry, optimized month-key operations; achieves stable 190-200fps on 200Hz displays with frame generation time down to 2ms
  • v0.6.3 WebGL rendering for K-lines, volume bars, and MACD bars; significant performance boost across the board
  • v0.6.1 Dual-layer canvas architecture: Main + Overlay separation with UpdateLevel filtering, achieves stable 180fps with low jitter on 200Hz displays
  • v0.6.0 Stateless indicator pipeline: MA/BOLL/EXPMA/ENE/RSI/CCI/STOCH/MOM/WMSR/KST/FASTK now use unified Calculator → Scheduler → StateStore → Renderer architecture for better performance and maintainability
  • v0.5.6 Logarithmic price axis with evenly distributed grid lines at pixel level
  • v0.5.2 Advanced drawing tools: parallel channel, regression channel, smooth top/bottom, and non-intersecting channel
  • v0.5.0 Complete drawing tool system, supporting line, rectangle, text drawing and style editing
  • v0.4 Modern UI, left toolbar, right axis optimization, TradingView-style zoom feel

📄 License

MIT

About

High-performance financial charting library with Canvas/WebGL/WebGPU hybrid rendering, delivering crisp multi-DPR visuals at 1-3ms GPU time per frame. Features plugin-based rendering and visual signal annotation. Exposes JSON semantic configuration for Agent-driven quantitative visualization. Works seamlessly across Vue, React, and Angular (soon).

Topics

Resources

Stars

22 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages