ccxt 4.3.22__py2.py3-none-any.whl → 4.3.23__py2.py3-none-any.whl

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.

Potentially problematic release.


This version of ccxt might be problematic. Click here for more details.

@@ -220,41 +220,22 @@ class probit(Exchange, ImplicitAPI):
220
220
  },
221
221
  },
222
222
  'commonCurrencies': {
223
- 'AUTO': 'Cube',
224
- 'AZU': 'Azultec',
225
- 'BCC': 'BCC',
226
- 'BDP': 'BidiPass',
227
- 'BIRD': 'Birdchain',
228
- 'BTCBEAR': 'BEAR',
229
- 'BTCBULL': 'BULL',
223
+ 'BB': 'Baby Bali',
230
224
  'CBC': 'CryptoBharatCoin',
231
- 'CHE': 'Chellit',
232
- 'CLR': 'Color Platform',
233
225
  'CTK': 'Cryptyk',
234
226
  'CTT': 'Castweet',
235
- 'DIP': 'Dipper',
236
227
  'DKT': 'DAKOTA',
237
228
  'EGC': 'EcoG9coin',
238
229
  'EPS': 'Epanus', # conflict with EPS Ellipsis https://github.com/ccxt/ccxt/issues/8909
239
230
  'FX': 'Fanzy',
240
- 'GDT': 'Gorilla Diamond',
241
231
  'GM': 'GM Holding',
242
232
  'GOGOL': 'GOL',
243
233
  'GOL': 'Goldofir',
244
- 'GRB': 'Global Reward Bank',
245
- 'HBC': 'Hybrid Bank Cash',
246
234
  'HUSL': 'The Hustle App',
247
235
  'LAND': 'Landbox',
248
- 'LBK': 'Legal Block',
249
- 'ORC': 'Oracle System',
250
- 'PXP': 'PIXSHOP COIN',
251
- 'PYE': 'CreamPYE',
252
- 'ROOK': 'Reckoon',
253
- 'SOC': 'Soda Coin',
254
236
  'SST': 'SocialSwap',
255
237
  'TCT': 'Top Coin Token',
256
238
  'TOR': 'Torex',
257
- 'TPAY': 'Tetra Pay',
258
239
  'UNI': 'UNICORN Token',
259
240
  'UNISWAP': 'UNI',
260
241
  },
@@ -245,6 +245,15 @@ class whitebit(Exchange, ImplicitAPI):
245
245
  'convert/estimate',
246
246
  'convert/confirm',
247
247
  'convert/history',
248
+ 'sub-account/create',
249
+ 'sub-account/delete',
250
+ 'sub-account/edit',
251
+ 'sub-account/list',
252
+ 'sub-account/transfer',
253
+ 'sub-account/block',
254
+ 'sub-account/unblock',
255
+ 'sub-account/balances',
256
+ 'sub-account/transfer/history',
248
257
  ],
249
258
  },
250
259
  },
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.22'
7
+ __version__ = '4.3.23'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
ccxt/binance.py CHANGED
@@ -9003,7 +9003,7 @@ class binance(Exchange, ImplicitAPI):
9003
9003
  self.load_markets()
9004
9004
  # by default cache the leverage bracket
9005
9005
  # it contains useful stuff like the maintenance margin and initial margin for positions
9006
- leverageBrackets = self.safe_dict(self.options, 'leverageBrackets', {})
9006
+ leverageBrackets = self.safe_dict(self.options, 'leverageBrackets')
9007
9007
  if (leverageBrackets is None) or (reload):
9008
9008
  defaultType = self.safe_string(self.options, 'defaultType', 'future')
9009
9009
  type = self.safe_string(params, 'type', defaultType)
ccxt/coinbase.py CHANGED
@@ -1753,6 +1753,10 @@ class coinbase(Exchange, ImplicitAPI):
1753
1753
  request = {}
1754
1754
  if symbols is not None:
1755
1755
  request['product_ids'] = self.market_ids(symbols)
1756
+ marketType = None
1757
+ marketType, params = self.handle_market_type_and_params('fetchTickers', self.get_market_from_symbols(symbols), params, 'default')
1758
+ if marketType is not None and marketType != 'default':
1759
+ request['product_type'] = 'FUTURE' if (marketType == 'swap') else 'SPOT'
1756
1760
  response = self.v3PublicGetBrokerageMarketProducts(self.extend(request, params))
1757
1761
  #
1758
1762
  # {
ccxt/coinex.py CHANGED
@@ -10,6 +10,7 @@ from typing import List
10
10
  from ccxt.base.errors import ExchangeError
11
11
  from ccxt.base.errors import AuthenticationError
12
12
  from ccxt.base.errors import PermissionDenied
13
+ from ccxt.base.errors import AccountSuspended
13
14
  from ccxt.base.errors import ArgumentsRequired
14
15
  from ccxt.base.errors import BadRequest
15
16
  from ccxt.base.errors import BadSymbol
@@ -480,10 +481,53 @@ class coinex(Exchange, ImplicitAPI):
480
481
  '36': RequestTimeout, # Service timeout
481
482
  '213': RateLimitExceeded, # Too many requests
482
483
  '107': InsufficientFunds,
484
+ '158': PermissionDenied, # {"code":158,"data":{},"message":"API permission is not allowed"}
483
485
  '600': OrderNotFound,
484
486
  '601': InvalidOrder,
485
487
  '602': InvalidOrder,
486
488
  '606': InvalidOrder,
489
+ '3008': RequestTimeout, # Service busy, please try again later.
490
+ '3109': InsufficientFunds, # {"code":3109,"data":{},"message":"balance not enough"}
491
+ '3127': InvalidOrder, # The order quantity is below the minimum requirement. Please adjust the order quantity.
492
+ '3606': InvalidOrder, # The price difference between the order price and the latest price is too large. Please adjust the order amount accordingly.
493
+ '3610': ExchangeError, # Order cancellation prohibited during the Call Auction period.
494
+ '3612': InvalidOrder, # The est. ask price is lower than the current bottom ask price. Please reduce the amount.
495
+ '3613': InvalidOrder, # The est. bid price is higher than the current top bid price. Please reduce the amount.
496
+ '3614': InvalidOrder, # The deviation between your est. filled price and the index price. Please reduce the amount.
497
+ '3615': InvalidOrder, # The deviation between your order price and the index price is too high. Please adjust your order price and try again.
498
+ '3616': InvalidOrder, # The order price exceeds the current top bid price. Please adjust the order price and try again.
499
+ '3617': InvalidOrder, # The order price exceeds the current bottom ask price. Please adjust the order price and try again.
500
+ '3618': InvalidOrder, # The deviation between your order price and the index price is too high. Please adjust your order price and try again.
501
+ '3619': InvalidOrder, # The deviation between your order price and the trigger price is too high. Please adjust your order price and try again.
502
+ '3620': InvalidOrder, # Market order submission is temporarily unavailable due to insufficient depth in the current market
503
+ '3621': InvalidOrder, # This order can't be completely executed and has been canceled.
504
+ '3622': InvalidOrder, # This order can't be set Only and has been canceled.
505
+ '3627': InvalidOrder, # The current market depth is low, please reduce your order amount and try again.
506
+ '3628': InvalidOrder, # The current market depth is low, please reduce your order amount and try again.
507
+ '3629': InvalidOrder, # The current market depth is low, please reduce your order amount and try again.
508
+ '3632': InvalidOrder, # The order price exceeds the current top bid price. Please adjust the order price and try again.
509
+ '3633': InvalidOrder, # The order price exceeds the current bottom ask price. Please adjust the order price and try again.
510
+ '3634': InvalidOrder, # The deviation between your est. filled price and the index price is too high. Please reduce the amount and try again.
511
+ '3635': InvalidOrder, # The deviation between your est. filled price and the index price is too high. Please reduce the amount and try again.
512
+ '4001': ExchangeNotAvailable, # Service unavailable, please try again later.
513
+ '4002': RequestTimeout, # Service request timed out, please try again later.
514
+ '4003': ExchangeError, # Internal error, please contact customer service for help.
515
+ '4004': BadRequest, # Parameter error, please check whether the request parameters are abnormal.
516
+ '4005': AuthenticationError, # Abnormal access_id, please check whether the value passed by X-COINEX-KEY is normal.
517
+ '4006': AuthenticationError, # Signature verification failed, please check the signature according to the documentation instructions.
518
+ '4007': PermissionDenied, # IP address prohibited, please check whether the whitelist or export IP is normal.
519
+ '4008': AuthenticationError, # Abnormal X-COIN-SIGN value, please check.
520
+ '4009': ExchangeError, # Abnormal request method, please check.
521
+ '4010': ExchangeError, # Expired request, please try again later.
522
+ '4011': PermissionDenied, # User prohibited from accessing, please contact customer service for help.
523
+ '4017': ExchangeError, # Signature expired, please try again later.
524
+ '4115': AccountSuspended, # User prohibited from trading, please contact customer service for help.
525
+ '4117': BadSymbol, # Trading hasattr(self, prohibited) market, please try again later.
526
+ '4123': RateLimitExceeded, # Rate limit triggered. Please adjust your strategy and reduce the request rate.
527
+ '4130': ExchangeError, # Futures trading prohibited, please try again later.
528
+ '4158': ExchangeError, # Trading prohibited, please try again later.
529
+ '4213': RateLimitExceeded, # The request is too frequent, please try again later.
530
+ '4512': PermissionDenied, # Insufficient sub-account permissions, please check.
487
531
  },
488
532
  'broad': {
489
533
  'ip not allow visit': PermissionDenied,
@@ -4138,8 +4182,8 @@ class coinex(Exchange, ImplicitAPI):
4138
4182
 
4139
4183
  def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4140
4184
  """
4141
- fetch the history of funding payments paid and received on self account
4142
- :see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http034_funding_position
4185
+ fetch the history of funding fee payments paid and received on self account
4186
+ :see: https://docs.coinex.com/api/v2/futures/position/http/list-position-funding-history
4143
4187
  :param str symbol: unified market symbol
4144
4188
  :param int [since]: the earliest time in ms to fetch funding history for
4145
4189
  :param int [limit]: the maximum number of funding history structures to retrieve
@@ -4148,53 +4192,45 @@ class coinex(Exchange, ImplicitAPI):
4148
4192
  """
4149
4193
  if symbol is None:
4150
4194
  raise ArgumentsRequired(self.id + ' fetchFundingHistory() requires a symbol argument')
4151
- limit = 100 if (limit is None) else limit
4152
4195
  self.load_markets()
4153
4196
  market = self.market(symbol)
4154
4197
  request = {
4155
4198
  'market': market['id'],
4156
- 'limit': limit,
4157
- # 'offset': 0,
4158
- # 'end_time': 1638990636000,
4159
- # 'windowtime': 1638990636000,
4199
+ 'market_type': 'FUTURES',
4160
4200
  }
4201
+ request, params = self.handle_until_option('end_time', request, params)
4161
4202
  if since is not None:
4162
4203
  request['start_time'] = since
4163
- response = self.v1PerpetualPrivateGetPositionFunding(self.extend(request, params))
4204
+ if limit is not None:
4205
+ request['limit'] = limit
4206
+ response = self.v2PrivateGetFuturesPositionFundingHistory(self.extend(request, params))
4164
4207
  #
4165
4208
  # {
4166
4209
  # "code": 0,
4167
- # "data": {
4168
- # "limit": 100,
4169
- # "offset": 0,
4170
- # "records": [
4171
- # {
4172
- # "amount": "0.0012",
4173
- # "asset": "USDT",
4174
- # "funding": "-0.0095688273996",
4175
- # "funding_rate": "0.00020034",
4176
- # "market": "BTCUSDT",
4177
- # "position_id": 62052321,
4178
- # "price": "39802.45",
4179
- # "real_funding_rate": "0.00020034",
4180
- # "side": 2,
4181
- # "time": 1650729623.933885,
4182
- # "type": 1,
4183
- # "user_id": 3620173,
4184
- # "value": "47.76294"
4185
- # },
4186
- # ]
4187
- # },
4188
- # "message": "OK"
4210
+ # "data": [
4211
+ # {
4212
+ # "ccy": "USDT",
4213
+ # "created_at": 1715673620183,
4214
+ # "funding_rate": "0",
4215
+ # "funding_value": "0",
4216
+ # "market": "BTCUSDT",
4217
+ # "market_type": "FUTURES",
4218
+ # "position_id": 306458800,
4219
+ # "side": "long"
4220
+ # },
4221
+ # ],
4222
+ # "message": "OK",
4223
+ # "pagination": {
4224
+ # "has_next": True
4225
+ # }
4189
4226
  # }
4190
4227
  #
4191
- data = self.safe_value(response, 'data', {})
4192
- resultList = self.safe_value(data, 'records', [])
4228
+ data = self.safe_list(response, 'data', [])
4193
4229
  result = []
4194
- for i in range(0, len(resultList)):
4195
- entry = resultList[i]
4196
- timestamp = self.safe_timestamp(entry, 'time')
4197
- currencyId = self.safe_string(entry, 'asset')
4230
+ for i in range(0, len(data)):
4231
+ entry = data[i]
4232
+ timestamp = self.safe_integer(entry, 'created_at')
4233
+ currencyId = self.safe_string(entry, 'ccy')
4198
4234
  code = self.safe_currency_code(currencyId)
4199
4235
  result.append({
4200
4236
  'info': entry,
@@ -4203,14 +4239,14 @@ class coinex(Exchange, ImplicitAPI):
4203
4239
  'timestamp': timestamp,
4204
4240
  'datetime': self.iso8601(timestamp),
4205
4241
  'id': self.safe_number(entry, 'position_id'),
4206
- 'amount': self.safe_number(entry, 'funding'),
4242
+ 'amount': self.safe_number(entry, 'funding_value'),
4207
4243
  })
4208
4244
  return result
4209
4245
 
4210
4246
  def fetch_funding_rate(self, symbol: str, params={}):
4211
4247
  """
4212
4248
  fetch the current funding rate
4213
- :see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http008_market_ticker
4249
+ :see: https://docs.coinex.com/api/v2/futures/market/http/list-market-funding-rate
4214
4250
  :param str symbol: unified market symbol
4215
4251
  :param dict [params]: extra parameters specific to the exchange API endpoint
4216
4252
  :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
@@ -4222,93 +4258,63 @@ class coinex(Exchange, ImplicitAPI):
4222
4258
  request = {
4223
4259
  'market': market['id'],
4224
4260
  }
4225
- response = self.v1PerpetualPublicGetMarketTicker(self.extend(request, params))
4261
+ response = self.v2PublicGetFuturesFundingRate(self.extend(request, params))
4226
4262
  #
4227
4263
  # {
4228
- # "code": 0,
4229
- # "data":
4230
- # {
4231
- # "date": 1650678472474,
4232
- # "ticker": {
4233
- # "vol": "6090.9430",
4234
- # "low": "39180.30",
4235
- # "open": "40474.97",
4236
- # "high": "40798.01",
4237
- # "last": "39659.30",
4238
- # "buy": "39663.79",
4239
- # "period": 86400,
4240
- # "funding_time": 372,
4241
- # "position_amount": "270.1956",
4242
- # "funding_rate_last": "0.00022913",
4243
- # "funding_rate_next": "0.00013158",
4244
- # "funding_rate_predict": "0.00016552",
4245
- # "insurance": "16045554.83969682659674035672",
4246
- # "sign_price": "39652.48",
4247
- # "index_price": "39648.44250000",
4248
- # "sell_total": "22.3913",
4249
- # "buy_total": "19.4498",
4250
- # "buy_amount": "12.8942",
4251
- # "sell": "39663.80",
4252
- # "sell_amount": "0.9388"
4264
+ # "code": 0,
4265
+ # "data": [
4266
+ # {
4267
+ # "latest_funding_rate": "0",
4268
+ # "latest_funding_time": 1715731200000,
4269
+ # "mark_price": "61602.22",
4270
+ # "market": "BTCUSDT",
4271
+ # "max_funding_rate": "0.00375",
4272
+ # "min_funding_rate": "-0.00375",
4273
+ # "next_funding_rate": "0.00021074",
4274
+ # "next_funding_time": 1715760000000
4253
4275
  # }
4254
- # },
4276
+ # ],
4255
4277
  # "message": "OK"
4256
4278
  # }
4257
4279
  #
4258
- data = self.safe_value(response, 'data', {})
4259
- ticker = self.safe_value(data, 'ticker', {})
4260
- timestamp = self.safe_integer(data, 'date')
4261
- ticker['timestamp'] = timestamp # avoid changing parseFundingRate signature
4262
- return self.parse_funding_rate(ticker, market)
4280
+ data = self.safe_list(response, 'data', [])
4281
+ first = self.safe_dict(data, 0, {})
4282
+ return self.parse_funding_rate(first, market)
4263
4283
 
4264
4284
  def parse_funding_rate(self, contract, market: Market = None):
4265
4285
  #
4266
- # fetchFundingRate
4286
+ # fetchFundingRate, fetchFundingRates
4267
4287
  #
4268
4288
  # {
4269
- # "vol": "6090.9430",
4270
- # "low": "39180.30",
4271
- # "open": "40474.97",
4272
- # "high": "40798.01",
4273
- # "last": "39659.30",
4274
- # "buy": "39663.79",
4275
- # "period": 86400,
4276
- # "funding_time": 372,
4277
- # "position_amount": "270.1956",
4278
- # "funding_rate_last": "0.00022913",
4279
- # "funding_rate_next": "0.00013158",
4280
- # "funding_rate_predict": "0.00016552",
4281
- # "insurance": "16045554.83969682659674035672",
4282
- # "sign_price": "39652.48",
4283
- # "index_price": "39648.44250000",
4284
- # "sell_total": "22.3913",
4285
- # "buy_total": "19.4498",
4286
- # "buy_amount": "12.8942",
4287
- # "sell": "39663.80",
4288
- # "sell_amount": "0.9388"
4289
+ # "latest_funding_rate": "0",
4290
+ # "latest_funding_time": 1715731200000,
4291
+ # "mark_price": "61602.22",
4292
+ # "market": "BTCUSDT",
4293
+ # "max_funding_rate": "0.00375",
4294
+ # "min_funding_rate": "-0.00375",
4295
+ # "next_funding_rate": "0.00021074",
4296
+ # "next_funding_time": 1715760000000
4289
4297
  # }
4290
4298
  #
4291
- timestamp = self.safe_integer(contract, 'timestamp')
4292
- contract = self.omit(contract, 'timestamp')
4293
- fundingDelta = self.safe_integer(contract, 'funding_time') * 60 * 1000
4294
- fundingHour = (timestamp + fundingDelta) / 3600000
4295
- fundingTimestamp = int(round(fundingHour)) * 3600000
4299
+ currentFundingTimestamp = self.safe_integer(contract, 'latest_funding_time')
4300
+ futureFundingTimestamp = self.safe_integer(contract, 'next_funding_time')
4301
+ marketId = self.safe_string(contract, 'market')
4296
4302
  return {
4297
4303
  'info': contract,
4298
- 'symbol': self.safe_symbol(None, market),
4299
- 'markPrice': self.safe_number(contract, 'sign_price'),
4300
- 'indexPrice': self.safe_number(contract, 'index_price'),
4304
+ 'symbol': self.safe_symbol(marketId, market, None, 'swap'),
4305
+ 'markPrice': self.safe_number(contract, 'mark_price'),
4306
+ 'indexPrice': None,
4301
4307
  'interestRate': None,
4302
4308
  'estimatedSettlePrice': None,
4303
- 'timestamp': timestamp,
4304
- 'datetime': self.iso8601(timestamp),
4305
- 'fundingRate': self.safe_number(contract, 'funding_rate_next'),
4306
- 'fundingTimestamp': fundingTimestamp,
4307
- 'fundingDatetime': self.iso8601(fundingTimestamp),
4308
- 'nextFundingRate': self.safe_number(contract, 'funding_rate_predict'),
4309
- 'nextFundingTimestamp': None,
4310
- 'nextFundingDatetime': None,
4311
- 'previousFundingRate': self.safe_number(contract, 'funding_rate_last'),
4309
+ 'timestamp': None,
4310
+ 'datetime': None,
4311
+ 'fundingRate': self.safe_number(contract, 'latest_funding_rate'),
4312
+ 'fundingTimestamp': currentFundingTimestamp,
4313
+ 'fundingDatetime': self.iso8601(currentFundingTimestamp),
4314
+ 'nextFundingRate': self.safe_number(contract, 'next_funding_rate'),
4315
+ 'nextFundingTimestamp': futureFundingTimestamp,
4316
+ 'nextFundingDatetime': self.iso8601(futureFundingTimestamp),
4317
+ 'previousFundingRate': None,
4312
4318
  'previousFundingTimestamp': None,
4313
4319
  'previousFundingDatetime': None,
4314
4320
  }
@@ -4316,65 +4322,43 @@ class coinex(Exchange, ImplicitAPI):
4316
4322
  def fetch_funding_rates(self, symbols: Strings = None, params={}):
4317
4323
  """
4318
4324
  fetch the current funding rates
4319
- :see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http009_market_ticker_all
4325
+ :see: https://docs.coinex.com/api/v2/futures/market/http/list-market-funding-rate
4320
4326
  :param str[] symbols: unified market symbols
4321
4327
  :param dict [params]: extra parameters specific to the exchange API endpoint
4322
4328
  :returns dict[]: an array of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-structure>`
4323
4329
  """
4324
4330
  self.load_markets()
4325
4331
  symbols = self.market_symbols(symbols)
4332
+ request = {}
4326
4333
  market = None
4327
4334
  if symbols is not None:
4328
4335
  symbol = self.safe_value(symbols, 0)
4329
4336
  market = self.market(symbol)
4330
4337
  if not market['swap']:
4331
4338
  raise BadSymbol(self.id + ' fetchFundingRates() supports swap contracts only')
4332
- response = self.v1PerpetualPublicGetMarketTickerAll(params)
4339
+ marketIds = self.market_ids(symbols)
4340
+ request['market'] = ','.join(marketIds)
4341
+ response = self.v2PublicGetFuturesFundingRate(self.extend(request, params))
4333
4342
  #
4334
4343
  # {
4335
4344
  # "code": 0,
4336
- # "data":
4337
- # {
4338
- # "date": 1650678472474,
4339
- # "ticker": {
4340
- # "BTCUSDT": {
4341
- # "vol": "6090.9430",
4342
- # "low": "39180.30",
4343
- # "open": "40474.97",
4344
- # "high": "40798.01",
4345
- # "last": "39659.30",
4346
- # "buy": "39663.79",
4347
- # "period": 86400,
4348
- # "funding_time": 372,
4349
- # "position_amount": "270.1956",
4350
- # "funding_rate_last": "0.00022913",
4351
- # "funding_rate_next": "0.00013158",
4352
- # "funding_rate_predict": "0.00016552",
4353
- # "insurance": "16045554.83969682659674035672",
4354
- # "sign_price": "39652.48",
4355
- # "index_price": "39648.44250000",
4356
- # "sell_total": "22.3913",
4357
- # "buy_total": "19.4498",
4358
- # "buy_amount": "12.8942",
4359
- # "sell": "39663.80",
4360
- # "sell_amount": "0.9388"
4361
- # }
4345
+ # "data": [
4346
+ # {
4347
+ # "latest_funding_rate": "0",
4348
+ # "latest_funding_time": 1715731200000,
4349
+ # "mark_price": "61602.22",
4350
+ # "market": "BTCUSDT",
4351
+ # "max_funding_rate": "0.00375",
4352
+ # "min_funding_rate": "-0.00375",
4353
+ # "next_funding_rate": "0.00021074",
4354
+ # "next_funding_time": 1715760000000
4362
4355
  # }
4363
- # },
4356
+ # ],
4364
4357
  # "message": "OK"
4365
4358
  # }
4366
- data = self.safe_value(response, 'data', {})
4367
- tickers = self.safe_value(data, 'ticker', {})
4368
- timestamp = self.safe_integer(data, 'date')
4369
- result = []
4370
- marketIds = list(tickers.keys())
4371
- for i in range(0, len(marketIds)):
4372
- marketId = marketIds[i]
4373
- if marketId.find('_') == -1: # skip _signprice and _indexprice
4374
- marketInner = self.safe_market(marketId, None, None, 'swap')
4375
- ticker = tickers[marketId]
4376
- ticker['timestamp'] = timestamp
4377
- result.append(self.parse_funding_rate(ticker, marketInner))
4359
+ #
4360
+ data = self.safe_list(response, 'data', [])
4361
+ result = self.parse_funding_rates(data, market)
4378
4362
  return self.filter_by_array(result, 'symbol', symbols)
4379
4363
 
4380
4364
  def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
@@ -4442,13 +4426,13 @@ class coinex(Exchange, ImplicitAPI):
4442
4426
 
4443
4427
  def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4444
4428
  """
4445
- :see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http038_funding_history
4446
4429
  fetches historical funding rate prices
4430
+ :see: https://docs.coinex.com/api/v2/futures/market/http/list-market-funding-rate-history
4447
4431
  :param str symbol: unified symbol of the market to fetch the funding rate history for
4448
4432
  :param int [since]: timestamp in ms of the earliest funding rate to fetch
4449
4433
  :param int [limit]: the maximum amount of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>` to fetch
4450
4434
  :param dict [params]: extra parameters specific to the exchange API endpoint
4451
- :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
4435
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
4452
4436
  :param int [params.until]: timestamp in ms of the latest funding rate
4453
4437
  :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>`
4454
4438
  """
@@ -4459,50 +4443,44 @@ class coinex(Exchange, ImplicitAPI):
4459
4443
  paginate, params = self.handle_option_and_params(params, 'fetchFundingRateHistory', 'paginate')
4460
4444
  if paginate:
4461
4445
  return self.fetch_paginated_call_deterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params, 1000)
4462
- if limit is None:
4463
- limit = 100
4464
4446
  market = self.market(symbol)
4465
4447
  request = {
4466
4448
  'market': market['id'],
4467
- 'limit': limit,
4468
- 'offset': 0,
4469
- # 'end_time': 1638990636,
4470
4449
  }
4471
4450
  if since is not None:
4472
4451
  request['start_time'] = since
4452
+ if limit is not None:
4453
+ request['limit'] = limit
4473
4454
  request, params = self.handle_until_option('end_time', request, params)
4474
- response = self.v1PerpetualPublicGetMarketFundingHistory(self.extend(request, params))
4455
+ response = self.v2PublicGetFuturesFundingRateHistory(self.extend(request, params))
4475
4456
  #
4476
4457
  # {
4477
4458
  # "code": 0,
4478
- # "data": {
4479
- # "offset": 0,
4480
- # "limit": 3,
4481
- # "records": [
4482
- # {
4483
- # "time": 1650672021.6230309,
4484
- # "market": "BTCUSDT",
4485
- # "asset": "USDT",
4486
- # "funding_rate": "0.00022913",
4487
- # "funding_rate_real": "0.00022913"
4488
- # },
4489
- # ]
4490
- # },
4491
- # "message": "OK"
4459
+ # "data": [
4460
+ # {
4461
+ # "actual_funding_rate": "0",
4462
+ # "funding_time": 1715731221761,
4463
+ # "market": "BTCUSDT",
4464
+ # "theoretical_funding_rate": "0"
4465
+ # },
4466
+ # ],
4467
+ # "message": "OK",
4468
+ # "pagination": {
4469
+ # "has_next": True
4470
+ # }
4492
4471
  # }
4493
4472
  #
4494
- data = self.safe_value(response, 'data')
4495
- result = self.safe_value(data, 'records', [])
4473
+ data = self.safe_list(response, 'data', [])
4496
4474
  rates = []
4497
- for i in range(0, len(result)):
4498
- entry = result[i]
4475
+ for i in range(0, len(data)):
4476
+ entry = data[i]
4499
4477
  marketId = self.safe_string(entry, 'market')
4500
4478
  symbolInner = self.safe_symbol(marketId, market, None, 'swap')
4501
- timestamp = self.safe_timestamp(entry, 'time')
4479
+ timestamp = self.safe_integer(entry, 'funding_time')
4502
4480
  rates.append({
4503
4481
  'info': entry,
4504
4482
  'symbol': symbolInner,
4505
- 'fundingRate': self.safe_number(entry, 'funding_rate'),
4483
+ 'fundingRate': self.safe_number(entry, 'actual_funding_rate'),
4506
4484
  'timestamp': timestamp,
4507
4485
  'datetime': self.iso8601(timestamp),
4508
4486
  })
ccxt/phemex.py CHANGED
@@ -3638,7 +3638,8 @@ class phemex(Exchange, ImplicitAPI):
3638
3638
  raise BadRequest(self.id + ' fetchFundingHistory() limit argument cannot exceed 200')
3639
3639
  request['limit'] = limit
3640
3640
  response = None
3641
- if market['settle'] == 'USDT':
3641
+ isUsdt = market['settle'] == 'USDT'
3642
+ if isUsdt:
3642
3643
  response = self.privateGetApiDataGFuturesFundingFees(self.extend(request, params))
3643
3644
  else:
3644
3645
  response = self.privateGetApiDataFuturesFundingFees(self.extend(request, params))
@@ -3651,13 +3652,13 @@ class phemex(Exchange, ImplicitAPI):
3651
3652
  # {
3652
3653
  # "symbol": "BTCUSD",
3653
3654
  # "currency": "BTC",
3654
- # "execQty": 18,
3655
+ # "execQty": 18, # "execQty" regular, but "execQtyRq" in hedge
3655
3656
  # "side": "Buy",
3656
- # "execPriceEp": 360086455,
3657
- # "execValueEv": 49987,
3658
- # "fundingRateEr": 10000,
3659
- # "feeRateEr": 10000,
3660
- # "execFeeEv": 5,
3657
+ # "execPriceEp": 360086455, # "execPriceEp" regular, but "execPriceRp" in hedge
3658
+ # "execValueEv": 49987, # "execValueEv" regular, but "execValueRv" in hedge
3659
+ # "fundingRateEr": 10000, # "fundingRateEr" regular, but "fundingRateRr" in hedge
3660
+ # "feeRateEr": 10000, # "feeRateEr" regular, but "feeRateRr" in hedge
3661
+ # "execFeeEv": 5, # "execFeeEv" regular, but "execFeeRv" in hedge
3661
3662
  # "createTime": 1651881600000
3662
3663
  # }
3663
3664
  # ]
@@ -3670,17 +3671,31 @@ class phemex(Exchange, ImplicitAPI):
3670
3671
  for i in range(0, len(rows)):
3671
3672
  entry = rows[i]
3672
3673
  timestamp = self.safe_integer(entry, 'createTime')
3674
+ execFee = self.safe_string_2(entry, 'execFeeEv', 'execFeeRv')
3675
+ currencyCode = self.safe_currency_code(self.safe_string(entry, 'currency'))
3673
3676
  result.append({
3674
3677
  'info': entry,
3675
3678
  'symbol': self.safe_string(entry, 'symbol'),
3676
- 'code': self.safe_currency_code(self.safe_string(entry, 'currency')),
3679
+ 'code': currencyCode,
3677
3680
  'timestamp': timestamp,
3678
3681
  'datetime': self.iso8601(timestamp),
3679
3682
  'id': None,
3680
- 'amount': self.from_ev(self.safe_string(entry, 'execFeeEv'), market),
3683
+ 'amount': self.parse_funding_fee_to_precision(execFee, market, currencyCode),
3681
3684
  })
3682
3685
  return result
3683
3686
 
3687
+ def parse_funding_fee_to_precision(self, value, market: Market = None, currencyCode: Str = None):
3688
+ if value is None or currencyCode is None:
3689
+ return value
3690
+ # it was confirmed by phemex support, that USDT contracts use direct amounts in funding fees, while USD & INVERSE needs 'valueScale'
3691
+ isUsdt = market['settle'] == 'USDT'
3692
+ if not isUsdt:
3693
+ currency = self.safe_currency(currencyCode)
3694
+ scale = self.safe_string(currency['info'], 'valueScale')
3695
+ tickPrecision = self.parse_precision(scale)
3696
+ value = Precise.string_mul(value, tickPrecision)
3697
+ return value
3698
+
3684
3699
  def fetch_funding_rate(self, symbol: str, params={}):
3685
3700
  """
3686
3701
  fetch the current funding rate