@orderly.network/hooks 3.0.0-beta.3 → 3.0.0-beta.4

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.d.mts CHANGED
@@ -170,7 +170,7 @@ declare global {
170
170
  };
171
171
  }
172
172
  }
173
- declare const _default: "3.0.0-beta.3";
173
+ declare const _default: "3.0.0-beta.4";
174
174
 
175
175
  declare const fetcher: (url: string, init: RequestInit | undefined, queryOptions: useQueryOptions<any>) => Promise<any>;
176
176
  type useQueryOptions<T> = SWRConfiguration & {
@@ -3139,6 +3139,12 @@ type TpslPriceParams = {
3139
3139
  slPrice?: string;
3140
3140
  liqPrice: number | null;
3141
3141
  side?: OrderSide;
3142
+ /**
3143
+ * Mark price for the symbol. When set with `side`, liq values that `useGetEstLiqPrice` would
3144
+ * hide (invalid vs mark — e.g. long est. liq above mark) are ignored here too so SL checks do
3145
+ * not run against a number the UI does not show as “Est. liq. price”.
3146
+ */
3147
+ markPrice?: number | null;
3142
3148
  /** Current position qty (signed: positive=Long, negative=Short). If missing, treated as is_reducing=true, skip liq check. */
3143
3149
  currentPosition?: number;
3144
3150
  /** Order quantity (non-negative, sign derived from side). If missing or 0, treated as is_reducing=true, skip liq check. */
package/dist/index.d.ts CHANGED
@@ -170,7 +170,7 @@ declare global {
170
170
  };
171
171
  }
172
172
  }
173
- declare const _default: "3.0.0-beta.3";
173
+ declare const _default: "3.0.0-beta.4";
174
174
 
175
175
  declare const fetcher: (url: string, init: RequestInit | undefined, queryOptions: useQueryOptions<any>) => Promise<any>;
176
176
  type useQueryOptions<T> = SWRConfiguration & {
@@ -3139,6 +3139,12 @@ type TpslPriceParams = {
3139
3139
  slPrice?: string;
3140
3140
  liqPrice: number | null;
3141
3141
  side?: OrderSide;
3142
+ /**
3143
+ * Mark price for the symbol. When set with `side`, liq values that `useGetEstLiqPrice` would
3144
+ * hide (invalid vs mark — e.g. long est. liq above mark) are ignored here too so SL checks do
3145
+ * not run against a number the UI does not show as “Est. liq. price”.
3146
+ */
3147
+ markPrice?: number | null;
3142
3148
  /** Current position qty (signed: positive=Long, negative=Short). If missing, treated as is_reducing=true, skip liq check. */
3143
3149
  currentPosition?: number;
3144
3150
  /** Order quantity (non-negative, sign derived from side). If missing or 0, treated as is_reducing=true, skip liq check. */
package/dist/index.js CHANGED
@@ -76,9 +76,9 @@ function useMarketCategoriesConfig() {
76
76
  // src/version.ts
77
77
  if (typeof window !== "undefined") {
78
78
  window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};
79
- window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "3.0.0-beta.3";
79
+ window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "3.0.0-beta.4";
80
80
  }
81
- var version_default = "3.0.0-beta.3";
81
+ var version_default = "3.0.0-beta.4";
82
82
  var fetcher = (url, init2 = {}, queryOptions) => net.get(url, init2, queryOptions?.formatter);
83
83
  var noCacheConfig = {
84
84
  dedupingInterval: 0,
@@ -607,6 +607,20 @@ var useAudioPlayer = (src, options = {}) => {
607
607
  const el = getOrderFilledAudio();
608
608
  el.volume = Math.max(0, Math.min(1, volume));
609
609
  }, [volume]);
610
+ React.useEffect(() => {
611
+ const handleVisibilityChange = () => {
612
+ if (document.visibilityState === "visible") {
613
+ const el = getOrderFilledAudio();
614
+ el.pause();
615
+ el.removeAttribute("src");
616
+ el.load();
617
+ }
618
+ };
619
+ document.addEventListener("visibilitychange", handleVisibilityChange);
620
+ return () => {
621
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
622
+ };
623
+ }, []);
610
624
  const play = React.useCallback(() => {
611
625
  const currentSrc = srcRef.current;
612
626
  const currentEnabled = enabledRef.current;
@@ -1316,7 +1330,7 @@ function checkTPSLOrderTypeIsMarket(key, values) {
1316
1330
  }
1317
1331
  function tpslCalculateHelper(key, inputs, options = {}) {
1318
1332
  const { symbol } = options;
1319
- if (key !== "quantity" && key !== "tp_trigger_price" && key !== "sl_trigger_price" && key !== "tp_pnl" && key !== "sl_pnl" && key !== "tp_offset" && key !== "sl_offset" && key !== "tp_offset_percentage" && key !== "sl_offset_percentage" && key !== "tp_order_price" && key !== "sl_order_price" && key !== "tp_order_type" && key !== "sl_order_type") {
1333
+ if (key !== "quantity" && key !== "tp_trigger_price" && key !== "sl_trigger_price" && key !== "tp_pnl" && key !== "sl_pnl" && key !== "tp_offset" && key !== "sl_offset" && key !== "tp_offset_percentage" && key !== "sl_offset_percentage" && key !== "tp_offset_from_mark" && key !== "sl_offset_from_mark" && key !== "tp_offset_percentage_from_mark" && key !== "sl_offset_percentage_from_mark" && key !== "tp_order_price" && key !== "sl_order_price" && key !== "tp_order_type" && key !== "sl_order_type") {
1320
1334
  return {
1321
1335
  [key]: inputs.value
1322
1336
  };
@@ -1324,6 +1338,7 @@ function tpslCalculateHelper(key, inputs, options = {}) {
1324
1338
  const orderType = key.startsWith("tp_") ? types.AlgoOrderType.TAKE_PROFIT : types.AlgoOrderType.STOP_LOSS;
1325
1339
  const keyPrefix = key.slice(0, 3);
1326
1340
  const qty = Number(key === "quantity" ? inputs.value : inputs.qty);
1341
+ const markPrice = inputs.markPrice ?? inputs.entryPrice;
1327
1342
  if (qty === 0 && (key === "tp_pnl" || key === "sl_pnl" || key === "tp_trigger_price" || key === "sl_trigger_price")) {
1328
1343
  return {
1329
1344
  // [`${keyPrefix}trigger_price`]: "",
@@ -1334,7 +1349,7 @@ function tpslCalculateHelper(key, inputs, options = {}) {
1334
1349
  [key]: inputs.value
1335
1350
  };
1336
1351
  }
1337
- let trigger_price, offset, offset_percentage, pnl, order_price, tpsl_order_type = inputs.values[`${keyPrefix}order_type`] ?? types.OrderType.MARKET;
1352
+ let trigger_price, offset, offset_percentage, offset_from_mark, offset_percentage_from_mark, pnl, order_price, tpsl_order_type = inputs.values[`${keyPrefix}order_type`] ?? types.OrderType.MARKET;
1338
1353
  const entryPrice = new utils.Decimal(inputs.entryPrice).todp(options.symbol?.quote_dp ?? 2, utils.Decimal.ROUND_UP).toNumber();
1339
1354
  switch (key) {
1340
1355
  case "tp_trigger_price":
@@ -1346,6 +1361,8 @@ function tpslCalculateHelper(key, inputs, options = {}) {
1346
1361
  [`${keyPrefix}trigger_price`]: trigger_price,
1347
1362
  [`${keyPrefix}offset`]: "",
1348
1363
  [`${keyPrefix}offset_percentage`]: "",
1364
+ [`${keyPrefix}offset_from_mark`]: "",
1365
+ [`${keyPrefix}offset_percentage_from_mark`]: "",
1349
1366
  [`${keyPrefix}pnl`]: "",
1350
1367
  [`${keyPrefix}ROI`]: ""
1351
1368
  };
@@ -1355,31 +1372,6 @@ function tpslCalculateHelper(key, inputs, options = {}) {
1355
1372
  }
1356
1373
  break;
1357
1374
  }
1358
- // case "tp_enable":
1359
- // case "sl_enable": {
1360
- // return {
1361
- // [`${keyPrefix}enable`]: inputs.value,
1362
- // [`${keyPrefix}order_type`]: OrderType.MARKET,
1363
- // [`${keyPrefix}trigger_price`]: "",
1364
- // [`${keyPrefix}order_price`]: "",
1365
- // [`${keyPrefix}offset`]: "",
1366
- // [`${keyPrefix}offset_percentage`]: "",
1367
- // [`${keyPrefix}pnl`]: "",
1368
- // [`${keyPrefix}ROI`]: "",
1369
- // };
1370
- // }
1371
- // case 'tp_pnl':{
1372
- // if (inputs.values.tp_order_type !== OrderType.MARKET) {
1373
- // pnl = inputs.value;
1374
- // trigger_price = pnlToPrice({
1375
- // qty,
1376
- // pnl: Number(inputs.value),
1377
- // entryPrice,
1378
- // orderSide: inputs.orderSide,
1379
- // orderType,
1380
- // })
1381
- // }
1382
- // }
1383
1375
  case "tp_pnl":
1384
1376
  case "sl_pnl": {
1385
1377
  pnl = inputs.value;
@@ -1426,6 +1418,30 @@ function tpslCalculateHelper(key, inputs, options = {}) {
1426
1418
  }
1427
1419
  break;
1428
1420
  }
1421
+ case "tp_offset_from_mark":
1422
+ case "sl_offset_from_mark": {
1423
+ offset_from_mark = inputs.value;
1424
+ if (!checkTPSLOrderTypeIsMarket(key, inputs.values)) {
1425
+ order_price = offsetToPrice({
1426
+ qty,
1427
+ offset: Number(inputs.value),
1428
+ entryPrice: markPrice,
1429
+ orderSide: inputs.orderSide,
1430
+ orderType: key === "tp_offset_from_mark" ? types.AlgoOrderType.TAKE_PROFIT : types.AlgoOrderType.STOP_LOSS
1431
+ });
1432
+ trigger_price = inputs.values[`${keyPrefix}trigger_price`] ?? order_price;
1433
+ } else {
1434
+ trigger_price = offsetToPrice({
1435
+ qty,
1436
+ offset: Number(inputs.value),
1437
+ // entryPrice,
1438
+ entryPrice: markPrice,
1439
+ orderSide: inputs.orderSide,
1440
+ orderType: key === "tp_offset_from_mark" ? types.AlgoOrderType.TAKE_PROFIT : types.AlgoOrderType.STOP_LOSS
1441
+ });
1442
+ }
1443
+ break;
1444
+ }
1429
1445
  case "tp_order_price":
1430
1446
  case "sl_order_price": {
1431
1447
  order_price = inputs.value;
@@ -1466,12 +1482,38 @@ function tpslCalculateHelper(key, inputs, options = {}) {
1466
1482
  }
1467
1483
  break;
1468
1484
  }
1485
+ case "tp_offset_percentage_from_mark":
1486
+ case "sl_offset_percentage_from_mark": {
1487
+ offset_percentage_from_mark = inputs.value;
1488
+ const markBase = Number(markPrice);
1489
+ if (!checkTPSLOrderTypeIsMarket(key, inputs.values)) {
1490
+ order_price = offsetPercentageToPrice({
1491
+ qty,
1492
+ percentage: Number(`${inputs.value}`.replace(/\.0{0,2}$/, "")),
1493
+ entryPrice: markBase,
1494
+ orderSide: inputs.orderSide,
1495
+ orderType
1496
+ });
1497
+ trigger_price = inputs.values[`${keyPrefix}trigger_price`] ?? order_price;
1498
+ } else {
1499
+ trigger_price = offsetPercentageToPrice({
1500
+ qty,
1501
+ percentage: Number(`${inputs.value}`.replace(/\.0{0,2}$/, "")),
1502
+ entryPrice: markBase,
1503
+ orderSide: inputs.orderSide,
1504
+ orderType
1505
+ });
1506
+ }
1507
+ break;
1508
+ }
1469
1509
  }
1470
1510
  if (!trigger_price && checkTPSLOrderTypeIsMarket(key, inputs.values)) {
1471
1511
  return {
1472
1512
  [`${keyPrefix}trigger_price`]: "",
1473
1513
  [`${keyPrefix}offset`]: "",
1474
1514
  [`${keyPrefix}offset_percentage`]: "",
1515
+ [`${keyPrefix}offset_from_mark`]: "",
1516
+ [`${keyPrefix}offset_percentage_from_mark`]: "",
1475
1517
  [`${keyPrefix}pnl`]: "",
1476
1518
  [`${keyPrefix}ROI`]: "",
1477
1519
  [key]: inputs.value
@@ -1516,6 +1558,8 @@ function tpslCalculateHelper(key, inputs, options = {}) {
1516
1558
  [`${keyPrefix}order_price`]: order_price ? utils.todpIfNeed(order_price, symbol?.quote_dp ?? 2) : "",
1517
1559
  [`${keyPrefix}offset`]: offset ?? "",
1518
1560
  [`${keyPrefix}offset_percentage`]: offset_percentage ?? "",
1561
+ [`${keyPrefix}offset_from_mark`]: offset_from_mark ?? inputs.values[`${keyPrefix}offset_from_mark`] ?? "",
1562
+ [`${keyPrefix}offset_percentage_from_mark`]: offset_percentage_from_mark ?? inputs.values[`${keyPrefix}offset_percentage_from_mark`] ?? "",
1519
1563
  [`${keyPrefix}pnl`]: pnl ?? ""
1520
1564
  // [`${keyPrefix}ROI`]: calcROI({
1521
1565
  // pnl: Number(pnl ?? 0),
@@ -1703,6 +1747,7 @@ function tpslInputHandle(inputs) {
1703
1747
  // order price or mark price
1704
1748
  qty: values.side === types.OrderSide.BUY ? Number(values.order_quantity) : Number(values.order_quantity) * -1,
1705
1749
  orderSide: values.side,
1750
+ markPrice,
1706
1751
  // values: newValues,
1707
1752
  values
1708
1753
  },
@@ -1738,6 +1783,10 @@ var getCalculateHandler = (fieldName) => {
1738
1783
  case "sl_offset":
1739
1784
  case "tp_offset_percentage":
1740
1785
  case "sl_offset_percentage":
1786
+ case "tp_offset_from_mark":
1787
+ case "sl_offset_from_mark":
1788
+ case "tp_offset_percentage_from_mark":
1789
+ case "sl_offset_percentage_from_mark":
1741
1790
  case "tp_order_price":
1742
1791
  case "tp_order_type":
1743
1792
  case "sl_order_type":
@@ -3162,7 +3211,9 @@ var DEFAULT_SYMBOL_DEPTHS = {
3162
3211
  };
3163
3212
  var DEFAULT_SYMBOL_DISPLAY_NAMES = {
3164
3213
  PERP_XAU_USDC: "XAU (Gold) ",
3165
- PERP_XAG_USDC: "XAG (Silver)"
3214
+ PERP_XAG_USDC: "XAG (Silver)",
3215
+ PERP_CL_USDC: "CL (WTI Crude Oil)",
3216
+ PERP_BZ_USDC: "BZ (Brent Crude Oil)"
3166
3217
  };
3167
3218
  var ProxyConfigStore = class {
3168
3219
  constructor(_originConfigStore) {
@@ -5150,6 +5201,11 @@ var MarkPriceCalculator = class extends BaseCalculator {
5150
5201
 
5151
5202
  // src/orderly/calculator/calculatorContext.ts
5152
5203
  var CalculatorContext = class _CalculatorContext {
5204
+ // holding: API.Holding[];
5205
+ // portfolio — dynamic getter to always read the latest output from PortfolioCalculator
5206
+ get portfolio() {
5207
+ return this.output["portfolio"] || useAppStore.getState().portfolio;
5208
+ }
5153
5209
  static get instance() {
5154
5210
  return this._instance;
5155
5211
  }
@@ -5168,7 +5224,6 @@ var CalculatorContext = class _CalculatorContext {
5168
5224
  update(scope, data) {
5169
5225
  this.setCtxData();
5170
5226
  this.markPrices = scope === "markPrice" /* MARK_PRICE */ ? data : this.output[MarketCalculatorName];
5171
- this.portfolio = this.output["portfolio"] || useAppStore.getState().portfolio;
5172
5227
  return this;
5173
5228
  }
5174
5229
  setCtxData() {
@@ -5186,7 +5241,6 @@ var CalculatorContext = class _CalculatorContext {
5186
5241
  clearCache() {
5187
5242
  this.output = {};
5188
5243
  this.accountInfo = void 0;
5189
- this.portfolio = void 0;
5190
5244
  }
5191
5245
  deleteByName(name) {
5192
5246
  delete this.output[name];
@@ -11052,7 +11106,11 @@ var tpslFields = [
11052
11106
  "tp_offset",
11053
11107
  "sl_offset",
11054
11108
  "tp_offset_percentage",
11055
- "sl_offset_percentage"
11109
+ "sl_offset_percentage",
11110
+ "tp_offset_from_mark",
11111
+ "sl_offset_from_mark",
11112
+ "tp_offset_percentage_from_mark",
11113
+ "sl_offset_percentage_from_mark"
11056
11114
  ];
11057
11115
  var isBracketOrder = (order) => {
11058
11116
  return !!order.tp_trigger_price || !!order.sl_trigger_price;
@@ -11268,6 +11326,8 @@ var useTaskProfitAndStopLossInternal = (position, options) => {
11268
11326
  entryPrice: position.average_open_price,
11269
11327
  qty: side === types.OrderSide.BUY ? Number(prev.quantity) : -Number(prev.quantity),
11270
11328
  orderSide: side,
11329
+ markPrice: markPrice ?? position.average_open_price,
11330
+ // use mark price as the default value
11271
11331
  values: prev
11272
11332
  },
11273
11333
  {
@@ -18648,10 +18708,14 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
18648
18708
  tp_pnl: "",
18649
18709
  tp_offset: "",
18650
18710
  tp_offset_percentage: "",
18711
+ tp_offset_from_mark: "",
18712
+ tp_offset_percentage_from_mark: "",
18651
18713
  sl_trigger_price: "",
18652
18714
  sl_pnl: "",
18653
18715
  sl_offset: "",
18654
- sl_offset_percentage: ""
18716
+ sl_offset_percentage: "",
18717
+ sl_offset_from_mark: "",
18718
+ sl_offset_percentage_from_mark: ""
18655
18719
  }));
18656
18720
  },
18657
18721
  hasTP_SL: () => {
@@ -18742,6 +18806,42 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
18742
18806
  symbolInfo2
18743
18807
  );
18744
18808
  }
18809
+ if (newValues.tp_offset_from_mark !== void 0 && newValues.tp_offset_from_mark !== "") {
18810
+ newValues = calculate2(
18811
+ newValues,
18812
+ "tp_offset_from_mark",
18813
+ newValues.tp_offset_from_mark,
18814
+ markPrice,
18815
+ symbolInfo2
18816
+ );
18817
+ }
18818
+ if (newValues.tp_offset_percentage_from_mark !== void 0 && newValues.tp_offset_percentage_from_mark !== "") {
18819
+ newValues = calculate2(
18820
+ newValues,
18821
+ "tp_offset_percentage_from_mark",
18822
+ newValues.tp_offset_percentage_from_mark,
18823
+ markPrice,
18824
+ symbolInfo2
18825
+ );
18826
+ }
18827
+ if (newValues.sl_offset_from_mark !== void 0 && newValues.sl_offset_from_mark !== "") {
18828
+ newValues = calculate2(
18829
+ newValues,
18830
+ "sl_offset_from_mark",
18831
+ newValues.sl_offset_from_mark,
18832
+ markPrice,
18833
+ symbolInfo2
18834
+ );
18835
+ }
18836
+ if (newValues.sl_offset_percentage_from_mark !== void 0 && newValues.sl_offset_percentage_from_mark !== "") {
18837
+ newValues = calculate2(
18838
+ newValues,
18839
+ "sl_offset_percentage_from_mark",
18840
+ newValues.sl_offset_percentage_from_mark,
18841
+ markPrice,
18842
+ symbolInfo2
18843
+ );
18844
+ }
18745
18845
  } else {
18746
18846
  if (typeof newValues.tp_trigger_price !== "undefined") {
18747
18847
  newValues = calculate2(
@@ -18761,6 +18861,42 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
18761
18861
  symbolInfo2
18762
18862
  );
18763
18863
  }
18864
+ if (newValues.tp_offset_from_mark !== void 0 && newValues.tp_offset_from_mark !== "") {
18865
+ newValues = calculate2(
18866
+ newValues,
18867
+ "tp_offset_from_mark",
18868
+ newValues.tp_offset_from_mark,
18869
+ markPrice,
18870
+ symbolInfo2
18871
+ );
18872
+ }
18873
+ if (newValues.tp_offset_percentage_from_mark !== void 0 && newValues.tp_offset_percentage_from_mark !== "") {
18874
+ newValues = calculate2(
18875
+ newValues,
18876
+ "tp_offset_percentage_from_mark",
18877
+ newValues.tp_offset_percentage_from_mark,
18878
+ markPrice,
18879
+ symbolInfo2
18880
+ );
18881
+ }
18882
+ if (newValues.sl_offset_from_mark !== void 0 && newValues.sl_offset_from_mark !== "") {
18883
+ newValues = calculate2(
18884
+ newValues,
18885
+ "sl_offset_from_mark",
18886
+ newValues.sl_offset_from_mark,
18887
+ markPrice,
18888
+ symbolInfo2
18889
+ );
18890
+ }
18891
+ if (newValues.sl_offset_percentage_from_mark !== void 0 && newValues.sl_offset_percentage_from_mark !== "") {
18892
+ newValues = calculate2(
18893
+ newValues,
18894
+ "sl_offset_percentage_from_mark",
18895
+ newValues.sl_offset_percentage_from_mark,
18896
+ markPrice,
18897
+ symbolInfo2
18898
+ );
18899
+ }
18764
18900
  }
18765
18901
  return newValues;
18766
18902
  };
@@ -19740,6 +19876,7 @@ var useTpslPriceChecker = (params) => {
19740
19876
  slPrice,
19741
19877
  liqPrice,
19742
19878
  side,
19879
+ markPrice,
19743
19880
  currentPosition,
19744
19881
  orderQuantity
19745
19882
  } = params;
@@ -19795,6 +19932,17 @@ var useTpslPriceChecker = (params) => {
19795
19932
  if (slPrice === void 0 || liqPrice === void 0 || side === void 0 || liqPrice === null) {
19796
19933
  return null;
19797
19934
  }
19935
+ if (markPrice != null && Number.isFinite(markPrice) && markPrice > 0) {
19936
+ if (side === types.OrderSide.BUY && liqPrice > markPrice) {
19937
+ return null;
19938
+ }
19939
+ if (side === types.OrderSide.SELL && liqPrice < markPrice) {
19940
+ return null;
19941
+ }
19942
+ }
19943
+ if (typeof liqPrice === "number" && (!Number.isFinite(liqPrice) || liqPrice <= 0)) {
19944
+ return null;
19945
+ }
19798
19946
  let slPriceDecimal;
19799
19947
  let liqPriceDecimal;
19800
19948
  try {
@@ -19821,6 +19969,7 @@ var useTpslPriceChecker = (params) => {
19821
19969
  slPrice,
19822
19970
  liqPrice,
19823
19971
  side,
19972
+ markPrice,
19824
19973
  warning_threshold,
19825
19974
  currentPosition,
19826
19975
  orderQuantity