@forgecharts/sdk 1.5.21 → 1.5.23

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/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { TextStyle, Application, Container, Graphics, Text, FillGradient } from 'pixi.js';
1
+ import { TextStyle, Application, Container, Graphics, Text, FillGradient, CanvasTextMetrics } from 'pixi.js';
2
2
  import { forwardRef, useRef, useState, useImperativeHandle, useEffect, useCallback, createContext, useMemo, useContext } from 'react';
3
3
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
4
  import ReactDOM from 'react-dom';
@@ -7761,9 +7761,11 @@ function orderRoleLabel(role) {
7761
7761
  }
7762
7762
  }
7763
7763
  function isDraggableRole(role) {
7764
- return role === "stop_loss" || role === "take_profit";
7764
+ return role === "stop_loss" || role === "take_profit" || role === "limit" || role === "stop";
7765
7765
  }
7766
7766
  var LINE_H = 15;
7767
+ var LABEL_GAP = 6;
7768
+ var LABEL_PAD = 6;
7767
7769
  var PILL_H = 16;
7768
7770
  var PILL_W = 28;
7769
7771
  var PILL_R = 4;
@@ -7930,13 +7932,18 @@ var PixiTradingRenderer = class {
7930
7932
  this._drawDragHandle(plotWidth - 26, y, color, alpha);
7931
7933
  }
7932
7934
  const boxY = y - LINE_H / 2;
7935
+ const roleStr = orderRoleLabel(order.role);
7936
+ const text = roleStr ? `${roleStr} ${order.qty}` : `${order.side.toUpperCase()} ${order.qty}`;
7937
+ const textW = Math.ceil(CanvasTextMetrics.measureText(text, labelStyle).width);
7938
+ const pillW = textW + LABEL_PAD * 2;
7939
+ const pillX = Math.max(0, plotWidth - LABEL_GAP - pillW);
7940
+ this._boxGfx.roundRect(pillX, boxY, pillW, LINE_H, PILL_R).fill({ color, alpha });
7941
+ labelIdx = this._drawLabel(text, pillX + pillW / 2, y, labelIdx, labelStyle, true);
7933
7942
  this._boxGfx.rect(plotWidth, boxY, psWidth, LINE_H).fill({ color, alpha });
7943
+ labelIdx = this._drawLabel(order.price.toFixed(2), plotWidth + 4, y, labelIdx, labelStyle);
7934
7944
  if (isDraggableRole(order.role)) {
7935
7945
  this._orderHitZones.push({ id: order.id, role: order.role, x: 0, y: boxY, w: plotWidth + psWidth, h: LINE_H });
7936
7946
  }
7937
- const roleStr = orderRoleLabel(order.role);
7938
- const text = roleStr && isDraggableRole(order.role) ? `${roleStr} ${order.price.toFixed(2)}` : roleStr ? `${roleStr} ${order.qty}` : `${order.side.toUpperCase()} ${order.qty}`;
7939
- labelIdx = this._drawLabel(text, plotWidth + 4, y, labelIdx, labelStyle);
7940
7947
  if (isEntry && !order.groupId && !bracketEntryIds.has(order.id)) {
7941
7948
  const tpPillY = y - PILL_H / 2;
7942
7949
  this._boxGfx.roundRect(PILL_TP_X, tpPillY, PILL_W, PILL_H, PILL_R).fill({ color: TP_PILL_COLOR, alpha: 0.85 });
@@ -8001,19 +8008,56 @@ var PixiTradingRenderer = class {
8001
8008
  }
8002
8009
  this._lineGfx.stroke();
8003
8010
  const boxY = y - LINE_H / 2;
8004
- this._boxGfx.rect(plotWidth, boxY, psWidth, LINE_H).fill({ color, alpha: 0.9 });
8005
- this._positionHitZones.push({ id: pos.id, x: plotWidth, y: boxY, w: psWidth, h: LINE_H });
8006
8011
  let text;
8007
8012
  if (pos.label) {
8008
8013
  text = pos.label;
8009
8014
  } else {
8010
- text = `Entry ${pos.entryPrice}`;
8015
+ text = `${pos.side.toUpperCase()} ${pos.qty}`;
8011
8016
  if (pos.unrealizedPnl !== void 0) {
8012
8017
  const pnlSign = pos.unrealizedPnl >= 0 ? "+" : "";
8013
8018
  text += ` ${pnlSign}${pos.unrealizedPnl.toFixed(2)}`;
8014
8019
  }
8015
8020
  }
8016
- labelIdx = this._drawLabel(text, plotWidth + 4, y, labelIdx, labelStyle);
8021
+ const textW = Math.ceil(CanvasTextMetrics.measureText(text, labelStyle).width);
8022
+ const pillW = textW + LABEL_PAD * 2;
8023
+ const pillX = Math.max(0, plotWidth - LABEL_GAP - pillW);
8024
+ this._boxGfx.roundRect(pillX, boxY, pillW, LINE_H, PILL_R).fill({ color, alpha: 0.9 });
8025
+ labelIdx = this._drawLabel(text, pillX + pillW / 2, y, labelIdx, labelStyle, true);
8026
+ this._boxGfx.rect(plotWidth, boxY, psWidth, LINE_H).fill({ color, alpha: 0.9 });
8027
+ labelIdx = this._drawLabel(String(pos.entryPrice), plotWidth + 4, y, labelIdx, labelStyle);
8028
+ this._positionHitZones.push({ id: pos.id, x: pillX, y: boxY, w: pillW, h: LINE_H });
8029
+ const linked = pos.linkedOrderIds ?? [];
8030
+ const hasTp = linked.some((id) => id.endsWith("-tp"));
8031
+ const hasSl = linked.some((id) => id.endsWith("-sl"));
8032
+ const entrySide = pos.side === "long" ? "buy" : "sell";
8033
+ if (!hasTp) {
8034
+ const tpY = y - PILL_H / 2;
8035
+ this._boxGfx.roundRect(PILL_TP_X, tpY, PILL_W, PILL_H, PILL_R).fill({ color: TP_PILL_COLOR, alpha: 0.85 });
8036
+ labelIdx = this._drawLabel("TP", PILL_TP_X + PILL_W / 2, y, labelIdx, pillLabelStyle, true);
8037
+ this._pillHitZones.push({
8038
+ kind: "tp",
8039
+ entryOrderId: pos.id,
8040
+ entrySide,
8041
+ x: PILL_TP_X,
8042
+ y: tpY,
8043
+ w: PILL_W,
8044
+ h: PILL_H
8045
+ });
8046
+ }
8047
+ if (!hasSl) {
8048
+ const slY = y - PILL_H / 2;
8049
+ this._boxGfx.roundRect(PILL_SL_X, slY, PILL_W, PILL_H, PILL_R).fill({ color: SL_PILL_COLOR, alpha: 0.85 });
8050
+ labelIdx = this._drawLabel("SL", PILL_SL_X + PILL_W / 2, y, labelIdx, pillLabelStyle, true);
8051
+ this._pillHitZones.push({
8052
+ kind: "sl",
8053
+ entryOrderId: pos.id,
8054
+ entrySide,
8055
+ x: PILL_SL_X,
8056
+ y: slY,
8057
+ w: PILL_W,
8058
+ h: PILL_H
8059
+ });
8060
+ }
8017
8061
  }
8018
8062
  }
8019
8063
  }
@@ -23171,7 +23215,11 @@ var ChartCanvas = forwardRef(
23171
23215
  type: "modify",
23172
23216
  orderId,
23173
23217
  symbol: symbolRef.current,
23174
- limitPrice: newPrice,
23218
+ // Route by role: a stop order's price is its TRIGGER, not a limit.
23219
+ // Sending limitPrice for a stop would modify the wrong field on the
23220
+ // broker (or be rejected), which matters now that stop orders are
23221
+ // draggable and not just bracket legs.
23222
+ ...order?.role === "stop" ? { stopPrice: newPrice } : { limitPrice: newPrice },
23175
23223
  timestamp: Date.now()
23176
23224
  });
23177
23225
  }