ccxt 4.4.67__py2.py3-none-any.whl → 4.4.69__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.
- ccxt/__init__.py +1 -1
- ccxt/abstract/paradex.py +23 -0
- ccxt/abstract/tradeogre.py +1 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +10 -5
- ccxt/async_support/binance.py +16 -2
- ccxt/async_support/bitrue.py +1 -1
- ccxt/async_support/bitstamp.py +2 -3
- ccxt/async_support/bybit.py +1 -1
- ccxt/async_support/coinbase.py +69 -2
- ccxt/async_support/cryptomus.py +122 -6
- ccxt/async_support/hyperliquid.py +1 -1
- ccxt/async_support/luno.py +113 -1
- ccxt/async_support/paradex.py +173 -5
- ccxt/async_support/phemex.py +2 -2
- ccxt/async_support/tradeogre.py +14 -9
- ccxt/async_support/whitebit.py +210 -2
- ccxt/base/exchange.py +6 -4
- ccxt/binance.py +16 -2
- ccxt/bitrue.py +1 -1
- ccxt/bitstamp.py +2 -3
- ccxt/bybit.py +1 -1
- ccxt/coinbase.py +69 -2
- ccxt/cryptomus.py +122 -6
- ccxt/hyperliquid.py +1 -1
- ccxt/luno.py +113 -1
- ccxt/paradex.py +173 -5
- ccxt/phemex.py +2 -2
- ccxt/pro/__init__.py +1 -1
- ccxt/test/tests_async.py +22 -0
- ccxt/test/tests_sync.py +22 -0
- ccxt/tradeogre.py +14 -9
- ccxt/whitebit.py +210 -2
- {ccxt-4.4.67.dist-info → ccxt-4.4.69.dist-info}/METADATA +6 -6
- {ccxt-4.4.67.dist-info → ccxt-4.4.69.dist-info}/RECORD +38 -38
- {ccxt-4.4.67.dist-info → ccxt-4.4.69.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.67.dist-info → ccxt-4.4.69.dist-info}/WHEEL +0 -0
- {ccxt-4.4.67.dist-info → ccxt-4.4.69.dist-info}/top_level.txt +0 -0
ccxt/async_support/whitebit.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.whitebit import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Any, Balances, BorrowInterest, Bool, Conversion, Currencies, Currency, DepositAddress, FundingHistory, Int, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFees, Transaction, TransferEntry
|
9
|
+
from ccxt.base.types import Any, Balances, BorrowInterest, Bool, Conversion, Currencies, Currency, DepositAddress, FundingHistory, Int, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFees, Transaction, TransferEntry
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
12
|
from ccxt.base.errors import AuthenticationError
|
@@ -38,7 +38,7 @@ class whitebit(Exchange, ImplicitAPI):
|
|
38
38
|
'CORS': None,
|
39
39
|
'spot': True,
|
40
40
|
'margin': True,
|
41
|
-
'swap':
|
41
|
+
'swap': True,
|
42
42
|
'future': False,
|
43
43
|
'option': False,
|
44
44
|
'cancelAllOrders': True,
|
@@ -88,7 +88,10 @@ class whitebit(Exchange, ImplicitAPI):
|
|
88
88
|
'fetchOpenOrders': True,
|
89
89
|
'fetchOrderBook': True,
|
90
90
|
'fetchOrderTrades': True,
|
91
|
+
'fetchPosition': True,
|
92
|
+
'fetchPositionHistory': True,
|
91
93
|
'fetchPositionMode': False,
|
94
|
+
'fetchPositions': True,
|
92
95
|
'fetchPremiumIndexOHLCV': False,
|
93
96
|
'fetchStatus': True,
|
94
97
|
'fetchTicker': True,
|
@@ -2859,6 +2862,211 @@ class whitebit(Exchange, ImplicitAPI):
|
|
2859
2862
|
'fee': None,
|
2860
2863
|
}
|
2861
2864
|
|
2865
|
+
async def fetch_position_history(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Position]:
|
2866
|
+
"""
|
2867
|
+
fetches historical positions
|
2868
|
+
|
2869
|
+
https://docs.whitebit.com/private/http-trade-v4/#positions-history
|
2870
|
+
|
2871
|
+
:param str symbol: unified contract symbol
|
2872
|
+
:param int [since]: the earliest time in ms to fetch positions for
|
2873
|
+
:param int [limit]: the maximum amount of records to fetch
|
2874
|
+
:param dict [params]: extra parameters specific to the exchange api endpoint
|
2875
|
+
:param int [params.positionId]: the id of the requested position
|
2876
|
+
:returns dict[]: a list of `position structures <https://docs.ccxt.com/#/?id=position-structure>`
|
2877
|
+
"""
|
2878
|
+
await self.load_markets()
|
2879
|
+
market = self.market(symbol)
|
2880
|
+
request: dict = {
|
2881
|
+
'market': market['id'],
|
2882
|
+
}
|
2883
|
+
if since is not None:
|
2884
|
+
request['startDate'] = since
|
2885
|
+
if limit is not None:
|
2886
|
+
request['limit'] = since
|
2887
|
+
request, params = self.handle_until_option('endDate', request, params)
|
2888
|
+
response = await self.v4PrivatePostCollateralAccountPositionsHistory(self.extend(request, params))
|
2889
|
+
#
|
2890
|
+
# [
|
2891
|
+
# {
|
2892
|
+
# "positionId": 479975679,
|
2893
|
+
# "market": "BTC_PERP",
|
2894
|
+
# "openDate": 1741941025.309887,
|
2895
|
+
# "modifyDate": 1741941025.309887,
|
2896
|
+
# "amount": "0.001",
|
2897
|
+
# "basePrice": "82498.7",
|
2898
|
+
# "realizedFunding": "0",
|
2899
|
+
# "liquidationPrice": "0",
|
2900
|
+
# "liquidationState": null,
|
2901
|
+
# "orderDetail": {
|
2902
|
+
# "id": 1224727949521,
|
2903
|
+
# "tradeAmount": "0.001",
|
2904
|
+
# "price": "82498.7",
|
2905
|
+
# "tradeFee": "0.028874545",
|
2906
|
+
# "fundingFee": "0",
|
2907
|
+
# "realizedPnl": "-0.028874545"
|
2908
|
+
# }
|
2909
|
+
# }
|
2910
|
+
# ]
|
2911
|
+
#
|
2912
|
+
positions = self.parse_positions(response)
|
2913
|
+
return self.filter_by_symbol_since_limit(positions, symbol, since, limit)
|
2914
|
+
|
2915
|
+
async def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
|
2916
|
+
"""
|
2917
|
+
fetch all open positions
|
2918
|
+
|
2919
|
+
https://docs.whitebit.com/private/http-trade-v4/#open-positions
|
2920
|
+
|
2921
|
+
:param str[] [symbols]: list of unified market symbols
|
2922
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2923
|
+
:returns dict[]: a list of `position structures <https://docs.ccxt.com/#/?id=position-structure>`
|
2924
|
+
"""
|
2925
|
+
await self.load_markets()
|
2926
|
+
symbols = self.market_symbols(symbols)
|
2927
|
+
response = await self.v4PrivatePostCollateralAccountPositionsOpen(params)
|
2928
|
+
#
|
2929
|
+
# [
|
2930
|
+
# {
|
2931
|
+
# "positionId": 479975679,
|
2932
|
+
# "market": "BTC_PERP",
|
2933
|
+
# "openDate": 1741941025.3098869,
|
2934
|
+
# "modifyDate": 1741941025.3098869,
|
2935
|
+
# "amount": "0.001",
|
2936
|
+
# "basePrice": "82498.7",
|
2937
|
+
# "liquidationPrice": "70177.2",
|
2938
|
+
# "pnl": "0",
|
2939
|
+
# "pnlPercent": "0.00",
|
2940
|
+
# "margin": "4.2",
|
2941
|
+
# "freeMargin": "9.9",
|
2942
|
+
# "funding": "0",
|
2943
|
+
# "unrealizedFunding": "0",
|
2944
|
+
# "liquidationState": null,
|
2945
|
+
# "tpsl": null
|
2946
|
+
# }
|
2947
|
+
# ]
|
2948
|
+
#
|
2949
|
+
return self.parse_positions(response, symbols)
|
2950
|
+
|
2951
|
+
async def fetch_position(self, symbol: str, params={}) -> Position:
|
2952
|
+
"""
|
2953
|
+
fetch data on a single open contract trade position
|
2954
|
+
|
2955
|
+
https://docs.whitebit.com/private/http-trade-v4/#open-positions
|
2956
|
+
|
2957
|
+
:param str symbol: unified market symbol of the market the position is held in
|
2958
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2959
|
+
:returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
|
2960
|
+
"""
|
2961
|
+
await self.load_markets()
|
2962
|
+
market = self.market(symbol)
|
2963
|
+
request: dict = {
|
2964
|
+
'symbol': market['id'],
|
2965
|
+
}
|
2966
|
+
response = await self.v4PrivatePostCollateralAccountPositionsOpen(self.extend(request, params))
|
2967
|
+
#
|
2968
|
+
# [
|
2969
|
+
# {
|
2970
|
+
# "positionId": 479975679,
|
2971
|
+
# "market": "BTC_PERP",
|
2972
|
+
# "openDate": 1741941025.3098869,
|
2973
|
+
# "modifyDate": 1741941025.3098869,
|
2974
|
+
# "amount": "0.001",
|
2975
|
+
# "basePrice": "82498.7",
|
2976
|
+
# "liquidationPrice": "70177.2",
|
2977
|
+
# "pnl": "0",
|
2978
|
+
# "pnlPercent": "0.00",
|
2979
|
+
# "margin": "4.2",
|
2980
|
+
# "freeMargin": "9.9",
|
2981
|
+
# "funding": "0",
|
2982
|
+
# "unrealizedFunding": "0",
|
2983
|
+
# "liquidationState": null,
|
2984
|
+
# "tpsl": null
|
2985
|
+
# }
|
2986
|
+
# ]
|
2987
|
+
#
|
2988
|
+
data = self.safe_dict(response, 0, {})
|
2989
|
+
return self.parse_position(data, market)
|
2990
|
+
|
2991
|
+
def parse_position(self, position: dict, market: Market = None) -> Position:
|
2992
|
+
#
|
2993
|
+
# fetchPosition, fetchPositions
|
2994
|
+
#
|
2995
|
+
# {
|
2996
|
+
# "positionId": 479975679,
|
2997
|
+
# "market": "BTC_PERP",
|
2998
|
+
# "openDate": 1741941025.3098869,
|
2999
|
+
# "modifyDate": 1741941025.3098869,
|
3000
|
+
# "amount": "0.001",
|
3001
|
+
# "basePrice": "82498.7",
|
3002
|
+
# "liquidationPrice": "70177.2",
|
3003
|
+
# "pnl": "0",
|
3004
|
+
# "pnlPercent": "0.00",
|
3005
|
+
# "margin": "4.2",
|
3006
|
+
# "freeMargin": "9.9",
|
3007
|
+
# "funding": "0",
|
3008
|
+
# "unrealizedFunding": "0",
|
3009
|
+
# "liquidationState": null,
|
3010
|
+
# "tpsl": null
|
3011
|
+
# }
|
3012
|
+
#
|
3013
|
+
# fetchPositionHistory
|
3014
|
+
#
|
3015
|
+
# {
|
3016
|
+
# "positionId": 479975679,
|
3017
|
+
# "market": "BTC_PERP",
|
3018
|
+
# "openDate": 1741941025.309887,
|
3019
|
+
# "modifyDate": 1741941025.309887,
|
3020
|
+
# "amount": "0.001",
|
3021
|
+
# "basePrice": "82498.7",
|
3022
|
+
# "realizedFunding": "0",
|
3023
|
+
# "liquidationPrice": "0",
|
3024
|
+
# "liquidationState": null,
|
3025
|
+
# "orderDetail": {
|
3026
|
+
# "id": 1224727949521,
|
3027
|
+
# "tradeAmount": "0.001",
|
3028
|
+
# "price": "82498.7",
|
3029
|
+
# "tradeFee": "0.028874545",
|
3030
|
+
# "fundingFee": "0",
|
3031
|
+
# "realizedPnl": "-0.028874545"
|
3032
|
+
# }
|
3033
|
+
# }
|
3034
|
+
#
|
3035
|
+
marketId = self.safe_string(position, 'market')
|
3036
|
+
timestamp = self.safe_timestamp(position, 'openDate')
|
3037
|
+
tpsl = self.safe_dict(position, 'tpsl', {})
|
3038
|
+
orderDetail = self.safe_dict(position, 'orderDetail', {})
|
3039
|
+
return self.safe_position({
|
3040
|
+
'info': position,
|
3041
|
+
'id': self.safe_string(position, 'positionId'),
|
3042
|
+
'symbol': self.safe_symbol(marketId, market),
|
3043
|
+
'notional': None,
|
3044
|
+
'marginMode': None,
|
3045
|
+
'liquidationPrice': self.safe_number(position, 'liquidationPrice'),
|
3046
|
+
'entryPrice': self.safe_number(position, 'basePrice'),
|
3047
|
+
'unrealizedPnl': self.safe_number(position, 'pnl'),
|
3048
|
+
'realizedPnl': self.safe_number(orderDetail, 'realizedPnl'),
|
3049
|
+
'percentage': self.safe_number(position, 'pnlPercent'),
|
3050
|
+
'contracts': None,
|
3051
|
+
'contractSize': None,
|
3052
|
+
'markPrice': None,
|
3053
|
+
'lastPrice': None,
|
3054
|
+
'side': None,
|
3055
|
+
'hedged': None,
|
3056
|
+
'timestamp': timestamp,
|
3057
|
+
'datetime': self.iso8601(timestamp),
|
3058
|
+
'lastUpdateTimestamp': self.safe_timestamp(position, 'modifyDate'),
|
3059
|
+
'maintenanceMargin': None,
|
3060
|
+
'maintenanceMarginPercentage': None,
|
3061
|
+
'collateral': self.safe_number(position, 'margin'),
|
3062
|
+
'initialMargin': None,
|
3063
|
+
'initialMarginPercentage': None,
|
3064
|
+
'leverage': None,
|
3065
|
+
'marginRatio': None,
|
3066
|
+
'stopLossPrice': self.safe_number(tpsl, 'stopLoss'),
|
3067
|
+
'takeProfitPrice': self.safe_number(tpsl, 'takeProfit'),
|
3068
|
+
})
|
3069
|
+
|
2862
3070
|
def is_fiat(self, currency: str) -> bool:
|
2863
3071
|
fiatCurrencies = self.safe_value(self.options, 'fiatCurrencies', [])
|
2864
3072
|
return self.in_array(currency, fiatCurrencies)
|
ccxt/base/exchange.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
|
7
|
-
__version__ = '4.4.
|
7
|
+
__version__ = '4.4.69'
|
8
8
|
|
9
9
|
# -----------------------------------------------------------------------------
|
10
10
|
|
@@ -21,6 +21,7 @@ from ccxt.base.errors import ArgumentsRequired
|
|
21
21
|
from ccxt.base.errors import BadSymbol
|
22
22
|
from ccxt.base.errors import NullResponse
|
23
23
|
from ccxt.base.errors import RateLimitExceeded
|
24
|
+
from ccxt.base.errors import OperationFailed
|
24
25
|
from ccxt.base.errors import BadRequest
|
25
26
|
from ccxt.base.errors import BadResponse
|
26
27
|
from ccxt.base.errors import InvalidProxySettings
|
@@ -4351,14 +4352,15 @@ class Exchange(object):
|
|
4351
4352
|
try:
|
4352
4353
|
return self.fetch(request['url'], request['method'], request['headers'], request['body'])
|
4353
4354
|
except Exception as e:
|
4354
|
-
if isinstance(e,
|
4355
|
+
if isinstance(e, OperationFailed):
|
4355
4356
|
if i < retries:
|
4356
4357
|
if self.verbose:
|
4357
4358
|
self.log('Request failed with the error: ' + str(e) + ', retrying ' + (i + str(1)) + ' of ' + str(retries) + '...')
|
4358
4359
|
if (retryDelay is not None) and (retryDelay != 0):
|
4359
4360
|
self.sleep(retryDelay)
|
4360
|
-
|
4361
|
-
|
4361
|
+
else:
|
4362
|
+
raise e
|
4363
|
+
else:
|
4362
4364
|
raise e
|
4363
4365
|
return None # self line is never reached, but exists for c# value return requirement
|
4364
4366
|
|
ccxt/binance.py
CHANGED
@@ -11325,8 +11325,22 @@ class binance(Exchange, ImplicitAPI):
|
|
11325
11325
|
query = None
|
11326
11326
|
# handle batchOrders
|
11327
11327
|
if (path == 'batchOrders') and ((method == 'POST') or (method == 'PUT')):
|
11328
|
-
batchOrders = self.
|
11329
|
-
|
11328
|
+
batchOrders = self.safe_list(params, 'batchOrders')
|
11329
|
+
checkedBatchOrders = batchOrders
|
11330
|
+
if method == 'POST' and api == 'fapiPrivate':
|
11331
|
+
# check broker id if batchOrders are called with fapiPrivatePostBatchOrders
|
11332
|
+
checkedBatchOrders = []
|
11333
|
+
for i in range(0, len(batchOrders)):
|
11334
|
+
batchOrder = batchOrders[i]
|
11335
|
+
newClientOrderId = self.safe_string(batchOrder, 'newClientOrderId')
|
11336
|
+
if newClientOrderId is None:
|
11337
|
+
defaultId = 'x-xcKtGhcu' # batchOrders can not be spot or margin
|
11338
|
+
broker = self.safe_dict(self.options, 'broker', {})
|
11339
|
+
brokerId = self.safe_string(broker, 'future', defaultId)
|
11340
|
+
newClientOrderId = brokerId + self.uuid22()
|
11341
|
+
batchOrder['newClientOrderId'] = newClientOrderId
|
11342
|
+
checkedBatchOrders.append(batchOrder)
|
11343
|
+
queryBatch = (self.json(checkedBatchOrders))
|
11330
11344
|
params['batchOrders'] = queryBatch
|
11331
11345
|
defaultRecvWindow = self.safe_integer(self.options, 'recvWindow')
|
11332
11346
|
extendedParams = self.extend({
|
ccxt/bitrue.py
CHANGED
@@ -1633,7 +1633,7 @@ class bitrue(Exchange, ImplicitAPI):
|
|
1633
1633
|
tickers: dict = {}
|
1634
1634
|
for i in range(0, len(data)):
|
1635
1635
|
ticker = self.safe_dict(data, i, {})
|
1636
|
-
market = self.
|
1636
|
+
market = self.safe_market(self.safe_string(ticker, 'symbol'))
|
1637
1637
|
tickers[market['id']] = ticker
|
1638
1638
|
return self.parse_tickers(tickers, symbols)
|
1639
1639
|
|
ccxt/bitstamp.py
CHANGED
@@ -1282,10 +1282,9 @@ class bitstamp(Exchange, ImplicitAPI):
|
|
1282
1282
|
|
1283
1283
|
def parse_trading_fees(self, fees):
|
1284
1284
|
result: dict = {'info': fees}
|
1285
|
-
|
1286
|
-
for i in range(0, len(symbols)):
|
1287
|
-
symbol = symbols[i]
|
1285
|
+
for i in range(0, len(fees)):
|
1288
1286
|
fee = self.parse_trading_fee(fees[i])
|
1287
|
+
symbol = fee['symbol']
|
1289
1288
|
result[symbol] = fee
|
1290
1289
|
return result
|
1291
1290
|
|
ccxt/bybit.py
CHANGED
@@ -8825,7 +8825,7 @@ classic accounts only/ spot not supported* fetches information on an order made
|
|
8825
8825
|
feedback = self.id + ' private api uses /user/v3/private/query-api to check if you have a unified account. The API key of user id must own one of permissions: "Account Transfer", "Subaccount Transfer", "Withdrawal" ' + body
|
8826
8826
|
else:
|
8827
8827
|
feedback = self.id + ' ' + body
|
8828
|
-
if body.find('Withdraw address chain or destination tag are not equal'):
|
8828
|
+
if body.find('Withdraw address chain or destination tag are not equal') > -1:
|
8829
8829
|
feedback = feedback + '; You might also need to ensure the address is whitelisted'
|
8830
8830
|
self.throw_broadly_matched_exception(self.exceptions['broad'], body, feedback)
|
8831
8831
|
self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
|
ccxt/coinbase.py
CHANGED
@@ -4088,6 +4088,7 @@ class coinbase(Exchange, ImplicitAPI):
|
|
4088
4088
|
'amount': self.number_to_string(amount),
|
4089
4089
|
'currency': code.upper(), # need to use code in case depositing USD etc.
|
4090
4090
|
'payment_method': id,
|
4091
|
+
'commit': True, # otheriwse the deposit does not go through
|
4091
4092
|
}
|
4092
4093
|
response = self.v2PrivatePostAccountsAccountIdDeposits(self.extend(request, params))
|
4093
4094
|
#
|
@@ -4126,7 +4127,8 @@ class coinbase(Exchange, ImplicitAPI):
|
|
4126
4127
|
# }
|
4127
4128
|
# }
|
4128
4129
|
#
|
4129
|
-
|
4130
|
+
# https://github.com/ccxt/ccxt/issues/25484
|
4131
|
+
data = self.safe_dict_2(response, 'data', 'transfer', {})
|
4130
4132
|
return self.parse_transaction(data)
|
4131
4133
|
|
4132
4134
|
def fetch_deposit(self, id: str, code: Str = None, params={}):
|
@@ -4191,7 +4193,8 @@ class coinbase(Exchange, ImplicitAPI):
|
|
4191
4193
|
# }
|
4192
4194
|
# }
|
4193
4195
|
#
|
4194
|
-
|
4196
|
+
# https://github.com/ccxt/ccxt/issues/25484
|
4197
|
+
data = self.safe_dict_2(response, 'data', 'transfer', {})
|
4195
4198
|
return self.parse_transaction(data)
|
4196
4199
|
|
4197
4200
|
def fetch_deposit_method_ids(self, params={}):
|
@@ -4669,6 +4672,70 @@ class coinbase(Exchange, ImplicitAPI):
|
|
4669
4672
|
}
|
4670
4673
|
return result
|
4671
4674
|
|
4675
|
+
def fetch_portfolio_details(self, portfolioUuid: str, params={}) -> List[Any]:
|
4676
|
+
"""
|
4677
|
+
Fetch details for a specific portfolio by UUID
|
4678
|
+
|
4679
|
+
https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getportfolios
|
4680
|
+
|
4681
|
+
:param str portfolioUuid: The unique identifier of the portfolio to fetch
|
4682
|
+
:param Dict [params]: Extra parameters specific to the exchange API endpoint
|
4683
|
+
:returns any[]: An account structure <https://docs.ccxt.com/#/?id=account-structure>
|
4684
|
+
"""
|
4685
|
+
self.load_markets()
|
4686
|
+
request = {
|
4687
|
+
'portfolio_uuid': portfolioUuid,
|
4688
|
+
}
|
4689
|
+
response = self.v3PrivateGetBrokeragePortfoliosPortfolioUuid(self.extend(request, params))
|
4690
|
+
result = self.parse_portfolio_details(response)
|
4691
|
+
return result
|
4692
|
+
|
4693
|
+
def parse_portfolio_details(self, portfolioData: dict):
|
4694
|
+
breakdown = portfolioData['breakdown']
|
4695
|
+
portfolioInfo = self.safe_dict(breakdown, 'portfolio', {})
|
4696
|
+
portfolioName = self.safe_string(portfolioInfo, 'name', 'Unknown')
|
4697
|
+
portfolioUuid = self.safe_string(portfolioInfo, 'uuid', '')
|
4698
|
+
spotPositions = self.safe_list(breakdown, 'spot_positions', [])
|
4699
|
+
parsedPositions = []
|
4700
|
+
for i in range(0, len(spotPositions)):
|
4701
|
+
position: dict = spotPositions[i]
|
4702
|
+
currencyCode = self.safe_string(position, 'asset', 'Unknown')
|
4703
|
+
availableBalanceStr = self.safe_string(position, 'available_to_trade_fiat', '0')
|
4704
|
+
availableBalance = self.parse_number(availableBalanceStr)
|
4705
|
+
totalBalanceFiatStr = self.safe_string(position, 'total_balance_fiat', '0')
|
4706
|
+
totalBalanceFiat = self.parse_number(totalBalanceFiatStr)
|
4707
|
+
holdAmount = totalBalanceFiat - availableBalance
|
4708
|
+
costBasisDict = self.safe_dict(position, 'cost_basis', {})
|
4709
|
+
costBasisStr = self.safe_string(costBasisDict, 'value', '0')
|
4710
|
+
averageEntryPriceDict = self.safe_dict(position, 'average_entry_price', {})
|
4711
|
+
averageEntryPriceStr = self.safe_string(averageEntryPriceDict, 'value', '0')
|
4712
|
+
positionData: dict = {
|
4713
|
+
'currency': currencyCode,
|
4714
|
+
'available_balance': availableBalance,
|
4715
|
+
'hold_amount': holdAmount > holdAmount if 0 else 0,
|
4716
|
+
'wallet_name': portfolioName,
|
4717
|
+
'account_id': portfolioUuid,
|
4718
|
+
'account_uuid': self.safe_string(position, 'account_uuid', ''),
|
4719
|
+
'total_balance_fiat': totalBalanceFiat,
|
4720
|
+
'total_balance_crypto': self.parse_number(self.safe_string(position, 'total_balance_crypto', '0')),
|
4721
|
+
'available_to_trade_fiat': self.parse_number(self.safe_string(position, 'available_to_trade_fiat', '0')),
|
4722
|
+
'available_to_trade_crypto': self.parse_number(self.safe_string(position, 'available_to_trade_crypto', '0')),
|
4723
|
+
'available_to_transfer_fiat': self.parse_number(self.safe_string(position, 'available_to_transfer_fiat', '0')),
|
4724
|
+
'available_to_transfer_crypto': self.parse_number(self.safe_string(position, 'available_to_trade_crypto', '0')),
|
4725
|
+
'allocation': self.parse_number(self.safe_string(position, 'allocation', '0')),
|
4726
|
+
'cost_basis': self.parse_number(costBasisStr),
|
4727
|
+
'cost_basis_currency': self.safe_string(costBasisDict, 'currency', 'USD'),
|
4728
|
+
'is_cash': self.safe_bool(position, 'is_cash', False),
|
4729
|
+
'average_entry_price': self.parse_number(averageEntryPriceStr),
|
4730
|
+
'average_entry_price_currency': self.safe_string(averageEntryPriceDict, 'currency', 'USD'),
|
4731
|
+
'asset_uuid': self.safe_string(position, 'asset_uuid', ''),
|
4732
|
+
'unrealized_pnl': self.parse_number(self.safe_string(position, 'unrealized_pnl', '0')),
|
4733
|
+
'asset_color': self.safe_string(position, 'asset_color', ''),
|
4734
|
+
'account_type': self.safe_string(position, 'account_type', ''),
|
4735
|
+
}
|
4736
|
+
parsedPositions.append(positionData)
|
4737
|
+
return parsedPositions
|
4738
|
+
|
4672
4739
|
def create_auth_token(self, seconds: Int, method: Str = None, url: Str = None):
|
4673
4740
|
# it may not work for v2
|
4674
4741
|
uri = None
|