ccxt 4.3.56 → 4.3.57

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.
@@ -1545,7 +1545,65 @@ class huobijp extends huobijp$1 {
1545
1545
  // }
1546
1546
  // }
1547
1547
  //
1548
- return response;
1548
+ return this.parseCancelOrders(response);
1549
+ }
1550
+ parseCancelOrders(orders) {
1551
+ //
1552
+ // {
1553
+ // "success": [
1554
+ // "5983466"
1555
+ // ],
1556
+ // "failed": [
1557
+ // {
1558
+ // "err-msg": "Incorrect order state",
1559
+ // "order-state": 7,
1560
+ // "order-id": "",
1561
+ // "err-code": "order-orderstate-error",
1562
+ // "client-order-id": "first"
1563
+ // },
1564
+ // ...
1565
+ // ]
1566
+ // }
1567
+ //
1568
+ // {
1569
+ // "errors": [
1570
+ // {
1571
+ // "order_id": "769206471845261312",
1572
+ // "err_code": 1061,
1573
+ // "err_msg": "This order doesnt exist."
1574
+ // }
1575
+ // ],
1576
+ // "successes": "1258075374411399168,1258075393254871040"
1577
+ // }
1578
+ //
1579
+ const successes = this.safeString(orders, 'successes');
1580
+ let success = undefined;
1581
+ if (successes !== undefined) {
1582
+ success = successes.split(',');
1583
+ }
1584
+ else {
1585
+ success = this.safeList(orders, 'success', []);
1586
+ }
1587
+ const failed = this.safeList2(orders, 'errors', 'failed', []);
1588
+ const result = [];
1589
+ for (let i = 0; i < success.length; i++) {
1590
+ const order = success[i];
1591
+ result.push(this.safeOrder({
1592
+ 'info': order,
1593
+ 'id': order,
1594
+ 'status': 'canceled',
1595
+ }));
1596
+ }
1597
+ for (let i = 0; i < failed.length; i++) {
1598
+ const order = failed[i];
1599
+ result.push(this.safeOrder({
1600
+ 'info': order,
1601
+ 'id': this.safeString2(order, 'order-id', 'order_id'),
1602
+ 'status': 'failed',
1603
+ 'clientOrderId': this.safeString(order, 'client-order-id'),
1604
+ }));
1605
+ }
1606
+ return result;
1549
1607
  }
1550
1608
  async cancelAllOrders(symbol = undefined, params = {}) {
1551
1609
  /**
@@ -1580,7 +1638,12 @@ class huobijp extends huobijp$1 {
1580
1638
  // }
1581
1639
  // }
1582
1640
  //
1583
- return response;
1641
+ const data = this.safeDict(response, 'data', {});
1642
+ return [
1643
+ this.safeOrder({
1644
+ 'info': data,
1645
+ }),
1646
+ ];
1584
1647
  }
1585
1648
  currencyToPrecision(code, fee, networkCode = undefined) {
1586
1649
  return this.decimalToPrecision(fee, 0, this.currencies[code]['precision'], this.precisionMode);
package/js/ccxt.d.ts CHANGED
@@ -4,7 +4,7 @@ import * as functions from './src/base/functions.js';
4
4
  import * as errors from './src/base/errors.js';
5
5
  import type { Int, int, Str, Strings, Num, Bool, IndexType, OrderSide, OrderType, MarketType, SubType, Dict, NullableDict, List, NullableList, Fee, OHLCV, OHLCVC, implicitReturnType, Market, Currency, Dictionary, MinMax, FeeInterface, TradingFeeInterface, MarketInterface, Trade, Order, OrderBook, Ticker, Transaction, Tickers, CurrencyInterface, Balance, BalanceAccount, Account, PartialBalances, Balances, DepositAddress, WithdrawalResponse, DepositAddressResponse, FundingRate, FundingRates, Position, BorrowInterest, LeverageTier, LedgerEntry, DepositWithdrawFeeNetwork, DepositWithdrawFee, TransferEntry, CrossBorrowRate, IsolatedBorrowRate, FundingRateHistory, OpenInterest, Liquidation, OrderRequest, CancellationRequest, FundingHistory, MarginMode, Greeks, Conversion, Option, LastPrice, Leverage, MarginModification, Leverages, LastPrices, Currencies, TradingFees, MarginModes, OptionChain, IsolatedBorrowRates, CrossBorrowRates, TransferEntries, LeverageTiers } from './src/base/types.js';
6
6
  import { BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, MarketClosed, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, ProxyError, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout } from './src/base/errors.js';
7
- declare const version = "4.3.55";
7
+ declare const version = "4.3.56";
8
8
  import ace from './src/ace.js';
9
9
  import alpaca from './src/alpaca.js';
10
10
  import ascendex from './src/ascendex.js';
package/js/ccxt.js CHANGED
@@ -38,7 +38,7 @@ import * as errors from './src/base/errors.js';
38
38
  import { BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, MarketClosed, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, ProxyError, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout } from './src/base/errors.js';
39
39
  //-----------------------------------------------------------------------------
40
40
  // this is updated by vss.js when building
41
- const version = '4.3.56';
41
+ const version = '4.3.57';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import ace from './src/ace.js';
@@ -5,6 +5,8 @@ export default class Client {
5
5
  disconnected: ReturnType<typeof Future>;
6
6
  futures: Dictionary<any>;
7
7
  rejections: Dictionary<any>;
8
+ messageQueue: Dictionary<string, any>;
9
+ useMessageQueue: boolean;
8
10
  keepAlive: number;
9
11
  connection: any;
10
12
  connectionTimeout: any;
@@ -11,6 +11,7 @@ import { isNode, isJsonEncodedObject, deepExtend, milliseconds, } from '../../ba
11
11
  import { utf8 } from '../../static_dependencies/scure-base/index.js';
12
12
  export default class Client {
13
13
  constructor(url, onMessageCallback, onErrorCallback, onCloseCallback, onConnectedCallback, config = {}) {
14
+ this.useMessageQueue = true;
14
15
  this.verbose = false;
15
16
  const defaults = {
16
17
  url,
@@ -24,6 +25,8 @@ export default class Client {
24
25
  futures: {},
25
26
  subscriptions: {},
26
27
  rejections: {},
28
+ messageQueue: {},
29
+ useMessageQueue: true,
27
30
  connected: undefined,
28
31
  error: undefined,
29
32
  connectionStarted: undefined,
@@ -54,6 +57,15 @@ export default class Client {
54
57
  if (messageHash in this.rejections) {
55
58
  future.reject(this.rejections[messageHash]);
56
59
  delete this.rejections[messageHash];
60
+ delete this.messageQueue[messageHash];
61
+ return future;
62
+ }
63
+ if (this.useMessageQueue) {
64
+ const queue = this.messageQueue[messageHash];
65
+ if (queue && queue.length) {
66
+ future.resolve(queue.shift());
67
+ delete this.futures[messageHash];
68
+ }
57
69
  }
58
70
  return future;
59
71
  }
@@ -61,10 +73,27 @@ export default class Client {
61
73
  if (this.verbose && (messageHash === undefined)) {
62
74
  this.log(new Date(), 'resolve received undefined messageHash');
63
75
  }
64
- if ((messageHash !== undefined) && (messageHash in this.futures)) {
65
- const promise = this.futures[messageHash];
66
- promise.resolve(result);
67
- delete this.futures[messageHash];
76
+ if (this.useMessageQueue === true) {
77
+ if (!(messageHash in this.messageQueue)) {
78
+ this.messageQueue[messageHash] = [];
79
+ }
80
+ const queue = this.messageQueue[messageHash];
81
+ queue.push(result);
82
+ while (queue.length > 10) { // limit size to 10 messages in the queue
83
+ queue.shift();
84
+ }
85
+ if ((messageHash !== undefined) && (messageHash in this.futures)) {
86
+ const promise = this.futures[messageHash];
87
+ promise.resolve(queue.shift());
88
+ delete this.futures[messageHash];
89
+ }
90
+ }
91
+ else {
92
+ if (messageHash in this.futures) {
93
+ const promise = this.futures[messageHash];
94
+ promise.resolve(result);
95
+ delete this.futures[messageHash];
96
+ }
68
97
  }
69
98
  return result;
70
99
  }
@@ -105,6 +134,7 @@ export default class Client {
105
134
  reset(error) {
106
135
  this.clearConnectionTimeout();
107
136
  this.clearPingInterval();
137
+ this.messageQueue = {};
108
138
  this.reject(error);
109
139
  }
110
140
  onConnectionTimeout() {
package/js/src/bingx.d.ts CHANGED
@@ -10,6 +10,7 @@ export default class bingx extends Exchange {
10
10
  fetchCurrencies(params?: {}): Promise<Currencies>;
11
11
  fetchSpotMarkets(params: any): Promise<import("./base/types.js").MarketInterface[]>;
12
12
  fetchSwapMarkets(params: any): Promise<import("./base/types.js").MarketInterface[]>;
13
+ fetchInverseSwapMarkets(params: any): Promise<import("./base/types.js").MarketInterface[]>;
13
14
  parseMarket(market: Dict): Market;
14
15
  fetchMarkets(params?: {}): Promise<Market[]>;
15
16
  fetchOHLCV(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<OHLCV[]>;
package/js/src/bingx.js CHANGED
@@ -672,6 +672,29 @@ export default class bingx extends Exchange {
672
672
  const markets = this.safeList(response, 'data', []);
673
673
  return this.parseMarkets(markets);
674
674
  }
675
+ async fetchInverseSwapMarkets(params) {
676
+ const response = await this.cswapV1PublicGetMarketContracts(params);
677
+ //
678
+ // {
679
+ // "code": 0,
680
+ // "msg": "",
681
+ // "timestamp": 1720074487610,
682
+ // "data": [
683
+ // {
684
+ // "symbol": "BNB-USD",
685
+ // "pricePrecision": 2,
686
+ // "minTickSize": "10",
687
+ // "minTradeValue": "10",
688
+ // "minQty": "1.00000000",
689
+ // "status": 1,
690
+ // "timeOnline": 1713175200000
691
+ // },
692
+ // ]
693
+ // }
694
+ //
695
+ const markets = this.safeList(response, 'data', []);
696
+ return this.parseMarkets(markets);
697
+ }
675
698
  parseMarket(market) {
676
699
  const id = this.safeString(market, 'symbol');
677
700
  const symbolParts = id.split('-');
@@ -679,7 +702,16 @@ export default class bingx extends Exchange {
679
702
  const quoteId = symbolParts[1];
680
703
  const base = this.safeCurrencyCode(baseId);
681
704
  const quote = this.safeCurrencyCode(quoteId);
682
- const currency = this.safeString(market, 'currency');
705
+ let currency = this.safeString(market, 'currency');
706
+ let checkIsInverse = false;
707
+ let checkIsLinear = true;
708
+ const minTickSize = this.safeNumber(market, 'minTickSize');
709
+ if (minTickSize !== undefined) {
710
+ // inverse swap market
711
+ currency = baseId;
712
+ checkIsInverse = true;
713
+ checkIsLinear = false;
714
+ }
683
715
  const settle = this.safeCurrencyCode(currency);
684
716
  let pricePrecision = this.safeNumber(market, 'tickSize');
685
717
  if (pricePrecision === undefined) {
@@ -699,8 +731,12 @@ export default class bingx extends Exchange {
699
731
  const fees = this.safeDict(this.fees, type, {});
700
732
  const contractSize = (swap) ? this.parseNumber('1') : undefined;
701
733
  const isActive = this.safeString(market, 'status') === '1';
702
- const isInverse = (spot) ? undefined : false;
703
- const isLinear = (spot) ? undefined : swap;
734
+ const isInverse = (spot) ? undefined : checkIsInverse;
735
+ const isLinear = (spot) ? undefined : checkIsLinear;
736
+ let timeOnline = this.safeInteger(market, 'timeOnline');
737
+ if (timeOnline === 0) {
738
+ timeOnline = undefined;
739
+ }
704
740
  return this.safeMarketStructure({
705
741
  'id': id,
706
742
  'symbol': symbol,
@@ -742,15 +778,15 @@ export default class bingx extends Exchange {
742
778
  'max': this.safeNumber(market, 'maxQty'),
743
779
  },
744
780
  'price': {
745
- 'min': undefined,
781
+ 'min': minTickSize,
746
782
  'max': undefined,
747
783
  },
748
784
  'cost': {
749
- 'min': this.safeNumber2(market, 'minNotional', 'tradeMinUSDT'),
785
+ 'min': this.safeNumberN(market, ['minNotional', 'tradeMinUSDT', 'minTradeValue']),
750
786
  'max': this.safeNumber(market, 'maxNotional'),
751
787
  },
752
788
  },
753
- 'created': undefined,
789
+ 'created': timeOnline,
754
790
  'info': market,
755
791
  });
756
792
  }
@@ -761,17 +797,21 @@ export default class bingx extends Exchange {
761
797
  * @description retrieves data on all markets for bingx
762
798
  * @see https://bingx-api.github.io/docs/#/spot/market-api.html#Query%20Symbols
763
799
  * @see https://bingx-api.github.io/docs/#/swapV2/market-api.html#Contract%20Information
800
+ * @see https://bingx-api.github.io/docs/#/en-us/cswap/market-api.html#Contract%20Information
764
801
  * @param {object} [params] extra parameters specific to the exchange API endpoint
765
802
  * @returns {object[]} an array of objects representing market data
766
803
  */
767
804
  const requests = [this.fetchSwapMarkets(params)];
768
805
  const isSandbox = this.safeBool(this.options, 'sandboxMode', false);
769
806
  if (!isSandbox) {
807
+ requests.push(this.fetchInverseSwapMarkets(params));
770
808
  requests.push(this.fetchSpotMarkets(params)); // sandbox is swap only
771
809
  }
772
810
  const promises = await Promise.all(requests);
773
- const spotMarkets = this.safeList(promises, 0, []);
774
- const swapMarkets = this.safeList(promises, 1, []);
811
+ const linearSwapMarkets = this.safeList(promises, 0, []);
812
+ const inverseSwapMarkets = this.safeList(promises, 1, []);
813
+ const spotMarkets = this.safeList(promises, 2, []);
814
+ const swapMarkets = this.arrayConcat(linearSwapMarkets, inverseSwapMarkets);
775
815
  return this.arrayConcat(spotMarkets, swapMarkets);
776
816
  }
777
817
  async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
@@ -64,7 +64,7 @@ export default class bitget extends Exchange {
64
64
  editOrder(id: string, symbol: string, type: OrderType, side: OrderSide, amount?: Num, price?: Num, params?: {}): Promise<Order>;
65
65
  cancelOrder(id: string, symbol?: Str, params?: {}): Promise<Order>;
66
66
  cancelOrders(ids: any, symbol?: Str, params?: {}): Promise<Order[]>;
67
- cancelAllOrders(symbol?: Str, params?: {}): Promise<any>;
67
+ cancelAllOrders(symbol?: Str, params?: {}): Promise<Order[]>;
68
68
  fetchOrder(id: string, symbol?: Str, params?: {}): Promise<Order>;
69
69
  fetchOpenOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
70
70
  fetchClosedOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
package/js/src/bitget.js CHANGED
@@ -5015,6 +5015,22 @@ export default class bitget extends Exchange {
5015
5015
  else {
5016
5016
  response = await this.privateMarginPostMarginV1IsolatedOrderBatchCancelOrder(this.extend(request, params));
5017
5017
  }
5018
+ //
5019
+ // {
5020
+ // "code": "00000",
5021
+ // "msg": "success",
5022
+ // "requestTime": 1700717155622,
5023
+ // "data": {
5024
+ // "resultList": [
5025
+ // {
5026
+ // "orderId": "1111453253721796609",
5027
+ // "clientOid": "2ae7fc8a4ff949b6b60d770ca3950e2d"
5028
+ // },
5029
+ // ],
5030
+ // "failure": []
5031
+ // }
5032
+ // }
5033
+ //
5018
5034
  }
5019
5035
  else {
5020
5036
  if (stop) {
@@ -5026,6 +5042,27 @@ export default class bitget extends Exchange {
5026
5042
  else {
5027
5043
  response = await this.privateSpotPostV2SpotTradeCancelSymbolOrder(this.extend(request, params));
5028
5044
  }
5045
+ //
5046
+ // {
5047
+ // "code": "00000",
5048
+ // "msg": "success",
5049
+ // "requestTime": 1700716953996,
5050
+ // "data": {
5051
+ // "symbol": "BTCUSDT"
5052
+ // }
5053
+ // }
5054
+ //
5055
+ const timestamp = this.safeInteger(response, 'requestTime');
5056
+ const responseData = this.safeDict(response, 'data');
5057
+ const marketId = this.safeString(responseData, 'symbol');
5058
+ return [
5059
+ this.safeOrder({
5060
+ 'info': response,
5061
+ 'symbol': this.safeSymbol(marketId, undefined, undefined, 'spot'),
5062
+ 'timestamp': timestamp,
5063
+ 'datetime': this.iso8601(timestamp),
5064
+ }),
5065
+ ];
5029
5066
  }
5030
5067
  }
5031
5068
  else {
@@ -5038,54 +5075,26 @@ export default class bitget extends Exchange {
5038
5075
  else {
5039
5076
  response = await this.privateMixPostV2MixOrderBatchCancelOrders(this.extend(request, params));
5040
5077
  }
5078
+ // {
5079
+ // "code": "00000",
5080
+ // "msg": "success",
5081
+ // "requestTime": "1680008815965",
5082
+ // "data": {
5083
+ // "successList": [
5084
+ // {
5085
+ // "orderId": "1024598257429823488",
5086
+ // "clientOid": "876493ce-c287-4bfc-9f4a-8b1905881313"
5087
+ // },
5088
+ // ],
5089
+ // "failureList": []
5090
+ // }
5091
+ // }
5041
5092
  }
5042
- //
5043
- // spot
5044
- //
5045
- // {
5046
- // "code": "00000",
5047
- // "msg": "success",
5048
- // "requestTime": 1700716953996,
5049
- // "data": {
5050
- // "symbol": "BTCUSDT"
5051
- // }
5052
- // }
5053
- //
5054
- // swap
5055
- //
5056
- // {
5057
- // "code": "00000",
5058
- // "msg": "success",
5059
- // "requestTime": "1680008815965",
5060
- // "data": {
5061
- // "successList": [
5062
- // {
5063
- // "orderId": "1024598257429823488",
5064
- // "clientOid": "876493ce-c287-4bfc-9f4a-8b1905881313"
5065
- // },
5066
- // ],
5067
- // "failureList": []
5068
- // }
5069
- // }
5070
- //
5071
- // spot margin
5072
- //
5073
- // {
5074
- // "code": "00000",
5075
- // "msg": "success",
5076
- // "requestTime": 1700717155622,
5077
- // "data": {
5078
- // "resultList": [
5079
- // {
5080
- // "orderId": "1111453253721796609",
5081
- // "clientOid": "2ae7fc8a4ff949b6b60d770ca3950e2d"
5082
- // },
5083
- // ],
5084
- // "failure": []
5085
- // }
5086
- // }
5087
- //
5088
- return response;
5093
+ const data = this.safeDict(response, 'data');
5094
+ const resultList = this.safeList2(data, 'resultList', 'successList');
5095
+ const failureList = this.safeList2(data, 'failure', 'failureList');
5096
+ const responseList = this.arrayConcat(resultList, failureList);
5097
+ return this.parseOrders(responseList);
5089
5098
  }
5090
5099
  async fetchOrder(id, symbol = undefined, params = {}) {
5091
5100
  /**
package/js/src/coinone.js CHANGED
@@ -21,8 +21,7 @@ export default class coinone extends Exchange {
21
21
  'id': 'coinone',
22
22
  'name': 'CoinOne',
23
23
  'countries': ['KR'],
24
- // 'enableRateLimit': false,
25
- 'rateLimit': 667,
24
+ 'rateLimit': 50,
26
25
  'version': 'v2',
27
26
  'pro': false,
28
27
  'has': {
@@ -194,10 +193,10 @@ export default class coinone extends Exchange {
194
193
  },
195
194
  'precisionMode': TICK_SIZE,
196
195
  'exceptions': {
197
- '405': OnMaintenance,
198
196
  '104': OrderNotFound,
197
+ '107': BadRequest,
199
198
  '108': BadSymbol,
200
- '107': BadRequest, // {"errorCode":"107","errorMsg":"Parameter error","result":"error"}
199
+ '405': OnMaintenance,
201
200
  },
202
201
  'commonCurrencies': {
203
202
  'SOC': 'Soda Coin',
@@ -1167,22 +1166,17 @@ export default class coinone extends Exchange {
1167
1166
  }
1168
1167
  handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
1169
1168
  if (response === undefined) {
1170
- return undefined;
1171
- }
1172
- if ('result' in response) {
1173
- const result = response['result'];
1174
- if (result !== 'success') {
1175
- //
1176
- // { "errorCode": "405", "status": "maintenance", "result": "error"}
1177
- //
1178
- const errorCode = this.safeString(response, 'errorCode');
1179
- const feedback = this.id + ' ' + body;
1180
- this.throwExactlyMatchedException(this.exceptions, errorCode, feedback);
1181
- throw new ExchangeError(feedback);
1182
- }
1169
+ return undefined; // fallback to default error handler
1183
1170
  }
1184
- else {
1185
- throw new ExchangeError(this.id + ' ' + body);
1171
+ //
1172
+ // {"result":"error","error_code":"107","error_msg":"Parameter value is wrong"}
1173
+ // {"result":"error","error_code":"108","error_msg":"Unknown CryptoCurrency"}
1174
+ //
1175
+ const errorCode = this.safeString(response, 'error_code');
1176
+ if (errorCode !== '0') {
1177
+ const feedback = this.id + ' ' + body;
1178
+ this.throwExactlyMatchedException(this.exceptions, errorCode, feedback);
1179
+ throw new ExchangeError(feedback); // unknown message
1186
1180
  }
1187
1181
  return undefined;
1188
1182
  }
package/js/src/gate.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import Exchange from './abstract/gate.js';
2
- import type { Int, OrderSide, OrderType, OHLCV, Trade, FundingRateHistory, OpenInterest, Order, Balances, OrderRequest, FundingHistory, Str, Transaction, Ticker, OrderBook, Tickers, Greeks, Strings, Market, Currency, MarketInterface, TransferEntry, Leverage, Leverages, Num, OptionChain, Option, MarginModification, TradingFeeInterface, Currencies, TradingFees, Position, Dict, LeverageTier, LeverageTiers, int } from './base/types.js';
2
+ import type { Int, OrderSide, OrderType, OHLCV, Trade, FundingRateHistory, OpenInterest, Order, Balances, OrderRequest, FundingHistory, Str, Transaction, Ticker, OrderBook, Tickers, Greeks, Strings, Market, Currency, MarketInterface, TransferEntry, Leverage, Leverages, Num, OptionChain, Option, MarginModification, TradingFeeInterface, Currencies, TradingFees, Position, Dict, LeverageTier, LeverageTiers, int, CancellationRequest } from './base/types.js';
3
3
  /**
4
4
  * @class gate
5
5
  * @augments Exchange
@@ -180,6 +180,8 @@ export default class gate extends Exchange {
180
180
  fetchOrdersByStatusRequest(status: any, symbol?: Str, since?: Int, limit?: Int, params?: {}): any[];
181
181
  fetchOrdersByStatus(status: any, symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<any>;
182
182
  cancelOrder(id: string, symbol?: Str, params?: {}): Promise<Order>;
183
+ cancelOrders(ids: string[], symbol?: Str, params?: {}): Promise<Order[]>;
184
+ cancelOrdersForSymbols(orders: CancellationRequest[], params?: {}): Promise<Order[]>;
183
185
  cancelAllOrders(symbol?: Str, params?: {}): Promise<Order[]>;
184
186
  transfer(code: string, amount: number, fromAccount: string, toAccount: string, params?: {}): Promise<TransferEntry>;
185
187
  parseTransfer(transfer: Dict, currency?: Currency): TransferEntry;
package/js/src/gate.js CHANGED
@@ -84,6 +84,8 @@ export default class gate extends Exchange {
84
84
  'borrowIsolatedMargin': true,
85
85
  'cancelAllOrders': true,
86
86
  'cancelOrder': true,
87
+ 'cancelOrders': true,
88
+ 'cancelOrdersForSymbols': true,
87
89
  'createMarketBuyOrderWithCost': true,
88
90
  'createMarketOrder': true,
89
91
  'createMarketOrderWithCost': false,
@@ -4470,6 +4472,8 @@ export default class gate extends Exchange {
4470
4472
  // "message": "Not enough balance"
4471
4473
  // }
4472
4474
  //
4475
+ // {"user_id":10406147,"id":"id","succeeded":false,"message":"INVALID_PROTOCOL","label":"INVALID_PROTOCOL"}
4476
+ //
4473
4477
  const succeeded = this.safeBool(order, 'succeeded', true);
4474
4478
  if (!succeeded) {
4475
4479
  // cancelOrders response
@@ -4477,6 +4481,7 @@ export default class gate extends Exchange {
4477
4481
  'clientOrderId': this.safeString(order, 'text'),
4478
4482
  'info': order,
4479
4483
  'status': 'rejected',
4484
+ 'id': this.safeString(order, 'id'),
4480
4485
  });
4481
4486
  }
4482
4487
  const put = this.safeValue2(order, 'put', 'initial', {});
@@ -5076,6 +5081,92 @@ export default class gate extends Exchange {
5076
5081
  //
5077
5082
  return this.parseOrder(response, market);
5078
5083
  }
5084
+ async cancelOrders(ids, symbol = undefined, params = {}) {
5085
+ /**
5086
+ * @method
5087
+ * @name gate#cancelOrders
5088
+ * @description cancel multiple orders
5089
+ * @see https://www.gate.io/docs/developers/apiv4/en/#cancel-a-batch-of-orders-with-an-id-list
5090
+ * @see https://www.gate.io/docs/developers/apiv4/en/#cancel-a-batch-of-orders-with-an-id-list-2
5091
+ * @param {string[]} ids order ids
5092
+ * @param {string} symbol unified symbol of the market the order was made in
5093
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
5094
+ * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
5095
+ */
5096
+ await this.loadMarkets();
5097
+ let market = undefined;
5098
+ if (symbol !== undefined) {
5099
+ market = this.market(symbol);
5100
+ }
5101
+ let type = undefined;
5102
+ const defaultSettle = (market === undefined) ? 'usdt' : market['settle'];
5103
+ const settle = this.safeStringLower(params, 'settle', defaultSettle);
5104
+ [type, params] = this.handleMarketTypeAndParams('cancelOrders', market, params);
5105
+ const isSpot = (type === 'spot');
5106
+ if (isSpot && (symbol === undefined)) {
5107
+ throw new ArgumentsRequired(this.id + ' cancelOrders requires a symbol argument for spot markets');
5108
+ }
5109
+ if (isSpot) {
5110
+ const ordersRequests = [];
5111
+ for (let i = 0; i < ids.length; i++) {
5112
+ const id = ids[i];
5113
+ const orderItem = {
5114
+ 'id': id,
5115
+ 'symbol': symbol,
5116
+ };
5117
+ ordersRequests.push(orderItem);
5118
+ }
5119
+ return await this.cancelOrdersForSymbols(ordersRequests, params);
5120
+ }
5121
+ const request = {
5122
+ 'settle': settle,
5123
+ };
5124
+ const finalList = [request]; // hacky but needs to be done here
5125
+ for (let i = 0; i < ids.length; i++) {
5126
+ finalList.push(ids[i]);
5127
+ }
5128
+ const response = await this.privateFuturesPostSettleBatchCancelOrders(finalList);
5129
+ return this.parseOrders(response);
5130
+ }
5131
+ async cancelOrdersForSymbols(orders, params = {}) {
5132
+ /**
5133
+ * @method
5134
+ * @name gate#cancelOrdersForSymbols
5135
+ * @description cancel multiple orders for multiple symbols
5136
+ * @see https://www.gate.io/docs/developers/apiv4/en/#cancel-a-batch-of-orders-with-an-id-list
5137
+ * @param {string[]} ids order ids
5138
+ * @param {string} symbol unified symbol of the market the order was made in
5139
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
5140
+ * @param {string[]} [params.clientOrderIds] client order ids
5141
+ * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
5142
+ */
5143
+ await this.loadMarkets();
5144
+ const ordersRequests = [];
5145
+ for (let i = 0; i < orders.length; i++) {
5146
+ const order = orders[i];
5147
+ const symbol = this.safeString(order, 'symbol');
5148
+ const market = this.market(symbol);
5149
+ if (!market['spot']) {
5150
+ throw new NotSupported(this.id + ' cancelOrdersForSymbols() supports only spot markets');
5151
+ }
5152
+ const id = this.safeString(order, 'id');
5153
+ const orderItem = {
5154
+ 'id': id,
5155
+ 'currency_pair': market['id'],
5156
+ };
5157
+ ordersRequests.push(orderItem);
5158
+ }
5159
+ const response = await this.privateSpotPostCancelBatchOrders(ordersRequests);
5160
+ //
5161
+ // [
5162
+ // {
5163
+ // "currency_pair": "BTC_USDT",
5164
+ // "id": "123456"
5165
+ // }
5166
+ // ]
5167
+ //
5168
+ return this.parseOrders(response);
5169
+ }
5079
5170
  async cancelAllOrders(symbol = undefined, params = {}) {
5080
5171
  /**
5081
5172
  * @method
@@ -6080,7 +6171,22 @@ export default class gate extends Exchange {
6080
6171
  const authentication = api[0]; // public, private
6081
6172
  const type = api[1]; // spot, margin, future, delivery
6082
6173
  let query = this.omit(params, this.extractParams(path));
6083
- if (Array.isArray(params)) {
6174
+ const containsSettle = path.indexOf('settle') > -1;
6175
+ if (containsSettle && path.endsWith('batch_cancel_orders')) { // weird check to prevent $settle in php and converting {settle} to array(settle)
6176
+ // special case where we need to extract the settle from the path
6177
+ // but the body is an array of strings
6178
+ const settle = this.safeDict(params, 0);
6179
+ path = this.implodeParams(path, settle);
6180
+ // remove the first element from params
6181
+ const newParams = [];
6182
+ const anyParams = params;
6183
+ for (let i = 1; i < anyParams.length; i++) {
6184
+ newParams.push(params[i]);
6185
+ }
6186
+ params = newParams;
6187
+ query = newParams;
6188
+ }
6189
+ else if (Array.isArray(params)) {
6084
6190
  // endpoints like createOrders use an array instead of an object
6085
6191
  // so we infer the settle from one of the elements
6086
6192
  // they have to be all the same so relying on the first one is fine
@@ -7553,6 +7659,7 @@ export default class gate extends Exchange {
7553
7659
  // {"label": "INVALID_PARAM_VALUE", "message": "invalid argument: Trigger.rule"}
7554
7660
  // {"label": "INVALID_PARAM_VALUE", "message": "invalid argument: trigger.expiration invalid range"}
7555
7661
  // {"label": "INVALID_ARGUMENT", "detail": "invalid size"}
7662
+ // {"user_id":10406147,"id":"id","succeeded":false,"message":"INVALID_PROTOCOL","label":"INVALID_PROTOCOL"}
7556
7663
  //
7557
7664
  const label = this.safeString(response, 'label');
7558
7665
  if (label !== undefined) {