acttrader-charts 1.3.0-beta.20 → 1.3.0-beta.22

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
@@ -262,6 +262,12 @@ chart.setLevels(
262
262
  );
263
263
  ```
264
264
 
265
+ **Trailing stop:** a trade with a trail always has a working stop, so keep passing its price as `stopLossPrice` and set `stopLossTrailing: true`. The line renders as usual but its pill reads **TSL** instead of SL, and it is read-only on the chart — no drag handle, no × — because the trail is a pip distance edited from the host's own panel. The level's TP stays fully editable.
266
+
267
+ ```ts
268
+ { label: 'POS-2', price: 1.0850, side: 'buy', lots: 1, stopLossPrice: 1.0800, stopLossTrailing: true }
269
+ ```
270
+
265
271
  **Bracket orders via `ToClose`** — link a separate SL/TP pending order to a parent level:
266
272
 
267
273
  ```ts
@@ -389,7 +395,7 @@ Alert | Pending | SL | TP | TSL | ×
389
395
  ```
390
396
 
391
397
  - No price readout — the axis already shows the price at that point.
392
- - **Alert** calls `onAddAlert(price)`. The chip is only rendered when that callback is set.
398
+ - **Alert** calls `onAddAlert(price)`. The chip is only rendered when that callback is set. The same callback also backs the **Alert** entry of the advanced header's ⋯ menu (`headerOverflowMenu`), which passes the current market price (live ask, else bid, else last close) so the host opens the same form.
393
399
  - **Pending** opens a sub-menu just above the bar — an `Above · 1.17586` / `Below · …`
394
400
  header, then the two orders that make sense at that price (`Buy Limit` / `Sell Stop`
395
401
  below the market, `Sell Limit` / `Buy Stop` above), each with its `@ price`. Picking a
@@ -526,14 +532,15 @@ use `{symbol}` and `{count}`. The maths behind the pill is exported as
526
532
  | `hideLevelConfirmCancel` | | `false` | Hide on-canvas ✓/✗ confirm-cancel buttons for TFC level edits |
527
533
  | `deselectActiveOnOutsideClick` | | `false` | When `true`, clicking/tapping anywhere outside a selected trade level dismisses it (reverting any pending edits, mirroring ✗ Cancel). Default `false` keeps the level active so incidental clicks — price-axis resize, taps outside the QTY input — don't drop an in-progress edit. The level can still be dismissed via ✓/✗, tapping the level again, or `setLevels()` removing it |
528
534
  | `showTradeLevelsAlways` | | `false` | Always render SL/TP bracket lines + price pills, even when the parent level is not hovered or selected. The close (×) button stays hover-only so the chart isn't cluttered. Toggleable from the Settings dialog (Trading tab). Persisted in `localStorage`. |
535
+ | `revealNewBrackets` | | `false` | When a level gains a **new** SL/TP — placed from the host's order panel, so it arrives via `setLevels()`, `updateLevelBracket()` or `updateDraftOrderBracket()` — whose price sits outside the visible price range, widen (compress) the price axis so the new line comes into view together with the candles already on screen. Animated, and the trader can drag or reset the axis afterwards as usual. A bracket dragged on the chart is visible by construction and never triggers it. Inert in compare (percent) mode |
529
536
  | `tradeLevelButtonScale` | | `1` | Multiplier for trade-level Confirm/Cancel/Edit/Close button radii and gaps. Scales visuals **and** hit/drag areas together — raise it on touch devices for larger tap targets. Clamped to `[1, 3]`. Also settable at runtime via `chart.setTradeLevelButtonScale(scale)` |
530
537
  | `tradeLevelBadgeScale` | | `1` | Shrinks the on-chart position / order tag — font, padding, grip, ✎ × buttons and their hit areas together. `0.6` is about half the default area. Clamped `[0.5, 1]` |
531
538
  | `tradeLevelBadgeAnchor` | | `"auto"` | `"left"` homes the tag at the plot's left edge like an axis label, whatever the open price or time anchor, so it never covers candles until the trader drags it. With `features.orderLineTimeDrag` the tag stays draggable along the time axis and the drop is remembered as before |
532
539
  | `tfcEnabled` | | `true` | Enable the TFC toggle button in the top bar. When `false`, TFC is completely disabled — the toggle button is hidden and all trade levels, draft orders, and the floating trade button are suppressed |
533
540
  | `crosshairEnabled` | | `true` | Draw the mouse crosshair. `false` hides it **and** the floating "place order at this price" button that rides on its horizontal line, ignores mirrored `setCrosshair()` calls and keeps the mobile long-press crosshair from arming. Trade levels, drawings and TFC are unaffected. Runtime: `chart.setCrosshairEnabled(enabled)` |
534
- | `enableCrossHairHeader` | | `false` | Crosshair on/off switch in the header (advanced toolbar, default top bar and the compact per-pane strip): the reference `rounded-sm` button. The crosshair is on by default, so the icon starts tinted; a click hides the crosshair (and the trade button riding on it) and drops the icon to its plain state, the next click brings both back. Calls `setCrosshairEnabled()` and emits `crosshairToggle` so the host can persist the choice — see [Header crosshair switch](#header-crosshair-switch--enablecrosshairheader) |
541
+ | `enableCrossHairHeader` | | `false` | Crosshair on/off switch in the header (advanced toolbar, default top bar, the compact per-pane strip and the mobile header): the reference `rounded-sm` button. The crosshair is on by default, so the icon starts tinted; a click hides the crosshair (and the trade button riding on it) and drops the icon to its plain state, the next click brings both back. Calls `setCrosshairEnabled()` and emits `crosshairToggle` so the host can persist the choice — see [Header crosshair switch](#header-crosshair-switch--enablecrosshairheader) |
535
542
  | `enableCrosshairToggle` | | `false` | **Deprecated** — alias of `enableCrossHairHeader`; either flag renders the switch |
536
- | `headerOverflowMenu` | | `false` | Advanced header only: the reference Hanko header. A 32px bar with six lowercase timeframe pills (`1m 5m 15m 1h 4h 1d`) and a ⌄ for the rest, then crosshair · P/L · Layout (grid icon) · ⋯ · fullscreen at 24px. Draw, Chart type, Indicators, Compare, Snapshot and Chart settings fold into the ⋯ menu; each keeps its behaviour |
543
+ | `headerOverflowMenu` | | `false` | Advanced header only: the reference Hanko header. A 32px bar with six lowercase timeframe pills (`1m 5m 15m 1h 4h 1d`) and a ⌄ for the rest, then crosshair · P/L · Layout (grid icon) · ⋯ · fullscreen at 24px. Draw, Chart type, Indicators, Compare, Snapshot and Chart settings fold into the ⋯ menu; each keeps its behaviour. With `onAddAlert` set the menu also offers **Alert** (own group, before Snapshot) at the current market price |
537
544
  | `features.orderLineTimeDrag` | | `false` | Enable **horizontal (time-axis) order-line dragging**. A level with `timeDraggable: true` (position or pending order) can have its info-box badge dragged left/right to re-anchor the order to a different candle — **price stays locked** while dragging sideways. Pending orders keep their vertical price drag: the badge's first movement picks the axis. Emits `orderLineMoved` on release. Off by default; intended to be enabled per broker (e.g. Hankotrade) by the host app |
538
545
  | `orderLineDragSnap` | | `true` | When horizontal dragging is enabled, snap the badge to the nearest candle on release. Set `false` to keep the exact released time |
539
546
  | `orderLineAnchorPersistence` | | `true` | When horizontal dragging is enabled, remember where each badge was dropped in `localStorage` (key `finchart.orderLineTimeAnchors`, keyed by level label) so it comes back to the same candle after a reload. A persisted anchor overrides the level's `timestamp` until the badge is dragged again. Set `false` to persist anchors yourself |
@@ -548,7 +555,7 @@ use `{symbol}` and `{count}`. The maths behind the pill is exported as
548
555
  | `quantityFieldConfig` | | — | Constraints for the draft order QTY field (only relevant when `showQuantityField` is `true`). Object: `{ minLots?: number, maxLots?: number }`. `minLots` also sets the initial quantity and the step value for the flyout input (default: `1`). `maxLots` caps the input (default: `100`) |
549
556
  | `tradesThresholdForHorizontalLine` | | `2` | Level count above which render auto-switches to `"dot"` mode |
550
557
  | `timezone` | | `"UTC"` | IANA timezone string for time-axis and crosshair labels. `"UTC"` (default), `"local"` (browser/device timezone), or any IANA string (`"America/New_York"`, `"Europe/London"`, etc.) |
551
- | `canvasColors` | | — | Per-theme colour overrides for the **canvas only** (persisted from the Settings dialog). The surface picks — `background`, `grid`, `axisText`, `axisBorder`, `crosshair` — repaint the chart canvas and leave the chart chrome (top/bottom/left bars, dialogs, popovers) on the theme from `themeOverrides`. Series picks (`candleUp`/`candleDown`/`wickUp`/`wickDown`/`borderUp`/`borderDown`/`volumeUp`/`volumeDown`) apply everywhere, so legends and indicator pills keep tracking them |
558
+ | `canvasColors` | | — | Per-theme colour overrides for the **canvas only** (persisted from the Settings dialog; runtime: `chart.setCanvasColors()`). The surface picks — `background`, `grid`, `axisText`, `axisBorder`, `crosshair` — repaint the chart canvas and leave the chart chrome (top/bottom/left bars, dialogs, popovers) on the theme from `themeOverrides`. Series picks (`candleUp`/`candleDown`/`wickUp`/`wickDown`/`borderUp`/`borderDown`/`volumeUp`/`volumeDown`) apply everywhere, so legends and indicator pills keep tracking them |
552
559
  | `aggregateFrom` | | — | Fetch finer-grained data and aggregate client-side per timeframe |
553
560
  | `onOrderSubmit` | | — | Called when user submits a trade via the floating button |
554
561
  | `onLevelEdit` | | — | Called when user confirms a TFC level edit |
@@ -931,7 +938,8 @@ chart.setTimeframe(tf: Timeframe): this // change timefr
931
938
  chart.setDuration(d: Duration, timeframe?: Timeframe): this // select a duration; pairs the timeframe and reloads
932
939
  chart.getDuration(): Duration | null // currently selected duration
933
940
  chart.setBracketLabelMode(mode, currencySymbol?): this // SL/TP pills: 'price' (default) or 'amount'
934
- chart.setThemeOverrides(overrides: ThemeOverrides): this // update per-theme color overrides at runtime
941
+ chart.setThemeOverrides(overrides: ThemeOverrides): this // update per-theme color overrides at runtime — canvas AND chrome
942
+ chart.setCanvasColors(colors: ChartConfig['canvasColors'] | null): this // recolour the canvas only at runtime (same picks as the Settings dialog); null clears
935
943
  chart.setTimezone(tz: string): this // change display timezone at runtime
936
944
  chart.setVolume(show: boolean): this
937
945
  ```
@@ -1133,6 +1133,16 @@ interface ChartConfig {
1133
1133
  * Default: `true`. Set `false` to only show them on hover/selection.
1134
1134
  */
1135
1135
  showTradeLevelsAlways?: boolean;
1136
+ /**
1137
+ * When a level gains a new SL/TP — the host's order panel just placed it, so it
1138
+ * arrives via `setLevels()`, `updateLevelBracket()` or `updateDraftOrderBracket()`
1139
+ * — and that price sits outside the visible price range, widen (compress) the
1140
+ * price axis so the new line comes into view together with the candles already
1141
+ * on screen. Animated; the trader can drag or reset the axis afterwards as usual.
1142
+ * A bracket dragged on the chart is visible by construction, so this never fires
1143
+ * for it. Off in compare (percent) mode. Default: `false`.
1144
+ */
1145
+ revealNewBrackets?: boolean;
1136
1146
  /**
1137
1147
  * Show the candle countdown timer on the right price axis, just below
1138
1148
  * the live price tag. Subject to the same `candleCountdownTimeframes`
@@ -1216,7 +1226,9 @@ interface ChartConfig {
1216
1226
  symbolNameDecoration?: 'underline' | 'none' | 'hover';
1217
1227
  /**
1218
1228
  * Called with the clicked price when the user picks **Alert** on the trade
1219
- * action bar (`features.tradeActionBar`). Omit to leave the Alert chip out.
1229
+ * action bar (`features.tradeActionBar`), and with the current market price
1230
+ * (live ask, else bid, else last close) from the **Alert** entry of the
1231
+ * advanced header's ⋯ menu (`headerOverflowMenu`). Omit to leave both out.
1220
1232
  */
1221
1233
  onAddAlert?: (price: number) => void;
1222
1234
  /**
@@ -2115,6 +2127,13 @@ interface PositionLevel {
2115
2127
  stopLossPrice?: number;
2116
2128
  /** Data object for the SL bracket — returned in SL-related events instead of the parent's `data`. */
2117
2129
  stopLossData?: unknown;
2130
+ /**
2131
+ * The stop-loss is a trailing stop. A trade with a trail always has a working stop
2132
+ * at `stopLossPrice`, so the line still renders — its pill reads "TSL" instead of
2133
+ * "SL" — but it is read-only on the chart (no drag handle, no ×): the trail lives
2134
+ * in pips and is edited from the host's order panel. Default: false.
2135
+ */
2136
+ stopLossTrailing?: boolean;
2118
2137
  /** Take-profit price. Renders as a secondary dashed line above entry (buy) or below (sell). Draggable — emits `tradeLevelBracketDrag`. */
2119
2138
  takeProfitPrice?: number;
2120
2139
  /** Data object for the TP bracket — returned in TP-related events instead of the parent's `data`. */
@@ -2197,6 +2216,8 @@ interface PendingOrderLevel {
2197
2216
  stopLossPrice?: number;
2198
2217
  /** Data object for the SL bracket — returned in SL-related events instead of the parent's `data`. */
2199
2218
  stopLossData?: unknown;
2219
+ /** The stop-loss is a trailing stop — pill reads "TSL", read-only on the chart. See `PositionLevel.stopLossTrailing`. */
2220
+ stopLossTrailing?: boolean;
2200
2221
  /**
2201
2222
  * Take-profit price. Renders as a secondary dashed line above the order price
2202
2223
  * (for buy orders) or below (for sell orders). Draggable — emits `tradeLevelBracketDrag`.
@@ -1133,6 +1133,16 @@ interface ChartConfig {
1133
1133
  * Default: `true`. Set `false` to only show them on hover/selection.
1134
1134
  */
1135
1135
  showTradeLevelsAlways?: boolean;
1136
+ /**
1137
+ * When a level gains a new SL/TP — the host's order panel just placed it, so it
1138
+ * arrives via `setLevels()`, `updateLevelBracket()` or `updateDraftOrderBracket()`
1139
+ * — and that price sits outside the visible price range, widen (compress) the
1140
+ * price axis so the new line comes into view together with the candles already
1141
+ * on screen. Animated; the trader can drag or reset the axis afterwards as usual.
1142
+ * A bracket dragged on the chart is visible by construction, so this never fires
1143
+ * for it. Off in compare (percent) mode. Default: `false`.
1144
+ */
1145
+ revealNewBrackets?: boolean;
1136
1146
  /**
1137
1147
  * Show the candle countdown timer on the right price axis, just below
1138
1148
  * the live price tag. Subject to the same `candleCountdownTimeframes`
@@ -1216,7 +1226,9 @@ interface ChartConfig {
1216
1226
  symbolNameDecoration?: 'underline' | 'none' | 'hover';
1217
1227
  /**
1218
1228
  * Called with the clicked price when the user picks **Alert** on the trade
1219
- * action bar (`features.tradeActionBar`). Omit to leave the Alert chip out.
1229
+ * action bar (`features.tradeActionBar`), and with the current market price
1230
+ * (live ask, else bid, else last close) from the **Alert** entry of the
1231
+ * advanced header's ⋯ menu (`headerOverflowMenu`). Omit to leave both out.
1220
1232
  */
1221
1233
  onAddAlert?: (price: number) => void;
1222
1234
  /**
@@ -2115,6 +2127,13 @@ interface PositionLevel {
2115
2127
  stopLossPrice?: number;
2116
2128
  /** Data object for the SL bracket — returned in SL-related events instead of the parent's `data`. */
2117
2129
  stopLossData?: unknown;
2130
+ /**
2131
+ * The stop-loss is a trailing stop. A trade with a trail always has a working stop
2132
+ * at `stopLossPrice`, so the line still renders — its pill reads "TSL" instead of
2133
+ * "SL" — but it is read-only on the chart (no drag handle, no ×): the trail lives
2134
+ * in pips and is edited from the host's order panel. Default: false.
2135
+ */
2136
+ stopLossTrailing?: boolean;
2118
2137
  /** Take-profit price. Renders as a secondary dashed line above entry (buy) or below (sell). Draggable — emits `tradeLevelBracketDrag`. */
2119
2138
  takeProfitPrice?: number;
2120
2139
  /** Data object for the TP bracket — returned in TP-related events instead of the parent's `data`. */
@@ -2197,6 +2216,8 @@ interface PendingOrderLevel {
2197
2216
  stopLossPrice?: number;
2198
2217
  /** Data object for the SL bracket — returned in SL-related events instead of the parent's `data`. */
2199
2218
  stopLossData?: unknown;
2219
+ /** The stop-loss is a trailing stop — pill reads "TSL", read-only on the chart. See `PositionLevel.stopLossTrailing`. */
2220
+ stopLossTrailing?: boolean;
2200
2221
  /**
2201
2222
  * Take-profit price. Renders as a secondary dashed line above the order price
2202
2223
  * (for buy orders) or below (for sell orders). Draggable — emits `tradeLevelBracketDrag`.