금융 차트
캔들 차트와 함께 쓰는 대시보드·보고서용 차트입니다. 각 차트는 요소와 옵션을 받는 클래스로, 요소 크기에 맞춰지고 차트의 다크 또는 라이트 테마로 그려집니다. 대부분은 포인터를 따라 툴팁을 보여 줍니다.
● 데모자산 곡선과 낙폭브라우저에서 생성한 시뮬레이션 시장 데이터차트 목록
| 클래스 | 용도 |
|---|---|
BarChart | 범주별 값: 순매수 흐름, 세션별 거래량, 월별 수익률. 묶음 또는 누적, 세로 또는 가로, 0을 기준으로 위아래로. |
DonutChart | 전체 중 부분: 자산 배분, 섹터별 익스포저. innerRadius: 0이면 파이 차트입니다. |
ScatterChart | 항목마다 두 값: 리스크 대비 수익률, 밸류에이션 대비 성장률. 점에 크기가 있으면 버블이 됩니다. |
HistogramChart | 값의 분포: 일별 수익률, 거래 결과. 평균이나 VaR 위치에 선을 표시합니다. |
CalendarChart | 달력 위에 하루 하나의 값: 일간 수익률, 손익, 매매 일지. |
MatrixChart | 행과 열의 쌍마다 하나의 값: 상관관계, 시간대와 요일별 거래량. |
CounterClockChart | 봉마다 평균 가격과 평균 거래량을 이은 종목의 역시계곡선. |
SparklineChart | 관심 종목 행이나 KPI 타일 속의 작은 선. |
GaugeChart | 구간과 비교해 보는 하나의 값: 시장 심리, 리스크, 증거금 사용률. |
HeatmapChart | 등락으로 색칠한 셀. 격자 또는 비중(시가총액)으로 크기를 정한 트리맵. grouped를 쓰면 섹터 맵이 됩니다. |
WaterfallChart | 시작부터 끝까지의 단계: 손익 기여도 분석, 현금 흐름. |
DepthChart | 호가창의 누적 매수/매도 잔량. |
EquityCurveChart | 시간에 따른 계좌 가치, 낙폭과 벤치마크 포함. |
PerformanceDashboard | 백테스트로 만드는 전략 보고서: 통계, 자산 곡선, 낙폭, 월별 수익률. |
공통 기능
const chart = new BarChart(element, { categories, series, theme: 'dark' })
chart.setOptions({ mode: 'stacked' }) // 어떤 옵션이든, 병합됨
chart.setTheme('light') // 'dark' | 'light' | Theme
chart.destroy() // 캔버스와 리스너를 제거 각 차트는 요소를 가득 채우고, 요소 크기가 바뀌면 다시 그립니다. 마우스를 올렸을 때 툴팁이 나오는 차트는 crosshair: false로 끌 수 있습니다. 막대, 도넛, 산점도, 히스토그램, 캘린더, 행렬 차트는 무엇을 보여 주는지 스크린 리더에
알립니다(캔버스에 image 역할과 라벨이 붙습니다). ariaLabel을 쓰면 이를 직접 고른 말로, 예를 들어 페이지의
언어로 바꿀 수 있습니다. 숫자는 valueFormat(또는 xFormat / yFormat)으로
표시되며, 지정하지 않으면 1,234.5 형식, 1만을 넘으면 12.3K 형식입니다.
막대 차트
import { BarChart } from '@tradecanvas/chart'
// 10개 세션의 외국인 순매수: 0 위는 초록, 아래는 빨강.
const flows = new BarChart(el, {
categories: ['6/10', '7/10', '8/10', '9/10'],
series: [{ name: 'Net', values: [-660, 860, -280, 230] }],
colorBySign: true, // 또는 { positive, negative }
valueFormat: (v) => v + ' bn',
onBarClick: ({ category, series, value, index }) => openDay(index),
})
// 여러 시리즈를 나란히, 또는 누적으로: 양수는 0에서 위로, 음수는 아래로.
new BarChart(el, {
categories: ['Foreign', 'Proprietary', 'Retail'],
series: [{ name: 'Buy', values: [820, 310, 4200] }, { name: 'Sell', values: [-760, -280, -4290] }],
mode: 'stacked',
orientation: 'horizontal', // 막대는 오른쪽으로, 라벨은 왼쪽에
showValues: true,
})
flows.update(categories, series) 값 축에는 항상 0이 포함됩니다. 범주에 마우스를 올리면 그 범주의 모든 시리즈 값이 표시되고, 시리즈가 둘 이상이면
범례가 나타납니다(legend로 선택). 아래쪽에 다 들어가지 않는 라벨은 몇 범주마다 하나씩 표시됩니다.
도넛 차트
import { DonutChart } from '@tradecanvas/chart'
new DonutChart(el, {
data: [
{ label: 'Stocks', value: 52 },
{ label: 'Bonds', value: 23 },
{ label: 'Cash', value: 15 },
{ label: 'Gold', value: 10, color: '#d4a017' },
],
innerRadius: 0.6, // 0이면 파이 차트
centerLabel: 'Total',
centerValue: '1.2B ₫',
onSliceClick: (slice) => filterBy(slice.label),
}) 조각은 12시 방향에서 시계 방향으로 놓이며, 0 이하의 값은 빠집니다. 각 조각은 공간이 있으면 비중을 표시하고, 범례는 이름과 비중을 나열합니다. 범례는 차트가 넓으면 링 옆에, 그렇지 않으면 아래에 놓입니다.
산점도와 버블 차트
import { ScatterChart } from '@tradecanvas/chart'
new ScatterChart(el, {
series: [{
name: 'Banks',
points: [
{ x: 21, y: 9, size: 480, label: 'VCB' }, // size: 시가총액, 버블 면적이 이에 비례
{ x: 34, y: 24, size: 170, label: 'TCB' },
],
}],
xLabel: 'Volatility',
yLabel: 'Return, a year',
xFormat: (v) => v + '%',
yFormat: (v) => v + '%',
showLabels: true,
onPointClick: (point, series) => openSymbol(point.label),
}) 축은 가장 큰 버블이 들어갈 여백을 남기고(maxRadius, 기본 24 px), 축 범위가 x = 0이나 y = 0을 지나면
그 자리에 선을 긋습니다(zeroLines: false로 숨김).
히스토그램
import { HistogramChart, histogramBins } from '@tradecanvas/chart'
new HistogramChart(el, {
values: dailyReturns, // 퍼센트 단위
binWidth: 0.5, // 또는 bins: 20, 또는 'auto'(Sturges 규칙)
colorBySign: true,
valueFormat: (v) => v.toFixed(1) + '%',
markers: [{ value: mean, label: 'Mean' }, { value: var95, label: 'VaR 95%', color: '#e85a67' }],
})
histogramBins([1, 2, 2, 3, 10], { bins: 3 })
// [{ from: 1, to: 4, count: 4 }, { from: 4, to: 7, count: 0 }, { from: 7, to: 10, count: 1 }] 캘린더
import { CalendarChart } from '@tradecanvas/chart'
// 1년 치 거래일(월~금)을 그날의 등락으로 색칠합니다.
new CalendarChart(el, {
data: [{ date: '2025-01-02', value: 1.2 }, { date: '2025-01-03', value: -0.8 }], // YYYY-MM-DD
weekdays: 5, // 7(기본값)은 매일, weekStart: 0이면 주가 일요일에 시작
locale: 'vi-VN', // 월과 요일 이름
colorScale: { min: -2, max: 2 }, // 테마의 빨강과 초록, ±2에서 가장 진하게
valueFormat: (v) => v.toFixed(2) + '%',
onDayClick: (day) => openSession(day.date),
}) 주는 왼쪽에서 오른쪽으로, 요일은 위에서 아래로 놓이며, 한 해에 한 줄씩 최대 10년입니다. 차트 높이가 모자라면 가장 오래된 해부터 빠집니다. 값이 없는 날은 빈 칸으로 그리고, 아래의 색상 막대가 색 척도를 보여 줍니다(legend: false로 숨김).
상관 행렬
import { MatrixChart, correlationMatrix } from '@tradecanvas/chart'
// 가격이 아닌 일간 수익률을 넘깁니다. 종목마다 배열 하나, 날짜는 같게.
const names = ['VCB', 'BID', 'CTG', 'TCB']
const values = correlationMatrix(returnsByStock)
new MatrixChart(el, {
rows: names, // 정사각이 아닌 행렬은 columns: [...]
values, // values[row][column]
triangle: 'lower', // 상관관계는 절반이면 충분
colorScale: { min: -1, max: 1 },
onCellClick: ({ row, column, value }) => compare(row, column),
}) 셀은 정사각형을 유지하고 들어갈 때 값을 표시합니다(valueFormat이 없으면 소수 둘째 자리). 셀 너비에 맞지 않는 열 이름은 기울입니다. correlationMatrix는 두 시계열 모두 값이 있는 날만 짝지으며, 3일 미만이면 NaN을 돌려주고 그 셀은 비워 둡니다. 시간대와 요일별 거래량 같은 다른 수치 표에도 맞습니다.
섹터 맵
import { HeatmapChart } from '@tradecanvas/chart'
new HeatmapChart(el, {
data: [
{ id: 'vcb', label: 'VCB', value: 0.8, weight: 480, group: '은행' },
{ id: 'hpg', label: 'HPG', value: 1.9, weight: 160, group: '철강' },
{ id: 'vhm', label: 'VHM', value: -2.4, weight: 170, group: '부동산' },
],
grouped: true, // 섹터별로, 그다음 종목별로 타일 배치
valueFormat: (v) => v.toFixed(1) + '%',
}) 각 섹터는 종목 비중의 합만큼 자리를 차지하고, 들어갈 때 타일 위쪽에 섹터 이름과 가중 평균 등락을 표시합니다. 히트맵의 색은 colorScale에 min과 max를 주지 않으면 -5에서 5까지입니다.
역시계곡선
import { CounterClockChart } from '@tradecanvas/chart'
const clock = new CounterClockChart(el, {
data: bars, // OHLCV 봉, 오래된 것부터
period: 25, // 평균에 넣을 봉 수
points: 120, // 그릴 최신 점의 수
xLabel: '거래량, 평균', yLabel: '가격, 평균',
onPointClick: (p) => goTo(p.time),
})
clock.getPhase() // 1~8: 마지막 움직임의 방향 각 점은 거래량(가로)과 종가(세로)의 25봉 평균이며, 시간 순서로 이어지고 오래될수록 흐려집니다. 건강한 순환은 시계 반대 방향으로 돕니다. getPhase()(와 counterClockPhase(points))는 마지막 움직임을 알려 줍니다: 1 거래량 증가, 2 가격과 거래량 동반 상승, 3 가격 상승, 4 거래량 감소 속 가격 상승, 5 거래량 감소, 6 동반 하락, 7 가격 하락, 8 거래량 증가 속 가격 하락.
스파크라인, 게이지, 히트맵, 워터폴, 시장 심도, 자산 곡선
import { SparklineChart, GaugeChart, HeatmapChart, WaterfallChart, DepthChart, EquityCurveChart } from '@tradecanvas/chart'
new SparklineChart(el, { data: closes, mode: 'area', showLastPoint: true })
const gauge = new GaugeChart(el, {
value: 72, min: 0, max: 100, label: 'Fear & Greed',
zones: [{ from: 0, to: 45, color: '#e8505b' }, { from: 45, to: 55, color: '#8a93a3' }, { from: 55, to: 100, color: '#1fa874' }],
})
gauge.setValue(64)
// 시가총액으로 크기를, 당일 등락으로 색을 정한 트리맵.
new HeatmapChart(el, {
data: [{ id: 'vcb', label: 'VCB', value: 1.2, weight: 480 }, { id: 'fpt', label: 'FPT', value: -0.8, weight: 170 }],
weighted: true, showLabels: true, showValues: true,
onCellClick: (cell) => openSymbol(cell.label),
})
new WaterfallChart(el, { data: [{ label: 'Start', value: 10000, type: 'total' }, { label: 'Fees', value: -85 }, { label: 'End', value: 9915, type: 'total' }] })
new DepthChart(el, { data: { bids, asks }, midPriceLine: true, spreadLabel: true })
new EquityCurveChart(el, { data: equity, benchmark, drawdown: true }) 성과 대시보드
PerformanceDashboard는 백테스트로 전략 보고서를 구성합니다. 주요 통계 띠, 자산 곡선, 그 아래의 낙폭,
월별 수익률 달력으로 이루어집니다. 분석 백테스터와 함께 사용하세요.
import { Backtester } from '@tradecanvas/analytics'
import { PerformanceDashboard } from '@tradecanvas/chart'
const result = new Backtester({ initialCash: 10_000 }).run(bars, myStrategy)
const dash = new PerformanceDashboard(document.getElementById('report')!, {
result, // { equityCurve, metrics }를 가진 무엇이든: Backtester 결과를 그대로 넣으면 됨
theme: 'dark',
title: 'SMA Crossover',
subtitle: 'BTC/USDT · 1h · 2023',
})
// 나중에: dash.update(newResult) · dash.setTheme('light') · dash.destroy() 레이아웃을 직접 구성할 수 있도록 계산 함수도 export되어 있습니다: computeMonthlyReturns, computeDrawdownCurve, toEquityPoints, selectKeyStats. 축을 직접 그릴 때는 niceScale(min, max)를 쓰세요(눈금 간격 1, 2, 2.5, 5).