ccxt 4.4.12__py2.py3-none-any.whl → 4.4.14__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/binance.py +1 -0
- ccxt/abstract/binancecoinm.py +1 -0
- ccxt/abstract/binanceus.py +1 -0
- ccxt/abstract/binanceusdm.py +1 -0
- ccxt/abstract/cryptocom.py +1 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +37 -1
- ccxt/async_support/bigone.py +2 -0
- ccxt/async_support/binance.py +113 -12
- ccxt/async_support/bingx.py +69 -3
- ccxt/async_support/bitget.py +102 -3
- ccxt/async_support/bitmex.py +1 -0
- ccxt/async_support/bitrue.py +1 -7
- ccxt/async_support/bitvavo.py +1 -3
- ccxt/async_support/bybit.py +2 -0
- ccxt/async_support/coinbaseinternational.py +2 -0
- ccxt/async_support/coinex.py +15 -1
- ccxt/async_support/cryptocom.py +1 -0
- ccxt/async_support/delta.py +2 -0
- ccxt/async_support/deribit.py +2 -0
- ccxt/async_support/digifinex.py +15 -1
- ccxt/async_support/gate.py +2 -0
- ccxt/async_support/htx.py +2 -2
- ccxt/async_support/huobijp.py +1 -3
- ccxt/async_support/krakenfutures.py +2 -0
- ccxt/async_support/kucoin.py +36 -1
- ccxt/async_support/kucoinfutures.py +56 -3
- ccxt/async_support/mexc.py +52 -8
- ccxt/async_support/okx.py +48 -0
- ccxt/async_support/oxfun.py +1 -0
- ccxt/async_support/paradex.py +1 -0
- ccxt/async_support/poloniex.py +1 -0
- ccxt/async_support/poloniexfutures.py +35 -11
- ccxt/async_support/woo.py +12 -0
- ccxt/async_support/woofipro.py +12 -0
- ccxt/async_support/xt.py +12 -0
- ccxt/base/exchange.py +44 -2
- ccxt/base/types.py +2 -0
- ccxt/bigone.py +2 -0
- ccxt/binance.py +113 -12
- ccxt/bingx.py +69 -3
- ccxt/bitget.py +102 -3
- ccxt/bitmex.py +1 -0
- ccxt/bitrue.py +1 -7
- ccxt/bitvavo.py +1 -3
- ccxt/bybit.py +2 -0
- ccxt/coinbaseinternational.py +2 -0
- ccxt/coinex.py +15 -1
- ccxt/cryptocom.py +1 -0
- ccxt/delta.py +2 -0
- ccxt/deribit.py +2 -0
- ccxt/digifinex.py +15 -1
- ccxt/gate.py +2 -0
- ccxt/htx.py +2 -2
- ccxt/huobijp.py +1 -3
- ccxt/krakenfutures.py +2 -0
- ccxt/kucoin.py +36 -1
- ccxt/kucoinfutures.py +56 -3
- ccxt/mexc.py +52 -8
- ccxt/okx.py +48 -0
- ccxt/oxfun.py +1 -0
- ccxt/paradex.py +1 -0
- ccxt/poloniex.py +1 -0
- ccxt/poloniexfutures.py +35 -11
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +72 -5
- ccxt/pro/bitfinex.py +8 -8
- ccxt/pro/krakenfutures.py +2 -0
- ccxt/pro/okx.py +38 -0
- ccxt/pro/phemex.py +2 -0
- ccxt/pro/woo.py +69 -0
- ccxt/test/tests_async.py +76 -48
- ccxt/test/tests_helpers.py +27 -36
- ccxt/test/tests_init.py +6 -2
- ccxt/test/tests_sync.py +76 -48
- ccxt/woo.py +12 -0
- ccxt/woofipro.py +12 -0
- ccxt/xt.py +12 -0
- {ccxt-4.4.12.dist-info → ccxt-4.4.14.dist-info}/METADATA +4 -5
- {ccxt-4.4.12.dist-info → ccxt-4.4.14.dist-info}/RECORD +84 -84
- {ccxt-4.4.12.dist-info → ccxt-4.4.14.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.12.dist-info → ccxt-4.4.14.dist-info}/WHEEL +0 -0
- {ccxt-4.4.12.dist-info → ccxt-4.4.14.dist-info}/top_level.txt +0 -0
ccxt/mexc.py
CHANGED
@@ -89,6 +89,8 @@ class mexc(Exchange, ImplicitAPI):
|
|
89
89
|
'fetchDepositWithdrawFee': 'emulated',
|
90
90
|
'fetchDepositWithdrawFees': True,
|
91
91
|
'fetchFundingHistory': True,
|
92
|
+
'fetchFundingInterval': True,
|
93
|
+
'fetchFundingIntervals': False,
|
92
94
|
'fetchFundingRate': True,
|
93
95
|
'fetchFundingRateHistory': True,
|
94
96
|
'fetchFundingRates': None,
|
@@ -2468,6 +2470,7 @@ class mexc(Exchange, ImplicitAPI):
|
|
2468
2470
|
:param int [since]: the earliest time in ms to fetch orders for
|
2469
2471
|
:param int [limit]: the maximum number of order structures to retrieve
|
2470
2472
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2473
|
+
:param int [params.until]: the latest time in ms to fetch orders for
|
2471
2474
|
:param str [params.marginMode]: only 'isolated' is supported, for spot-margin trading
|
2472
2475
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
2473
2476
|
"""
|
@@ -2477,6 +2480,8 @@ class mexc(Exchange, ImplicitAPI):
|
|
2477
2480
|
if symbol is not None:
|
2478
2481
|
market = self.market(symbol)
|
2479
2482
|
request['symbol'] = market['id']
|
2483
|
+
until = self.safe_integer(params, 'until')
|
2484
|
+
params = self.omit(params, 'until')
|
2480
2485
|
marketType, query = self.handle_market_type_and_params('fetchOrders', market, params)
|
2481
2486
|
if marketType == 'spot':
|
2482
2487
|
if symbol is None:
|
@@ -2484,6 +2489,8 @@ class mexc(Exchange, ImplicitAPI):
|
|
2484
2489
|
marginMode, queryInner = self.handle_margin_mode_and_params('fetchOrders', params)
|
2485
2490
|
if since is not None:
|
2486
2491
|
request['startTime'] = since
|
2492
|
+
if until is not None:
|
2493
|
+
request['endTime'] = until
|
2487
2494
|
if limit is not None:
|
2488
2495
|
request['limit'] = limit
|
2489
2496
|
response = None
|
@@ -2545,9 +2552,17 @@ class mexc(Exchange, ImplicitAPI):
|
|
2545
2552
|
else:
|
2546
2553
|
if since is not None:
|
2547
2554
|
request['start_time'] = since
|
2548
|
-
end = self.safe_integer(params, 'end_time')
|
2555
|
+
end = self.safe_integer(params, 'end_time', until)
|
2549
2556
|
if end is None:
|
2550
2557
|
request['end_time'] = self.sum(since, self.options['maxTimeTillEnd'])
|
2558
|
+
else:
|
2559
|
+
if (end - since) > self.options['maxTimeTillEnd']:
|
2560
|
+
raise BadRequest(self.id + ' end is invalid, i.e. exceeds allowed 90 days.')
|
2561
|
+
else:
|
2562
|
+
request['end_time'] = until
|
2563
|
+
elif until is not None:
|
2564
|
+
request['start_time'] = self.sum(until, self.options['maxTimeTillEnd'] * -1)
|
2565
|
+
request['end_time'] = until
|
2551
2566
|
if limit is not None:
|
2552
2567
|
request['page_size'] = limit
|
2553
2568
|
method = self.safe_string(self.options, 'fetchOrders', 'contractPrivateGetOrderListHistoryOrders')
|
@@ -3937,9 +3952,12 @@ class mexc(Exchange, ImplicitAPI):
|
|
3937
3952
|
nextFundingRate = self.safe_number(contract, 'fundingRate')
|
3938
3953
|
nextFundingTimestamp = self.safe_integer(contract, 'nextSettleTime')
|
3939
3954
|
marketId = self.safe_string(contract, 'symbol')
|
3940
|
-
symbol = self.safe_symbol(marketId, market)
|
3955
|
+
symbol = self.safe_symbol(marketId, market, None, 'contract')
|
3941
3956
|
timestamp = self.safe_integer(contract, 'timestamp')
|
3942
|
-
|
3957
|
+
interval = self.safe_string(contract, 'collectCycle')
|
3958
|
+
intervalString = None
|
3959
|
+
if interval is not None:
|
3960
|
+
intervalString = interval + 'h'
|
3943
3961
|
return {
|
3944
3962
|
'info': contract,
|
3945
3963
|
'symbol': symbol,
|
@@ -3948,7 +3966,7 @@ class mexc(Exchange, ImplicitAPI):
|
|
3948
3966
|
'interestRate': None,
|
3949
3967
|
'estimatedSettlePrice': None,
|
3950
3968
|
'timestamp': timestamp,
|
3951
|
-
'datetime':
|
3969
|
+
'datetime': self.iso8601(timestamp),
|
3952
3970
|
'fundingRate': nextFundingRate,
|
3953
3971
|
'fundingTimestamp': nextFundingTimestamp,
|
3954
3972
|
'fundingDatetime': self.iso8601(nextFundingTimestamp),
|
@@ -3958,9 +3976,19 @@ class mexc(Exchange, ImplicitAPI):
|
|
3958
3976
|
'previousFundingRate': None,
|
3959
3977
|
'previousFundingTimestamp': None,
|
3960
3978
|
'previousFundingDatetime': None,
|
3961
|
-
'interval':
|
3979
|
+
'interval': intervalString,
|
3962
3980
|
}
|
3963
3981
|
|
3982
|
+
def fetch_funding_interval(self, symbol: str, params={}) -> FundingRate:
|
3983
|
+
"""
|
3984
|
+
fetch the current funding rate interval
|
3985
|
+
:see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-contract-funding-rate
|
3986
|
+
:param str symbol: unified market symbol
|
3987
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3988
|
+
:returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
3989
|
+
"""
|
3990
|
+
return self.fetch_funding_rate(symbol, params)
|
3991
|
+
|
3964
3992
|
def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
|
3965
3993
|
"""
|
3966
3994
|
fetch the current funding rate
|
@@ -4229,7 +4257,15 @@ class mexc(Exchange, ImplicitAPI):
|
|
4229
4257
|
networkCode = self.safe_string(params, 'network')
|
4230
4258
|
networkId = None
|
4231
4259
|
if networkCode is not None:
|
4232
|
-
|
4260
|
+
# createDepositAddress and fetchDepositAddress use a different network-id compared to withdraw
|
4261
|
+
networkUnified = self.network_id_to_code(networkCode, code)
|
4262
|
+
networks = self.safe_dict(currency, 'networks', {})
|
4263
|
+
if networkUnified in networks:
|
4264
|
+
network = self.safe_dict(networks, networkUnified, {})
|
4265
|
+
networkInfo = self.safe_value(network, 'info', {})
|
4266
|
+
networkId = self.safe_string(networkInfo, 'network')
|
4267
|
+
else:
|
4268
|
+
networkId = self.network_code_to_id(networkCode, code)
|
4233
4269
|
if networkId is not None:
|
4234
4270
|
request['network'] = networkId
|
4235
4271
|
params = self.omit(params, 'network')
|
@@ -4265,7 +4301,16 @@ class mexc(Exchange, ImplicitAPI):
|
|
4265
4301
|
networkCode = self.safe_string(params, 'network')
|
4266
4302
|
if networkCode is None:
|
4267
4303
|
raise ArgumentsRequired(self.id + ' createDepositAddress requires a `network` parameter')
|
4268
|
-
|
4304
|
+
# createDepositAddress and fetchDepositAddress use a different network-id compared to withdraw
|
4305
|
+
networkId = None
|
4306
|
+
networkUnified = self.network_id_to_code(networkCode, code)
|
4307
|
+
networks = self.safe_dict(currency, 'networks', {})
|
4308
|
+
if networkUnified in networks:
|
4309
|
+
network = self.safe_dict(networks, networkUnified, {})
|
4310
|
+
networkInfo = self.safe_value(network, 'info', {})
|
4311
|
+
networkId = self.safe_string(networkInfo, 'network')
|
4312
|
+
else:
|
4313
|
+
networkId = self.network_code_to_id(networkCode, code)
|
4269
4314
|
if networkId is not None:
|
4270
4315
|
request['network'] = networkId
|
4271
4316
|
params = self.omit(params, 'network')
|
@@ -4288,7 +4333,6 @@ class mexc(Exchange, ImplicitAPI):
|
|
4288
4333
|
:returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
|
4289
4334
|
"""
|
4290
4335
|
network = self.safe_string(params, 'network')
|
4291
|
-
params = self.omit(params, ['network'])
|
4292
4336
|
addressStructures = self.fetch_deposit_addresses_by_network(code, params)
|
4293
4337
|
result = None
|
4294
4338
|
if network is not None:
|
ccxt/okx.py
CHANGED
@@ -104,6 +104,8 @@ class okx(Exchange, ImplicitAPI):
|
|
104
104
|
'fetchDepositWithdrawFee': 'emulated',
|
105
105
|
'fetchDepositWithdrawFees': True,
|
106
106
|
'fetchFundingHistory': True,
|
107
|
+
'fetchFundingInterval': True,
|
108
|
+
'fetchFundingIntervals': False,
|
107
109
|
'fetchFundingRate': True,
|
108
110
|
'fetchFundingRateHistory': True,
|
109
111
|
'fetchFundingRates': False,
|
@@ -120,6 +122,7 @@ class okx(Exchange, ImplicitAPI):
|
|
120
122
|
'fetchMarketLeverageTiers': True,
|
121
123
|
'fetchMarkets': True,
|
122
124
|
'fetchMarkOHLCV': True,
|
125
|
+
'fetchMarkPrices': True,
|
123
126
|
'fetchMySettlementHistory': False,
|
124
127
|
'fetchMyTrades': True,
|
125
128
|
'fetchOHLCV': True,
|
@@ -1784,6 +1787,13 @@ class okx(Exchange, ImplicitAPI):
|
|
1784
1787
|
return self.parse_order_book(first, symbol, timestamp)
|
1785
1788
|
|
1786
1789
|
def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
|
1790
|
+
#
|
1791
|
+
# {
|
1792
|
+
# "instType":"SWAP",
|
1793
|
+
# "instId":"BTC-USDT-SWAP",
|
1794
|
+
# "markPx":"200",
|
1795
|
+
# "ts":"1597026383085"
|
1796
|
+
# }
|
1787
1797
|
#
|
1788
1798
|
# {
|
1789
1799
|
# "instType": "SPOT",
|
@@ -1835,6 +1845,7 @@ class okx(Exchange, ImplicitAPI):
|
|
1835
1845
|
'average': None,
|
1836
1846
|
'baseVolume': baseVolume,
|
1837
1847
|
'quoteVolume': quoteVolume,
|
1848
|
+
'markPrice': self.safe_string(ticker, 'markPx'),
|
1838
1849
|
'info': ticker,
|
1839
1850
|
}, market)
|
1840
1851
|
|
@@ -1935,6 +1946,33 @@ class okx(Exchange, ImplicitAPI):
|
|
1935
1946
|
tickers = self.safe_list(response, 'data', [])
|
1936
1947
|
return self.parse_tickers(tickers, symbols)
|
1937
1948
|
|
1949
|
+
def fetch_mark_prices(self, symbols: Strings = None, params={}) -> Tickers:
|
1950
|
+
"""
|
1951
|
+
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
1952
|
+
:see: https://www.okx.com/docs-v5/en/#public-data-rest-api-get-mark-price
|
1953
|
+
:param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
1954
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1955
|
+
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
1956
|
+
"""
|
1957
|
+
self.load_markets()
|
1958
|
+
symbols = self.market_symbols(symbols)
|
1959
|
+
market = self.get_market_from_symbols(symbols)
|
1960
|
+
marketType = None
|
1961
|
+
marketType, params = self.handle_market_type_and_params('fetchTickers', market, params, 'swap')
|
1962
|
+
request: dict = {
|
1963
|
+
'instType': self.convert_to_instrument_type(marketType),
|
1964
|
+
}
|
1965
|
+
if marketType == 'option':
|
1966
|
+
defaultUnderlying = self.safe_string(self.options, 'defaultUnderlying', 'BTC-USD')
|
1967
|
+
currencyId = self.safe_string_2(params, 'uly', 'marketId', defaultUnderlying)
|
1968
|
+
if currencyId is None:
|
1969
|
+
raise ArgumentsRequired(self.id + ' fetchTickers() requires an underlying uly or marketId parameter for options markets')
|
1970
|
+
else:
|
1971
|
+
request['uly'] = currencyId
|
1972
|
+
response = self.publicGetPublicMarkPrice(self.extend(request, params))
|
1973
|
+
tickers = self.safe_list(response, 'data', [])
|
1974
|
+
return self.parse_tickers(tickers, symbols)
|
1975
|
+
|
1938
1976
|
def parse_trade(self, trade: dict, market: Market = None) -> Trade:
|
1939
1977
|
#
|
1940
1978
|
# public fetchTrades
|
@@ -5689,6 +5727,16 @@ class okx(Exchange, ImplicitAPI):
|
|
5689
5727
|
}
|
5690
5728
|
return self.safe_string(intervals, interval, interval)
|
5691
5729
|
|
5730
|
+
def fetch_funding_interval(self, symbol: str, params={}) -> FundingRate:
|
5731
|
+
"""
|
5732
|
+
fetch the current funding rate interval
|
5733
|
+
:see: https://www.okx.com/docs-v5/en/#public-data-rest-api-get-funding-rate
|
5734
|
+
:param str symbol: unified market symbol
|
5735
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
5736
|
+
:returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
5737
|
+
"""
|
5738
|
+
return self.fetch_funding_rate(symbol, params)
|
5739
|
+
|
5692
5740
|
def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
|
5693
5741
|
"""
|
5694
5742
|
fetch the current funding rate
|
ccxt/oxfun.py
CHANGED
@@ -858,6 +858,7 @@ class oxfun(Exchange, ImplicitAPI):
|
|
858
858
|
'average': None,
|
859
859
|
'baseVolume': self.safe_string(ticker, 'currencyVolume24h'),
|
860
860
|
'quoteVolume': None, # the exchange returns cost in OX
|
861
|
+
'markPrice': self.safe_string(ticker, 'markPrice'),
|
861
862
|
'info': ticker,
|
862
863
|
}, market)
|
863
864
|
|
ccxt/paradex.py
CHANGED
ccxt/poloniex.py
CHANGED
@@ -633,6 +633,7 @@ class poloniex(Exchange, ImplicitAPI):
|
|
633
633
|
'average': None,
|
634
634
|
'baseVolume': self.safe_string(ticker, 'quantity'),
|
635
635
|
'quoteVolume': self.safe_string(ticker, 'amount'),
|
636
|
+
'markPrice': self.safe_string(ticker, 'markPrice'),
|
636
637
|
'info': ticker,
|
637
638
|
}, market)
|
638
639
|
|
ccxt/poloniexfutures.py
CHANGED
@@ -48,6 +48,8 @@ class poloniexfutures(Exchange, ImplicitAPI):
|
|
48
48
|
'fetchDepositAddress': False,
|
49
49
|
'fetchDepositAddresses': False,
|
50
50
|
'fetchDepositAddressesByNetwork': False,
|
51
|
+
'fetchFundingInterval': True,
|
52
|
+
'fetchFundingIntervals': False,
|
51
53
|
'fetchFundingRate': True,
|
52
54
|
'fetchFundingRateHistory': False,
|
53
55
|
'fetchL3OrderBook': True,
|
@@ -1550,28 +1552,50 @@ class poloniexfutures(Exchange, ImplicitAPI):
|
|
1550
1552
|
# "predictedValue": 0.00375
|
1551
1553
|
# }
|
1552
1554
|
#
|
1553
|
-
data = self.
|
1555
|
+
data = self.safe_dict(response, 'data', {})
|
1556
|
+
return self.parse_funding_rate(data, market)
|
1557
|
+
|
1558
|
+
def fetch_funding_interval(self, symbol: str, params={}) -> FundingRate:
|
1559
|
+
"""
|
1560
|
+
fetch the current funding rate interval
|
1561
|
+
:see: https://api-docs.poloniex.com/futures/api/futures-index#get-premium-index
|
1562
|
+
:param str symbol: unified market symbol
|
1563
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1564
|
+
:returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
1565
|
+
"""
|
1566
|
+
return self.fetch_funding_rate(symbol, params)
|
1567
|
+
|
1568
|
+
def parse_funding_rate(self, data, market: Market = None) -> FundingRate:
|
1569
|
+
#
|
1570
|
+
# {
|
1571
|
+
# "symbol": ".ETHUSDTMFPI8H",
|
1572
|
+
# "granularity": 28800000,
|
1573
|
+
# "timePoint": 1637380800000,
|
1574
|
+
# "value": 0.0001,
|
1575
|
+
# "predictedValue": 0.0001,
|
1576
|
+
# }
|
1577
|
+
#
|
1554
1578
|
fundingTimestamp = self.safe_integer(data, 'timePoint')
|
1555
|
-
|
1579
|
+
marketId = self.safe_string(data, 'symbol')
|
1556
1580
|
return {
|
1557
1581
|
'info': data,
|
1558
|
-
'symbol': market
|
1582
|
+
'symbol': self.safe_symbol(marketId, market, None, 'contract'),
|
1559
1583
|
'markPrice': None,
|
1560
1584
|
'indexPrice': None,
|
1561
1585
|
'interestRate': None,
|
1562
1586
|
'estimatedSettlePrice': None,
|
1563
1587
|
'timestamp': None,
|
1564
1588
|
'datetime': None,
|
1565
|
-
'fundingRate': self.safe_number(data, '
|
1566
|
-
'fundingTimestamp':
|
1567
|
-
'fundingDatetime':
|
1568
|
-
'nextFundingRate':
|
1589
|
+
'fundingRate': self.safe_number(data, 'value'),
|
1590
|
+
'fundingTimestamp': fundingTimestamp,
|
1591
|
+
'fundingDatetime': self.iso8601(fundingTimestamp),
|
1592
|
+
'nextFundingRate': self.safe_number(data, 'predictedValue'),
|
1569
1593
|
'nextFundingTimestamp': None,
|
1570
1594
|
'nextFundingDatetime': None,
|
1571
|
-
'previousFundingRate':
|
1572
|
-
'previousFundingTimestamp':
|
1573
|
-
'previousFundingDatetime':
|
1574
|
-
'interval': self.parse_funding_interval(self.safe_string(data, '
|
1595
|
+
'previousFundingRate': None,
|
1596
|
+
'previousFundingTimestamp': None,
|
1597
|
+
'previousFundingDatetime': None,
|
1598
|
+
'interval': self.parse_funding_interval(self.safe_string(data, 'granularity')),
|
1575
1599
|
}
|
1576
1600
|
|
1577
1601
|
def parse_funding_interval(self, interval):
|
ccxt/pro/__init__.py
CHANGED
ccxt/pro/binance.py
CHANGED
@@ -43,6 +43,8 @@ class binance(ccxt.async_support.binance):
|
|
43
43
|
'watchPositions': True,
|
44
44
|
'watchTicker': True,
|
45
45
|
'watchTickers': True,
|
46
|
+
'watchMarkPrices': True,
|
47
|
+
'watchMarkPrice': True,
|
46
48
|
'watchTrades': True,
|
47
49
|
'watchTradesForSymbols': True,
|
48
50
|
'createOrderWs': True,
|
@@ -159,6 +161,7 @@ class binance(ccxt.async_support.binance):
|
|
159
161
|
'tickerChannelsMap': {
|
160
162
|
'24hrTicker': 'ticker',
|
161
163
|
'24hrMiniTicker': 'miniTicker',
|
164
|
+
'markPriceUpdate': 'markPrice',
|
162
165
|
# rolling window tickers
|
163
166
|
'1hTicker': 'ticker_1h',
|
164
167
|
'4hTicker': 'ticker_4h',
|
@@ -1641,6 +1644,39 @@ class binance(ccxt.async_support.binance):
|
|
1641
1644
|
tickers = await self.watch_tickers([symbol], self.extend(params, {'callerMethodName': 'watchTicker'}))
|
1642
1645
|
return tickers[symbol]
|
1643
1646
|
|
1647
|
+
async def watch_mark_price(self, symbol: str, params={}) -> Ticker:
|
1648
|
+
"""
|
1649
|
+
:see: https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Mark-Price-Stream
|
1650
|
+
watches a mark price for a specific market
|
1651
|
+
:param str symbol: unified symbol of the market to fetch the ticker for
|
1652
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1653
|
+
:param boolean [params.use1sFreq]: *default is True* if set to True, the mark price will be updated every second, otherwise every 3 seconds
|
1654
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
1655
|
+
"""
|
1656
|
+
await self.load_markets()
|
1657
|
+
symbol = self.symbol(symbol)
|
1658
|
+
tickers = await self.watch_mark_prices([symbol], self.extend(params, {'callerMethodName': 'watchMarkPrice'}))
|
1659
|
+
return tickers[symbol]
|
1660
|
+
|
1661
|
+
async def watch_mark_prices(self, symbols: Strings = None, params={}) -> Tickers:
|
1662
|
+
"""
|
1663
|
+
:see: https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Mark-Price-Stream-for-All-market
|
1664
|
+
watches the mark price for all markets
|
1665
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
1666
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1667
|
+
:param boolean [params.use1sFreq]: *default is True* if set to True, the mark price will be updated every second, otherwise every 3 seconds
|
1668
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
1669
|
+
"""
|
1670
|
+
channelName = None
|
1671
|
+
# for now watchmarkPrice uses the same messageHash
|
1672
|
+
# so it's impossible to watch both at the same time
|
1673
|
+
# refactor self to use different messageHashes
|
1674
|
+
channelName, params = self.handle_option_and_params(params, 'watchMarkPrices', 'name', 'markPrice')
|
1675
|
+
newTickers = await self.watch_multi_ticker_helper('watchMarkPrices', channelName, symbols, params)
|
1676
|
+
if self.newUpdates:
|
1677
|
+
return newTickers
|
1678
|
+
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
1679
|
+
|
1644
1680
|
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
1645
1681
|
"""
|
1646
1682
|
:see: https://binance-docs.github.io/apidocs/spot/en/#individual-symbol-mini-ticker-stream
|
@@ -1775,12 +1811,16 @@ class binance(ccxt.async_support.binance):
|
|
1775
1811
|
async def watch_multi_ticker_helper(self, methodName, channelName: str, symbols: Strings = None, params={}):
|
1776
1812
|
await self.load_markets()
|
1777
1813
|
symbols = self.market_symbols(symbols, None, True, False, True)
|
1814
|
+
isBidAsk = (channelName == 'bookTicker')
|
1815
|
+
isMarkPrice = (channelName == 'markPrice')
|
1816
|
+
use1sFreq = self.safe_bool(params, 'use1sFreq', True)
|
1778
1817
|
firstMarket = None
|
1779
1818
|
marketType = None
|
1780
1819
|
symbolsDefined = (symbols is not None)
|
1781
1820
|
if symbolsDefined:
|
1782
1821
|
firstMarket = self.market(symbols[0])
|
1783
|
-
|
1822
|
+
defaultMarket = 'swap' if (isMarkPrice) else 'spot'
|
1823
|
+
marketType, params = self.handle_market_type_and_params(methodName, firstMarket, params, defaultMarket)
|
1784
1824
|
subType = None
|
1785
1825
|
subType, params = self.handle_sub_type_and_params(methodName, firstMarket, params)
|
1786
1826
|
rawMarketType = None
|
@@ -1792,20 +1832,24 @@ class binance(ccxt.async_support.binance):
|
|
1792
1832
|
rawMarketType = marketType
|
1793
1833
|
else:
|
1794
1834
|
raise NotSupported(self.id + ' ' + methodName + '() does not support options markets')
|
1795
|
-
isBidAsk = (channelName == 'bookTicker')
|
1796
1835
|
subscriptionArgs = []
|
1797
1836
|
messageHashes = []
|
1837
|
+
suffix = ''
|
1838
|
+
if isMarkPrice:
|
1839
|
+
suffix = '@1s' if (use1sFreq) else ''
|
1798
1840
|
if symbolsDefined:
|
1799
1841
|
for i in range(0, len(symbols)):
|
1800
1842
|
symbol = symbols[i]
|
1801
1843
|
market = self.market(symbol)
|
1802
|
-
subscriptionArgs.append(market['lowercaseId'] + '@' + channelName)
|
1844
|
+
subscriptionArgs.append(market['lowercaseId'] + '@' + channelName + suffix)
|
1803
1845
|
messageHashes.append(self.get_message_hash(channelName, market['symbol'], isBidAsk))
|
1804
1846
|
else:
|
1805
1847
|
if isBidAsk:
|
1806
1848
|
if marketType == 'spot':
|
1807
1849
|
raise ArgumentsRequired(self.id + ' ' + methodName + '() requires symbols for self channel for spot markets')
|
1808
1850
|
subscriptionArgs.append('!' + channelName)
|
1851
|
+
elif isMarkPrice:
|
1852
|
+
subscriptionArgs.append('!' + channelName + '@arr' + suffix)
|
1809
1853
|
else:
|
1810
1854
|
subscriptionArgs.append('!' + channelName + '@arr')
|
1811
1855
|
messageHashes.append(self.get_message_hash(channelName, None, isBidAsk))
|
@@ -1833,6 +1877,17 @@ class binance(ccxt.async_support.binance):
|
|
1833
1877
|
return newDict
|
1834
1878
|
|
1835
1879
|
def parse_ws_ticker(self, message, marketType):
|
1880
|
+
# markPrice
|
1881
|
+
# {
|
1882
|
+
# "e": "markPriceUpdate", # Event type
|
1883
|
+
# "E": 1562305380000, # Event time
|
1884
|
+
# "s": "BTCUSDT", # Symbol
|
1885
|
+
# "p": "11794.15000000", # Mark price
|
1886
|
+
# "i": "11784.62659091", # Index price
|
1887
|
+
# "P": "11784.25641265", # Estimated Settle Price, only useful in the last hour before the settlement starts
|
1888
|
+
# "r": "0.00038167", # Funding rate
|
1889
|
+
# "T": 1562306400000 # Next funding time
|
1890
|
+
# }
|
1836
1891
|
#
|
1837
1892
|
# ticker
|
1838
1893
|
# {
|
@@ -1890,9 +1945,21 @@ class binance(ccxt.async_support.binance):
|
|
1890
1945
|
# "time":1589437530011,
|
1891
1946
|
# }
|
1892
1947
|
#
|
1948
|
+
marketId = self.safe_string_2(message, 's', 'symbol')
|
1949
|
+
symbol = self.safe_symbol(marketId, None, None, marketType)
|
1893
1950
|
event = self.safe_string(message, 'e', 'bookTicker')
|
1894
1951
|
if event == '24hrTicker':
|
1895
1952
|
event = 'ticker'
|
1953
|
+
if event == 'markPriceUpdate':
|
1954
|
+
# handle self separately because some fields clash with the ticker fields
|
1955
|
+
return self.safe_ticker({
|
1956
|
+
'symbol': symbol,
|
1957
|
+
'timestamp': self.safe_integer(message, 'E'),
|
1958
|
+
'datetime': self.iso8601(self.safe_integer(message, 'E')),
|
1959
|
+
'info': message,
|
1960
|
+
'markPrice': self.safe_string(message, 'p'),
|
1961
|
+
'indexPrice': self.safe_string(message, 'i'),
|
1962
|
+
})
|
1896
1963
|
timestamp = None
|
1897
1964
|
if event == 'bookTicker':
|
1898
1965
|
# take the event timestamp, if available, for spot tickers it is not
|
@@ -1900,8 +1967,6 @@ class binance(ccxt.async_support.binance):
|
|
1900
1967
|
else:
|
1901
1968
|
# take the timestamp of the closing price for candlestick streams
|
1902
1969
|
timestamp = self.safe_integer_n(message, ['C', 'E', 'time'])
|
1903
|
-
marketId = self.safe_string_2(message, 's', 'symbol')
|
1904
|
-
symbol = self.safe_symbol(marketId, None, None, marketType)
|
1905
1970
|
market = self.safe_market(marketId, None, None, marketType)
|
1906
1971
|
last = self.safe_string_2(message, 'c', 'price')
|
1907
1972
|
return self.safe_ticker({
|
@@ -3864,6 +3929,8 @@ class binance(ccxt.async_support.binance):
|
|
3864
3929
|
'1dTicker': self.handle_tickers,
|
3865
3930
|
'24hrTicker': self.handle_tickers,
|
3866
3931
|
'24hrMiniTicker': self.handle_tickers,
|
3932
|
+
'markPriceUpdate': self.handle_tickers,
|
3933
|
+
'markPriceUpdate@arr': self.handle_tickers,
|
3867
3934
|
'bookTicker': self.handle_bids_asks, # there is no "bookTicker@arr" endpoint
|
3868
3935
|
'outboundAccountPosition': self.handle_balance,
|
3869
3936
|
'balanceUpdate': self.handle_balance,
|
ccxt/pro/bitfinex.py
CHANGED
@@ -213,15 +213,15 @@ class bitfinex(ccxt.async_support.bitfinex):
|
|
213
213
|
open = None
|
214
214
|
if (last is not None) and (change is not None):
|
215
215
|
open = Precise.string_sub(last, change)
|
216
|
-
result = {
|
216
|
+
result = self.safe_ticker({
|
217
217
|
'symbol': symbol,
|
218
218
|
'timestamp': None,
|
219
219
|
'datetime': None,
|
220
|
-
'high': self.
|
221
|
-
'low': self.
|
222
|
-
'bid': self.
|
220
|
+
'high': self.safe_string(message, 9),
|
221
|
+
'low': self.safe_string(message, 10),
|
222
|
+
'bid': self.safe_string(message, 1),
|
223
223
|
'bidVolume': None,
|
224
|
-
'ask': self.
|
224
|
+
'ask': self.safe_string(message, 3),
|
225
225
|
'askVolume': None,
|
226
226
|
'vwap': None,
|
227
227
|
'open': self.parse_number(open),
|
@@ -229,12 +229,12 @@ class bitfinex(ccxt.async_support.bitfinex):
|
|
229
229
|
'last': self.parse_number(last),
|
230
230
|
'previousClose': None,
|
231
231
|
'change': self.parse_number(change),
|
232
|
-
'percentage': self.
|
232
|
+
'percentage': self.safe_string(message, 6),
|
233
233
|
'average': None,
|
234
|
-
'baseVolume': self.
|
234
|
+
'baseVolume': self.safe_string(message, 8),
|
235
235
|
'quoteVolume': None,
|
236
236
|
'info': message,
|
237
|
-
}
|
237
|
+
})
|
238
238
|
self.tickers[symbol] = result
|
239
239
|
client.resolve(result, messageHash)
|
240
240
|
|
ccxt/pro/krakenfutures.py
CHANGED
@@ -998,6 +998,8 @@ class krakenfutures(ccxt.async_support.krakenfutures):
|
|
998
998
|
'average': None,
|
999
999
|
'baseVolume': self.safe_string(ticker, 'volume'),
|
1000
1000
|
'quoteVolume': self.safe_string(ticker, 'volumeQuote'),
|
1001
|
+
'markPrice': self.safe_string(ticker, 'markPrice'),
|
1002
|
+
'indexPrice': self.safe_string(ticker, 'index'),
|
1001
1003
|
})
|
1002
1004
|
|
1003
1005
|
def handle_order_book_snapshot(self, client: Client, message):
|
ccxt/pro/okx.py
CHANGED
@@ -25,6 +25,8 @@ class okx(ccxt.async_support.okx):
|
|
25
25
|
'has': {
|
26
26
|
'ws': True,
|
27
27
|
'watchTicker': True,
|
28
|
+
'watchMarkPrice': True,
|
29
|
+
'watchMarkPrices': True,
|
28
30
|
'watchTickers': True,
|
29
31
|
'watchBidsAsks': True,
|
30
32
|
'watchOrderBook': True,
|
@@ -408,6 +410,41 @@ class okx(ccxt.async_support.okx):
|
|
408
410
|
return newTickers
|
409
411
|
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
410
412
|
|
413
|
+
async def watch_mark_price(self, symbol: str, params={}) -> Ticker:
|
414
|
+
"""
|
415
|
+
:see: https://www.okx.com/docs-v5/en/#public-data-websocket-mark-price-channel
|
416
|
+
watches a mark price
|
417
|
+
:param str symbol: unified symbol of the market to fetch the ticker for
|
418
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
419
|
+
:param str [params.channel]: the channel to subscribe to, tickers by default. Can be tickers, sprd-tickers, index-tickers, block-tickers
|
420
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
421
|
+
"""
|
422
|
+
channel = None
|
423
|
+
channel, params = self.handle_option_and_params(params, 'watchMarkPrice', 'channel', 'mark-price')
|
424
|
+
params['channel'] = channel
|
425
|
+
market = self.market(symbol)
|
426
|
+
symbol = market['symbol']
|
427
|
+
ticker = await self.watch_mark_prices([symbol], params)
|
428
|
+
return ticker[symbol]
|
429
|
+
|
430
|
+
async def watch_mark_prices(self, symbols: Strings = None, params={}) -> Tickers:
|
431
|
+
"""
|
432
|
+
:see: https://www.okx.com/docs-v5/en/#public-data-websocket-mark-price-channel
|
433
|
+
watches mark prices
|
434
|
+
:param str[] [symbols]: unified symbol of the market to fetch the ticker for
|
435
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
436
|
+
:param str [params.channel]: the channel to subscribe to, tickers by default. Can be tickers, sprd-tickers, index-tickers, block-tickers
|
437
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
438
|
+
"""
|
439
|
+
await self.load_markets()
|
440
|
+
symbols = self.market_symbols(symbols, None, False)
|
441
|
+
channel = None
|
442
|
+
channel, params = self.handle_option_and_params(params, 'watchMarkPrices', 'channel', 'mark-price')
|
443
|
+
newTickers = await self.subscribe_multiple('public', channel, symbols, params)
|
444
|
+
if self.newUpdates:
|
445
|
+
return newTickers
|
446
|
+
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
447
|
+
|
411
448
|
async def un_watch_tickers(self, symbols: Strings = None, params={}) -> Any:
|
412
449
|
"""
|
413
450
|
:see: https://www.okx.com/docs-v5/en/#order-book-trading-market-data-ws-tickers-channel
|
@@ -2157,6 +2194,7 @@ class okx(ccxt.async_support.okx):
|
|
2157
2194
|
'books50-l2-tbt': self.handle_order_book, # only users who're VIP4 and above can subscribe, identity verification required before subscription
|
2158
2195
|
'books-l2-tbt': self.handle_order_book, # only users who're VIP5 and above can subscribe, identity verification required before subscription
|
2159
2196
|
'tickers': self.handle_ticker,
|
2197
|
+
'mark-price': self.handle_ticker,
|
2160
2198
|
'positions': self.handle_positions,
|
2161
2199
|
'index-tickers': self.handle_ticker,
|
2162
2200
|
'sprd-tickers': self.handle_ticker,
|
ccxt/pro/phemex.py
CHANGED
@@ -132,6 +132,8 @@ class phemex(ccxt.async_support.phemex):
|
|
132
132
|
'average': average,
|
133
133
|
'baseVolume': baseVolume,
|
134
134
|
'quoteVolume': quoteVolume,
|
135
|
+
'markPrice': self.parse_number(self.from_ep(self.safe_string(ticker, 'markPrice'), market)),
|
136
|
+
'indexPrice': self.parse_number(self.from_ep(self.safe_string(ticker, 'indexPrice'), market)),
|
135
137
|
'info': ticker,
|
136
138
|
}
|
137
139
|
return result
|