ccxt 4.5.15 → 4.5.17

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/cjs/ccxt.js CHANGED
@@ -189,7 +189,7 @@ var xt$1 = require('./src/pro/xt.js');
189
189
  // ----------------------------------------------------------------------------
190
190
  //-----------------------------------------------------------------------------
191
191
  // this is updated by vss.js when building
192
- const version = '4.5.15';
192
+ const version = '4.5.17';
193
193
  Exchange["default"].ccxtVersion = version;
194
194
  const exchanges = {
195
195
  'alpaca': alpaca["default"],
@@ -30,23 +30,40 @@ class arkham extends arkham$1["default"] {
30
30
  'swap': true,
31
31
  'future': false,
32
32
  'option': false,
33
+ 'borrowCrossMargin': false,
34
+ 'borrowIsolatedMargin': false,
35
+ 'borrowMargin': false,
33
36
  'cancelAllOrders': true,
34
37
  'cancelOrder': true,
35
38
  'createDepositAddress': true,
36
39
  'createOrder': true,
37
40
  'fetchAccounts': true,
41
+ 'fetchAllGreeks': false,
38
42
  'fetchBalance': true,
43
+ 'fetchBorrowInterest': false,
44
+ 'fetchBorrowRate': false,
45
+ 'fetchBorrowRateHistories': false,
46
+ 'fetchBorrowRateHistory': false,
47
+ 'fetchBorrowRates': false,
48
+ 'fetchBorrowRatesPerSymbol': false,
39
49
  'fetchClosedOrders': true,
50
+ 'fetchCrossBorrowRate': false,
51
+ 'fetchCrossBorrowRates': false,
40
52
  'fetchCurrencies': true,
41
53
  'fetchDepositAddress': false,
42
54
  'fetchDepositAddressesByNetwork': true,
43
55
  'fetchDeposits': true,
44
56
  'fetchFundingHistory': true,
57
+ 'fetchGreeks': false,
58
+ 'fetchIsolatedBorrowRate': false,
59
+ 'fetchIsolatedBorrowRates': false,
45
60
  'fetchLeverage': true,
46
61
  'fetchLeverageTiers': true,
47
62
  'fetchMyTrades': true,
48
63
  'fetchOHLCV': true,
49
64
  'fetchOpenOrders': true,
65
+ 'fetchOption': false,
66
+ 'fetchOptionChain': false,
50
67
  'fetchOrder': true,
51
68
  'fetchOrderBook': true,
52
69
  'fetchPositions': true,
@@ -55,7 +72,10 @@ class arkham extends arkham$1["default"] {
55
72
  'fetchTime': true,
56
73
  'fetchTrades': true,
57
74
  'fetchTradingFees': true,
75
+ 'fetchVolatilityHistory': false,
58
76
  'fetchWithdrawals': true,
77
+ 'repayCrossMargin': false,
78
+ 'repayIsolatedMargin': false,
59
79
  'sandbox': false,
60
80
  'setLeverage': true,
61
81
  'withdraw': true,
@@ -1455,8 +1455,10 @@ class Exchange {
1455
1455
  'cancelAllOrders': undefined,
1456
1456
  'cancelAllOrdersWs': undefined,
1457
1457
  'cancelOrder': true,
1458
+ 'cancelOrderWithClientOrderId': undefined,
1458
1459
  'cancelOrderWs': undefined,
1459
1460
  'cancelOrders': undefined,
1461
+ 'cancelOrdersWithClientOrderId': undefined,
1460
1462
  'cancelOrdersWs': undefined,
1461
1463
  'closeAllPositions': undefined,
1462
1464
  'closePosition': undefined,
@@ -1506,6 +1508,7 @@ class Exchange {
1506
1508
  'createTriggerOrderWs': undefined,
1507
1509
  'deposit': undefined,
1508
1510
  'editOrder': 'emulated',
1511
+ 'editOrderWithClientOrderId': undefined,
1509
1512
  'editOrders': undefined,
1510
1513
  'editOrderWs': undefined,
1511
1514
  'fetchAccounts': undefined,
@@ -1584,6 +1587,7 @@ class Exchange {
1584
1587
  'fetchOption': undefined,
1585
1588
  'fetchOptionChain': undefined,
1586
1589
  'fetchOrder': undefined,
1590
+ 'fetchOrderWithClientOrderId': undefined,
1587
1591
  'fetchOrderBook': true,
1588
1592
  'fetchOrderBooks': undefined,
1589
1593
  'fetchOrderBookWs': undefined,
@@ -4767,6 +4771,9 @@ class Exchange {
4767
4771
  await this.cancelOrder(id, symbol);
4768
4772
  return await this.createOrder(symbol, type, side, amount, price, params);
4769
4773
  }
4774
+ async editOrderWithClientOrderId(clientOrderId, symbol, type, side, amount = undefined, price = undefined, params = {}) {
4775
+ return await this.editOrder('', symbol, type, side, amount, price, this.extend({ 'clientOrderId': clientOrderId }, params));
4776
+ }
4770
4777
  async editOrderWs(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
4771
4778
  await this.cancelOrderWs(id, symbol);
4772
4779
  return await this.createOrderWs(symbol, type, side, amount, price, params);
@@ -5257,6 +5264,19 @@ class Exchange {
5257
5264
  async fetchOrder(id, symbol = undefined, params = {}) {
5258
5265
  throw new errors.NotSupported(this.id + ' fetchOrder() is not supported yet');
5259
5266
  }
5267
+ /**
5268
+ * @method
5269
+ * @name fetchOrderWithClientOrderId
5270
+ * @description create a market order by providing the symbol, side and cost
5271
+ * @param {string} clientOrderId client order Id
5272
+ * @param {string} symbol unified symbol of the market to create an order in
5273
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
5274
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
5275
+ */
5276
+ async fetchOrderWithClientOrderId(clientOrderId, symbol = undefined, params = {}) {
5277
+ const extendedParams = this.extend(params, { 'clientOrderId': clientOrderId });
5278
+ return await this.fetchOrder('', symbol, extendedParams);
5279
+ }
5260
5280
  async fetchOrderWs(id, symbol = undefined, params = {}) {
5261
5281
  throw new errors.NotSupported(this.id + ' fetchOrderWs() is not supported yet');
5262
5282
  }
@@ -5711,12 +5731,38 @@ class Exchange {
5711
5731
  async cancelOrder(id, symbol = undefined, params = {}) {
5712
5732
  throw new errors.NotSupported(this.id + ' cancelOrder() is not supported yet');
5713
5733
  }
5734
+ /**
5735
+ * @method
5736
+ * @name cancelOrderWithClientOrderId
5737
+ * @description create a market order by providing the symbol, side and cost
5738
+ * @param {string} clientOrderId client order Id
5739
+ * @param {string} symbol unified symbol of the market to create an order in
5740
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
5741
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
5742
+ */
5743
+ async cancelOrderWithClientOrderId(clientOrderId, symbol = undefined, params = {}) {
5744
+ const extendedParams = this.extend(params, { 'clientOrderId': clientOrderId });
5745
+ return await this.cancelOrder('', symbol, extendedParams);
5746
+ }
5714
5747
  async cancelOrderWs(id, symbol = undefined, params = {}) {
5715
5748
  throw new errors.NotSupported(this.id + ' cancelOrderWs() is not supported yet');
5716
5749
  }
5717
5750
  async cancelOrders(ids, symbol = undefined, params = {}) {
5718
5751
  throw new errors.NotSupported(this.id + ' cancelOrders() is not supported yet');
5719
5752
  }
5753
+ /**
5754
+ * @method
5755
+ * @name cancelOrdersWithClientOrderIds
5756
+ * @description create a market order by providing the symbol, side and cost
5757
+ * @param {string[]} clientOrderIds client order Ids
5758
+ * @param {string} symbol unified symbol of the market to create an order in
5759
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
5760
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
5761
+ */
5762
+ async cancelOrdersWithClientOrderIds(clientOrderIds, symbol = undefined, params = {}) {
5763
+ const extendedParams = this.extend(params, { 'clientOrderIds': clientOrderIds });
5764
+ return await this.cancelOrders([], symbol, extendedParams);
5765
+ }
5720
5766
  async cancelOrdersWs(ids, symbol = undefined, params = {}) {
5721
5767
  throw new errors.NotSupported(this.id + ' cancelOrdersWs() is not supported yet');
5722
5768
  }
@@ -1388,18 +1388,20 @@ class blofin extends blofin$1["default"] {
1388
1388
  [method, params] = this.handleOptionAndParams(params, 'createOrder', 'method', 'privatePostTradeOrder');
1389
1389
  const isStopLossPriceDefined = this.safeString(params, 'stopLossPrice') !== undefined;
1390
1390
  const isTakeProfitPriceDefined = this.safeString(params, 'takeProfitPrice') !== undefined;
1391
- const isTriggerOrder = this.safeString(params, 'triggerPrice') !== undefined;
1391
+ const hasTriggerPrice = this.safeString(params, 'triggerPrice') !== undefined;
1392
1392
  const isType2Order = (isStopLossPriceDefined || isTakeProfitPriceDefined);
1393
1393
  let response = undefined;
1394
1394
  const reduceOnly = this.safeBool(params, 'reduceOnly');
1395
1395
  if (reduceOnly !== undefined) {
1396
1396
  params['reduceOnly'] = reduceOnly ? 'true' : 'false';
1397
1397
  }
1398
- if (tpsl || (method === 'privatePostTradeOrderTpsl') || isType2Order) {
1398
+ const isTpslOrder = tpsl || (method === 'privatePostTradeOrderTpsl') || isType2Order;
1399
+ const isTriggerOrder = hasTriggerPrice || (method === 'privatePostTradeOrderAlgo');
1400
+ if (isTpslOrder) {
1399
1401
  const tpslRequest = this.createTpslOrderRequest(symbol, type, side, amount, price, params);
1400
1402
  response = await this.privatePostTradeOrderTpsl(tpslRequest);
1401
1403
  }
1402
- else if (isTriggerOrder || (method === 'privatePostTradeOrderAlgo')) {
1404
+ else if (isTriggerOrder) {
1403
1405
  const triggerRequest = this.createOrderRequest(symbol, type, side, amount, price, params);
1404
1406
  response = await this.privatePostTradeOrderAlgo(triggerRequest);
1405
1407
  }
@@ -1407,10 +1409,9 @@ class blofin extends blofin$1["default"] {
1407
1409
  const request = this.createOrderRequest(symbol, type, side, amount, price, params);
1408
1410
  response = await this.privatePostTradeOrder(request);
1409
1411
  }
1410
- if (isTriggerOrder || (method === 'privatePostTradeOrderAlgo')) {
1412
+ if (isTpslOrder || isTriggerOrder) {
1411
1413
  const dataDict = this.safeDict(response, 'data', {});
1412
- const triggerOrder = this.parseOrder(dataDict, market);
1413
- return triggerOrder;
1414
+ return this.parseOrder(dataDict, market);
1414
1415
  }
1415
1416
  const data = this.safeList(response, 'data', []);
1416
1417
  const first = this.safeDict(data, 0);
@@ -514,6 +514,7 @@ class bybit extends bybit$1["default"] {
514
514
  'v5/account/mmp-reset': 5,
515
515
  'v5/account/borrow': 5,
516
516
  'v5/account/repay': 5,
517
+ 'v5/account/no-convert-repay': 5,
517
518
  // asset
518
519
  'v5/asset/exchange/quote-apply': 1,
519
520
  'v5/asset/exchange/convert-execute': 1,
@@ -3948,7 +3949,7 @@ class bybit extends bybit$1["default"] {
3948
3949
  * @param {string} [params.positionIdx] *contracts only* 0 for one-way mode, 1 buy side of hedged mode, 2 sell side of hedged mode
3949
3950
  * @param {bool} [params.hedged] *contracts only* true for hedged mode, false for one way mode, default is false
3950
3951
  * @param {int} [params.isLeverage] *unified spot only* false then spot trading true then margin trading
3951
- * @param {string} [params.tpslMode] *contract only* 'full' or 'partial'
3952
+ * @param {string} [params.tpslMode] *contract only* 'Full' or 'Partial'
3952
3953
  * @param {string} [params.mmp] *option only* market maker protection
3953
3954
  * @param {string} [params.triggerDirection] *contract only* the direction for trigger orders, 'ascending' or 'descending'
3954
3955
  * @param {float} [params.triggerPrice] The price at which a trigger order is triggered at
@@ -4072,22 +4073,31 @@ class bybit extends bybit$1["default"] {
4072
4073
  throw new errors.InvalidOrder(this.id + ' the API endpoint used only supports contract trailingAmount, stopLossPrice and takeProfitPrice orders');
4073
4074
  }
4074
4075
  if (isStopLossTriggerOrder || isTakeProfitTriggerOrder) {
4076
+ const tpslMode = this.safeString(params, 'tpslMode', 'Partial');
4077
+ const isFullTpsl = tpslMode === 'Full';
4078
+ const isPartialTpsl = tpslMode === 'Partial';
4079
+ if (isLimit && isFullTpsl) {
4080
+ throw new errors.InvalidOrder(this.id + ' tpsl orders with "full" tpslMode only support "market" type');
4081
+ }
4082
+ request['tpslMode'] = tpslMode;
4075
4083
  if (isStopLossTriggerOrder) {
4076
4084
  request['stopLoss'] = this.getPrice(symbol, stopLossTriggerPrice);
4085
+ if (isPartialTpsl) {
4086
+ request['slSize'] = amountString;
4087
+ }
4077
4088
  if (isLimit) {
4078
- request['tpslMode'] = 'Partial';
4079
4089
  request['slOrderType'] = 'Limit';
4080
4090
  request['slLimitPrice'] = priceString;
4081
- request['slSize'] = amountString;
4082
4091
  }
4083
4092
  }
4084
4093
  else if (isTakeProfitTriggerOrder) {
4085
4094
  request['takeProfit'] = this.getPrice(symbol, takeProfitTriggerPrice);
4095
+ if (isPartialTpsl) {
4096
+ request['tpSize'] = amountString;
4097
+ }
4086
4098
  if (isLimit) {
4087
- request['tpslMode'] = 'Partial';
4088
4099
  request['tpOrderType'] = 'Limit';
4089
4100
  request['tpLimitPrice'] = priceString;
4090
- request['tpSize'] = amountString;
4091
4101
  }
4092
4102
  }
4093
4103
  }
@@ -4273,7 +4283,7 @@ class bybit extends bybit$1["default"] {
4273
4283
  }
4274
4284
  request['positionIdx'] = (side === 'buy') ? 1 : 2;
4275
4285
  }
4276
- params = this.omit(params, ['stopPrice', 'timeInForce', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'clientOrderId', 'triggerPrice', 'stopLoss', 'takeProfit', 'trailingAmount', 'trailingTriggerPrice', 'hedged']);
4286
+ params = this.omit(params, ['stopPrice', 'timeInForce', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'clientOrderId', 'triggerPrice', 'stopLoss', 'takeProfit', 'trailingAmount', 'trailingTriggerPrice', 'hedged', 'tpslMode']);
4277
4287
  return this.extend(request, params);
4278
4288
  }
4279
4289
  /**
@@ -67,6 +67,7 @@ class delta extends delta$1["default"] {
67
67
  'fetchOpenOrders': true,
68
68
  'fetchOption': true,
69
69
  'fetchOptionChain': false,
70
+ 'fetchOrder': true,
70
71
  'fetchOrderBook': true,
71
72
  'fetchPosition': true,
72
73
  'fetchPositionMode': false,
@@ -145,6 +146,8 @@ class delta extends delta$1["default"] {
145
146
  'private': {
146
147
  'get': [
147
148
  'orders',
149
+ 'orders/{order_id}',
150
+ 'orders/client_order_id/{client_oid}',
148
151
  'products/{product_id}/orders/leverage',
149
152
  'positions/margined',
150
153
  'positions',
@@ -158,8 +161,8 @@ class delta extends delta$1["default"] {
158
161
  'users/trading_preferences',
159
162
  'sub_accounts',
160
163
  'profile',
164
+ 'heartbeat',
161
165
  'deposits/address',
162
- 'orders/leverage',
163
166
  ],
164
167
  'post': [
165
168
  'orders',
@@ -169,6 +172,8 @@ class delta extends delta$1["default"] {
169
172
  'positions/change_margin',
170
173
  'positions/close_all',
171
174
  'wallets/sub_account_balance_transfer',
175
+ 'heartbeat/create',
176
+ 'heartbeat',
172
177
  'orders/cancel_after',
173
178
  'orders/leverage',
174
179
  ],
@@ -1885,9 +1890,40 @@ class delta extends delta$1["default"] {
1885
1890
  // "user_id":22142
1886
1891
  // }
1887
1892
  //
1893
+ // fetchOrder
1894
+ //
1895
+ // {
1896
+ // "id": 123,
1897
+ // "user_id": 453671,
1898
+ // "size": 10,
1899
+ // "unfilled_size": 2,
1900
+ // "side": "buy",
1901
+ // "order_type": "limit_order",
1902
+ // "limit_price": "59000",
1903
+ // "stop_order_type": "stop_loss_order",
1904
+ // "stop_price": "55000",
1905
+ // "paid_commission": "0.5432",
1906
+ // "commission": "0.5432",
1907
+ // "reduce_only": false,
1908
+ // "client_order_id": "my_signal_34521712",
1909
+ // "state": "open",
1910
+ // "created_at": "1725865012000000",
1911
+ // "product_id": 27,
1912
+ // "product_symbol": "BTCUSD"
1913
+ // }
1914
+ //
1888
1915
  const id = this.safeString(order, 'id');
1889
1916
  const clientOrderId = this.safeString(order, 'client_order_id');
1890
- const timestamp = this.parse8601(this.safeString(order, 'created_at'));
1917
+ const createdAt = this.safeString(order, 'created_at');
1918
+ let timestamp = undefined;
1919
+ if (createdAt !== undefined) {
1920
+ if (createdAt.indexOf('-') >= 0) {
1921
+ timestamp = this.parse8601(createdAt);
1922
+ }
1923
+ else {
1924
+ timestamp = this.safeIntegerProduct(order, 'created_at', 0.001);
1925
+ }
1926
+ }
1891
1927
  const marketId = this.safeString(order, 'product_id');
1892
1928
  const marketsByNumericId = this.safeDict(this.options, 'marketsByNumericId', {});
1893
1929
  market = this.safeValue(marketsByNumericId, marketId, market);
@@ -1895,7 +1931,9 @@ class delta extends delta$1["default"] {
1895
1931
  const status = this.parseOrderStatus(this.safeString(order, 'state'));
1896
1932
  const side = this.safeString(order, 'side');
1897
1933
  let type = this.safeString(order, 'order_type');
1898
- type = type.replace('_order', '');
1934
+ if (type !== undefined) {
1935
+ type = type.replace('_order', '');
1936
+ }
1899
1937
  const price = this.safeString(order, 'limit_price');
1900
1938
  const amount = this.safeString(order, 'size');
1901
1939
  const remaining = this.safeString(order, 'unfilled_size');
@@ -2160,6 +2198,63 @@ class delta extends delta$1["default"] {
2160
2198
  }),
2161
2199
  ];
2162
2200
  }
2201
+ /**
2202
+ * @method
2203
+ * @name delta#fetchOrder
2204
+ * @description fetches information on an order made by the user
2205
+ * @see https://docs.delta.exchange/#get-order-by-id
2206
+ * @see https://docs.delta.exchange/#get-order-by-client-oid
2207
+ * @param {string} id the order id
2208
+ * @param {string} [symbol] unified symbol of the market the order was made in
2209
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2210
+ * @param {string} [params.clientOrderId] client order id of the order
2211
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2212
+ */
2213
+ async fetchOrder(id, symbol = undefined, params = {}) {
2214
+ await this.loadMarkets();
2215
+ let market = undefined;
2216
+ if (symbol !== undefined) {
2217
+ market = this.market(symbol);
2218
+ }
2219
+ const clientOrderId = this.safeStringN(params, ['clientOrderId', 'client_oid', 'clientOid']);
2220
+ params = this.omit(params, ['clientOrderId', 'client_oid', 'clientOid']);
2221
+ const request = {};
2222
+ let response = undefined;
2223
+ if (clientOrderId !== undefined) {
2224
+ request['client_oid'] = clientOrderId;
2225
+ response = await this.privateGetOrdersClientOrderIdClientOid(this.extend(request, params));
2226
+ }
2227
+ else {
2228
+ request['order_id'] = id;
2229
+ response = await this.privateGetOrdersOrderId(this.extend(request, params));
2230
+ }
2231
+ //
2232
+ // {
2233
+ // "success": true,
2234
+ // "result": {
2235
+ // "id": 123,
2236
+ // "user_id": 453671,
2237
+ // "size": 10,
2238
+ // "unfilled_size": 2,
2239
+ // "side": "buy",
2240
+ // "order_type": "limit_order",
2241
+ // "limit_price": "59000",
2242
+ // "stop_order_type": "stop_loss_order",
2243
+ // "stop_price": "55000",
2244
+ // "paid_commission": "0.5432",
2245
+ // "commission": "0.5432",
2246
+ // "reduce_only": false,
2247
+ // "client_order_id": "my_signal_34521712",
2248
+ // "state": "open",
2249
+ // "created_at": "1725865012000000",
2250
+ // "product_id": 27,
2251
+ // "product_symbol": "BTCUSD"
2252
+ // }
2253
+ // }
2254
+ //
2255
+ const result = this.safeDict(response, 'result', {});
2256
+ return this.parseOrder(result, market);
2257
+ }
2163
2258
  /**
2164
2259
  * @method
2165
2260
  * @name delta#fetchOpenOrders
@@ -410,7 +410,7 @@ class hyperliquid extends hyperliquid$1["default"] {
410
410
  */
411
411
  async fetchCurrencies(params = {}) {
412
412
  if (this.checkRequiredCredentials(false)) {
413
- await this.handleBuilderFeeApproval();
413
+ await this.initializeClient();
414
414
  }
415
415
  const request = {
416
416
  'type': 'meta',
@@ -1472,6 +1472,32 @@ class hyperliquid extends hyperliquid$1["default"] {
1472
1472
  };
1473
1473
  return this.signUserSignedAction(messageTypes, message);
1474
1474
  }
1475
+ async setRef() {
1476
+ if (this.safeBool(this.options, 'refSet', false)) {
1477
+ return true;
1478
+ }
1479
+ this.options['refSet'] = true;
1480
+ const action = {
1481
+ 'type': 'setReferrer',
1482
+ 'code': this.safeString(this.options, 'ref', 'CCXT1'),
1483
+ };
1484
+ const nonce = this.milliseconds();
1485
+ const signature = this.signL1Action(action, nonce);
1486
+ const request = {
1487
+ 'action': action,
1488
+ 'nonce': nonce,
1489
+ 'signature': signature,
1490
+ };
1491
+ let response = undefined;
1492
+ try {
1493
+ response = await this.privatePostExchange(request);
1494
+ return response;
1495
+ }
1496
+ catch (e) {
1497
+ response = undefined; // ignore this
1498
+ }
1499
+ return response;
1500
+ }
1475
1501
  async approveBuilderFee(builder, maxFeeRate) {
1476
1502
  const nonce = this.milliseconds();
1477
1503
  const isSandboxMode = this.safeBool(this.options, 'sandboxMode', false);
@@ -1506,6 +1532,15 @@ class hyperliquid extends hyperliquid$1["default"] {
1506
1532
  //
1507
1533
  return await this.privatePostExchange(request);
1508
1534
  }
1535
+ async initializeClient() {
1536
+ try {
1537
+ await Promise.all([this.handleBuilderFeeApproval(), this.setRef()]);
1538
+ }
1539
+ catch (e) {
1540
+ return false;
1541
+ }
1542
+ return true;
1543
+ }
1509
1544
  async handleBuilderFeeApproval() {
1510
1545
  const buildFee = this.safeBool(this.options, 'builderFee', true);
1511
1546
  if (!buildFee) {
@@ -1564,7 +1599,7 @@ class hyperliquid extends hyperliquid$1["default"] {
1564
1599
  */
1565
1600
  async createOrders(orders, params = {}) {
1566
1601
  await this.loadMarkets();
1567
- await this.handleBuilderFeeApproval();
1602
+ await this.initializeClient();
1568
1603
  const request = this.createOrdersRequest(orders, params);
1569
1604
  const response = await this.privatePostExchange(request);
1570
1605
  //
@@ -1816,6 +1851,7 @@ class hyperliquid extends hyperliquid$1["default"] {
1816
1851
  throw new errors.ArgumentsRequired(this.id + ' cancelOrders() requires a symbol argument');
1817
1852
  }
1818
1853
  await this.loadMarkets();
1854
+ await this.initializeClient();
1819
1855
  const request = this.cancelOrdersRequest(ids, symbol, params);
1820
1856
  const response = await this.privatePostExchange(request);
1821
1857
  //
@@ -1919,6 +1955,7 @@ class hyperliquid extends hyperliquid$1["default"] {
1919
1955
  async cancelOrdersForSymbols(orders, params = {}) {
1920
1956
  this.checkRequiredCredentials();
1921
1957
  await this.loadMarkets();
1958
+ await this.initializeClient();
1922
1959
  const nonce = this.milliseconds();
1923
1960
  const request = {
1924
1961
  'nonce': nonce,
@@ -1993,6 +2030,7 @@ class hyperliquid extends hyperliquid$1["default"] {
1993
2030
  async cancelAllOrdersAfter(timeout, params = {}) {
1994
2031
  this.checkRequiredCredentials();
1995
2032
  await this.loadMarkets();
2033
+ await this.initializeClient();
1996
2034
  params = this.omit(params, ['clientOrderId', 'client_id']);
1997
2035
  const nonce = this.milliseconds();
1998
2036
  const request = {
@@ -2186,6 +2224,7 @@ class hyperliquid extends hyperliquid$1["default"] {
2186
2224
  */
2187
2225
  async editOrders(orders, params = {}) {
2188
2226
  await this.loadMarkets();
2227
+ await this.initializeClient();
2189
2228
  const request = this.editOrdersRequest(orders, params);
2190
2229
  const response = await this.privatePostExchange(request);
2191
2230
  //
@@ -46,6 +46,7 @@ class kraken extends kraken$1["default"] {
46
46
  'createMarketOrderWithCost': false,
47
47
  'createMarketSellOrderWithCost': false,
48
48
  'createOrder': true,
49
+ 'createOrders': true,
49
50
  'createStopLimitOrder': true,
50
51
  'createStopMarketOrder': true,
51
52
  'createStopOrder': true,
@@ -473,7 +474,11 @@ class kraken extends kraken$1["default"] {
473
474
  'selfTradePrevention': true,
474
475
  'iceberg': true, // todo implement
475
476
  },
476
- 'createOrders': undefined,
477
+ 'createOrders': {
478
+ 'min': 2,
479
+ 'max': 15,
480
+ 'sameSymbolOnly': true,
481
+ },
477
482
  'fetchMyTrades': {
478
483
  'marginMode': false,
479
484
  'limit': undefined,
@@ -1678,6 +1683,79 @@ class kraken extends kraken$1["default"] {
1678
1683
  // this usingCost flag is used to help the parsing but omited from the order
1679
1684
  return this.parseOrder(result);
1680
1685
  }
1686
+ /**
1687
+ * @method
1688
+ * @name kraken#createOrders
1689
+ * @description create a list of trade orders
1690
+ * @see https://docs.kraken.com/api/docs/rest-api/add-order-batch/
1691
+ * @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
1692
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1693
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1694
+ */
1695
+ async createOrders(orders, params = {}) {
1696
+ await this.loadMarkets();
1697
+ const ordersRequests = [];
1698
+ let orderSymbols = [];
1699
+ let symbol = undefined;
1700
+ let market = undefined;
1701
+ for (let i = 0; i < orders.length; i++) {
1702
+ const rawOrder = orders[i];
1703
+ const marketId = this.safeString(rawOrder, 'symbol');
1704
+ if (symbol === undefined) {
1705
+ symbol = marketId;
1706
+ }
1707
+ else {
1708
+ if (symbol !== marketId) {
1709
+ throw new errors.BadRequest(this.id + ' createOrders() requires all orders to have the same symbol');
1710
+ }
1711
+ }
1712
+ market = this.market(marketId);
1713
+ orderSymbols.push(marketId);
1714
+ const type = this.safeString(rawOrder, 'type');
1715
+ const side = this.safeString(rawOrder, 'side');
1716
+ const amount = this.safeValue(rawOrder, 'amount');
1717
+ const price = this.safeValue(rawOrder, 'price');
1718
+ const orderParams = this.safeDict(rawOrder, 'params', {});
1719
+ const req = {
1720
+ 'type': side,
1721
+ 'ordertype': type,
1722
+ 'volume': this.amountToPrecision(market['symbol'], amount),
1723
+ };
1724
+ const orderRequest = this.orderRequest('createOrders', marketId, type, req, amount, price, orderParams);
1725
+ ordersRequests.push(orderRequest[0]);
1726
+ }
1727
+ orderSymbols = this.marketSymbols(orderSymbols, undefined, false, true, true);
1728
+ let response = undefined;
1729
+ let request = {
1730
+ 'orders': ordersRequests,
1731
+ 'pair': market['id'],
1732
+ };
1733
+ request = this.extend(request, params);
1734
+ response = await this.privatePostAddOrderBatch(request);
1735
+ //
1736
+ // {
1737
+ // "error":[
1738
+ // ],
1739
+ // "result":{
1740
+ // "orders":[
1741
+ // {
1742
+ // "txid":"OEPPJX-34RMM-OROGZE",
1743
+ // "descr":{
1744
+ // "order":"sell 6.000000 ADAUSDC @ limit 0.400000"
1745
+ // }
1746
+ // },
1747
+ // {
1748
+ // "txid":"OLQY7O-OYBXW-W23PGL",
1749
+ // "descr":{
1750
+ // "order":"sell 6.000000 ADAUSDC @ limit 0.400000"
1751
+ // }
1752
+ // }
1753
+ // ]
1754
+ // }
1755
+ //
1756
+ const result = this.safeDict(response, 'result', {});
1757
+ return this.parseOrders(this.safeList(result, 'orders'));
1758
+ }
1681
1759
  findMarketByAltnameOrId(id) {
1682
1760
  const marketsByAltname = this.safeValue(this.options, 'marketsByAltname', {});
1683
1761
  if (id in marketsByAltname) {
@@ -3470,10 +3548,11 @@ class kraken extends kraken$1["default"] {
3470
3548
  isTriggerPercent = (price.endsWith('%')) ? true : false;
3471
3549
  }
3472
3550
  const isCancelOrderBatch = (path === 'CancelOrderBatch');
3551
+ const isBatchOrder = (path === 'AddOrderBatch');
3473
3552
  this.checkRequiredCredentials();
3474
3553
  const nonce = this.nonce().toString();
3475
3554
  // urlencodeNested is used to address https://github.com/ccxt/ccxt/issues/12872
3476
- if (isCancelOrderBatch || isTriggerPercent) {
3555
+ if (isCancelOrderBatch || isTriggerPercent || isBatchOrder) {
3477
3556
  body = this.json(this.extend({ 'nonce': nonce }, params));
3478
3557
  }
3479
3558
  else {
@@ -3489,7 +3568,7 @@ class kraken extends kraken$1["default"] {
3489
3568
  'API-Key': this.apiKey,
3490
3569
  'API-Sign': signature,
3491
3570
  };
3492
- if (isCancelOrderBatch || isTriggerPercent) {
3571
+ if (isCancelOrderBatch || isTriggerPercent || isBatchOrder) {
3493
3572
  headers['Content-Type'] = 'application/json';
3494
3573
  }
3495
3574
  else {
@@ -3514,10 +3593,10 @@ class kraken extends kraken$1["default"] {
3514
3593
  }
3515
3594
  if (body[0] === '{') {
3516
3595
  if (typeof response !== 'string') {
3596
+ const message = this.id + ' ' + body;
3517
3597
  if ('error' in response) {
3518
3598
  const numErrors = response['error'].length;
3519
3599
  if (numErrors) {
3520
- const message = this.id + ' ' + body;
3521
3600
  for (let i = 0; i < response['error'].length; i++) {
3522
3601
  const error = response['error'][i];
3523
3602
  this.throwExactlyMatchedException(this.exceptions['exact'], error, message);
@@ -3526,6 +3605,22 @@ class kraken extends kraken$1["default"] {
3526
3605
  throw new errors.ExchangeError(message);
3527
3606
  }
3528
3607
  }
3608
+ // handleCreateOrdersErrors:
3609
+ if ('result' in response) {
3610
+ const result = this.safeDict(response, 'result', {});
3611
+ if ('orders' in result) {
3612
+ const orders = this.safeList(result, 'orders', []);
3613
+ for (let i = 0; i < orders.length; i++) {
3614
+ const order = orders[i];
3615
+ const error = this.safeString(order, 'error');
3616
+ if (error !== undefined) {
3617
+ this.throwExactlyMatchedException(this.exceptions['exact'], error, message);
3618
+ this.throwBroadlyMatchedException(this.exceptions['broad'], error, message);
3619
+ throw new errors.ExchangeError(message);
3620
+ }
3621
+ }
3622
+ }
3623
+ }
3529
3624
  }
3530
3625
  }
3531
3626
  return undefined;