ccxt 4.4.6 → 4.4.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/js/src/mexc.js CHANGED
@@ -43,8 +43,8 @@ export default class mexc extends Exchange {
43
43
  'closePosition': false,
44
44
  'createDepositAddress': true,
45
45
  'createMarketBuyOrderWithCost': true,
46
- 'createMarketOrderWithCost': false,
47
- 'createMarketSellOrderWithCost': false,
46
+ 'createMarketOrderWithCost': true,
47
+ 'createMarketSellOrderWithCost': true,
48
48
  'createOrder': true,
49
49
  'createOrders': true,
50
50
  'createPostOnlyOrder': true,
@@ -133,7 +133,7 @@ export default class mexc extends Exchange {
133
133
  'repayCrossMargin': false,
134
134
  'repayIsolatedMargin': false,
135
135
  'setLeverage': true,
136
- 'setMarginMode': undefined,
136
+ 'setMarginMode': true,
137
137
  'setPositionMode': true,
138
138
  'signIn': undefined,
139
139
  'transfer': undefined,
@@ -419,7 +419,6 @@ export default class mexc extends Exchange {
419
419
  'options': {
420
420
  'adjustForTimeDifference': false,
421
421
  'timeDifference': 0,
422
- 'createMarketBuyOrderRequiresPrice': true,
423
422
  'unavailableContracts': {
424
423
  'BTC/USDT:USDT': true,
425
424
  'LTC/USDT:USDT': true,
@@ -468,12 +467,14 @@ export default class mexc extends Exchange {
468
467
  'LTC': 'LTC',
469
468
  },
470
469
  'networks': {
470
+ 'ZKSYNC': 'ZKSYNCERA',
471
471
  'TRC20': 'TRX',
472
472
  'TON': 'TONCOIN',
473
473
  'AVAXC': 'AVAX_CCHAIN',
474
474
  'ERC20': 'ETH',
475
475
  'ACA': 'ACALA',
476
476
  'BEP20': 'BSC',
477
+ 'OPTIMISM': 'OP',
477
478
  // 'ADA': 'Cardano(ADA)',
478
479
  // 'AE': 'AE',
479
480
  // 'ALGO': 'Algorand(ALGO)',
@@ -2109,8 +2110,27 @@ export default class mexc extends Exchange {
2109
2110
  if (!market['spot']) {
2110
2111
  throw new NotSupported(this.id + ' createMarketBuyOrderWithCost() supports spot orders only');
2111
2112
  }
2112
- params['createMarketBuyOrderRequiresPrice'] = false;
2113
- return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
2113
+ params['cost'] = cost;
2114
+ return await this.createOrder(symbol, 'market', 'buy', 0, undefined, params);
2115
+ }
2116
+ async createMarketSellOrderWithCost(symbol, cost, params = {}) {
2117
+ /**
2118
+ * @method
2119
+ * @name mexc#createMarketSellOrderWithCost
2120
+ * @description create a market sell order by providing the symbol and cost
2121
+ * @see https://mexcdevelop.github.io/apidocs/spot_v3_en/#new-order
2122
+ * @param {string} symbol unified symbol of the market to create an order in
2123
+ * @param {float} cost how much you want to trade in units of the quote currency
2124
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2125
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2126
+ */
2127
+ await this.loadMarkets();
2128
+ const market = this.market(symbol);
2129
+ if (!market['spot']) {
2130
+ throw new NotSupported(this.id + ' createMarketBuyOrderWithCost() supports spot orders only');
2131
+ }
2132
+ params['cost'] = cost;
2133
+ return await this.createOrder(symbol, 'market', 'sell', 0, undefined, params);
2114
2134
  }
2115
2135
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
2116
2136
  /**
@@ -2136,6 +2156,7 @@ export default class mexc extends Exchange {
2136
2156
  * @param {long} [params.positionId] *contract only* it is recommended to fill in this parameter when closing a position
2137
2157
  * @param {string} [params.externalOid] *contract only* external order ID
2138
2158
  * @param {int} [params.positionMode] *contract only* 1:hedge, 2:one-way, default: the user's current config
2159
+ * @param {boolean} [params.test] *spot only* whether to use the test endpoint or not, default is false
2139
2160
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2140
2161
  */
2141
2162
  await this.loadMarkets();
@@ -2156,26 +2177,25 @@ export default class mexc extends Exchange {
2156
2177
  'side': orderSide,
2157
2178
  'type': type.toUpperCase(),
2158
2179
  };
2159
- if (orderSide === 'BUY' && type === 'market') {
2160
- let createMarketBuyOrderRequiresPrice = true;
2161
- [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
2180
+ if (type === 'market') {
2162
2181
  const cost = this.safeNumber2(params, 'cost', 'quoteOrderQty');
2163
2182
  params = this.omit(params, 'cost');
2164
2183
  if (cost !== undefined) {
2165
2184
  amount = cost;
2185
+ request['quoteOrderQty'] = this.costToPrecision(symbol, amount);
2166
2186
  }
2167
- else if (createMarketBuyOrderRequiresPrice) {
2187
+ else {
2168
2188
  if (price === undefined) {
2169
- throw new InvalidOrder(this.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend in the amount argument');
2189
+ request['quantity'] = this.amountToPrecision(symbol, amount);
2170
2190
  }
2171
2191
  else {
2172
2192
  const amountString = this.numberToString(amount);
2173
2193
  const priceString = this.numberToString(price);
2174
2194
  const quoteAmount = Precise.stringMul(amountString, priceString);
2175
2195
  amount = quoteAmount;
2196
+ request['quoteOrderQty'] = this.costToPrecision(symbol, amount);
2176
2197
  }
2177
2198
  }
2178
- request['quoteOrderQty'] = this.costToPrecision(symbol, amount);
2179
2199
  }
2180
2200
  else {
2181
2201
  request['quantity'] = this.amountToPrecision(symbol, amount);
@@ -2219,8 +2239,16 @@ export default class mexc extends Exchange {
2219
2239
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2220
2240
  */
2221
2241
  await this.loadMarkets();
2242
+ const test = this.safeBool(params, 'test', false);
2243
+ params = this.omit(params, 'test');
2222
2244
  const request = this.createSpotOrderRequest(market, type, side, amount, price, marginMode, params);
2223
- const response = await this.spotPrivatePostOrder(this.extend(request, params));
2245
+ let response = undefined;
2246
+ if (test) {
2247
+ response = await this.spotPrivatePostOrderTest(request);
2248
+ }
2249
+ else {
2250
+ response = await this.spotPrivatePostOrder(request);
2251
+ }
2224
2252
  //
2225
2253
  // spot
2226
2254
  //
@@ -2573,6 +2601,9 @@ export default class mexc extends Exchange {
2573
2601
  * @method
2574
2602
  * @name mexc#fetchOrders
2575
2603
  * @description fetches information on multiple orders made by the user
2604
+ * @see https://mexcdevelop.github.io/apidocs/spot_v3_en/#all-orders
2605
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-all-of-the-user-39-s-historical-orders
2606
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#gets-the-trigger-order-list
2576
2607
  * @param {string} symbol unified market symbol of the market orders were made in
2577
2608
  * @param {int} [since] the earliest time in ms to fetch orders for
2578
2609
  * @param {int} [limit] the maximum number of order structures to retrieve
@@ -2805,6 +2836,9 @@ export default class mexc extends Exchange {
2805
2836
  * @method
2806
2837
  * @name mexc#fetchOpenOrders
2807
2838
  * @description fetch all unfilled currently open orders
2839
+ * @see https://mexcdevelop.github.io/apidocs/spot_v3_en/#current-open-orders
2840
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-all-of-the-user-39-s-historical-orders
2841
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#gets-the-trigger-order-list
2808
2842
  * @param {string} symbol unified market symbol
2809
2843
  * @param {int} [since] the earliest time in ms to fetch open orders for
2810
2844
  * @param {int} [limit] the maximum number of open orders structures to retrieve
@@ -2896,6 +2930,9 @@ export default class mexc extends Exchange {
2896
2930
  * @method
2897
2931
  * @name mexc#fetchClosedOrders
2898
2932
  * @description fetches information on multiple closed orders made by the user
2933
+ * @see https://mexcdevelop.github.io/apidocs/spot_v3_en/#all-orders
2934
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-all-of-the-user-39-s-historical-orders
2935
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#gets-the-trigger-order-list
2899
2936
  * @param {string} symbol unified market symbol of the market orders were made in
2900
2937
  * @param {int} [since] the earliest time in ms to fetch orders for
2901
2938
  * @param {int} [limit] the maximum number of order structures to retrieve
@@ -2909,6 +2946,9 @@ export default class mexc extends Exchange {
2909
2946
  * @method
2910
2947
  * @name mexc#fetchCanceledOrders
2911
2948
  * @description fetches information on multiple canceled orders made by the user
2949
+ * @see https://mexcdevelop.github.io/apidocs/spot_v3_en/#all-orders
2950
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-all-of-the-user-39-s-historical-orders
2951
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#gets-the-trigger-order-list
2912
2952
  * @param {string} symbol unified market symbol of the market orders were made in
2913
2953
  * @param {int} [since] timestamp in ms of the earliest order, default is undefined
2914
2954
  * @param {int} [limit] max number of orders to return, default is undefined
@@ -5653,6 +5693,50 @@ export default class mexc extends Exchange {
5653
5693
  const positions = this.parsePositions(data, symbols, params);
5654
5694
  return this.filterBySinceLimit(positions, since, limit);
5655
5695
  }
5696
+ async setMarginMode(marginMode, symbol = undefined, params = {}) {
5697
+ /**
5698
+ * @method
5699
+ * @name mexc#setMarginMode
5700
+ * @description set margin mode to 'cross' or 'isolated'
5701
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#switch-leverage
5702
+ * @param {string} marginMode 'cross' or 'isolated'
5703
+ * @param {string} [symbol] required when there is no position, else provide params["positionId"]
5704
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
5705
+ * @param {string} [params.positionId] required when a position is set
5706
+ * @param {string} [params.direction] "long" or "short" required when there is no position
5707
+ * @returns {object} response from the exchange
5708
+ */
5709
+ await this.loadMarkets();
5710
+ const market = this.market(symbol);
5711
+ if (market['spot']) {
5712
+ throw new BadSymbol(this.id + ' setMarginMode() supports contract markets only');
5713
+ }
5714
+ marginMode = marginMode.toLowerCase();
5715
+ if (marginMode !== 'isolated' && marginMode !== 'cross') {
5716
+ throw new BadRequest(this.id + ' setMarginMode() marginMode argument should be isolated or cross');
5717
+ }
5718
+ const leverage = this.safeInteger(params, 'leverage');
5719
+ if (leverage === undefined) {
5720
+ throw new ArgumentsRequired(this.id + ' setMarginMode() requires a leverage parameter');
5721
+ }
5722
+ const direction = this.safeStringLower2(params, 'direction', 'positionId');
5723
+ const request = {
5724
+ 'leverage': leverage,
5725
+ 'openType': (marginMode === 'isolated') ? 1 : 2,
5726
+ };
5727
+ if (symbol !== undefined) {
5728
+ request['symbol'] = market['id'];
5729
+ }
5730
+ if (direction !== undefined) {
5731
+ request['positionType'] = (direction === 'short') ? 2 : 1;
5732
+ }
5733
+ params = this.omit(params, 'direction');
5734
+ const response = await this.contractPrivatePostPositionChangeLeverage(this.extend(request, params));
5735
+ //
5736
+ // { success: true, code: '0' }
5737
+ //
5738
+ return this.parseLeverage(response, market);
5739
+ }
5656
5740
  nonce() {
5657
5741
  return this.milliseconds() - this.safeInteger(this.options, 'timeDifference', 0);
5658
5742
  }
@@ -14,6 +14,9 @@ export default class bitget extends bitgetRest {
14
14
  watchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
15
15
  handleTicker(client: Client, message: any): void;
16
16
  parseWsTicker(message: any, market?: any): Ticker;
17
+ watchBidsAsks(symbols?: Strings, params?: {}): Promise<Tickers>;
18
+ handleBidAsk(client: Client, message: any): void;
19
+ parseWsBidAsk(message: any, market?: any): Ticker;
17
20
  watchOHLCV(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<OHLCV[]>;
18
21
  unWatchOHLCV(symbol: string, timeframe?: string, params?: {}): Promise<any>;
19
22
  handleOHLCV(client: Client, message: any): void;
@@ -37,6 +37,7 @@ export default class bitget extends bitgetRest {
37
37
  'watchOrders': true,
38
38
  'watchTicker': true,
39
39
  'watchTickers': true,
40
+ 'watchBidsAsks': true,
40
41
  'watchTrades': true,
41
42
  'watchTradesForSymbols': true,
42
43
  'watchPositions': true,
@@ -215,6 +216,7 @@ export default class bitget extends bitgetRest {
215
216
  // "ts": 1701842994341
216
217
  // }
217
218
  //
219
+ this.handleBidAsk(client, message);
218
220
  const ticker = this.parseWsTicker(message);
219
221
  const symbol = ticker['symbol'];
220
222
  this.tickers[symbol] = ticker;
@@ -326,6 +328,70 @@ export default class bitget extends bitgetRest {
326
328
  'info': ticker,
327
329
  }, market);
328
330
  }
331
+ async watchBidsAsks(symbols = undefined, params = {}) {
332
+ /**
333
+ * @method
334
+ * @name bitget#watchBidsAsks
335
+ * @see https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
336
+ * @see https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
337
+ * @description watches best bid & ask for symbols
338
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
339
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
340
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
341
+ */
342
+ await this.loadMarkets();
343
+ symbols = this.marketSymbols(symbols, undefined, false);
344
+ const market = this.market(symbols[0]);
345
+ let instType = undefined;
346
+ [instType, params] = this.getInstType(market, params);
347
+ const topics = [];
348
+ const messageHashes = [];
349
+ for (let i = 0; i < symbols.length; i++) {
350
+ const symbol = symbols[i];
351
+ const marketInner = this.market(symbol);
352
+ const args = {
353
+ 'instType': instType,
354
+ 'channel': 'ticker',
355
+ 'instId': marketInner['id'],
356
+ };
357
+ topics.push(args);
358
+ messageHashes.push('bidask:' + symbol);
359
+ }
360
+ const tickers = await this.watchPublicMultiple(messageHashes, topics, params);
361
+ if (this.newUpdates) {
362
+ const result = {};
363
+ result[tickers['symbol']] = tickers;
364
+ return result;
365
+ }
366
+ return this.filterByArray(this.bidsasks, 'symbol', symbols);
367
+ }
368
+ handleBidAsk(client, message) {
369
+ const ticker = this.parseWsBidAsk(message);
370
+ const symbol = ticker['symbol'];
371
+ this.bidsasks[symbol] = ticker;
372
+ const messageHash = 'bidask:' + symbol;
373
+ client.resolve(ticker, messageHash);
374
+ }
375
+ parseWsBidAsk(message, market = undefined) {
376
+ const arg = this.safeValue(message, 'arg', {});
377
+ const data = this.safeValue(message, 'data', []);
378
+ const ticker = this.safeValue(data, 0, {});
379
+ const timestamp = this.safeInteger(ticker, 'ts');
380
+ const instType = this.safeString(arg, 'instType');
381
+ const marketType = (instType === 'SPOT') ? 'spot' : 'contract';
382
+ const marketId = this.safeString(ticker, 'instId');
383
+ market = this.safeMarket(marketId, market, undefined, marketType);
384
+ return this.safeTicker({
385
+ 'symbol': market['symbol'],
386
+ 'timestamp': timestamp,
387
+ 'datetime': this.iso8601(timestamp),
388
+ 'ask': this.safeString(ticker, 'askPr'),
389
+ 'askVolume': this.safeString(ticker, 'askSz'),
390
+ 'bid': this.safeString(ticker, 'bidPr'),
391
+ 'bidVolume': this.safeString(ticker, 'bidSz'),
392
+ 'info': ticker,
393
+ }, market);
394
+ }
329
395
  async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
330
396
  /**
331
397
  * @method
@@ -52,6 +52,7 @@ export default class okx extends okxRest {
52
52
  watchOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
53
53
  handleOrders(client: Client, message: any, subscription?: any): void;
54
54
  handleMyTrades(client: Client, message: any): void;
55
+ requestId(): string;
55
56
  createOrderWs(symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, params?: {}): Promise<Order>;
56
57
  handlePlaceOrders(client: Client, message: any): void;
57
58
  editOrderWs(id: string, symbol: string, type: OrderType, side: OrderSide, amount?: Num, price?: Num, params?: {}): Promise<Order>;
package/js/src/pro/okx.js CHANGED
@@ -1957,6 +1957,12 @@ export default class okx extends okxRest {
1957
1957
  client.resolve(this.orders, symbolMessageHash);
1958
1958
  }
1959
1959
  }
1960
+ requestId() {
1961
+ const ts = this.milliseconds().toString();
1962
+ const randomNumber = this.randNumber(4);
1963
+ const randomPart = randomNumber.toString();
1964
+ return ts + randomPart;
1965
+ }
1960
1966
  async createOrderWs(symbol, type, side, amount, price = undefined, params = {}) {
1961
1967
  /**
1962
1968
  * @method
@@ -1975,7 +1981,7 @@ export default class okx extends okxRest {
1975
1981
  await this.loadMarkets();
1976
1982
  await this.authenticate();
1977
1983
  const url = this.getUrl('private', 'private');
1978
- const messageHash = this.milliseconds().toString();
1984
+ const messageHash = this.requestId();
1979
1985
  let op = undefined;
1980
1986
  [op, params] = this.handleOptionAndParams(params, 'createOrderWs', 'op', 'batch-orders');
1981
1987
  const args = this.createOrderRequest(symbol, type, side, amount, price, params);
@@ -2045,7 +2051,7 @@ export default class okx extends okxRest {
2045
2051
  await this.loadMarkets();
2046
2052
  await this.authenticate();
2047
2053
  const url = this.getUrl('private', 'private');
2048
- const messageHash = this.milliseconds().toString();
2054
+ const messageHash = this.requestId();
2049
2055
  let op = undefined;
2050
2056
  [op, params] = this.handleOptionAndParams(params, 'editOrderWs', 'op', 'amend-order');
2051
2057
  const args = this.editOrderRequest(id, symbol, type, side, amount, price, params);
@@ -2074,7 +2080,7 @@ export default class okx extends okxRest {
2074
2080
  await this.loadMarkets();
2075
2081
  await this.authenticate();
2076
2082
  const url = this.getUrl('private', 'private');
2077
- const messageHash = this.milliseconds().toString();
2083
+ const messageHash = this.requestId();
2078
2084
  const clientOrderId = this.safeString2(params, 'clOrdId', 'clientOrderId');
2079
2085
  params = this.omit(params, ['clientOrderId', 'clOrdId']);
2080
2086
  const arg = {
@@ -2114,7 +2120,7 @@ export default class okx extends okxRest {
2114
2120
  await this.loadMarkets();
2115
2121
  await this.authenticate();
2116
2122
  const url = this.getUrl('private', 'private');
2117
- const messageHash = this.milliseconds().toString();
2123
+ const messageHash = this.requestId();
2118
2124
  const args = [];
2119
2125
  for (let i = 0; i < idsLength; i++) {
2120
2126
  const arg = {
@@ -2150,7 +2156,7 @@ export default class okx extends okxRest {
2150
2156
  throw new BadRequest(this.id + 'cancelAllOrdersWs is only applicable to Option in Portfolio Margin mode, and MMP privilege is required.');
2151
2157
  }
2152
2158
  const url = this.getUrl('private', 'private');
2153
- const messageHash = this.milliseconds().toString();
2159
+ const messageHash = this.requestId();
2154
2160
  const request = {
2155
2161
  'id': messageHash,
2156
2162
  'op': 'mass-cancel',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.4.6",
3
+ "version": "4.4.7",
4
4
  "description": "A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges",
5
5
  "unpkg": "dist/ccxt.browser.min.js",
6
6
  "type": "module",