react-klinecharts-ui
v0.3.0
Published
Headless React components for building financial trading terminals with klinecharts
Maintainers
Readme
react-klinecharts-ui — Library Reference
react-klinecharts-ui is a headless React library for building financial trading terminals on top of klinecharts. It provides a state provider, a set of hooks, and overlay templates. No UI components are included — use any UI framework you prefer.
Acknowledgments
Many features in this library — including 11 TradingView-style indicators, 9 drawing overlays, the TA math library, undo/redo, layout manager, and script editor — were ported from the QUANTIX Extended Edition fork of KLineChart-Pro by @dsavenk0. The original fork implements these as a tightly-coupled Vue 3 application; this library re-implements them as headless React hooks following the composable, framework-agnostic architecture.
Table of Contents
- Installation
- Concept
- KlinechartsUIProvider
- Types
- Hooks
- Utilities
- Data & Constants
- Custom Indicator Templates
- Drawing Overlays
- Extensions
- State Callbacks
- Full Export List
Installation
npm install react-klinecharts-ui react-klinecharts
# or with pnpm
pnpm add react-klinecharts-ui react-klinecharts
# or with yarn
yarn add react-klinecharts-ui react-klinechartsConcept
The library follows a headless pattern — all UI is written by the consumer. The library is responsible for:
- State management — current symbol, period, theme, indicators, timezone, screenshots
- Datafeed integration — abstract interface for loading historical data and subscribing to real-time updates
- klinecharts overlay management — indicators, drawing tools, order lines
- Utilities —
createDataLoader, overlay templates
All hooks must be called inside <KlinechartsUIProvider>.
KlinechartsUIProvider
The root provider. Wraps the application and supplies the context.
import { KlinechartsUIProvider } from "react-klinecharts-ui";
<KlinechartsUIProvider
datafeed={myDatafeed}
defaultSymbol={{ ticker: "BTCUSDT", pricePrecision: 2 }}
defaultTheme="dark"
overlays={[orderLine]}
onSymbolChange={(symbol) => saveToStorage("symbol", symbol)}
>
<App />
</KlinechartsUIProvider>;Props
| Prop | Type | Default | Description |
| ------------------------ | ---------------------------------------------- | ------------------ | ---------------------------------------------------------------- |
| datafeed | Datafeed | — | Required. Datafeed interface implementation |
| defaultSymbol | PartialSymbolInfo | null | Initial trading instrument |
| defaultPeriod | TerminalPeriod | First in periods | Initial timeframe |
| defaultTheme | string | "light" | Initial theme ("light" or "dark") |
| defaultTimezone | string | "Asia/Shanghai" | Initial timezone (IANA) |
| defaultMainIndicators | string[] | ["MA"] | Indicators on the main chart at startup |
| defaultSubIndicators | string[] | ["VOL"] | Indicators on sub-panels at startup |
| defaultLocale | string | "en-US" | Locale passed to klinecharts |
| periods | TerminalPeriod[] | DEFAULT_PERIODS | List of available timeframes |
| styles | DeepPartial<Styles> | — | Custom klinecharts styles (applied when the chart is ready) |
| registerExtensions | boolean | true | Whether to register built-in drawing overlays |
| overlays | OverlayTemplate[] | — | Additional overlay templates (e.g. orderLine, custom overlays) |
| onStateChange | (action, nextState, prevState) => void | — | Called synchronously on every dispatched action |
| onSymbolChange | (symbol) => void | — | Called when the symbol changes |
| onPeriodChange | (period) => void | — | Called when the period changes |
| onThemeChange | (theme) => void | — | Called when the theme changes |
| onTimezoneChange | (timezone) => void | — | Called when the timezone changes |
| onMainIndicatorsChange | (indicators: string[]) => void | — | Called when main indicators change |
| onSubIndicatorsChange | (indicators: Record<string, string>) => void | — | Called when sub-indicators change |
| onSettingsChange | (settings: Record<string, unknown>) => void | — | Called when settings change via useKlinechartsUISettings |
Overlay registration
The provider registers overlays once on mount via useRef — passing an inline array is safe and does not cause re-registration:
// Safe — does not re-register on every render
<KlinechartsUIProvider overlays={[orderLine, myCustomOverlay]}>Types
Datafeed
Data interface implemented by the consumer.
interface Datafeed {
/**
* Search symbols by a query string.
* signal — AbortSignal to cancel the request when a newer query is typed.
*/
searchSymbols(
search: string,
signal?: AbortSignal,
): Promise<PartialSymbolInfo[]>;
/**
* Load historical bars.
* from/to — timestamps in milliseconds.
* When from=0, load the most recent available data.
*/
getHistoryKLineData(
symbol: SymbolInfo,
period: TerminalPeriod,
from: number,
to: number,
): Promise<KLineData[]>;
/**
* Subscribe to real-time updates.
* callback is called for every new bar.
*/
subscribe(
symbol: SymbolInfo,
period: TerminalPeriod,
callback: (data: KLineData) => void,
): void;
/** Unsubscribe from real-time updates. */
unsubscribe(symbol: SymbolInfo, period: TerminalPeriod): void;
}PartialSymbolInfo
Minimal description of a trading instrument.
interface PartialSymbolInfo {
ticker: string; // e.g. "BTCUSDT", "AAPL", "EUR/USD"
pricePrecision?: number; // Decimal places for price display
volumePrecision?: number; // Decimal places for volume display
[key: string]: unknown; // Any additional fields
}KlinechartsUIState
Complete provider state. Accessible via useKlinechartsUI().state.
interface KlinechartsUIState {
chart: Chart | null; // klinecharts Chart instance (null before onReady)
datafeed: Datafeed; // The datafeed passed to the provider
symbol: PartialSymbolInfo | null; // Current symbol
period: TerminalPeriod; // Current timeframe
theme: string; // Current theme: "light" | "dark"
timezone: string; // Current timezone (IANA)
isLoading: boolean; // true while data is loading
locale: string; // klinecharts locale ("en-US")
periods: TerminalPeriod[]; // List of available timeframes
mainIndicators: string[]; // Active main chart indicators
subIndicators: Record<string, string>; // Active sub-indicators: { name → paneId }
styles: DeepPartial<Styles> | undefined; // Custom klinecharts styles
screenshotUrl: string | null; // URL of the last screenshot
}KlinechartsUIAction
Union type of all possible actions for dispatch.
type KlinechartsUIAction =
| { type: "SET_CHART"; chart: Chart }
| { type: "SET_SYMBOL"; symbol: PartialSymbolInfo }
| { type: "SET_PERIOD"; period: TerminalPeriod }
| { type: "SET_THEME"; theme: string }
| { type: "SET_TIMEZONE"; timezone: string }
| { type: "SET_LOADING"; isLoading: boolean }
| { type: "SET_MAIN_INDICATORS"; indicators: string[] }
| { type: "SET_SUB_INDICATORS"; indicators: Record<string, string> }
| { type: "SET_STYLES"; styles: DeepPartial<Styles> | undefined }
| { type: "SET_LOCALE"; locale: string }
| { type: "SET_SCREENSHOT_URL"; url: string | null };Hooks
useKlinechartsUI
The primary hook — returns the full context: state, dispatch, datafeed, and fullscreen ref.
const { state, dispatch, datafeed, onSettingsChange, fullscreenContainerRef } =
useKlinechartsUI();Return value:
interface KlinechartsUIContextValue {
state: KlinechartsUIState;
dispatch: Dispatch<KlinechartsUIAction>; // enhancedDispatch with synchronous callbacks
datafeed: Datafeed;
onSettingsChange?: (settings: Record<string, unknown>) => void;
fullscreenContainerRef: RefObject<HTMLElement | null>;
}Note:
dispatchisenhancedDispatch. It synchronously computes the new state by calling the pure reducer directly and immediately invokesonStateChange/ individual callbacks — without waiting for a React re-render.
useKlinechartsUITheme
Manage the chart theme.
const { theme, setTheme, toggleTheme } = useKlinechartsUITheme();| Field | Type | Description |
| ------------- | ------------------------- | ------------------------------------- |
| theme | string | Current theme: "light" or "dark" |
| setTheme | (theme: string) => void | Set a specific theme |
| toggleTheme | () => void | Toggle between "light" and "dark" |
const { theme, toggleTheme } = useKlinechartsUITheme();
<button onClick={toggleTheme}>
{theme === "dark" ? <SunIcon /> : <MoonIcon />}
</button>;useKlinechartsUILoading
Loading state of chart data.
const { isLoading } = useKlinechartsUILoading();| Field | Type | Description |
| ----------- | --------- | ------------------------------------------------ |
| isLoading | boolean | true while createDataLoader is fetching bars |
const { isLoading } = useKlinechartsUILoading();
{
isLoading && <div className="spinner" />;
}usePeriods
Manage timeframes.
const { periods, activePeriod, setPeriod } = usePeriods();| Field | Type | Description |
| -------------- | ---------------------------------- | --------------------------------- |
| periods | TerminalPeriod[] | Full list of available timeframes |
| activePeriod | TerminalPeriod | Currently selected timeframe |
| setPeriod | (period: TerminalPeriod) => void | Change the timeframe |
TerminalPeriod extends KlinechartsPeriod with a label: string field.
Default timeframes: 1m, 5m, 15m, 1H, 2H, 4H, D, W, M, Y
const { periods, activePeriod, setPeriod } = usePeriods();
<div className="flex gap-1">
{periods.map((p) => (
<button
key={p.label}
onClick={() => setPeriod(p)}
className={activePeriod.label === p.label ? "active" : ""}
>
{p.label}
</button>
))}
</div>;useTimezone
Manage the chart timezone.
const { timezones, activeTimezone, setTimezone } = useTimezone();| Field | Type | Description |
| ---------------- | ---------------------------- | ------------------------- |
| timezones | TimezoneItem[] | Full list of timezones |
| activeTimezone | string | Current IANA timezone key |
| setTimezone | (timezone: string) => void | Change the timezone |
interface TimezoneItem {
key: string; // IANA: "Europe/London", "America/New_York", "UTC"
localeKey: string; // Short name: "london", "new_york", "utc"
}Available timezones:
UTC, Pacific/Honolulu, America/Juneau, America/Los_Angeles, America/Chicago, America/Toronto, America/Sao_Paulo, Europe/London, Europe/Berlin, Asia/Bahrain, Asia/Dubai, Asia/Ashkhabad, Asia/Almaty, Asia/Bangkok, Asia/Shanghai, Asia/Tokyo, Australia/Sydney, Pacific/Norfolk
const { timezones, activeTimezone, setTimezone } = useTimezone();
<select value={activeTimezone} onChange={(e) => setTimezone(e.target.value)}>
{timezones.map((tz) => (
<option key={tz.key} value={tz.key}>
{tz.key}
</option>
))}
</select>;useSymbolSearch
Search and select a trading instrument.
const {
query,
results,
isSearching,
activeSymbol,
setQuery,
selectSymbol,
clearResults,
} = useSymbolSearch(debounceMs);| Parameter | Type | Default | Description |
| ------------ | -------- | ------- | --------------------------------------------- |
| debounceMs | number | 300 | Delay before calling datafeed.searchSymbols |
| Field | Type | Description |
| -------------- | ------------------------------------- | --------------------------------------------- |
| query | string | Current search query |
| results | PartialSymbolInfo[] | Results from the last search |
| isSearching | boolean | true while the request is in flight |
| activeSymbol | PartialSymbolInfo \| null | Currently selected symbol from state.symbol |
| setQuery | (q: string) => void | Update the query (triggers debounced search) |
| selectSymbol | (symbol: PartialSymbolInfo) => void | Select a symbol — dispatches SET_SYMBOL |
| clearResults | () => void | Clear search results |
The hook automatically cancels in-flight requests via AbortController on every new keystroke and on unmount.
const { query, results, isSearching, selectSymbol, setQuery } =
useSymbolSearch(300);
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
/>;
{
isSearching && <Spinner />;
}
{
results.map((sym) => (
<button key={sym.ticker} onClick={() => selectSymbol(sym)}>
{sym.ticker}
</button>
));
}useIndicators
Full indicator management: add/remove, visibility, parameters, move between panes.
const {
mainIndicators,
subIndicators,
activeMainIndicators,
activeSubIndicators,
availableMainIndicators,
availableSubIndicators,
addMainIndicator,
removeMainIndicator,
addSubIndicator,
removeSubIndicator,
toggleMainIndicator,
toggleSubIndicator,
moveToMain,
moveToSub,
setIndicatorVisible,
updateIndicatorParams,
getIndicatorParams,
isMainIndicatorActive,
isSubIndicatorActive,
} = useIndicators();Fields
| Field | Type | Description |
| ------------------------- | ------------------------ | ------------------------------------------ |
| mainIndicators | IndicatorInfo[] | All main indicators with isActive flag |
| subIndicators | IndicatorInfo[] | All sub-indicators with isActive flag |
| activeMainIndicators | string[] | Active main indicator names only |
| activeSubIndicators | Record<string, string> | Active sub-indicators: { name → paneId } |
| availableMainIndicators | string[] | Full list from MAIN_INDICATORS |
| availableSubIndicators | string[] | Full list from SUB_INDICATORS |
interface IndicatorInfo {
name: string; // "MA", "MACD", "RSI", etc.
isActive: boolean; // Whether it is currently on the chart
}Methods
| Method | Description |
| --------------------------------------------- | ------------------------------------------------------------- |
| addMainIndicator(name) | Creates the indicator on candle_pane with id main_${name} |
| removeMainIndicator(name) | Removes the indicator and updates state |
| addSubIndicator(name) | Creates the indicator on a new sub-pane with id sub_${name} |
| removeSubIndicator(name) | Removes the sub-indicator and its pane |
| toggleMainIndicator(name) | add if inactive, remove if active |
| toggleSubIndicator(name) | Same for sub-indicators |
| moveToMain(name) | Moves from sub-pane to candle_pane |
| moveToSub(name) | Moves from candle_pane to a new sub-pane |
| setIndicatorVisible(name, isMain, visible) | Show/hide indicator via chart.overrideIndicator |
| updateIndicatorParams(name, paneId, params) | Update calcParams via chart.overrideIndicator |
| getIndicatorParams(name) | Returns [{ label, defaultValue }] or [] if no parameters |
| isMainIndicatorActive(name) | Quick active check |
| isSubIndicatorActive(name) | Quick active check |
Available indicators
Main chart (MAIN_INDICATORS): MA, EMA, SMA, BOLL, SAR, BBI
Sub-panes (SUB_INDICATORS): MA, EMA, VOL, MACD, BOLL, KDJ, RSI, BIAS, BRAR, CCI, DMI, CR, PSY, DMA, TRIX, OBV, VR, WR, MTM, EMV, SAR, SMA, ROC, PVT, BBI, AO
Indicators with configurable parameters: SMA, BOLL, SAR, BBI, MACD, KDJ, BRAR, CCI, DMI, CR, PSY, DMA, TRIX, OBV, VR, MTM, EMV, ROC, AO and others.
useDrawingTools
Manage drawing tools (chart overlays).
const {
categories,
activeTool,
magnetMode,
isLocked,
isVisible,
selectTool,
clearActiveTool,
setMagnetMode,
toggleLock,
toggleVisibility,
removeAllDrawings,
} = useDrawingTools();| Field/Method | Type | Description |
| --------------------- | -------------------------------- | ------------------------------------------------------- |
| categories | DrawingCategoryItem[] | Tool categories with nested tools |
| activeTool | string \| null | Name of the last selected tool |
| magnetMode | "normal" \| "weak" \| "strong" | Snap-to-OHLC mode |
| isLocked | boolean | Whether all drawings are locked |
| isVisible | boolean | Whether all drawings are visible |
| selectTool(name) | — | Start drawing via chart.createOverlay |
| clearActiveTool() | — | Deselect tool (local state only) |
| setMagnetMode(mode) | — | Change magnet mode for all existing and future drawings |
| toggleLock() | — | Toggle lock on all drawings |
| toggleVisibility() | — | Show/hide all drawings |
| removeAllDrawings() | — | Remove all drawings in the drawing_tools group |
interface DrawingToolItem {
name: string; // klinecharts overlay name, e.g. "arrow", "fibonacciLine"
localeKey: string; // Localization key
}
interface DrawingCategoryItem {
key: string; // "singleLine" | "moreLine" | "polygon" | "fibonacci" | "wave"
tools: DrawingToolItem[];
}Categories and tools:
| Category (key) | Tools |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| singleLine | horizontalStraightLine, horizontalRayLine, horizontalSegment, verticalStraightLine, verticalRayLine, verticalSegment, straightLine, rayLine, segment, arrow, priceLine |
| moreLine | priceChannelLine, parallelStraightLine |
| polygon | circle, rect, parallelogram, triangle |
| fibonacci | fibonacciLine, fibonacciSegment, fibonacciCircle, fibonacciSpiral, fibonacciSpeedResistanceFan, fibonacciExtension, gannBox |
| wave | xabcd, abcd, threeWaves, fiveWaves, eightWaves, anyWaves |
useKlinechartsUISettings
Manage chart appearance: candle type, colors, price marks, axes, grid, crosshair, tooltips.
const settings = useKlinechartsUISettings();State
| Field | Type | Default | Description |
| ------------------------ | --------------- | ---------------- | ------------------------- |
| candleType | string | "candle_solid" | Candle display type |
| candleUpColor | string | "#2DC08E" | Bullish candle color |
| candleDownColor | string | "#F92855" | Bearish candle color |
| showLastPrice | boolean | true | Last price mark on Y-axis |
| showHighPrice | boolean | true | High price mark |
| showLowPrice | boolean | true | Low price mark |
| showIndicatorLastValue | boolean | true | Indicator last value mark |
| priceAxisType | PriceAxisType | "normal" | Y-axis scale type |
| reverseCoordinate | boolean | false | Invert Y-axis |
| showTimeAxis | boolean | true | Show X-axis |
| showGrid | boolean | true | Show grid |
| showCrosshair | boolean | true | Show crosshair |
| showCandleTooltip | boolean | true | OHLCV tooltip |
| showIndicatorTooltip | boolean | true | Indicator tooltip |
Candle types: candle_solid, candle_stroke, candle_up_stroke, candle_down_stroke, ohlc, area
Price axis types: "normal", "percentage", "log"
Extra fields
| Field | Type | Description |
| ---------------- | --------------------------------------------- | ----------------------------------------------------- |
| candleTypes | CandleTypeItem[] | List of { key, localeKey } for rendering a selector |
| priceAxisTypes | { key: PriceAxisType; localeKey: string }[] | List for rendering a selector |
Setters
Each field has a corresponding setter: setCandleType, setCandleUpColor, setCandleDownColor, setShowLastPrice, setShowHighPrice, setShowLowPrice, setShowIndicatorLastValue, setPriceAxisType, setReverseCoordinate, setShowTimeAxis, setShowGrid, setShowCrosshair, setShowCandleTooltip, setShowIndicatorTooltip.
All setters immediately apply changes via chart.setStyles(...).
| Method | Description |
| ------------------- | ----------------------------------------------------------- |
| resetToDefaults() | Reset all settings to defaults via chart.setStyles(theme) |
Important: Settings are stored in local
useStateinside the hook — they are not part of the provider's reducer state. The hook must be called unconditionally (not only when a dialog is open) to preserve settings across dialog open/close cycles. Changes triggeronSettingsChangefrom the provider.
useScreenshot
Capture and download a chart screenshot.
const { screenshotUrl, capture, download, clear } = useScreenshot();| Field/Method | Type | Description |
| --------------------- | ----------------------------- | ------------------------------------------------------ |
| screenshotUrl | string \| null | JPEG data URL of the last screenshot |
| capture() | () => void | Capture the current chart state |
| download(filename?) | (filename?: string) => void | Download as a file (default: "chart-screenshot.jpg") |
| clear() | () => void | Clear screenshotUrl from state |
Screenshot is created via chart.getConvertPictureUrl(true, "jpeg", bgColor). Background depends on the current theme: #151517 for dark, #ffffff for light.
const { screenshotUrl, capture, download, clear } = useScreenshot();
<button onClick={capture}>Capture</button>;
{
screenshotUrl && (
<>
<img src={screenshotUrl} alt="chart" />
<button onClick={() => download()}>Download</button>
<button onClick={clear}>Close</button>
</>
);
}useFullscreen
Toggle fullscreen mode. Uses fullscreenContainerRef from the provider.
const { isFullscreen, toggle, enter, exit, containerRef } = useFullscreen();| Field/Method | Type | Description |
| -------------- | -------------------------------- | ------------------------------ |
| isFullscreen | boolean | Current fullscreen state |
| toggle() | () => void | Toggle |
| enter() | () => void | Enter fullscreen |
| exit() | () => void | Exit fullscreen |
| containerRef | RefObject<HTMLElement \| null> | The same ref from the provider |
Supports cross-browser vendor prefixes (webkit, ms).
Important: containerRef must be assigned to the container element that should occupy the full screen (typically the root layout element):
const { containerRef, toggle, isFullscreen } = useFullscreen();
<div ref={containerRef as React.RefObject<HTMLDivElement>}>
<button onClick={toggle}>{isFullscreen ? "Exit" : "Fullscreen"}</button>
<ChartView />
</div>;useOrderLines
Create and manage horizontal price level lines (order lines).
Requirement: The
orderLineoverlay must be registered viaoverlays={[orderLine]}on the provider.
const {
createOrderLine,
updateOrderLine,
removeOrderLine,
removeAllOrderLines,
} = useOrderLines();createOrderLine
createOrderLine(options: OrderLineOptions): string | nullReturns the id of the created line, or null if the chart is not ready.
interface OrderLineOptions extends OrderLineExtendData {
id?: string; // Auto-generated if omitted
price: number; // Price level
draggable?: boolean; // Allow drag to change price. Default: false
onPriceChange?: (price: number) => void; // Called when drag ends
}All OrderLineExtendData fields (see orderLine extension) are accepted directly — they flow through as overlay extendData.
updateOrderLine
updateOrderLine(id: string, options: Partial<Omit<OrderLineOptions, "id">>): voidUpdates an existing line. Only pass the fields you want to change.
removeOrderLine / removeAllOrderLines
removeOrderLine(id: string): void
removeAllOrderLines(): void // Removes all overlays with name="orderLine"const { createOrderLine, updateOrderLine, removeOrderLine } = useOrderLines();
const id = createOrderLine({
price: 45000,
color: "#ff9900",
text: "Target",
line: { style: "dashed" },
mark: { bg: "#ff9900", color: "#fff" },
draggable: true,
onPriceChange: (newPrice) => console.log("Moved to:", newPrice),
});
updateOrderLine(id!, { color: "#00ff00" });
removeOrderLine(id!);useUndoRedo
Undo/redo history for drawing overlays and indicator toggles. Automatically connected to useDrawingTools and useIndicators via a shared context ref — actions are recorded without manual wiring.
Keyboard shortcuts: Ctrl+Z (undo), Ctrl+Y / Ctrl+Shift+Z (redo).
import { useUndoRedo } from "react-klinecharts-ui";
const { canUndo, canRedo, undo, redo, pushAction, clear } = useUndoRedo();Return type: UseUndoRedoReturn
| Property | Type | Description |
|----------|------|-------------|
| canUndo | boolean | Whether there are actions to undo |
| canRedo | boolean | Whether there are actions to redo |
| undo | () => void | Undo the last action |
| redo | () => void | Redo the last undone action |
| pushAction | (action: UndoRedoAction) => void | Push a new action onto the undo stack (clears redo) |
| clear | () => void | Clear all undo/redo history |
Action types
| Type | Trigger | Undo behaviour | Redo behaviour |
|------|---------|----------------|----------------|
| overlay_added | User completes a drawing | Removes the overlay | Re-creates the overlay |
| overlays_removed | removeAllDrawings() | Restores all removed overlays | Re-removes them |
| indicator_toggled | Add/remove indicator | Reverses the toggle | Re-applies the toggle |
Cross-hook communication
useUndoRedo registers a pushAction callback on undoRedoListenerRef (shared via provider context). When useDrawingTools finishes a drawing or useIndicators toggles an indicator, they call the ref to record the action — no prop drilling required.
useLayoutManager
Save, load, rename, and delete named chart layouts via localStorage. Captures indicators, drawings, symbol, and period. Optional auto-save with 5-second debounce.
import { useLayoutManager } from "react-klinecharts-ui";
const {
layouts,
saveLayout,
loadLayout,
deleteLayout,
renameLayout,
refreshLayouts,
autoSaveEnabled,
setAutoSaveEnabled,
} = useLayoutManager();Return type: UseLayoutManagerReturn
| Property | Type | Description |
|----------|------|-------------|
| layouts | LayoutEntry[] | List of saved layout entries |
| saveLayout | (name: string) => string \| null | Save current chart state; returns layout ID |
| loadLayout | (id: string) => boolean | Load and apply a layout by ID |
| deleteLayout | (id: string) => void | Delete a layout |
| renameLayout | (id: string, name: string) => boolean | Rename a layout |
| refreshLayouts | () => void | Refresh the list from localStorage |
| autoSaveEnabled | boolean | Whether auto-save is enabled |
| setAutoSaveEnabled | (enabled: boolean) => void | Toggle auto-save |
LayoutEntry
interface LayoutEntry {
id: string;
name: string;
symbol: string;
period: string;
timestamp: number;
lastModified: number;
state: ChartLayoutState;
}ChartLayoutState
interface ChartLayoutState {
version: string;
meta: { symbol: string; period: string; timestamp: number; lastModified: number };
indicators: Array<{ paneId: string; name: string; calcParams: any[]; visible: boolean }>;
drawings: Array<{ name: string; points: any[]; styles?: any; extendData?: any }>;
}useScriptEditor
Pine Script-style custom indicator editor. Users write plain JavaScript function bodies that receive TA, dataList (array of KLineData), and params (parsed from a comma-separated string). The script must return an array of objects — one per candle, each key becomes a chart series.
Scripts execute inside a sandboxed new Function() with dangerous globals shadowed: fetch, XMLHttpRequest, WebSocket, Worker, SharedWorker, importScripts, self, caches, indexedDB.
import { useScriptEditor } from "react-klinecharts-ui";
const {
code, setCode,
scriptName, setScriptName,
params, setParams,
placement, setPlacement,
error, status, isRunning, hasActiveScript,
runScript, removeScript, resetCode,
exportScript, importScript,
defaultScript,
} = useScriptEditor();Return type: UseScriptEditorReturn
| Property | Type | Description |
|----------|------|-------------|
| code | string | Current script source code |
| setCode | (code: string) => void | Update the source code |
| scriptName | string | Display name of the script |
| setScriptName | (name: string) => void | Update the name |
| params | string | Comma-separated numeric params (e.g. "14, 26, 9") |
| setParams | (params: string) => void | Update params |
| placement | ScriptPlacement | "main" or "sub" |
| setPlacement | (p: ScriptPlacement) => void | Set placement |
| error | string | Last error message (empty = no error) |
| status | string | Last status message |
| isRunning | boolean | Whether the script is currently executing |
| hasActiveScript | boolean | Whether a script indicator is on the chart |
| runScript | () => void | Execute the script and register the indicator |
| removeScript | () => void | Remove the current script indicator from the chart |
| resetCode | () => void | Reset code to the default template |
| exportScript | () => void | Download the code as a .js file |
| importScript | (file: File) => void | Load a script from a file |
| defaultScript | string | The default template code |
Example script
// Available: TA, dataList, params
const period = params[0] ?? 14;
const closes = dataList.map(d => d.close);
const highs = dataList.map(d => d.high);
const lows = dataList.map(d => d.low);
const rsi = TA.rsi(closes, period);
const boll = TA.bollinger(closes, period, 2);
// Return one object per candle — each key = one line on the chart
return rsi.map((v, i) => ({
rsi: v,
upper: boll.upper[i],
mid: boll.mid[i],
lower: boll.lower[i],
}));useWatchlist
Manage a list of tracked symbols with live price updates from your datafeed.
import { useWatchlist } from "react-klinecharts-ui";
const {
items,
addSymbol,
removeSymbol,
switchSymbol,
activeSymbol,
} = useWatchlist();Return type: UseWatchlistReturn
| Property | Type | Description |
|----------|------|-------------|
| items | WatchlistItem[] | Array of tracked symbols with price data |
| addSymbol | (ticker: string) => void | Add a symbol to the watchlist |
| removeSymbol | (ticker: string) => void | Remove a symbol from the watchlist |
| switchSymbol | (ticker: string) => void | Change the chart to display a symbol |
| activeSymbol | string \| null | Currently displayed symbol ticker |
WatchlistItem
| Property | Type | Description |
|----------|------|-------------|
| ticker | string | Symbol identifier |
| lastPrice | number \| null | Last traded price |
| change | number \| null | Absolute price change |
| changePercent | number \| null | 24h percentage change |
useCompare
Compare multiple symbols on the same chart with individual colors and visibility toggle.
import { useCompare } from "react-klinecharts-ui";
const {
symbols,
addSymbol,
removeSymbol,
toggleSymbol,
clearAll,
} = useCompare();Return type: UseCompareReturn
| Property | Type | Description |
|----------|------|-------------|
| symbols | CompareSymbol[] | Array of comparison symbols with metadata |
| addSymbol | (ticker: string) => void | Add a symbol to compare |
| removeSymbol | (ticker: string) => void | Remove a comparison symbol |
| toggleSymbol | (ticker: string) => void | Toggle visibility of a symbol |
| clearAll | () => void | Remove all comparison symbols |
CompareSymbol
| Property | Type | Description |
|----------|------|-------------|
| ticker | string | Symbol identifier |
| visible | boolean | Whether the symbol is currently visible on chart |
| color | string | Hex color code for the symbol's line |
useMeasure
Measure price changes, percentage swings, bar count, and time intervals between two points on the chart.
import { useMeasure } from "react-klinecharts-ui";
const {
isActive,
startMeasure,
cancelMeasure,
result,
} = useMeasure();Return type: UseMeasureReturn
| Property | Type | Description |
|----------|------|-------------|
| isActive | boolean | Whether measurement mode is enabled |
| startMeasure | () => void | Enter measurement mode (click two points) |
| cancelMeasure | () => void | Exit measurement mode |
| result | MeasureResult \| null | Measurement data (null if not measured yet) |
MeasureResult
| Property | Type | Description |
|----------|------|-------------|
| priceDiff | number | Absolute price difference |
| pricePercent | number | Percentage change |
| bars | number | Number of bars between points |
| timeDiff | number | Time difference in milliseconds |
useAnnotations
Add text annotations at specific price levels and timestamps with optional colors.
import { useAnnotations } from "react-klinecharts-ui";
const {
annotations,
addAnnotation,
removeAnnotation,
updateAnnotation,
clearAnnotations,
} = useAnnotations();Return type: UseAnnotationsReturn
| Property | Type | Description |
|----------|------|-------------|
| annotations | Annotation[] | Array of all annotations |
| addAnnotation | (text, price, timestamp, color?) => string | Add annotation; returns ID |
| removeAnnotation | (id: string) => void | Remove annotation by ID |
| updateAnnotation | (id, updates) => void | Update text or color |
| clearAnnotations | () => void | Remove all annotations |
Annotation
| Property | Type | Description |
|----------|------|-------------|
| id | string | Unique identifier |
| text | string | Annotation text |
| price | number | Price level |
| timestamp | number | Candle timestamp |
| color | string \| undefined | Optional hex color |
useReplay
Replay historical candles at various speeds with play/pause/step controls and progress tracking.
import { useReplay } from "react-klinecharts-ui";
const {
isPlaying,
speed,
currentIndex,
totalBars,
play,
pause,
stop,
step,
setSpeed,
} = useReplay();Return type: UseReplayReturn
| Property | Type | Description |
|----------|------|-------------|
| isPlaying | boolean | Whether replay is running |
| speed | number | Current playback speed (0.25, 0.5, 1, 2, 4) |
| currentIndex | number | Current bar index being displayed |
| totalBars | number | Total bars in the dataset |
| play | () => void | Start replay from current position |
| pause | () => void | Pause replay (can resume with play) |
| stop | () => void | Stop replay and reset to start |
| step | () => void | Advance one bar when paused |
| setSpeed | (speed: number) => void | Set playback speed multiplier |
Utilities
createDataLoader
Creates a klinecharts DataLoader from a Datafeed instance.
function createDataLoader(
datafeed: Datafeed,
dispatch: Dispatch<KlinechartsUIAction>,
): DataLoader;This bridges the Datafeed interface to the klinecharts native DataLoader format.
Behavior:
| klinecharts request type | Action |
| ------------------------ | ------------------------------------------------------------------------------------------------------- |
| "init" | Loads the latest ~1000 bars (to=Date.now(), from=0), saves oldestTimestamp, increments currentGen |
| "forward" | Loads bars older than oldestTimestamp - 1 for left-scroll pagination |
| "backward" | Ignored (real-time handled via subscribeBar) |
Race condition protection: each "init" increments currentGen. If a "forward" request completes after a new "init" has started, the result is discarded.
function ChartView() {
const { state, dispatch, datafeed } = useKlinechartsUI();
const dataLoader = useMemo(
() => createDataLoader(datafeed, dispatch),
[datafeed, dispatch],
);
return (
<KLineChart
dataLoader={dataLoader}
symbol={state.symbol ?? undefined}
period={state.period}
locale={state.locale}
timezone={state.timezone}
styles={state.theme}
onReady={(chart) => dispatch({ type: "SET_CHART", chart })}
/>
);
}TA (Technical Analysis)
A standalone math library for computing common technical indicators. Used internally by indicator templates and available to custom scripts via useScriptEditor.
import { TA } from "react-klinecharts-ui";| Function | Signature | Returns |
|----------|-----------|---------|
| TA.sma | (data: number[], period: number) | number[] — Simple Moving Average |
| TA.ema | (data: number[], period: number) | number[] — Exponential Moving Average |
| TA.rma | (data: number[], period: number) | number[] — Running (Wilder's) Moving Average |
| TA.wma | (data: number[], period: number) | number[] — Weighted Moving Average |
| TA.hma | (data: number[], period: number) | number[] — Hull Moving Average |
| TA.stdev | (data: number[], period: number) | number[] — Standard Deviation |
| TA.rsi | (data: number[], period: number) | (number \| null)[] — Relative Strength Index |
| TA.macd | (data: number[], fast?: number, slow?: number, signal?: number) | { dif, dea, macd } — each (number \| null)[] |
| TA.bollinger | (data: number[], period?: number, mult?: number) | { upper, mid, lower } — each (number \| null)[] |
| TA.tr | (highs: number[], lows: number[], closes: number[]) | number[] — True Range |
| TA.atr | (highs: number[], lows: number[], closes: number[], period: number) | number[] — Average True Range |
| TA.vwap | (highs: number[], lows: number[], closes: number[], volumes: number[]) | number[] — Volume Weighted Average Price |
| TA.cci | (highs: number[], lows: number[], closes: number[], period: number) | number[] — Commodity Channel Index |
| TA.stoch | (highs: number[], lows: number[], closes: number[], kPeriod?, kSmooth?, dPeriod?) | { k, d } — each (number \| null)[] |
Data & Constants
All constants are exported from the root index.ts:
DEFAULT_PERIODS
const DEFAULT_PERIODS: TerminalPeriod[] = [
{ span: 1, type: "minute", label: "1m" },
{ span: 5, type: "minute", label: "5m" },
{ span: 15, type: "minute", label: "15m" },
{ span: 1, type: "hour", label: "1H" },
{ span: 2, type: "hour", label: "2H" },
{ span: 4, type: "hour", label: "4H" },
{ span: 1, type: "day", label: "D" },
{ span: 1, type: "week", label: "W" },
{ span: 1, type: "month", label: "M" },
{ span: 1, type: "year", label: "Y" },
];TIMEZONES
Array of TimezoneOption[] — 18 timezones. Fields: key (IANA) and localeKey (short name).
MAIN_INDICATORS / SUB_INDICATORS
String arrays of indicator names used as the available-for-selection list.
INDICATOR_PARAMS
const INDICATOR_PARAMS: Record<string, IndicatorDefinition>;
interface IndicatorDefinition {
name: string;
localeKey: string;
params: { label: string; defaultValue: number }[];
}Used internally by getIndicatorParams inside useIndicators.
DRAWING_CATEGORIES
Array of drawing tool categories. Used by useDrawingTools.
CANDLE_TYPES
const CANDLE_TYPES: CandleTypeOption[] = [
{ key: "candle_solid", localeKey: "candle_solid" },
{ key: "candle_stroke", localeKey: "candle_stroke" },
{ key: "candle_up_stroke", localeKey: "candle_up_stroke" },
{ key: "candle_down_stroke", localeKey: "candle_down_stroke" },
{ key: "ohlc", localeKey: "ohlc" },
{ key: "area", localeKey: "area" },
];PRICE_AXIS_TYPES
const PRICE_AXIS_TYPES = ["normal", "percentage", "log"] as const;
type PriceAxisType = "normal" | "percentage" | "log";Custom Indicator Templates
11 TradingView-style indicator templates ported from QUANTIX Extended Edition. All are registered automatically via registerExtensions. Each template uses the TA library for calculations and includes custom draw functions for TradingView-like visual styling (gradient fills, dashed level lines, multi-color histograms).
import { indicators } from "react-klinecharts-ui";
// indicators === [bollTv, cci, hma, ichimoku, maRibbon, macdTv, pivotPoints, rsiTv, stochastic, superTrend, vwap]Main chart indicators
| Template | Name | Default params | Description |
|----------|------|----------------|-------------|
| bollTv | BOLL_TV | [20, 2] | Bollinger Bands — TradingView style with filled band area, SMA midline, and upper/lower bands |
| hma | HMA | [9] | Hull Moving Average — high smoothing with minimal lag via TA.hma() |
| ichimoku | ICHIMOKU | [9, 26, 52, 26] | Ichimoku Cloud — Tenkan-sen, Kijun-sen, Senkou Span A/B (filled cloud), Chikou Span |
| maRibbon | MA_RIBBON | [5, 10, 20, 30, 50, 100] | Moving Average Ribbon — 6 EMAs with distinct colors for trend visualization |
| pivotPoints | PIVOT_POINTS | [1] | Standard pivot with Pivot, R1, R2, S1, S2 levels as dashed horizontal lines |
| superTrend | SUPERTREND | [10, 3] | ATR-based trend — dynamic green (up) / red (down) line coloring |
| vwap | VWAP | [] | Volume Weighted Average Price — single blue line via TA.vwap() |
Sub-pane indicators
| Template | Name | Default params | Description |
|----------|------|----------------|-------------|
| macdTv | MACD_TV | [12, 26, 9] | 4-color histogram: growing-positive (#26A69A), shrinking-positive (#B2DFDB), growing-negative (#FFCDD2), shrinking-negative (#EF5350). MACD line (#2962FF), Signal line (#FF6D00) |
| rsiTv | RSI_TV | [14, 14] | RSI + MA line. Dashed levels at 70/50/30. Gradient fills in overbought (>70, red) and oversold (<30, green) zones |
| cci | CCI | [20] | Commodity Channel Index via TA.cci() with dashed +100/0/-100 reference lines |
| stochastic | STOCHASTIC | [14, 1, 3] | %K (#2962FF) and %D (#FF6D00) lines. Dashed 80/50/20 levels. Gradient fills in overbought/oversold zones |
Drawing Overlays
OverlayTemplate instances for drawing tools. Automatically registered when registerExtensions: true (default).
Named exports:
| Export | Overlay name | Description |
| ----------------------------- | ------------------------------- | ------------------- |
| arrow | "arrow" | Arrow |
| circle | "circle" | Circle |
| rect | "rect" | Rectangle |
| triangle | "triangle" | Triangle |
| parallelogram | "parallelogram" | Parallelogram |
| fibonacciCircle | "fibonacciCircle" | Fibonacci circle |
| fibonacciSegment | "fibonacciSegment" | Fibonacci segment |
| fibonacciSpiral | "fibonacciSpiral" | Fibonacci spiral |
| fibonacciSpeedResistanceFan | "fibonacciSpeedResistanceFan" | Fibonacci fan |
| fibonacciExtension | "fibonacciExtension" | Fibonacci extension |
| gannBox | "gannBox" | Gann box |
| threeWaves | "threeWaves" | 3-wave pattern |
| fiveWaves | "fiveWaves" | 5-wave pattern |
| eightWaves | "eightWaves" | 8-wave pattern |
| anyWaves | "anyWaves" | Custom wave pattern |
| abcd | "abcd" | ABCD pattern |
| xabcd | "xabcd" | XABCD pattern |
| elliottWave | "elliottWave" | Elliott Wave (5-wave cycle with numbered vertices) |
| gannFan | "gannFan" | Gann Fan (1x1, 1x2, etc.) |
| fibRetracement | "fibRetracement" | Fibonacci retracement levels |
| parallelChannel | "parallelChannel" | Parallel channel (two parallel lines) |
| longPosition | "longPosition" | Long position risk/reward (TP/SL with % labels) |
| shortPosition | "shortPosition" | Short position risk/reward (TP/SL with % labels) |
| measure | "measure" | Measure tool (price %, bar count, time delta) |
| brush | "brush" | Freehand brush drawing (Bezier smoothing) |
| ray | "ray" | Infinite ray from a point |
Extensions
registerExtensions
Registers all built-in drawing overlays via registerOverlay. Called automatically by the provider when registerExtensions: true.
import { registerExtensions } from "react-klinecharts-ui";
registerExtensions(); // Idempotent — repeated calls are ignoredorderLine
Overlay template for horizontal price level lines. Not registered automatically — must be passed explicitly to the provider.
import { orderLine, KlinechartsUIProvider } from "react-klinecharts-ui";
<KlinechartsUIProvider overlays={[orderLine]}>...</KlinechartsUIProvider>;Implementation details:
needDefaultYAxisFigure: false— custom rendering of the Y-axis markcreateYAxisFigures— draws a colored price mark on the right axiscreatePointFigures— draws a horizontal line with an optional text labelperformEventPressedMove— updatespoints[0].valueduring drag- Uses
chart.getSymbol()?.pricePrecision ?? 2for price formatting
OrderLineExtendData
All fields are optional. Defaults produce an orange dashed line with a white-on-orange price mark.
interface OrderLineExtendData {
/** Primary color for line, mark bg, and label fallback. Default: "rgba(255, 165, 0, 0.85)" */
color?: string;
/** Optional text label displayed above the line. */
text?: string;
/** Line style overrides. */
line?: OrderLineLineStyle;
/** Y-axis price mark style overrides. */
mark?: OrderLineMarkStyle;
/** Text label style overrides. */
label?: OrderLineLabelStyle;
}
interface OrderLineLineStyle {
style?: "solid" | "dashed" | "dotted"; // Default: "dashed"
width?: number; // Default: 1
dashedValue?: [number, number]; // Default: [4, 2]
}
interface OrderLineMarkStyle {
color?: string; // Text color. Default: "#ffffff"
bg?: string; // Background (falls back to top-level color)
borderRadius?: number; // Default: 2
font?: OrderLineFontStyle;
padding?: OrderLinePadding;
}
interface OrderLineLabelStyle {
color?: string; // Text color (falls back to top-level color)
bg?: string; // Background. Default: "transparent"
borderRadius?: number; // Default: 0
font?: OrderLineFontStyle;
padding?: OrderLinePadding;
offset?: OrderLinePadding; // Position offset. Defaults: x=8, y=3
}
interface OrderLineFontStyle {
size?: number; // Default: 11
family?: string; // Default: "Helvetica Neue, Arial, sans-serif"
weight?: string; // Default: "bold" (mark) / "normal" (label)
}
interface OrderLinePadding {
x?: number;
y?: number;
}All sub-interfaces (OrderLineLineStyle, OrderLineMarkStyle, OrderLineLabelStyle, OrderLineFontStyle, OrderLinePadding) are exported as named types from both the main and extensions entry points.
depthOverlay
Overlay template for visualizing order book depth as horizontal liquidity bars at each price level. Shows cumulative buy/sell volume at price levels, useful for understanding support/resistance zones.
import { depthOverlay, KlinechartsUIProvider } from "react-klinecharts-ui/extensions";
<KlinechartsUIProvider overlays={[depthOverlay]}>...</KlinechartsUIProvider>;Implementation details:
needDefaultPointFigure: false,needDefaultXAxisFigure: false,needDefaultYAxisFigure: false— entirely custom renderingcreatePointFigures— draws rect figures at each price level usingyAxis.convertToPixel(price)for positioningzLevel: -1— renders behind the main candlestick data- Dynamic data via
extendData— update withchart.overrideOverlay({ id, extendData: newData })
DepthOverlayExtendData
interface DepthOverlayExtendData {
rows?: DepthOverlayRow[];
/** Optional: customize buy side color. Default: "rgba(16, 186, 156, 0.3)" */
buyColor?: string;
/** Optional: customize sell side color. Default: "rgba(239, 68, 68, 0.3)" */
sellColor?: string;
}
interface DepthOverlayRow {
price: number;
buyVolume: number;
sellVolume: number;
}Usage example:
const chart = state.chart;
if (chart) {
const rows: DepthOverlayRow[] = [
{ price: 40000, buyVolume: 5.2, sellVolume: 3.1 },
{ price: 40100, buyVolume: 4.8, sellVolume: 4.2 },
// ...
];
chart.overrideOverlay({
id: "depthOverlay",
extendData: { rows, buyColor: "rgba(34, 197, 94, 0.3)" },
});
}overlays (array)
Array of all built-in drawing overlays — for direct access to the list:
import { overlays } from "react-klinecharts-ui";
// overlays === [arrow, circle, rect, triangle, ...] (26 items)State Callbacks
Callbacks are invoked synchronously inside enhancedDispatch, before the React re-render — enabling immediate state persistence.
<KlinechartsUIProvider
datafeed={datafeed}
onStateChange={(action, nextState, prevState) => {
// Called for every dispatched action
console.log(action.type, nextState);
}}
onSymbolChange={(symbol) => {
localStorage.setItem('symbol', JSON.stringify(symbol));
}}
onPeriodChange={(period) => {
localStorage.setItem('period', JSON.stringify(period));
}}
onThemeChange={(theme) => {
localStorage.setItem('theme', theme);
}}
onTimezoneChange={(timezone) => {
localStorage.setItem('timezone', timezone);
}}
onMainIndicatorsChange={(indicators) => {
localStorage.setItem('mainIndicators', JSON.stringify(indicators));
}}
onSubIndicatorsChange={(indicators) => {
localStorage.setItem('subIndicators', JSON.stringify(indicators));
}}
onSettingsChange={(settings) => {
// Called from useKlinechartsUISettings on every change
localStorage.setItem('settings', JSON.stringify(settings));
}}
>Restoring persisted state:
const savedSymbol = JSON.parse(localStorage.getItem('symbol') ?? 'null');
const savedTheme = localStorage.getItem('theme') ?? 'dark';
<KlinechartsUIProvider
defaultSymbol={savedSymbol ?? { ticker: 'BTCUSDT' }}
defaultTheme={savedTheme}
>Full Export List
// Provider & context
export { KlinechartsUIProvider };
export {
useKlinechartsUI,
KlinechartsUIStateContext,
KlinechartsUIDispatchContext,
};
export type {
KlinechartsUIOptions,
KlinechartsUIState,
KlinechartsUIAction,
KlinechartsUIContextValue,
KlinechartsUIDispatchValue,
Datafeed,
PartialSymbolInfo,
};
// Hooks
export { useKlinechartsUITheme, type UseKlinechartsUIThemeReturn };
export { useKlinechartsUILoading, type UseKlinechartsUILoadingReturn };
export { usePeriods, type UsePeriodsReturn };
export { useTimezone, type UseTimezoneReturn, type TimezoneItem };
export { useSymbolSearch, type UseSymbolSearchReturn };
export { useIndicators, type UseIndicatorsReturn, type IndicatorInfo };
export {
useDrawingTools,
type UseDrawingToolsReturn,
type DrawingToolItem,
type DrawingCategoryItem,
};
export {
useKlinechartsUISettings,
type UseKlinechartsUISettingsReturn,
type KlinechartsUISettingsState,
type CandleTypeItem,
};
export { useScreenshot, type UseScreenshotReturn };
export { useFullscreen, type UseFullscreenReturn };
export { useOrderLines, type UseOrderLinesReturn, type OrderLineOptions };
export {
useUndoRedo,
type UseUndoRedoReturn,
type UndoRedoAction,
type UndoRedoActionType,
};
export {
useLayoutManager,
type UseLayoutManagerReturn,
type LayoutEntry,
type ChartLayoutState,
};
export {
useScriptEditor,
type UseScriptEditorReturn,
type ScriptPlacement,
};
// Data
export { DEFAULT_PERIODS, type TerminalPeriod };
export { TIMEZONES, type TimezoneOption };
export {
MAIN_INDICATORS,
SUB_INDICATORS,
INDICATOR_PARAMS,
type IndicatorParamConfig,
type IndicatorDefinition,
};
export {
DRAWING_CATEGORIES,
type DrawingTool,
type DrawingToolCategory,
type MagnetMode,
};
export {
CANDLE_TYPES,
PRICE_AXIS_TYPES,
YAXIS_POSITIONS,
COMPARE_RULES,
TOOLTIP_SHOW_RULES,
type CandleTypeOption,
type PriceAxisType,
type YAxisPosition,
type CompareRule,
type TooltipShowRule,
};
// Utilities
export { createDataLoader };
export { default as TA } from "./utils/TA";
// Drawing overlays (all 26)
export {
arrow, circle, rect, triangle, parallelogram,
fibonacciCircle, fibonacciSegment, fibonacciSpiral,
fibonacciSpeedResistanceFan, fibonacciExtension,
fibRetracement,
gannBox, gannFan,
threeWaves, fiveWaves, eightWaves, anyWaves, elliottWave,
abcd, xabcd,
parallelChannel, ray,
longPosition, shortPosition,
measure, brush,
};
// Custom indicator templates (all 11)
export * from "./indicators";
// Extensions
export { registerExtensions, overlays, indicators, orderLine };
export type {
OrderLineExtendData,
OrderLineLineStyle,
OrderLineMarkStyle,
OrderLineLabelStyle,
OrderLineFontStyle,
OrderLinePadding,
};