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

ccxt/async_support/woo.py CHANGED
@@ -155,7 +155,7 @@ class woo(Exchange, ImplicitAPI):
155
155
  'https://support.woo.org/hc/en-001/articles/4404611795353--Trading-Fees',
156
156
  ],
157
157
  'referral': {
158
- 'url': 'https://x.woo.org/register?ref=YWOWC96B',
158
+ 'url': 'https://x.woo.org/register?ref=DIJT0CNL',
159
159
  'discount': 0.35,
160
160
  },
161
161
  },
@@ -5,6 +5,7 @@
5
5
 
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.yobit import ImplicitAPI
8
+ import asyncio
8
9
  import hashlib
9
10
  from ccxt.base.types import Balances, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees
10
11
  from typing import List
@@ -541,31 +542,7 @@ class yobit(Exchange, ImplicitAPI):
541
542
  'info': ticker,
542
543
  }, market)
543
544
 
544
- async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
545
- """
546
- :see: https://yobit.net/en/api
547
- fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
548
- :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
549
- :param dict [params]: extra parameters specific to the exchange API endpoint
550
- :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
551
- """
552
- if symbols is None:
553
- raise ArgumentsRequired(self.id + ' fetchTickers() requires "symbols" argument')
554
- await self.load_markets()
555
- symbols = self.market_symbols(symbols)
556
- ids = None
557
- if symbols is None:
558
- ids = self.ids
559
- else:
560
- ids = self.market_ids(symbols)
561
- idsLength: number = len(ids)
562
- idsString = '-'.join(ids)
563
- maxLength = self.safe_integer(self.options, 'maxUrlLength', 2048)
564
- # max URL length is 2048 symbols, including http schema, hostname, tld, etc...
565
- lenghtOfBaseUrl = 30 # the url including api-base and endpoint dir is 30 chars
566
- actualLength = len(idsString) + lenghtOfBaseUrl
567
- if actualLength > maxLength:
568
- raise ArgumentsRequired(self.id + ' fetchTickers() is being requested for ' + str(idsLength) + ' markets(which has an URL length of ' + str(actualLength) + ' characters), but it exceedes max URL length(' + str(maxLength) + '), please pass limisted symbols array to fetchTickers to fit in one request')
545
+ async def fetch_tickers_helper(self, idsString: str, params={}) -> Tickers:
569
546
  request: dict = {
570
547
  'pair': idsString,
571
548
  }
@@ -578,7 +555,53 @@ class yobit(Exchange, ImplicitAPI):
578
555
  market = self.safe_market(id)
579
556
  symbol = market['symbol']
580
557
  result[symbol] = self.parse_ticker(ticker, market)
581
- return self.filter_by_array_tickers(result, 'symbol', symbols)
558
+ return result
559
+
560
+ async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
561
+ """
562
+ :see: https://yobit.net/en/api
563
+ fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
564
+ :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
565
+ :param dict [params]: extra parameters specific to the exchange API endpoint
566
+ :param dict [params.all]: you can set to `true` for convenience to fetch all tickers from self exchange by sending multiple requests
567
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
568
+ """
569
+ allSymbols = None
570
+ allSymbols, params = self.handle_param_bool(params, 'all', False)
571
+ if symbols is None and not allSymbols:
572
+ raise ArgumentsRequired(self.id + ' fetchTickers() requires "symbols" argument or use `params["all"] = True` to send multiple requests for all markets')
573
+ await self.load_markets()
574
+ promises = []
575
+ maxLength = self.safe_integer(self.options, 'maxUrlLength', 2048)
576
+ # max URL length is 2048 symbols, including http schema, hostname, tld, etc...
577
+ lenghtOfBaseUrl = 40 # safe space for the url including api-base and endpoint dir is 30 chars
578
+ if allSymbols:
579
+ symbols = self.symbols
580
+ ids = ''
581
+ for i in range(0, len(self.ids)):
582
+ id = self.ids[i]
583
+ prefix = '' if (ids == '') else '-'
584
+ ids += prefix + id
585
+ if len(ids) > maxLength:
586
+ promises.append(self.fetch_tickers_helper(ids, params))
587
+ ids = ''
588
+ if ids != '':
589
+ promises.append(self.fetch_tickers_helper(ids, params))
590
+ else:
591
+ symbols = self.market_symbols(symbols)
592
+ ids = self.market_ids(symbols)
593
+ idsLength: number = len(ids)
594
+ idsString = '-'.join(ids)
595
+ actualLength = len(idsString) + lenghtOfBaseUrl
596
+ if actualLength > maxLength:
597
+ raise ArgumentsRequired(self.id + ' fetchTickers() is being requested for ' + str(idsLength) + ' markets(which has an URL length of ' + str(actualLength) + ' characters), but it exceedes max URL length(' + str(maxLength) + '), please pass limisted symbols array to fetchTickers to fit in one request')
598
+ promises.append(self.fetch_tickers_helper(idsString, params))
599
+ resultAll = await asyncio.gather(*promises)
600
+ finalResult = {}
601
+ for i in range(0, len(resultAll)):
602
+ result = self.filter_by_array_tickers(resultAll[i], 'symbol', symbols)
603
+ finalResult = self.extend(finalResult, result)
604
+ return finalResult
582
605
 
583
606
  async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
584
607
  """
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.73'
7
+ __version__ = '4.3.74'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
ccxt/binance.py CHANGED
@@ -212,8 +212,10 @@ class binance(Exchange, ImplicitAPI):
212
212
  'dapiPrivateV2': 'https://testnet.binancefuture.com/dapi/v2',
213
213
  'fapiPublic': 'https://testnet.binancefuture.com/fapi/v1',
214
214
  'fapiPublicV2': 'https://testnet.binancefuture.com/fapi/v2',
215
+ 'fapiPublicV3': 'https://testnet.binancefuture.com/fapi/v3',
215
216
  'fapiPrivate': 'https://testnet.binancefuture.com/fapi/v1',
216
217
  'fapiPrivateV2': 'https://testnet.binancefuture.com/fapi/v2',
218
+ 'fapiPrivateV3': 'https://testnet.binancefuture.com/fapi/v3',
217
219
  'public': 'https://testnet.binance.vision/api/v3',
218
220
  'private': 'https://testnet.binance.vision/api/v3',
219
221
  'v1': 'https://testnet.binance.vision/api/v1',
@@ -231,9 +233,11 @@ class binance(Exchange, ImplicitAPI):
231
233
  'dapiData': 'https://dapi.binance.com/futures/data',
232
234
  'fapiPublic': 'https://fapi.binance.com/fapi/v1',
233
235
  'fapiPublicV2': 'https://fapi.binance.com/fapi/v2',
236
+ 'fapiPublicV3': 'https://fapi.binance.com/fapi/v3',
234
237
  'fapiPrivate': 'https://fapi.binance.com/fapi/v1',
235
- 'fapiData': 'https://fapi.binance.com/futures/data',
236
238
  'fapiPrivateV2': 'https://fapi.binance.com/fapi/v2',
239
+ 'fapiPrivateV3': 'https://fapi.binance.com/fapi/v3',
240
+ 'fapiData': 'https://fapi.binance.com/futures/data',
237
241
  'public': 'https://api.binance.com/api/v3',
238
242
  'private': 'https://api.binance.com/api/v3',
239
243
  'v1': 'https://api.binance.com/api/v1',
@@ -869,6 +873,8 @@ class binance(Exchange, ImplicitAPI):
869
873
  'trade/asyn': 1000,
870
874
  'trade/asyn/id': 10,
871
875
  'feeBurn': 1,
876
+ 'symbolConfig': 5,
877
+ 'accountConfig': 5,
872
878
  },
873
879
  'post': {
874
880
  'batchOrders': 5,
@@ -909,6 +915,16 @@ class binance(Exchange, ImplicitAPI):
909
915
  'positionRisk': 1,
910
916
  },
911
917
  },
918
+ 'fapiPublicV3': {
919
+ 'get': {},
920
+ },
921
+ 'fapiPrivateV3': {
922
+ 'get': {
923
+ 'account': 1,
924
+ 'balance': 1,
925
+ 'positionRisk': 1,
926
+ },
927
+ },
912
928
  'eapiPublic': {
913
929
  'get': {
914
930
  'ping': 1,
@@ -3347,7 +3363,7 @@ class binance(Exchange, ImplicitAPI):
3347
3363
  response = self.papiGetBalance(self.extend(request, query))
3348
3364
  elif self.is_linear(type, subType):
3349
3365
  type = 'linear'
3350
- response = self.fapiPrivateV2GetAccount(self.extend(request, query))
3366
+ response = self.fapiPrivateV3GetAccount(self.extend(request, query))
3351
3367
  elif self.is_inverse(type, subType):
3352
3368
  type = 'inverse'
3353
3369
  response = self.dapiPrivateGetAccount(self.extend(request, query))
@@ -8765,24 +8781,29 @@ class binance(Exchange, ImplicitAPI):
8765
8781
  #
8766
8782
  # usdm
8767
8783
  #
8784
+ # v3(similar for cross & isolated)
8785
+ #
8768
8786
  # {
8769
- # "symbol": "BTCBUSD",
8770
- # "initialMargin": "0",
8771
- # "maintMargin": "0",
8772
- # "unrealizedProfit": "0.00000000",
8773
- # "positionInitialMargin": "0",
8774
- # "openOrderInitialMargin": "0",
8775
- # "leverage": "20",
8776
- # "isolated": False,
8777
- # "entryPrice": "0.0000",
8778
- # "maxNotional": "100000",
8779
- # "positionSide": "BOTH",
8780
- # "positionAmt": "0.000",
8781
- # "notional": "0",
8782
- # "isolatedWallet": "0",
8783
- # "updateTime": "0",
8784
- # "crossMargin": "100.93634809",
8785
- # }
8787
+ # "symbol": "WLDUSDT",
8788
+ # "positionSide": "BOTH",
8789
+ # "positionAmt": "-849",
8790
+ # "unrealizedProfit": "11.17920750",
8791
+ # "notional": "-1992.46079250",
8792
+ # "isolatedMargin": "0",
8793
+ # "isolatedWallet": "0",
8794
+ # "initialMargin": "99.62303962",
8795
+ # "maintMargin": "11.95476475",
8796
+ # "updateTime": "1721995760449"
8797
+ # "leverage": "50", # in v2
8798
+ # "entryPrice": "2.34", # in v2
8799
+ # "positionInitialMargin": "118.82116614", # in v2
8800
+ # "openOrderInitialMargin": "0", # in v2
8801
+ # "isolated": False, # in v2
8802
+ # "breakEvenPrice": "2.3395788", # in v2
8803
+ # "maxNotional": "25000", # in v2
8804
+ # "bidNotional": "0", # in v2
8805
+ # "askNotional": "0" # in v2
8806
+ # }
8786
8807
  #
8787
8808
  # coinm
8788
8809
  #
@@ -8848,13 +8869,15 @@ class binance(Exchange, ImplicitAPI):
8848
8869
  market = self.safe_market(marketId, market, None, 'contract')
8849
8870
  symbol = self.safe_string(market, 'symbol')
8850
8871
  leverageString = self.safe_string(position, 'leverage')
8851
- leverage = int(leverageString)
8872
+ leverage = int(leverageString) if (leverageString is not None) else None
8852
8873
  initialMarginString = self.safe_string(position, 'initialMargin')
8853
8874
  initialMargin = self.parse_number(initialMarginString)
8854
- initialMarginPercentageString = Precise.string_div('1', leverageString, 8)
8855
- rational = self.is_round_number(1000 % leverage)
8856
- if not rational:
8857
- initialMarginPercentageString = Precise.string_div(Precise.string_add(initialMarginPercentageString, '1e-8'), '1', 8)
8875
+ initialMarginPercentageString = None
8876
+ if leverageString is not None:
8877
+ initialMarginPercentageString = Precise.string_div('1', leverageString, 8)
8878
+ rational = self.is_round_number(1000 % leverage)
8879
+ if not rational:
8880
+ initialMarginPercentageString = Precise.string_div(Precise.string_add(initialMarginPercentageString, '1e-8'), '1', 8)
8858
8881
  # to notionalValue
8859
8882
  usdm = ('notional' in position)
8860
8883
  maintenanceMarginString = self.safe_string(position, 'maintMargin')
@@ -8887,6 +8910,9 @@ class binance(Exchange, ImplicitAPI):
8887
8910
  if timestamp == 0:
8888
8911
  timestamp = None
8889
8912
  isolated = self.safe_bool(position, 'isolated')
8913
+ if isolated is None:
8914
+ isolatedMarginRaw = self.safe_string(position, 'isolatedMargin')
8915
+ isolated = not Precise.string_eq(isolatedMarginRaw, '0')
8890
8916
  marginMode = None
8891
8917
  collateralString = None
8892
8918
  walletBalance = None
@@ -8991,23 +9017,34 @@ class binance(Exchange, ImplicitAPI):
8991
9017
  #
8992
9018
  # usdm
8993
9019
  #
8994
- # {
8995
- # "symbol": "BTCUSDT",
8996
- # "positionAmt": "0.001",
8997
- # "entryPrice": "43578.07000",
8998
- # "markPrice": "43532.30000000",
8999
- # "unRealizedProfit": "-0.04577000",
9000
- # "liquidationPrice": "21841.24993976",
9001
- # "leverage": "2",
9002
- # "maxNotionalValue": "300000000",
9003
- # "marginType": "isolated",
9004
- # "isolatedMargin": "21.77841506",
9005
- # "isAutoAddMargin": "false",
9006
- # "positionSide": "BOTH",
9007
- # "notional": "43.53230000",
9008
- # "isolatedWallet": "21.82418506",
9009
- # "updateTime": "1621358023886"
9010
- # }
9020
+ # {
9021
+ # symbol: "WLDUSDT",
9022
+ # positionSide: "BOTH",
9023
+ # positionAmt: "5",
9024
+ # entryPrice: "2.3483",
9025
+ # breakEvenPrice: "2.349356735",
9026
+ # markPrice: "2.39560000",
9027
+ # unRealizedProfit: "0.23650000",
9028
+ # liquidationPrice: "0",
9029
+ # isolatedMargin: "0",
9030
+ # notional: "11.97800000",
9031
+ # isolatedWallet: "0",
9032
+ # updateTime: "1722062678998",
9033
+ # initialMargin: "2.39560000", # not in v2
9034
+ # maintMargin: "0.07186800", # not in v2
9035
+ # positionInitialMargin: "2.39560000", # not in v2
9036
+ # openOrderInitialMargin: "0", # not in v2
9037
+ # adl: "2", # not in v2
9038
+ # bidNotional: "0", # not in v2
9039
+ # askNotional: "0", # not in v2
9040
+ # marginAsset: "USDT", # not in v2
9041
+ # # the below fields are only in v2
9042
+ # leverage: "5",
9043
+ # maxNotionalValue: "6000000",
9044
+ # marginType: "cross",
9045
+ # isAutoAddMargin: "false",
9046
+ # isolated: False,
9047
+ # adlQuantile: "2",
9011
9048
  #
9012
9049
  # coinm
9013
9050
  #
@@ -9065,6 +9102,7 @@ class binance(Exchange, ImplicitAPI):
9065
9102
  marketId = self.safe_string(position, 'symbol')
9066
9103
  market = self.safe_market(marketId, market, None, 'contract')
9067
9104
  symbol = self.safe_string(market, 'symbol')
9105
+ isolatedMarginString = self.safe_string(position, 'isolatedMargin')
9068
9106
  leverageBrackets = self.safe_dict(self.options, 'leverageBrackets', {})
9069
9107
  leverageBracket = self.safe_list(leverageBrackets, symbol, [])
9070
9108
  notionalString = self.safe_string_2(position, 'notional', 'notionalValue')
@@ -9080,12 +9118,12 @@ class binance(Exchange, ImplicitAPI):
9080
9118
  contracts = self.parse_number(contractsAbs)
9081
9119
  unrealizedPnlString = self.safe_string(position, 'unRealizedProfit')
9082
9120
  unrealizedPnl = self.parse_number(unrealizedPnlString)
9083
- leverageString = self.safe_string(position, 'leverage')
9084
- leverage = int(leverageString)
9085
9121
  liquidationPriceString = self.omit_zero(self.safe_string(position, 'liquidationPrice'))
9086
9122
  liquidationPrice = self.parse_number(liquidationPriceString)
9087
9123
  collateralString = None
9088
9124
  marginMode = self.safe_string(position, 'marginType')
9125
+ if marginMode is None and isolatedMarginString:
9126
+ marginMode = 'cross' if Precise.string_eq(isolatedMarginString, '0') else 'isolated'
9089
9127
  side = None
9090
9128
  if Precise.string_gt(notionalString, '0'):
9091
9129
  side = 'long'
@@ -9142,13 +9180,25 @@ class binance(Exchange, ImplicitAPI):
9142
9180
  timestamp = None
9143
9181
  maintenanceMarginPercentage = self.parse_number(maintenanceMarginPercentageString)
9144
9182
  maintenanceMarginString = Precise.string_mul(maintenanceMarginPercentageString, notionalStringAbs)
9183
+ if maintenanceMarginString is None:
9184
+ # for a while, self new value was a backup to the existing calculations, but in future we might prioritize self
9185
+ maintenanceMarginString = self.safe_string(position, 'maintMargin')
9145
9186
  maintenanceMargin = self.parse_number(maintenanceMarginString)
9146
- initialMarginPercentageString = Precise.string_div('1', leverageString, 8)
9147
- rational = self.is_round_number(1000 % leverage)
9148
- if not rational:
9149
- initialMarginPercentageString = Precise.string_add(initialMarginPercentageString, '1e-8')
9150
- initialMarginString = Precise.string_div(Precise.string_mul(notionalStringAbs, initialMarginPercentageString), '1', 8)
9151
- initialMargin = self.parse_number(initialMarginString)
9187
+ initialMarginString = None
9188
+ initialMarginPercentageString = None
9189
+ leverageString = self.safe_string(position, 'leverage')
9190
+ if leverageString is not None:
9191
+ leverage = int(leverageString)
9192
+ rational = self.is_round_number(1000 % leverage)
9193
+ initialMarginPercentageString = Precise.string_div('1', leverageString, 8)
9194
+ if not rational:
9195
+ initialMarginPercentageString = Precise.string_add(initialMarginPercentageString, '1e-8')
9196
+ unrounded = Precise.string_mul(notionalStringAbs, initialMarginPercentageString)
9197
+ initialMarginString = Precise.string_div(unrounded, '1', 8)
9198
+ else:
9199
+ initialMarginString = self.safe_string(position, 'initialMargin')
9200
+ unrounded = Precise.string_mul(initialMarginString, '1')
9201
+ initialMarginPercentageString = Precise.string_div(unrounded, notionalStringAbs, 8)
9152
9202
  marginRatio = None
9153
9203
  percentage = None
9154
9204
  if not Precise.string_equals(collateralString, '0'):
@@ -9170,7 +9220,7 @@ class binance(Exchange, ImplicitAPI):
9170
9220
  'markPrice': markPrice,
9171
9221
  'entryPrice': entryPrice,
9172
9222
  'timestamp': timestamp,
9173
- 'initialMargin': initialMargin,
9223
+ 'initialMargin': self.parse_number(initialMarginString),
9174
9224
  'initialMarginPercentage': self.parse_number(initialMarginPercentageString),
9175
9225
  'maintenanceMargin': maintenanceMargin,
9176
9226
  'maintenanceMarginPercentage': maintenanceMarginPercentage,
@@ -9500,9 +9550,14 @@ class binance(Exchange, ImplicitAPI):
9500
9550
  :param str [method]: method name to call, "positionRisk", "account" or "option", default is "positionRisk"
9501
9551
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
9502
9552
  """
9503
- defaultValue = self.safe_string(self.options, 'fetchPositions', 'positionRisk')
9504
9553
  defaultMethod = None
9505
- defaultMethod, params = self.handle_option_and_params(params, 'fetchPositions', 'method', defaultValue)
9554
+ defaultMethod, params = self.handle_option_and_params(params, 'fetchPositions', 'method')
9555
+ if defaultMethod is None:
9556
+ options = self.safe_dict(self.options, 'fetchPositions')
9557
+ if options is None:
9558
+ defaultMethod = self.safe_string(self.options, 'fetchPositions', 'positionRisk')
9559
+ else:
9560
+ defaultMethod = 'positionRisk'
9506
9561
  if defaultMethod == 'positionRisk':
9507
9562
  return self.fetch_positions_risk(symbols, params)
9508
9563
  elif defaultMethod == 'account':
@@ -9510,7 +9565,7 @@ class binance(Exchange, ImplicitAPI):
9510
9565
  elif defaultMethod == 'option':
9511
9566
  return self.fetch_option_positions(symbols, params)
9512
9567
  else:
9513
- raise NotSupported(self.id + '.options["fetchPositions"]/params["method"] = "' + defaultMethod + '" is invalid, please choose between "account", "positionRisk" and "option"')
9568
+ raise NotSupported(self.id + '.options["fetchPositions"]["method"] or params["method"] = "' + defaultMethod + '" is invalid, please choose between "account", "positionRisk" and "option"')
9514
9569
 
9515
9570
  def fetch_account_positions(self, symbols: Strings = None, params={}):
9516
9571
  """
@@ -9525,6 +9580,7 @@ class binance(Exchange, ImplicitAPI):
9525
9580
  :param boolean [params.portfolioMargin]: set to True if you would like to fetch positions in a portfolio margin account
9526
9581
  :param str [params.subType]: "linear" or "inverse"
9527
9582
  :param boolean [params.filterClosed]: set to True if you would like to filter out closed positions, default is False
9583
+ :param boolean [params.useV2]: set to True if you want to use obsolete endpoint, where some more additional fields were provided
9528
9584
  :returns dict: data on account positions
9529
9585
  """
9530
9586
  if symbols is not None:
@@ -9544,7 +9600,78 @@ class binance(Exchange, ImplicitAPI):
9544
9600
  if isPortfolioMargin:
9545
9601
  response = self.papiGetUmAccount(params)
9546
9602
  else:
9547
- response = self.fapiPrivateV2GetAccount(params)
9603
+ useV2 = None
9604
+ useV2, params = self.handle_option_and_params(params, 'fetchAccountPositions', 'useV2', False)
9605
+ if not useV2:
9606
+ response = self.fapiPrivateV3GetAccount(params)
9607
+ else:
9608
+ response = self.fapiPrivateV2GetAccount(params)
9609
+ #
9610
+ # {
9611
+ # "totalInitialMargin": "99.62112386",
9612
+ # "totalMaintMargin": "11.95453485",
9613
+ # "totalWalletBalance": "99.84331553",
9614
+ # "totalUnrealizedProfit": "11.17675690",
9615
+ # "totalMarginBalance": "111.02007243",
9616
+ # "totalPositionInitialMargin": "99.62112386",
9617
+ # "totalOpenOrderInitialMargin": "0.00000000",
9618
+ # "totalCrossWalletBalance": "99.84331553",
9619
+ # "totalCrossUnPnl": "11.17675690",
9620
+ # "availableBalance": "11.39894857",
9621
+ # "maxWithdrawAmount": "11.39894857",
9622
+ # "feeTier": "0", # in v2
9623
+ # "canTrade": True, # in v2
9624
+ # "canDeposit": True, # in v2
9625
+ # "canWithdraw": True, # in v2
9626
+ # "feeBurn": True, # in v2
9627
+ # "tradeGroupId": "-1",// in v2
9628
+ # "updateTime": "0", # in v2
9629
+ # "multiAssetsMargin": True # in v2
9630
+ # "assets": [
9631
+ # {
9632
+ # "asset": "USDT",
9633
+ # "walletBalance": "72.72317863",
9634
+ # "unrealizedProfit": "11.17920750",
9635
+ # "marginBalance": "83.90238613",
9636
+ # "maintMargin": "11.95476475",
9637
+ # "initialMargin": "99.62303962",
9638
+ # "positionInitialMargin": "99.62303962",
9639
+ # "openOrderInitialMargin": "0.00000000",
9640
+ # "crossWalletBalance": "72.72317863",
9641
+ # "crossUnPnl": "11.17920750",
9642
+ # "availableBalance": "11.39916777",
9643
+ # "maxWithdrawAmount": "11.39916777",
9644
+ # "updateTime": "1721995605338",
9645
+ # "marginAvailable": True # in v2
9646
+ # },
9647
+ # ... and some few supported settle currencies: USDC, BTC, ETH, BNB ..
9648
+ # ],
9649
+ # "positions": [
9650
+ # {
9651
+ # "symbol": "WLDUSDT",
9652
+ # "positionSide": "BOTH",
9653
+ # "positionAmt": "-849",
9654
+ # "unrealizedProfit": "11.17920750",
9655
+ # "isolatedMargin": "0",
9656
+ # "isolatedWallet": "0",
9657
+ # "notional": "-1992.46079250",
9658
+ # "initialMargin": "99.62303962",
9659
+ # "maintMargin": "11.95476475",
9660
+ # "updateTime": "1721995760449"
9661
+ # "leverage": "50", # in v2
9662
+ # "entryPrice": "2.34", # in v2
9663
+ # "positionInitialMargin": "118.82116614", # in v2
9664
+ # "openOrderInitialMargin": "0", # in v2
9665
+ # "isolated": False, # in v2
9666
+ # "breakEvenPrice": "2.3395788", # in v2
9667
+ # "maxNotional": "25000", # in v2
9668
+ # "bidNotional": "0", # in v2
9669
+ # "askNotional": "0" # in v2
9670
+ # },
9671
+ # ...
9672
+ # ]
9673
+ # }
9674
+ #
9548
9675
  elif self.is_inverse(type, subType):
9549
9676
  if isPortfolioMargin:
9550
9677
  response = self.papiGetCmAccount(params)
@@ -9591,7 +9718,33 @@ class binance(Exchange, ImplicitAPI):
9591
9718
  if isPortfolioMargin:
9592
9719
  response = self.papiGetUmPositionRisk(self.extend(request, params))
9593
9720
  else:
9594
- response = self.fapiPrivateV2GetPositionRisk(self.extend(request, params))
9721
+ response = self.fapiPrivateV3GetPositionRisk(self.extend(request, params))
9722
+ #
9723
+ # [
9724
+ # {
9725
+ # symbol: "WLDUSDT",
9726
+ # positionSide: "BOTH",
9727
+ # positionAmt: "5",
9728
+ # entryPrice: "2.3483",
9729
+ # breakEvenPrice: "2.349356735",
9730
+ # markPrice: "2.39560000",
9731
+ # unRealizedProfit: "0.23650000",
9732
+ # liquidationPrice: "0",
9733
+ # isolatedMargin: "0",
9734
+ # notional: "11.97800000",
9735
+ # isolatedWallet: "0",
9736
+ # updateTime: "1722062678998",
9737
+ # initialMargin: "2.39560000", # added in v3
9738
+ # maintMargin: "0.07186800", # added in v3
9739
+ # positionInitialMargin: "2.39560000", # added in v3
9740
+ # openOrderInitialMargin: "0", # added in v3
9741
+ # adl: "2", # added in v3
9742
+ # bidNotional: "0", # added in v3
9743
+ # askNotional: "0", # added in v3
9744
+ # marginAsset: "USDT", # added in v3
9745
+ # },
9746
+ # ]
9747
+ #
9595
9748
  elif self.is_inverse(type, subType):
9596
9749
  if isPortfolioMargin:
9597
9750
  response = self.papiGetCmPositionRisk(self.extend(request, params))
@@ -9605,18 +9758,18 @@ class binance(Exchange, ImplicitAPI):
9605
9758
  #
9606
9759
  # [
9607
9760
  # {
9761
+ # "symbol": "BTCUSDT",
9762
+ # "positionSide": "BOTH",
9763
+ # "positionAmt": "0.000",
9608
9764
  # "entryPrice": "0.00000",
9765
+ # "markPrice": "6679.50671178",
9766
+ # "unRealizedProfit": "0.00000000",
9767
+ # "liquidationPrice": "0",
9768
+ # "isolatedMargin": "0.00000000",
9609
9769
  # "marginType": "isolated",
9610
9770
  # "isAutoAddMargin": "false",
9611
- # "isolatedMargin": "0.00000000",
9612
9771
  # "leverage": "10",
9613
- # "liquidationPrice": "0",
9614
- # "markPrice": "6679.50671178",
9615
9772
  # "maxNotionalValue": "20000000",
9616
- # "positionAmt": "0.000",
9617
- # "symbol": "BTCUSDT",
9618
- # "unRealizedProfit": "0.00000000",
9619
- # "positionSide": "BOTH",
9620
9773
  # "updateTime": 0
9621
9774
  # }
9622
9775
  # ]
@@ -9633,27 +9786,13 @@ class binance(Exchange, ImplicitAPI):
9633
9786
  # "liquidationPrice": "5930.78",
9634
9787
  # "markPrice": "6679.50671178",
9635
9788
  # "maxNotionalValue": "20000000",
9636
- # "positionAmt": "20.000",
9789
+ # "positionSide": "LONG",
9790
+ # "positionAmt": "20.000", # negative value for 'SHORT'
9637
9791
  # "symbol": "BTCUSDT",
9638
9792
  # "unRealizedProfit": "2316.83423560"
9639
- # "positionSide": "LONG",
9640
9793
  # "updateTime": 1625474304765
9641
9794
  # },
9642
- # {
9643
- # "entryPrice": "0.00000",
9644
- # "marginType": "isolated",
9645
- # "isAutoAddMargin": "false",
9646
- # "isolatedMargin": "5413.95799991",
9647
- # "leverage": "10",
9648
- # "liquidationPrice": "7189.95",
9649
- # "markPrice": "6679.50671178",
9650
- # "maxNotionalValue": "20000000",
9651
- # "positionAmt": "-10.000",
9652
- # "symbol": "BTCUSDT",
9653
- # "unRealizedProfit": "-1156.46711780",
9654
- # "positionSide": "SHORT",
9655
- # "updateTime": 0
9656
- # }
9795
+ # .. second dict is similar, but with `positionSide: SHORT`
9657
9796
  # ]
9658
9797
  #
9659
9798
  # inverse portfolio margin:
@@ -9697,10 +9836,9 @@ class binance(Exchange, ImplicitAPI):
9697
9836
  result = []
9698
9837
  for i in range(0, len(response)):
9699
9838
  rawPosition = response[i]
9700
- entryPrice = self.safe_string(rawPosition, 'entryPrice')
9701
- if (entryPrice != '0') and (entryPrice != '0.0') and (entryPrice != '0.00000000'):
9702
- parsed = self.parse_position_risk(response[i])
9703
- result.append(parsed)
9839
+ entryPriceString = self.safe_string(rawPosition, 'entryPrice')
9840
+ if Precise.string_gt(entryPriceString, '0'):
9841
+ result.append(self.parse_position_risk(response[i]))
9704
9842
  symbols = self.market_symbols(symbols)
9705
9843
  return self.filter_by_array_positions(result, 'symbol', symbols, False)
9706
9844
 
@@ -10335,7 +10473,7 @@ class binance(Exchange, ImplicitAPI):
10335
10473
  body = self.urlencode(params)
10336
10474
  else:
10337
10475
  raise AuthenticationError(self.id + ' userDataStream endpoint requires `apiKey` credential')
10338
- elif (api == 'private') or (api == 'eapiPrivate') or (api == 'sapi' and path != 'system/status') or (api == 'sapiV2') or (api == 'sapiV3') or (api == 'sapiV4') or (api == 'dapiPrivate') or (api == 'dapiPrivateV2') or (api == 'fapiPrivate') or (api == 'fapiPrivateV2') or (api == 'papi' and path != 'ping'):
10476
+ elif (api == 'private') or (api == 'eapiPrivate') or (api == 'sapi' and path != 'system/status') or (api == 'sapiV2') or (api == 'sapiV3') or (api == 'sapiV4') or (api == 'dapiPrivate') or (api == 'dapiPrivateV2') or (api == 'fapiPrivate') or (api == 'fapiPrivateV2') or (api == 'fapiPrivateV3') or (api == 'papi' and path != 'ping'):
10339
10477
  self.check_required_credentials()
10340
10478
  if method == 'POST' and ((path == 'order') or (path == 'sor/order')):
10341
10479
  # inject in implicit API calls
ccxt/bybit.py CHANGED
@@ -6738,8 +6738,8 @@ class bybit(Exchange, ImplicitAPI):
6738
6738
  currency = None
6739
6739
  request: dict = {}
6740
6740
  if code is not None:
6741
- currency = self.safe_currency_code(code)
6742
- request['coin'] = currency
6741
+ currency = self.safe_currency(code)
6742
+ request['coin'] = currency['id']
6743
6743
  if since is not None:
6744
6744
  request['startTime'] = since
6745
6745
  if limit is not None:
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.73'
7
+ __version__ = '4.3.74'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10