backtestcharts
v1.1.26
Published
Responsive, theme-aware React candlestick widget with taapi.io indicators, drawing tools, and animated backtesting
Maintainers
Readme
backtestcharts
A responsive, theme-aware React candlestick widget. Uses klinecharts for rendering and taapi.io for OHLCV, indicators (60+ library entries), and RSI. Includes drawing tools, position boxes, animated strategy backtesting, and works across phones, tablets, and desktops out of the box.
Supports Binance crypto (BTC/USDT) and US stocks (type=stocks).
Install
npm install backtestchartsPeer dependencies (install in your app if not already present):
npm install react react-dom klinechartsStyles
Import the built CSS once in your app entry:
import 'backtestcharts/styles.css'The stylesheet ships Tailwind's output plus a set of --bt-* CSS variables for theming (see Theming).
Use
Important (Vite): The published bundle is built ahead of time. import.meta.env inside the package is frozen at publish time, so this library does not read VITE_* internally. Your app must read env and pass props:
import BacktestChartWidget from 'backtestcharts'
import 'backtestcharts/styles.css'
export function Page() {
return (
<div style={{ height: '100vh' }}>
<BacktestChartWidget
taapiSecret={import.meta.env.VITE_TAAPI_SECRET}
taapiProxy={import.meta.env.VITE_TAAPI_PROXY === 'true'}
taapiBaseUrl={import.meta.env.VITE_TAAPI_BASE_URL}
defaultSymbol="BTCUSDT"
interval="1m"
theme="auto"
accent="#f97316"
/>
</div>
)
}Give the parent a height so the chart can fill the layout.
Props
Data
| Prop | Default | Description |
|---|---|---|
| taapiSecret | — | taapi.io secret — loads OHLCV from /candles plus indicators/RSI |
| taapiProxy | false | When true, requests omit the secret; use a server that injects it (see taapi_proxy in this workspace) |
| taapiBaseUrl | https://api.taapi.io | Override taapi root (e.g. http://localhost:4010 for the standalone proxy) |
| apiBaseUrl | — | Legacy backend for GET /candles when taapiSecret is omitted |
| exchange | 'binance' | TAAPI crypto exchange id (ignored for US stocks) |
| interval | '1m' | Initial chart interval |
| marketType | inferred | 'crypto' | 'stocks' |
| defaultSymbol | BTCUSDT | "ETHUSDT" / "AAPL", or { candle, taapi, label } |
| symbols | TAAPI list | Replace the built-in search universe |
UI & behaviour
| Prop | Default | Description |
|---|---|---|
| showHeader | false | Title + description bar at the top |
| showSymbolSearch | true | Symbol picker + interval select in the indicator strip |
| showBacktest | true | "Backtest" + "Reset view" action buttons |
| showDrawingRail | true | Left-side drawing rail (desktop) / FAB (phone) |
| embedMode | true | Tighter padding; drops the header description |
| defaultRsiPeriod / rsiPeriod / onRsiPeriodChange | 14 | Controlled / uncontrolled RSI length |
| className, style | — | Applied to the widget root |
Theming (new in 1.1)
| Prop | Default | Description |
|---|---|---|
| theme | 'auto' | 'dark' \| 'light' \| 'auto'. 'auto' follows prefers-color-scheme live. |
| accent | theme default | CSS color for default drawing color, primary buttons, focus rings. E.g. "#f97316". |
| density | 'comfortable' | 'comfortable' \| 'compact'. Compact tightens control heights — good for small embeds. |
| themeTokens | — | Advanced: override any --bt-* CSS variable. { bg: '#111', border: '#333', panel: '#1a1a1a' } |
Callbacks
| Prop | Description |
|---|---|
| onIntervalChange | (interval: string) => void |
| onSymbolChange | (symbol: ChartSymbol) => void |
| onLoad | ({ symbol, candleCount }) => void after candles load |
| onError | (err) => void on load/fetch failures |
Theming
The widget ships both dark and light palettes. theme="auto" respects the user's OS preference and updates live when they flip it — no reload needed.
Quick tweaks
// Brand accent only (the fastest customization)
<BacktestChartWidget theme="dark" accent="#f97316" />
// Swap a few tokens without leaving dark mode
<BacktestChartWidget
theme="dark"
themeTokens={{
panel: '#0b0f14',
border: 'rgba(99, 102, 241, 0.35)',
accent: '#6366f1',
}}
/>Deep customisation via CSS
All surfaces reference CSS variables with the --bt- prefix. Override them in your app CSS:
/* Applies to every widget on the page */
[data-bt-theme='dark'] {
--bt-bg: #08080c;
--bt-panel: #11131a;
--bt-accent: #8b5cf6;
--bt-candle-up: #38bdf8;
--bt-candle-down: #f43f5e;
}Full token reference:
| Surface | Border | Text | Semantic | Chart |
|---|---|---|---|---|
| --bt-bg | --bt-border | --bt-text | --bt-accent / --bt-accent-soft / --bt-accent-fg | --bt-candle-up / --bt-candle-down |
| --bt-panel | --bt-border-strong | --bt-text-muted | --bt-success / --bt-success-soft | --bt-buy / --bt-sell |
| --bt-panel-elev | --bt-border-subtle | --bt-text-dim | --bt-danger / --bt-danger-soft | |
| --bt-overlay | | --bt-text-faint | --bt-warning / --bt-warning-soft | |
| --bt-scrim | | | | |
Shadows use --bt-shadow (elevated surfaces) and --bt-shadow-inner.
Responsive
Breakpoints match Tailwind defaults: sm 640px, md 768px, lg 1024px.
- Phone (<640px): drawing rail collapses to a floating action button that opens a bottom-sheet tool picker; the drawing overlay toolbar docks to the bottom edge; the indicator strip stacks and scrolls horizontally; modals render as bottom sheets.
- Tablet (640–1024px): vertical drawing rail, modals centered, indicator strip wraps.
- Desktop (≥1024px): full layout with hover tooltips, preview pane in symbol search, floating drawing toolbar anchored to the selection.
You can hide individual chrome via showHeader, showSymbolSearch, showBacktest, showDrawingRail for tight embeds.
Browser CORS
TAAPI blocks direct browser calls to https://api.taapi.io for many endpoints. Use the taapi_proxy Express server (TAAPI_SECRET only on the server) and set taapiProxy + taapiBaseUrl, or run your own reverse proxy to Taapi.
Develop this repo
npm install
cp .env.example .env # either VITE_TAAPI_SECRET, or VITE_TAAPI_PROXY + VITE_TAAPI_BASE_URL (see ../taapi_proxy)
npm run dev- Demo app build:
npm run build→dist/ - Library build (for npm):
npm run build:lib→dist-lib/
prepublishOnly runs build:lib before npm publish.
Install from a local path (without publishing)
npm install ../backtestCharts
# or
npm install file:/absolute/path/to/backtestChartsThen import BacktestChartWidget from 'backtestcharts' as above.
License
MIT
