ccxt 4.2.63 → 4.2.65

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.
Files changed (60) hide show
  1. package/README.md +3 -3
  2. package/build.sh +2 -2
  3. package/dist/ccxt.browser.js +565 -178
  4. package/dist/ccxt.browser.min.js +3 -3
  5. package/dist/cjs/ccxt.js +1 -1
  6. package/dist/cjs/src/base/Exchange.js +12 -0
  7. package/dist/cjs/src/binance.js +33 -12
  8. package/dist/cjs/src/bingx.js +58 -49
  9. package/dist/cjs/src/bitget.js +69 -1
  10. package/dist/cjs/src/bitmex.js +3 -1
  11. package/dist/cjs/src/blofin.js +46 -11
  12. package/dist/cjs/src/btcmarkets.js +12 -0
  13. package/dist/cjs/src/bybit.js +100 -7
  14. package/dist/cjs/src/coinbase.js +12 -2
  15. package/dist/cjs/src/delta.js +95 -1
  16. package/dist/cjs/src/gemini.js +9 -4
  17. package/dist/cjs/src/hitbtc.js +1 -1
  18. package/dist/cjs/src/krakenfutures.js +1 -0
  19. package/dist/cjs/src/kucoin.js +87 -62
  20. package/dist/cjs/src/pro/bitget.js +5 -5
  21. package/dist/cjs/src/pro/coinex.js +4 -4
  22. package/dist/cjs/src/pro/currencycom.js +1 -1
  23. package/dist/cjs/src/pro/lbank.js +1 -1
  24. package/dist/cjs/src/yobit.js +15 -15
  25. package/js/ccxt.d.ts +1 -1
  26. package/js/ccxt.js +1 -1
  27. package/js/src/abstract/blofin.d.ts +1 -0
  28. package/js/src/abstract/krakenfutures.d.ts +1 -0
  29. package/js/src/abstract/kucoin.d.ts +10 -0
  30. package/js/src/abstract/kucoinfutures.d.ts +10 -0
  31. package/js/src/base/Exchange.js +12 -0
  32. package/js/src/binance.d.ts +1 -1
  33. package/js/src/binance.js +33 -12
  34. package/js/src/bingx.js +58 -49
  35. package/js/src/bitget.d.ts +3 -1
  36. package/js/src/bitget.js +69 -1
  37. package/js/src/bitmex.js +3 -1
  38. package/js/src/blofin.d.ts +3 -1
  39. package/js/src/blofin.js +46 -11
  40. package/js/src/btcmarkets.js +12 -0
  41. package/js/src/bybit.d.ts +1 -0
  42. package/js/src/bybit.js +100 -7
  43. package/js/src/coinbase.js +12 -2
  44. package/js/src/delta.d.ts +3 -1
  45. package/js/src/delta.js +95 -1
  46. package/js/src/gate.d.ts +1 -1
  47. package/js/src/gemini.js +9 -4
  48. package/js/src/hitbtc.js +1 -1
  49. package/js/src/krakenfutures.js +1 -0
  50. package/js/src/kucoin.js +87 -62
  51. package/js/src/okx.d.ts +1 -1
  52. package/js/src/pro/bitget.js +5 -5
  53. package/js/src/pro/coinex.js +4 -4
  54. package/js/src/pro/currencycom.d.ts +1 -1
  55. package/js/src/pro/currencycom.js +1 -1
  56. package/js/src/pro/lbank.js +1 -1
  57. package/js/src/woo.d.ts +1 -1
  58. package/js/src/yobit.js +15 -15
  59. package/package.json +2 -2
  60. package/skip-tests.json +47 -22
@@ -917,6 +917,18 @@ export default class btcmarkets extends Exchange {
917
917
  return await this.privateDeleteOrdersId(this.extend(request, params));
918
918
  }
919
919
  calculateFee(symbol, type, side, amount, price, takerOrMaker = 'taker', params = {}) {
920
+ /**
921
+ * @method
922
+ * @description calculates the presumptive fee that would be charged for an order
923
+ * @param {string} symbol unified market symbol
924
+ * @param {string} type not used by btcmarkets.calculateFee
925
+ * @param {string} side not used by btcmarkets.calculateFee
926
+ * @param {float} amount how much you want to trade, in units of the base currency on most exchanges, or number of contracts
927
+ * @param {float} price the price for the order to be filled at, in units of the quote currency
928
+ * @param {string} takerOrMaker 'taker' or 'maker'
929
+ * @param {object} params
930
+ * @returns {object} contains the rate, the percentage multiplied to the order amount to obtain the fee amount, and cost, the total value of the fee in units of the quote currency, for the order
931
+ */
920
932
  const market = this.markets[symbol];
921
933
  let currency = undefined;
922
934
  let cost = undefined;
package/js/src/bybit.d.ts CHANGED
@@ -66,6 +66,7 @@ export default class bybit extends Exchange {
66
66
  editOrder(id: string, symbol: string, type: OrderType, side: OrderSide, amount?: number, price?: number, params?: {}): Promise<Order>;
67
67
  cancelUsdcOrder(id: any, symbol?: Str, params?: {}): Promise<Order>;
68
68
  cancelOrder(id: string, symbol?: Str, params?: {}): Promise<Order>;
69
+ cancelOrders(ids: any, symbol?: Str, params?: {}): Promise<Order[]>;
69
70
  cancelAllUsdcOrders(symbol?: Str, params?: {}): Promise<any>;
70
71
  cancelAllOrders(symbol?: Str, params?: {}): Promise<any>;
71
72
  fetchUsdcOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
package/js/src/bybit.js CHANGED
@@ -3787,8 +3787,8 @@ export default class bybit extends Exchange {
3787
3787
  const market = this.market(symbols[0]);
3788
3788
  let category = undefined;
3789
3789
  [category, params] = this.getBybitType('createOrders', market, params);
3790
- if ((category === 'spot') || (category === 'inverse')) {
3791
- throw new NotSupported(this.id + ' createOrders does not allow spot or inverse orders');
3790
+ if (category === 'inverse') {
3791
+ throw new NotSupported(this.id + ' createOrders does not allow inverse orders');
3792
3792
  }
3793
3793
  const request = {
3794
3794
  'category': category,
@@ -4268,6 +4268,87 @@ export default class bybit extends Exchange {
4268
4268
  const result = this.safeValue(response, 'result', {});
4269
4269
  return this.parseOrder(result, market);
4270
4270
  }
4271
+ async cancelOrders(ids, symbol = undefined, params = {}) {
4272
+ /**
4273
+ * @method
4274
+ * @name bybit#cancelOrders
4275
+ * @description cancel multiple orders
4276
+ * @see https://bybit-exchange.github.io/docs/v5/order/batch-cancel
4277
+ * @param {string[]} ids order ids
4278
+ * @param {string} symbol unified symbol of the market the order was made in
4279
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
4280
+ * @param {string[]} [params.clientOrderIds] client order ids
4281
+ * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
4282
+ */
4283
+ if (symbol === undefined) {
4284
+ throw new ArgumentsRequired(this.id + ' cancelOrders() requires a symbol argument');
4285
+ }
4286
+ await this.loadMarkets();
4287
+ const market = this.market(symbol);
4288
+ let category = undefined;
4289
+ [category, params] = this.getBybitType('cancelOrders', market, params);
4290
+ if (category === 'inverse') {
4291
+ throw new NotSupported(this.id + ' cancelOrders does not allow inverse orders');
4292
+ }
4293
+ const ordersRequests = [];
4294
+ const clientOrderIds = this.safeList2(params, 'clientOrderIds', 'clientOids', []);
4295
+ params = this.omit(params, ['clientOrderIds', 'clientOids']);
4296
+ for (let i = 0; i < clientOrderIds.length; i++) {
4297
+ ordersRequests.push({
4298
+ 'symbol': market['id'],
4299
+ 'orderLinkId': this.safeString(clientOrderIds, i),
4300
+ });
4301
+ }
4302
+ for (let i = 0; i < ids.length; i++) {
4303
+ ordersRequests.push({
4304
+ 'symbol': market['id'],
4305
+ 'orderId': this.safeString(ids, i),
4306
+ });
4307
+ }
4308
+ const request = {
4309
+ 'category': category,
4310
+ 'request': ordersRequests,
4311
+ };
4312
+ const response = await this.privatePostV5OrderCancelBatch(this.extend(request, params));
4313
+ //
4314
+ // {
4315
+ // "retCode": "0",
4316
+ // "retMsg": "OK",
4317
+ // "result": {
4318
+ // "list": [
4319
+ // {
4320
+ // "category": "spot",
4321
+ // "symbol": "BTCUSDT",
4322
+ // "orderId": "1636282505818800896",
4323
+ // "orderLinkId": "1636282505818800897"
4324
+ // },
4325
+ // {
4326
+ // "category": "spot",
4327
+ // "symbol": "BTCUSDT",
4328
+ // "orderId": "1636282505818800898",
4329
+ // "orderLinkId": "1636282505818800899"
4330
+ // }
4331
+ // ]
4332
+ // },
4333
+ // "retExtInfo": {
4334
+ // "list": [
4335
+ // {
4336
+ // "code": "0",
4337
+ // "msg": "OK"
4338
+ // },
4339
+ // {
4340
+ // "code": "0",
4341
+ // "msg": "OK"
4342
+ // }
4343
+ // ]
4344
+ // },
4345
+ // "time": "1709796158501"
4346
+ // }
4347
+ //
4348
+ const result = this.safeDict(response, 'result', {});
4349
+ const row = this.safeList(result, 'list', []);
4350
+ return this.parseOrders(row, market);
4351
+ }
4271
4352
  async cancelAllUsdcOrders(symbol = undefined, params = {}) {
4272
4353
  if (symbol === undefined) {
4273
4354
  throw new ArgumentsRequired(this.id + ' cancelAllUsdcOrders() requires a symbol argument');
@@ -7230,7 +7311,8 @@ export default class bybit extends Exchange {
7230
7311
  // }
7231
7312
  //
7232
7313
  const marketId = this.safeString(fee, 'symbol');
7233
- const symbol = this.safeSymbol(marketId, undefined, undefined, 'contract');
7314
+ const defaultType = (market !== undefined) ? market['type'] : 'contract';
7315
+ const symbol = this.safeSymbol(marketId, market, undefined, defaultType);
7234
7316
  return {
7235
7317
  'info': fee,
7236
7318
  'symbol': symbol,
@@ -7250,12 +7332,23 @@ export default class bybit extends Exchange {
7250
7332
  */
7251
7333
  await this.loadMarkets();
7252
7334
  const market = this.market(symbol);
7253
- if (market['spot']) {
7254
- throw new NotSupported(this.id + ' fetchTradingFee() is not supported for spot market');
7255
- }
7256
7335
  const request = {
7257
7336
  'symbol': market['id'],
7258
7337
  };
7338
+ let category = undefined;
7339
+ if (market['linear']) {
7340
+ category = 'linear';
7341
+ }
7342
+ else if (market['inverse']) {
7343
+ category = 'inverse';
7344
+ }
7345
+ else if (market['spot']) {
7346
+ category = 'spot';
7347
+ }
7348
+ else {
7349
+ category = 'option';
7350
+ }
7351
+ request['category'] = category;
7259
7352
  const response = await this.privateGetV5AccountFeeRate(this.extend(request, params));
7260
7353
  //
7261
7354
  // {
@@ -7277,7 +7370,7 @@ export default class bybit extends Exchange {
7277
7370
  const result = this.safeValue(response, 'result', {});
7278
7371
  const fees = this.safeValue(result, 'list', []);
7279
7372
  const first = this.safeValue(fees, 0, {});
7280
- return this.parseTradingFee(first);
7373
+ return this.parseTradingFee(first, market);
7281
7374
  }
7282
7375
  async fetchTradingFees(params = {}) {
7283
7376
  /**
@@ -3724,7 +3724,8 @@ export default class coinbase extends Exchange {
3724
3724
  sign(path, api = [], method = 'GET', params = {}, headers = undefined, body = undefined) {
3725
3725
  const version = api[0];
3726
3726
  const signed = api[1] === 'private';
3727
- const pathPart = (version === 'v3') ? 'api/v3' : 'v2';
3727
+ const isV3 = version === 'v3';
3728
+ const pathPart = (isV3) ? 'api/v3' : 'v2';
3728
3729
  let fullPath = '/' + pathPart + '/' + this.implodeParams(path, params);
3729
3730
  const query = this.omit(params, this.extractParams(path));
3730
3731
  const savedPath = fullPath;
@@ -3768,8 +3769,17 @@ export default class coinbase extends Exchange {
3768
3769
  payload = body;
3769
3770
  }
3770
3771
  }
3771
- // 'GET' doesn't need payload in the signature. inside url is enough
3772
+ else {
3773
+ if (!isV3) {
3774
+ if (Object.keys(query).length) {
3775
+ payload += '?' + this.urlencode(query);
3776
+ }
3777
+ }
3778
+ }
3779
+ // v3: 'GET' doesn't need payload in the signature. inside url is enough
3772
3780
  // https://docs.cloud.coinbase.com/advanced-trade-api/docs/auth#example-request
3781
+ // v2: 'GET' require payload in the signature
3782
+ // https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-key-authentication
3773
3783
  const auth = timestampString + method + savedPath + payload;
3774
3784
  const signature = this.hmac(this.encode(auth), this.encode(this.secret), sha256);
3775
3785
  headers = {
package/js/src/delta.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import Exchange from './abstract/delta.js';
2
- import type { Balances, Currency, Greeks, Int, Market, MarketInterface, OHLCV, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Position, Leverage } from './base/types.js';
2
+ import type { Balances, Currency, Greeks, Int, Market, MarketInterface, OHLCV, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Position, Leverage, MarginMode } from './base/types.js';
3
3
  /**
4
4
  * @class delta
5
5
  * @augments Exchange
@@ -188,6 +188,8 @@ export default class delta extends Exchange {
188
188
  info: any;
189
189
  };
190
190
  closeAllPositions(params?: {}): Promise<Position[]>;
191
+ fetchMarginMode(symbol: string, params?: {}): Promise<MarginMode>;
192
+ parseMarginMode(marginMode: any, market?: any): MarginMode;
191
193
  sign(path: any, api?: string, method?: string, params?: {}, headers?: any, body?: any): {
192
194
  url: string;
193
195
  method: string;
package/js/src/delta.js CHANGED
@@ -54,7 +54,8 @@ export default class delta extends Exchange {
54
54
  'fetchLedger': true,
55
55
  'fetchLeverage': true,
56
56
  'fetchLeverageTiers': false,
57
- 'fetchMarginMode': false,
57
+ 'fetchMarginMode': true,
58
+ 'fetchMarginModes': false,
58
59
  'fetchMarketLeverageTiers': false,
59
60
  'fetchMarkets': true,
60
61
  'fetchMarkOHLCV': true,
@@ -3204,6 +3205,99 @@ export default class delta extends Exchange {
3204
3205
  const position = this.parsePosition(this.safeValue(response, 'result', {}));
3205
3206
  return [position];
3206
3207
  }
3208
+ async fetchMarginMode(symbol, params = {}) {
3209
+ /**
3210
+ * @method
3211
+ * @name delta#fetchMarginMode
3212
+ * @description fetches the margin mode of a trading pair
3213
+ * @see https://docs.delta.exchange/#get-user
3214
+ * @param {string} symbol unified symbol of the market to fetch the margin mode for
3215
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3216
+ * @returns {object} a [margin mode structure]{@link https://docs.ccxt.com/#/?id=margin-mode-structure}
3217
+ */
3218
+ await this.loadMarkets();
3219
+ let market = undefined;
3220
+ if (symbol !== undefined) {
3221
+ market = this.market(symbol);
3222
+ }
3223
+ const response = await this.privateGetProfile(params);
3224
+ //
3225
+ // {
3226
+ // "result": {
3227
+ // "is_password_set": true,
3228
+ // "kyc_expiry_date": null,
3229
+ // "phishing_code": "12345",
3230
+ // "preferences": {
3231
+ // "favorites": []
3232
+ // },
3233
+ // "is_kyc_provisioned": false,
3234
+ // "country": "Canada",
3235
+ // "margin_mode": "isolated",
3236
+ // "mfa_updated_at": "2023-07-19T01:04:43Z",
3237
+ // "last_name": "",
3238
+ // "oauth_apple_active": false,
3239
+ // "pf_index_symbol": null,
3240
+ // "proof_of_identity_status": "approved",
3241
+ // "dob": null,
3242
+ // "email": "abc_123@gmail.com",
3243
+ // "force_change_password": false,
3244
+ // "nick_name": "still-breeze-123",
3245
+ // "oauth_google_active": false,
3246
+ // "phone_verification_status": "verified",
3247
+ // "id": 12345678,
3248
+ // "last_seen": null,
3249
+ // "is_withdrawal_enabled": true,
3250
+ // "force_change_mfa": false,
3251
+ // "enable_bots": false,
3252
+ // "kyc_verified_on": null,
3253
+ // "created_at": "2023-07-19T01:02:32Z",
3254
+ // "withdrawal_blocked_till": null,
3255
+ // "proof_of_address_status": "approved",
3256
+ // "is_password_change_blocked": false,
3257
+ // "is_mfa_enabled": true,
3258
+ // "is_kyc_done": true,
3259
+ // "oauth": null,
3260
+ // "account_name": "Main",
3261
+ // "sub_account_permissions": null,
3262
+ // "phone_number": null,
3263
+ // "tracking_info": {
3264
+ // "ga_cid": "1234.4321",
3265
+ // "is_kyc_gtm_tracked": true,
3266
+ // "sub_account_config": {
3267
+ // "cross": 2,
3268
+ // "isolated": 2,
3269
+ // "portfolio": 2
3270
+ // }
3271
+ // },
3272
+ // "first_name": "",
3273
+ // "phone_verified_on": null,
3274
+ // "seen_intro": false,
3275
+ // "password_updated_at": null,
3276
+ // "is_login_enabled": true,
3277
+ // "registration_date": "2023-07-19T01:02:32Z",
3278
+ // "permissions": {},
3279
+ // "max_sub_accounts_limit": 2,
3280
+ // "country_calling_code": null,
3281
+ // "is_sub_account": false,
3282
+ // "is_kyc_refresh_required": false
3283
+ // },
3284
+ // "success": true
3285
+ // }
3286
+ //
3287
+ const result = this.safeDict(response, 'result', {});
3288
+ return this.parseMarginMode(result, market);
3289
+ }
3290
+ parseMarginMode(marginMode, market = undefined) {
3291
+ let symbol = undefined;
3292
+ if (market !== undefined) {
3293
+ symbol = market['symbol'];
3294
+ }
3295
+ return {
3296
+ 'info': marginMode,
3297
+ 'symbol': symbol,
3298
+ 'marginMode': this.safeString(marginMode, 'margin_mode'),
3299
+ };
3300
+ }
3207
3301
  sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
3208
3302
  const requestPath = '/' + this.version + '/' + this.implodeParams(path, params);
3209
3303
  let url = this.urls['api'][api] + requestPath;
package/js/src/gate.d.ts CHANGED
@@ -6,7 +6,7 @@ import type { Int, OrderSide, OrderType, OHLCV, Trade, FundingRateHistory, OpenI
6
6
  */
7
7
  export default class gate extends Exchange {
8
8
  describe(): any;
9
- setSandboxMode(enable: any): void;
9
+ setSandboxMode(enable: boolean): void;
10
10
  convertExpireDate(date: any): string;
11
11
  createExpiredOptionMarket(symbol: string): MarketInterface;
12
12
  safeMarket(marketId?: any, market?: any, delimiter?: any, marketType?: any): MarketInterface;
package/js/src/gemini.js CHANGED
@@ -265,12 +265,12 @@ export default class gemini extends Exchange {
265
265
  'webApiEnable': true,
266
266
  'webApiRetries': 10,
267
267
  },
268
+ 'fetchUsdtMarkets': ['btcusdt', 'ethusdt'],
268
269
  'fetchCurrencies': {
269
270
  'webApiEnable': true,
270
271
  'webApiRetries': 5,
271
272
  'webApiMuteFailure': true,
272
273
  },
273
- 'fetchUsdtMarkets': ['btcusdt', 'ethusdt'],
274
274
  'fetchTickerMethod': 'fetchTickerV1',
275
275
  'networks': {
276
276
  'BTC': 'bitcoin',
@@ -409,9 +409,11 @@ export default class gemini extends Exchange {
409
409
  */
410
410
  const method = this.safeValue(this.options, 'fetchMarketsMethod', 'fetch_markets_from_api');
411
411
  if (method === 'fetch_markets_from_web') {
412
- const usdMarkets = await this.fetchMarketsFromWeb(params); // get usd markets
413
- const usdtMarkets = await this.fetchUSDTMarkets(params); // get usdt markets
414
- return this.arrayConcat(usdMarkets, usdtMarkets);
412
+ const promises = [];
413
+ promises.push(this.fetchMarketsFromWeb(params)); // get usd markets
414
+ promises.push(this.fetchUSDTMarkets(params)); // get usdt markets
415
+ const promisesResult = await Promise.all(promises);
416
+ return this.arrayConcat(promisesResult[0], promisesResult[1]);
415
417
  }
416
418
  return await this.fetchMarketsFromAPI(params);
417
419
  }
@@ -519,6 +521,9 @@ export default class gemini extends Exchange {
519
521
  'post_only': true,
520
522
  'limit_only': true,
521
523
  };
524
+ if (status === undefined) {
525
+ return true; // as defaulted below
526
+ }
522
527
  return this.safeBool(statuses, status, true);
523
528
  }
524
529
  async fetchUSDTMarkets(params = {}) {
package/js/src/hitbtc.js CHANGED
@@ -2520,7 +2520,7 @@ export default class hitbtc extends Exchange {
2520
2520
  * @see https://api.hitbtc.com/#get-futures-position-parameters
2521
2521
  * @param {string} symbol unified symbol of the market the order was made in
2522
2522
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2523
- * @returns {object} Struct of MarginMode
2523
+ * @returns {object} a list of [margin mode structures]{@link https://docs.ccxt.com/#/?id=margin-mode-structure}
2524
2524
  */
2525
2525
  await this.loadMarkets();
2526
2526
  let market = undefined;
@@ -149,6 +149,7 @@ export default class krakenfutures extends Exchange {
149
149
  'executions',
150
150
  'triggers',
151
151
  'accountlogcsv',
152
+ 'account-log',
152
153
  'market/{symbol}/orders',
153
154
  'market/{symbol}/executions',
154
155
  ],