Skip to content

About

High-performance financial charting terminal with Canvas/WebGL/WebGPU backends, 1–3ms GPU time per frame, plugin-based rendering, visual signal annotation, AI-native architecture. Seamlessly supports Vue, React, and Angular.

Topics

Resources

Stars

33 stars

Watchers

0 watching

Forks

Latest commit

 

History

1,545 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

High-performance financial charting infrastructure with a single-frame generation time of just 2 ms, stable scrolling at 190–200 fps in a 200 Hz environment, a native AI-Native chart architecture, full-link ResizeObserver-driven crisp rendering, a QuickJS indicator runtime, and support for running scripts against the in-house KCQ financial analysis API to render indicators.

English | 简体中文

📈 KLineChartQuant

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

npm version npm downloads license demo

qq tg


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.

🤖 Agent-Native Architecture

KLineChartQuant treats the Agent as a first-class citizen of the chart, equal in standing to the human user. It is not a chat layer bolted on top: the Agent operates the chart through the same primitives as the UI, and the endpoints it acts on are exposed by the chart core itself.

  • The Agent is the user, and the user is the Agent: The Agent is not a guest of the chart; it is an operator with the same standing as the person in front of the screen. Everything a user can do through the UI, the Agent can do through the same entry points, and vice versa. Equality of access is the design premise, not a toggle.

  • The Agent serves the chart, not a stream of text: An embedded Agent exists to drive the chart the user is looking at, not to bury them in prose. Its output lands as real interaction on the surface the user sees—indicators, drawings, viewport changes—with conversation only as the means. The chart and its interaction remain the subject.

  • AI-Native architecture, not a parasitic layer: Tools are woven into the chart API primitives as aspects rather than wrapped in a separate layer, so there is one implementation, naturally consistent state, and zero bridge overhead. Zed is the reference: its agent is built into the editor's own foundation (GPUI). VS Code is the counter-example: Copilot and Claude Code enter through the extension layer, where the Claude extension is essentially a GUI wrapper around an external CLI. The former makes the Agent native; the latter makes it parasitic.

  • The Agent pushes the architecture toward stability and efficiency: Adding an Agent adds no architectural burden; it forces the architecture to be better. Because every capability must be exposed through a single API and unified primitives, state is consolidated into one source of truth and kept absolutely consistent—scattered state, derived copies, multi-write paths, parallel pipelines, and races cannot survive. The Agent and the user travel the same path, and that constraint settles into a more stable, testable chart core.

  • No blind use of MCP: The project evolved through three stages—an early JSON-configuration approach, then MCP, and finally an AI-Native architecture. MCP demands an intermediate layer or DSL that spends tokens, loses information, and keeps a second copy of state that invades frontend logic. The current design drops the bridge entirely: tools register directly on the chart core, and a single call reaches the kernel.

  • The reactive kernel is the Agent's foundation: StateKernel is the single source of truth—only actions may write, computed values derive automatically, and external consumers receive readonly signals, backed by batched atomic snapshots and frozen state. The kernel is zero-dependency, extremely light, and has controllable render timing. This lets the Agent share the user's exact state at near-zero cost and keeps tools a subset of actions rather than a parallel system.

✨ Core Features

  • Agent Native - The chart core exposes its capabilities as @Tool-decorated domain primitives, and the Agent calls the same primitives as the UI. Tools are a subset of actions: one shared state, one execution path, no bridge layer
  • Script Indicators - Write indicators in plain TypeScript. Sandboxed QuickJS execution with time and memory budgets, a built-in editor with completions and hover signatures, and plots that flow through the normal rendering chain
  • 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
  • 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 the #kline-tooltip slot, 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. The AI Agent drives the chart through the same @Tool primitives as the UI, sharing one state source instead of a 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/>KLineChart (direct core) · KLineChartWC (Vue Web Component)"]
        AngularPkg["@363045841yyt/klinechart-angular"]
        Agent["AI Agent"]
        AgentRt["@363045841yyt/klinechart-agent-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 · Drawing<br/>Timeshare · Compare · Components"]
    end

    subgraph conn["Market Data Backends"]
        Go["GoTDX-Connector<br/>gotdx :8080"]
        Bn["Binance-Connector<br/>Binance spot K-line / trades :8091"]
        Bs["Baostock-Tradingview-Connector<br/>BaoStock / TradingView :8000"]
        Mt["KCQ-MT5-connector<br/>MT5 (Exness) :8090"]
        Th["KCQ-THS-connector<br/>THS daily bars :8092"]
    end

    UI --> VuePkg
    UI --> ReactPkg
    UI --> AngularPkg
    VuePkg -->|"Web Component"| ReactPkg
    Agent --> AgentRt
    VuePkg --> Ctl
    ReactPkg --> Ctl
    AngularPkg --> Ctl
    AgentRt -->|"@Tool primitives (same path as UI)"| 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
    Mt -->|"market data + SSE"| Data
    Th -->|"market data (daily)"| 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 / MT5 / THS / mock) and Binance Spot K-lines and trades.
  • Plugin subsystem — PluginHost / HookSystem / EventBus / RendererPluginManager; indicators and drawing tools plug in as Scene Layers.
  • React bindings — @363045841yyt/klinechart-react's KLineChart mounts the core directly (client-only, no Vue runtime); KLineChartWC renders the full-UI <kline-chart> Custom Element bundled from the Vue package (@363045841yyt/klinechart/web-component).
  • Agent Native — @363045841yyt/klinechart-agent-runtime orchestrates the Agent, which invokes the core's @Tool-registered primitives—the same entry points the UI uses.

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

📜 Script Indicators

Indicators can be written as plain TypeScript instead of being compiled ahead of time. A script is one file that declares a single indicator through defineIndicator; the engine compiles it once, then runs it bar by bar and collects Plot points. Scripts are data-source and render agnostic — the host supplies the bars, the chart adapter renders the result.

defineIndicator({
  name: 'Volume Tide',
  position: Position.Sub,
  onBar() {
    const RED = '#F08080'
    const RED_LIGHT = 'rgba(240, 128, 128, 0.5)'
    const RED_LIGHTER = 'rgba(240, 128, 128, 0.15)'
    const GREEN = '#008000'
    const GREEN_LIGHT = 'rgba(0, 128, 0, 0.5)'
    const GREEN_LIGHTER = 'rgba(0, 128, 0, 0.1)'
    const GRAY_LIGHTER = 'rgba(128, 128, 128, 0.15)'

    const barUp = ta.rising(close, 1)
    const barDn = ta.falling(close, 1)
    const volumeChange = ta.change(volume)

    const volumeColor = barUp
      ? RED_LIGHTER
      : barDn ? GREEN_LIGHTER : GRAY_LIGHTER

    plot.Columns(volume, 'Volume columns', {
      color: volumeColor,
    })

    const volumeChangeColor = barUp
      ? (volumeChange > 0 ? RED : RED_LIGHT)
      : barDn
        ? (volumeChange > 0 ? GREEN : GREEN_LIGHT)
        : Color.Gray

    plot.Histogram(volumeChange, 'Volume change columns', {
      color: volumeChangeColor,
      size: 12,
    })

    plot.Line(0, 'Zero line', {
      color: Color.Gray,
    })
  },
})

Everything a script needs is injected as a global before it runs:

Global Meaning
open high low close volume time price series; close reads the current bar, close[1] one bar back
input.int input.float input.bool input.string declare a parameter at the top level of onBar; the variable reads back the user's value
plot.Line plot.Columns plot.Histogram plot.Point plot.Shape plot.Char plot.Arrow emit plot points; the method name selects the shape; each returns a handle
fill(from, to, color, title, options?) fill the area between two plots; from / to are handles returned by plot.*
ta built-in technical analysis library
Position Position.Main or Position.Sub
Color common Material 400 colors, or pass any CSS color string
defineIndicator / defineLibrary / importLibrary declare the indicator, declare a library, use a library

Parameters are plain const declarations, so the variable name is the parameter identity — no inputs block and no params object:

onBar() {
  const period = input.int(20, { title: 'Period', min: 1 })
  const type = input.string('SMA', { options: ['SMA', 'EMA'] })
  plot.Line(type === 'SMA' ? ta.sma(close, period) : ta.ema(close, period), 'ma')
}

The built-in ta library covers sma, ema, wma, vwma, rsi, highest, lowest, crossover, crossunder, rising, falling and change. User libraries use the same defineLibrary call and join the same global namespace.

  • Sandboxed execution - Scripts run in an embedded QuickJS runtime with per-run time and memory budgets, so a runaway script fails instead of hanging the host
  • No future data - History that is not yet available reads as NaN; a script can never look ahead
  • Real editor - The chart ships a CodeMirror-based script editor with completions, hover signatures, and signature help generated from the same declarations the compiler uses
  • Same rendering path - Plots flow through the engine's normal Plot, axis, and legend chain, so script indicators behave exactly like built-in ones

Register scripts through the script service; each one then appears in the indicator picker as a normal entry:

import { createScriptService } from '@363045841yyt/klinechart-script-chart'

const scripts = await createScriptService()
await scripts.create(source)

See the script docs for the full declaration reference, libraries, and Plot API.

⚡ Performance

KLineChartQuant submits drawing primitives directly to Canvas2D, WebGL2 or WebGPU. These measurements come from the reproducible benchmark in bench/ (node bench/run.mjs), sampled on 2026-10-03 with analytic line AA enabled for GPU backends. Configuration: 1180 × 640 viewport, DPR 2, 4× MSAA, 120 warm-up frames and 600 sampled frames per scenario. Hardware: NVIDIA GeForce RTX 4060 Laptop GPU, driver 616.92, headless Chrome 154.0.8037.93, forced to the discrete GPU. Observed FPS is capped by the calibrated 200 Hz refresh rate.

Measurement scope: fixed geometry is built once during warm-up and replayed from cache. Frame Prepare P50 measures the cache lookup and geometry retrieval; 0.000 ms is a rounded value, not zero computation or the cost of rebuilding indicators. CPU Submit measures synchronous backend processing and API submission, not GPU completion. GPU time is measured separately with timer queries; Canvas2D has no page-level GPU timer. This benchmark does not cover continuous geometry rebuilding during scrolling, zooming or data updates, and is not directly comparable to the previous README measurements that rebuilt geometry every frame.

WebGPU Command Submission

Seven command buffers submitted as one batched queue.submit versus seven separate submissions; 50 warm-up samples, 400 measured samples, 100 repetitions per sample:

Submission P50 (ms)
One queue.submit (batched) 0.003
Seven queue.submit (split) 0.025
Speedup 8.33×

MA5 / MA20 / MA60 (Simple Indicator)

Visible K-lines Backend Frame Prepare P50 (ms) CPU Submit P50 (ms) GPU P50 (ms) FPS 1% Low Frame P99 (ms) Severe Jank
1,000 Canvas2D 0.000 0.700 N/A 98.3 52.4 19.10 48.33%
1,000 WebGL2 0.000 0.500 0.127 199.3 163.9 6.10 0.00%
1,000 WebGPU 0.000 0.300 0.036 200.0 192.3 5.20 0.00%
5,000 Canvas2D 0.000 1.100 N/A 104.7 66.2 15.10 28.33%
5,000 WebGL2 0.000 1.800 0.212 199.3 192.3 5.20 0.00%
5,000 WebGPU 0.000 0.500 0.050 200.0 192.3 5.20 0.00%
10,000 Canvas2D 0.000 5.600 N/A 38.8 22.2 45.00 99.00%
10,000 WebGL2 0.000 2.800 0.712 199.0 192.3 5.20 0.17%
10,000 WebGPU 0.000 1.200 0.022 199.0 181.7 5.50 0.17%

Ichimoku (Complex Rendering Workload)

Visible K-lines Backend Frame Prepare P50 (ms) CPU Submit P50 (ms) GPU P50 (ms) FPS 1% Low Frame P99 (ms) Severe Jank
1,000 Canvas2D 0.000 0.800 N/A 68.5 33.9 29.50 60.00%
1,000 WebGL2 0.000 1.000 0.116 200.0 192.3 5.20 0.00%
1,000 WebGPU 0.000 0.900 0.053 199.3 169.4 5.90 0.17%
5,000 Canvas2D 0.000 5.150 N/A 25.8 15.5 64.60 100.00%
5,000 WebGL2 0.000 2.500 0.302 195.1 100.0 10.00 0.83%
5,000 WebGPU 0.000 1.400 0.129 198.0 146.7 6.82 0.33%
10,000 Canvas2D 0.000 7.000 N/A 28.6 15.4 64.90 100.00%
10,000 WebGL2 0.000 3.700 0.534 184.9 97.0 10.31 3.00%
10,000 WebGPU 0.000 1.800 0.134 198.0 160.4 6.24 0.50%

1% Low is the reciprocal of frame interval P99; Severe Jank is the share of intervals exceeding twice the calibrated refresh interval (10 ms here). Results are from one complete repeat run, not selected best cases. Browser scheduling and system load cause variation between runs; these numbers do not establish that analytic AA improves GPU performance or that all workloads avoid regressions. Source: bench/results/render-bench-analytic-aa-confirmation.json and .csv (local generated artifacts).

📡 Data Sources

KLineChart requires a market data backend. Supported data sources:

Data Source Description Docs
gotdx Tongdaxin (GOTDX) quotes: A-share / futures / MAC, served by GoTDX-Connector GoTDX-Connector
binance Binance Spot K-lines and real tick-by-tick trades (footprint / order-flow), served by Binance-Connector Binance-Connector
baostock BaoStock A-share daily / weekly / monthly & minute K-lines, served by Baostock-Tradingview-Connector BaoStock
tradingview TradingView global instruments, served by Baostock-Tradingview-Connector BaoStock
mt5 MT5 (Exness) local terminal: forex / metals / crypto CFDs, served by KCQ-MT5-connector MT5
ths Tonghuashun (THS): A-share / index / ETF / futures / options daily bars, served by KCQ-THS-connector THS
mock Debug 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:backends

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

pnpm dev                      # frontend only (Vite dev server)
pnpm dev -c all               # frontend + all backends (gotdx + binance + baostock; mt5 / ths excluded)
pnpm dev -c gotdx baostock    # frontend + selected backends
pnpm dev -c mt5               # frontend + MT5 local terminal (Windows + logged-in MT5 terminal)
pnpm dev -c ths               # frontend + THS daily bars (needs THS_API_KEY or ths.api_key in config.json)
pnpm dev -c tdx               # aliases supported (tdx / g / b / bnb / m / t / 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 spot market data
pnpm dev:mt5                  # frontend + MT5 local terminal
pnpm dev:ths                  # frontend + THS daily bars
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], [baostock], [mt5], and [ths].

In Windows PowerShell, run node scripts/dev.mjs -c gotdx (or use the other -c arguments above) to finish shutdown logs before the next prompt after Ctrl+C. pnpm dev adds a pnpm process that also receives Ctrl+C; the child script cannot control when pnpm prints [ELIFECYCLE].

Backend only (no frontend):

pnpm connector                # all backends (mt5 / ths excluded)
pnpm connector gotdx          # gotdx (Tongdaxin) :8080
pnpm connector binance        # binance (Binance spot K-line & trades) :8091
pnpm connector baostock       # BaoStock / TradingView :8000
pnpm connector mt5            # MT5 local terminal :8090 (Windows + logged-in MT5 terminal)
pnpm connector ths            # THS daily bars :8092 (needs THS_API_KEY or ths.api_key in config.json)

For backend only with the same shutdown ordering, run node scripts/start-connector.mjs gotdx.

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

🚀 Quick Start

3. Install and Use

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

Use the component:

<template>
  <div class="app-container" :data-theme="currentTheme">
    <KlineChart v-model:theme="currentTheme" :custom-data="customData" :settings="chartSettings" />
  </div>
</template>

<script setup lang="ts">
  import { ref } from 'vue'
  import type { ChartSettings } from '@363045841yyt/klinechart-core'
  import { type CustomDataSource, KlineChart } from '@363045841yyt/klinechart'
  import demoData from './demo-data.json'

  const currentTheme = ref<'light' | 'dark'>('dark')

  const customData = ref<CustomDataSource>(demoData as CustomDataSource)

  const chartSettings: ChartSettings = {
    showGridLines: true,
    isAsiaMarket: true,
    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'
import App from './App.vue'

createApp(App).mount('#app')

Slot Usage — Custom Tooltip:

<KlineChart>
  <template #kline-tooltip="{ hoverData, upColor, downColor }">
    <div class="custom-tooltip">
      <div class="custom-tooltip__title">
        <span>{{ hoverData.stockCode }}</span>
        <span>{{ formatTimestamp(hoverData.timestamp, { timeZone: 'Asia/Shanghai' }) }}</span>
      </div>
      <div
        class="custom-tooltip__price"
        :style="{ color: hoverData.close >= hoverData.open ? upColor : downColor }"
      >
        {{ hoverData.close.toFixed(2) }}
      </div>
      <div class="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 }">
  <div class="my-legend">
    <!-- Custom fields added to KLineData[] for PR #98 are exposed through currentBar -->
    <div v-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>
      <span v-if="currentBar.volumeText"> Vol {{ currentBar.volumeText }}</span>
    </div>

    <div v-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 -->
    <div v-for="indicator in indicators" :key="indicator.name" class="my-legend__row">
      <span>{{ indicator.name }}:</span>
      <template v-for="value in indicator.values" :key="value.label">
        <span :style="{ color: value.color }">
          {{ value.label }} {{ value.value.toFixed(3) }}
        </span>
      </template>
    </div>
    <!-- Using comparison commodity data -->
    <div
      v-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>

Host toolbar controls

Use #toolbar-start and #toolbar-end to place host account or workspace controls in the native toolbar. Both slots are optional and inherit the resolved chart theme. They stay outside the draggable, scrolling chart controls.

<KlineChart>
  <template #toolbar-start><AccountMenu /></template>
  <template #toolbar-end><WorkspaceActions /></template>
</KlineChart>

4. (Optional) Add AI Agent Control

The chart core exposes its domain capabilities as @Tool primitives. Both the UI and the Agent call them through the same path:

import { getRegisteredChartTools } from '@363045841yyt/klinechart-core/controllers'

getRegisteredChartTools() returns every tool with its parameter schema, safety level, and unified executor. Hand them to @363045841yyt/klinechart-agent-runtime, which orchestrates the Agent inside your app (browser or Electron) against a Provider profile — no MCP bridge, no side-channel state. See agent-runtime.

📖 More Documentation

  • Rendering Pipeline - Current paint path: FrameTransaction, Scene/Layer, Renderer backends
  • Script Indicators - Declaring an indicator in TypeScript: inputs, Plot API, libraries

📋 Component Props

Prop Type Default Description
theme 'light' | 'dark' — Chart theme. Use v-model:theme for two-way binding
isFullscreen boolean — Controlled fullscreen state. Leave unbound for internal (non-controlled) mode
timezone string 'Asia/Shanghai' Time zone for date/time display
yPaddingPx number 20 Y-axis padding in pixels
minKWidth number 1 Minimum K-line width (logical pixels)
maxKWidth number 200 Maximum K-line width (logical pixels)
rightAxisWidth number 0 Right price axis width
leftAxisWidth number 0 Left price axis width (0 = hidden)
bottomAxisHeight number 24 Bottom time axis height
priceLabelWidth number 60 Price label extra width for showing change percentage
zoomLevels number 80 Total number of zoom levels
initialZoomLevel number 3 Initial zoom level (1 ~ zoomLevels)
customData CustomDataSource — Inline data bundle: { symbol?, period?, data, comparisons? }. Bypasses the fetcher pipeline entirely. See example above
teleportContainer string | HTMLElement — Teleport target for dropdowns/modals (CSS selector or element). Defaults to internal .chart-wrapper

🗺️ 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

Package Description npm
@363045841yyt/klinechart-core Headless chart engine + controllers npm
@363045841yyt/klinechart Vue 3 bindings npm
@363045841yyt/klinechart-react React bindings npm
@363045841yyt/klinechart-angular Angular bindings npm
@363045841yyt/klinechart-agent-runtime Framework-neutral Agent runtime (Pi orchestration + host contracts) npm
@363045841yyt/klinechart-script Sandboxed script indicator engine (QuickJS runtime + language service) npm
@363045841yyt/klinechart-script-chart Registers script indicators as chart indicators npm
@363045841yyt/klinechart-plot-contracts Plot declaration contracts shared by the engine and the script runtime npm

🚀 What's New

  • v0.11 Introduced the AI Agent runtime (agent-runtime and AI runtime with OpenAI protocol support and a shared web/Electron Agent workspace) plus @tool registration and drawing Agent tools. Drawing gained sub-pane and timeshare support with workspace isolation, multi-select and batch editing, blank-area anchors, inline text editing, marquee group drag, and configurable labels; five-day timeshare, native timeshare indicators, and persistent view workspaces landed alongside WebGL-on-visible-canvas rendering.
  • v0.10 Reworked the data layer around a unified MarketDataProvider, added multi-day timeshare, a unified indicator query pipeline shared by charts and Agents, Fibonacci/rectangle/arrow annotation tools, and promoted comparison to a first-class chart mode. Aligned the Vue/React/Angular bindings with the unified provider contract and shipped multiple rendering and state-consistency fixes.
  • 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

Apache-2.0

About

High-performance financial charting terminal with Canvas/WebGL/WebGPU backends, 1–3ms GPU time per frame, plugin-based rendering, visual signal annotation, AI-native architecture. Seamlessly supports Vue, React, and Angular.

Topics

Resources

Stars

33 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages