ccxt 4.2.58 → 4.2.60

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 (92) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/README.md +3 -3
  3. package/build.sh +1 -1
  4. package/cleanup.sh +3 -0
  5. package/dist/ccxt.browser.js +716 -382
  6. package/dist/ccxt.browser.min.js +3 -3
  7. package/dist/cjs/ccxt.js +1 -1
  8. package/dist/cjs/src/ascendex.js +10 -12
  9. package/dist/cjs/src/base/Exchange.js +2 -0
  10. package/dist/cjs/src/binance.js +2 -2
  11. package/dist/cjs/src/bingx.js +41 -3
  12. package/dist/cjs/src/bitfinex2.js +21 -4
  13. package/dist/cjs/src/bitget.js +10 -3
  14. package/dist/cjs/src/bitmart.js +41 -23
  15. package/dist/cjs/src/bitmex.js +1 -1
  16. package/dist/cjs/src/blofin.js +60 -2
  17. package/dist/cjs/src/coinbase.js +24 -14
  18. package/dist/cjs/src/hitbtc.js +1 -1
  19. package/dist/cjs/src/htx.js +4 -1
  20. package/dist/cjs/src/kraken.js +42 -39
  21. package/dist/cjs/src/kucoinfutures.js +1 -0
  22. package/dist/cjs/src/lbank.js +1 -1
  23. package/dist/cjs/src/mexc.js +1 -1
  24. package/dist/cjs/src/okx.js +1 -1
  25. package/dist/cjs/src/phemex.js +1 -1
  26. package/dist/cjs/src/pro/binance.js +17 -4
  27. package/dist/cjs/src/pro/bitfinex2.js +1 -1
  28. package/dist/cjs/src/pro/bitget.js +1 -1
  29. package/dist/cjs/src/pro/bitmart.js +51 -89
  30. package/dist/cjs/src/pro/bitvavo.js +1 -1
  31. package/dist/cjs/src/pro/bybit.js +1 -1
  32. package/dist/cjs/src/pro/coinex.js +1 -1
  33. package/dist/cjs/src/pro/cryptocom.js +1 -1
  34. package/dist/cjs/src/pro/deribit.js +201 -84
  35. package/dist/cjs/src/pro/gate.js +1 -1
  36. package/dist/cjs/src/pro/independentreserve.js +1 -1
  37. package/dist/cjs/src/pro/kraken.js +1 -1
  38. package/dist/cjs/src/pro/kucoinfutures.js +1 -1
  39. package/dist/cjs/src/pro/mexc.js +5 -3
  40. package/dist/cjs/src/pro/okx.js +1 -1
  41. package/dist/cjs/src/pro/woo.js +1 -1
  42. package/dist/cjs/src/wazirx.js +6 -1
  43. package/dist/cjs/src/woo.js +159 -79
  44. package/js/ccxt.d.ts +1 -1
  45. package/js/ccxt.js +1 -1
  46. package/js/src/abstract/blofin.d.ts +1 -0
  47. package/js/src/abstract/wazirx.d.ts +5 -0
  48. package/js/src/ascendex.d.ts +2 -2
  49. package/js/src/ascendex.js +10 -12
  50. package/js/src/base/Exchange.js +2 -0
  51. package/js/src/binance.js +2 -2
  52. package/js/src/bingx.d.ts +3 -1
  53. package/js/src/bingx.js +41 -3
  54. package/js/src/bitfinex2.js +21 -4
  55. package/js/src/bitget.js +10 -3
  56. package/js/src/bitmart.d.ts +9 -2
  57. package/js/src/bitmart.js +41 -23
  58. package/js/src/bitmex.js +1 -1
  59. package/js/src/blofin.d.ts +2 -1
  60. package/js/src/blofin.js +60 -2
  61. package/js/src/coinbase.js +24 -14
  62. package/js/src/hitbtc.js +1 -1
  63. package/js/src/htx.js +4 -1
  64. package/js/src/kraken.js +42 -39
  65. package/js/src/kucoinfutures.js +1 -0
  66. package/js/src/lbank.js +1 -1
  67. package/js/src/mexc.js +1 -1
  68. package/js/src/okx.js +1 -1
  69. package/js/src/phemex.js +1 -1
  70. package/js/src/pro/binance.js +17 -4
  71. package/js/src/pro/bitfinex2.js +1 -1
  72. package/js/src/pro/bitget.js +1 -1
  73. package/js/src/pro/bitmart.d.ts +2 -2
  74. package/js/src/pro/bitmart.js +51 -89
  75. package/js/src/pro/bitvavo.js +1 -1
  76. package/js/src/pro/bybit.js +1 -1
  77. package/js/src/pro/coinex.js +1 -1
  78. package/js/src/pro/cryptocom.js +1 -1
  79. package/js/src/pro/deribit.d.ts +5 -0
  80. package/js/src/pro/deribit.js +202 -85
  81. package/js/src/pro/gate.js +1 -1
  82. package/js/src/pro/independentreserve.js +1 -1
  83. package/js/src/pro/kraken.js +1 -1
  84. package/js/src/pro/kucoinfutures.js +1 -1
  85. package/js/src/pro/mexc.js +6 -4
  86. package/js/src/pro/okx.js +1 -1
  87. package/js/src/pro/woo.js +1 -1
  88. package/js/src/wazirx.js +6 -1
  89. package/js/src/woo.d.ts +8 -0
  90. package/js/src/woo.js +159 -79
  91. package/package.json +1 -1
  92. package/skip-tests.json +44 -18
package/js/src/bingx.js CHANGED
@@ -62,6 +62,7 @@ export default class bingx extends Exchange {
62
62
  'fetchFundingRates': true,
63
63
  'fetchLeverage': true,
64
64
  'fetchLiquidations': false,
65
+ 'fetchMarginMode': true,
65
66
  'fetchMarkets': true,
66
67
  'fetchMarkOHLCV': true,
67
68
  'fetchMyLiquidations': true,
@@ -452,7 +453,7 @@ export default class bingx extends Exchange {
452
453
  if (!this.checkRequiredCredentials(false)) {
453
454
  return undefined;
454
455
  }
455
- const isSandbox = this.safeValue(this.options, 'sandboxMode', false);
456
+ const isSandbox = this.safeBool(this.options, 'sandboxMode', false);
456
457
  if (isSandbox) {
457
458
  return undefined;
458
459
  }
@@ -696,7 +697,7 @@ export default class bingx extends Exchange {
696
697
  * @returns {object[]} an array of objects representing market data
697
698
  */
698
699
  const requests = [this.fetchSwapMarkets(params)];
699
- const isSandbox = this.safeValue(this.options, 'sandboxMode', false);
700
+ const isSandbox = this.safeBool(this.options, 'sandboxMode', false);
700
701
  if (!isSandbox) {
701
702
  requests.push(this.fetchSpotMarkets(params)); // sandbox is swap only
702
703
  }
@@ -4169,11 +4170,48 @@ export default class bingx extends Exchange {
4169
4170
  const data = this.safeDict(response, 'data');
4170
4171
  return this.parseOrder(data, market);
4171
4172
  }
4173
+ async fetchMarginMode(symbol, params = {}) {
4174
+ /**
4175
+ * @method
4176
+ * @name bingx#fetchMarginMode
4177
+ * @description fetches the margin mode of the trading pair
4178
+ * @see https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Query%20Margin%20Mode
4179
+ * @param {string} symbol unified symbol of the market to fetch the margin mode for
4180
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
4181
+ * @returns {object} Struct of MarginMode
4182
+ */
4183
+ await this.loadMarkets();
4184
+ const market = this.market(symbol);
4185
+ const request = {
4186
+ 'symbol': market['id'],
4187
+ };
4188
+ const response = await this.swapV2PrivateGetTradeMarginType(this.extend(request, params));
4189
+ //
4190
+ // {
4191
+ // "code": 0,
4192
+ // "msg": "",
4193
+ // "data": {
4194
+ // "marginType": "CROSSED"
4195
+ // }
4196
+ // }
4197
+ //
4198
+ const data = this.safeDict(response, 'data', {});
4199
+ return this.parseMarginMode(data, market);
4200
+ }
4201
+ parseMarginMode(marginMode, market = undefined) {
4202
+ let marginType = this.safeStringLower(marginMode, 'marginType');
4203
+ marginType = (marginType === 'crossed') ? 'cross' : marginType;
4204
+ return {
4205
+ 'info': marginMode,
4206
+ 'symbol': market['symbol'],
4207
+ 'marginMode': marginType,
4208
+ };
4209
+ }
4172
4210
  sign(path, section = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
4173
4211
  const type = section[0];
4174
4212
  const version = section[1];
4175
4213
  const access = section[2];
4176
- const isSandbox = this.safeValue(this.options, 'sandboxMode', false);
4214
+ const isSandbox = this.safeBool(this.options, 'sandboxMode', false);
4177
4215
  if (isSandbox && (type !== 'swap')) {
4178
4216
  throw new NotSupported(this.id + ' does not have a testnet/sandbox URL for ' + type + ' endpoints');
4179
4217
  }
@@ -30,8 +30,8 @@ export default class bitfinex2 extends Exchange {
30
30
  'spot': true,
31
31
  'margin': true,
32
32
  'swap': true,
33
- 'future': undefined,
34
- 'option': undefined,
33
+ 'future': false,
34
+ 'option': false,
35
35
  'addMargin': false,
36
36
  'borrowCrossMargin': false,
37
37
  'borrowIsolatedMargin': false,
@@ -42,6 +42,7 @@ export default class bitfinex2 extends Exchange {
42
42
  'createLimitOrder': true,
43
43
  'createMarketOrder': true,
44
44
  'createOrder': true,
45
+ 'createPostOnlyOrder': true,
45
46
  'createReduceOnlyOrder': true,
46
47
  'createStopLimitOrder': true,
47
48
  'createStopMarketOrder': true,
@@ -52,8 +53,11 @@ export default class bitfinex2 extends Exchange {
52
53
  'editOrder': true,
53
54
  'fetchBalance': true,
54
55
  'fetchBorrowInterest': false,
55
- 'fetchBorrowRateHistories': false,
56
+ 'fetchBorrowRate': false,
56
57
  'fetchBorrowRateHistory': false,
58
+ 'fetchBorrowRateHistories': false,
59
+ 'fetchBorrowRates': false,
60
+ 'fetchBorrowRatesPerSymbol': false,
57
61
  'fetchClosedOrder': true,
58
62
  'fetchClosedOrders': true,
59
63
  'fetchCrossBorrowRate': false,
@@ -82,6 +86,8 @@ export default class bitfinex2 extends Exchange {
82
86
  'fetchOpenOrder': true,
83
87
  'fetchOpenOrders': true,
84
88
  'fetchOrder': true,
89
+ 'fetchOrderBook': true,
90
+ 'fetchOrderBooks': false,
85
91
  'fetchOrderTrades': true,
86
92
  'fetchPosition': false,
87
93
  'fetchPositionMode': false,
@@ -101,6 +107,8 @@ export default class bitfinex2 extends Exchange {
101
107
  'setMargin': true,
102
108
  'setMarginMode': false,
103
109
  'setPositionMode': false,
110
+ 'signIn': false,
111
+ 'transfer': true,
104
112
  'withdraw': true,
105
113
  },
106
114
  'timeframes': {
@@ -1533,7 +1541,16 @@ export default class bitfinex2 extends Exchange {
1533
1541
  * @param {float} amount how much you want to trade in units of the base currency
1534
1542
  * @param {float} [price] the price of the order, in units of the quote currency, ignored in market orders
1535
1543
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1536
- * @returns {object} request to be sent to the exchange
1544
+ * @param {float} [params.stopPrice] The price at which a trigger order is triggered at
1545
+ * @param {string} [params.timeInForce] "GTC", "IOC", "FOK", or "PO"
1546
+ * @param {bool} [params.postOnly]
1547
+ * @param {bool} [params.reduceOnly] Ensures that the executed order does not flip the opened position.
1548
+ * @param {int} [params.flags] additional order parameters: 4096 (Post Only), 1024 (Reduce Only), 16384 (OCO), 64 (Hidden), 512 (Close), 524288 (No Var Rates)
1549
+ * @param {int} [params.lev] leverage for a derivative order, supported by derivative symbol orders only. The value should be between 1 and 100 inclusive.
1550
+ * @param {string} [params.price_traling] The trailing price for a trailing stop order
1551
+ * @param {string} [params.price_aux_limit] Order price for stop limit orders
1552
+ * @param {string} [params.price_oco_stop] OCO stop price
1553
+ * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
1537
1554
  */
1538
1555
  const market = this.market(symbol);
1539
1556
  let amountString = this.amountToPrecision(symbol, amount);
package/js/src/bitget.js CHANGED
@@ -2931,8 +2931,15 @@ export default class bitget extends Exchange {
2931
2931
  const currencyCode = this.safeCurrencyCode(this.safeString(feeStructure, 'feeCoin'));
2932
2932
  fee = {
2933
2933
  'currency': currencyCode,
2934
- 'cost': Precise.stringAbs(this.safeString(feeStructure, 'totalFee')),
2935
2934
  };
2935
+ const feeCostString = this.safeString(feeStructure, 'totalFee');
2936
+ const deduction = this.safeString(feeStructure, 'deduction') === 'yes' ? true : false;
2937
+ if (deduction) {
2938
+ fee['cost'] = feeCostString;
2939
+ }
2940
+ else {
2941
+ fee['cost'] = Precise.stringNeg(feeCostString);
2942
+ }
2936
2943
  }
2937
2944
  return this.safeTrade({
2938
2945
  'info': trade,
@@ -4031,7 +4038,7 @@ export default class bitget extends Exchange {
4031
4038
  * @see https://www.bitget.com/api-doc/margin/isolated/trade/Isolated-Place-Order
4032
4039
  * @param {string} symbol unified symbol of the market to create an order in
4033
4040
  * @param {string} type 'market' or 'limit'
4034
- * @param {string} side 'buy' or 'sell' or 'open_long' or 'open_short' or 'close_long' or 'close_short'
4041
+ * @param {string} side 'buy' or 'sell'
4035
4042
  * @param {float} amount how much you want to trade in units of the base currency
4036
4043
  * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
4037
4044
  * @param {object} [params] extra parameters specific to the exchange API endpoint
@@ -4516,7 +4523,7 @@ export default class bitget extends Exchange {
4516
4523
  params = this.omit(params, ['stopPrice', 'triggerType', 'stopLossPrice', 'takeProfitPrice', 'stopLoss', 'takeProfit', 'clientOrderId', 'trailingTriggerPrice', 'trailingPercent']);
4517
4524
  let response = undefined;
4518
4525
  if (market['spot']) {
4519
- const editMarketBuyOrderRequiresPrice = this.safeValue(this.options, 'editMarketBuyOrderRequiresPrice', true);
4526
+ const editMarketBuyOrderRequiresPrice = this.safeBool(this.options, 'editMarketBuyOrderRequiresPrice', true);
4520
4527
  if (editMarketBuyOrderRequiresPrice && isMarketOrder && (side === 'buy')) {
4521
4528
  if (price === undefined) {
4522
4529
  throw new InvalidOrder(this.id + ' editOrder() requires price argument for market buy orders on spot markets to calculate the total amount to spend (amount * price), alternatively set the editMarketBuyOrderRequiresPrice option to false and pass in the cost to spend into the amount parameter');
@@ -76,13 +76,20 @@ export default class bitmart extends Exchange {
76
76
  fetchCanceledOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
77
77
  fetchOrder(id: string, symbol?: Str, params?: {}): Promise<Order>;
78
78
  fetchDepositAddress(code: string, params?: {}): Promise<{
79
+ info: any;
79
80
  currency: string;
80
81
  address: string;
81
82
  tag: string;
82
83
  network: any;
83
- info: any;
84
84
  }>;
85
- safeNetwork(networkId: any): any;
85
+ parseDepositAddress(depositAddress: any, currency?: any): {
86
+ info: any;
87
+ currency: string;
88
+ address: string;
89
+ tag: string;
90
+ network: any;
91
+ };
92
+ safeNetworkCode(networkId: any, currency?: any): string;
86
93
  withdraw(code: string, amount: number, address: any, tag?: any, params?: {}): Promise<any>;
87
94
  fetchTransactionsByType(type: any, code?: Str, since?: Int, limit?: Int, params?: {}): Promise<Transaction[]>;
88
95
  fetchDeposit(id: string, code?: Str, params?: {}): Promise<Transaction>;
package/js/src/bitmart.js CHANGED
@@ -515,6 +515,7 @@ export default class bitmart extends Exchange {
515
515
  },
516
516
  'networks': {
517
517
  'ERC20': 'ERC20',
518
+ 'SOL': 'SOL',
518
519
  'BTC': 'BTC',
519
520
  'TRC20': 'TRC20',
520
521
  // todo: should be TRX after unification
@@ -537,7 +538,6 @@ export default class bitmart extends Exchange {
537
538
  'FIO': 'FIO',
538
539
  'SCRT': 'SCRT',
539
540
  'IOTX': 'IOTX',
540
- 'SOL': 'SOL',
541
541
  'ALGO': 'ALGO',
542
542
  'ATOM': 'ATOM',
543
543
  'DOT': 'DOT',
@@ -3090,6 +3090,7 @@ export default class bitmart extends Exchange {
3090
3090
  * @method
3091
3091
  * @name bitmart#fetchDepositAddress
3092
3092
  * @description fetch the deposit address for a currency associated with this account
3093
+ * @see https://developer-pro.bitmart.com/en/spot/#deposit-address-keyed
3093
3094
  * @param {string} code unified currency code
3094
3095
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3095
3096
  * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
@@ -3112,40 +3113,57 @@ export default class bitmart extends Exchange {
3112
3113
  }
3113
3114
  const response = await this.privateGetAccountV1DepositAddress(this.extend(request, params));
3114
3115
  //
3115
- // {
3116
- // "message":"OK",
3117
- // "code":1000,
3118
- // "trace":"0e6edd79-f77f-4251-abe5-83ba75d06c1a",
3119
- // "data":{
3120
- // "currency":"USDT-TRC20",
3121
- // "chain":"USDT-TRC20",
3122
- // "address":"TGR3ghy2b5VLbyAYrmiE15jasR6aPHTvC5",
3123
- // "address_memo":""
3124
- // }
3125
- // }
3116
+ // {
3117
+ // "message": "OK",
3118
+ // "code": 1000,
3119
+ // "trace": "0e6edd79-f77f-4251-abe5-83ba75d06c1a",
3120
+ // "data": {
3121
+ // currency: 'ETH',
3122
+ // chain: 'Ethereum',
3123
+ // address: '0x99B5EEc2C520f86F0F62F05820d28D05D36EccCf',
3124
+ // address_memo: ''
3125
+ // }
3126
+ // }
3126
3127
  //
3127
3128
  const data = this.safeValue(response, 'data', {});
3128
- const address = this.safeString(data, 'address');
3129
- const tag = this.safeString(data, 'address_memo');
3130
- const chain = this.safeString(data, 'chain');
3129
+ return this.parseDepositAddress(data, currency);
3130
+ }
3131
+ parseDepositAddress(depositAddress, currency = undefined) {
3132
+ //
3133
+ // {
3134
+ // currency: 'ETH',
3135
+ // chain: 'Ethereum',
3136
+ // address: '0x99B5EEc2C520f86F0F62F05820d28D05D36EccCf',
3137
+ // address_memo: ''
3138
+ // }
3139
+ //
3140
+ const currencyId = this.safeString(depositAddress, 'currency');
3141
+ const address = this.safeString(depositAddress, 'address');
3142
+ const chain = this.safeString(depositAddress, 'chain');
3131
3143
  let network = undefined;
3144
+ currency = this.safeCurrency(currencyId, currency);
3132
3145
  if (chain !== undefined) {
3133
3146
  const parts = chain.split('-');
3134
- const networkId = this.safeString(parts, 1);
3135
- network = this.safeNetwork(networkId);
3147
+ const partsLength = parts.length;
3148
+ const networkId = this.safeString(parts, partsLength - 1);
3149
+ network = this.safeNetworkCode(networkId, currency);
3136
3150
  }
3137
3151
  this.checkAddress(address);
3138
3152
  return {
3139
- 'currency': code,
3153
+ 'info': depositAddress,
3154
+ 'currency': this.safeString(currency, 'code'),
3140
3155
  'address': address,
3141
- 'tag': tag,
3156
+ 'tag': this.safeString(depositAddress, 'address_memo'),
3142
3157
  'network': network,
3143
- 'info': response,
3144
3158
  };
3145
3159
  }
3146
- safeNetwork(networkId) {
3147
- // TODO: parse
3148
- return networkId;
3160
+ safeNetworkCode(networkId, currency = undefined) {
3161
+ const name = this.safeString(currency, 'name');
3162
+ if (networkId === name) {
3163
+ const code = this.safeString(currency, 'code');
3164
+ return code;
3165
+ }
3166
+ return this.networkIdToCode(networkId);
3149
3167
  }
3150
3168
  async withdraw(code, amount, address, tag = undefined, params = {}) {
3151
3169
  /**
package/js/src/bitmex.js CHANGED
@@ -1510,7 +1510,7 @@ export default class bitmex extends Exchange {
1510
1510
  request['endTime'] = this.iso8601(until);
1511
1511
  }
1512
1512
  const duration = this.parseTimeframe(timeframe) * 1000;
1513
- const fetchOHLCVOpenTimestamp = this.safeValue(this.options, 'fetchOHLCVOpenTimestamp', true);
1513
+ const fetchOHLCVOpenTimestamp = this.safeBool(this.options, 'fetchOHLCVOpenTimestamp', true);
1514
1514
  // if since is not set, they will return candles starting from 2017-01-01
1515
1515
  if (since !== undefined) {
1516
1516
  let timestamp = since;
@@ -1,5 +1,5 @@
1
1
  import Exchange from './abstract/blofin.js';
2
- import type { Int, OrderSide, OrderType, Trade, OHLCV, Order, FundingRateHistory, OrderRequest, Str, Transaction, Ticker, OrderBook, Balances, Tickers, Market, Strings, Currency, Position, TransferEntry, Leverage } from './base/types.js';
2
+ import type { Int, OrderSide, OrderType, Trade, OHLCV, Order, FundingRateHistory, OrderRequest, Str, Transaction, Ticker, OrderBook, Balances, Tickers, Market, Strings, Currency, Position, TransferEntry, Leverage, Leverages } from './base/types.js';
3
3
  /**
4
4
  * @class blofin
5
5
  * @augments Exchange
@@ -110,6 +110,7 @@ export default class blofin extends Exchange {
110
110
  fetchPosition(symbol: string, params?: {}): Promise<Position>;
111
111
  fetchPositions(symbols?: string[], params?: {}): Promise<Position[]>;
112
112
  parsePosition(position: any, market?: Market): Position;
113
+ fetchLeverages(symbols?: string[], params?: {}): Promise<Leverages>;
113
114
  fetchLeverage(symbol: string, params?: {}): Promise<Leverage>;
114
115
  parseLeverage(leverage: any, market?: any): Leverage;
115
116
  setLeverage(leverage: Int, symbol?: Str, params?: {}): Promise<any>;
package/js/src/blofin.js CHANGED
@@ -83,6 +83,7 @@ export default class blofin extends Exchange {
83
83
  'fetchLedger': true,
84
84
  'fetchLedgerEntry': undefined,
85
85
  'fetchLeverage': true,
86
+ 'fetchLeverages': true,
86
87
  'fetchLeverageTiers': false,
87
88
  'fetchMarketLeverageTiers': false,
88
89
  'fetchMarkets': true,
@@ -187,6 +188,7 @@ export default class blofin extends Exchange {
187
188
  'account/balance': 1,
188
189
  'account/positions': 1,
189
190
  'account/leverage-info': 1,
191
+ 'account/batch-leverage-info': 1,
190
192
  'trade/orders-tpsl-pending': 1,
191
193
  'trade/orders-history': 1,
192
194
  'trade/orders-tpsl-history': 1,
@@ -491,7 +493,7 @@ export default class blofin extends Exchange {
491
493
  const symbol = market['symbol'];
492
494
  const last = this.safeString(ticker, 'last');
493
495
  const open = this.safeString(ticker, 'open24h');
494
- const spot = this.safeValue(market, 'spot', false);
496
+ const spot = this.safeBool(market, 'spot', false);
495
497
  const quoteVolume = spot ? this.safeString(ticker, 'volCurrency24h') : undefined;
496
498
  const baseVolume = this.safeString(ticker, 'vol24h');
497
499
  const high = this.safeString(ticker, 'high24h');
@@ -1884,12 +1886,68 @@ export default class blofin extends Exchange {
1884
1886
  'takeProfitPrice': undefined,
1885
1887
  });
1886
1888
  }
1889
+ async fetchLeverages(symbols = undefined, params = {}) {
1890
+ /**
1891
+ * @method
1892
+ * @name blofin#fetchLeverages
1893
+ * @description fetch the set leverage for all contract markets
1894
+ * @see https://docs.blofin.com/index.html#get-multiple-leverage
1895
+ * @param {string[]} symbols a list of unified market symbols, required on blofin
1896
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1897
+ * @param {string} [params.marginMode] 'cross' or 'isolated'
1898
+ * @returns {object} a list of [leverage structures]{@link https://docs.ccxt.com/#/?id=leverage-structure}
1899
+ */
1900
+ await this.loadMarkets();
1901
+ if (symbols === undefined) {
1902
+ throw new ArgumentsRequired(this.id + ' fetchLeverages() requires a symbols argument');
1903
+ }
1904
+ let marginMode = undefined;
1905
+ [marginMode, params] = this.handleMarginModeAndParams('fetchLeverages', params);
1906
+ if (marginMode === undefined) {
1907
+ marginMode = this.safeString(params, 'marginMode', 'cross'); // cross as default marginMode
1908
+ }
1909
+ if ((marginMode !== 'cross') && (marginMode !== 'isolated')) {
1910
+ throw new BadRequest(this.id + ' fetchLeverages() requires a marginMode parameter that must be either cross or isolated');
1911
+ }
1912
+ symbols = this.marketSymbols(symbols);
1913
+ let instIds = '';
1914
+ for (let i = 0; i < symbols.length; i++) {
1915
+ const entry = symbols[i];
1916
+ const entryMarket = this.market(entry);
1917
+ if (i > 0) {
1918
+ instIds = instIds + ',' + entryMarket['id'];
1919
+ }
1920
+ else {
1921
+ instIds = instIds + entryMarket['id'];
1922
+ }
1923
+ }
1924
+ const request = {
1925
+ 'instId': instIds,
1926
+ 'marginMode': marginMode,
1927
+ };
1928
+ const response = await this.privateGetAccountBatchLeverageInfo(this.extend(request, params));
1929
+ //
1930
+ // {
1931
+ // "code": "0",
1932
+ // "msg": "success",
1933
+ // "data": [
1934
+ // {
1935
+ // "leverage": "3",
1936
+ // "marginMode": "cross",
1937
+ // "instId": "BTC-USDT"
1938
+ // },
1939
+ // ]
1940
+ // }
1941
+ //
1942
+ const leverages = this.safeList(response, 'data', []);
1943
+ return this.parseLeverages(leverages, symbols, 'instId');
1944
+ }
1887
1945
  async fetchLeverage(symbol, params = {}) {
1888
1946
  /**
1889
1947
  * @method
1890
1948
  * @name blofin#fetchLeverage
1891
1949
  * @description fetch the set leverage for a market
1892
- * @see https://blofin.com/docs#set-leverage
1950
+ * @see https://docs.blofin.com/index.html#get-leverage
1893
1951
  * @param {string} symbol unified market symbol
1894
1952
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1895
1953
  * @param {string} [params.marginMode] 'cross' or 'isolated'
@@ -3068,10 +3068,12 @@ export default class coinbase extends Exchange {
3068
3068
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
3069
3069
  */
3070
3070
  await this.loadMarkets();
3071
+ const maxLimit = 300;
3072
+ limit = (limit === undefined) ? maxLimit : Math.min(limit, maxLimit);
3071
3073
  let paginate = false;
3072
3074
  [paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate', false);
3073
3075
  if (paginate) {
3074
- return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 299);
3076
+ return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimit - 1);
3075
3077
  }
3076
3078
  const market = this.market(symbol);
3077
3079
  const request = {
@@ -3081,20 +3083,20 @@ export default class coinbase extends Exchange {
3081
3083
  const until = this.safeValueN(params, ['until', 'till', 'end']);
3082
3084
  params = this.omit(params, ['until', 'till']);
3083
3085
  const duration = this.parseTimeframe(timeframe);
3084
- const candles300 = 300 * duration;
3086
+ const requestedDuration = limit * duration;
3085
3087
  let sinceString = undefined;
3086
3088
  if (since !== undefined) {
3087
3089
  sinceString = this.numberToString(this.parseToInt(since / 1000));
3088
3090
  }
3089
3091
  else {
3090
3092
  const now = this.seconds().toString();
3091
- sinceString = Precise.stringSub(now, candles300.toString());
3093
+ sinceString = Precise.stringSub(now, requestedDuration.toString());
3092
3094
  }
3093
3095
  request['start'] = sinceString;
3094
3096
  let endString = this.numberToString(until);
3095
3097
  if (until === undefined) {
3096
3098
  // 300 candles max
3097
- endString = Precise.stringAdd(sinceString, candles300.toString());
3099
+ endString = Precise.stringAdd(sinceString, requestedDuration.toString());
3098
3100
  }
3099
3101
  request['end'] = endString;
3100
3102
  const response = await this.v3PrivateGetBrokerageProductsProductIdCandles(this.extend(request, params));
@@ -3154,8 +3156,19 @@ export default class coinbase extends Exchange {
3154
3156
  const request = {
3155
3157
  'product_id': market['id'],
3156
3158
  };
3159
+ if (since !== undefined) {
3160
+ request['start'] = this.numberToString(this.parseToInt(since / 1000));
3161
+ }
3157
3162
  if (limit !== undefined) {
3158
- request['limit'] = limit;
3163
+ request['limit'] = Math.min(limit, 1000);
3164
+ }
3165
+ let until = undefined;
3166
+ [until, params] = this.handleOptionAndParams(params, 'fetchTrades', 'until');
3167
+ if (until !== undefined) {
3168
+ request['end'] = this.numberToString(this.parseToInt(until / 1000));
3169
+ }
3170
+ else if (since !== undefined) {
3171
+ throw new ArgumentsRequired(this.id + ' fetchTrades() requires a `until` parameter when you use `since` argument');
3159
3172
  }
3160
3173
  const response = await this.v3PrivateGetBrokerageProductsProductIdTicker(this.extend(request, params));
3161
3174
  //
@@ -3289,7 +3302,7 @@ export default class coinbase extends Exchange {
3289
3302
  // }
3290
3303
  // }
3291
3304
  //
3292
- const data = this.safeValue(response, 'pricebook', {});
3305
+ const data = this.safeDict(response, 'pricebook', {});
3293
3306
  const time = this.safeString(data, 'time');
3294
3307
  const timestamp = this.parse8601(time);
3295
3308
  return this.parseOrderBook(data, symbol, timestamp, 'bids', 'asks', 'price', 'size');
@@ -3742,7 +3755,7 @@ export default class coinbase extends Exchange {
3742
3755
  }
3743
3756
  else {
3744
3757
  this.checkRequiredCredentials();
3745
- const nonce = this.nonce().toString();
3758
+ const timestampString = this.seconds().toString();
3746
3759
  let payload = '';
3747
3760
  if (method !== 'GET') {
3748
3761
  if (Object.keys(query).length) {
@@ -3750,17 +3763,14 @@ export default class coinbase extends Exchange {
3750
3763
  payload = body;
3751
3764
  }
3752
3765
  }
3753
- else {
3754
- if (Object.keys(query).length) {
3755
- payload += '?' + this.urlencode(query);
3756
- }
3757
- }
3758
- const auth = nonce + method + savedPath + payload;
3766
+ // 'GET' doesn't need payload in the signature. inside url is enough
3767
+ // https://docs.cloud.coinbase.com/advanced-trade-api/docs/auth#example-request
3768
+ const auth = timestampString + method + savedPath + payload;
3759
3769
  const signature = this.hmac(this.encode(auth), this.encode(this.secret), sha256);
3760
3770
  headers = {
3761
3771
  'CB-ACCESS-KEY': this.apiKey,
3762
3772
  'CB-ACCESS-SIGN': signature,
3763
- 'CB-ACCESS-TIMESTAMP': nonce,
3773
+ 'CB-ACCESS-TIMESTAMP': timestampString,
3764
3774
  'Content-Type': 'application/json',
3765
3775
  };
3766
3776
  }
package/js/src/hitbtc.js CHANGED
@@ -2702,7 +2702,7 @@ export default class hitbtc extends Exchange {
2702
2702
  if ((network !== undefined) && (code === 'USDT')) {
2703
2703
  const parsedNetwork = this.safeString(networks, network);
2704
2704
  if (parsedNetwork !== undefined) {
2705
- request['currency'] = parsedNetwork;
2705
+ request['network_code'] = parsedNetwork;
2706
2706
  }
2707
2707
  params = this.omit(params, 'network');
2708
2708
  }
package/js/src/htx.js CHANGED
@@ -2594,7 +2594,10 @@ export default class htx extends Exchange {
2594
2594
  amountString = this.safeString(trade, 'trade_volume', amountString);
2595
2595
  const costString = this.safeString(trade, 'trade_turnover');
2596
2596
  let fee = undefined;
2597
- let feeCost = this.safeString2(trade, 'filled-fees', 'trade_fee');
2597
+ let feeCost = this.safeString(trade, 'filled-fees');
2598
+ if (feeCost === undefined) {
2599
+ feeCost = Precise.stringNeg(this.safeString(trade, 'trade_fee'));
2600
+ }
2598
2601
  const feeCurrencyId = this.safeString2(trade, 'fee-currency', 'fee_asset');
2599
2602
  let feeCurrency = this.safeCurrencyCode(feeCurrencyId);
2600
2603
  const filledPoints = this.safeString(trade, 'filled-points');