Skip to content

363045841/KLineChartQuant

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

611 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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 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.




✨ 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

🚀 Quick Start

Prerequisites

The chart loads K-line / timeshare / depth via DataFetcher. For local development, keep related repos under the same parent directory:

workspace/
├── KLineChartQuant/      # This repository (frontend)
├── stockbao/             # BaoStock backend (optional, port 8000)
└── KlineChartQuantGo/    # TDX + Binance backends (optional, ports 8080 / 8081)

Data Sources

Source source Backend repo Default port Capabilities How to start
baostock stockbao 8000 A-share K-lines (daily/weekly/monthly/5–60m) see below
gotdx KlineChartQuantGo services/tdx-api 8080 A-share + overseas K-lines, timeshare, ticks see below
binance same repo services/binance-api 8081 Binance L2 depth (SSE) see below
tradingview / mock none demo / fixtures built-in

Pick a source via symbol config:

// K-lines via gotdx
{ symbol: '600519', period: 'daily', source: 'gotdx' }

// K-lines via baostock
{ symbol: 'sh.600519', period: 'daily', source: 'baostock' }

// Depth heatmap via Binance SSE (default URL)
import { BinanceSSESource, DEFAULT_BINANCE_SSE_URL } from '@363045841yyt/klinechart-core'
const depth = new BinanceSSESource('btcusdt') // → http://localhost:8081/api/binance/depth-events

Start backends (as needed):

# 1) BaoStock — http://localhost:8000
cd KLineChartQuant
npm run stockbao
# or: cd ../stockbao && uv run python ./server.py

# 2) TDX gotdx — http://127.0.0.1:8080
cd ../KlineChartQuantGo
go run . tdx

# 3) Binance depth — http://127.0.0.1:8081
go run . binance
# Set HTTP_PROXY / HTTPS_PROXY if Binance needs a proxy
# (defaults to http://127.0.0.1:6666 when unset)

Frontend adapters:

Source Adapter Main endpoints
baostock packages/core/src/data/baostock.ts GET :8000/api/stock/kdata?...
gotdx packages/core/src/data/gotdx.ts POST :8080/api/stock/*, /api/ex/*
binance packages/core/src/data/binance.ts GET :8081/api/binance/depth-events, /orderbook

You can also skip backends entirely and pass inline bars via customData (see example below).

1. Clone Repositories

git clone https://github.com/363045841/KLineChartQuant.git
# optional backends
git clone https://github.com/363045841/stockbao.git
git clone https://github.com/363045841/KlineChartQuantGo.git

2. 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,
    showVolumePriceMarkers: false,
    leftAxisType: '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>
  <KlineChart>
    <template #legend="{ ohlc, indicators, comparisons, colors }">
      <div class="my-legend" v-if="ohlc">
        <span :style="{ color: ohlc.color }">
          O {{ ohlc.open.toFixed(2) }}
          H {{ ohlc.high.toFixed(2) }}
          L {{ ohlc.low.toFixed(2) }}
          C {{ ohlc.close.toFixed(2) }}
        </span>
        <span v-for="ind in indicators" :key="ind.name" class="my-legend__ind">
          {{ ind.name }}
          <template v-if="ind.values">
            <span
              v-for="v in ind.values"
              :key="v.label"
              :style="{ color: v.color }"
            >
              {{ v.label }} {{ v.value.toFixed(3) }}
            </span>
          </template>
        </span>
        <span v-for="c in comparisons" :key="c.symbol" :style="{ color: c.percentColor }">
          {{ c.symbol }} {{ c.percent > 0 ? '+' : '' }}{{ c.percent.toFixed(2) }}%
        </span>
      </div>
    </template>
  </KlineChart>
</template>

4. (Optional) Enable MCP / AI Agent Control

npm install @363045841yyt/klinechart-ai-runtime
<template>
  <div class="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<typeof KlineChart> | 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' }
      return executeTool(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

  • Rendering Pipeline - Current paint path: FrameTransaction, Scene/Layer, Renderer backends

📋 Component Props

Prop Type Default Description
semanticConfig SemanticChartConfig Semantic configuration (optional). When provided, drives chart data, indicators, markers and chart options
dataFetcher DataFetcher built-in routerDataFetcher Routes by source to registered adapters (baostock / gotdx / …); see Data Sources above
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 50 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 20 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
mcp McpConfig MCP/AI runtime bridge config: { wsUrl?, autoReconnect?, onToolCall? }. See @363045841yyt/klinechart-ai-runtime

🗺️ Roadmap

  • 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-ai-runtime MCP 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 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 React, Vue, and Angular (soon).

Topics

Resources

License

Stars

16 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors