Skip to content

MG-Trading-Terminal/mg-exchange-chart

Repository files navigation

@mg-exchange/charts

Professional financial charting library for cryptocurrency exchanges.

Zero dependencies. Canvas 2D + WebGL. TypeScript. Works with React, Vue, or vanilla JS.

Live Demo | API Reference | Trading Integration | Examples


Why

  • No production-ready OSS charting library covers: indicators + drawings + multi-pane + real-time + trading
  • Existing open-source options lack drawing tools, multi-pane layouts, or real-time streaming
  • Commercial solutions are expensive and vendor-locked

Exchange Charts fills that gap — free, open-source, production-ready.

Features

Rendering

  • Canvas 2D with optional WebGL acceleration (67x faster at 500K bars)
  • Layered canvases: background, series, crosshair, drawings, UI — only dirty layers re-render
  • 60fps with 100K visible bars, 1M loaded, 5 indicators, 20 drawings

Chart Types

Candlestick, Heikin Ashi, OHLC Bars, Line, Area, Baseline

21 Built-in Indicators

Category Indicators
Trend SMA, EMA, Ichimoku Cloud, TWAP, Supertrend, EMA Ribbon, Parabolic SAR, ADX
Momentum RSI, MACD, Stochastic, Williams %R, Rate of Change
Volatility Bollinger Bands, ATR, Envelope
Volume VWAP, OBV, MFI, Cumulative Volume Delta, Volume Profile
Smart Money Order Blocks, Fair Value Gaps, BOS/CHoCH, Market Structure

47 Drawing Tools

Category Tools
Lines Trend Line, Ray, Info Line, Extended Line, Horizontal/Vertical/Cross Line, Polyline
Channels Parallel Channel, Regression Channel, Pitchfork
Fibonacci Retracement, Extension, Channel, Time Zone, Speed Fan, Circles, Spiral, Arcs, Wedge
Gann Box, Square, Fan
Patterns XABCD, ABCD, Head & Shoulders, Triangle, Three Drives
Elliott Impulse (12345), Correction (ABC), Triangle (ABCDE)
Shapes Rectangle, Ellipse, Arc, Arrow, Brush
Text Text, Callout, Note, Flag
Trading Long/Short Position (TP/SL/P&L), Forecast
Measure Price Range, Date Range, Fixed Range Volume Profile

Drawing tools show real calculations: angle, bars, price change, %, channel width, Fibonacci levels, standard deviation.

Trading Integration

  • Order lines (limit, stop, TP, SL, entry, liquidation, breakeven)
  • Position overlays with P&L zones (Bybit-style)
  • Draggable order lines
  • Customizable trade actions — exchange provides its own UI
  • Serialization: getOrderLines() / loadOrderLines()

More

  • Real-time: WebSocket streaming with bar construction and tick updates
  • Multi-pane: Separate panes for oscillators with resize handles
  • Multi-chart: Grid layouts (2x2, 2x3) with synced crosshair/timeframe
  • Mobile: Pinch-to-zoom, momentum scroll, long-press crosshair
  • Themes: Dark/light, fully customizable
  • Persistence: Serialize/restore drawings, indicators, order lines
  • Price alerts: Directional alerts with callbacks

Install

npm install @mg-exchange/charts

Quick Start

import { Chart } from '@mg-exchange/charts';
import { sma, rsi, bollingerBands } from '@mg-exchange/charts';

const chart = new Chart({
  container: '#chart',
  symbol: 'BTCUSDT',
  timeframe: '1H',
  datafeed: myDatafeed,
  renderer: 'webgl',
});

// Add indicators
chart.addIndicator(sma, { period: 20 });
chart.addIndicator(rsi, { period: 14 });
chart.addIndicator(bollingerBands, { period: 20, stdDev: 2 });

// Drawing tools
chart.setDrawingTool('fib-retracement');

// Events
chart.on('crosshairMove', ({ price, time, bar }) => { /* ... */ });
chart.on('barUpdate', (bar) => { /* real-time update */ });

Datafeed Interface

Implement 3 methods to connect any data source:

import type { Datafeed } from '@mg-exchange/charts';

const myDatafeed: Datafeed = {
  async getBars({ symbol, timeframe, from, to, limit }) {
    const res = await fetch(`/api/klines?symbol=${symbol}&interval=${timeframe}&limit=${limit}`);
    return res.json();
  },

  subscribe({ symbol, timeframe, onBar, onTick }) {
    const ws = new WebSocket(`wss://stream.example.com/${symbol}`);
    ws.onmessage = (e) => {
      const data = JSON.parse(e.data);
      onTick({ time: data.time, price: data.price, volume: data.volume });
    };
    return () => ws.close();
  },

  async searchSymbols(query) {
    return [{ symbol: 'BTCUSDT', name: 'Bitcoin / USDT', exchange: 'Binance' }];
  },
};

Trading API

The chart provides primitives for exchanges to build their own trading UI. The chart does not place orders — it gives you events and rendering tools.

Basic: Order Lines + Position Overlays

import type { OrderLine, PositionOverlayData } from '@mg-exchange/charts';

// Show a limit order on chart
chart.addOrderLine({
  id: 'order-1',
  price: 87500,
  type: 'limit',
  side: 'buy',
  label: 'BUY LIMIT 0.05',
  quantity: 0.05,
});

// Update when price changes
chart.updateOrderLine('order-1', { price: 87400 });

// Show position with TP/SL zones (Bybit-style)
chart.setPositionOverlays([{
  side: 'long',
  entryPrice: 87500,
  quantity: 0.05,
  currentPrice: 87800,
  pnl: 15.0,
  breakeven: 87587.5,
  tpLevels: [{ price: 89250, quantity: 0.05 }],
  slLevels: [{ price: 86625, quantity: 0.05 }],
}]);

// Serialize/restore
const lines = chart.getOrderLines();
chart.loadOrderLines(lines);

Events

// User clicked "+" on price axis or right-click trade menu
chart.on('tradeRequested', ({ side, price, type, action }) => {
  // 'side': 'buy' | 'sell'
  // 'price': clicked price level
  // 'type': 'limit' | 'market'
  // 'action': custom action string (if using custom context menu)
  showMyOrderForm({ side, price, type });
});

// User dragged an order line to a new price
chart.on('orderLineMoved', ({ id, price }) => {
  updateOrderOnServer(id, price);
});

Custom Trade Actions (for exchanges)

Override the default "+" button and right-click menu with your own UI:

chart.setTradeMode(true, {
  // Replace default "+" behavior with your handler
  onTradeAction: ({ price, clientX, clientY, suggestedSide }) => {
    showMyOrderPopup({ price, x: clientX, y: clientY, side: suggestedSide });
  },

  // Or customize the right-click menu items
  contextMenuItems: (price) => [
    { label: `Limit Buy @ ${price.toFixed(2)}`, action: 'limit-buy' },
    { label: `Limit Sell @ ${price.toFixed(2)}`, action: 'limit-sell' },
    { label: 'Place OCO Order', action: 'oco', separator: true },
    { label: 'Set Alert', action: 'alert' },
  ],

  // Callback when user drags order lines
  onOrderLineDrag: (id, newPrice) => {
    modifyOrderOnExchange(id, newPrice);
  },

  // Control individual features
  showPlusButton: true,
  showContextMenu: true,
  draggableOrderLines: true,
});

Granular Control

// Enable trade mode without any built-in UI
chart.setTradeMode(true, {
  showPlusButton: false,
  showContextMenu: false,
  onTradeAction: myHandler,
});

// Listen to raw click events and build completely custom UX
chart.on('click', ({ price, time }) => {
  if (myState.placingOrder) {
    placeOrderAt(price);
  }
});

React Wrapper

import { ChartContainer, useChart } from '@mg-exchange/charts/react';

function TradingChart() {
  const chartRef = useChart();

  return (
    <ChartContainer
      ref={chartRef}
      options={{
        symbol: 'BTCUSDT',
        timeframe: '1H',
        datafeed: myDatafeed,
        theme: 'dark',
      }}
      style={{ width: '100%', height: 600 }}
    />
  );
}

Multi-Chart Layout

import { MultiChart } from '@mg-exchange/charts';

const multi = new MultiChart({
  container: '#charts',
  layout: '2x2',
  datafeed: myDatafeed,
  syncCrosshair: true,
  syncTimeframe: true,
  charts: [
    { symbol: 'BTCUSDT', timeframe: '1H' },
    { symbol: 'ETHUSDT', timeframe: '1H' },
    { symbol: 'SOLUSDT', timeframe: '1H' },
    { symbol: 'BTCUSDT', timeframe: '1D' },
  ],
});

WebGL Rendering

const chart = new Chart({
  // ...
  renderer: 'webgl',
});

// Falls back to Canvas 2D automatically if WebGL2 unavailable
console.log(chart.getRendererBackend()); // 'webgl' or 'canvas2d'

WebGL uses dedicated OHLC shaders — raw price data uploaded to GPU, coordinate math in vertex shader. 67x improvement at 500K bars.

Chart Options

interface ChartOptions {
  container: HTMLElement | string;
  symbol: string;
  timeframe: Timeframe;
  datafeed: Datafeed;
  chartType?: ChartType;
  priceScale?: PriceScaleMode;
  theme?: 'dark' | 'light' | Theme;
  renderer?: 'canvas2d' | 'webgl';
  pricePrecision?: number;
  trading?: Partial<TradeOptions>;
  features?: Partial<ChartFeatures>;
}

Full API Reference

// ── Chart Control ──────────────────────────────────────
chart.setSymbol('ETHUSDT');
chart.setTimeframe('4H');
chart.setChartType('heikin_ashi');
chart.setTheme('light');
chart.goToLive();
chart.exportPNG('chart.png');
chart.destroy();

// ── Indicators ─────────────────────────────────────────
const id = chart.addIndicator(indicator, params);
chart.removeIndicator(id);
chart.setVolumeProfile(true);

// ── Drawings ───────────────────────────────────────────
chart.setDrawingTool('trend-line');
chart.setDrawingTool(null);
chart.clearDrawings();
chart.removeDrawing(id);
chart.updateDrawing(id, { color: '#ff0000' });
chart.toggleDrawingVisible(id);
chart.toggleDrawingLock(id);
chart.reorderDrawing(id, newIndex);
chart.bringDrawingToFront(id);
chart.sendDrawingToBack(id);
const drawings = chart.getDrawings();
chart.loadDrawings(drawings);
chart.getDrawingInstances();
chart.setMagnetMode(true);

// ── Trading ────────────────────────────────────────────
chart.setTradeMode(true, options);
chart.setTradeOptions(options);
chart.addOrderLine(line);
chart.updateOrderLine(id, updates);
chart.removeOrderLine(id);
chart.clearOrderLines();
chart.getOrderLines();
chart.loadOrderLines(lines);
chart.setPositionOverlays(positions);

// ── Alerts ─────────────────────────────────────────────
chart.addAlert(price);
chart.removeAlert(id);

// ── Compare ────────────────────────────────────────────
chart.addCompare('ETHUSDT');
chart.removeCompare('ETHUSDT');

// ── Events ─────────────────────────────────────────────
chart.on('crosshairMove', cb);
chart.on('barUpdate', cb);
chart.on('click', cb);
chart.on('drawingAdded', cb);
chart.on('drawingRemoved', cb);
chart.on('drawingModified', cb);
chart.on('drawingSelected', cb);
chart.on('drawingDeselected', cb);
chart.on('tradeRequested', cb);
chart.on('orderLineMoved', cb);
chart.on('symbolChange', cb);
chart.on('timeframeChange', cb);
chart.on('visibleRangeChange', cb);
chart.on('dataLoaded', cb);
chart.off(event, cb);

Theming

import type { Theme } from '@mg-exchange/charts';

const customTheme: Theme = {
  name: 'midnight',
  bg: '#0a0a0a',
  gridLine: '#1a1a1a',
  bullCandle: '#00ff88',
  bearCandle: '#ff4444',
  bullCandleWick: '#00ff88',
  bearCandleWick: '#ff4444',
  text: '#e0e0e0',
  textSecondary: '#808080',
  crosshairLine: '#555555',
  crosshairLabel: '#333333',
  // ... see Theme interface for all 30+ properties
};

chart.setTheme(customTheme);

Custom Indicators

import type { Indicator } from '@mg-exchange/charts';
import { registerIndicator } from '@mg-exchange/charts';

const myIndicator: Indicator = {
  name: 'My VWMA',
  shortName: 'VWMA',
  description: 'Volume Weighted Moving Average',
  overlay: true,
  params: [{ name: 'period', type: 'number', default: 20, min: 1, max: 500 }],

  calculate(bars, params) {
    const { period } = params;
    return bars.map((_, i) => {
      if (i < period - 1) return { values: [NaN] };
      let sumPV = 0, sumV = 0;
      for (let j = i - period + 1; j <= i; j++) {
        sumPV += bars[j].close * bars[j].volume;
        sumV += bars[j].volume;
      }
      return { values: [sumPV / sumV] };
    });
  },

  plots: [{ type: 'line', color: '#FF6D00', lineWidth: 2 }],
};

registerIndicator(myIndicator);
chart.addIndicator(myIndicator, { period: 20 });

Development

git clone https://github.com/iZonex/mg-exchange-chart.git
cd mg-exchange-chart
npm install
npm run dev          # Dev server with live Binance data
npm run build        # Build library (dist/)
npm run test         # Run all tests
npm run typecheck    # tsc --noEmit
npm run lint         # ESLint

Examples

See the examples/ directory:

License

Apache 2.0

About

Professional financial charting library for cryptocurrency exchanges. Canvas 2D + WebGL, 60+ drawing tools, 20+ indicators, real-time streaming.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors