ccxt 4.4.77__py2.py3-none-any.whl → 4.4.80__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 +3 -3
- ccxt/abstract/apex.py +31 -0
- ccxt/abstract/bitmart.py +1 -0
- ccxt/apex.py +1884 -0
- ccxt/ascendex.py +23 -6
- ccxt/async_support/__init__.py +3 -3
- ccxt/async_support/apex.py +1884 -0
- ccxt/async_support/ascendex.py +23 -6
- ccxt/async_support/base/exchange.py +5 -1
- ccxt/async_support/binance.py +9 -3
- ccxt/async_support/bingx.py +4 -4
- ccxt/async_support/bitfinex.py +61 -36
- ccxt/async_support/bitflyer.py +2 -2
- ccxt/async_support/bitget.py +186 -128
- ccxt/async_support/bitmart.py +9 -4
- ccxt/async_support/bitmex.py +14 -7
- ccxt/async_support/bitopro.py +5 -1
- ccxt/async_support/bitrue.py +2 -1
- ccxt/async_support/bitso.py +1 -1
- ccxt/async_support/bitteam.py +2 -0
- ccxt/async_support/bitvavo.py +25 -10
- ccxt/async_support/btcalpha.py +1 -1
- ccxt/async_support/btcmarkets.py +1 -1
- ccxt/async_support/btcturk.py +1 -1
- ccxt/async_support/bybit.py +27 -15
- ccxt/async_support/cex.py +1 -1
- ccxt/async_support/coinbase.py +17 -4
- ccxt/async_support/coincatch.py +66 -0
- ccxt/async_support/coinex.py +2 -1
- ccxt/async_support/coinlist.py +1 -0
- ccxt/async_support/coinone.py +1 -0
- ccxt/async_support/cryptocom.py +2 -2
- ccxt/async_support/defx.py +1 -1
- ccxt/async_support/delta.py +4 -1
- ccxt/async_support/deribit.py +3 -2
- ccxt/async_support/derive.py +2 -2
- ccxt/async_support/digifinex.py +2 -2
- ccxt/async_support/gate.py +1 -1
- ccxt/async_support/hitbtc.py +5 -2
- ccxt/async_support/hollaex.py +1 -0
- ccxt/async_support/htx.py +9 -5
- ccxt/async_support/huobijp.py +1 -0
- ccxt/async_support/hyperliquid.py +14 -6
- ccxt/async_support/kraken.py +4 -2
- ccxt/async_support/krakenfutures.py +2 -2
- ccxt/async_support/kucoinfutures.py +2 -2
- ccxt/async_support/mexc.py +50 -52
- ccxt/async_support/okx.py +2 -2
- ccxt/async_support/oxfun.py +2 -2
- ccxt/async_support/paradex.py +2 -2
- ccxt/async_support/phemex.py +4 -3
- ccxt/async_support/poloniex.py +4 -3
- ccxt/async_support/probit.py +1 -0
- ccxt/async_support/timex.py +2 -2
- ccxt/async_support/tradeogre.py +2 -1
- ccxt/async_support/upbit.py +243 -63
- ccxt/async_support/vertex.py +2 -2
- ccxt/async_support/whitebit.py +66 -12
- ccxt/async_support/woo.py +5 -3
- ccxt/async_support/woofipro.py +2 -2
- ccxt/async_support/xt.py +9 -2
- ccxt/base/exchange.py +69 -2
- ccxt/binance.py +9 -3
- ccxt/bingx.py +4 -4
- ccxt/bitfinex.py +61 -36
- ccxt/bitflyer.py +2 -2
- ccxt/bitget.py +186 -128
- ccxt/bitmart.py +9 -4
- ccxt/bitmex.py +14 -7
- ccxt/bitopro.py +5 -1
- ccxt/bitrue.py +2 -1
- ccxt/bitso.py +1 -1
- ccxt/bitteam.py +2 -0
- ccxt/bitvavo.py +25 -10
- ccxt/btcalpha.py +1 -1
- ccxt/btcmarkets.py +1 -1
- ccxt/btcturk.py +1 -1
- ccxt/bybit.py +27 -15
- ccxt/cex.py +1 -1
- ccxt/coinbase.py +17 -4
- ccxt/coincatch.py +66 -0
- ccxt/coinex.py +2 -1
- ccxt/coinlist.py +1 -0
- ccxt/coinone.py +1 -0
- ccxt/cryptocom.py +2 -2
- ccxt/defx.py +1 -1
- ccxt/delta.py +4 -1
- ccxt/deribit.py +3 -2
- ccxt/derive.py +2 -2
- ccxt/digifinex.py +2 -2
- ccxt/gate.py +1 -1
- ccxt/hitbtc.py +5 -2
- ccxt/hollaex.py +1 -0
- ccxt/htx.py +9 -5
- ccxt/huobijp.py +1 -0
- ccxt/hyperliquid.py +14 -6
- ccxt/kraken.py +4 -2
- ccxt/krakenfutures.py +2 -2
- ccxt/kucoinfutures.py +2 -2
- ccxt/mexc.py +50 -52
- ccxt/okx.py +2 -2
- ccxt/oxfun.py +2 -2
- ccxt/paradex.py +2 -2
- ccxt/phemex.py +4 -3
- ccxt/poloniex.py +4 -3
- ccxt/pro/__init__.py +5 -1
- ccxt/pro/apex.py +984 -0
- ccxt/pro/binance.py +3 -3
- ccxt/pro/coinbase.py +43 -57
- ccxt/pro/gate.py +22 -2
- ccxt/pro/hollaex.py +2 -2
- ccxt/pro/p2b.py +2 -2
- ccxt/pro/tradeogre.py +272 -0
- ccxt/pro/upbit.py +42 -0
- ccxt/probit.py +1 -0
- ccxt/test/tests_async.py +4 -1
- ccxt/test/tests_sync.py +4 -1
- ccxt/timex.py +2 -2
- ccxt/tradeogre.py +2 -1
- ccxt/upbit.py +243 -63
- ccxt/vertex.py +2 -2
- ccxt/whitebit.py +66 -12
- ccxt/woo.py +5 -3
- ccxt/woofipro.py +2 -2
- ccxt/xt.py +9 -2
- {ccxt-4.4.77.dist-info → ccxt-4.4.80.dist-info}/METADATA +9 -11
- {ccxt-4.4.77.dist-info → ccxt-4.4.80.dist-info}/RECORD +130 -128
- ccxt/abstract/ace.py +0 -15
- ccxt/ace.py +0 -1152
- ccxt/async_support/ace.py +0 -1152
- {ccxt-4.4.77.dist-info → ccxt-4.4.80.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.77.dist-info → ccxt-4.4.80.dist-info}/WHEEL +0 -0
- {ccxt-4.4.77.dist-info → ccxt-4.4.80.dist-info}/top_level.txt +0 -0
ccxt/async_support/bitget.py
CHANGED
@@ -1393,28 +1393,44 @@ class bitget(Exchange, ImplicitAPI):
|
|
1393
1393
|
'fillResponseFromRequest': True,
|
1394
1394
|
},
|
1395
1395
|
'fetchOHLCV': {
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
'
|
1400
|
-
'method': 'publicMixGetV2MixMarketCandles', # publicMixGetV2MixMarketCandles or publicMixGetV2MixMarketHistoryCandles or publicMixGetV2MixMarketHistoryIndexCandles or publicMixGetV2MixMarketHistoryMarkCandles
|
1401
|
-
},
|
1402
|
-
'maxDaysPerTimeframe': {
|
1396
|
+
# ### Timeframe settings ###
|
1397
|
+
# after testing, the below values are real ones, because the values provided by API DOCS are wrong
|
1398
|
+
# so, start timestamp should be within these thresholds to be able to call "recent" candles endpoint
|
1399
|
+
'maxRecentDaysPerTimeframe': {
|
1403
1400
|
'1m': 30,
|
1404
1401
|
'3m': 30,
|
1405
1402
|
'5m': 30,
|
1406
|
-
'
|
1407
|
-
'
|
1408
|
-
'
|
1409
|
-
'1h': 83,
|
1410
|
-
'2h': 120,
|
1403
|
+
'15m': 30,
|
1404
|
+
'30m': 30,
|
1405
|
+
'1h': 60,
|
1411
1406
|
'4h': 240,
|
1412
1407
|
'6h': 360,
|
1413
|
-
'12h':
|
1414
|
-
'1d':
|
1415
|
-
'3d':
|
1416
|
-
'1w':
|
1417
|
-
'1M':
|
1408
|
+
'12h': 720,
|
1409
|
+
'1d': 1440,
|
1410
|
+
'3d': 1440 * 3,
|
1411
|
+
'1w': 1440 * 7,
|
1412
|
+
'1M': 1440 * 30,
|
1413
|
+
},
|
1414
|
+
'spot': {
|
1415
|
+
'maxLimitPerTimeframe': {
|
1416
|
+
'1d': 300,
|
1417
|
+
'3d': 100,
|
1418
|
+
'1w': 100,
|
1419
|
+
'1M': 100,
|
1420
|
+
},
|
1421
|
+
'method': 'publicSpotGetV2SpotMarketCandles', # publicSpotGetV2SpotMarketCandles or publicSpotGetV2SpotMarketHistoryCandles
|
1422
|
+
},
|
1423
|
+
'swap': {
|
1424
|
+
'maxLimitPerTimeframe': {
|
1425
|
+
'4h': 540,
|
1426
|
+
'6h': 360,
|
1427
|
+
'12h': 180,
|
1428
|
+
'1d': 90,
|
1429
|
+
'3d': 30,
|
1430
|
+
'1w': 13,
|
1431
|
+
'1M': 4,
|
1432
|
+
},
|
1433
|
+
'method': 'publicMixGetV2MixMarketCandles', # publicMixGetV2MixMarketCandles or publicMixGetV2MixMarketHistoryCandles or publicMixGetV2MixMarketHistoryIndexCandles or publicMixGetV2MixMarketHistoryMarkCandles
|
1418
1434
|
},
|
1419
1435
|
},
|
1420
1436
|
'fetchTrades': {
|
@@ -1425,6 +1441,9 @@ class bitget(Exchange, ImplicitAPI):
|
|
1425
1441
|
'method': 'publicMixGetV2MixMarketFillsHistory', # or publicMixGetV2MixMarketFills
|
1426
1442
|
},
|
1427
1443
|
},
|
1444
|
+
'fetchFundingRate': {
|
1445
|
+
'method': 'publicMixGetV2MixMarketCurrentFundRate', # or publicMixGetV2MixMarketFundingTime
|
1446
|
+
},
|
1428
1447
|
'accountsByType': {
|
1429
1448
|
'spot': 'spot',
|
1430
1449
|
'cross': 'crossed_margin',
|
@@ -1548,6 +1567,8 @@ class bitget(Exchange, ImplicitAPI):
|
|
1548
1567
|
'method': 'privateMixGetV2MixPositionAllPosition', # or privateMixGetV2MixPositionHistoryPosition
|
1549
1568
|
},
|
1550
1569
|
'defaultTimeInForce': 'GTC', # 'GTC' = Good To Cancel(default), 'IOC' = Immediate Or Cancel
|
1570
|
+
# fiat currencies on deposit page
|
1571
|
+
'fiatCurrencies': ['EUR', 'VND', 'PLN', 'CZK', 'HUF', 'DKK', 'AUD', 'CAD', 'NOK', 'SEK', 'CHF', 'MXN', 'COP', 'ARS', 'GBP', 'BRL', 'UAH', 'ZAR'],
|
1551
1572
|
},
|
1552
1573
|
'features': {
|
1553
1574
|
'spot': {
|
@@ -1622,7 +1643,7 @@ class bitget(Exchange, ImplicitAPI):
|
|
1622
1643
|
'symbolRequired': False,
|
1623
1644
|
},
|
1624
1645
|
'fetchOHLCV': {
|
1625
|
-
'limit':
|
1646
|
+
'limit': 200, # variable timespans for recent endpoint, 200 for historical
|
1626
1647
|
},
|
1627
1648
|
},
|
1628
1649
|
'forPerps': {
|
@@ -1697,11 +1718,12 @@ class bitget(Exchange, ImplicitAPI):
|
|
1697
1718
|
defaultProductType = None
|
1698
1719
|
if (subType is not None) and (market is None):
|
1699
1720
|
# set default only if subType is defined and market is not defined, since there is also USDC productTypes which are also linear
|
1700
|
-
sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
|
1701
|
-
if sandboxMode:
|
1702
|
-
|
1703
|
-
else:
|
1704
|
-
|
1721
|
+
# sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
|
1722
|
+
# if sandboxMode:
|
1723
|
+
# defaultProductType = 'SUSDT-FUTURES' if (subType == 'linear') else 'SCOIN-FUTURES'
|
1724
|
+
# else:
|
1725
|
+
defaultProductType = 'USDT-FUTURES' if (subType == 'linear') else 'COIN-FUTURES'
|
1726
|
+
# }
|
1705
1727
|
productType = self.safe_string(params, 'productType', defaultProductType)
|
1706
1728
|
if (productType is None) and (market is not None):
|
1707
1729
|
settle = market['settle']
|
@@ -2005,99 +2027,85 @@ class bitget(Exchange, ImplicitAPI):
|
|
2005
2027
|
"""
|
2006
2028
|
response = await self.publicSpotGetV2SpotPublicCoins(params)
|
2007
2029
|
#
|
2008
|
-
#
|
2009
|
-
#
|
2010
|
-
#
|
2011
|
-
#
|
2012
|
-
#
|
2013
|
-
#
|
2014
|
-
#
|
2015
|
-
#
|
2016
|
-
#
|
2017
|
-
#
|
2018
|
-
#
|
2019
|
-
#
|
2020
|
-
#
|
2021
|
-
#
|
2022
|
-
#
|
2023
|
-
#
|
2024
|
-
#
|
2025
|
-
#
|
2026
|
-
#
|
2027
|
-
#
|
2028
|
-
#
|
2029
|
-
#
|
2030
|
-
#
|
2031
|
-
#
|
2032
|
-
#
|
2033
|
-
#
|
2034
|
-
#
|
2030
|
+
# {
|
2031
|
+
# "code": "00000",
|
2032
|
+
# "msg": "success",
|
2033
|
+
# "requestTime": "1746195617812",
|
2034
|
+
# "data": [
|
2035
|
+
# {
|
2036
|
+
# "coinId": "1456",
|
2037
|
+
# "coin": "NEIROETH",
|
2038
|
+
# "transfer": "false",
|
2039
|
+
# "chains": [
|
2040
|
+
# {
|
2041
|
+
# "chain": "ERC20",
|
2042
|
+
# "needTag": "false",
|
2043
|
+
# "withdrawable": "true",
|
2044
|
+
# "rechargeable": "true",
|
2045
|
+
# "withdrawFee": "44.91017965",
|
2046
|
+
# "extraWithdrawFee": "0",
|
2047
|
+
# "depositConfirm": "12",
|
2048
|
+
# "withdrawConfirm": "64",
|
2049
|
+
# "minDepositAmount": "0.06",
|
2050
|
+
# "minWithdrawAmount": "60",
|
2051
|
+
# "browserUrl": "https://etherscan.io/tx/",
|
2052
|
+
# "contractAddress": "0xee2a03aa6dacf51c18679c516ad5283d8e7c2637",
|
2053
|
+
# "withdrawStep": "0",
|
2054
|
+
# "withdrawMinScale": "8",
|
2055
|
+
# "congestion": "normal"
|
2056
|
+
# }
|
2057
|
+
# ],
|
2058
|
+
# "areaCoin": "no"
|
2059
|
+
# },
|
2060
|
+
# ...
|
2035
2061
|
#
|
2036
2062
|
result: dict = {}
|
2037
2063
|
data = self.safe_value(response, 'data', [])
|
2064
|
+
fiatCurrencies = self.safe_list(self.options, 'fiatCurrencies', [])
|
2038
2065
|
for i in range(0, len(data)):
|
2039
2066
|
entry = data[i]
|
2040
2067
|
id = self.safe_string(entry, 'coin') # we don't use 'coinId' has no use. it is 'coin' field that needs to be used in currency related endpoints(deposit, withdraw, etc..)
|
2041
2068
|
code = self.safe_currency_code(id)
|
2042
2069
|
chains = self.safe_value(entry, 'chains', [])
|
2043
2070
|
networks: dict = {}
|
2044
|
-
deposit = False
|
2045
|
-
withdraw = False
|
2046
|
-
minWithdrawString = None
|
2047
|
-
minDepositString = None
|
2048
|
-
minWithdrawFeeString = None
|
2049
2071
|
for j in range(0, len(chains)):
|
2050
2072
|
chain = chains[j]
|
2051
2073
|
networkId = self.safe_string(chain, 'chain')
|
2052
2074
|
network = self.network_id_to_code(networkId, code)
|
2053
2075
|
if network is not None:
|
2054
2076
|
network = network.upper()
|
2055
|
-
withdrawEnabled = self.safe_string(chain, 'withdrawable')
|
2056
|
-
canWithdraw = withdrawEnabled == 'true'
|
2057
|
-
withdraw = canWithdraw if (canWithdraw) else withdraw
|
2058
|
-
depositEnabled = self.safe_string(chain, 'rechargeable')
|
2059
|
-
canDeposit = depositEnabled == 'true'
|
2060
|
-
deposit = canDeposit if (canDeposit) else deposit
|
2061
|
-
networkWithdrawFeeString = self.safe_string(chain, 'withdrawFee')
|
2062
|
-
if networkWithdrawFeeString is not None:
|
2063
|
-
minWithdrawFeeString = networkWithdrawFeeString if (minWithdrawFeeString is None) else Precise.string_min(networkWithdrawFeeString, minWithdrawFeeString)
|
2064
|
-
networkMinWithdrawString = self.safe_string(chain, 'minWithdrawAmount')
|
2065
|
-
if networkMinWithdrawString is not None:
|
2066
|
-
minWithdrawString = networkMinWithdrawString if (minWithdrawString is None) else Precise.string_min(networkMinWithdrawString, minWithdrawString)
|
2067
|
-
networkMinDepositString = self.safe_string(chain, 'minDepositAmount')
|
2068
|
-
if networkMinDepositString is not None:
|
2069
|
-
minDepositString = networkMinDepositString if (minDepositString is None) else Precise.string_min(networkMinDepositString, minDepositString)
|
2070
2077
|
networks[network] = {
|
2071
2078
|
'info': chain,
|
2072
2079
|
'id': networkId,
|
2073
2080
|
'network': network,
|
2074
2081
|
'limits': {
|
2075
2082
|
'withdraw': {
|
2076
|
-
'min': self.
|
2083
|
+
'min': self.safe_number(chain, 'minWithdrawAmount'),
|
2077
2084
|
'max': None,
|
2078
2085
|
},
|
2079
2086
|
'deposit': {
|
2080
|
-
'min': self.
|
2087
|
+
'min': self.safe_number(chain, 'minDepositAmount'),
|
2081
2088
|
'max': None,
|
2082
2089
|
},
|
2083
2090
|
},
|
2084
|
-
'active':
|
2085
|
-
'withdraw':
|
2086
|
-
'deposit':
|
2087
|
-
'fee': self.
|
2088
|
-
'precision':
|
2091
|
+
'active': None,
|
2092
|
+
'withdraw': self.safe_string(chain, 'withdrawable') == 'true',
|
2093
|
+
'deposit': self.safe_string(chain, 'rechargeable') == 'true',
|
2094
|
+
'fee': self.safe_number(chain, 'withdrawFee'),
|
2095
|
+
'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'withdrawMinScale'))),
|
2089
2096
|
}
|
2090
|
-
|
2097
|
+
isFiat = self.in_array(code, fiatCurrencies)
|
2098
|
+
result[code] = self.safe_currency_structure({
|
2091
2099
|
'info': entry,
|
2092
2100
|
'id': id,
|
2093
2101
|
'code': code,
|
2094
2102
|
'networks': networks,
|
2095
|
-
'type':
|
2103
|
+
'type': 'fiat' if isFiat else 'crypto',
|
2096
2104
|
'name': None,
|
2097
|
-
'active':
|
2098
|
-
'deposit':
|
2099
|
-
'withdraw':
|
2100
|
-
'fee':
|
2105
|
+
'active': None,
|
2106
|
+
'deposit': None,
|
2107
|
+
'withdraw': None,
|
2108
|
+
'fee': None,
|
2101
2109
|
'precision': None,
|
2102
2110
|
'limits': {
|
2103
2111
|
'amount': {
|
@@ -2105,16 +2113,16 @@ class bitget(Exchange, ImplicitAPI):
|
|
2105
2113
|
'max': None,
|
2106
2114
|
},
|
2107
2115
|
'withdraw': {
|
2108
|
-
'min':
|
2116
|
+
'min': None,
|
2109
2117
|
'max': None,
|
2110
2118
|
},
|
2111
2119
|
'deposit': {
|
2112
|
-
'min':
|
2120
|
+
'min': None,
|
2113
2121
|
'max': None,
|
2114
2122
|
},
|
2115
2123
|
},
|
2116
2124
|
'created': None,
|
2117
|
-
}
|
2125
|
+
})
|
2118
2126
|
return result
|
2119
2127
|
|
2120
2128
|
async def fetch_market_leverage_tiers(self, symbol: str, params={}) -> List[LeverageTier]:
|
@@ -2733,7 +2741,7 @@ class bitget(Exchange, ImplicitAPI):
|
|
2733
2741
|
close = self.safe_string(ticker, 'lastPr')
|
2734
2742
|
timestamp = self.safe_integer_omit_zero(ticker, 'ts') # exchange bitget provided 0
|
2735
2743
|
change = self.safe_string(ticker, 'change24h')
|
2736
|
-
open24 = self.
|
2744
|
+
open24 = self.safe_string_2(ticker, 'open24', 'open24h')
|
2737
2745
|
open = self.safe_string(ticker, 'open')
|
2738
2746
|
symbol: str
|
2739
2747
|
openValue: str
|
@@ -3416,29 +3424,31 @@ class bitget(Exchange, ImplicitAPI):
|
|
3416
3424
|
market = self.market(symbol)
|
3417
3425
|
marketType = 'spot' if market['spot'] else 'swap'
|
3418
3426
|
timeframes = self.options['timeframes'][marketType]
|
3419
|
-
msInDay = 86400000
|
3420
|
-
duration = self.parse_timeframe(timeframe) * 1000
|
3421
3427
|
request: dict = {
|
3422
3428
|
'symbol': market['id'],
|
3423
3429
|
'granularity': self.safe_string(timeframes, timeframe, timeframe),
|
3424
3430
|
}
|
3431
|
+
msInDay = 86400000
|
3432
|
+
now = self.milliseconds()
|
3433
|
+
duration = self.parse_timeframe(timeframe) * 1000
|
3425
3434
|
until = self.safe_integer(params, 'until')
|
3426
3435
|
limitDefined = limit is not None
|
3427
3436
|
sinceDefined = since is not None
|
3428
3437
|
untilDefined = until is not None
|
3429
3438
|
params = self.omit(params, ['until'])
|
3430
|
-
response = None
|
3431
|
-
now = self.milliseconds()
|
3432
3439
|
# retrievable periods listed here:
|
3433
3440
|
# - https://www.bitget.com/api-doc/spot/market/Get-Candle-Data#request-parameters
|
3434
3441
|
# - https://www.bitget.com/api-doc/contract/market/Get-Candle-Data#description
|
3435
|
-
|
3436
|
-
|
3437
|
-
|
3438
|
-
|
3442
|
+
key = 'spot' if market['spot'] else 'swap'
|
3443
|
+
ohlcOptions = self.safe_dict(self.options['fetchOHLCV'], key, {})
|
3444
|
+
maxLimitPerTimeframe = self.safe_dict(ohlcOptions, 'maxLimitPerTimeframe', {})
|
3445
|
+
maxLimitForThisTimeframe = self.safe_integer(maxLimitPerTimeframe, timeframe, limit)
|
3446
|
+
recentEndpointDaysMap = self.safe_dict(self.options['fetchOHLCV'], 'maxRecentDaysPerTimeframe', {})
|
3447
|
+
recentEndpointAvailableDays = self.safe_integer(recentEndpointDaysMap, timeframe)
|
3448
|
+
recentEndpointBoundaryTs = now - (recentEndpointAvailableDays - 1) * msInDay
|
3439
3449
|
if limitDefined:
|
3440
3450
|
limit = min(limit, maxLimitForRecentEndpoint)
|
3441
|
-
|
3451
|
+
limit = min(limit, maxLimitForThisTimeframe)
|
3442
3452
|
else:
|
3443
3453
|
limit = defaultLimit
|
3444
3454
|
limitMultipliedDuration = limit * duration
|
@@ -3458,26 +3468,33 @@ class bitget(Exchange, ImplicitAPI):
|
|
3458
3468
|
if not sinceDefined:
|
3459
3469
|
calculatedStartTime = calculatedEndTime - limitMultipliedDuration
|
3460
3470
|
# we do not need to set "startTime" here
|
3461
|
-
|
3462
|
-
|
3471
|
+
# if historical endpoint is needed, we should re-set the variables
|
3472
|
+
historicalEndpointNeeded = False
|
3473
|
+
if (calculatedStartTime is not None and calculatedStartTime <= recentEndpointBoundaryTs) or useHistoryEndpoint:
|
3474
|
+
historicalEndpointNeeded = True
|
3463
3475
|
# only for "historical-candles" - ensure we use correct max limit
|
3464
|
-
|
3465
|
-
|
3476
|
+
limit = min(limit, maxLimitForHistoryEndpoint)
|
3477
|
+
limitMultipliedDuration = limit * duration
|
3478
|
+
calculatedStartTime = calculatedEndTime - limitMultipliedDuration
|
3479
|
+
request['startTime'] = calculatedStartTime
|
3480
|
+
# for contract, maximum 90 days allowed between start-end times
|
3481
|
+
if not market['spot']:
|
3482
|
+
maxDistanceDaysForContracts = 90
|
3483
|
+
# only correct if request is larger
|
3484
|
+
if calculatedEndTime - calculatedStartTime > maxDistanceDaysForContracts * msInDay:
|
3485
|
+
calculatedEndTime = self.sum(calculatedStartTime, maxDistanceDaysForContracts * msInDay)
|
3486
|
+
request['endTime'] = calculatedEndTime
|
3487
|
+
# we need to set limit to safely cover the period
|
3488
|
+
request['limit'] = limit
|
3466
3489
|
# make request
|
3490
|
+
response = None
|
3467
3491
|
if market['spot']:
|
3468
3492
|
# checks if we need history endpoint
|
3469
|
-
if historicalEndpointNeeded
|
3493
|
+
if historicalEndpointNeeded:
|
3470
3494
|
response = await self.publicSpotGetV2SpotMarketHistoryCandles(self.extend(request, params))
|
3471
3495
|
else:
|
3472
3496
|
response = await self.publicSpotGetV2SpotMarketCandles(self.extend(request, params))
|
3473
3497
|
else:
|
3474
|
-
maxDistanceDaysForContracts = 90 # for contract, maximum 90 days allowed between start-end times
|
3475
|
-
# only correct the request to fix 90 days if until was auto-calculated
|
3476
|
-
if sinceDefined:
|
3477
|
-
if not untilDefined:
|
3478
|
-
request['endTime'] = min(calculatedEndTime, self.sum(since, maxDistanceDaysForContracts * msInDay))
|
3479
|
-
elif calculatedEndTime - calculatedStartTime > maxDistanceDaysForContracts * msInDay:
|
3480
|
-
raise BadRequest(self.id + ' fetchOHLCV() between start and end must be less than ' + str(maxDistanceDaysForContracts) + ' days')
|
3481
3498
|
priceType = None
|
3482
3499
|
priceType, params = self.handle_param_string(params, 'price')
|
3483
3500
|
productType = None
|
@@ -3490,7 +3507,7 @@ class bitget(Exchange, ImplicitAPI):
|
|
3490
3507
|
elif priceType == 'index':
|
3491
3508
|
response = await self.publicMixGetV2MixMarketHistoryIndexCandles(extended)
|
3492
3509
|
else:
|
3493
|
-
if historicalEndpointNeeded
|
3510
|
+
if historicalEndpointNeeded:
|
3494
3511
|
response = await self.publicMixGetV2MixMarketHistoryCandles(extended)
|
3495
3512
|
else:
|
3496
3513
|
response = await self.publicMixGetV2MixMarketCandles(extended)
|
@@ -6444,9 +6461,11 @@ class bitget(Exchange, ImplicitAPI):
|
|
6444
6461
|
fetch the current funding rate
|
6445
6462
|
|
6446
6463
|
https://www.bitget.com/api-doc/contract/market/Get-Current-Funding-Rate
|
6464
|
+
https://www.bitget.com/api-doc/contract/market/Get-Symbol-Next-Funding-Time
|
6447
6465
|
|
6448
6466
|
:param str symbol: unified market symbol
|
6449
6467
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
6468
|
+
:param str [params.method]: either(default) 'publicMixGetV2MixMarketCurrentFundRate' or 'publicMixGetV2MixMarketFundingTime'
|
6450
6469
|
:returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
6451
6470
|
"""
|
6452
6471
|
await self.load_markets()
|
@@ -6459,21 +6478,45 @@ class bitget(Exchange, ImplicitAPI):
|
|
6459
6478
|
'symbol': market['id'],
|
6460
6479
|
'productType': productType,
|
6461
6480
|
}
|
6462
|
-
|
6463
|
-
|
6464
|
-
|
6465
|
-
|
6466
|
-
|
6467
|
-
|
6468
|
-
|
6469
|
-
|
6470
|
-
|
6471
|
-
|
6472
|
-
|
6473
|
-
|
6474
|
-
|
6475
|
-
|
6476
|
-
|
6481
|
+
method = None
|
6482
|
+
method, params = self.handle_option_and_params(params, 'fetchFundingRate', 'method', 'publicMixGetV2MixMarketCurrentFundRate')
|
6483
|
+
response = None
|
6484
|
+
if method == 'publicMixGetV2MixMarketCurrentFundRate':
|
6485
|
+
response = await self.publicMixGetV2MixMarketCurrentFundRate(self.extend(request, params))
|
6486
|
+
#
|
6487
|
+
# {
|
6488
|
+
# "code": "00000",
|
6489
|
+
# "msg": "success",
|
6490
|
+
# "requestTime": 1745500709429,
|
6491
|
+
# "data": [
|
6492
|
+
# {
|
6493
|
+
# "symbol": "BTCUSDT",
|
6494
|
+
# "fundingRate": "-0.000013",
|
6495
|
+
# "fundingRateInterval": "8",
|
6496
|
+
# "nextUpdate": "1745510400000",
|
6497
|
+
# "minFundingRate": "-0.003",
|
6498
|
+
# "maxFundingRate": "0.003"
|
6499
|
+
# }
|
6500
|
+
# ]
|
6501
|
+
# }
|
6502
|
+
#
|
6503
|
+
elif method == 'publicMixGetV2MixMarketFundingTime':
|
6504
|
+
response = await self.publicMixGetV2MixMarketFundingTime(self.extend(request, params))
|
6505
|
+
#
|
6506
|
+
# {
|
6507
|
+
# "code": "00000",
|
6508
|
+
# "msg": "success",
|
6509
|
+
# "requestTime": 1745402092428,
|
6510
|
+
# "data": [
|
6511
|
+
# {
|
6512
|
+
# "symbol": "BTCUSDT",
|
6513
|
+
# "nextFundingTime": "1745424000000",
|
6514
|
+
# "ratePeriod": "8"
|
6515
|
+
# }
|
6516
|
+
# ]
|
6517
|
+
# }
|
6518
|
+
#
|
6519
|
+
data = self.safe_list(response, 'data', [])
|
6477
6520
|
return self.parse_funding_rate(data[0], market)
|
6478
6521
|
|
6479
6522
|
async def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
|
@@ -6536,11 +6579,23 @@ class bitget(Exchange, ImplicitAPI):
|
|
6536
6579
|
|
6537
6580
|
def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
|
6538
6581
|
#
|
6539
|
-
# fetchFundingRate
|
6582
|
+
# fetchFundingRate: publicMixGetV2MixMarketCurrentFundRate
|
6540
6583
|
#
|
6541
6584
|
# {
|
6542
6585
|
# "symbol": "BTCUSDT",
|
6543
|
-
# "fundingRate": "-0.
|
6586
|
+
# "fundingRate": "-0.000013",
|
6587
|
+
# "fundingRateInterval": "8",
|
6588
|
+
# "nextUpdate": "1745510400000",
|
6589
|
+
# "minFundingRate": "-0.003",
|
6590
|
+
# "maxFundingRate": "0.003"
|
6591
|
+
# }
|
6592
|
+
#
|
6593
|
+
# fetchFundingRate: publicMixGetV2MixMarketFundingTime
|
6594
|
+
#
|
6595
|
+
# {
|
6596
|
+
# "symbol": "BTCUSDT",
|
6597
|
+
# "nextFundingTime": "1745424000000",
|
6598
|
+
# "ratePeriod": "8"
|
6544
6599
|
# }
|
6545
6600
|
#
|
6546
6601
|
# fetchFundingInterval
|
@@ -6550,7 +6605,9 @@ class bitget(Exchange, ImplicitAPI):
|
|
6550
6605
|
# "nextFundingTime": "1727942400000",
|
6551
6606
|
# "ratePeriod": "8"
|
6552
6607
|
# }
|
6608
|
+
#
|
6553
6609
|
# fetchFundingRates
|
6610
|
+
#
|
6554
6611
|
# {
|
6555
6612
|
# "symbol": "BTCUSD",
|
6556
6613
|
# "lastPr": "29904.5",
|
@@ -6576,10 +6633,11 @@ class bitget(Exchange, ImplicitAPI):
|
|
6576
6633
|
# "open24h": "0",
|
6577
6634
|
# "markPrice": "12345"
|
6578
6635
|
# }
|
6636
|
+
#
|
6579
6637
|
marketId = self.safe_string(contract, 'symbol')
|
6580
6638
|
symbol = self.safe_symbol(marketId, market, None, 'swap')
|
6581
|
-
fundingTimestamp = self.
|
6582
|
-
interval = self.
|
6639
|
+
fundingTimestamp = self.safe_integer_2(contract, 'nextFundingTime', 'nextUpdate')
|
6640
|
+
interval = self.safe_string_2(contract, 'ratePeriod', 'fundingRateInterval')
|
6583
6641
|
timestamp = self.safe_integer(contract, 'ts')
|
6584
6642
|
markPrice = self.safe_number(contract, 'markPrice')
|
6585
6643
|
indexPrice = self.safe_number(contract, 'indexPrice')
|
ccxt/async_support/bitmart.py
CHANGED
@@ -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 Any, 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, MarketInterface, TransferEntry
|
9
|
+
from ccxt.base.types import Any, Balances, BorrowInterest, Currencies, Currency, DepositAddress, FundingHistory, Int, IsolatedBorrowRate, IsolatedBorrowRates, LedgerEntry, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, MarketInterface, TransferEntry
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
12
|
from ccxt.base.errors import AuthenticationError
|
@@ -225,6 +225,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
225
225
|
'contract/private/order': 1.2,
|
226
226
|
'contract/private/order-history': 10,
|
227
227
|
'contract/private/position': 10,
|
228
|
+
'contract/private/position-v2': 10,
|
228
229
|
'contract/private/get-open-orders': 1.2,
|
229
230
|
'contract/private/current-plan-order': 1.2,
|
230
231
|
'contract/private/trades': 10,
|
@@ -1214,6 +1215,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1214
1215
|
# {
|
1215
1216
|
# "currency": "BTC",
|
1216
1217
|
# "name": "Bitcoin",
|
1218
|
+
# "recharge_minsize": '0.00000001',
|
1217
1219
|
# "contract_address": null,
|
1218
1220
|
# "network": "BTC",
|
1219
1221
|
# "withdraw_enabled": True,
|
@@ -1235,7 +1237,8 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1235
1237
|
fullId = self.safe_string(currency, 'currency')
|
1236
1238
|
currencyId = fullId
|
1237
1239
|
networkId = self.safe_string(currency, 'network')
|
1238
|
-
|
1240
|
+
isNtf = (fullId.find('NFT') >= 0)
|
1241
|
+
if not isNtf:
|
1239
1242
|
parts = fullId.split('-')
|
1240
1243
|
currencyId = self.safe_string(parts, 0)
|
1241
1244
|
second = self.safe_string(parts, 1)
|
@@ -1254,6 +1257,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1254
1257
|
'withdraw': None,
|
1255
1258
|
'active': None,
|
1256
1259
|
'networks': {},
|
1260
|
+
'type': 'other' if isNtf else 'crypto',
|
1257
1261
|
}
|
1258
1262
|
networkCode = self.network_id_to_code(networkId)
|
1259
1263
|
withdraw = self.safe_bool(currency, 'withdraw_enabled')
|
@@ -4654,11 +4658,12 @@ class bitmart(Exchange, ImplicitAPI):
|
|
4654
4658
|
first = self.safe_dict(data, 0, {})
|
4655
4659
|
return self.parse_position(first, market)
|
4656
4660
|
|
4657
|
-
async def fetch_positions(self, symbols: Strings = None, params={}):
|
4661
|
+
async def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
|
4658
4662
|
"""
|
4659
4663
|
fetch all open contract positions
|
4660
4664
|
|
4661
4665
|
https://developer-pro.bitmart.com/en/futuresv2/#get-current-position-keyed
|
4666
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-current-position-v2-keyed
|
4662
4667
|
|
4663
4668
|
:param str[]|None symbols: list of unified market symbols
|
4664
4669
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -4675,7 +4680,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
4675
4680
|
if symbolsLength == 1:
|
4676
4681
|
# only supports symbols or sending one symbol
|
4677
4682
|
request['symbol'] = market['id']
|
4678
|
-
response = await self.
|
4683
|
+
response = await self.privateGetContractPrivatePositionV2(self.extend(request, params))
|
4679
4684
|
#
|
4680
4685
|
# {
|
4681
4686
|
# "code": 1000,
|
ccxt/async_support/bitmex.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.bitmex import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Any, Balances, Currencies, Currency, DepositAddress, Int, LedgerEntry, Leverage, Leverages, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, Transaction
|
9
|
+
from ccxt.base.types import Any, Balances, Currencies, Currency, DepositAddress, Int, LedgerEntry, Leverage, Leverages, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, Transaction
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
12
|
from ccxt.base.errors import AuthenticationError
|
@@ -503,6 +503,7 @@ class bitmex(Exchange, ImplicitAPI):
|
|
503
503
|
maxWithdrawal = self.parse_number(Precise.string_mul(maxWithdrawalString, precisionString))
|
504
504
|
minDepositString = self.safe_string(currency, 'minDepositAmount')
|
505
505
|
minDeposit = self.parse_number(Precise.string_mul(minDepositString, precisionString))
|
506
|
+
isCrypto = self.safe_string(currency, 'currencyType') == 'Crypto'
|
506
507
|
result[code] = {
|
507
508
|
'id': id,
|
508
509
|
'code': code,
|
@@ -528,6 +529,7 @@ class bitmex(Exchange, ImplicitAPI):
|
|
528
529
|
},
|
529
530
|
},
|
530
531
|
'networks': networks,
|
532
|
+
'type': 'crypto' if isCrypto else 'other',
|
531
533
|
}
|
532
534
|
return result
|
533
535
|
|
@@ -729,7 +731,7 @@ class bitmex(Exchange, ImplicitAPI):
|
|
729
731
|
isQuanto = self.safe_value(market, 'isQuanto') # self is True when BASE and SETTLE are different, i.e. AXS/XXX:BTC
|
730
732
|
linear = (not isInverse and not isQuanto) if contract else None
|
731
733
|
status = self.safe_string(market, 'state')
|
732
|
-
active = status
|
734
|
+
active = status == 'Open' # Open, Settled, Unlisted
|
733
735
|
expiry = None
|
734
736
|
expiryDatetime = None
|
735
737
|
symbol = None
|
@@ -743,9 +745,9 @@ class bitmex(Exchange, ImplicitAPI):
|
|
743
745
|
else:
|
744
746
|
multiplierString = Precise.string_abs(self.safe_string(market, 'multiplier'))
|
745
747
|
contractSize = self.parse_number(multiplierString)
|
746
|
-
|
747
|
-
|
748
|
-
|
748
|
+
expiryDatetime = self.safe_string(market, 'expiry')
|
749
|
+
expiry = self.parse8601(expiryDatetime)
|
750
|
+
if expiry is not None:
|
749
751
|
symbol = symbol + '-' + self.yymmdd(expiry)
|
750
752
|
else:
|
751
753
|
# for index/exotic markets, default to id
|
@@ -756,6 +758,11 @@ class bitmex(Exchange, ImplicitAPI):
|
|
756
758
|
maxOrderQty = self.safe_number(market, 'maxOrderQty')
|
757
759
|
initMargin = self.safe_string(market, 'initMargin', '1')
|
758
760
|
maxLeverage = self.parse_number(Precise.string_div('1', initMargin))
|
761
|
+
# subtype should be None for spot markets
|
762
|
+
if spot:
|
763
|
+
isInverse = None
|
764
|
+
isQuanto = None
|
765
|
+
linear = None
|
759
766
|
return {
|
760
767
|
'id': id,
|
761
768
|
'symbol': symbol,
|
@@ -805,7 +812,7 @@ class bitmex(Exchange, ImplicitAPI):
|
|
805
812
|
'max': maxOrderQty if positionIsQuote else None,
|
806
813
|
},
|
807
814
|
},
|
808
|
-
'created':
|
815
|
+
'created': None, # 'listing' field is buggy, e.g. 2200-02-01T00:00:00.000Z
|
809
816
|
'info': market,
|
810
817
|
}
|
811
818
|
|
@@ -2182,7 +2189,7 @@ class bitmex(Exchange, ImplicitAPI):
|
|
2182
2189
|
'shortLeverage': self.safe_integer(leverage, 'leverage'),
|
2183
2190
|
}
|
2184
2191
|
|
2185
|
-
async def fetch_positions(self, symbols: Strings = None, params={}):
|
2192
|
+
async def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
|
2186
2193
|
"""
|
2187
2194
|
fetch all open positions
|
2188
2195
|
|