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/bitget.py
CHANGED
@@ -1392,28 +1392,44 @@ class bitget(Exchange, ImplicitAPI):
|
|
1392
1392
|
'fillResponseFromRequest': True,
|
1393
1393
|
},
|
1394
1394
|
'fetchOHLCV': {
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
'
|
1399
|
-
'method': 'publicMixGetV2MixMarketCandles', # publicMixGetV2MixMarketCandles or publicMixGetV2MixMarketHistoryCandles or publicMixGetV2MixMarketHistoryIndexCandles or publicMixGetV2MixMarketHistoryMarkCandles
|
1400
|
-
},
|
1401
|
-
'maxDaysPerTimeframe': {
|
1395
|
+
# ### Timeframe settings ###
|
1396
|
+
# after testing, the below values are real ones, because the values provided by API DOCS are wrong
|
1397
|
+
# so, start timestamp should be within these thresholds to be able to call "recent" candles endpoint
|
1398
|
+
'maxRecentDaysPerTimeframe': {
|
1402
1399
|
'1m': 30,
|
1403
1400
|
'3m': 30,
|
1404
1401
|
'5m': 30,
|
1405
|
-
'
|
1406
|
-
'
|
1407
|
-
'
|
1408
|
-
'1h': 83,
|
1409
|
-
'2h': 120,
|
1402
|
+
'15m': 30,
|
1403
|
+
'30m': 30,
|
1404
|
+
'1h': 60,
|
1410
1405
|
'4h': 240,
|
1411
1406
|
'6h': 360,
|
1412
|
-
'12h':
|
1413
|
-
'1d':
|
1414
|
-
'3d':
|
1415
|
-
'1w':
|
1416
|
-
'1M':
|
1407
|
+
'12h': 720,
|
1408
|
+
'1d': 1440,
|
1409
|
+
'3d': 1440 * 3,
|
1410
|
+
'1w': 1440 * 7,
|
1411
|
+
'1M': 1440 * 30,
|
1412
|
+
},
|
1413
|
+
'spot': {
|
1414
|
+
'maxLimitPerTimeframe': {
|
1415
|
+
'1d': 300,
|
1416
|
+
'3d': 100,
|
1417
|
+
'1w': 100,
|
1418
|
+
'1M': 100,
|
1419
|
+
},
|
1420
|
+
'method': 'publicSpotGetV2SpotMarketCandles', # publicSpotGetV2SpotMarketCandles or publicSpotGetV2SpotMarketHistoryCandles
|
1421
|
+
},
|
1422
|
+
'swap': {
|
1423
|
+
'maxLimitPerTimeframe': {
|
1424
|
+
'4h': 540,
|
1425
|
+
'6h': 360,
|
1426
|
+
'12h': 180,
|
1427
|
+
'1d': 90,
|
1428
|
+
'3d': 30,
|
1429
|
+
'1w': 13,
|
1430
|
+
'1M': 4,
|
1431
|
+
},
|
1432
|
+
'method': 'publicMixGetV2MixMarketCandles', # publicMixGetV2MixMarketCandles or publicMixGetV2MixMarketHistoryCandles or publicMixGetV2MixMarketHistoryIndexCandles or publicMixGetV2MixMarketHistoryMarkCandles
|
1417
1433
|
},
|
1418
1434
|
},
|
1419
1435
|
'fetchTrades': {
|
@@ -1424,6 +1440,9 @@ class bitget(Exchange, ImplicitAPI):
|
|
1424
1440
|
'method': 'publicMixGetV2MixMarketFillsHistory', # or publicMixGetV2MixMarketFills
|
1425
1441
|
},
|
1426
1442
|
},
|
1443
|
+
'fetchFundingRate': {
|
1444
|
+
'method': 'publicMixGetV2MixMarketCurrentFundRate', # or publicMixGetV2MixMarketFundingTime
|
1445
|
+
},
|
1427
1446
|
'accountsByType': {
|
1428
1447
|
'spot': 'spot',
|
1429
1448
|
'cross': 'crossed_margin',
|
@@ -1547,6 +1566,8 @@ class bitget(Exchange, ImplicitAPI):
|
|
1547
1566
|
'method': 'privateMixGetV2MixPositionAllPosition', # or privateMixGetV2MixPositionHistoryPosition
|
1548
1567
|
},
|
1549
1568
|
'defaultTimeInForce': 'GTC', # 'GTC' = Good To Cancel(default), 'IOC' = Immediate Or Cancel
|
1569
|
+
# fiat currencies on deposit page
|
1570
|
+
'fiatCurrencies': ['EUR', 'VND', 'PLN', 'CZK', 'HUF', 'DKK', 'AUD', 'CAD', 'NOK', 'SEK', 'CHF', 'MXN', 'COP', 'ARS', 'GBP', 'BRL', 'UAH', 'ZAR'],
|
1550
1571
|
},
|
1551
1572
|
'features': {
|
1552
1573
|
'spot': {
|
@@ -1621,7 +1642,7 @@ class bitget(Exchange, ImplicitAPI):
|
|
1621
1642
|
'symbolRequired': False,
|
1622
1643
|
},
|
1623
1644
|
'fetchOHLCV': {
|
1624
|
-
'limit':
|
1645
|
+
'limit': 200, # variable timespans for recent endpoint, 200 for historical
|
1625
1646
|
},
|
1626
1647
|
},
|
1627
1648
|
'forPerps': {
|
@@ -1696,11 +1717,12 @@ class bitget(Exchange, ImplicitAPI):
|
|
1696
1717
|
defaultProductType = None
|
1697
1718
|
if (subType is not None) and (market is None):
|
1698
1719
|
# set default only if subType is defined and market is not defined, since there is also USDC productTypes which are also linear
|
1699
|
-
sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
|
1700
|
-
if sandboxMode:
|
1701
|
-
|
1702
|
-
else:
|
1703
|
-
|
1720
|
+
# sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
|
1721
|
+
# if sandboxMode:
|
1722
|
+
# defaultProductType = 'SUSDT-FUTURES' if (subType == 'linear') else 'SCOIN-FUTURES'
|
1723
|
+
# else:
|
1724
|
+
defaultProductType = 'USDT-FUTURES' if (subType == 'linear') else 'COIN-FUTURES'
|
1725
|
+
# }
|
1704
1726
|
productType = self.safe_string(params, 'productType', defaultProductType)
|
1705
1727
|
if (productType is None) and (market is not None):
|
1706
1728
|
settle = market['settle']
|
@@ -2004,99 +2026,85 @@ class bitget(Exchange, ImplicitAPI):
|
|
2004
2026
|
"""
|
2005
2027
|
response = self.publicSpotGetV2SpotPublicCoins(params)
|
2006
2028
|
#
|
2007
|
-
#
|
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
|
-
#
|
2029
|
+
# {
|
2030
|
+
# "code": "00000",
|
2031
|
+
# "msg": "success",
|
2032
|
+
# "requestTime": "1746195617812",
|
2033
|
+
# "data": [
|
2034
|
+
# {
|
2035
|
+
# "coinId": "1456",
|
2036
|
+
# "coin": "NEIROETH",
|
2037
|
+
# "transfer": "false",
|
2038
|
+
# "chains": [
|
2039
|
+
# {
|
2040
|
+
# "chain": "ERC20",
|
2041
|
+
# "needTag": "false",
|
2042
|
+
# "withdrawable": "true",
|
2043
|
+
# "rechargeable": "true",
|
2044
|
+
# "withdrawFee": "44.91017965",
|
2045
|
+
# "extraWithdrawFee": "0",
|
2046
|
+
# "depositConfirm": "12",
|
2047
|
+
# "withdrawConfirm": "64",
|
2048
|
+
# "minDepositAmount": "0.06",
|
2049
|
+
# "minWithdrawAmount": "60",
|
2050
|
+
# "browserUrl": "https://etherscan.io/tx/",
|
2051
|
+
# "contractAddress": "0xee2a03aa6dacf51c18679c516ad5283d8e7c2637",
|
2052
|
+
# "withdrawStep": "0",
|
2053
|
+
# "withdrawMinScale": "8",
|
2054
|
+
# "congestion": "normal"
|
2055
|
+
# }
|
2056
|
+
# ],
|
2057
|
+
# "areaCoin": "no"
|
2058
|
+
# },
|
2059
|
+
# ...
|
2034
2060
|
#
|
2035
2061
|
result: dict = {}
|
2036
2062
|
data = self.safe_value(response, 'data', [])
|
2063
|
+
fiatCurrencies = self.safe_list(self.options, 'fiatCurrencies', [])
|
2037
2064
|
for i in range(0, len(data)):
|
2038
2065
|
entry = data[i]
|
2039
2066
|
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..)
|
2040
2067
|
code = self.safe_currency_code(id)
|
2041
2068
|
chains = self.safe_value(entry, 'chains', [])
|
2042
2069
|
networks: dict = {}
|
2043
|
-
deposit = False
|
2044
|
-
withdraw = False
|
2045
|
-
minWithdrawString = None
|
2046
|
-
minDepositString = None
|
2047
|
-
minWithdrawFeeString = None
|
2048
2070
|
for j in range(0, len(chains)):
|
2049
2071
|
chain = chains[j]
|
2050
2072
|
networkId = self.safe_string(chain, 'chain')
|
2051
2073
|
network = self.network_id_to_code(networkId, code)
|
2052
2074
|
if network is not None:
|
2053
2075
|
network = network.upper()
|
2054
|
-
withdrawEnabled = self.safe_string(chain, 'withdrawable')
|
2055
|
-
canWithdraw = withdrawEnabled == 'true'
|
2056
|
-
withdraw = canWithdraw if (canWithdraw) else withdraw
|
2057
|
-
depositEnabled = self.safe_string(chain, 'rechargeable')
|
2058
|
-
canDeposit = depositEnabled == 'true'
|
2059
|
-
deposit = canDeposit if (canDeposit) else deposit
|
2060
|
-
networkWithdrawFeeString = self.safe_string(chain, 'withdrawFee')
|
2061
|
-
if networkWithdrawFeeString is not None:
|
2062
|
-
minWithdrawFeeString = networkWithdrawFeeString if (minWithdrawFeeString is None) else Precise.string_min(networkWithdrawFeeString, minWithdrawFeeString)
|
2063
|
-
networkMinWithdrawString = self.safe_string(chain, 'minWithdrawAmount')
|
2064
|
-
if networkMinWithdrawString is not None:
|
2065
|
-
minWithdrawString = networkMinWithdrawString if (minWithdrawString is None) else Precise.string_min(networkMinWithdrawString, minWithdrawString)
|
2066
|
-
networkMinDepositString = self.safe_string(chain, 'minDepositAmount')
|
2067
|
-
if networkMinDepositString is not None:
|
2068
|
-
minDepositString = networkMinDepositString if (minDepositString is None) else Precise.string_min(networkMinDepositString, minDepositString)
|
2069
2076
|
networks[network] = {
|
2070
2077
|
'info': chain,
|
2071
2078
|
'id': networkId,
|
2072
2079
|
'network': network,
|
2073
2080
|
'limits': {
|
2074
2081
|
'withdraw': {
|
2075
|
-
'min': self.
|
2082
|
+
'min': self.safe_number(chain, 'minWithdrawAmount'),
|
2076
2083
|
'max': None,
|
2077
2084
|
},
|
2078
2085
|
'deposit': {
|
2079
|
-
'min': self.
|
2086
|
+
'min': self.safe_number(chain, 'minDepositAmount'),
|
2080
2087
|
'max': None,
|
2081
2088
|
},
|
2082
2089
|
},
|
2083
|
-
'active':
|
2084
|
-
'withdraw':
|
2085
|
-
'deposit':
|
2086
|
-
'fee': self.
|
2087
|
-
'precision':
|
2090
|
+
'active': None,
|
2091
|
+
'withdraw': self.safe_string(chain, 'withdrawable') == 'true',
|
2092
|
+
'deposit': self.safe_string(chain, 'rechargeable') == 'true',
|
2093
|
+
'fee': self.safe_number(chain, 'withdrawFee'),
|
2094
|
+
'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'withdrawMinScale'))),
|
2088
2095
|
}
|
2089
|
-
|
2096
|
+
isFiat = self.in_array(code, fiatCurrencies)
|
2097
|
+
result[code] = self.safe_currency_structure({
|
2090
2098
|
'info': entry,
|
2091
2099
|
'id': id,
|
2092
2100
|
'code': code,
|
2093
2101
|
'networks': networks,
|
2094
|
-
'type':
|
2102
|
+
'type': 'fiat' if isFiat else 'crypto',
|
2095
2103
|
'name': None,
|
2096
|
-
'active':
|
2097
|
-
'deposit':
|
2098
|
-
'withdraw':
|
2099
|
-
'fee':
|
2104
|
+
'active': None,
|
2105
|
+
'deposit': None,
|
2106
|
+
'withdraw': None,
|
2107
|
+
'fee': None,
|
2100
2108
|
'precision': None,
|
2101
2109
|
'limits': {
|
2102
2110
|
'amount': {
|
@@ -2104,16 +2112,16 @@ class bitget(Exchange, ImplicitAPI):
|
|
2104
2112
|
'max': None,
|
2105
2113
|
},
|
2106
2114
|
'withdraw': {
|
2107
|
-
'min':
|
2115
|
+
'min': None,
|
2108
2116
|
'max': None,
|
2109
2117
|
},
|
2110
2118
|
'deposit': {
|
2111
|
-
'min':
|
2119
|
+
'min': None,
|
2112
2120
|
'max': None,
|
2113
2121
|
},
|
2114
2122
|
},
|
2115
2123
|
'created': None,
|
2116
|
-
}
|
2124
|
+
})
|
2117
2125
|
return result
|
2118
2126
|
|
2119
2127
|
def fetch_market_leverage_tiers(self, symbol: str, params={}) -> List[LeverageTier]:
|
@@ -2732,7 +2740,7 @@ class bitget(Exchange, ImplicitAPI):
|
|
2732
2740
|
close = self.safe_string(ticker, 'lastPr')
|
2733
2741
|
timestamp = self.safe_integer_omit_zero(ticker, 'ts') # exchange bitget provided 0
|
2734
2742
|
change = self.safe_string(ticker, 'change24h')
|
2735
|
-
open24 = self.
|
2743
|
+
open24 = self.safe_string_2(ticker, 'open24', 'open24h')
|
2736
2744
|
open = self.safe_string(ticker, 'open')
|
2737
2745
|
symbol: str
|
2738
2746
|
openValue: str
|
@@ -3415,29 +3423,31 @@ class bitget(Exchange, ImplicitAPI):
|
|
3415
3423
|
market = self.market(symbol)
|
3416
3424
|
marketType = 'spot' if market['spot'] else 'swap'
|
3417
3425
|
timeframes = self.options['timeframes'][marketType]
|
3418
|
-
msInDay = 86400000
|
3419
|
-
duration = self.parse_timeframe(timeframe) * 1000
|
3420
3426
|
request: dict = {
|
3421
3427
|
'symbol': market['id'],
|
3422
3428
|
'granularity': self.safe_string(timeframes, timeframe, timeframe),
|
3423
3429
|
}
|
3430
|
+
msInDay = 86400000
|
3431
|
+
now = self.milliseconds()
|
3432
|
+
duration = self.parse_timeframe(timeframe) * 1000
|
3424
3433
|
until = self.safe_integer(params, 'until')
|
3425
3434
|
limitDefined = limit is not None
|
3426
3435
|
sinceDefined = since is not None
|
3427
3436
|
untilDefined = until is not None
|
3428
3437
|
params = self.omit(params, ['until'])
|
3429
|
-
response = None
|
3430
|
-
now = self.milliseconds()
|
3431
3438
|
# retrievable periods listed here:
|
3432
3439
|
# - https://www.bitget.com/api-doc/spot/market/Get-Candle-Data#request-parameters
|
3433
3440
|
# - https://www.bitget.com/api-doc/contract/market/Get-Candle-Data#description
|
3434
|
-
|
3435
|
-
|
3436
|
-
|
3437
|
-
|
3441
|
+
key = 'spot' if market['spot'] else 'swap'
|
3442
|
+
ohlcOptions = self.safe_dict(self.options['fetchOHLCV'], key, {})
|
3443
|
+
maxLimitPerTimeframe = self.safe_dict(ohlcOptions, 'maxLimitPerTimeframe', {})
|
3444
|
+
maxLimitForThisTimeframe = self.safe_integer(maxLimitPerTimeframe, timeframe, limit)
|
3445
|
+
recentEndpointDaysMap = self.safe_dict(self.options['fetchOHLCV'], 'maxRecentDaysPerTimeframe', {})
|
3446
|
+
recentEndpointAvailableDays = self.safe_integer(recentEndpointDaysMap, timeframe)
|
3447
|
+
recentEndpointBoundaryTs = now - (recentEndpointAvailableDays - 1) * msInDay
|
3438
3448
|
if limitDefined:
|
3439
3449
|
limit = min(limit, maxLimitForRecentEndpoint)
|
3440
|
-
|
3450
|
+
limit = min(limit, maxLimitForThisTimeframe)
|
3441
3451
|
else:
|
3442
3452
|
limit = defaultLimit
|
3443
3453
|
limitMultipliedDuration = limit * duration
|
@@ -3457,26 +3467,33 @@ class bitget(Exchange, ImplicitAPI):
|
|
3457
3467
|
if not sinceDefined:
|
3458
3468
|
calculatedStartTime = calculatedEndTime - limitMultipliedDuration
|
3459
3469
|
# we do not need to set "startTime" here
|
3460
|
-
|
3461
|
-
|
3470
|
+
# if historical endpoint is needed, we should re-set the variables
|
3471
|
+
historicalEndpointNeeded = False
|
3472
|
+
if (calculatedStartTime is not None and calculatedStartTime <= recentEndpointBoundaryTs) or useHistoryEndpoint:
|
3473
|
+
historicalEndpointNeeded = True
|
3462
3474
|
# only for "historical-candles" - ensure we use correct max limit
|
3463
|
-
|
3464
|
-
|
3475
|
+
limit = min(limit, maxLimitForHistoryEndpoint)
|
3476
|
+
limitMultipliedDuration = limit * duration
|
3477
|
+
calculatedStartTime = calculatedEndTime - limitMultipliedDuration
|
3478
|
+
request['startTime'] = calculatedStartTime
|
3479
|
+
# for contract, maximum 90 days allowed between start-end times
|
3480
|
+
if not market['spot']:
|
3481
|
+
maxDistanceDaysForContracts = 90
|
3482
|
+
# only correct if request is larger
|
3483
|
+
if calculatedEndTime - calculatedStartTime > maxDistanceDaysForContracts * msInDay:
|
3484
|
+
calculatedEndTime = self.sum(calculatedStartTime, maxDistanceDaysForContracts * msInDay)
|
3485
|
+
request['endTime'] = calculatedEndTime
|
3486
|
+
# we need to set limit to safely cover the period
|
3487
|
+
request['limit'] = limit
|
3465
3488
|
# make request
|
3489
|
+
response = None
|
3466
3490
|
if market['spot']:
|
3467
3491
|
# checks if we need history endpoint
|
3468
|
-
if historicalEndpointNeeded
|
3492
|
+
if historicalEndpointNeeded:
|
3469
3493
|
response = self.publicSpotGetV2SpotMarketHistoryCandles(self.extend(request, params))
|
3470
3494
|
else:
|
3471
3495
|
response = self.publicSpotGetV2SpotMarketCandles(self.extend(request, params))
|
3472
3496
|
else:
|
3473
|
-
maxDistanceDaysForContracts = 90 # for contract, maximum 90 days allowed between start-end times
|
3474
|
-
# only correct the request to fix 90 days if until was auto-calculated
|
3475
|
-
if sinceDefined:
|
3476
|
-
if not untilDefined:
|
3477
|
-
request['endTime'] = min(calculatedEndTime, self.sum(since, maxDistanceDaysForContracts * msInDay))
|
3478
|
-
elif calculatedEndTime - calculatedStartTime > maxDistanceDaysForContracts * msInDay:
|
3479
|
-
raise BadRequest(self.id + ' fetchOHLCV() between start and end must be less than ' + str(maxDistanceDaysForContracts) + ' days')
|
3480
3497
|
priceType = None
|
3481
3498
|
priceType, params = self.handle_param_string(params, 'price')
|
3482
3499
|
productType = None
|
@@ -3489,7 +3506,7 @@ class bitget(Exchange, ImplicitAPI):
|
|
3489
3506
|
elif priceType == 'index':
|
3490
3507
|
response = self.publicMixGetV2MixMarketHistoryIndexCandles(extended)
|
3491
3508
|
else:
|
3492
|
-
if historicalEndpointNeeded
|
3509
|
+
if historicalEndpointNeeded:
|
3493
3510
|
response = self.publicMixGetV2MixMarketHistoryCandles(extended)
|
3494
3511
|
else:
|
3495
3512
|
response = self.publicMixGetV2MixMarketCandles(extended)
|
@@ -6443,9 +6460,11 @@ class bitget(Exchange, ImplicitAPI):
|
|
6443
6460
|
fetch the current funding rate
|
6444
6461
|
|
6445
6462
|
https://www.bitget.com/api-doc/contract/market/Get-Current-Funding-Rate
|
6463
|
+
https://www.bitget.com/api-doc/contract/market/Get-Symbol-Next-Funding-Time
|
6446
6464
|
|
6447
6465
|
:param str symbol: unified market symbol
|
6448
6466
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
6467
|
+
:param str [params.method]: either(default) 'publicMixGetV2MixMarketCurrentFundRate' or 'publicMixGetV2MixMarketFundingTime'
|
6449
6468
|
:returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
6450
6469
|
"""
|
6451
6470
|
self.load_markets()
|
@@ -6458,21 +6477,45 @@ class bitget(Exchange, ImplicitAPI):
|
|
6458
6477
|
'symbol': market['id'],
|
6459
6478
|
'productType': productType,
|
6460
6479
|
}
|
6461
|
-
|
6462
|
-
|
6463
|
-
|
6464
|
-
|
6465
|
-
|
6466
|
-
|
6467
|
-
|
6468
|
-
|
6469
|
-
|
6470
|
-
|
6471
|
-
|
6472
|
-
|
6473
|
-
|
6474
|
-
|
6475
|
-
|
6480
|
+
method = None
|
6481
|
+
method, params = self.handle_option_and_params(params, 'fetchFundingRate', 'method', 'publicMixGetV2MixMarketCurrentFundRate')
|
6482
|
+
response = None
|
6483
|
+
if method == 'publicMixGetV2MixMarketCurrentFundRate':
|
6484
|
+
response = self.publicMixGetV2MixMarketCurrentFundRate(self.extend(request, params))
|
6485
|
+
#
|
6486
|
+
# {
|
6487
|
+
# "code": "00000",
|
6488
|
+
# "msg": "success",
|
6489
|
+
# "requestTime": 1745500709429,
|
6490
|
+
# "data": [
|
6491
|
+
# {
|
6492
|
+
# "symbol": "BTCUSDT",
|
6493
|
+
# "fundingRate": "-0.000013",
|
6494
|
+
# "fundingRateInterval": "8",
|
6495
|
+
# "nextUpdate": "1745510400000",
|
6496
|
+
# "minFundingRate": "-0.003",
|
6497
|
+
# "maxFundingRate": "0.003"
|
6498
|
+
# }
|
6499
|
+
# ]
|
6500
|
+
# }
|
6501
|
+
#
|
6502
|
+
elif method == 'publicMixGetV2MixMarketFundingTime':
|
6503
|
+
response = self.publicMixGetV2MixMarketFundingTime(self.extend(request, params))
|
6504
|
+
#
|
6505
|
+
# {
|
6506
|
+
# "code": "00000",
|
6507
|
+
# "msg": "success",
|
6508
|
+
# "requestTime": 1745402092428,
|
6509
|
+
# "data": [
|
6510
|
+
# {
|
6511
|
+
# "symbol": "BTCUSDT",
|
6512
|
+
# "nextFundingTime": "1745424000000",
|
6513
|
+
# "ratePeriod": "8"
|
6514
|
+
# }
|
6515
|
+
# ]
|
6516
|
+
# }
|
6517
|
+
#
|
6518
|
+
data = self.safe_list(response, 'data', [])
|
6476
6519
|
return self.parse_funding_rate(data[0], market)
|
6477
6520
|
|
6478
6521
|
def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
|
@@ -6535,11 +6578,23 @@ class bitget(Exchange, ImplicitAPI):
|
|
6535
6578
|
|
6536
6579
|
def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
|
6537
6580
|
#
|
6538
|
-
# fetchFundingRate
|
6581
|
+
# fetchFundingRate: publicMixGetV2MixMarketCurrentFundRate
|
6539
6582
|
#
|
6540
6583
|
# {
|
6541
6584
|
# "symbol": "BTCUSDT",
|
6542
|
-
# "fundingRate": "-0.
|
6585
|
+
# "fundingRate": "-0.000013",
|
6586
|
+
# "fundingRateInterval": "8",
|
6587
|
+
# "nextUpdate": "1745510400000",
|
6588
|
+
# "minFundingRate": "-0.003",
|
6589
|
+
# "maxFundingRate": "0.003"
|
6590
|
+
# }
|
6591
|
+
#
|
6592
|
+
# fetchFundingRate: publicMixGetV2MixMarketFundingTime
|
6593
|
+
#
|
6594
|
+
# {
|
6595
|
+
# "symbol": "BTCUSDT",
|
6596
|
+
# "nextFundingTime": "1745424000000",
|
6597
|
+
# "ratePeriod": "8"
|
6543
6598
|
# }
|
6544
6599
|
#
|
6545
6600
|
# fetchFundingInterval
|
@@ -6549,7 +6604,9 @@ class bitget(Exchange, ImplicitAPI):
|
|
6549
6604
|
# "nextFundingTime": "1727942400000",
|
6550
6605
|
# "ratePeriod": "8"
|
6551
6606
|
# }
|
6607
|
+
#
|
6552
6608
|
# fetchFundingRates
|
6609
|
+
#
|
6553
6610
|
# {
|
6554
6611
|
# "symbol": "BTCUSD",
|
6555
6612
|
# "lastPr": "29904.5",
|
@@ -6575,10 +6632,11 @@ class bitget(Exchange, ImplicitAPI):
|
|
6575
6632
|
# "open24h": "0",
|
6576
6633
|
# "markPrice": "12345"
|
6577
6634
|
# }
|
6635
|
+
#
|
6578
6636
|
marketId = self.safe_string(contract, 'symbol')
|
6579
6637
|
symbol = self.safe_symbol(marketId, market, None, 'swap')
|
6580
|
-
fundingTimestamp = self.
|
6581
|
-
interval = self.
|
6638
|
+
fundingTimestamp = self.safe_integer_2(contract, 'nextFundingTime', 'nextUpdate')
|
6639
|
+
interval = self.safe_string_2(contract, 'ratePeriod', 'fundingRateInterval')
|
6582
6640
|
timestamp = self.safe_integer(contract, 'ts')
|
6583
6641
|
markPrice = self.safe_number(contract, 'markPrice')
|
6584
6642
|
indexPrice = self.safe_number(contract, 'indexPrice')
|
ccxt/bitmart.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.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
|
-
def fetch_positions(self, symbols: Strings = None, params={}):
|
4661
|
+
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 = self.
|
4683
|
+
response = self.privateGetContractPrivatePositionV2(self.extend(request, params))
|
4679
4684
|
#
|
4680
4685
|
# {
|
4681
4686
|
# "code": 1000,
|
ccxt/bitmex.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.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
|
-
def fetch_positions(self, symbols: Strings = None, params={}):
|
2192
|
+
def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
|
2186
2193
|
"""
|
2187
2194
|
fetch all open positions
|
2188
2195
|
|