ccxt 4.4.61 → 4.4.62

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.
@@ -72,6 +72,7 @@ class binance extends binance$1 {
72
72
  'ws-api': {
73
73
  'spot': 'wss://testnet.binance.vision/ws-api/v3',
74
74
  'future': 'wss://testnet.binancefuture.com/ws-fapi/v1',
75
+ 'delivery': 'wss://testnet.binancefuture.com/ws-dapi/v1',
75
76
  },
76
77
  },
77
78
  },
@@ -84,6 +85,7 @@ class binance extends binance$1 {
84
85
  'ws-api': {
85
86
  'spot': 'wss://ws-api.binance.com:443/ws-api/v3',
86
87
  'future': 'wss://ws-fapi.binance.com/ws-fapi/v1',
88
+ 'delivery': 'wss://ws-dapi.binance.com/ws-dapi/v1',
87
89
  },
88
90
  'papi': 'wss://fstream.binance.com/pm/ws',
89
91
  },
@@ -2504,6 +2506,7 @@ class binance extends binance$1 {
2504
2506
  * @description fetch balance and get the amount of funds available for trading or funds locked in orders
2505
2507
  * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/account/websocket-api/Futures-Account-Balance
2506
2508
  * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-api#account-information-user_data
2509
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/account/websocket-api
2507
2510
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2508
2511
  * @param {string|undefined} [params.type] 'future', 'delivery', 'savings', 'funding', or 'spot'
2509
2512
  * @param {string|undefined} [params.marginMode] 'cross' or 'isolated', for margin trading, uses this.options.defaultMarginMode if not passed, defaults to undefined/None/null
@@ -2514,7 +2517,7 @@ class binance extends binance$1 {
2514
2517
  async fetchBalanceWs(params = {}) {
2515
2518
  await this.loadMarkets();
2516
2519
  const type = this.getMarketType('fetchBalanceWs', undefined, params);
2517
- if (type !== 'spot' && type !== 'future') {
2520
+ if (type !== 'spot' && type !== 'future' && type !== 'delivery') {
2518
2521
  throw new errors.BadRequest(this.id + ' fetchBalanceWs only supports spot or swap markets');
2519
2522
  }
2520
2523
  const url = this.urls['api']['ws']['ws-api'][type];
@@ -2623,6 +2626,7 @@ class binance extends binance$1 {
2623
2626
  * @name binance#fetchPositionsWs
2624
2627
  * @description fetch all open positions
2625
2628
  * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Position-Information
2629
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/websocket-api/Position-Information
2626
2630
  * @param {string[]} [symbols] list of unified market symbols
2627
2631
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2628
2632
  * @param {boolean} [params.returnRateLimits] set to true to return rate limit informations, defaults to false.
@@ -2631,17 +2635,23 @@ class binance extends binance$1 {
2631
2635
  */
2632
2636
  async fetchPositionsWs(symbols = undefined, params = {}) {
2633
2637
  await this.loadMarkets();
2634
- symbols = this.marketSymbols(symbols, 'swap', true, true, true);
2635
- const url = this.urls['api']['ws']['ws-api']['future'];
2636
- const requestId = this.requestId(url);
2637
- const messageHash = requestId.toString();
2638
2638
  const payload = {};
2639
+ let market = undefined;
2640
+ symbols = this.marketSymbols(symbols, 'swap', true, true, true);
2639
2641
  if (symbols !== undefined) {
2640
2642
  const symbolsLength = symbols.length;
2641
2643
  if (symbolsLength === 1) {
2642
- payload['symbol'] = this.marketId(symbols[0]);
2644
+ market = this.market(symbols[0]);
2645
+ payload['symbol'] = market['id'];
2643
2646
  }
2644
2647
  }
2648
+ const type = this.getMarketType('fetchPositionsWs', market, params);
2649
+ if (type !== 'future' && type !== 'delivery') {
2650
+ throw new errors.BadRequest(this.id + ' fetchPositionsWs only supports swap markets');
2651
+ }
2652
+ const url = this.urls['api']['ws']['ws-api'][type];
2653
+ const requestId = this.requestId(url);
2654
+ const messageHash = requestId.toString();
2645
2655
  let returnRateLimits = false;
2646
2656
  [returnRateLimits, params] = this.handleOptionAndParams(params, 'fetchPositionsWs', 'returnRateLimits', false);
2647
2657
  payload['returnRateLimits'] = returnRateLimits;
@@ -2867,6 +2877,7 @@ class binance extends binance$1 {
2867
2877
  * @description create a trade order
2868
2878
  * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-api#place-new-order-trade
2869
2879
  * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/New-Order
2880
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/websocket-api
2870
2881
  * @param {string} symbol unified symbol of the market to create an order in
2871
2882
  * @param {string} type 'market' or 'limit'
2872
2883
  * @param {string} side 'buy' or 'sell'
@@ -2881,7 +2892,7 @@ class binance extends binance$1 {
2881
2892
  await this.loadMarkets();
2882
2893
  const market = this.market(symbol);
2883
2894
  const marketType = this.getMarketType('createOrderWs', market, params);
2884
- if (marketType !== 'spot' && marketType !== 'future') {
2895
+ if (marketType !== 'spot' && marketType !== 'future' && marketType !== 'delivery') {
2885
2896
  throw new errors.BadRequest(this.id + ' createOrderWs only supports spot or swap markets');
2886
2897
  }
2887
2898
  const url = this.urls['api']['ws']['ws-api'][marketType];
@@ -3015,6 +3026,7 @@ class binance extends binance$1 {
3015
3026
  * @description edit a trade order
3016
3027
  * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-api#cancel-and-replace-order-trade
3017
3028
  * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Modify-Order
3029
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/websocket-api/Modify-Order
3018
3030
  * @param {string} id order id
3019
3031
  * @param {string} symbol unified symbol of the market to create an order in
3020
3032
  * @param {string} type 'market' or 'limit'
@@ -3028,17 +3040,18 @@ class binance extends binance$1 {
3028
3040
  await this.loadMarkets();
3029
3041
  const market = this.market(symbol);
3030
3042
  const marketType = this.getMarketType('editOrderWs', market, params);
3031
- if (marketType !== 'spot' && marketType !== 'future') {
3043
+ if (marketType !== 'spot' && marketType !== 'future' && marketType !== 'delivery') {
3032
3044
  throw new errors.BadRequest(this.id + ' editOrderWs only supports spot or swap markets');
3033
3045
  }
3034
3046
  const url = this.urls['api']['ws']['ws-api'][marketType];
3035
3047
  const requestId = this.requestId(url);
3036
3048
  const messageHash = requestId.toString();
3049
+ const isSwap = (marketType === 'future' || marketType === 'delivery');
3037
3050
  let payload = undefined;
3038
3051
  if (marketType === 'spot') {
3039
3052
  payload = this.editSpotOrderRequest(id, symbol, type, side, amount, price, params);
3040
3053
  }
3041
- else if (marketType === 'future') {
3054
+ else if (isSwap) {
3042
3055
  payload = this.editContractOrderRequest(id, symbol, type, side, amount, price, params);
3043
3056
  }
3044
3057
  let returnRateLimits = false;
@@ -3046,7 +3059,7 @@ class binance extends binance$1 {
3046
3059
  payload['returnRateLimits'] = returnRateLimits;
3047
3060
  const message = {
3048
3061
  'id': messageHash,
3049
- 'method': (marketType === 'future') ? 'order.modify' : 'order.cancelReplace',
3062
+ 'method': (isSwap) ? 'order.modify' : 'order.cancelReplace',
3050
3063
  'params': this.signParams(this.extend(payload, params)),
3051
3064
  };
3052
3065
  const subscription = {
@@ -3171,6 +3184,7 @@ class binance extends binance$1 {
3171
3184
  * @description cancel multiple orders
3172
3185
  * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-api#cancel-order-trade
3173
3186
  * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Cancel-Order
3187
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/websocket-api/Cancel-Order
3174
3188
  * @param {string} id order id
3175
3189
  * @param {string} [symbol] unified market symbol, default is undefined
3176
3190
  * @param {object} [params] extra parameters specific to the exchange API endpoint
@@ -3252,6 +3266,7 @@ class binance extends binance$1 {
3252
3266
  * @description fetches information on an order made by the user
3253
3267
  * @see https://developers.binance.com/docs/binance-spot-api-docs/web-socket-api#query-order-user_data
3254
3268
  * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Query-Order
3269
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/websocket-api/Query-Order
3255
3270
  * @param {string} id order id
3256
3271
  * @param {string} [symbol] unified symbol of the market the order was made in
3257
3272
  * @param {object} [params] extra parameters specific to the exchange API endpoint
@@ -3264,7 +3279,7 @@ class binance extends binance$1 {
3264
3279
  }
3265
3280
  const market = this.market(symbol);
3266
3281
  const type = this.getMarketType('fetchOrderWs', market, params);
3267
- if (type !== 'spot' && type !== 'future') {
3282
+ if (type !== 'spot' && type !== 'future' && type !== 'delivery') {
3268
3283
  throw new errors.BadRequest(this.id + ' fetchOrderWs only supports spot or swap markets');
3269
3284
  }
3270
3285
  const url = this.urls['api']['ws']['ws-api'][type];
@@ -428,7 +428,7 @@ class lbank extends lbank$1 {
428
428
  // "volume":6.3607,
429
429
  // "amount":77148.9303,
430
430
  // "price":12129,
431
- // "direction":"sell", // or "sell_market"
431
+ // "direction":"sell", // buy, sell, buy_market, sell_market, buy_maker, sell_maker, buy_ioc, sell_ioc, buy_fok, sell_fok
432
432
  // "TS":"2019-06-28T19:55:49.460"
433
433
  // },
434
434
  // "type":"trade",
@@ -468,7 +468,7 @@ class lbank extends lbank$1 {
468
468
  // "volume":6.3607,
469
469
  // "amount":77148.9303,
470
470
  // "price":12129,
471
- // "direction":"sell", // or "sell_market"
471
+ // "direction":"sell", // buy, sell, buy_market, sell_market, buy_maker, sell_maker, buy_ioc, sell_ioc, buy_fok, sell_fok
472
472
  // "TS":"2019-06-28T19:55:49.460"
473
473
  // }
474
474
  //
@@ -477,8 +477,15 @@ class lbank extends lbank$1 {
477
477
  if (timestamp === undefined) {
478
478
  timestamp = this.parse8601(datetime);
479
479
  }
480
- let side = this.safeString2(trade, 'direction', 3);
481
- side = side.replace('_market', '');
480
+ const rawSide = this.safeString2(trade, 'direction', 3);
481
+ const parts = rawSide.split('_');
482
+ const firstPart = this.safeString(parts, 0);
483
+ const secondPart = this.safeString(parts, 1);
484
+ let side = firstPart;
485
+ // reverse if it was 'maker'
486
+ if (secondPart !== undefined && secondPart === 'maker') {
487
+ side = (side === 'buy') ? 'sell' : 'buy';
488
+ }
482
489
  return this.safeTrade({
483
490
  'timestamp': timestamp,
484
491
  'datetime': datetime,
@@ -8,11 +8,20 @@ class myokx extends okx {
8
8
  describe() {
9
9
  return this.deepExtend(super.describe(), {
10
10
  'id': 'myokx',
11
- 'name': 'MyOKX',
11
+ 'name': 'MyOKX (EEA)',
12
+ 'hostname': 'eea.okx.com',
12
13
  'urls': {
13
14
  'api': {
15
+ 'rest': 'https://{hostname}',
14
16
  'ws': 'wss://wseea.okx.com:8443/ws/v5',
15
17
  },
18
+ 'www': 'https://my.okx.com',
19
+ 'doc': 'https://my.okx.com/docs-v5/en/#overview',
20
+ 'fees': 'https://my.okx.com/pages/products/fees.html',
21
+ 'referral': {
22
+ 'url': 'https://www.my.okx.com/join/CCXT2023',
23
+ 'discount': 0.2,
24
+ },
16
25
  'test': {
17
26
  'ws': 'wss://wseeapap.okx.com:8443/ws/v5',
18
27
  },
@@ -1158,6 +1158,7 @@ class whitebit extends whitebit$1 {
1158
1158
  // "clientOrderId": "customId11",
1159
1159
  // "role": 2, // 1 = maker, 2 = taker
1160
1160
  // "deal": "0.00419198" // amount in money
1161
+ // "feeAsset": "USDT"
1161
1162
  // }
1162
1163
  //
1163
1164
  // fetchMyTrades
@@ -1173,6 +1174,7 @@ class whitebit extends whitebit$1 {
1173
1174
  // "deal": "9.981007",
1174
1175
  // "fee": "0.009981007",
1175
1176
  // "orderId": 58166729555,
1177
+ // "feeAsset": "USDT"
1176
1178
  // }
1177
1179
  //
1178
1180
  market = this.safeMarket(undefined, market);
@@ -1194,7 +1196,7 @@ class whitebit extends whitebit$1 {
1194
1196
  if (feeCost !== undefined) {
1195
1197
  fee = {
1196
1198
  'cost': feeCost,
1197
- 'currency': market['quote'],
1199
+ 'currency': this.safeCurrencyCode(this.safeString(trade, 'feeAsset')),
1198
1200
  };
1199
1201
  }
1200
1202
  return this.safeTrade({
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, MarketMarginModes, MarginMode, Greeks, Conversion, Option, LastPrice, Leverage, MarginModification, Leverages, LastPrices, Currencies, TradingFees, MarginModes, OptionChain, IsolatedBorrowRates, CrossBorrowRates, LeverageTiers, LongShortRatio, OrderBooks, OpenInterests } from './src/base/types.js';
6
6
  import { BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, MarketClosed, ManualInteractionNeeded, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, InvalidProxySettings, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, ChecksumError, RequestTimeout, BadResponse, NullResponse, CancelPending, UnsubscribeError } from './src/base/errors.js';
7
- declare const version = "4.4.60";
7
+ declare const version = "4.4.61";
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, ManualInteractionNeeded, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, InvalidProxySettings, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, ChecksumError, RequestTimeout, BadResponse, NullResponse, CancelPending, UnsubscribeError } from './src/base/errors.js';
39
39
  //-----------------------------------------------------------------------------
40
40
  // this is updated by vss.js when building
41
- const version = '4.4.61';
41
+ const version = '4.4.62';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import ace from './src/ace.js';
@@ -47,6 +47,7 @@ interface Exchange {
47
47
  publicGetV5SpotLeverTokenInfo(params?: {}): Promise<implicitReturnType>;
48
48
  publicGetV5SpotLeverTokenReference(params?: {}): Promise<implicitReturnType>;
49
49
  publicGetV5SpotMarginTradeData(params?: {}): Promise<implicitReturnType>;
50
+ publicGetV5SpotMarginTradeCollateral(params?: {}): Promise<implicitReturnType>;
50
51
  publicGetV5SpotCrossMarginTradeData(params?: {}): Promise<implicitReturnType>;
51
52
  publicGetV5SpotCrossMarginTradePledgeToken(params?: {}): Promise<implicitReturnType>;
52
53
  publicGetV5SpotCrossMarginTradeBorrowToken(params?: {}): Promise<implicitReturnType>;
@@ -52,6 +52,7 @@ export default class Exchange {
52
52
  userAgents: any;
53
53
  headers: any;
54
54
  origin: string;
55
+ MAX_VALUE: Num;
55
56
  agent: any;
56
57
  nodeHttpModuleLoaded: boolean;
57
58
  httpAgent: any;
@@ -312,8 +313,8 @@ export default class Exchange {
312
313
  constructor(userConfig?: {});
313
314
  encodeURIComponent(...args: any[]): string;
314
315
  checkRequiredVersion(requiredVersion: any, error?: boolean): boolean;
315
- initRestRateLimiter(): void;
316
316
  throttle(cost?: any): any;
317
+ initThrottler(): void;
317
318
  defineRestApiEndpoint(methodName: any, uppercaseMethod: any, lowercaseMethod: any, camelcaseMethod: any, path: any, paths: any, config?: {}): void;
318
319
  defineRestApi(api: any, methodName: any, paths?: any[]): void;
319
320
  log(...args: any[]): void;
@@ -495,6 +496,7 @@ export default class Exchange {
495
496
  safeNumberOmitZero(obj: object, key: IndexType, defaultValue?: Num): Num;
496
497
  safeIntegerOmitZero(obj: object, key: IndexType, defaultValue?: Int): Int;
497
498
  afterConstruct(): void;
499
+ initRestRateLimiter(): void;
498
500
  featuresGenerator(): void;
499
501
  featuresMapper(initialFeatures: any, marketType: Str, subType?: Str): any;
500
502
  orderbookChecksumMessage(symbol: Str): string;
@@ -49,6 +49,7 @@ export default class Exchange {
49
49
  };
50
50
  this.headers = {};
51
51
  this.origin = '*'; // CORS origin
52
+ this.MAX_VALUE = Number.MAX_VALUE;
52
53
  //
53
54
  this.agent = undefined; // maintained for backwards compatibility
54
55
  this.nodeHttpModuleLoaded = false;
@@ -341,18 +342,8 @@ export default class Exchange {
341
342
  if (this.api) {
342
343
  this.defineRestApi(this.api, 'request');
343
344
  }
344
- // init the request rate limiter
345
- this.initRestRateLimiter();
346
- // init predefined markets if any
347
- if (this.markets) {
348
- this.setMarkets(this.markets);
349
- }
350
345
  this.newUpdates = (this.options.newUpdates !== undefined) ? this.options.newUpdates : true;
351
346
  this.afterConstruct();
352
- const isSandbox = this.safeBool2(this.options, 'sandbox', 'testnet', false);
353
- if (isSandbox) {
354
- this.setSandboxMode(isSandbox);
355
- }
356
347
  }
357
348
  encodeURIComponent(...args) {
358
349
  // @ts-expect-error
@@ -382,22 +373,12 @@ export default class Exchange {
382
373
  }
383
374
  return result;
384
375
  }
385
- initRestRateLimiter() {
386
- if (this.rateLimit === undefined) {
387
- throw new Error(this.id + '.rateLimit property is not configured');
388
- }
389
- this.tokenBucket = this.extend({
390
- delay: 0.001,
391
- capacity: 1,
392
- cost: 1,
393
- maxCapacity: 1000,
394
- refillRate: (this.rateLimit > 0) ? 1 / this.rateLimit : Number.MAX_VALUE,
395
- }, this.tokenBucket);
396
- this.throttler = new Throttler(this.tokenBucket);
397
- }
398
376
  throttle(cost = undefined) {
399
377
  return this.throttler.throttle(cost);
400
378
  }
379
+ initThrottler() {
380
+ this.throttler = new Throttler(this.tokenBucket);
381
+ }
401
382
  defineRestApiEndpoint(methodName, uppercaseMethod, lowercaseMethod, camelcaseMethod, path, paths, config = {}) {
402
383
  const splitPath = path.split(/[^a-zA-Z0-9]/);
403
384
  const camelcaseSuffix = splitPath.map(this.capitalize).join('');
@@ -2322,8 +2303,39 @@ export default class Exchange {
2322
2303
  return timestamp;
2323
2304
  }
2324
2305
  afterConstruct() {
2306
+ // networks
2325
2307
  this.createNetworksByIdObject();
2326
2308
  this.featuresGenerator();
2309
+ // init predefined markets if any
2310
+ if (this.markets) {
2311
+ this.setMarkets(this.markets);
2312
+ }
2313
+ // init the request rate limiter
2314
+ this.initRestRateLimiter();
2315
+ // sanbox mode
2316
+ const isSandbox = this.safeBool2(this.options, 'sandbox', 'testnet', false);
2317
+ if (isSandbox) {
2318
+ this.setSandboxMode(isSandbox);
2319
+ }
2320
+ }
2321
+ initRestRateLimiter() {
2322
+ if (this.rateLimit === undefined || (this.id !== undefined && this.rateLimit === -1)) {
2323
+ throw new ExchangeError(this.id + '.rateLimit property is not configured');
2324
+ }
2325
+ let refillRate = this.MAX_VALUE;
2326
+ if (this.rateLimit > 0) {
2327
+ refillRate = 1 / this.rateLimit;
2328
+ }
2329
+ const defaultBucket = {
2330
+ 'delay': 0.001,
2331
+ 'capacity': 1,
2332
+ 'cost': 1,
2333
+ 'maxCapacity': 1000,
2334
+ 'refillRate': refillRate,
2335
+ };
2336
+ const existingBucket = (this.tokenBucket === undefined) ? {} : this.tokenBucket;
2337
+ this.tokenBucket = this.extend(defaultBucket, existingBucket);
2338
+ this.initThrottler();
2327
2339
  }
2328
2340
  featuresGenerator() {
2329
2341
  //
@@ -4594,24 +4606,34 @@ export default class Exchange {
4594
4606
  * @param {string} [defaultValue] assigned programatically in the method calling handleMarketTypeAndParams
4595
4607
  * @returns {[string, object]} the market type and params with type and defaultType omitted
4596
4608
  */
4597
- const defaultType = this.safeString2(this.options, 'defaultType', 'type', 'spot');
4598
- if (defaultValue === undefined) { // defaultValue takes precendence over exchange wide defaultType
4599
- defaultValue = defaultType;
4609
+ // type from param
4610
+ const type = this.safeString2(params, 'defaultType', 'type');
4611
+ if (type !== undefined) {
4612
+ params = this.omit(params, ['defaultType', 'type']);
4613
+ return [type, params];
4614
+ }
4615
+ // type from market
4616
+ if (market !== undefined) {
4617
+ return [market['type'], params];
4618
+ }
4619
+ // type from default-argument
4620
+ if (defaultValue !== undefined) {
4621
+ return [defaultValue, params];
4600
4622
  }
4601
4623
  const methodOptions = this.safeDict(this.options, methodName);
4602
- let methodType = defaultValue;
4603
- if (methodOptions !== undefined) { // user defined methodType takes precedence over defaultValue
4624
+ if (methodOptions !== undefined) {
4604
4625
  if (typeof methodOptions === 'string') {
4605
- methodType = methodOptions;
4626
+ return [methodOptions, params];
4606
4627
  }
4607
4628
  else {
4608
- methodType = this.safeString2(methodOptions, 'defaultType', 'type', methodType);
4629
+ const typeFromMethod = this.safeString2(methodOptions, 'defaultType', 'type');
4630
+ if (typeFromMethod !== undefined) {
4631
+ return [typeFromMethod, params];
4632
+ }
4609
4633
  }
4610
4634
  }
4611
- const marketType = (market === undefined) ? methodType : market['type'];
4612
- const type = this.safeString2(params, 'defaultType', 'type', marketType);
4613
- params = this.omit(params, ['defaultType', 'type']);
4614
- return [type, params];
4635
+ const defaultType = this.safeString2(this.options, 'defaultType', 'type', 'spot');
4636
+ return [defaultType, params];
4615
4637
  }
4616
4638
  handleSubTypeAndParams(methodName, market = undefined, params = {}, defaultValue = undefined) {
4617
4639
  let subType = undefined;
package/js/src/bingx.js CHANGED
@@ -4670,14 +4670,13 @@ export default class bingx extends Exchange {
4670
4670
  * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
4671
4671
  */
4672
4672
  async fetchCanceledAndClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
4673
- if (symbol === undefined) {
4674
- throw new ArgumentsRequired(this.id + ' fetchClosedOrders() requires a symbol argument');
4675
- }
4676
4673
  await this.loadMarkets();
4677
- const market = this.market(symbol);
4678
- const request = {
4679
- 'symbol': market['id'],
4680
- };
4674
+ let market = undefined;
4675
+ const request = {};
4676
+ if (symbol !== undefined) {
4677
+ market = this.market(symbol);
4678
+ request['symbol'] = market['id'];
4679
+ }
4681
4680
  let type = undefined;
4682
4681
  let subType = undefined;
4683
4682
  let standard = undefined;
package/js/src/bybit.d.ts CHANGED
@@ -87,6 +87,18 @@ export default class bybit extends Exchange {
87
87
  * @returns {object} an array of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
88
88
  */
89
89
  fetchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
90
+ /**
91
+ * @method
92
+ * @name bybit#fetchBidsAsks
93
+ * @description fetches the bid and ask price and volume for multiple markets
94
+ * @see https://bybit-exchange.github.io/docs/v5/market/tickers
95
+ * @param {string[]|undefined} symbols unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
96
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
97
+ * @param {string} [params.subType] *contract only* 'linear', 'inverse'
98
+ * @param {string} [params.baseCoin] *option only* base coin, default is 'BTC'
99
+ * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
100
+ */
101
+ fetchBidsAsks(symbols?: Strings, params?: {}): Promise<Tickers>;
90
102
  parseOHLCV(ohlcv: any, market?: Market): OHLCV;
91
103
  /**
92
104
  * @method
@@ -267,6 +279,16 @@ export default class bybit extends Exchange {
267
279
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
268
280
  */
269
281
  editOrder(id: string, symbol: string, type: OrderType, side: OrderSide, amount?: Num, price?: Num, params?: {}): Promise<Order>;
282
+ /**
283
+ * @method
284
+ * @name bybit#editOrders
285
+ * @description edit a list of trade orders
286
+ * @see https://bybit-exchange.github.io/docs/v5/order/batch-amend
287
+ * @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
288
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
289
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
290
+ */
291
+ editOrders(orders: OrderRequest[], params?: {}): Promise<Order[]>;
270
292
  cancelOrderRequest(id: string, symbol?: Str, params?: {}): any;
271
293
  /**
272
294
  * @method
package/js/src/bybit.js CHANGED
@@ -59,7 +59,9 @@ export default class bybit extends Exchange {
59
59
  'createTrailingAmountOrder': true,
60
60
  'createTriggerOrder': true,
61
61
  'editOrder': true,
62
+ 'editOrders': true,
62
63
  'fetchBalance': true,
64
+ 'fetchBidsAsks': 'emulated',
63
65
  'fetchBorrowInterest': false,
64
66
  'fetchBorrowRateHistories': false,
65
67
  'fetchBorrowRateHistory': false,
@@ -240,6 +242,7 @@ export default class bybit extends Exchange {
240
242
  'v5/spot-lever-token/reference': 5,
241
243
  // spot margin trade
242
244
  'v5/spot-margin-trade/data': 5,
245
+ 'v5/spot-margin-trade/collateral': 5,
243
246
  'v5/spot-cross-margin-trade/data': 5,
244
247
  'v5/spot-cross-margin-trade/pledge-token': 5,
245
248
  'v5/spot-cross-margin-trade/borrow-token': 5,
@@ -1225,6 +1228,9 @@ export default class bybit extends Exchange {
1225
1228
  'fetchOHLCV': {
1226
1229
  'limit': 1000,
1227
1230
  },
1231
+ 'editOrders': {
1232
+ 'max': 10,
1233
+ },
1228
1234
  },
1229
1235
  'spot': {
1230
1236
  'extends': 'default',
@@ -2527,6 +2533,20 @@ export default class bybit extends Exchange {
2527
2533
  const tickerList = this.safeList(result, 'list', []);
2528
2534
  return this.parseTickers(tickerList, parsedSymbols);
2529
2535
  }
2536
+ /**
2537
+ * @method
2538
+ * @name bybit#fetchBidsAsks
2539
+ * @description fetches the bid and ask price and volume for multiple markets
2540
+ * @see https://bybit-exchange.github.io/docs/v5/market/tickers
2541
+ * @param {string[]|undefined} symbols unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
2542
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2543
+ * @param {string} [params.subType] *contract only* 'linear', 'inverse'
2544
+ * @param {string} [params.baseCoin] *option only* base coin, default is 'BTC'
2545
+ * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
2546
+ */
2547
+ async fetchBidsAsks(symbols = undefined, params = {}) {
2548
+ return await this.fetchTickers(symbols, params);
2549
+ }
2530
2550
  parseOHLCV(ohlcv, market = undefined) {
2531
2551
  //
2532
2552
  // [
@@ -4210,14 +4230,16 @@ export default class bybit extends Exchange {
4210
4230
  const price = this.safeValue(rawOrder, 'price');
4211
4231
  const orderParams = this.safeDict(rawOrder, 'params', {});
4212
4232
  const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams, isUta);
4233
+ delete orderRequest['category'];
4213
4234
  ordersRequests.push(orderRequest);
4214
4235
  }
4215
4236
  const symbols = this.marketSymbols(orderSymbols, undefined, false, true, true);
4216
4237
  const market = this.market(symbols[0]);
4238
+ const unifiedMarginStatus = this.safeInteger(this.options, 'unifiedMarginStatus', 3);
4217
4239
  let category = undefined;
4218
4240
  [category, params] = this.getBybitType('createOrders', market, params);
4219
- if (category === 'inverse') {
4220
- throw new NotSupported(this.id + ' createOrders does not allow inverse orders');
4241
+ if ((category === 'inverse') && (unifiedMarginStatus < 5)) {
4242
+ throw new NotSupported(this.id + ' createOrders does not allow inverse orders for non UTA2.0 account');
4221
4243
  }
4222
4244
  const request = {
4223
4245
  'category': category,
@@ -4400,6 +4422,95 @@ export default class bybit extends Exchange {
4400
4422
  'id': this.safeString(result, 'orderId'),
4401
4423
  });
4402
4424
  }
4425
+ /**
4426
+ * @method
4427
+ * @name bybit#editOrders
4428
+ * @description edit a list of trade orders
4429
+ * @see https://bybit-exchange.github.io/docs/v5/order/batch-amend
4430
+ * @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
4431
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
4432
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
4433
+ */
4434
+ async editOrders(orders, params = {}) {
4435
+ await this.loadMarkets();
4436
+ const ordersRequests = [];
4437
+ let orderSymbols = [];
4438
+ for (let i = 0; i < orders.length; i++) {
4439
+ const rawOrder = orders[i];
4440
+ const symbol = this.safeString(rawOrder, 'symbol');
4441
+ orderSymbols.push(symbol);
4442
+ const id = this.safeString(rawOrder, 'id');
4443
+ const type = this.safeString(rawOrder, 'type');
4444
+ const side = this.safeString(rawOrder, 'side');
4445
+ const amount = this.safeValue(rawOrder, 'amount');
4446
+ const price = this.safeValue(rawOrder, 'price');
4447
+ const orderParams = this.safeDict(rawOrder, 'params', {});
4448
+ const orderRequest = this.editOrderRequest(id, symbol, type, side, amount, price, orderParams);
4449
+ delete orderRequest['category'];
4450
+ ordersRequests.push(orderRequest);
4451
+ }
4452
+ orderSymbols = this.marketSymbols(orderSymbols, undefined, false, true, true);
4453
+ const market = this.market(orderSymbols[0]);
4454
+ const unifiedMarginStatus = this.safeInteger(this.options, 'unifiedMarginStatus', 3);
4455
+ let category = undefined;
4456
+ [category, params] = this.getBybitType('editOrders', market, params);
4457
+ if ((category === 'inverse') && (unifiedMarginStatus < 5)) {
4458
+ throw new NotSupported(this.id + ' editOrders does not allow inverse orders for non UTA2.0 account');
4459
+ }
4460
+ const request = {
4461
+ 'category': category,
4462
+ 'request': ordersRequests,
4463
+ };
4464
+ const response = await this.privatePostV5OrderAmendBatch(this.extend(request, params));
4465
+ const result = this.safeDict(response, 'result', {});
4466
+ const data = this.safeList(result, 'list', []);
4467
+ const retInfo = this.safeDict(response, 'retExtInfo', {});
4468
+ const codes = this.safeList(retInfo, 'list', []);
4469
+ // extend the error with the unsuccessful orders
4470
+ for (let i = 0; i < codes.length; i++) {
4471
+ const code = codes[i];
4472
+ const retCode = this.safeInteger(code, 'code');
4473
+ if (retCode !== 0) {
4474
+ data[i] = this.extend(data[i], code);
4475
+ }
4476
+ }
4477
+ //
4478
+ // {
4479
+ // "retCode": 0,
4480
+ // "retMsg": "OK",
4481
+ // "result": {
4482
+ // "list": [
4483
+ // {
4484
+ // "category": "option",
4485
+ // "symbol": "ETH-30DEC22-500-C",
4486
+ // "orderId": "b551f227-7059-4fb5-a6a6-699c04dbd2f2",
4487
+ // "orderLinkId": ""
4488
+ // },
4489
+ // {
4490
+ // "category": "option",
4491
+ // "symbol": "ETH-30DEC22-700-C",
4492
+ // "orderId": "fa6a595f-1a57-483f-b9d3-30e9c8235a52",
4493
+ // "orderLinkId": ""
4494
+ // }
4495
+ // ]
4496
+ // },
4497
+ // "retExtInfo": {
4498
+ // "list": [
4499
+ // {
4500
+ // "code": 0,
4501
+ // "msg": "OK"
4502
+ // },
4503
+ // {
4504
+ // "code": 0,
4505
+ // "msg": "OK"
4506
+ // }
4507
+ // ]
4508
+ // },
4509
+ // "time": 1672222808060
4510
+ // }
4511
+ //
4512
+ return this.parseOrders(data);
4513
+ }
4403
4514
  cancelOrderRequest(id, symbol = undefined, params = {}) {
4404
4515
  const market = this.market(symbol);
4405
4516
  const request = {