react-klinecharts-ui 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -41,6 +41,9 @@ Many features in this library — including 11 TradingView-style indicators, 9 d
41
41
  - [useMeasure](#usemeasure)
42
42
  - [useAnnotations](#useannotations)
43
43
  - [useReplay](#usereplay)
44
+ - [useAlerts](#usealerts)
45
+ - [useCrosshair](#usecrosshair)
46
+ - [useDataExport](#usedataexport)
44
47
  6. [Utilities](#utilities)
45
48
  - [createDataLoader](#createdataloader)
46
49
  - [TA (Technical Analysis)](#ta-technical-analysis)
@@ -49,7 +52,8 @@ Many features in this library — including 11 TradingView-style indicators, 9 d
49
52
  9. [Drawing Overlays](#drawing-overlays)
50
53
  10. [Extensions](#extensions)
51
54
  11. [State Callbacks](#state-callbacks)
52
- 12. [Full Export List](#full-export-list)
55
+ 12. [Backend Signals & Notifications](#backend-signals--notifications)
56
+ 13. [Full Export List](#full-export-list)
53
57
 
54
58
  ---
55
59
 
@@ -207,6 +211,10 @@ interface KlinechartsUIState {
207
211
  mainIndicators: string[]; // Active main chart indicators
208
212
  subIndicators: Record<string, string>; // Active sub-indicators: { name → paneId }
209
213
  indicatorAxes: Record<string, string>; // Custom Y-axis bindings: { indicatorId → yAxisId }
214
+ indicatorVisibility: Record<string, boolean>; // Visibility overrides: { indicatorId → false } (sparse)
215
+ alerts: Alert[]; // Price alerts (useAlerts) — shared across all consumers
216
+ measure: MeasureState; // Measure-tool state (useMeasure): { isActive, fromPoint, result }
217
+ replay: ReplayState; // Replay control state (useReplay): { isReplaying, isPaused, speed, barIndex, totalBars }
210
218
  styles: DeepPartial<Styles> | undefined; // Custom klinecharts styles
211
219
  screenshotUrl: string | null; // URL of the last screenshot
212
220
  }
@@ -227,6 +235,10 @@ type KlinechartsUIAction =
227
235
  | { type: "SET_MAIN_INDICATORS"; indicators: string[] }
228
236
  | { type: "SET_SUB_INDICATORS"; indicators: Record<string, string> }
229
237
  | { type: "SET_INDICATOR_AXES"; axes: Record<string, string> }
238
+ | { type: "SET_INDICATOR_VISIBILITY"; visibility: Record<string, boolean> }
239
+ | { type: "SET_ALERTS"; alerts: Alert[] }
240
+ | { type: "SET_MEASURE"; measure: Partial<MeasureState> }
241
+ | { type: "SET_REPLAY"; replay: Partial<ReplayState> }
230
242
  | { type: "SET_STYLES"; styles: DeepPartial<Styles> | undefined }
231
243
  | { type: "SET_LOCALE"; locale: string }
232
244
  | { type: "SET_SCREENSHOT_URL"; url: string | null };
@@ -457,12 +469,14 @@ const {
457
469
  moveToMain,
458
470
  moveToSub,
459
471
  setIndicatorVisible,
472
+ isIndicatorVisible,
460
473
  updateIndicatorParams,
461
474
  getIndicatorParams,
462
475
  isMainIndicatorActive,
463
476
  isSubIndicatorActive,
464
477
  indicatorAxes,
465
478
  getIndicatorAxis,
479
+ indicatorVisibility,
466
480
  bindIndicatorToNewAxis,
467
481
  } = useIndicators();
468
482
  ```
@@ -471,17 +485,20 @@ const {
471
485
 
472
486
  | Field | Type | Description |
473
487
  | ------------------------- | ------------------------ | ------------------------------------------ |
474
- | `mainIndicators` | `IndicatorInfo[]` | All main indicators with `isActive` flag |
475
- | `subIndicators` | `IndicatorInfo[]` | All sub-indicators with `isActive` flag |
488
+ | `mainIndicators` | `IndicatorInfo[]` | All main indicators with `isActive` + `visible` flags |
489
+ | `subIndicators` | `IndicatorInfo[]` | All sub-indicators with `isActive` + `visible` flags |
476
490
  | `activeMainIndicators` | `string[]` | Active main indicator names only |
477
491
  | `activeSubIndicators` | `Record<string, string>` | Active sub-indicators: `{ name → paneId }` |
478
492
  | `availableMainIndicators` | `string[]` | Full list from `MAIN_INDICATORS` |
479
493
  | `availableSubIndicators` | `string[]` | Full list from `SUB_INDICATORS` |
494
+ | `indicatorAxes` | `Record<string, string>` | Custom Y-axis bindings: `{ indicatorId → yAxisId }` |
495
+ | `indicatorVisibility` | `Record<string, boolean>`| Visibility overrides: `{ indicatorId → false }` (sparse — only hidden indicators; absent means visible) |
480
496
 
481
497
  ```typescript
482
498
  interface IndicatorInfo {
483
499
  name: string; // "MA", "MACD", "RSI", etc.
484
500
  isActive: boolean; // Whether it is currently on the chart
501
+ visible: boolean; // Whether it is currently shown (vs hidden); true when inactive
485
502
  }
486
503
  ```
487
504
 
@@ -497,7 +514,8 @@ interface IndicatorInfo {
497
514
  | `toggleSubIndicator(name)` | Same for sub-indicators |
498
515
  | `moveToMain(name)` | Moves from sub-pane to `candle_pane` |
499
516
  | `moveToSub(name)` | Moves from `candle_pane` to a new sub-pane |
500
- | `setIndicatorVisible(name, isMain, visible)` | Show/hide indicator via `chart.overrideIndicator` |
517
+ | `setIndicatorVisible(name, isMain, visible)` | Show/hide indicator via `chart.overrideIndicator`; mirrors the flag into `indicatorVisibility` |
518
+ | `isIndicatorVisible(name, isMain)` | Reactive read counterpart to `setIndicatorVisible`; returns `true` for the default/inactive state |
501
519
  | `updateIndicatorParams(name, paneId, params)` | Update `calcParams` via `chart.overrideIndicator` |
502
520
  | `getIndicatorParams(name)` | Returns `[{ label, defaultValue }]` or `[]` if no parameters |
503
521
  | `isMainIndicatorActive(name)` | Quick active check |
@@ -1022,6 +1040,8 @@ const {
1022
1040
 
1023
1041
  Measure price changes, percentage swings, bar count, and time intervals between two points on the chart.
1024
1042
 
1043
+ > **Multi-instance safe.** State lives in the shared provider store (`state.measure`), so calling `useMeasure()` in several components (e.g. a toolbar toggle and a separate result panel) keeps them in sync — no need to hoist a single instance.
1044
+
1025
1045
  ```typescript
1026
1046
  import { useMeasure } from "react-klinecharts-ui";
1027
1047
 
@@ -1095,6 +1115,8 @@ const {
1095
1115
 
1096
1116
  Replay historical candles at various speeds with play/pause/step controls and progress tracking.
1097
1117
 
1118
+ > **Multi-instance safe.** Control state lives in the shared store (`state.replay`) and the playback timer + data buffers are owned by the provider, so there is exactly one replay session no matter how many `useReplay()` instances are mounted — start in one component and step in another, and they drive the same session.
1119
+
1098
1120
  ```typescript
1099
1121
  import { useReplay } from "react-klinecharts-ui";
1100
1122
 
@@ -1127,6 +1149,128 @@ const {
1127
1149
 
1128
1150
  ---
1129
1151
 
1152
+ ### useAlerts
1153
+
1154
+ Client-side price alerts. Draws a locked horizontal line on the chart for each alert and polls the latest candle once per second, firing a callback when the close price crosses the alert level. This is the primary hook for reacting to price events — e.g. forwarding a buy/sell signal to your backend or triggering a push notification (see [Backend Signals & Notifications](#backend-signals--notifications)).
1155
+
1156
+ > **Multi-instance safe.** The alert list lives in the shared store (`state.alerts`) and the crossing poller is owned by the provider (one poller, active only while alerts exist), so multiple `useAlerts()` instances share one list. Note: `onAlertTriggered` registers a **single** listener — the last registration wins.
1157
+
1158
+ ```typescript
1159
+ import { useAlerts } from "react-klinecharts-ui";
1160
+
1161
+ const {
1162
+ alerts,
1163
+ addAlert,
1164
+ removeAlert,
1165
+ clearAlerts,
1166
+ onAlertTriggered,
1167
+ } = useAlerts();
1168
+
1169
+ const id = addAlert(65000, "crossing_up", "BTC broke 65k");
1170
+
1171
+ onAlertTriggered((alert) => {
1172
+ console.log("Alert fired:", alert.message, alert.price);
1173
+ });
1174
+ ```
1175
+
1176
+ #### Return type: `UseAlertsReturn`
1177
+
1178
+ | Property | Type | Description |
1179
+ |----------|------|-------------|
1180
+ | `alerts` | `Alert[]` | Current alerts (active and triggered) |
1181
+ | `addAlert` | `(price: number, condition: AlertCondition, message?: string) => string` | Create an alert at a price level; returns its id |
1182
+ | `removeAlert` | `(id: string) => void` | Remove a single alert and its chart line |
1183
+ | `clearAlerts` | `() => void` | Remove all alerts |
1184
+ | `onAlertTriggered` | `(callback: (alert: Alert) => void) => void` | Register a callback fired once when an alert's condition is met |
1185
+
1186
+ #### Types
1187
+
1188
+ ```typescript
1189
+ type AlertCondition = "crossing_up" | "crossing_down" | "crossing";
1190
+
1191
+ interface Alert {
1192
+ id: string;
1193
+ price: number;
1194
+ condition: AlertCondition;
1195
+ message?: string;
1196
+ triggered: boolean;
1197
+ }
1198
+ ```
1199
+
1200
+ | Condition | Fires when |
1201
+ |-----------|------------|
1202
+ | `crossing_up` | Previous close `<` price **and** current close `>=` price |
1203
+ | `crossing_down` | Previous close `>` price **and** current close `<=` price |
1204
+ | `crossing` | Either direction |
1205
+
1206
+ > Detection is based on the **latest candle's close**, polled every second from `chart.getDataList()`. An alert fires at most once (its `triggered` flag flips to `true`); recreate it to re-arm.
1207
+
1208
+ ---
1209
+
1210
+ ### useCrosshair
1211
+
1212
+ Tracks the OHLCV data of the bar currently under the crosshair. Returns `null` when the cursor is off-chart. Updates are throttled with `requestAnimationFrame`, making it suitable for driving a live data panel / legend that follows the cursor.
1213
+
1214
+ ```typescript
1215
+ import { useCrosshair } from "react-klinecharts-ui";
1216
+
1217
+ const { barData } = useCrosshair();
1218
+
1219
+ // barData is null until the cursor is over a candle
1220
+ if (barData) {
1221
+ console.log(barData.close, barData.changePercent);
1222
+ }
1223
+ ```
1224
+
1225
+ #### Return type: `UseCrosshairReturn`
1226
+
1227
+ | Property | Type | Description |
1228
+ |----------|------|-------------|
1229
+ | `barData` | `CrosshairBarData \| null` | OHLCV of the hovered bar, or `null` when off-chart |
1230
+
1231
+ #### CrosshairBarData
1232
+
1233
+ | Property | Type | Description |
1234
+ |----------|------|-------------|
1235
+ | `open` | `number` | Open price |
1236
+ | `high` | `number` | High price |
1237
+ | `low` | `number` | Low price |
1238
+ | `close` | `number` | Close price |
1239
+ | `volume` | `number` | Volume |
1240
+ | `timestamp` | `number` | Bar timestamp (ms) |
1241
+ | `change` | `number` | `close - open`, rounded to the symbol's price precision |
1242
+ | `changePercent` | `number` | Percent change relative to open, 2 decimals |
1243
+
1244
+ ---
1245
+
1246
+ ### useDataExport
1247
+
1248
+ Export chart candle data to a downloaded file in CSV or JSON format. Columns: `Date` (ISO), `Open`, `High`, `Low`, `Close`, `Volume`. The file is named `<ticker>_<YYYY-MM-DD>.<format>`.
1249
+
1250
+ ```typescript
1251
+ import { useDataExport } from "react-klinecharts-ui";
1252
+
1253
+ const { exportAll, exportVisible } = useDataExport();
1254
+
1255
+ exportAll("csv"); // every loaded bar
1256
+ exportVisible("json"); // only the currently visible range
1257
+ ```
1258
+
1259
+ #### Return type: `UseDataExportReturn`
1260
+
1261
+ | Property | Type | Description |
1262
+ |----------|------|-------------|
1263
+ | `exportAll` | `(format: ExportFormat) => void` | Download all loaded candles |
1264
+ | `exportVisible` | `(format: ExportFormat) => void` | Download only the visible range (falls back to all bars if the range is unavailable) |
1265
+
1266
+ ```typescript
1267
+ type ExportFormat = "csv" | "json";
1268
+ ```
1269
+
1270
+ > No-op when the chart is not ready or holds no data.
1271
+
1272
+ ---
1273
+
1130
1274
  ## Utilities
1131
1275
 
1132
1276
  ### createDataLoader
@@ -1271,6 +1415,29 @@ const PRICE_AXIS_TYPES = ["normal", "percentage", "log"] as const;
1271
1415
  type PriceAxisType = "normal" | "percentage" | "log";
1272
1416
  ```
1273
1417
 
1418
+ ### YAXIS_POSITIONS
1419
+
1420
+ ```typescript
1421
+ const YAXIS_POSITIONS = ["left", "right"] as const;
1422
+ type YAxisPosition = "left" | "right";
1423
+ ```
1424
+
1425
+ ### COMPARE_RULES
1426
+
1427
+ Baseline rule used when overlaying compared symbols (see [useCompare](#usecompare)).
1428
+
1429
+ ```typescript
1430
+ const COMPARE_RULES = ["current_open", "prev_close"] as const;
1431
+ type CompareRule = "current_open" | "prev_close";
1432
+ ```
1433
+
1434
+ ### TOOLTIP_SHOW_RULES
1435
+
1436
+ ```typescript
1437
+ const TOOLTIP_SHOW_RULES = ["always", "follow_cross", "none"] as const;
1438
+ type TooltipShowRule = "always" | "follow_cross" | "none";
1439
+ ```
1440
+
1274
1441
  ---
1275
1442
 
1276
1443
  ## Custom Indicator Templates
@@ -1539,6 +1706,97 @@ const savedTheme = localStorage.getItem('theme') ?? 'dark';
1539
1706
 
1540
1707
  ---
1541
1708
 
1709
+ ## Backend Signals & Notifications
1710
+
1711
+ A common question: **how do front-end indicators connect to a backend for buy/sell signals or push notifications?**
1712
+
1713
+ This library is **headless by design** — it owns chart state, datafeed wiring, and overlay management, but it deliberately does **not** generate trading signals, execute orders, or send notifications. Those belong to your application/backend layer. What the library provides is the full set of extension points to connect the two. Backend-driven signals are **not** a built-in feature and are not planned as one, because they fall outside the headless UI scope.
1714
+
1715
+ There are two directions to wire up.
1716
+
1717
+ ### Backend → chart (display server signals)
1718
+
1719
+ Push signals computed on your backend into the chart through the `Datafeed` and overlay hooks:
1720
+
1721
+ - **`Datafeed.subscribe`** — your real-time channel (WebSocket/SSE). Stream live candles, and alongside them any backend-computed signal payloads.
1722
+ - **[`useOrderLines`](#useorderlines)** — render entry/SL/TP levels as draggable horizontal lines; `onPriceChange` reports the new price when a user drags one.
1723
+ - **[`useAnnotations`](#useannotations)** — drop markers/notes on the chart at the bars where signals fired.
1724
+
1725
+ ```tsx
1726
+ // A WebSocket carrying both candles and backend signals
1727
+ const datafeed: Datafeed = {
1728
+ // ...searchSymbols / getHistoryKLineData
1729
+ subscribe(symbol, period, callback) {
1730
+ const ws = new WebSocket(`wss://api.example.com/stream/${symbol.ticker}`);
1731
+ ws.onmessage = (e) => {
1732
+ const msg = JSON.parse(e.data);
1733
+ if (msg.type === "kline") callback(msg.candle);
1734
+ if (msg.type === "signal") signalBus.emit(msg); // hand off to your UI
1735
+ };
1736
+ sockets.set(symbol.ticker, ws);
1737
+ },
1738
+ unsubscribe(symbol) {
1739
+ sockets.get(symbol.ticker)?.close();
1740
+ sockets.delete(symbol.ticker);
1741
+ },
1742
+ };
1743
+ ```
1744
+
1745
+ ```tsx
1746
+ // Render a backend signal as an order line + annotation
1747
+ function SignalLayer() {
1748
+ const { createOrderLine } = useOrderLines();
1749
+ const { addAnnotation } = useAnnotations();
1750
+
1751
+ useEffect(() => {
1752
+ return signalBus.on("signal", (s) => {
1753
+ createOrderLine({ price: s.entry, text: `${s.side} @ ${s.entry}` });
1754
+ addAnnotation(s.side === "buy" ? "▲" : "▼", s.entry, s.timestamp);
1755
+ });
1756
+ }, [createOrderLine, addAnnotation]);
1757
+
1758
+ return null;
1759
+ }
1760
+ ```
1761
+
1762
+ ### Chart → backend (react to price events)
1763
+
1764
+ Detect a price event on the client and forward it to your backend (webhook, order placement) or fire a push notification — all inside the [`useAlerts`](#usealerts) callback:
1765
+
1766
+ ```tsx
1767
+ function PriceAlertBridge() {
1768
+ const { addAlert, onAlertTriggered } = useAlerts();
1769
+
1770
+ useEffect(() => {
1771
+ addAlert(65000, "crossing_up", "BTC > 65k");
1772
+
1773
+ onAlertTriggered(async (alert) => {
1774
+ // 1. Notify your backend (e.g. to place/adjust an order)
1775
+ await fetch("https://api.example.com/signals", {
1776
+ method: "POST",
1777
+ headers: { "Content-Type": "application/json" },
1778
+ body: JSON.stringify({ price: alert.price, condition: alert.condition }),
1779
+ });
1780
+
1781
+ // 2. Browser push notification
1782
+ if (Notification.permission === "granted") {
1783
+ new Notification("Price alert", { body: alert.message });
1784
+ }
1785
+ });
1786
+ }, [addAlert, onAlertTriggered]);
1787
+
1788
+ return null;
1789
+ }
1790
+ ```
1791
+
1792
+ > The chart-side `useAlerts` detection is a convenience based on the latest candle close (polled once per second) — it is **not** a substitute for authoritative server-side alerting. For guaranteed delivery, run the alert/signal logic on your backend and use the **Backend → chart** path above to visualize it.
1793
+
1794
+ ### Observing state
1795
+
1796
+ Use **[State Callbacks](#state-callbacks)** (`onStateChange`, `onSymbolChange`, `onSubIndicatorsChange`, …) to forward symbol/period/indicator changes to your backend — for example, to subscribe the right server-side signal stream for whatever the user is currently viewing.
1797
+
1798
+ ---
1799
+
1542
1800
  ## Full Export List
1543
1801
 
1544
1802
  ```typescript
@@ -1565,7 +1823,12 @@ export { useKlinechartsUILoading, type UseKlinechartsUILoadingReturn };
1565
1823
  export { usePeriods, type UsePeriodsReturn };
1566
1824
  export { useTimezone, type UseTimezoneReturn, type TimezoneItem };
1567
1825
  export { useSymbolSearch, type UseSymbolSearchReturn };
1568
- export { useIndicators, type UseIndicatorsReturn, type IndicatorInfo };
1826
+ export {
1827
+ useIndicators,
1828
+ type UseIndicatorsReturn,
1829
+ type IndicatorInfo,
1830
+ type AddIndicatorOptions,
1831
+ };
1569
1832
  export {
1570
1833
  useDrawingTools,
1571
1834
  type UseDrawingToolsReturn,
@@ -1598,6 +1861,19 @@ export {
1598
1861
  type UseScriptEditorReturn,
1599
1862
  type ScriptPlacement,
1600
1863
  };
1864
+ export { useCrosshair, type UseCrosshairReturn, type CrosshairBarData };
1865
+ export { useAlerts, type UseAlertsReturn, type Alert, type AlertCondition };
1866
+ export { useDataExport, type UseDataExportReturn, type ExportFormat };
1867
+ export { useWatchlist, type UseWatchlistReturn, type WatchlistItem };
1868
+ export { useReplay, type UseReplayReturn, type ReplaySpeed };
1869
+ export { useCompare, type UseCompareReturn, type CompareSymbol };
1870
+ export {
1871
+ useMeasure,
1872
+ type UseMeasureReturn,
1873
+ type MeasureResult,
1874
+ type MeasurePoint,
1875
+ };
1876
+ export { useAnnotations, type UseAnnotationsReturn, type Annotation };
1601
1877
 
1602
1878
  // Data
1603
1879
  export { DEFAULT_PERIODS, type TerminalPeriod };
@@ -1650,7 +1926,7 @@ export {
1650
1926
  export * from "./indicators";
1651
1927
 
1652
1928
  // Extensions
1653
- export { registerExtensions, overlays, indicators, orderLine };
1929
+ export { registerExtensions, overlays, indicators, orderLine, depthOverlay };
1654
1930
  export type {
1655
1931
  OrderLineExtendData,
1656
1932
  OrderLineLineStyle,
@@ -1658,5 +1934,7 @@ export type {
1658
1934
  OrderLineLabelStyle,
1659
1935
  OrderLineFontStyle,
1660
1936
  OrderLinePadding,
1937
+ DepthOverlayExtendData,
1938
+ DepthOverlayRow,
1661
1939
  };
1662
1940
  ```
@@ -929,18 +929,14 @@ var ray = {
929
929
  needDefaultYAxisFigure: true,
930
930
  createPointFigures: ({ coordinates, bounding }) => {
931
931
  if (coordinates.length > 1) {
932
- let coordinate = { x: 0, y: 0 };
933
- if (coordinates[0].x === coordinates[1].x && coordinates[0].y !== coordinates[1].y) {
934
- if (coordinates[0].y < coordinates[1].y) {
935
- coordinate = { x: coordinates[0].x, y: bounding.height };
936
- } else {
937
- coordinate = { x: coordinates[0].x, y: 0 };
932
+ const coordinate = (() => {
933
+ if (coordinates[0].x === coordinates[1].x && coordinates[0].y !== coordinates[1].y) {
934
+ return coordinates[0].y < coordinates[1].y ? { x: coordinates[0].x, y: bounding.height } : { x: coordinates[0].x, y: 0 };
938
935
  }
939
- } else {
940
936
  const x = coordinates[0].x < coordinates[1].x ? bounding.width : 0;
941
937
  const y = (coordinates[1].y - coordinates[0].y) / (coordinates[1].x - coordinates[0].x) * (x - coordinates[0].x) + coordinates[0].y;
942
- coordinate = { x, y };
943
- }
938
+ return { x, y };
939
+ })();
944
940
  return [
945
941
  {
946
942
  type: "line",
@@ -1950,14 +1946,7 @@ var macdTv = {
1950
1946
  styles: (data) => {
1951
1947
  const current = data.current?.histogram ?? 0;
1952
1948
  const pre = data.prev?.histogram ?? 0;
1953
- let color = "#26A69A";
1954
- if (current > 0) {
1955
- color = current > pre ? "#26A69A" : "#B2DFDB";
1956
- } else if (current < 0) {
1957
- color = current < pre ? "#FF5252" : "#FFCDD2";
1958
- } else {
1959
- color = "#B2DFDB";
1960
- }
1949
+ const color = current > 0 ? current > pre ? "#26A69A" : "#B2DFDB" : current < 0 ? current < pre ? "#FF5252" : "#FFCDD2" : "#B2DFDB";
1961
1950
  return { color };
1962
1951
  }
1963
1952
  },
@@ -2464,5 +2453,5 @@ function registerExtensions() {
2464
2453
  }
2465
2454
 
2466
2455
  export { TA_default, abcd_default, anyWaves_default, arrow_default, bollTv_default, brush_default, cci_default, circle_default, depthOverlay_default, eightWaves_default, elliottWave_default, fibRetracement_default, fibonacciCircle_default, fibonacciExtension_default, fibonacciSegment_default, fibonacciSpeedResistanceFan_default, fibonacciSpiral_default, fiveWaves_default, gannBox_default, gannFan_default, hma_default, ichimoku_default, indicators, longPosition_default, maRibbon_default, macdTv_default, measure_default, orderLine_default, overlays, parallelChannel_default, parallelogram_default, pivotPoints_default, ray_default, rect_default, registerExtensions, rsiTv_default, shortPosition_default, stochastic_default, superTrend_default, threeWaves_default, triangle_default, vwap_default, xabcd_default };
2467
- //# sourceMappingURL=chunk-U325AHHX.js.map
2468
- //# sourceMappingURL=chunk-U325AHHX.js.map
2456
+ //# sourceMappingURL=chunk-DTBNTO4M.js.map
2457
+ //# sourceMappingURL=chunk-DTBNTO4M.js.map