ccxt 4.4.40__py2.py3-none-any.whl → 4.4.42__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.
Files changed (173) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/binance.py +3 -0
  3. ccxt/abstract/binancecoinm.py +3 -0
  4. ccxt/abstract/binanceus.py +3 -0
  5. ccxt/abstract/binanceusdm.py +3 -0
  6. ccxt/abstract/bitmart.py +2 -0
  7. ccxt/abstract/okx.py +5 -0
  8. ccxt/ace.py +1 -1
  9. ccxt/alpaca.py +0 -1
  10. ccxt/ascendex.py +0 -1
  11. ccxt/async_support/__init__.py +1 -1
  12. ccxt/async_support/ace.py +1 -1
  13. ccxt/async_support/alpaca.py +0 -1
  14. ccxt/async_support/ascendex.py +0 -1
  15. ccxt/async_support/base/exchange.py +24 -17
  16. ccxt/async_support/bigone.py +0 -1
  17. ccxt/async_support/binance.py +27 -24
  18. ccxt/async_support/bingx.py +5 -1
  19. ccxt/async_support/bitfinex.py +123 -1
  20. ccxt/async_support/bitget.py +1 -0
  21. ccxt/async_support/bitmart.py +243 -2
  22. ccxt/async_support/blofin.py +16 -7
  23. ccxt/async_support/bybit.py +8 -8
  24. ccxt/async_support/cex.py +1 -1
  25. ccxt/async_support/coinbase.py +8 -9
  26. ccxt/async_support/coinbaseexchange.py +5 -6
  27. ccxt/async_support/coinbaseinternational.py +7 -8
  28. ccxt/async_support/coincatch.py +0 -1
  29. ccxt/async_support/coincheck.py +0 -1
  30. ccxt/async_support/coinex.py +91 -6
  31. ccxt/async_support/coinlist.py +3 -4
  32. ccxt/async_support/coinmate.py +1 -3
  33. ccxt/async_support/coinmetro.py +4 -5
  34. ccxt/async_support/coinone.py +0 -1
  35. ccxt/async_support/coinsph.py +7 -8
  36. ccxt/async_support/cryptocom.py +3 -0
  37. ccxt/async_support/currencycom.py +3 -4
  38. ccxt/async_support/defx.py +6 -7
  39. ccxt/async_support/deribit.py +1 -3
  40. ccxt/async_support/digifinex.py +0 -1
  41. ccxt/async_support/ellipx.py +0 -2
  42. ccxt/async_support/exmo.py +61 -6
  43. ccxt/async_support/gate.py +2 -3
  44. ccxt/async_support/gemini.py +4 -5
  45. ccxt/async_support/hashkey.py +79 -67
  46. ccxt/async_support/hitbtc.py +47 -5
  47. ccxt/async_support/hollaex.py +4 -6
  48. ccxt/async_support/htx.py +2 -4
  49. ccxt/async_support/huobijp.py +0 -1
  50. ccxt/async_support/hyperliquid.py +60 -1
  51. ccxt/async_support/idex.py +8 -8
  52. ccxt/async_support/independentreserve.py +0 -1
  53. ccxt/async_support/indodax.py +0 -1
  54. ccxt/async_support/kraken.py +186 -28
  55. ccxt/async_support/krakenfutures.py +75 -3
  56. ccxt/async_support/kucoin.py +6 -4
  57. ccxt/async_support/kucoinfutures.py +10 -9
  58. ccxt/async_support/kuna.py +1 -3
  59. ccxt/async_support/latoken.py +1 -3
  60. ccxt/async_support/lbank.py +0 -1
  61. ccxt/async_support/luno.py +0 -1
  62. ccxt/async_support/lykke.py +0 -1
  63. ccxt/async_support/mercado.py +0 -1
  64. ccxt/async_support/mexc.py +6 -7
  65. ccxt/async_support/ndax.py +1 -1
  66. ccxt/async_support/novadax.py +4 -6
  67. ccxt/async_support/oceanex.py +0 -1
  68. ccxt/async_support/okcoin.py +1 -3
  69. ccxt/async_support/okx.py +7 -4
  70. ccxt/async_support/onetrading.py +1 -3
  71. ccxt/async_support/p2b.py +1 -1
  72. ccxt/async_support/paradex.py +5 -7
  73. ccxt/async_support/phemex.py +8 -10
  74. ccxt/async_support/poloniex.py +1 -3
  75. ccxt/async_support/poloniexfutures.py +6 -6
  76. ccxt/async_support/probit.py +0 -1
  77. ccxt/async_support/timex.py +0 -1
  78. ccxt/async_support/tokocrypto.py +11 -14
  79. ccxt/async_support/tradeogre.py +1 -1
  80. ccxt/async_support/upbit.py +0 -1
  81. ccxt/async_support/wavesexchange.py +4 -5
  82. ccxt/async_support/whitebit.py +8 -9
  83. ccxt/async_support/woo.py +98 -12
  84. ccxt/async_support/woofipro.py +96 -15
  85. ccxt/async_support/xt.py +6 -3
  86. ccxt/async_support/yobit.py +0 -1
  87. ccxt/async_support/zaif.py +0 -1
  88. ccxt/async_support/zonda.py +1 -2
  89. ccxt/base/exchange.py +39 -20
  90. ccxt/base/types.py +10 -0
  91. ccxt/bigone.py +0 -1
  92. ccxt/binance.py +27 -24
  93. ccxt/bingx.py +5 -1
  94. ccxt/bitfinex.py +123 -1
  95. ccxt/bitget.py +1 -0
  96. ccxt/bitmart.py +243 -2
  97. ccxt/blofin.py +16 -7
  98. ccxt/bybit.py +8 -8
  99. ccxt/cex.py +1 -1
  100. ccxt/coinbase.py +8 -9
  101. ccxt/coinbaseexchange.py +5 -6
  102. ccxt/coinbaseinternational.py +7 -8
  103. ccxt/coincatch.py +0 -1
  104. ccxt/coincheck.py +0 -1
  105. ccxt/coinex.py +91 -6
  106. ccxt/coinlist.py +3 -4
  107. ccxt/coinmate.py +1 -3
  108. ccxt/coinmetro.py +4 -5
  109. ccxt/coinone.py +0 -1
  110. ccxt/coinsph.py +7 -8
  111. ccxt/cryptocom.py +3 -0
  112. ccxt/currencycom.py +3 -4
  113. ccxt/defx.py +6 -7
  114. ccxt/deribit.py +1 -3
  115. ccxt/digifinex.py +0 -1
  116. ccxt/ellipx.py +0 -2
  117. ccxt/exmo.py +61 -6
  118. ccxt/gate.py +2 -3
  119. ccxt/gemini.py +4 -5
  120. ccxt/hashkey.py +79 -67
  121. ccxt/hitbtc.py +47 -5
  122. ccxt/hollaex.py +4 -6
  123. ccxt/htx.py +2 -4
  124. ccxt/huobijp.py +0 -1
  125. ccxt/hyperliquid.py +60 -1
  126. ccxt/idex.py +8 -8
  127. ccxt/independentreserve.py +0 -1
  128. ccxt/indodax.py +0 -1
  129. ccxt/kraken.py +186 -28
  130. ccxt/krakenfutures.py +75 -3
  131. ccxt/kucoin.py +6 -4
  132. ccxt/kucoinfutures.py +10 -9
  133. ccxt/kuna.py +1 -3
  134. ccxt/latoken.py +1 -3
  135. ccxt/lbank.py +0 -1
  136. ccxt/luno.py +0 -1
  137. ccxt/lykke.py +0 -1
  138. ccxt/mercado.py +0 -1
  139. ccxt/mexc.py +6 -7
  140. ccxt/ndax.py +1 -1
  141. ccxt/novadax.py +4 -6
  142. ccxt/oceanex.py +0 -1
  143. ccxt/okcoin.py +1 -3
  144. ccxt/okx.py +7 -4
  145. ccxt/onetrading.py +1 -3
  146. ccxt/p2b.py +1 -1
  147. ccxt/paradex.py +5 -7
  148. ccxt/phemex.py +8 -10
  149. ccxt/poloniex.py +1 -3
  150. ccxt/poloniexfutures.py +6 -6
  151. ccxt/pro/__init__.py +1 -1
  152. ccxt/probit.py +0 -1
  153. ccxt/timex.py +0 -1
  154. ccxt/tokocrypto.py +11 -14
  155. ccxt/tradeogre.py +1 -1
  156. ccxt/upbit.py +0 -1
  157. ccxt/wavesexchange.py +4 -5
  158. ccxt/whitebit.py +8 -9
  159. ccxt/woo.py +98 -12
  160. ccxt/woofipro.py +96 -15
  161. ccxt/xt.py +6 -3
  162. ccxt/yobit.py +0 -1
  163. ccxt/zaif.py +0 -1
  164. ccxt/zonda.py +1 -2
  165. {ccxt-4.4.40.dist-info → ccxt-4.4.42.dist-info}/METADATA +5 -5
  166. {ccxt-4.4.40.dist-info → ccxt-4.4.42.dist-info}/RECORD +169 -173
  167. ccxt/bitbay.py +0 -17
  168. ccxt/bitfinex2.py +0 -3624
  169. ccxt/hitbtc3.py +0 -16
  170. ccxt/pro/bitfinex2.py +0 -1086
  171. {ccxt-4.4.40.dist-info → ccxt-4.4.42.dist-info}/LICENSE.txt +0 -0
  172. {ccxt-4.4.40.dist-info → ccxt-4.4.42.dist-info}/WHEEL +0 -0
  173. {ccxt-4.4.40.dist-info → ccxt-4.4.42.dist-info}/top_level.txt +0 -0
@@ -101,6 +101,7 @@ class bitfinex(Exchange, ImplicitAPI):
101
101
  'fetchOHLCV': True,
102
102
  'fetchOpenInterest': True,
103
103
  'fetchOpenInterestHistory': True,
104
+ 'fetchOpenInterests': True,
104
105
  'fetchOpenOrder': True,
105
106
  'fetchOpenOrders': True,
106
107
  'fetchOrder': True,
@@ -420,6 +421,75 @@ class bitfinex(Exchange, ImplicitAPI):
420
421
  'TETHERUSE': 'ERC20',
421
422
  },
422
423
  },
424
+ 'features': {
425
+ 'default': {
426
+ 'sandbox': False,
427
+ 'createOrder': {
428
+ 'marginMode': True,
429
+ 'triggerPrice': True,
430
+ 'triggerPriceType': None,
431
+ 'triggerDirection': False,
432
+ 'stopLossPrice': True,
433
+ 'takeProfitPrice': True,
434
+ 'attachedStopLossTakeProfit': None,
435
+ 'timeInForce': {
436
+ 'IOC': True,
437
+ 'FOK': True,
438
+ 'PO': True,
439
+ 'GTD': False,
440
+ },
441
+ 'hedged': False,
442
+ 'trailing': True, # todo: unify
443
+ # todo: leverage unify
444
+ },
445
+ 'createOrders': {
446
+ 'max': 75,
447
+ },
448
+ 'fetchMyTrades': {
449
+ 'marginMode': False,
450
+ 'limit': 2500,
451
+ 'daysBack': None,
452
+ 'untilDays': 100000, # todo: implement
453
+ },
454
+ 'fetchOrder': {
455
+ 'marginMode': False,
456
+ 'trigger': False,
457
+ 'trailing': False,
458
+ },
459
+ 'fetchOpenOrders': {
460
+ 'marginMode': False,
461
+ 'limit': None,
462
+ 'trigger': False,
463
+ 'trailing': False,
464
+ },
465
+ 'fetchOrders': None,
466
+ 'fetchClosedOrders': {
467
+ 'marginMode': False,
468
+ 'limit': None,
469
+ 'daysBackClosed': None,
470
+ 'daysBackCanceled': None,
471
+ 'untilDays': 100000,
472
+ 'trigger': False,
473
+ 'trailing': False,
474
+ },
475
+ 'fetchOHLCV': {
476
+ 'limit': 10000,
477
+ },
478
+ },
479
+ 'spot': {
480
+ 'extends': 'default',
481
+ },
482
+ 'swap': {
483
+ 'linear': {
484
+ 'extends': 'default',
485
+ },
486
+ 'inverse': None,
487
+ },
488
+ 'future': {
489
+ 'linear': None,
490
+ 'inverse': None,
491
+ },
492
+ },
423
493
  'exceptions': {
424
494
  'exact': {
425
495
  '11010': RateLimitExceeded,
@@ -3117,6 +3187,58 @@ class bitfinex(Exchange, ImplicitAPI):
3117
3187
  'previousFundingDatetime': None,
3118
3188
  }
3119
3189
 
3190
+ async def fetch_open_interests(self, symbols: Strings = None, params={}):
3191
+ """
3192
+ Retrieves the open interest for a list of symbols
3193
+
3194
+ https://docs.bitfinex.com/reference/rest-public-derivatives-status
3195
+
3196
+ :param str[] [symbols]: a list of unified CCXT market symbols
3197
+ :param dict [params]: exchange specific parameters
3198
+ :returns dict[]: a list of `open interest structures <https://docs.ccxt.com/#/?id=open-interest-structure>`
3199
+ """
3200
+ await self.load_markets()
3201
+ symbols = self.market_symbols(symbols)
3202
+ marketIds = ['ALL']
3203
+ if symbols is not None:
3204
+ marketIds = self.market_ids(symbols)
3205
+ request: dict = {
3206
+ 'keys': ','.join(marketIds),
3207
+ }
3208
+ response = await self.publicGetStatusDeriv(self.extend(request, params))
3209
+ #
3210
+ # [
3211
+ # [
3212
+ # "tXRPF0:USTF0", # market id
3213
+ # 1706256986000, # millisecond timestamp
3214
+ # null,
3215
+ # 0.512705, # derivative mid price
3216
+ # 0.512395, # underlying spot mid price
3217
+ # null,
3218
+ # 37671483.04, # insurance fund balance
3219
+ # null,
3220
+ # 1706284800000, # timestamp of next funding
3221
+ # 0.00002353, # accrued funding for next period
3222
+ # 317, # next funding step
3223
+ # null,
3224
+ # 0, # current funding
3225
+ # null,
3226
+ # null,
3227
+ # 0.5123016, # mark price
3228
+ # null,
3229
+ # null,
3230
+ # 2233562.03115, # open interest in contracts
3231
+ # null,
3232
+ # null,
3233
+ # null,
3234
+ # 0.0005, # average spread without funding payment
3235
+ # 0.0025 # funding payment cap
3236
+ # ]
3237
+ # ]
3238
+ #
3239
+ result = self.parse_open_interests(response)
3240
+ return self.filter_by_array(result, 'symbol', symbols)
3241
+
3120
3242
  async def fetch_open_interest(self, symbol: str, params={}):
3121
3243
  """
3122
3244
  retrieves the open interest of a contract trading pair
@@ -3225,7 +3347,7 @@ class bitfinex(Exchange, ImplicitAPI):
3225
3347
  # ],
3226
3348
  # ]
3227
3349
  #
3228
- return self.parse_open_interests(response, market, since, limit)
3350
+ return self.parse_open_interests_history(response, market, since, limit)
3229
3351
 
3230
3352
  def parse_open_interest(self, interest, market: Market = None):
3231
3353
  #
@@ -1265,6 +1265,7 @@ class bitget(Exchange, ImplicitAPI):
1265
1265
  '41103': InvalidOrder, # {"code":"41103","msg":"param price scale error error","requestTime":1725635883561,"data":null}
1266
1266
  '41114': OnMaintenance, # {"code":"41114","msg":"The current trading pair is under maintenance, please refer to the official announcement for the opening time","requestTime":1679196062544,"data":null}
1267
1267
  '43011': InvalidOrder, # The parameter does not meet the specification executePrice <= 0
1268
+ '43001': OrderNotFound,
1268
1269
  '43012': InsufficientFunds, # {"code":"43012","msg":"Insufficient balance","requestTime":1711648951774,"data":null}
1269
1270
  '43025': InvalidOrder, # Plan order does not exist
1270
1271
  '43115': OnMaintenance, # {"code":"43115","msg":"The current trading pair is opening soon, please refer to the official announcement for the opening time","requestTime":1688907202434,"data":null}
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.bitmart import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, BorrowInterest, Currencies, Currency, DepositAddress, Int, IsolatedBorrowRate, IsolatedBorrowRates, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, TransferEntry
9
+ from ccxt.base.types import Balances, BorrowInterest, Currencies, Currency, DepositAddress, FundingHistory, Int, IsolatedBorrowRate, IsolatedBorrowRates, LedgerEntry, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -81,12 +81,13 @@ class bitmart(Exchange, ImplicitAPI):
81
81
  'fetchDeposits': True,
82
82
  'fetchDepositWithdrawFee': True,
83
83
  'fetchDepositWithdrawFees': False,
84
- 'fetchFundingHistory': None,
84
+ 'fetchFundingHistory': True,
85
85
  'fetchFundingRate': True,
86
86
  'fetchFundingRateHistory': False,
87
87
  'fetchFundingRates': False,
88
88
  'fetchIsolatedBorrowRate': True,
89
89
  'fetchIsolatedBorrowRates': True,
90
+ 'fetchLedger': True,
90
91
  'fetchLiquidations': False,
91
92
  'fetchMarginMode': False,
92
93
  'fetchMarkets': True,
@@ -173,6 +174,7 @@ class bitmart(Exchange, ImplicitAPI):
173
174
  'contract/public/depth': 5,
174
175
  'contract/public/open-interest': 30,
175
176
  'contract/public/funding-rate': 30,
177
+ 'contract/public/funding-rate-history': 30,
176
178
  'contract/public/kline': 6, # should be 5 but errors
177
179
  'account/v1/currencies': 30,
178
180
  },
@@ -223,6 +225,7 @@ class bitmart(Exchange, ImplicitAPI):
223
225
  'contract/private/position-risk': 10,
224
226
  'contract/private/affilate/rebate-list': 10,
225
227
  'contract/private/affilate/trade-list': 10,
228
+ 'contract/private/transaction-history': 10,
226
229
  },
227
230
  'post': {
228
231
  # sub-account endpoints
@@ -4375,6 +4378,62 @@ class bitmart(Exchange, ImplicitAPI):
4375
4378
  data = self.safe_dict(response, 'data', {})
4376
4379
  return self.parse_funding_rate(data, market)
4377
4380
 
4381
+ async def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4382
+ """
4383
+ fetches historical funding rate prices
4384
+
4385
+ https://developer-pro.bitmart.com/en/futuresv2/#get-funding-rate-history
4386
+
4387
+ :param str symbol: unified symbol of the market to fetch the funding rate history for
4388
+ :param int [since]: timestamp in ms of the earliest funding rate to fetch
4389
+ :param int [limit]: the maximum amount of funding rate structures to fetch
4390
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4391
+ :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>`
4392
+ """
4393
+ if symbol is None:
4394
+ raise ArgumentsRequired(self.id + ' fetchFundingRateHistory() requires a symbol argument')
4395
+ await self.load_markets()
4396
+ market = self.market(symbol)
4397
+ request: dict = {
4398
+ 'symbol': market['id'],
4399
+ }
4400
+ if limit is not None:
4401
+ request['limit'] = limit
4402
+ response = await self.publicGetContractPublicFundingRateHistory(self.extend(request, params))
4403
+ #
4404
+ # {
4405
+ # "code": 1000,
4406
+ # "message": "Ok",
4407
+ # "data": {
4408
+ # "list": [
4409
+ # {
4410
+ # "symbol": "BTCUSDT",
4411
+ # "funding_rate": "0.000091412174",
4412
+ # "funding_time": "1734336000000"
4413
+ # },
4414
+ # ]
4415
+ # },
4416
+ # "trace": "fg73d949fgfdf6a40c8fc7f5ae6738.54.345345345345"
4417
+ # }
4418
+ #
4419
+ data = self.safe_dict(response, 'data', {})
4420
+ result = self.safe_list(data, 'list', [])
4421
+ rates = []
4422
+ for i in range(0, len(result)):
4423
+ entry = result[i]
4424
+ marketId = self.safe_string(entry, 'symbol')
4425
+ symbolInner = self.safe_symbol(marketId, market, '-', 'swap')
4426
+ timestamp = self.safe_integer(entry, 'funding_time')
4427
+ rates.append({
4428
+ 'info': entry,
4429
+ 'symbol': symbolInner,
4430
+ 'fundingRate': self.safe_number(entry, 'funding_rate'),
4431
+ 'timestamp': timestamp,
4432
+ 'datetime': self.iso8601(timestamp),
4433
+ })
4434
+ sorted = self.sort_by(rates, 'timestamp')
4435
+ return self.filter_by_symbol_since_limit(sorted, market['symbol'], since, limit)
4436
+
4378
4437
  def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
4379
4438
  #
4380
4439
  # {
@@ -4788,6 +4847,188 @@ class bitmart(Exchange, ImplicitAPI):
4788
4847
  data = self.safe_dict(response, 'data', {})
4789
4848
  return self.parse_order(data, market)
4790
4849
 
4850
+ async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
4851
+ """
4852
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
4853
+
4854
+ https://developer-pro.bitmart.com/en/futuresv2/#get-transaction-history-keyed
4855
+
4856
+ :param str [code]: unified currency code
4857
+ :param int [since]: timestamp in ms of the earliest ledger entry
4858
+ :param int [limit]: max number of ledger entries to return
4859
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4860
+ :param int [params.until]: timestamp in ms of the latest ledger entry
4861
+ :returns dict[]: a list of `ledger structures <https://docs.ccxt.com/#/?id=ledger>`
4862
+ """
4863
+ await self.load_markets()
4864
+ currency = None
4865
+ if code is not None:
4866
+ currency = self.currency(code)
4867
+ request: dict = {}
4868
+ request, params = self.handle_until_option('end_time', request, params)
4869
+ transactionsRequest = self.fetch_transactions_request(0, None, since, limit, params)
4870
+ response = await self.privateGetContractPrivateTransactionHistory(transactionsRequest)
4871
+ #
4872
+ # {
4873
+ # "code": 1000,
4874
+ # "message": "Ok",
4875
+ # "data": [
4876
+ # {
4877
+ # "time": "1734422402121",
4878
+ # "type": "Funding Fee",
4879
+ # "amount": "-0.00008253",
4880
+ # "asset": "USDT",
4881
+ # "symbol": "LTCUSDT",
4882
+ # "tran_id": "1734422402121",
4883
+ # "flow_type": 3
4884
+ # },
4885
+ # ],
4886
+ # "trace": "4cd11f83c71egfhfgh842790f07241e.23.173442343427772866"
4887
+ # }
4888
+ #
4889
+ data = self.safe_list(response, 'data', [])
4890
+ return self.parse_ledger(data, currency, since, limit)
4891
+
4892
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
4893
+ #
4894
+ # {
4895
+ # "time": "1734422402121",
4896
+ # "type": "Funding Fee",
4897
+ # "amount": "-0.00008253",
4898
+ # "asset": "USDT",
4899
+ # "symbol": "LTCUSDT",
4900
+ # "tran_id": "1734422402121",
4901
+ # "flow_type": 3
4902
+ # }
4903
+ #
4904
+ amount = self.safe_string(item, 'amount')
4905
+ direction = None
4906
+ if Precise.string_le(amount, '0'):
4907
+ direction = 'out'
4908
+ amount = Precise.string_mul('-1', amount)
4909
+ else:
4910
+ direction = 'in'
4911
+ currencyId = self.safe_string(item, 'asset')
4912
+ timestamp = self.safe_integer(item, 'time')
4913
+ type = self.safe_string(item, 'type')
4914
+ return self.safe_ledger_entry({
4915
+ 'info': item,
4916
+ 'id': self.safe_string(item, 'tran_id'),
4917
+ 'direction': direction,
4918
+ 'account': None,
4919
+ 'referenceAccount': None,
4920
+ 'referenceId': self.safe_string(item, 'tradeId'),
4921
+ 'type': self.parse_ledger_entry_type(type),
4922
+ 'currency': self.safe_currency_code(currencyId, currency),
4923
+ 'amount': self.parse_number(amount),
4924
+ 'timestamp': timestamp,
4925
+ 'datetime': self.iso8601(timestamp),
4926
+ 'before': None,
4927
+ 'after': None,
4928
+ 'status': None,
4929
+ 'fee': None,
4930
+ }, currency)
4931
+
4932
+ def parse_ledger_entry_type(self, type):
4933
+ ledgerType: dict = {
4934
+ 'Commission Fee': 'fee',
4935
+ 'Funding Fee': 'fee',
4936
+ 'Realized PNL': 'trade',
4937
+ 'Transfer': 'transfer',
4938
+ 'Liquidation Clearance': 'settlement',
4939
+ }
4940
+ return self.safe_string(ledgerType, type, type)
4941
+
4942
+ def fetch_transactions_request(self, flowType: Int = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4943
+ request: dict = {}
4944
+ if flowType is not None:
4945
+ request['flow_type'] = flowType
4946
+ market = None
4947
+ if symbol is not None:
4948
+ market = self.market(symbol)
4949
+ request['symbol'] = market['id']
4950
+ if since is not None:
4951
+ request['start_time'] = since
4952
+ if limit is not None:
4953
+ request['page_size'] = limit
4954
+ request, params = self.handle_until_option('end_time', request, params)
4955
+ return self.extend(request, params)
4956
+
4957
+ async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[FundingHistory]:
4958
+ """
4959
+ fetch the history of funding payments paid and received on self account
4960
+
4961
+ https://developer-pro.bitmart.com/en/futuresv2/#get-transaction-history-keyed
4962
+
4963
+ :param str [symbol]: unified market symbol
4964
+ :param int [since]: the starting timestamp in milliseconds
4965
+ :param int [limit]: the number of entries to return
4966
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4967
+ :param int [params.until]: the latest time in ms to fetch funding history for
4968
+ :returns dict[]: a list of `funding history structures <https://docs.ccxt.com/#/?id=funding-history-structure>`
4969
+ """
4970
+ await self.load_markets()
4971
+ market = None
4972
+ if symbol is not None:
4973
+ market = self.market(symbol)
4974
+ request: dict = {}
4975
+ request, params = self.handle_until_option('end_time', request, params)
4976
+ transactionsRequest = self.fetch_transactions_request(3, symbol, since, limit, params)
4977
+ response = await self.privateGetContractPrivateTransactionHistory(transactionsRequest)
4978
+ #
4979
+ # {
4980
+ # "code": 1000,
4981
+ # "message": "Ok",
4982
+ # "data": [
4983
+ # {
4984
+ # "time": "1734422402121",
4985
+ # "type": "Funding Fee",
4986
+ # "amount": "-0.00008253",
4987
+ # "asset": "USDT",
4988
+ # "symbol": "LTCUSDT",
4989
+ # "tran_id": "1734422402121",
4990
+ # "flow_type": 3
4991
+ # },
4992
+ # ],
4993
+ # "trace": "4cd11f83c71egfhfgh842790f07241e.23.173442343427772866"
4994
+ # }
4995
+ #
4996
+ data = self.safe_list(response, 'data', [])
4997
+ return self.parse_funding_histories(data, market, since, limit)
4998
+
4999
+ def parse_funding_history(self, contract, market: Market = None):
5000
+ #
5001
+ # {
5002
+ # "time": "1734422402121",
5003
+ # "type": "Funding Fee",
5004
+ # "amount": "-0.00008253",
5005
+ # "asset": "USDT",
5006
+ # "symbol": "LTCUSDT",
5007
+ # "tran_id": "1734422402121",
5008
+ # "flow_type": 3
5009
+ # }
5010
+ #
5011
+ marketId = self.safe_string(contract, 'symbol')
5012
+ currencyId = self.safe_string(contract, 'asset')
5013
+ timestamp = self.safe_integer(contract, 'time')
5014
+ return {
5015
+ 'info': contract,
5016
+ 'symbol': self.safe_symbol(marketId, market, None, 'swap'),
5017
+ 'code': self.safe_currency_code(currencyId),
5018
+ 'timestamp': timestamp,
5019
+ 'datetime': self.iso8601(timestamp),
5020
+ 'id': self.safe_string(contract, 'tran_id'),
5021
+ 'amount': self.safe_number(contract, 'amount'),
5022
+ }
5023
+
5024
+ def parse_funding_histories(self, contracts, market=None, since: Int = None, limit: Int = None) -> List[FundingHistory]:
5025
+ result = []
5026
+ for i in range(0, len(contracts)):
5027
+ contract = contracts[i]
5028
+ result.append(self.parse_funding_history(contract, market))
5029
+ sorted = self.sort_by(result, 'timestamp')
5030
+ return self.filter_by_since_limit(sorted, since, limit)
5031
+
4791
5032
  def nonce(self):
4792
5033
  return self.milliseconds()
4793
5034
 
@@ -167,7 +167,7 @@ class blofin(Exchange, ImplicitAPI):
167
167
  'rest': 'https://openapi.blofin.com',
168
168
  },
169
169
  'referral': {
170
- 'url': 'https://blofin.com/register?referral_code=jBd8U1',
170
+ 'url': 'https://blofin.com/register?referral_code=f79EsS',
171
171
  'discount': 0.05,
172
172
  },
173
173
  'www': 'https://www.blofin.com',
@@ -287,10 +287,18 @@ class blofin(Exchange, ImplicitAPI):
287
287
  'brokerId': 'ec6dd3a7dd982d0b',
288
288
  'accountsByType': {
289
289
  'swap': 'futures',
290
+ 'funding': 'funding',
290
291
  'future': 'futures',
292
+ 'copy_trading': 'copy_trading',
293
+ 'earn': 'earn',
294
+ 'spot': 'spot',
291
295
  },
292
296
  'accountsById': {
297
+ 'funding': 'funding',
293
298
  'futures': 'swap',
299
+ 'copy_trading': 'copy_trading',
300
+ 'earn': 'earn',
301
+ 'spot': 'spot',
294
302
  },
295
303
  'sandboxMode': False,
296
304
  'defaultNetwork': 'ERC20',
@@ -873,8 +881,9 @@ class blofin(Exchange, ImplicitAPI):
873
881
  entry = self.safe_dict(data, 0, {})
874
882
  return self.parse_funding_rate(entry, market)
875
883
 
876
- def parse_balance_by_type(self, type, response):
877
- if type:
884
+ def parse_balance_by_type(self, response):
885
+ data = self.safe_list(response, 'data')
886
+ if (data is not None) and isinstance(data, list):
878
887
  return self.parse_funding_balance(response)
879
888
  else:
880
889
  return self.parse_balance(response)
@@ -986,19 +995,19 @@ class blofin(Exchange, ImplicitAPI):
986
995
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
987
996
  """
988
997
  await self.load_markets()
989
- accountType = self.safe_string_2(params, 'accountType', 'type')
990
- params = self.omit(params, ['accountType', 'type'])
998
+ accountType = None
999
+ accountType, params = self.handle_option_and_params_2(params, 'fetchBalance', 'accountType', 'type')
991
1000
  request: dict = {
992
1001
  }
993
1002
  response = None
994
- if accountType is not None:
1003
+ if accountType is not None and accountType != 'swap':
995
1004
  options = self.safe_dict(self.options, 'accountsByType', {})
996
1005
  parsedAccountType = self.safe_string(options, accountType, accountType)
997
1006
  request['accountType'] = parsedAccountType
998
1007
  response = await self.privateGetAssetBalances(self.extend(request, params))
999
1008
  else:
1000
1009
  response = await self.privateGetAccountBalance(self.extend(request, params))
1001
- return self.parse_balance_by_type(accountType, response)
1010
+ return self.parse_balance_by_type(response)
1002
1011
 
1003
1012
  def create_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1004
1013
  market = self.market(symbol)
@@ -3531,29 +3531,29 @@ class bybit(Exchange, ImplicitAPI):
3531
3531
  avgPrice = self.omit_zero(self.safe_string(order, 'avgPrice'))
3532
3532
  rawTimeInForce = self.safe_string(order, 'timeInForce')
3533
3533
  timeInForce = self.parse_time_in_force(rawTimeInForce)
3534
- stopPrice = self.omit_zero(self.safe_string(order, 'triggerPrice'))
3534
+ triggerPrice = self.omit_zero(self.safe_string(order, 'triggerPrice'))
3535
3535
  reduceOnly = self.safe_bool(order, 'reduceOnly')
3536
3536
  takeProfitPrice = self.omit_zero(self.safe_string(order, 'takeProfit'))
3537
3537
  stopLossPrice = self.omit_zero(self.safe_string(order, 'stopLoss'))
3538
3538
  triggerDirection = self.safe_string(order, 'triggerDirection')
3539
3539
  isAscending = (triggerDirection == '1')
3540
- isStopOrderType2 = (stopPrice is not None) and reduceOnly
3540
+ isStopOrderType2 = (triggerPrice is not None) and reduceOnly
3541
3541
  if (stopLossPrice is None) and isStopOrderType2:
3542
3542
  # check if order is stop order type 2 - stopLossPrice
3543
3543
  if isAscending and (side == 'buy'):
3544
3544
  # stopLoss order against short position
3545
- stopLossPrice = stopPrice
3545
+ stopLossPrice = triggerPrice
3546
3546
  if not isAscending and (side == 'sell'):
3547
3547
  # stopLoss order against a long position
3548
- stopLossPrice = stopPrice
3548
+ stopLossPrice = triggerPrice
3549
3549
  if (takeProfitPrice is None) and isStopOrderType2:
3550
3550
  # check if order is stop order type 2 - takeProfitPrice
3551
3551
  if isAscending and (side == 'sell'):
3552
3552
  # takeprofit order against a long position
3553
- takeProfitPrice = stopPrice
3553
+ takeProfitPrice = triggerPrice
3554
3554
  if not isAscending and (side == 'buy'):
3555
3555
  # takeprofit order against a short position
3556
- takeProfitPrice = stopPrice
3556
+ takeProfitPrice = triggerPrice
3557
3557
  return self.safe_order({
3558
3558
  'info': order,
3559
3559
  'id': id,
@@ -3569,7 +3569,7 @@ class bybit(Exchange, ImplicitAPI):
3569
3569
  'reduceOnly': self.safe_bool(order, 'reduceOnly'),
3570
3570
  'side': side,
3571
3571
  'price': price,
3572
- 'triggerPrice': stopPrice,
3572
+ 'triggerPrice': triggerPrice,
3573
3573
  'takeProfitPrice': takeProfitPrice,
3574
3574
  'stopLossPrice': stopLossPrice,
3575
3575
  'amount': amount,
@@ -6370,7 +6370,7 @@ classic accounts only/ spot not supported* fetches information on an order made
6370
6370
  data = self.add_pagination_cursor_to_result(response)
6371
6371
  id = self.safe_string(result, 'symbol')
6372
6372
  market = self.safe_market(id, market, None, 'contract')
6373
- return self.parse_open_interests(data, market, since, limit)
6373
+ return self.parse_open_interests_history(data, market, since, limit)
6374
6374
 
6375
6375
  async def fetch_open_interest(self, symbol: str, params={}):
6376
6376
  """
ccxt/async_support/cex.py CHANGED
@@ -1067,7 +1067,7 @@ class cex(Exchange, ImplicitAPI):
1067
1067
  'postOnly': None,
1068
1068
  'side': self.safe_string_lower(order, 'side'),
1069
1069
  'price': self.safe_number(order, 'price'),
1070
- 'stopPrice': self.safe_number(order, 'stopPrice'),
1070
+ 'triggerPrice': self.safe_number(order, 'stopPrice'),
1071
1071
  'amount': requestedBase,
1072
1072
  'cost': executedQuote,
1073
1073
  'average': self.safe_number(order, 'averagePrice'),
@@ -2810,10 +2810,10 @@ class coinbase(Exchange, ImplicitAPI):
2810
2810
  'product_id': market['id'],
2811
2811
  'side': side.upper(),
2812
2812
  }
2813
- stopPrice = self.safe_number_n(params, ['stopPrice', 'stop_price', 'triggerPrice'])
2813
+ triggerPrice = self.safe_number_n(params, ['stopPrice', 'stop_price', 'triggerPrice'])
2814
2814
  stopLossPrice = self.safe_number(params, 'stopLossPrice')
2815
2815
  takeProfitPrice = self.safe_number(params, 'takeProfitPrice')
2816
- isStop = stopPrice is not None
2816
+ isStop = triggerPrice is not None
2817
2817
  isStopLoss = stopLossPrice is not None
2818
2818
  isTakeProfit = takeProfitPrice is not None
2819
2819
  timeInForce = self.safe_string(params, 'timeInForce')
@@ -2831,7 +2831,7 @@ class coinbase(Exchange, ImplicitAPI):
2831
2831
  'stop_limit_stop_limit_gtd': {
2832
2832
  'base_size': self.amount_to_precision(symbol, amount),
2833
2833
  'limit_price': self.price_to_precision(symbol, price),
2834
- 'stop_price': self.price_to_precision(symbol, stopPrice),
2834
+ 'stop_price': self.price_to_precision(symbol, triggerPrice),
2835
2835
  'stop_direction': stopDirection,
2836
2836
  'end_time': endTime,
2837
2837
  },
@@ -2841,25 +2841,25 @@ class coinbase(Exchange, ImplicitAPI):
2841
2841
  'stop_limit_stop_limit_gtc': {
2842
2842
  'base_size': self.amount_to_precision(symbol, amount),
2843
2843
  'limit_price': self.price_to_precision(symbol, price),
2844
- 'stop_price': self.price_to_precision(symbol, stopPrice),
2844
+ 'stop_price': self.price_to_precision(symbol, triggerPrice),
2845
2845
  'stop_direction': stopDirection,
2846
2846
  },
2847
2847
  }
2848
2848
  elif isStopLoss or isTakeProfit:
2849
- triggerPrice = None
2849
+ tpslPrice = None
2850
2850
  if isStopLoss:
2851
2851
  if stopDirection is None:
2852
2852
  stopDirection = 'STOP_DIRECTION_STOP_UP' if (side == 'buy') else 'STOP_DIRECTION_STOP_DOWN'
2853
- triggerPrice = self.price_to_precision(symbol, stopLossPrice)
2853
+ tpslPrice = self.price_to_precision(symbol, stopLossPrice)
2854
2854
  else:
2855
2855
  if stopDirection is None:
2856
2856
  stopDirection = 'STOP_DIRECTION_STOP_DOWN' if (side == 'buy') else 'STOP_DIRECTION_STOP_UP'
2857
- triggerPrice = self.price_to_precision(symbol, takeProfitPrice)
2857
+ tpslPrice = self.price_to_precision(symbol, takeProfitPrice)
2858
2858
  request['order_configuration'] = {
2859
2859
  'stop_limit_stop_limit_gtc': {
2860
2860
  'base_size': self.amount_to_precision(symbol, amount),
2861
2861
  'limit_price': self.price_to_precision(symbol, price),
2862
- 'stop_price': triggerPrice,
2862
+ 'stop_price': tpslPrice,
2863
2863
  'stop_direction': stopDirection,
2864
2864
  },
2865
2865
  }
@@ -3110,7 +3110,6 @@ class coinbase(Exchange, ImplicitAPI):
3110
3110
  'postOnly': postOnly,
3111
3111
  'side': self.safe_string_lower(order, 'side'),
3112
3112
  'price': price,
3113
- 'stopPrice': triggerPrice,
3114
3113
  'triggerPrice': triggerPrice,
3115
3114
  'amount': amount,
3116
3115
  'filled': self.safe_string(order, 'filled_size'),