AI Generated Documentation
This document provides a comprehensive overview of the OpenBackTest project structure. It is intended to help developers and AI agents navigate the codebase efficiently.
OpenBackTest is a high-performance trading backtesting utility built with React and Vite.
- Charting Engine: KlineCharts is used for high-performance financial charting.
- State Management: Zustand handles global application state, split into backtest playback and trading simulation.
- Styling: Modern, dark-themed UI built with custom CSS utilities and
lucide-reacticons.
The codebase follows a Decoupled Bridge Architecture:
- State (Pure): Stores handle raw data and math (PnL, aggregation). They are chart-agnostic.
- View (Declarative): React components manage layout and user input.
- Hooks (The Bridge): These "watch" the State and imperatively update the Chart Engine (
chart.applyNewData(),chart.createOverlay()). - Engine (Imperative): KlineCharts handles high-performance Canvas rendering via extensions in
lib/chart/.
UI components categorized by functional area.
ChartGrid.tsx: Dynamic, resizable grid layout usingreact-resizable-panelsto display up to 3 charts simultaneously.TradingChart/: All components related to the chart interface (overlays, menus, legends, individual chart containers).Controls.tsx: Top navigation, data loading controls, and session import/export management.PlaybackBar.tsx: The bottom timeline and playback controls.TradingPanel.tsx: The right-side panel for trade execution and account status.StatsModal.tsx: Performance analysis dashboard with equity curve and export features.
Custom React hooks encapsulating complex logic.
useChart.ts: Lifecycle management for the KlineCharts instance.useIndicators.ts: Logic for adding, removing, and managing technical indicators.useTradeOverlays.ts: Rendering logic for TP/SL lines and trade entry areas.useContextMenu.ts: Logic for the chart's right-click interaction.
Zustand stores defining the global state and actions.
useBacktestStore.ts: Controls data playback (Play/Pause/Step), symbol selection, and multi-chart state management (array ofChartConfig).useTradeStore.ts: Core trading engine. Manages positions, orders, PnL calculations, trade history, and session statistics.useChartStyleStore.ts: Manages styling properties for the chart, such as bullish/bearish candle colors, and persists user settings in localStorage.
Low-level extensions for KlineCharts.
customIndicators.ts: Definitions for complex indicators like Volume Profile (VPVR).overlays.ts: Registration of custom visual elements (e.g., TP/SL lines).constants.ts: Shared IDs and configuration constants for the chart.
index.ts: Shared TypeScript interfaces for Candles, Trades, and Timeframes.indicatorTypes.ts: Types specific to indicator configurations.
| File | Responsibility |
|---|---|
src/App.tsx |
Main application shell and layout. Hosts the ChartGrid. |
src/components/ChartGrid.tsx |
Manages the resizable split-pane layout for multiple charts. |
src/hooks/useChart.ts |
Initializes chart, handles data updates, and manages responsive resizing with isolated container IDs. |
src/store/useBacktestStore.ts |
Centralizes data state; includes stepForward, togglePlayback, loadData, updateLiveCandle, and multi-chart configurations. |
src/store/useTradeStore.ts |
Executes trades; tracks account equity, leverage, and aggregates positions for statistics. |
src/store/useBinanceStore.ts |
Manages Binance Futures connection state, symbols, and live polling. |
src/store/useChartStyleStore.ts |
Central store managing persistent chart styles and styling properties. |
src/components/TradingChart/CandleStyleEditor.tsx |
Floating overlay editor for bullish/bearish candle, border, and wick colors. |
src/components/StatsModal.tsx |
Calculates and displays Win Rate, Profit Factor, R/R, and Equity Curve; handles CSV exports. |
src/lib/chart/customIndicators.ts |
Mathematical logic for indicators not natively supported by KlineCharts. |
src/components/TradingChart/ContextMenu.tsx |
UI for the right-click menu (Set TP/SL, Reset View). |
src/components/TradingChart/DrawingToolbar.tsx |
Left-side sidebar for chart annotation tools (Lines, Measures). |
src/hooks/useIndicators.ts |
Bridges the store state to the KlineCharts indicator API. |
src/utils/aggregation.ts |
Logic to convert 1m raw data into higher timeframes (5m, 1h, etc.). |
src/services/binance.ts |
Handles Binance API interactions (fetching symbols, historical klines, live polling). |
- Adding a New Indicator:
- Define logic in
src/lib/chart/customIndicators.ts. - Add the indicator name to
INDICATORS_LISTinsrc/hooks/useIndicators.ts.
- Define logic in
- Modifying Trading Logic:
- Edit
src/store/useTradeStore.tsfor execution logic. - Edit
src/hooks/useTradeOverlays.tsto change how positions look on the chart.
- Edit
- Adjusting Statistics & Reporting:
- Statistics are calculated in
src/components/StatsModal.tsxusingfinishedPositionsfrom the trade store. - To add new metrics, update the
Positioninterface inuseTradeStore.tsand the calculation logic inStatsModal.tsx.
- Statistics are calculated in
KlineCharts: For chart API questions.Zustand: For state management patterns.VPVR: For Volume Profile logic.useBacktestStore: For playback control.StatsModal: For performance metrics and reporting.
When working on features, bug fixes, or enhancements, you MUST adhere to the following rules:
- Test Directory Structure: All unit and integration tests MUST be placed in the root
tests/directory (e.g.,tests/store,tests/components,tests/hooks). Do not place__tests__folders or.test.tsfiles alongside the source code in thesrc/directory. - Testing Stack: The project uses
vitest,jsdom, and@testing-library/react. - Mocking: When writing tests for complex React hooks and Zustand stores (especially those interacting with the canvas or browser APIs), actively use
@testing-library/react'srenderHookandvitest'svi.mock()/vi.spyOn(). - Coverage: When adding new UI components or data stores, ensure that you provide corresponding test coverage. Run
npm run coverageto verify your changes.
- Data Source: CSV/JSON loaded into
useBacktestStore. - Aggregation:
useBacktestStoreusesaggregation.tsto prepare data for the current timeframe. - Rendering:
useChartdetects data changes and callschart.applyNewData(). - Interaction: User actions trigger
useTradeStore, which updates overlays viauseTradeOverlays. - Completion: When a simulation is finished,
useTradeStoreaggregates all trades intofinishedPositionsand triggers theStatsModal.
graph TD
%% Layers
subgraph UI ["View Layer (React)"]
App["App.tsx"]
Controls["Controls.tsx"]
ChartGrid["ChartGrid.tsx"]
ChartUI["TradingChart/index.tsx"]
CandleEditor["TradingChart/CandleStyleEditor.tsx"]
Stats["StatsModal.tsx"]
end
subgraph Logic ["Logic & State (Zustand)"]
BS["useBacktestStore (Playback)"]
TS["useTradeStore (Execution & Stats)"]
CSS["useChartStyleStore (Styles)"]
BNS["useBinanceStore (Live Data)"]
end
subgraph Bridge ["Bridge Hooks (Glue)"]
UC["useChart (Lifecycle)"]
UIH["useIndicators (Math)"]
UT["useTradeOverlays (Visuals)"]
end
subgraph Engine ["Engine Layer"]
KC["KlineCharts (Canvas)"]
Lib["lib/chart/* (Extensions)"]
end
%% Mapping
App --> Controls & ChartGrid & Stats
ChartGrid --> ChartUI
Controls --> BS & TS & BNS
BNS --> BS
ChartUI --> UC & UIH & UT & CandleEditor
CandleEditor --> CSS
Stats --> TS
UC & UIH & UT --> KC
UC --> CSS
KC <--> Lib
BS --> Agg["aggregation.ts"]
OpenBackTest supports connecting directly to the Binance Futures API to stream historical and live market data.
src/services/binance.ts: Handles fetching futures symbols, historical 1m klines, and REST-based live polling (every 1.5s).src/store/useBinanceStore.ts: Zustand store that manages the Binance connection state (isBinanceConnected,isBinanceLoading), available symbols, and the current active symbol. When connected, it clears the chart, loads historical data intouseBacktestStore, and starts the live polling service.src/store/useBacktestStore.ts: ExposesupdateLiveCandle(kline)to update the most recent candle or append a new one when the timestamp advances.
Import trades from another platform and analyze them using OpenBackTest's Statistics Modal. Construct a JSON file that mimics the internal session state. Load a CSV file into the application before importing the JSON session file.
JSON structure required to populate the statistics:
{
"backtest": {},
"trade": {
"initialBalance": 10000,
"isFinished": true,
"showStatsModal": true,
"tradeHistory": [
{
"id": "trade-1",
"type": "buy",
"price": 50000,
"time": 1704067200,
"quantity": 1,
"fee": 0,
"realizedPnL": 0,
"positionSize": 1,
"entryPrice": 50000,
"balance": 10000
},
{
"id": "trade-2",
"type": "sell",
"price": 51000,
"time": 1704070800,
"quantity": 1,
"fee": 10,
"realizedPnL": 1000,
"positionSize": 0,
"entryPrice": null,
"balance": 11000
}
],
"finishedPositions": [
{
"id": "pos-1",
"type": "long",
"entryPrice": 50000,
"exitPrice": 51000,
"quantity": 1,
"pnl": 1000,
"openTime": 1704067200,
"closeTime": 1704070800,
"trades": []
}
]
}
}
Key Fields to Map:
initialBalance: Your starting account equity.isFinished&showStatsModal: Set totrueto immediately open the dashboard.finishedPositions: Powers core stats (Win Rate, PnL, Drawdown, Profit Factor). Thepnlfield should be the gross profit/loss (before fees). Thetradesarray should be left empty ([]) for imported data.tradeHistory: Powers the "Trade Log" export, "Backtest from/to" dates, and fee calculations. Fees intradeHistoryentries are automatically subtracted from the gross PnL to compute the net profit displayed in the Statistics Modal.