acttrader-charts 1.2.0-beta.5 → 1.2.0-beta.7

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
@@ -141,7 +141,26 @@ Auto-reconnects with exponential backoff (2 s → 30 s). Stream status is reflec
141
141
  To push ticks directly without an adapter (e.g. from your own WebSocket handler):
142
142
 
143
143
  ```ts
144
- chart.pushTick({ time: Date.now(), bid: 1.2055, ask: 1.2057, volume: 120 });
144
+ chart.pushTick({ B: 1.2055, A: 1.2057, T: Date.now() });
145
+
146
+ // Exchange/dealing feeds: include the last traded price/volume on trade ticks —
147
+ // consumed when the chart is configured with `tickClosePriceSource: 'ltp'`.
148
+ chart.pushTick({ B: 1.2055, A: 1.2057, T: Date.now(), LTP: 1.2056, LTPV: 120 });
149
+
150
+ // Dealing-feed setup — candle-source toggle + independent line checks:
151
+ const dealingChart = new ChartEngine({
152
+ container,
153
+ // "Show chart by" toggle: 'ltp' | 'ask' | 'bid' (candle close/high/low source)
154
+ tickClosePriceSource: 'ltp',
155
+ // Chart line checkboxes — each price line is independent:
156
+ showAskLine: true, // Show AskLine
157
+ showBidLine: true, // Show BidLine
158
+ showLtpPrice: true, // Show LTP Line (dashed line + axis tag)
159
+ });
160
+ // ...and at runtime:
161
+ dealingChart.setShowAskLine(false); // hide the ask line
162
+ dealingChart.setShowBidLine(true); // show the bid line
163
+ dealingChart.setShowLtpPrice(true); // show the LTP line
145
164
  ```
146
165
 
147
166
  ### Compare symbols
@@ -382,8 +401,11 @@ chart.on('orderLineMoved', ({ label, fromTimestamp, toTimestamp, data }) => {
382
401
  | `themeOverrides` | | — | Deep-partial color overrides applied on top of the built-in dark/light themes |
383
402
  | `uiConfig` | | `DEFAULT_UI_CONFIG` | Deep-partial size / font overrides per component |
384
403
  | `labels` | | `DEFAULT_LABELS` | Deep-partial string overrides for i18n/translation |
385
- | `tickClosePriceSource` | | `"bid"` | Which quote side drives live tick close/high/low (`"bid"` or `"ask"`) |
386
- | `showBidAskLines` | | `false` | Show both bid and ask as dashed lines during a live stream |
404
+ | `tickClosePriceSource` | | `"bid"` | Which price drives live tick close/high/low: `"bid"`, `"ask"`, or `"ltp"` (build candles from the last traded price — exchange/dealing feeds; ticks without a valid LTP fall back to the bid) |
405
+ | `showLtpPrice` | | unset | Show the LTP marker (dashed price line + axis tag). Unset: shown only in `"ltp"` mode. `true`: always shown when the feed supplies an LTP. `false`: hidden even in `"ltp"` mode (candles still build from the LTP). Toggle at runtime with `chart.setShowLtpPrice(show)` |
406
+ | `showBidAskLines` | | `false` | **Deprecated** — show both bid and ask as dashed lines during a live stream. Prefer the per-line checks `showAskLine` / `showBidLine`, which override it when set |
407
+ | `showAskLine` | | unset | Show the Ask price line (dashed line + axis tag) independently. Unset: legacy `showBidAskLines` behavior. Toggle at runtime with `chart.setShowAskLine(show)` |
408
+ | `showBidLine` | | unset | Show the Bid price line (dashed line + axis tag) independently. Unset: legacy `showBidAskLines` behavior. Toggle at runtime with `chart.setShowBidLine(show)` |
387
409
  | `showActLogo` | | `false` | Show the ACT watermark logo in the bottom-left corner |
388
410
  | `showCandleCountdown` | | `true` | Show countdown timer on the live candle (time axis) |
389
411
  | `candleCountdownTimeframes` | | intraday only | Timeframes where the countdown appears; `'all'` or `Timeframe[]` |
@@ -721,7 +743,7 @@ chart.isAtLiveEdge(): boolean
721
743
  ```ts
722
744
  chart.connectStream(adapter: IWebSocketAdapter): this
723
745
  chart.disconnectStream(): this
724
- chart.pushTick(tick: { time: number; bid: number; ask: number; volume?: number }): void // push a tick directly without an adapter
746
+ chart.pushTick(prices: { B: number; A: number; T?: string | number; LTP?: number; LTPV?: number }): this // push a tick directly without an adapter; LTP/LTPV feed 'ltp' mode
725
747
  ```
726
748
 
727
749
  ### State Persistence
@@ -841,11 +841,21 @@ interface ChartConfig {
841
841
  */
842
842
  targetCandleWidth?: number;
843
843
  /**
844
- * Which side of the quote to use for candle close/high/low during live
845
- * tick updates. Defaults to `'bid'` (forex convention). Set to `'ask'`
846
- * if your broker streams ask-based OHLCV bars.
844
+ * Which price to use for candle close/high/low during live tick updates.
845
+ * Defaults to `'bid'` (forex convention). Set to `'ask'` if your broker
846
+ * streams ask-based OHLCV bars, or `'ltp'` for exchange/dealing feeds
847
+ * that stream a last-traded price — ticks without a valid LTP fall back
848
+ * to the bid.
847
849
  */
848
- tickClosePriceSource?: 'bid' | 'ask';
850
+ tickClosePriceSource?: 'bid' | 'ask' | 'ltp';
851
+ /**
852
+ * Show the last-traded-price (LTP) marker — dashed price line + axis tag.
853
+ * Defaults to following `tickClosePriceSource`: the marker is shown only in
854
+ * `'ltp'` mode. Set `true` to always show it when the feed supplies an LTP
855
+ * (even on a bid/ask-driven chart), or `false` to hide it even in `'ltp'`
856
+ * mode (candles still build from the LTP).
857
+ */
858
+ showLtpPrice?: boolean;
849
859
  /**
850
860
  * When the combined count of open positions and pending orders exceeds this
851
861
  * number, the position render style auto-defaults to `'dot'` (compact).
@@ -877,8 +887,23 @@ interface ChartConfig {
877
887
  * When `false` (default), only the `tickClosePriceSource` side is shown.
878
888
  * Only relevant when a live tick stream is active.
879
889
  * Default: `false`.
890
+ * @deprecated Prefer the per-line checks `showAskLine` / `showBidLine`,
891
+ * which override this flag when set.
880
892
  */
881
893
  showBidAskLines?: boolean;
894
+ /**
895
+ * Show the Ask price line (dashed line + axis tag) independently of the
896
+ * Bid line. Unset falls back to the legacy `showBidAskLines` behavior
897
+ * (both sides when `true`, only the `tickClosePriceSource` side when
898
+ * `false`). Toggle at runtime with `setShowAskLine()`.
899
+ */
900
+ showAskLine?: boolean;
901
+ /**
902
+ * Show the Bid price line (dashed line + axis tag) independently of the
903
+ * Ask line. Unset falls back to the legacy `showBidAskLines` behavior.
904
+ * Toggle at runtime with `setShowBidLine()`.
905
+ */
906
+ showBidLine?: boolean;
882
907
  /**
883
908
  * Show the ACT logo watermark in the bottom-left corner of the price pane.
884
909
  * Default: `false`.
@@ -1255,6 +1280,8 @@ interface Tick {
1255
1280
  bid: number;
1256
1281
  ask: number;
1257
1282
  volume: number;
1283
+ /** Last traded price (exchange/dealing feeds). Absent on pure quote feeds. */
1284
+ ltp?: number;
1258
1285
  }
1259
1286
  interface IWebSocketAdapter {
1260
1287
  connect(): void;
@@ -841,11 +841,21 @@ interface ChartConfig {
841
841
  */
842
842
  targetCandleWidth?: number;
843
843
  /**
844
- * Which side of the quote to use for candle close/high/low during live
845
- * tick updates. Defaults to `'bid'` (forex convention). Set to `'ask'`
846
- * if your broker streams ask-based OHLCV bars.
844
+ * Which price to use for candle close/high/low during live tick updates.
845
+ * Defaults to `'bid'` (forex convention). Set to `'ask'` if your broker
846
+ * streams ask-based OHLCV bars, or `'ltp'` for exchange/dealing feeds
847
+ * that stream a last-traded price — ticks without a valid LTP fall back
848
+ * to the bid.
847
849
  */
848
- tickClosePriceSource?: 'bid' | 'ask';
850
+ tickClosePriceSource?: 'bid' | 'ask' | 'ltp';
851
+ /**
852
+ * Show the last-traded-price (LTP) marker — dashed price line + axis tag.
853
+ * Defaults to following `tickClosePriceSource`: the marker is shown only in
854
+ * `'ltp'` mode. Set `true` to always show it when the feed supplies an LTP
855
+ * (even on a bid/ask-driven chart), or `false` to hide it even in `'ltp'`
856
+ * mode (candles still build from the LTP).
857
+ */
858
+ showLtpPrice?: boolean;
849
859
  /**
850
860
  * When the combined count of open positions and pending orders exceeds this
851
861
  * number, the position render style auto-defaults to `'dot'` (compact).
@@ -877,8 +887,23 @@ interface ChartConfig {
877
887
  * When `false` (default), only the `tickClosePriceSource` side is shown.
878
888
  * Only relevant when a live tick stream is active.
879
889
  * Default: `false`.
890
+ * @deprecated Prefer the per-line checks `showAskLine` / `showBidLine`,
891
+ * which override this flag when set.
880
892
  */
881
893
  showBidAskLines?: boolean;
894
+ /**
895
+ * Show the Ask price line (dashed line + axis tag) independently of the
896
+ * Bid line. Unset falls back to the legacy `showBidAskLines` behavior
897
+ * (both sides when `true`, only the `tickClosePriceSource` side when
898
+ * `false`). Toggle at runtime with `setShowAskLine()`.
899
+ */
900
+ showAskLine?: boolean;
901
+ /**
902
+ * Show the Bid price line (dashed line + axis tag) independently of the
903
+ * Ask line. Unset falls back to the legacy `showBidAskLines` behavior.
904
+ * Toggle at runtime with `setShowBidLine()`.
905
+ */
906
+ showBidLine?: boolean;
882
907
  /**
883
908
  * Show the ACT logo watermark in the bottom-left corner of the price pane.
884
909
  * Default: `false`.
@@ -1255,6 +1280,8 @@ interface Tick {
1255
1280
  bid: number;
1256
1281
  ask: number;
1257
1282
  volume: number;
1283
+ /** Last traded price (exchange/dealing feeds). Absent on pure quote feeds. */
1284
+ ltp?: number;
1258
1285
  }
1259
1286
  interface IWebSocketAdapter {
1260
1287
  connect(): void;
package/dist/index.cjs CHANGED
@@ -22212,6 +22212,8 @@ var _ChartEngine = class _ChartEngine {
22212
22212
  // Streaming
22213
22213
  this.streamAdapter = null;
22214
22214
  this.liveBidAsk = null;
22215
+ /** Last traded price from the most recent tick that carried one ('ltp' source mode). */
22216
+ this.liveLtp = null;
22215
22217
  this.tickClosePriceSource = "bid";
22216
22218
  /** True while an async data fetch is in-flight; suppresses tick processing to
22217
22219
  * prevent stale ticks from corrupting newly-loaded bars. */
@@ -23337,10 +23339,11 @@ var _ChartEngine = class _ChartEngine {
23337
23339
  if (all.length === 0) return;
23338
23340
  if (this._suppressTicks) return;
23339
23341
  this.liveBidAsk = { bid: tick.bid, ask: tick.ask };
23342
+ if (tick.ltp != null && tick.ltp > 0) this.liveLtp = tick.ltp;
23340
23343
  this.setDotTickActive();
23341
23344
  const last = all[all.length - 1];
23342
23345
  const intervalMs = this.timeframeToMs(this.timeframe);
23343
- const tickPrice = this.tickClosePriceSource === "ask" ? tick.ask : tick.bid;
23346
+ const tickPrice = this.tickClosePriceSource === "ltp" ? this.liveLtp ?? tick.bid : this.tickClosePriceSource === "ask" ? tick.ask : tick.bid;
23344
23347
  if (tick.time < last.time + intervalMs) {
23345
23348
  const updated = {
23346
23349
  ...last,
@@ -23457,6 +23460,7 @@ var _ChartEngine = class _ChartEngine {
23457
23460
  this._targetViewport = { ...this.viewport };
23458
23461
  this.maxSubPanes = config.maxSubPanes ?? 3;
23459
23462
  this.tickClosePriceSource = config.tickClosePriceSource ?? "bid";
23463
+ this.showLtpPrice = config.showLtpPrice;
23460
23464
  this.tradesThresholdForHorizontalLine = config.tradesThresholdForHorizontalLine ?? 2;
23461
23465
  if (config.positionRenderStyle === "line" || config.positionRenderStyle === "dot") {
23462
23466
  this.positionRenderStyleOverride = config.positionRenderStyle;
@@ -23476,6 +23480,8 @@ var _ChartEngine = class _ChartEngine {
23476
23480
  }
23477
23481
  this.recomputeRenderStyle();
23478
23482
  this.showBidAskLines = config.showBidAskLines ?? false;
23483
+ this.showAskLine = config.showAskLine;
23484
+ this.showBidLine = config.showBidLine;
23479
23485
  this.showActLogo = config.showActLogo ?? false;
23480
23486
  this.hideLevelConfirmCancel = config.hideLevelConfirmCancel ?? false;
23481
23487
  this.deselectActiveOnOutsideClick = config.deselectActiveOnOutsideClick ?? false;
@@ -24318,6 +24324,7 @@ var _ChartEngine = class _ChartEngine {
24318
24324
  this._suppressTicks = false;
24319
24325
  if (bars.length > 0) this.setNoData(false);
24320
24326
  this.liveBidAsk = null;
24327
+ this.liveLtp = null;
24321
24328
  this.pricePanOffset = 0;
24322
24329
  this.priceScaleFactor = 1;
24323
24330
  this._displayedPriceRange = null;
@@ -25371,6 +25378,7 @@ var _ChartEngine = class _ChartEngine {
25371
25378
  if (this.siStreamDot)
25372
25379
  this.siStreamDot.style.background = this.theme.ui.stream[this.streamStatus];
25373
25380
  this.liveBidAsk = null;
25381
+ this.liveLtp = null;
25374
25382
  return this;
25375
25383
  }
25376
25384
  /**
@@ -25588,12 +25596,43 @@ var _ChartEngine = class _ChartEngine {
25588
25596
  this.streamAdapter = null;
25589
25597
  return this;
25590
25598
  }
25599
+ /** Show/hide the LTP (last traded price) marker — dashed line + axis tag.
25600
+ * `true` always shows it when the feed supplies an LTP, `false` hides it
25601
+ * even in `'ltp'` mode; pass `undefined` to restore the default
25602
+ * (shown only when `tickClosePriceSource` is `'ltp'`). */
25603
+ setShowLtpPrice(show) {
25604
+ this.showLtpPrice = show;
25605
+ this.scheduleRender();
25606
+ return this;
25607
+ }
25608
+ /** Show/hide the Ask price line (dashed line + axis tag). Pass `undefined`
25609
+ * to restore the legacy `showBidAskLines` fallback. */
25610
+ setShowAskLine(show) {
25611
+ this.showAskLine = show;
25612
+ this.scheduleRender();
25613
+ return this;
25614
+ }
25615
+ /** Show/hide the Bid price line (dashed line + axis tag). Pass `undefined`
25616
+ * to restore the legacy `showBidAskLines` fallback. */
25617
+ setShowBidLine(show) {
25618
+ this.showBidLine = show;
25619
+ this.scheduleRender();
25620
+ return this;
25621
+ }
25591
25622
  /** Push a live bid/ask tick directly — no adapter needed.
25592
25623
  * Pass `T` from your feed as the server timestamp (ISO string or Unix ms)
25593
- * to avoid system clock skew causing premature candle formation. */
25624
+ * to avoid system clock skew causing premature candle formation.
25625
+ * `LTP`/`LTPV` (last traded price/volume) are optional — sent by
25626
+ * exchange/dealing feeds and consumed when `tickClosePriceSource: 'ltp'`. */
25594
25627
  pushTick(prices) {
25595
25628
  const time = prices.T != null ? typeof prices.T === "string" ? new Date(prices.T).getTime() : prices.T : Date.now();
25596
- this.onTick({ time, bid: prices.B, ask: prices.A, volume: 0 });
25629
+ this.onTick({
25630
+ time,
25631
+ bid: prices.B,
25632
+ ask: prices.A,
25633
+ volume: prices.LTPV != null && prices.LTPV > 0 ? prices.LTPV : 0,
25634
+ ltp: prices.LTP != null && prices.LTP > 0 ? prices.LTP : void 0
25635
+ });
25597
25636
  return this;
25598
25637
  }
25599
25638
  // ── Trade / Position level API ────────────────────────────────────────────
@@ -27693,18 +27732,19 @@ var _ChartEngine = class _ChartEngine {
27693
27732
  let primaryPriceBoxW = 0;
27694
27733
  if (this.liveBidAsk) {
27695
27734
  const { bid, ask } = this.liveBidAsk;
27696
- if (this.showBidAskLines) {
27697
- const bidTag = drawPriceLine(bid, theme.candle.down, "");
27698
- const askTag = drawPriceLine(ask, theme.candle.up, "");
27699
- const primary = this.tickClosePriceSource === "ask" ? askTag : bidTag;
27735
+ const isLtpMode = this.tickClosePriceSource === "ltp";
27736
+ const ltpVisible = this.showLtpPrice ?? isLtpMode;
27737
+ const ltpPrice = ltpVisible ? this.liveLtp ?? (isLtpMode ? bid : null) : null;
27738
+ const ltpColor = lastBar.close >= lastBar.open ? theme.candle.up : theme.candle.down;
27739
+ const askVisible = this.showAskLine ?? (this.showBidAskLines || this.tickClosePriceSource === "ask");
27740
+ const bidVisible = this.showBidLine ?? (this.showBidAskLines || this.tickClosePriceSource === "bid" || isLtpMode && ltpPrice == null);
27741
+ const bidTag = bidVisible ? drawPriceLine(bid, theme.candle.down, "") : null;
27742
+ const askTag = askVisible ? drawPriceLine(ask, theme.candle.up, "") : null;
27743
+ const ltpTag = ltpPrice != null ? drawPriceLine(ltpPrice, ltpColor, "") : null;
27744
+ const primary = isLtpMode ? ltpTag ?? bidTag ?? askTag : this.tickClosePriceSource === "ask" ? askTag ?? ltpTag ?? bidTag : bidTag ?? ltpTag ?? askTag;
27745
+ if (primary) {
27700
27746
  primaryPriceY = primary.y;
27701
27747
  primaryPriceBoxW = primary.boxW;
27702
- } else {
27703
- const price = this.tickClosePriceSource === "ask" ? ask : bid;
27704
- const color = this.tickClosePriceSource === "ask" ? theme.candle.up : theme.candle.down;
27705
- const tag = drawPriceLine(price, color, "");
27706
- primaryPriceY = tag.y;
27707
- primaryPriceBoxW = tag.boxW;
27708
27748
  }
27709
27749
  } else {
27710
27750
  const isUp = lastBar.close >= lastBar.open;