acttrader-charts 1.3.0-beta.6 → 1.3.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 +34 -0
- package/dist/{MACD-kgOWCAte.d.cts → MACD-vpoNIMIp.d.cts} +4 -1
- package/dist/{MACD-kgOWCAte.d.ts → MACD-vpoNIMIp.d.ts} +4 -1
- package/dist/index.cjs +20 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +20 -11
- package/dist/index.js.map +1 -1
- package/dist/indicators/index.d.cts +2 -2
- package/dist/indicators/index.d.ts +2 -2
- package/dist/webview/chart.html +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -684,6 +684,9 @@ chart.loadData(newBars);
|
|
|
684
684
|
chart.setSeries(series: SeriesType): this
|
|
685
685
|
chart.setTheme('dark' | 'light'): this
|
|
686
686
|
chart.setTimeframe(tf: Timeframe): this // change timeframe and reload data
|
|
687
|
+
chart.setDuration(d: Duration, timeframe?: Timeframe): this // select a duration; pairs the timeframe and reloads
|
|
688
|
+
chart.getDuration(): Duration | null // currently selected duration
|
|
689
|
+
chart.setBracketLabelMode(mode, currencySymbol?): this // SL/TP pills: 'price' (default) or 'amount'
|
|
687
690
|
chart.setThemeOverrides(overrides: ThemeOverrides): this // update per-theme color overrides at runtime
|
|
688
691
|
chart.setTimezone(tz: string): this // change display timezone at runtime
|
|
689
692
|
chart.setVolume(show: boolean): this
|
|
@@ -888,6 +891,37 @@ Sub-pane heights are user-resizable by dragging the separator between panes.
|
|
|
888
891
|
| `flatChannel` | Flat Channel | 2 clicks |
|
|
889
892
|
| `disjointChannel` | Disjoint Channel | 3 clicks |
|
|
890
893
|
|
|
894
|
+
### SL/TP bracket labels — price or amount
|
|
895
|
+
|
|
896
|
+
By default an SL/TP pill reads `SL 4159.00`. With `bracketLabelMode: 'amount'`
|
|
897
|
+
it reads `SL -$290.80` — the money the position gains or loses if that bracket
|
|
898
|
+
is hit, currency symbol in front.
|
|
899
|
+
|
|
900
|
+
The chart has no access to contract specs or the account currency, so each level
|
|
901
|
+
supplies what the maths needs:
|
|
902
|
+
|
|
903
|
+
```ts
|
|
904
|
+
new ChartEngine({ container, bracketLabelMode: 'amount', currencySymbol: '$' });
|
|
905
|
+
|
|
906
|
+
chart.setLevels([{
|
|
907
|
+
label: 'POS-1', price: 4173.54, side: 'buy', lots: 0.20,
|
|
908
|
+
stopLossPrice: 4159.00, takeProfitPrice: 4183.00,
|
|
909
|
+
contractSize: 100, // units per lot (100 for XAUUSD, 100000 for most FX)
|
|
910
|
+
valuePerPoint: 1, // account-currency value of one price unit
|
|
911
|
+
currencySymbol: '$', // optional per-level override
|
|
912
|
+
}], 'label', 'price', 'position');
|
|
913
|
+
// pills render: SL -$290.80 TP +$189.20
|
|
914
|
+
```
|
|
915
|
+
|
|
916
|
+
```
|
|
917
|
+
amount = (bracket − entry) × direction × lots × contractSize × valuePerPoint
|
|
918
|
+
```
|
|
919
|
+
|
|
920
|
+
`valuePerPoint` is where a quote → account currency conversion goes. A level
|
|
921
|
+
missing `lots` or `contractSize` keeps showing its price, so a partial rollout
|
|
922
|
+
degrades level by level rather than rendering `NaN`. Toggle at runtime with
|
|
923
|
+
`chart.setBracketLabelMode('amount')`.
|
|
924
|
+
|
|
891
925
|
### Fibonacci & Gann
|
|
892
926
|
|
|
893
927
|
`fibRetracement` · `fibExtension` · `fibChannel` · `fibTimezone` · `fibCircles` · `fibSpiral` · `fibFan` · `fibProjection` · `gannFan` · `gannSquare` · `gannBox`
|
|
@@ -1009,8 +1009,11 @@ interface ChartConfig {
|
|
|
1009
1009
|
* is hit — `SL -$290.80` — computed from the level's `lots`, `contractSize`
|
|
1010
1010
|
* and `valuePerPoint`. Falls back to the price for any level lacking the
|
|
1011
1011
|
* data needed to compute it, so a partial rollout degrades gracefully.
|
|
1012
|
+
* `'priceAndAmount'` keeps the price but puts the currency symbol in front
|
|
1013
|
+
* of it — `SL $1.27859` — and appends the P/L while the bracket is being
|
|
1014
|
+
* dragged: `SL $1.27859 -$29.08`.
|
|
1012
1015
|
*/
|
|
1013
|
-
bracketLabelMode?: 'price' | 'amount';
|
|
1016
|
+
bracketLabelMode?: 'price' | 'amount' | 'priceAndAmount';
|
|
1014
1017
|
/**
|
|
1015
1018
|
* Currency symbol for SL/TP amounts, used when `bracketLabelMode: 'amount'`
|
|
1016
1019
|
* and the level does not carry its own `currencySymbol`. Default `'$'`.
|
|
@@ -1009,8 +1009,11 @@ interface ChartConfig {
|
|
|
1009
1009
|
* is hit — `SL -$290.80` — computed from the level's `lots`, `contractSize`
|
|
1010
1010
|
* and `valuePerPoint`. Falls back to the price for any level lacking the
|
|
1011
1011
|
* data needed to compute it, so a partial rollout degrades gracefully.
|
|
1012
|
+
* `'priceAndAmount'` keeps the price but puts the currency symbol in front
|
|
1013
|
+
* of it — `SL $1.27859` — and appends the P/L while the bracket is being
|
|
1014
|
+
* dragged: `SL $1.27859 -$29.08`.
|
|
1012
1015
|
*/
|
|
1013
|
-
bracketLabelMode?: 'price' | 'amount';
|
|
1016
|
+
bracketLabelMode?: 'price' | 'amount' | 'priceAndAmount';
|
|
1014
1017
|
/**
|
|
1015
1018
|
* Currency symbol for SL/TP amounts, used when `bracketLabelMode: 'amount'`
|
|
1016
1019
|
* and the level does not carry its own `currencySymbol`. Default `'$'`.
|
package/dist/index.cjs
CHANGED
|
@@ -1906,10 +1906,12 @@ var BRACKET_BOX_PAD_Y = 3;
|
|
|
1906
1906
|
var BRACKET_BOX_H = ROW_H + BRACKET_BOX_PAD_Y * 2;
|
|
1907
1907
|
var FONT_BRACKET = "12px 'Inter', system-ui, sans-serif";
|
|
1908
1908
|
var DEFAULT_BRACKET_LABEL = { mode: "price", currencySymbol: "$" };
|
|
1909
|
-
function bracketBoxLabel(bracketType, price, precision, level, opts = DEFAULT_BRACKET_LABEL) {
|
|
1909
|
+
function bracketBoxLabel(bracketType, price, precision, level, opts = DEFAULT_BRACKET_LABEL, active = false) {
|
|
1910
1910
|
const typeLabel = bracketType === "stopLoss" ? "SL" : "TP";
|
|
1911
|
-
|
|
1912
|
-
|
|
1911
|
+
const symbol = level?.currencySymbol ?? opts.currencySymbol;
|
|
1912
|
+
const amount = () => {
|
|
1913
|
+
if (!level || !level.side || typeof level.lots !== "number") return null;
|
|
1914
|
+
return bracketPnl({
|
|
1913
1915
|
entryPrice: level.price,
|
|
1914
1916
|
bracketPrice: price,
|
|
1915
1917
|
side: level.side,
|
|
@@ -1917,9 +1919,16 @@ function bracketBoxLabel(bracketType, price, precision, level, opts = DEFAULT_BR
|
|
|
1917
1919
|
contractSize: level.contractSize,
|
|
1918
1920
|
valuePerPoint: level.valuePerPoint
|
|
1919
1921
|
});
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1922
|
+
};
|
|
1923
|
+
if (opts.mode === "amount") {
|
|
1924
|
+
const pnl = amount();
|
|
1925
|
+
if (pnl !== null) return `${typeLabel} ${formatMoney(pnl, symbol)}`;
|
|
1926
|
+
}
|
|
1927
|
+
if (opts.mode === "priceAndAmount") {
|
|
1928
|
+
const priced = `${typeLabel} ${symbol}${price.toFixed(precision)}`;
|
|
1929
|
+
if (!active) return priced;
|
|
1930
|
+
const pnl = amount();
|
|
1931
|
+
return pnl === null ? priced : `${priced} ${formatMoney(pnl, symbol)}`;
|
|
1923
1932
|
}
|
|
1924
1933
|
return `${typeLabel} ${price.toFixed(precision)}`;
|
|
1925
1934
|
}
|
|
@@ -2318,8 +2327,8 @@ function renderTradeLevels(ctx, levels, scale, priceRange, theme, chartW, priceH
|
|
|
2318
2327
|
ctx.save();
|
|
2319
2328
|
ctx.font = FONT_BRACKET;
|
|
2320
2329
|
const closeSlot = CLOSE_R * 2 + BRACKET_BOX_PAD_X / 2;
|
|
2321
|
-
const slBW = BRACKET_BOX_PAD_X + ctx.measureText(bracketBoxLabel("stopLoss", offSlPrice, precision, bh, bracketLabel)).width + BRACKET_BOX_PAD_X + closeSlot;
|
|
2322
|
-
const tpBW = BRACKET_BOX_PAD_X + ctx.measureText(bracketBoxLabel("takeProfit", offTpPrice, precision, bh, bracketLabel)).width + BRACKET_BOX_PAD_X + closeSlot;
|
|
2330
|
+
const slBW = BRACKET_BOX_PAD_X + ctx.measureText(bracketBoxLabel("stopLoss", offSlPrice, precision, bh, bracketLabel, draggingLabel === slDragKey)).width + BRACKET_BOX_PAD_X + closeSlot;
|
|
2331
|
+
const tpBW = BRACKET_BOX_PAD_X + ctx.measureText(bracketBoxLabel("takeProfit", offTpPrice, precision, bh, bracketLabel, draggingLabel === tpDragKey)).width + BRACKET_BOX_PAD_X + closeSlot;
|
|
2323
2332
|
ctx.restore();
|
|
2324
2333
|
const connX = ((bracketLineXMap.get(slDragKey) ?? fallbackX) - slBW / 2 - 2 + ((bracketLineXMap.get(tpDragKey) ?? fallbackX) - tpBW / 2 - 2)) / 2;
|
|
2325
2334
|
const slPillY = bracketBoxYMap.get(slDragKey) ?? slY - bracketBH / 2;
|
|
@@ -2642,8 +2651,8 @@ function drawLevel(ctx, level, layout, chartW, colors, theme, precision, hovered
|
|
|
2642
2651
|
ctx.save();
|
|
2643
2652
|
ctx.font = FONT_BRACKET;
|
|
2644
2653
|
const closeSlot = hideConfirmCancel ? 0 : closeR * 2 + BRACKET_BOX_PAD_X / 2;
|
|
2645
|
-
const slBW = BRACKET_BOX_PAD_X + ctx.measureText(bracketBoxLabel("stopLoss", slRenderPrice, precision, level, bracketLabel)).width + BRACKET_BOX_PAD_X + closeSlot;
|
|
2646
|
-
const tpBW = BRACKET_BOX_PAD_X + ctx.measureText(bracketBoxLabel("takeProfit", tpRenderPrice, precision, level, bracketLabel)).width + BRACKET_BOX_PAD_X + closeSlot;
|
|
2654
|
+
const slBW = BRACKET_BOX_PAD_X + ctx.measureText(bracketBoxLabel("stopLoss", slRenderPrice, precision, level, bracketLabel, draggingLabel === slDragKey)).width + BRACKET_BOX_PAD_X + closeSlot;
|
|
2655
|
+
const tpBW = BRACKET_BOX_PAD_X + ctx.measureText(bracketBoxLabel("takeProfit", tpRenderPrice, precision, level, bracketLabel, draggingLabel === tpDragKey)).width + BRACKET_BOX_PAD_X + closeSlot;
|
|
2647
2656
|
ctx.restore();
|
|
2648
2657
|
const slBLineX = bracketLineXMap.get(slDragKey) ?? chartW * BRACKET_BASE_RATIO;
|
|
2649
2658
|
const tpBLineX = bracketLineXMap.get(tpDragKey) ?? chartW * BRACKET_BASE_RATIO;
|
|
@@ -3083,7 +3092,7 @@ function drawBracketLine(ctx, level, bracketType, bracketPrice, scale, priceRang
|
|
|
3083
3092
|
ctx.lineTo(chartW, y);
|
|
3084
3093
|
ctx.stroke();
|
|
3085
3094
|
ctx.globalAlpha = 1;
|
|
3086
|
-
const boxLabel = bracketBoxLabel(bracketType, price, precision, level, bracketLabel);
|
|
3095
|
+
const boxLabel = bracketBoxLabel(bracketType, price, precision, level, bracketLabel, isDraggingThis);
|
|
3087
3096
|
ctx.font = FONT_BRACKET;
|
|
3088
3097
|
const textW = ctx.measureText(boxLabel).width;
|
|
3089
3098
|
const pnlW = pnlText ? ctx.measureText(pnlText).width + BRACKET_BOX_PAD_X : 0;
|