ccxt 4.3.27 → 4.3.28

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/README.md CHANGED
@@ -215,13 +215,13 @@ console.log(version, Object.keys(exchanges));
215
215
 
216
216
  All-in-one browser bundle (dependencies included), served from a CDN of your choice:
217
217
 
218
- * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.27/dist/ccxt.browser.js
219
- * unpkg: https://unpkg.com/ccxt@4.3.27/dist/ccxt.browser.js
218
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.28/dist/ccxt.browser.js
219
+ * unpkg: https://unpkg.com/ccxt@4.3.28/dist/ccxt.browser.js
220
220
 
221
221
  CDNs are not updated in real-time and may have delays. Defaulting to the most recent version without specifying the version number is not recommended. Please, keep in mind that we are not responsible for the correct operation of those CDN servers.
222
222
 
223
223
  ```HTML
224
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.27/dist/ccxt.browser.js"></script>
224
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.28/dist/ccxt.browser.js"></script>
225
225
  ```
226
226
 
227
227
  Creates a global `ccxt` object:
package/dist/cjs/ccxt.js CHANGED
@@ -185,7 +185,7 @@ var woofipro$1 = require('./src/pro/woofipro.js');
185
185
 
186
186
  //-----------------------------------------------------------------------------
187
187
  // this is updated by vss.js when building
188
- const version = '4.3.27';
188
+ const version = '4.3.28';
189
189
  Exchange["default"].ccxtVersion = version;
190
190
  const exchanges = {
191
191
  'ace': ace,
@@ -1403,7 +1403,7 @@ class ascendex extends ascendex$1 {
1403
1403
  'currency': feeCurrencyCode,
1404
1404
  };
1405
1405
  }
1406
- const stopPrice = this.safeNumber(order, 'stopPrice');
1406
+ const stopPrice = this.omitZero(this.safeString(order, 'stopPrice'));
1407
1407
  let reduceOnly = undefined;
1408
1408
  const execInst = this.safeString(order, 'execInst');
1409
1409
  if (execInst === 'reduceOnly') {
@@ -2506,6 +2506,7 @@ class Exchange {
2506
2506
  const shouldParseFees = parseFee || parseFees;
2507
2507
  const fees = this.safeList(order, 'fees', []);
2508
2508
  let trades = [];
2509
+ const isTriggerOrSLTpOrder = ((this.safeString(order, 'triggerPrice') !== undefined || (this.safeString(order, 'stopLossPrice') !== undefined)) || (this.safeString(order, 'takeProfitPrice') !== undefined));
2509
2510
  if (parseFilled || parseCost || shouldParseFees) {
2510
2511
  const rawTrades = this.safeValue(order, 'trades', trades);
2511
2512
  const oldNumber = this.number;
@@ -2708,7 +2709,7 @@ class Exchange {
2708
2709
  let postOnly = this.safeValue(order, 'postOnly');
2709
2710
  // timeInForceHandling
2710
2711
  if (timeInForce === undefined) {
2711
- if (this.safeString(order, 'type') === 'market') {
2712
+ if (!isTriggerOrSLTpOrder && (this.safeString(order, 'type') === 'market')) {
2712
2713
  timeInForce = 'IOC';
2713
2714
  }
2714
2715
  // allow postOnly override
@@ -2214,6 +2214,10 @@ class bingx extends bingx$1 {
2214
2214
  const types = {
2215
2215
  'trigger_market': 'market',
2216
2216
  'trigger_limit': 'limit',
2217
+ 'stop_limit': 'limit',
2218
+ 'stop_market': 'market',
2219
+ 'take_profit_market': 'market',
2220
+ 'stop': 'limit',
2217
2221
  };
2218
2222
  return this.safeString(types, type, type);
2219
2223
  }
@@ -2417,6 +2421,25 @@ class bingx extends bingx$1 {
2417
2421
  // side: 'SELL'
2418
2422
  // }
2419
2423
  // }
2424
+ // stop loss order
2425
+ // {
2426
+ // "symbol": "ETH-USDT",
2427
+ // "orderId": "1792461744476422144",
2428
+ // "price": "2775.65",
2429
+ // "StopPrice": "2778.42",
2430
+ // "origQty": "0.032359",
2431
+ // "executedQty": "0",
2432
+ // "cummulativeQuoteQty": "0",
2433
+ // "status": "NEW",
2434
+ // "type": "TAKE_STOP_LIMIT",
2435
+ // "side": "SELL",
2436
+ // "time": "1716191156868",
2437
+ // "updateTime": "1716191156868",
2438
+ // "origQuoteOrderQty": "0",
2439
+ // "fee": "0",
2440
+ // "feeAsset": "USDT",
2441
+ // "clientOrderID": ""
2442
+ // }
2420
2443
  //
2421
2444
  const info = order;
2422
2445
  const newOrder = this.safeDict2(order, 'newOrderResponse', 'orderOpenResponse');
@@ -2451,26 +2474,39 @@ class bingx extends bingx$1 {
2451
2474
  let stopLoss = this.safeValue(order, 'stopLoss');
2452
2475
  let stopLossPrice = undefined;
2453
2476
  if ((stopLoss !== undefined) && (stopLoss !== '')) {
2454
- stopLossPrice = this.safeNumber(stopLoss, 'stopLoss');
2477
+ stopLossPrice = this.omitZero(this.safeString(stopLoss, 'stopLoss'));
2455
2478
  }
2456
2479
  if ((stopLoss !== undefined) && (typeof stopLoss !== 'number') && (stopLoss !== '')) {
2457
2480
  // stopLoss: '{"stopPrice":50,"workingType":"MARK_PRICE","type":"STOP_MARKET","quantity":1}',
2458
2481
  if (typeof stopLoss === 'string') {
2459
2482
  stopLoss = this.parseJson(stopLoss);
2460
2483
  }
2461
- stopLossPrice = this.safeNumber(stopLoss, 'stopPrice');
2484
+ stopLossPrice = this.omitZero(this.safeString(stopLoss, 'stopPrice'));
2462
2485
  }
2463
2486
  let takeProfit = this.safeValue(order, 'takeProfit');
2464
2487
  let takeProfitPrice = undefined;
2465
2488
  if (takeProfit !== undefined && (takeProfit !== '')) {
2466
- takeProfitPrice = this.safeNumber(takeProfit, 'takeProfit');
2489
+ takeProfitPrice = this.omitZero(this.safeString(takeProfit, 'takeProfit'));
2467
2490
  }
2468
2491
  if ((takeProfit !== undefined) && (typeof takeProfit !== 'number') && (takeProfit !== '')) {
2469
2492
  // takeProfit: '{"stopPrice":150,"workingType":"MARK_PRICE","type":"TAKE_PROFIT_MARKET","quantity":1}',
2470
2493
  if (typeof takeProfit === 'string') {
2471
2494
  takeProfit = this.parseJson(takeProfit);
2472
2495
  }
2473
- takeProfitPrice = this.safeNumber(takeProfit, 'stopPrice');
2496
+ takeProfitPrice = this.omitZero(this.safeString(takeProfit, 'stopPrice'));
2497
+ }
2498
+ const rawType = this.safeStringLower2(order, 'type', 'o');
2499
+ const stopPrice = this.omitZero(this.safeString2(order, 'StopPrice', 'stopPrice'));
2500
+ let triggerPrice = stopPrice;
2501
+ if (stopPrice !== undefined) {
2502
+ if ((rawType.indexOf('stop') > -1) && (stopLossPrice === undefined)) {
2503
+ stopLossPrice = stopPrice;
2504
+ triggerPrice = undefined;
2505
+ }
2506
+ if ((rawType.indexOf('take') > -1) && (takeProfitPrice === undefined)) {
2507
+ takeProfitPrice = stopPrice;
2508
+ triggerPrice = undefined;
2509
+ }
2474
2510
  }
2475
2511
  return this.safeOrder({
2476
2512
  'info': info,
@@ -2481,13 +2517,13 @@ class bingx extends bingx$1 {
2481
2517
  'datetime': this.iso8601(timestamp),
2482
2518
  'lastTradeTimestamp': lastTradeTimestamp,
2483
2519
  'lastUpdateTimestamp': this.safeInteger(order, 'updateTime'),
2484
- 'type': this.parseOrderType(this.safeStringLower2(order, 'type', 'o')),
2520
+ 'type': this.parseOrderType(rawType),
2485
2521
  'timeInForce': this.safeString(order, 'timeInForce'),
2486
2522
  'postOnly': undefined,
2487
2523
  'side': this.parseOrderSide(side),
2488
2524
  'price': this.safeString2(order, 'price', 'p'),
2489
- 'stopPrice': this.safeNumber(order, 'stopPrice'),
2490
- 'triggerPrice': this.safeNumber(order, 'stopPrice'),
2525
+ 'stopPrice': triggerPrice,
2526
+ 'triggerPrice': triggerPrice,
2491
2527
  'stopLossPrice': stopLossPrice,
2492
2528
  'takeProfitPrice': takeProfitPrice,
2493
2529
  'average': this.safeString2(order, 'avgPrice', 'ap'),
@@ -757,6 +757,7 @@ class bitget extends bitget$1 {
757
757
  'v2/earn/loan/borrow-history': 2,
758
758
  'v2/earn/loan/debts': 2,
759
759
  'v2/earn/loan/reduces': 2,
760
+ 'v2/earn/account/assets': 2,
760
761
  },
761
762
  'post': {
762
763
  'v2/earn/savings/subscribe': 2,
@@ -35,7 +35,7 @@ class bitmart extends bitmart$1 {
35
35
  'borrowIsolatedMargin': true,
36
36
  'cancelAllOrders': true,
37
37
  'cancelOrder': true,
38
- 'cancelOrders': false,
38
+ 'cancelOrders': true,
39
39
  'createMarketBuyOrderWithCost': true,
40
40
  'createMarketOrderWithCost': false,
41
41
  'createMarketSellOrderWithCost': false,
@@ -179,7 +179,7 @@ class bitmart extends bitmart$1 {
179
179
  'spot/v2/orders': 5,
180
180
  'spot/v1/trades': 5,
181
181
  // newer order endpoint
182
- 'spot/v2/trades': 5,
182
+ 'spot/v2/trades': 4,
183
183
  'spot/v3/orders': 5,
184
184
  'spot/v2/order_detail': 1,
185
185
  // margin
@@ -223,6 +223,7 @@ class bitmart extends bitmart$1 {
223
223
  'spot/v4/query/history-orders': 5,
224
224
  'spot/v4/query/trades': 5,
225
225
  'spot/v4/query/order-trades': 5,
226
+ 'spot/v4/cancel_orders': 3,
226
227
  // newer endpoint
227
228
  'spot/v3/cancel_order': 1,
228
229
  'spot/v2/batch_orders': 1,
@@ -2672,6 +2673,68 @@ class bitmart extends bitmart$1 {
2672
2673
  const order = this.parseOrder(id, market);
2673
2674
  return this.extend(order, { 'id': id });
2674
2675
  }
2676
+ async cancelOrders(ids, symbol = undefined, params = {}) {
2677
+ /**
2678
+ * @method
2679
+ * @name bitmart#cancelOrders
2680
+ * @description cancel multiple orders
2681
+ * @see https://developer-pro.bitmart.com/en/spot/#cancel-batch-order-v4-signed
2682
+ * @param {string[]} ids order ids
2683
+ * @param {string} symbol unified symbol of the market the order was made in
2684
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2685
+ * @param {string[]} [params.clientOrderIds] client order ids
2686
+ * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2687
+ */
2688
+ if (symbol === undefined) {
2689
+ throw new errors.ArgumentsRequired(this.id + ' cancelOrders() requires a symbol argument');
2690
+ }
2691
+ await this.loadMarkets();
2692
+ const market = this.market(symbol);
2693
+ if (!market['spot']) {
2694
+ throw new errors.NotSupported(this.id + ' cancelOrders() does not support ' + market['type'] + ' orders, only spot orders are accepted');
2695
+ }
2696
+ const clientOrderIds = this.safeList(params, 'clientOrderIds');
2697
+ params = this.omit(params, ['clientOrderIds']);
2698
+ const request = {
2699
+ 'symbol': market['id'],
2700
+ };
2701
+ if (clientOrderIds !== undefined) {
2702
+ request['clientOrderIds'] = clientOrderIds;
2703
+ }
2704
+ else {
2705
+ request['orderIds'] = ids;
2706
+ }
2707
+ const response = await this.privatePostSpotV4CancelOrders(this.extend(request, params));
2708
+ //
2709
+ // {
2710
+ // "message": "OK",
2711
+ // "code": 1000,
2712
+ // "trace": "c4edbce860164203954f7c3c81d60fc6.309.17022669632770001",
2713
+ // "data": {
2714
+ // "successIds": [
2715
+ // "213055379155243012"
2716
+ // ],
2717
+ // "failIds": [],
2718
+ // "totalCount": 1,
2719
+ // "successCount": 1,
2720
+ // "failedCount": 0
2721
+ // }
2722
+ // }
2723
+ //
2724
+ const data = this.safeDict(response, 'data', {});
2725
+ const allOrders = [];
2726
+ const successIds = this.safeList(data, 'successIds', []);
2727
+ for (let i = 0; i < successIds.length; i++) {
2728
+ const id = successIds[i];
2729
+ allOrders.push(this.safeOrder({ 'id': id, 'status': 'canceled' }, market));
2730
+ }
2731
+ const failIds = this.safeList(data, 'failIds', []);
2732
+ for (let i = 0; i < failIds.length; i++) {
2733
+ const id = failIds[i];
2734
+ allOrders.push(this.safeOrder({ 'id': id, 'status': 'failed' }, market));
2735
+ }
2736
+ return allOrders;
2737
+ }
2675
2738
  async cancelAllOrders(symbol = undefined, params = {}) {
2676
2739
  /**
2677
2740
  * @method
@@ -2486,14 +2486,14 @@ class bybit extends bybit$1 {
2486
2486
  throw new errors.ArgumentsRequired(this.id + ' fetchFundingRateHistory() requires a symbol argument');
2487
2487
  }
2488
2488
  await this.loadMarkets();
2489
- if (limit === undefined) {
2490
- limit = 200;
2491
- }
2492
2489
  let paginate = false;
2493
2490
  [paginate, params] = this.handleOptionAndParams(params, 'fetchFundingRateHistory', 'paginate');
2494
2491
  if (paginate) {
2495
2492
  return await this.fetchPaginatedCallDeterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params, 200);
2496
2493
  }
2494
+ if (limit === undefined) {
2495
+ limit = 200;
2496
+ }
2497
2497
  const request = {
2498
2498
  // 'category': '', // Product type. linear,inverse
2499
2499
  // 'symbol': '', // Symbol name
@@ -2978,7 +2978,7 @@ class coinbase extends coinbase$1 {
2978
2978
  const marketId = this.safeString(order, 'product_id');
2979
2979
  const symbol = this.safeSymbol(marketId, market, '-');
2980
2980
  if (symbol !== undefined) {
2981
- market = this.market(symbol);
2981
+ market = this.safeMarket(symbol, market);
2982
2982
  }
2983
2983
  const orderConfiguration = this.safeDict(order, 'order_configuration', {});
2984
2984
  const limitGTC = this.safeDict(orderConfiguration, 'limit_limit_gtc');
@@ -2237,7 +2237,7 @@ class krakenfutures extends krakenfutures$1 {
2237
2237
  /**
2238
2238
  * @method
2239
2239
  * @name krakenfutures#fetchPositions
2240
- * @see https://docs.futures.kraken.com/#websocket-api-private-feeds-open-positions
2240
+ * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-account-information-get-open-positions
2241
2241
  * @description Fetches current contract trading positions
2242
2242
  * @param {string[]} symbols List of unified symbols
2243
2243
  * @param {object} [params] Not used by krakenfutures
@@ -246,13 +246,17 @@ class coinbase extends coinbase$1 {
246
246
  //
247
247
  const channel = this.safeString(message, 'channel');
248
248
  const events = this.safeValue(message, 'events', []);
249
+ const datetime = this.safeString(message, 'timestamp');
250
+ const timestamp = this.parse8601(datetime);
249
251
  const newTickers = [];
250
252
  for (let i = 0; i < events.length; i++) {
251
253
  const tickersObj = events[i];
252
- const tickers = this.safeValue(tickersObj, 'tickers', []);
254
+ const tickers = this.safeList(tickersObj, 'tickers', []);
253
255
  for (let j = 0; j < tickers.length; j++) {
254
256
  const ticker = tickers[j];
255
257
  const result = this.parseWsTicker(ticker);
258
+ result['timestamp'] = timestamp;
259
+ result['datetime'] = datetime;
256
260
  const symbol = result['symbol'];
257
261
  this.tickers[symbol] = result;
258
262
  const wsMarketId = this.safeString(ticker, 'product_id');
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 { Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax, Position, FundingRateHistory, Liquidation, FundingHistory, MarginMode, Greeks, Leverage, Leverages, Option, OptionChain, Conversion } 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.26";
7
+ declare const version = "4.3.27";
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.27';
41
+ const version = '4.3.28';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import ace from './src/ace.js';
@@ -497,6 +497,7 @@ interface Exchange {
497
497
  privateEarnGetV2EarnLoanBorrowHistory(params?: {}): Promise<implicitReturnType>;
498
498
  privateEarnGetV2EarnLoanDebts(params?: {}): Promise<implicitReturnType>;
499
499
  privateEarnGetV2EarnLoanReduces(params?: {}): Promise<implicitReturnType>;
500
+ privateEarnGetV2EarnAccountAssets(params?: {}): Promise<implicitReturnType>;
500
501
  privateEarnPostV2EarnSavingsSubscribe(params?: {}): Promise<implicitReturnType>;
501
502
  privateEarnPostV2EarnSavingsRedeem(params?: {}): Promise<implicitReturnType>;
502
503
  privateEarnPostV2EarnSharkfinSubscribe(params?: {}): Promise<implicitReturnType>;
@@ -79,6 +79,7 @@ interface Exchange {
79
79
  privatePostSpotV4QueryHistoryOrders(params?: {}): Promise<implicitReturnType>;
80
80
  privatePostSpotV4QueryTrades(params?: {}): Promise<implicitReturnType>;
81
81
  privatePostSpotV4QueryOrderTrades(params?: {}): Promise<implicitReturnType>;
82
+ privatePostSpotV4CancelOrders(params?: {}): Promise<implicitReturnType>;
82
83
  privatePostSpotV3CancelOrder(params?: {}): Promise<implicitReturnType>;
83
84
  privatePostSpotV2BatchOrders(params?: {}): Promise<implicitReturnType>;
84
85
  privatePostSpotV2SubmitOrder(params?: {}): Promise<implicitReturnType>;
@@ -1406,7 +1406,7 @@ export default class ascendex extends Exchange {
1406
1406
  'currency': feeCurrencyCode,
1407
1407
  };
1408
1408
  }
1409
- const stopPrice = this.safeNumber(order, 'stopPrice');
1409
+ const stopPrice = this.omitZero(this.safeString(order, 'stopPrice'));
1410
1410
  let reduceOnly = undefined;
1411
1411
  const execInst = this.safeString(order, 'execInst');
1412
1412
  if (execInst === 'reduceOnly') {
@@ -2493,6 +2493,7 @@ export default class Exchange {
2493
2493
  const shouldParseFees = parseFee || parseFees;
2494
2494
  const fees = this.safeList(order, 'fees', []);
2495
2495
  let trades = [];
2496
+ const isTriggerOrSLTpOrder = ((this.safeString(order, 'triggerPrice') !== undefined || (this.safeString(order, 'stopLossPrice') !== undefined)) || (this.safeString(order, 'takeProfitPrice') !== undefined));
2496
2497
  if (parseFilled || parseCost || shouldParseFees) {
2497
2498
  const rawTrades = this.safeValue(order, 'trades', trades);
2498
2499
  const oldNumber = this.number;
@@ -2695,7 +2696,7 @@ export default class Exchange {
2695
2696
  let postOnly = this.safeValue(order, 'postOnly');
2696
2697
  // timeInForceHandling
2697
2698
  if (timeInForce === undefined) {
2698
- if (this.safeString(order, 'type') === 'market') {
2699
+ if (!isTriggerOrSLTpOrder && (this.safeString(order, 'type') === 'market')) {
2699
2700
  timeInForce = 'IOC';
2700
2701
  }
2701
2702
  // allow postOnly override
package/js/src/bingx.js CHANGED
@@ -2217,6 +2217,10 @@ export default class bingx extends Exchange {
2217
2217
  const types = {
2218
2218
  'trigger_market': 'market',
2219
2219
  'trigger_limit': 'limit',
2220
+ 'stop_limit': 'limit',
2221
+ 'stop_market': 'market',
2222
+ 'take_profit_market': 'market',
2223
+ 'stop': 'limit',
2220
2224
  };
2221
2225
  return this.safeString(types, type, type);
2222
2226
  }
@@ -2420,6 +2424,25 @@ export default class bingx extends Exchange {
2420
2424
  // side: 'SELL'
2421
2425
  // }
2422
2426
  // }
2427
+ // stop loss order
2428
+ // {
2429
+ // "symbol": "ETH-USDT",
2430
+ // "orderId": "1792461744476422144",
2431
+ // "price": "2775.65",
2432
+ // "StopPrice": "2778.42",
2433
+ // "origQty": "0.032359",
2434
+ // "executedQty": "0",
2435
+ // "cummulativeQuoteQty": "0",
2436
+ // "status": "NEW",
2437
+ // "type": "TAKE_STOP_LIMIT",
2438
+ // "side": "SELL",
2439
+ // "time": "1716191156868",
2440
+ // "updateTime": "1716191156868",
2441
+ // "origQuoteOrderQty": "0",
2442
+ // "fee": "0",
2443
+ // "feeAsset": "USDT",
2444
+ // "clientOrderID": ""
2445
+ // }
2423
2446
  //
2424
2447
  const info = order;
2425
2448
  const newOrder = this.safeDict2(order, 'newOrderResponse', 'orderOpenResponse');
@@ -2454,26 +2477,39 @@ export default class bingx extends Exchange {
2454
2477
  let stopLoss = this.safeValue(order, 'stopLoss');
2455
2478
  let stopLossPrice = undefined;
2456
2479
  if ((stopLoss !== undefined) && (stopLoss !== '')) {
2457
- stopLossPrice = this.safeNumber(stopLoss, 'stopLoss');
2480
+ stopLossPrice = this.omitZero(this.safeString(stopLoss, 'stopLoss'));
2458
2481
  }
2459
2482
  if ((stopLoss !== undefined) && (typeof stopLoss !== 'number') && (stopLoss !== '')) {
2460
2483
  // stopLoss: '{"stopPrice":50,"workingType":"MARK_PRICE","type":"STOP_MARKET","quantity":1}',
2461
2484
  if (typeof stopLoss === 'string') {
2462
2485
  stopLoss = this.parseJson(stopLoss);
2463
2486
  }
2464
- stopLossPrice = this.safeNumber(stopLoss, 'stopPrice');
2487
+ stopLossPrice = this.omitZero(this.safeString(stopLoss, 'stopPrice'));
2465
2488
  }
2466
2489
  let takeProfit = this.safeValue(order, 'takeProfit');
2467
2490
  let takeProfitPrice = undefined;
2468
2491
  if (takeProfit !== undefined && (takeProfit !== '')) {
2469
- takeProfitPrice = this.safeNumber(takeProfit, 'takeProfit');
2492
+ takeProfitPrice = this.omitZero(this.safeString(takeProfit, 'takeProfit'));
2470
2493
  }
2471
2494
  if ((takeProfit !== undefined) && (typeof takeProfit !== 'number') && (takeProfit !== '')) {
2472
2495
  // takeProfit: '{"stopPrice":150,"workingType":"MARK_PRICE","type":"TAKE_PROFIT_MARKET","quantity":1}',
2473
2496
  if (typeof takeProfit === 'string') {
2474
2497
  takeProfit = this.parseJson(takeProfit);
2475
2498
  }
2476
- takeProfitPrice = this.safeNumber(takeProfit, 'stopPrice');
2499
+ takeProfitPrice = this.omitZero(this.safeString(takeProfit, 'stopPrice'));
2500
+ }
2501
+ const rawType = this.safeStringLower2(order, 'type', 'o');
2502
+ const stopPrice = this.omitZero(this.safeString2(order, 'StopPrice', 'stopPrice'));
2503
+ let triggerPrice = stopPrice;
2504
+ if (stopPrice !== undefined) {
2505
+ if ((rawType.indexOf('stop') > -1) && (stopLossPrice === undefined)) {
2506
+ stopLossPrice = stopPrice;
2507
+ triggerPrice = undefined;
2508
+ }
2509
+ if ((rawType.indexOf('take') > -1) && (takeProfitPrice === undefined)) {
2510
+ takeProfitPrice = stopPrice;
2511
+ triggerPrice = undefined;
2512
+ }
2477
2513
  }
2478
2514
  return this.safeOrder({
2479
2515
  'info': info,
@@ -2484,13 +2520,13 @@ export default class bingx extends Exchange {
2484
2520
  'datetime': this.iso8601(timestamp),
2485
2521
  'lastTradeTimestamp': lastTradeTimestamp,
2486
2522
  'lastUpdateTimestamp': this.safeInteger(order, 'updateTime'),
2487
- 'type': this.parseOrderType(this.safeStringLower2(order, 'type', 'o')),
2523
+ 'type': this.parseOrderType(rawType),
2488
2524
  'timeInForce': this.safeString(order, 'timeInForce'),
2489
2525
  'postOnly': undefined,
2490
2526
  'side': this.parseOrderSide(side),
2491
2527
  'price': this.safeString2(order, 'price', 'p'),
2492
- 'stopPrice': this.safeNumber(order, 'stopPrice'),
2493
- 'triggerPrice': this.safeNumber(order, 'stopPrice'),
2528
+ 'stopPrice': triggerPrice,
2529
+ 'triggerPrice': triggerPrice,
2494
2530
  'stopLossPrice': stopLossPrice,
2495
2531
  'takeProfitPrice': takeProfitPrice,
2496
2532
  'average': this.safeString2(order, 'avgPrice', 'ap'),
package/js/src/bitget.js CHANGED
@@ -760,6 +760,7 @@ export default class bitget extends Exchange {
760
760
  'v2/earn/loan/borrow-history': 2,
761
761
  'v2/earn/loan/debts': 2,
762
762
  'v2/earn/loan/reduces': 2,
763
+ 'v2/earn/account/assets': 2,
763
764
  },
764
765
  'post': {
765
766
  'v2/earn/savings/subscribe': 2,
@@ -59,6 +59,7 @@ export default class bitmart extends Exchange {
59
59
  createSwapOrderRequest(symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, params?: {}): any;
60
60
  createSpotOrderRequest(symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, params?: {}): any;
61
61
  cancelOrder(id: string, symbol?: Str, params?: {}): Promise<any>;
62
+ cancelOrders(ids: string[], symbol?: Str, params?: {}): Promise<any[]>;
62
63
  cancelAllOrders(symbol?: Str, params?: {}): Promise<any>;
63
64
  fetchOrdersByStatus(status: any, symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
64
65
  fetchOpenOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
package/js/src/bitmart.js CHANGED
@@ -38,7 +38,7 @@ export default class bitmart extends Exchange {
38
38
  'borrowIsolatedMargin': true,
39
39
  'cancelAllOrders': true,
40
40
  'cancelOrder': true,
41
- 'cancelOrders': false,
41
+ 'cancelOrders': true,
42
42
  'createMarketBuyOrderWithCost': true,
43
43
  'createMarketOrderWithCost': false,
44
44
  'createMarketSellOrderWithCost': false,
@@ -182,7 +182,7 @@ export default class bitmart extends Exchange {
182
182
  'spot/v2/orders': 5,
183
183
  'spot/v1/trades': 5,
184
184
  // newer order endpoint
185
- 'spot/v2/trades': 5,
185
+ 'spot/v2/trades': 4,
186
186
  'spot/v3/orders': 5,
187
187
  'spot/v2/order_detail': 1,
188
188
  // margin
@@ -226,6 +226,7 @@ export default class bitmart extends Exchange {
226
226
  'spot/v4/query/history-orders': 5,
227
227
  'spot/v4/query/trades': 5,
228
228
  'spot/v4/query/order-trades': 5,
229
+ 'spot/v4/cancel_orders': 3,
229
230
  // newer endpoint
230
231
  'spot/v3/cancel_order': 1,
231
232
  'spot/v2/batch_orders': 1,
@@ -2675,6 +2676,68 @@ export default class bitmart extends Exchange {
2675
2676
  const order = this.parseOrder(id, market);
2676
2677
  return this.extend(order, { 'id': id });
2677
2678
  }
2679
+ async cancelOrders(ids, symbol = undefined, params = {}) {
2680
+ /**
2681
+ * @method
2682
+ * @name bitmart#cancelOrders
2683
+ * @description cancel multiple orders
2684
+ * @see https://developer-pro.bitmart.com/en/spot/#cancel-batch-order-v4-signed
2685
+ * @param {string[]} ids order ids
2686
+ * @param {string} symbol unified symbol of the market the order was made in
2687
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2688
+ * @param {string[]} [params.clientOrderIds] client order ids
2689
+ * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2690
+ */
2691
+ if (symbol === undefined) {
2692
+ throw new ArgumentsRequired(this.id + ' cancelOrders() requires a symbol argument');
2693
+ }
2694
+ await this.loadMarkets();
2695
+ const market = this.market(symbol);
2696
+ if (!market['spot']) {
2697
+ throw new NotSupported(this.id + ' cancelOrders() does not support ' + market['type'] + ' orders, only spot orders are accepted');
2698
+ }
2699
+ const clientOrderIds = this.safeList(params, 'clientOrderIds');
2700
+ params = this.omit(params, ['clientOrderIds']);
2701
+ const request = {
2702
+ 'symbol': market['id'],
2703
+ };
2704
+ if (clientOrderIds !== undefined) {
2705
+ request['clientOrderIds'] = clientOrderIds;
2706
+ }
2707
+ else {
2708
+ request['orderIds'] = ids;
2709
+ }
2710
+ const response = await this.privatePostSpotV4CancelOrders(this.extend(request, params));
2711
+ //
2712
+ // {
2713
+ // "message": "OK",
2714
+ // "code": 1000,
2715
+ // "trace": "c4edbce860164203954f7c3c81d60fc6.309.17022669632770001",
2716
+ // "data": {
2717
+ // "successIds": [
2718
+ // "213055379155243012"
2719
+ // ],
2720
+ // "failIds": [],
2721
+ // "totalCount": 1,
2722
+ // "successCount": 1,
2723
+ // "failedCount": 0
2724
+ // }
2725
+ // }
2726
+ //
2727
+ const data = this.safeDict(response, 'data', {});
2728
+ const allOrders = [];
2729
+ const successIds = this.safeList(data, 'successIds', []);
2730
+ for (let i = 0; i < successIds.length; i++) {
2731
+ const id = successIds[i];
2732
+ allOrders.push(this.safeOrder({ 'id': id, 'status': 'canceled' }, market));
2733
+ }
2734
+ const failIds = this.safeList(data, 'failIds', []);
2735
+ for (let i = 0; i < failIds.length; i++) {
2736
+ const id = failIds[i];
2737
+ allOrders.push(this.safeOrder({ 'id': id, 'status': 'failed' }, market));
2738
+ }
2739
+ return allOrders;
2740
+ }
2678
2741
  async cancelAllOrders(symbol = undefined, params = {}) {
2679
2742
  /**
2680
2743
  * @method
package/js/src/bybit.js CHANGED
@@ -2489,14 +2489,14 @@ export default class bybit extends Exchange {
2489
2489
  throw new ArgumentsRequired(this.id + ' fetchFundingRateHistory() requires a symbol argument');
2490
2490
  }
2491
2491
  await this.loadMarkets();
2492
- if (limit === undefined) {
2493
- limit = 200;
2494
- }
2495
2492
  let paginate = false;
2496
2493
  [paginate, params] = this.handleOptionAndParams(params, 'fetchFundingRateHistory', 'paginate');
2497
2494
  if (paginate) {
2498
2495
  return await this.fetchPaginatedCallDeterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params, 200);
2499
2496
  }
2497
+ if (limit === undefined) {
2498
+ limit = 200;
2499
+ }
2500
2500
  const request = {
2501
2501
  // 'category': '', // Product type. linear,inverse
2502
2502
  // 'symbol': '', // Symbol name
@@ -2981,7 +2981,7 @@ export default class coinbase extends Exchange {
2981
2981
  const marketId = this.safeString(order, 'product_id');
2982
2982
  const symbol = this.safeSymbol(marketId, market, '-');
2983
2983
  if (symbol !== undefined) {
2984
- market = this.market(symbol);
2984
+ market = this.safeMarket(symbol, market);
2985
2985
  }
2986
2986
  const orderConfiguration = this.safeDict(order, 'order_configuration', {});
2987
2987
  const limitGTC = this.safeDict(orderConfiguration, 'limit_limit_gtc');
@@ -2240,7 +2240,7 @@ export default class krakenfutures extends Exchange {
2240
2240
  /**
2241
2241
  * @method
2242
2242
  * @name krakenfutures#fetchPositions
2243
- * @see https://docs.futures.kraken.com/#websocket-api-private-feeds-open-positions
2243
+ * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-account-information-get-open-positions
2244
2244
  * @description Fetches current contract trading positions
2245
2245
  * @param {string[]} symbols List of unified symbols
2246
2246
  * @param {object} [params] Not used by krakenfutures
@@ -249,13 +249,17 @@ export default class coinbase extends coinbaseRest {
249
249
  //
250
250
  const channel = this.safeString(message, 'channel');
251
251
  const events = this.safeValue(message, 'events', []);
252
+ const datetime = this.safeString(message, 'timestamp');
253
+ const timestamp = this.parse8601(datetime);
252
254
  const newTickers = [];
253
255
  for (let i = 0; i < events.length; i++) {
254
256
  const tickersObj = events[i];
255
- const tickers = this.safeValue(tickersObj, 'tickers', []);
257
+ const tickers = this.safeList(tickersObj, 'tickers', []);
256
258
  for (let j = 0; j < tickers.length; j++) {
257
259
  const ticker = tickers[j];
258
260
  const result = this.parseWsTicker(ticker);
261
+ result['timestamp'] = timestamp;
262
+ result['datetime'] = datetime;
259
263
  const symbol = result['symbol'];
260
264
  this.tickers[symbol] = result;
261
265
  const wsMarketId = this.safeString(ticker, 'product_id');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.3.27",
3
+ "version": "4.3.28",
4
4
  "description": "A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges",
5
5
  "unpkg": "dist/ccxt.browser.js",
6
6
  "type": "module",