ccxt 4.2.89__py2.py3-none-any.whl → 4.2.90__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.

Files changed (64) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/bingx.py +2 -0
  3. ccxt/abstract/bybit.py +2 -0
  4. ccxt/ascendex.py +1 -0
  5. ccxt/async_support/__init__.py +1 -1
  6. ccxt/async_support/ascendex.py +1 -0
  7. ccxt/async_support/base/exchange.py +13 -1
  8. ccxt/async_support/binance.py +81 -9
  9. ccxt/async_support/bingx.py +94 -1
  10. ccxt/async_support/bitfinex2.py +1 -0
  11. ccxt/async_support/bitget.py +2 -0
  12. ccxt/async_support/bitmex.py +1 -0
  13. ccxt/async_support/bitrue.py +1 -0
  14. ccxt/async_support/bybit.py +50 -0
  15. ccxt/async_support/coinbase.py +40 -20
  16. ccxt/async_support/coinbaseinternational.py +1 -0
  17. ccxt/async_support/coinex.py +96 -8
  18. ccxt/async_support/cryptocom.py +1 -0
  19. ccxt/async_support/delta.py +1 -0
  20. ccxt/async_support/digifinex.py +1 -0
  21. ccxt/async_support/exmo.py +1 -0
  22. ccxt/async_support/gate.py +2 -0
  23. ccxt/async_support/gemini.py +10 -9
  24. ccxt/async_support/hitbtc.py +1 -0
  25. ccxt/async_support/htx.py +1 -0
  26. ccxt/async_support/hyperliquid.py +1 -0
  27. ccxt/async_support/kucoin.py +1 -0
  28. ccxt/async_support/kucoinfutures.py +32 -4
  29. ccxt/async_support/mexc.py +1 -0
  30. ccxt/async_support/okx.py +143 -8
  31. ccxt/async_support/phemex.py +1 -0
  32. ccxt/async_support/woo.py +1 -0
  33. ccxt/base/exchange.py +52 -6
  34. ccxt/base/types.py +1 -0
  35. ccxt/binance.py +81 -9
  36. ccxt/bingx.py +94 -1
  37. ccxt/bitfinex2.py +1 -0
  38. ccxt/bitget.py +2 -0
  39. ccxt/bitmex.py +1 -0
  40. ccxt/bitrue.py +1 -0
  41. ccxt/bybit.py +50 -0
  42. ccxt/coinbase.py +40 -20
  43. ccxt/coinbaseinternational.py +1 -0
  44. ccxt/coinex.py +96 -8
  45. ccxt/cryptocom.py +1 -0
  46. ccxt/delta.py +1 -0
  47. ccxt/digifinex.py +1 -0
  48. ccxt/exmo.py +1 -0
  49. ccxt/gate.py +2 -0
  50. ccxt/gemini.py +10 -9
  51. ccxt/hitbtc.py +1 -0
  52. ccxt/htx.py +1 -0
  53. ccxt/hyperliquid.py +1 -0
  54. ccxt/kucoin.py +1 -0
  55. ccxt/kucoinfutures.py +32 -4
  56. ccxt/mexc.py +1 -0
  57. ccxt/okx.py +143 -8
  58. ccxt/phemex.py +1 -0
  59. ccxt/pro/__init__.py +1 -1
  60. ccxt/woo.py +1 -0
  61. {ccxt-4.2.89.dist-info → ccxt-4.2.90.dist-info}/METADATA +4 -4
  62. {ccxt-4.2.89.dist-info → ccxt-4.2.90.dist-info}/RECORD +64 -64
  63. {ccxt-4.2.89.dist-info → ccxt-4.2.90.dist-info}/WHEEL +0 -0
  64. {ccxt-4.2.89.dist-info → ccxt-4.2.90.dist-info}/top_level.txt +0 -0
ccxt/coinex.py CHANGED
@@ -92,6 +92,7 @@ class coinex(Exchange, ImplicitAPI):
92
92
  'fetchLeverage': 'emulated',
93
93
  'fetchLeverages': True,
94
94
  'fetchLeverageTiers': True,
95
+ 'fetchMarginAdjustmentHistory': True,
95
96
  'fetchMarketLeverageTiers': 'emulated',
96
97
  'fetchMarkets': True,
97
98
  'fetchMarkOHLCV': False,
@@ -3966,11 +3967,10 @@ class coinex(Exchange, ImplicitAPI):
3966
3967
  # "message":"OK"
3967
3968
  # }
3968
3969
  #
3970
+ data = self.safe_dict(response, 'data')
3969
3971
  status = self.safe_string(response, 'message')
3970
- type = 'add' if (addOrReduce == 1) else 'reduce'
3971
- return self.extend(self.parse_margin_modification(response, market), {
3972
+ return self.extend(self.parse_margin_modification(data, market), {
3972
3973
  'amount': self.parse_number(amount),
3973
- 'type': type,
3974
3974
  'status': status,
3975
3975
  })
3976
3976
 
@@ -4030,13 +4030,34 @@ class coinex(Exchange, ImplicitAPI):
4030
4030
  # "user_id": 3620173
4031
4031
  # }
4032
4032
  #
4033
- timestamp = self.safe_integer_product(data, 'update_time', 1000)
4033
+ # fetchMarginAdjustmentHistory
4034
+ #
4035
+ # {
4036
+ # bkr_price: '0',
4037
+ # leverage: '3',
4038
+ # liq_price: '0',
4039
+ # margin_amount: '5.33236666666666666666',
4040
+ # margin_change: '3',
4041
+ # market: 'XRPUSDT',
4042
+ # position_amount: '11',
4043
+ # position_id: '297155652',
4044
+ # position_type: '2',
4045
+ # settle_price: '0.6361',
4046
+ # time: '1711050906.382891',
4047
+ # type: '1',
4048
+ # user_id: '3685860'
4049
+ # }
4050
+ #
4051
+ marketId = self.safe_string(data, 'market')
4052
+ type = self.safe_string(data, 'type')
4053
+ timestamp = self.safe_integer_product_2(data, 'time', 'update_time', 1000)
4034
4054
  return {
4035
4055
  'info': data,
4036
- 'symbol': self.safe_symbol(None, market),
4037
- 'type': None,
4038
- 'amount': self.safe_number(data, 'margin_amount'),
4039
- 'total': None,
4056
+ 'symbol': self.safe_symbol(marketId, market, None, 'swap'),
4057
+ 'type': 'add' if (type == '1') else 'reduce',
4058
+ 'marginMode': 'isolated',
4059
+ 'amount': self.safe_number(data, 'margin_change'),
4060
+ 'total': self.safe_number(data, 'position_amount'),
4040
4061
  'code': market['quote'],
4041
4062
  'status': None,
4042
4063
  'timestamp': timestamp,
@@ -4644,6 +4665,7 @@ class coinex(Exchange, ImplicitAPI):
4644
4665
  currencyId = self.safe_string(transfer, 'asset')
4645
4666
  currencyCode = self.safe_currency_code(currencyId, currency)
4646
4667
  return {
4668
+ 'info': transfer,
4647
4669
  'id': self.safe_integer(transfer, 'id'),
4648
4670
  'timestamp': timestamp,
4649
4671
  'datetime': self.iso8601(timestamp),
@@ -5410,3 +5432,69 @@ class coinex(Exchange, ImplicitAPI):
5410
5432
  self.throw_exactly_matched_exception(self.exceptions['exact'], code, feedback)
5411
5433
  raise ExchangeError(feedback)
5412
5434
  return None
5435
+
5436
+ def fetch_margin_adjustment_history(self, symbol: Str = None, type: Str = None, since: Num = None, limit: Num = None, params={}) -> List[MarginModification]:
5437
+ """
5438
+ fetches the history of margin added or reduced from contract isolated positions
5439
+ :see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http046_position_margin_history
5440
+ :param str [symbol]: unified market symbol
5441
+ :param str [type]: not used by coinex fetchMarginAdjustmentHistory
5442
+ :param int [since]: timestamp in ms of the earliest change to fetch
5443
+ :param int [limit]: the maximum amount of changes to fetch, default=100, max=100
5444
+ :param dict params: extra parameters specific to the exchange api endpoint
5445
+ :param int [params.until]: timestamp in ms of the latest change to fetch
5446
+ *
5447
+ * EXCHANGE SPECIFIC PARAMETERS
5448
+ :param int [params.offset]: offset
5449
+ :returns dict[]: a list of `margin structures <https://docs.ccxt.com/#/?id=margin-loan-structure>`
5450
+ """
5451
+ self.load_markets()
5452
+ until = self.safe_integer(params, 'until')
5453
+ params = self.omit(params, 'until')
5454
+ if limit is None:
5455
+ limit = 100
5456
+ request = {
5457
+ 'market': '',
5458
+ 'position_id': 0,
5459
+ 'offset': 0,
5460
+ 'limit': limit,
5461
+ }
5462
+ if symbol is not None:
5463
+ market = self.market(symbol)
5464
+ request['market'] = market['id']
5465
+ if since is not None:
5466
+ request['start_time'] = since
5467
+ if until is not None:
5468
+ request['end_time'] = until
5469
+ response = self.v1PerpetualPrivateGetPositionMarginHistory(self.extend(request, params))
5470
+ #
5471
+ # {
5472
+ # code: '0',
5473
+ # data: {
5474
+ # limit: '100',
5475
+ # offset: '0',
5476
+ # records: [
5477
+ # {
5478
+ # bkr_price: '0',
5479
+ # leverage: '3',
5480
+ # liq_price: '0',
5481
+ # margin_amount: '5.33236666666666666666',
5482
+ # margin_change: '3',
5483
+ # market: 'XRPUSDT',
5484
+ # position_amount: '11',
5485
+ # position_id: '297155652',
5486
+ # position_type: '2',
5487
+ # settle_price: '0.6361',
5488
+ # time: '1711050906.382891',
5489
+ # type: '1',
5490
+ # user_id: '3685860'
5491
+ # }
5492
+ # ]
5493
+ # },
5494
+ # message: 'OK'
5495
+ # }
5496
+ #
5497
+ data = self.safe_dict(response, 'data', {})
5498
+ records = self.safe_list(data, 'records', [])
5499
+ modifications = self.parse_margin_modifications(records, None, 'market', 'swap')
5500
+ return self.filter_by_symbol_since_limit(modifications, symbol, since, limit)
ccxt/cryptocom.py CHANGED
@@ -81,6 +81,7 @@ class cryptocom(Exchange, ImplicitAPI):
81
81
  'fetchLedger': True,
82
82
  'fetchLeverage': False,
83
83
  'fetchLeverageTiers': False,
84
+ 'fetchMarginAdjustmentHistory': False,
84
85
  'fetchMarginMode': False,
85
86
  'fetchMarketLeverageTiers': False,
86
87
  'fetchMarkets': True,
ccxt/delta.py CHANGED
@@ -2566,6 +2566,7 @@ class delta(Exchange, ImplicitAPI):
2566
2566
  'info': data,
2567
2567
  'symbol': market['symbol'],
2568
2568
  'type': None,
2569
+ 'marginMode': 'isolated',
2569
2570
  'amount': None,
2570
2571
  'total': self.safe_number(data, 'margin'),
2571
2572
  'code': None,
ccxt/digifinex.py CHANGED
@@ -3850,6 +3850,7 @@ class digifinex(Exchange, ImplicitAPI):
3850
3850
  'info': data,
3851
3851
  'symbol': self.safe_symbol(marketId, market, None, 'swap'),
3852
3852
  'type': 'add' if (rawType == 1) else 'reduce',
3853
+ 'marginMode': 'isolated',
3853
3854
  'amount': self.safe_number(data, 'amount'),
3854
3855
  'total': None,
3855
3856
  'code': market['settle'],
ccxt/exmo.py CHANGED
@@ -273,6 +273,7 @@ class exmo(Exchange, ImplicitAPI):
273
273
  'info': data,
274
274
  'symbol': self.safe_symbol(None, market),
275
275
  'type': None,
276
+ 'marginMode': 'isolated',
276
277
  'amount': None,
277
278
  'total': None,
278
279
  'code': self.safe_value(market, 'quote'),
ccxt/gate.py CHANGED
@@ -138,6 +138,7 @@ class gate(Exchange, ImplicitAPI):
138
138
  'fetchLeverages': True,
139
139
  'fetchLeverageTiers': True,
140
140
  'fetchLiquidations': True,
141
+ 'fetchMarginAdjustmentHistory': False,
141
142
  'fetchMarginMode': False,
142
143
  'fetchMarketLeverageTiers': True,
143
144
  'fetchMarkets': True,
@@ -5687,6 +5688,7 @@ class gate(Exchange, ImplicitAPI):
5687
5688
  'info': data,
5688
5689
  'symbol': market['symbol'],
5689
5690
  'type': None,
5691
+ 'marginMode': 'isolated',
5690
5692
  'amount': None,
5691
5693
  'total': total,
5692
5694
  'code': self.safe_value(market, 'quote'),
ccxt/gemini.py CHANGED
@@ -121,6 +121,7 @@ class gemini(Exchange, ImplicitAPI):
121
121
  # https://github.com/ccxt/ccxt/issues/7874
122
122
  # https://github.com/ccxt/ccxt/issues/7894
123
123
  'web': 'https://docs.gemini.com',
124
+ 'webExchange': 'https://exchange.gemini.com',
124
125
  },
125
126
  'fees': [
126
127
  'https://gemini.com/api-fee-schedule',
@@ -629,7 +630,7 @@ class gemini(Exchange, ImplicitAPI):
629
630
  quoteId = None
630
631
  settleId = None
631
632
  tickSize = None
632
- increment = None
633
+ amountPrecision = None
633
634
  minSize = None
634
635
  status = None
635
636
  swap = False
@@ -640,9 +641,9 @@ class gemini(Exchange, ImplicitAPI):
640
641
  isArray = (isinstance(response, list))
641
642
  if not isString and not isArray:
642
643
  marketId = self.safe_string_lower(response, 'symbol')
644
+ amountPrecision = self.safe_number(response, 'tick_size') # right, exchange has an imperfect naming and self turns out to be an amount-precision
645
+ tickSize = self.safe_number(response, 'quote_increment') # self is tick-size actually
643
646
  minSize = self.safe_number(response, 'min_order_size')
644
- tickSize = self.safe_number(response, 'tick_size')
645
- increment = self.safe_number(response, 'quote_increment')
646
647
  status = self.parse_market_active(self.safe_string(response, 'status'))
647
648
  baseId = self.safe_string(response, 'base_currency')
648
649
  quoteId = self.safe_string(response, 'quote_currency')
@@ -653,9 +654,9 @@ class gemini(Exchange, ImplicitAPI):
653
654
  marketId = response
654
655
  else:
655
656
  marketId = self.safe_string_lower(response, 0)
656
- minSize = self.safe_number(response, 3)
657
- tickSize = self.parse_number(self.parse_precision(self.safe_string(response, 1)))
658
- increment = self.parse_number(self.parse_precision(self.safe_string(response, 2)))
657
+ tickSize = self.parse_number(self.parse_precision(self.safe_string(response, 1))) # priceTickDecimalPlaces
658
+ amountPrecision = self.parse_number(self.parse_precision(self.safe_string(response, 2))) # quantityTickDecimalPlaces
659
+ minSize = self.safe_number(response, 3) # quantityMinimum
659
660
  marketIdUpper = marketId.upper()
660
661
  isPerp = (marketIdUpper.find('PERP') >= 0)
661
662
  marketIdWithoutPerp = marketIdUpper.replace('PERP', '')
@@ -704,8 +705,8 @@ class gemini(Exchange, ImplicitAPI):
704
705
  'strike': None,
705
706
  'optionType': None,
706
707
  'precision': {
707
- 'price': increment,
708
- 'amount': tickSize,
708
+ 'price': tickSize,
709
+ 'amount': amountPrecision,
709
710
  },
710
711
  'limits': {
711
712
  'leverage': {
@@ -1707,7 +1708,7 @@ class gemini(Exchange, ImplicitAPI):
1707
1708
  apiKey = self.apiKey
1708
1709
  if apiKey.find('account') < 0:
1709
1710
  raise AuthenticationError(self.id + ' sign() requires an account-key, master-keys are not-supported')
1710
- nonce = self.nonce()
1711
+ nonce = str(self.nonce())
1711
1712
  request = self.extend({
1712
1713
  'request': url,
1713
1714
  'nonce': nonce,
ccxt/hitbtc.py CHANGED
@@ -3082,6 +3082,7 @@ class hitbtc(Exchange, ImplicitAPI):
3082
3082
  'info': data,
3083
3083
  'symbol': market['symbol'],
3084
3084
  'type': None,
3085
+ 'marginMode': 'isolated',
3085
3086
  'amount': None,
3086
3087
  'total': None,
3087
3088
  'code': self.safe_string(currencyInfo, 'code'),
ccxt/htx.py CHANGED
@@ -102,6 +102,7 @@ class htx(Exchange, ImplicitAPI):
102
102
  'fetchLeverage': False,
103
103
  'fetchLeverageTiers': True,
104
104
  'fetchLiquidations': True,
105
+ 'fetchMarginAdjustmentHistory': False,
105
106
  'fetchMarketLeverageTiers': True,
106
107
  'fetchMarkets': True,
107
108
  'fetchMarkOHLCV': True,
ccxt/hyperliquid.py CHANGED
@@ -2024,6 +2024,7 @@ class hyperliquid(Exchange, ImplicitAPI):
2024
2024
  'info': data,
2025
2025
  'symbol': self.safe_symbol(None, market),
2026
2026
  'type': None,
2027
+ 'marginMode': 'isolated',
2027
2028
  'amount': None,
2028
2029
  'total': None,
2029
2030
  'code': self.safe_string(market, 'settle'),
ccxt/kucoin.py CHANGED
@@ -92,6 +92,7 @@ class kucoin(Exchange, ImplicitAPI):
92
92
  'fetchL3OrderBook': True,
93
93
  'fetchLedger': True,
94
94
  'fetchLeverageTiers': False,
95
+ 'fetchMarginAdjustmentHistory': False,
95
96
  'fetchMarginMode': False,
96
97
  'fetchMarketLeverageTiers': False,
97
98
  'fetchMarkets': True,
ccxt/kucoinfutures.py CHANGED
@@ -80,6 +80,7 @@ class kucoinfutures(kucoin, ImplicitAPI):
80
80
  'fetchL3OrderBook': True,
81
81
  'fetchLedger': True,
82
82
  'fetchLeverageTiers': False,
83
+ 'fetchMarginAdjustmentHistory': False,
83
84
  'fetchMarginMode': False,
84
85
  'fetchMarketLeverageTiers': True,
85
86
  'fetchMarkets': True,
@@ -1497,7 +1498,7 @@ class kucoinfutures(kucoin, ImplicitAPI):
1497
1498
  'direction': 'in',
1498
1499
  })
1499
1500
 
1500
- def parse_margin_modification(self, info, market: Market = None):
1501
+ def parse_margin_modification(self, info, market: Market = None) -> MarginModification:
1501
1502
  #
1502
1503
  # {
1503
1504
  # "id": "62311d26064e8f00013f2c6d",
@@ -1549,14 +1550,18 @@ class kucoinfutures(kucoin, ImplicitAPI):
1549
1550
  crossMode = self.safe_value(info, 'crossMode')
1550
1551
  mode = 'cross' if crossMode else 'isolated'
1551
1552
  marketId = self.safe_string(market, 'symbol')
1553
+ timestamp = self.safe_integer(info, 'currentTimestamp')
1552
1554
  return {
1553
1555
  'info': info,
1554
- 'direction': None,
1555
- 'mode': mode,
1556
+ 'symbol': self.safe_symbol(marketId, market),
1557
+ 'type': None,
1558
+ 'marginMode': mode,
1556
1559
  'amount': None,
1560
+ 'total': None,
1557
1561
  'code': self.safe_currency_code(currencyId),
1558
- 'symbol': self.safe_symbol(marketId, market),
1559
1562
  'status': None,
1563
+ 'timestamp': timestamp,
1564
+ 'datetime': self.iso8601(timestamp),
1560
1565
  }
1561
1566
 
1562
1567
  def fetch_orders_by_status(self, status, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
@@ -1682,6 +1687,29 @@ class kucoinfutures(kucoin, ImplicitAPI):
1682
1687
  return self.fetch_paginated_call_dynamic('fetchClosedOrders', symbol, since, limit, params)
1683
1688
  return self.fetch_orders_by_status('done', symbol, since, limit, params)
1684
1689
 
1690
+ def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1691
+ """
1692
+ fetches information on multiple open orders made by the user
1693
+ :see: https://docs.kucoin.com/futures/#get-order-list
1694
+ :see: https://docs.kucoin.com/futures/#get-untriggered-stop-order-list
1695
+ :param str symbol: unified market symbol of the market orders were made in
1696
+ :param int [since]: the earliest time in ms to fetch orders for
1697
+ :param int [limit]: the maximum number of order structures to retrieve
1698
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1699
+ :param int [params.till]: end time in ms
1700
+ :param str [params.side]: buy or sell
1701
+ :param str [params.type]: limit, or market
1702
+ :param boolean [params.trigger]: set to True to retrieve untriggered stop orders
1703
+ :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)
1704
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1705
+ """
1706
+ self.load_markets()
1707
+ paginate = False
1708
+ paginate, params = self.handle_option_and_params(params, 'fetchOpenOrders', 'paginate')
1709
+ if paginate:
1710
+ return self.fetch_paginated_call_dynamic('fetchOpenOrders', symbol, since, limit, params)
1711
+ return self.fetch_orders_by_status('open', symbol, since, limit, params)
1712
+
1685
1713
  def fetch_order(self, id: Str = None, symbol: Str = None, params={}):
1686
1714
  """
1687
1715
  fetches information on an order made by the user
ccxt/mexc.py CHANGED
@@ -89,6 +89,7 @@ class mexc(Exchange, ImplicitAPI):
89
89
  'fetchLeverage': True,
90
90
  'fetchLeverages': False,
91
91
  'fetchLeverageTiers': True,
92
+ 'fetchMarginAdjustmentHistory': False,
92
93
  'fetchMarginMode': False,
93
94
  'fetchMarketLeverageTiers': None,
94
95
  'fetchMarkets': True,
ccxt/okx.py CHANGED
@@ -106,6 +106,7 @@ class okx(Exchange, ImplicitAPI):
106
106
  'fetchLedgerEntry': None,
107
107
  'fetchLeverage': True,
108
108
  'fetchLeverageTiers': False,
109
+ 'fetchMarginAdjustmentHistory': True,
109
110
  'fetchMarketLeverageTiers': True,
110
111
  'fetchMarkets': True,
111
112
  'fetchMarkOHLCV': True,
@@ -6035,9 +6036,9 @@ class okx(Exchange, ImplicitAPI):
6035
6036
  # }
6036
6037
  #
6037
6038
  data = self.safe_list(response, 'data', [])
6039
+ entry = self.safe_dict(data, 0, {})
6038
6040
  errorCode = self.safe_string(response, 'code')
6039
- item = self.safe_dict(data, 0, {})
6040
- return self.extend(self.parse_margin_modification(item, market), {
6041
+ return self.extend(self.parse_margin_modification(entry, market), {
6041
6042
  'status': 'ok' if (errorCode == '0') else 'failed',
6042
6043
  })
6043
6044
 
@@ -6052,22 +6053,66 @@ class okx(Exchange, ImplicitAPI):
6052
6053
  # "type": "reduce"
6053
6054
  # }
6054
6055
  #
6055
- amountRaw = self.safe_number(data, 'amt')
6056
+ # fetchMarginAdjustmentHistory
6057
+ #
6058
+ # {
6059
+ # bal: '67621.4325135010619812',
6060
+ # balChg: '-10.0000000000000000',
6061
+ # billId: '691293628710342659',
6062
+ # ccy: 'USDT',
6063
+ # clOrdId: '',
6064
+ # execType: '',
6065
+ # fee: '0',
6066
+ # fillFwdPx: '',
6067
+ # fillIdxPx: '',
6068
+ # fillMarkPx: '',
6069
+ # fillMarkVol: '',
6070
+ # fillPxUsd: '',
6071
+ # fillPxVol: '',
6072
+ # fillTime: '1711089244850',
6073
+ # from: '',
6074
+ # instId: 'XRP-USDT-SWAP',
6075
+ # instType: 'SWAP',
6076
+ # interest: '0',
6077
+ # mgnMode: 'isolated',
6078
+ # notes: '',
6079
+ # ordId: '',
6080
+ # pnl: '0',
6081
+ # posBal: '73.12',
6082
+ # posBalChg: '10.00',
6083
+ # px: '',
6084
+ # subType: '160',
6085
+ # sz: '10',
6086
+ # tag: '',
6087
+ # to: '',
6088
+ # tradeId: '0',
6089
+ # ts: '1711089244699',
6090
+ # type: '6'
6091
+ # }
6092
+ #
6093
+ amountRaw = self.safe_string_2(data, 'amt', 'posBalChg')
6056
6094
  typeRaw = self.safe_string(data, 'type')
6057
- type = 'reduce' if (typeRaw == 'reduce') else 'add'
6095
+ type = None
6096
+ if typeRaw == '6':
6097
+ type = 'add' if Precise.string_gt(amountRaw, '0') else 'reduce'
6098
+ else:
6099
+ type = typeRaw
6100
+ amount = Precise.string_abs(amountRaw)
6058
6101
  marketId = self.safe_string(data, 'instId')
6059
6102
  responseMarket = self.safe_market(marketId, market)
6060
6103
  code = responseMarket['base'] if responseMarket['inverse'] else responseMarket['quote']
6104
+ timestamp = self.safe_integer(data, 'ts')
6061
6105
  return {
6062
6106
  'info': data,
6063
6107
  'symbol': responseMarket['symbol'],
6064
6108
  'type': type,
6065
- 'amount': amountRaw,
6066
- 'total': None,
6109
+ 'marginMode': 'isolated',
6110
+ 'amount': self.parse_number(amount),
6067
6111
  'code': code,
6112
+ 'total': None,
6068
6113
  'status': None,
6069
- 'timestamp': None,
6070
- 'datetime': None,
6114
+ 'timestamp': timestamp,
6115
+ 'datetime': self.iso8601(timestamp),
6071
6116
  }
6072
6117
 
6073
6118
  def reduce_margin(self, symbol: str, amount, params={}) -> MarginModification:
@@ -7088,3 +7133,93 @@ class okx(Exchange, ImplicitAPI):
7088
7133
  self.throw_exactly_matched_exception(self.exceptions['exact'], code, feedback)
7089
7134
  raise ExchangeError(feedback) # unknown message
7090
7135
  return None
7136
+
7137
+ def fetch_margin_adjustment_history(self, symbol: Str = None, type: Str = None, since: Num = None, limit: Num = None, params={}) -> List[MarginModification]:
7138
+ """
7139
+ fetches the history of margin added or reduced from contract isolated positions
7140
+ :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-7-days
7141
+ :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-3-months
7142
+ :param str [symbol]: not used by okx fetchMarginAdjustmentHistory
7143
+ :param str [type]: "add" or "reduce"
7144
+ :param dict params: extra parameters specific to the exchange api endpoint
7145
+ :param boolean [params.auto]: True if fetching auto margin increases
7146
+ :returns dict[]: a list of `margin structures <https://docs.ccxt.com/#/?id=margin-loan-structure>`
7147
+ """
7148
+ self.load_markets()
7149
+ auto = self.safe_bool(params, 'auto')
7150
+ if type is None:
7151
+ raise ArgumentsRequired(self.id + ' fetchMarginAdjustmentHistory() requires a type argument')
7152
+ isAdd = type == 'add'
7153
+ subType = '160' if isAdd else '161'
7154
+ if auto:
7155
+ if isAdd:
7156
+ subType = '162'
7157
+ else:
7158
+ raise BadRequest(self.id + ' cannot fetch margin adjustments for type ' + type)
7159
+ request = {
7160
+ 'subType': subType,
7161
+ 'mgnMode': 'isolated',
7162
+ }
7163
+ until = self.safe_integer(params, 'until')
7164
+ params = self.omit(params, 'until')
7165
+ if since is not None:
7166
+ request['startTime'] = since
7167
+ if limit is not None:
7168
+ request['limit'] = limit
7169
+ if until is not None:
7170
+ request['endTime'] = until
7171
+ response = None
7172
+ now = self.milliseconds()
7173
+ oneWeekAgo = now - 604800000
7174
+ threeMonthsAgo = now - 7776000000
7175
+ if (since is None) or (since > oneWeekAgo):
7176
+ response = self.privateGetAccountBills(self.extend(request, params))
7177
+ elif since > threeMonthsAgo:
7178
+ response = self.privateGetAccountBillsArchive(self.extend(request, params))
7179
+ else:
7180
+ raise BadRequest(self.id + ' fetchMarginAdjustmentHistory() cannot fetch margin adjustments older than 3 months')
7181
+ #
7182
+ # {
7183
+ # code: '0',
7184
+ # data: [
7185
+ # {
7186
+ # bal: '67621.4325135010619812',
7187
+ # balChg: '-10.0000000000000000',
7188
+ # billId: '691293628710342659',
7189
+ # ccy: 'USDT',
7190
+ # clOrdId: '',
7191
+ # execType: '',
7192
+ # fee: '0',
7193
+ # fillFwdPx: '',
7194
+ # fillIdxPx: '',
7195
+ # fillMarkPx: '',
7196
+ # fillMarkVol: '',
7197
+ # fillPxUsd: '',
7198
+ # fillPxVol: '',
7199
+ # fillTime: '1711089244850',
7200
+ # from: '',
7201
+ # instId: 'XRP-USDT-SWAP',
7202
+ # instType: 'SWAP',
7203
+ # interest: '0',
7204
+ # mgnMode: 'isolated',
7205
+ # notes: '',
7206
+ # ordId: '',
7207
+ # pnl: '0',
7208
+ # posBal: '73.12',
7209
+ # posBalChg: '10.00',
7210
+ # px: '',
7211
+ # subType: '160',
7212
+ # sz: '10',
7213
+ # tag: '',
7214
+ # to: '',
7215
+ # tradeId: '0',
7216
+ # ts: '1711089244699',
7217
+ # type: '6'
7218
+ # }
7219
+ # ],
7220
+ # msg: ''
7221
+ # }
7222
+ #
7223
+ data = self.safe_list(response, 'data')
7224
+ modifications = self.parse_margin_modifications(data)
7225
+ return self.filter_by_symbol_since_limit(modifications, symbol, since, limit)
ccxt/phemex.py CHANGED
@@ -3792,6 +3792,7 @@ class phemex(Exchange, ImplicitAPI):
3792
3792
  'info': data,
3793
3793
  'symbol': self.safe_symbol(None, market),
3794
3794
  'type': 'set',
3795
+ 'marginMode': 'isolated',
3795
3796
  'amount': None,
3796
3797
  'total': None,
3797
3798
  'code': market[codeCurrency],
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.2.89'
7
+ __version__ = '4.2.90'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/woo.py CHANGED
@@ -77,6 +77,7 @@ class woo(Exchange, ImplicitAPI):
77
77
  'fetchIndexOHLCV': False,
78
78
  'fetchLedger': True,
79
79
  'fetchLeverage': True,
80
+ 'fetchMarginAdjustmentHistory': False,
80
81
  'fetchMarginMode': False,
81
82
  'fetchMarkets': True,
82
83
  'fetchMarkOHLCV': False,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ccxt
3
- Version: 4.2.89
3
+ Version: 4.2.90
4
4
  Summary: A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges
5
5
  Home-page: https://ccxt.com
6
6
  Author: Igor Kroitor
@@ -261,13 +261,13 @@ console.log(version, Object.keys(exchanges));
261
261
 
262
262
  All-in-one browser bundle (dependencies included), served from a CDN of your choice:
263
263
 
264
- * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.2.89/dist/ccxt.browser.js
265
- * unpkg: https://unpkg.com/ccxt@4.2.89/dist/ccxt.browser.js
264
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.2.90/dist/ccxt.browser.js
265
+ * unpkg: https://unpkg.com/ccxt@4.2.90/dist/ccxt.browser.js
266
266
 
267
267
  CDNs are not updated in real-time and may have delays. Defaulting to the most recent version without specifying the version number is not recommended. Please, keep in mind that we are not responsible for the correct operation of those CDN servers.
268
268
 
269
269
  ```HTML
270
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.2.89/dist/ccxt.browser.js"></script>
270
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.2.90/dist/ccxt.browser.js"></script>
271
271
  ```
272
272
 
273
273
  Creates a global `ccxt` object: