ccxt 4.4.12__py2.py3-none-any.whl → 4.4.13__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/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +4 -1
- ccxt/async_support/bigone.py +2 -0
- ccxt/async_support/binance.py +44 -1
- ccxt/async_support/bingx.py +69 -3
- ccxt/async_support/bitget.py +1 -0
- ccxt/async_support/bitmex.py +1 -0
- ccxt/async_support/bybit.py +2 -0
- ccxt/async_support/coinbaseinternational.py +2 -0
- ccxt/async_support/coinex.py +2 -0
- ccxt/async_support/delta.py +2 -0
- ccxt/async_support/deribit.py +2 -0
- ccxt/async_support/digifinex.py +2 -0
- ccxt/async_support/gate.py +2 -0
- ccxt/async_support/htx.py +2 -2
- ccxt/async_support/krakenfutures.py +2 -0
- ccxt/async_support/kucoinfutures.py +2 -0
- ccxt/async_support/okx.py +36 -0
- ccxt/async_support/oxfun.py +1 -0
- ccxt/async_support/paradex.py +1 -0
- ccxt/async_support/poloniex.py +1 -0
- ccxt/base/exchange.py +7 -1
- ccxt/base/types.py +2 -0
- ccxt/bigone.py +2 -0
- ccxt/binance.py +44 -1
- ccxt/bingx.py +69 -3
- ccxt/bitget.py +1 -0
- ccxt/bitmex.py +1 -0
- ccxt/bybit.py +2 -0
- ccxt/coinbaseinternational.py +2 -0
- ccxt/coinex.py +2 -0
- ccxt/delta.py +2 -0
- ccxt/deribit.py +2 -0
- ccxt/digifinex.py +2 -0
- ccxt/gate.py +2 -0
- ccxt/htx.py +2 -2
- ccxt/krakenfutures.py +2 -0
- ccxt/kucoinfutures.py +2 -0
- ccxt/okx.py +36 -0
- ccxt/oxfun.py +1 -0
- ccxt/paradex.py +1 -0
- ccxt/poloniex.py +1 -0
- 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/phemex.py +2 -0
- ccxt/pro/woo.py +69 -0
- ccxt/test/tests_async.py +31 -3
- ccxt/test/tests_helpers.py +13 -36
- ccxt/test/tests_init.py +6 -2
- ccxt/test/tests_sync.py +31 -3
- {ccxt-4.4.12.dist-info → ccxt-4.4.13.dist-info}/METADATA +4 -5
- {ccxt-4.4.12.dist-info → ccxt-4.4.13.dist-info}/RECORD +58 -58
- {ccxt-4.4.12.dist-info → ccxt-4.4.13.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.12.dist-info → ccxt-4.4.13.dist-info}/WHEEL +0 -0
- {ccxt-4.4.12.dist-info → ccxt-4.4.13.dist-info}/top_level.txt +0 -0
ccxt/bingx.py
CHANGED
@@ -80,6 +80,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
80
80
|
'fetchMarginMode': True,
|
81
81
|
'fetchMarkets': True,
|
82
82
|
'fetchMarkOHLCV': True,
|
83
|
+
'fetchMarkPrices': True,
|
83
84
|
'fetchMyLiquidations': True,
|
84
85
|
'fetchOHLCV': True,
|
85
86
|
'fetchOpenInterest': True,
|
@@ -590,8 +591,8 @@ class bingx(Exchange, ImplicitAPI):
|
|
590
591
|
networkList = self.safe_list(entry, 'networkList')
|
591
592
|
networks: dict = {}
|
592
593
|
fee = None
|
593
|
-
depositEnabled =
|
594
|
-
withdrawEnabled =
|
594
|
+
depositEnabled = False
|
595
|
+
withdrawEnabled = False
|
595
596
|
defaultLimits: dict = {}
|
596
597
|
for j in range(0, len(networkList)):
|
597
598
|
rawNetwork = networkList[j]
|
@@ -602,7 +603,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
602
603
|
if networkDepositEnabled:
|
603
604
|
depositEnabled = True
|
604
605
|
networkWithdrawEnabled = self.safe_bool(rawNetwork, 'withdrawEnable')
|
605
|
-
if
|
606
|
+
if networkWithdrawEnabled:
|
606
607
|
withdrawEnabled = True
|
607
608
|
limits: dict = {
|
608
609
|
'withdraw': {
|
@@ -1654,7 +1655,70 @@ class bingx(Exchange, ImplicitAPI):
|
|
1654
1655
|
tickers = self.safe_list(response, 'data')
|
1655
1656
|
return self.parse_tickers(tickers, symbols)
|
1656
1657
|
|
1658
|
+
def fetch_mark_prices(self, symbols: Strings = None, params={}) -> Tickers:
|
1659
|
+
"""
|
1660
|
+
fetches mark prices for multiple markets
|
1661
|
+
:see: https://bingx-api.github.io/docs/#/en-us/swapV2/market-api.html#Mark%20Price%20and%20Funding%20Rate
|
1662
|
+
:param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
1663
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1664
|
+
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
1665
|
+
"""
|
1666
|
+
self.load_markets()
|
1667
|
+
market = None
|
1668
|
+
if symbols is not None:
|
1669
|
+
symbols = self.market_symbols(symbols)
|
1670
|
+
firstSymbol = self.safe_string(symbols, 0)
|
1671
|
+
if firstSymbol is not None:
|
1672
|
+
market = self.market(firstSymbol)
|
1673
|
+
subType = None
|
1674
|
+
subType, params = self.handle_sub_type_and_params('fetchMarkPrices', market, params, 'linear')
|
1675
|
+
response = None
|
1676
|
+
if subType == 'inverse':
|
1677
|
+
response = self.cswapV1PublicGetMarketPremiumIndex(params)
|
1678
|
+
else:
|
1679
|
+
response = self.swapV2PublicGetQuotePremiumIndex(params)
|
1680
|
+
#
|
1681
|
+
# spot and swap
|
1682
|
+
#
|
1683
|
+
# {
|
1684
|
+
# "code": 0,
|
1685
|
+
# "msg": "",
|
1686
|
+
# "timestamp": 1720647285296,
|
1687
|
+
# "data": [
|
1688
|
+
# {
|
1689
|
+
# "symbol": "SOL-USD",
|
1690
|
+
# "priceChange": "-2.418",
|
1691
|
+
# "priceChangePercent": "-1.6900%",
|
1692
|
+
# "lastPrice": "140.574",
|
1693
|
+
# "lastQty": "1",
|
1694
|
+
# "highPrice": "146.190",
|
1695
|
+
# "lowPrice": "138.586",
|
1696
|
+
# "volume": "1464648.00",
|
1697
|
+
# "quoteVolume": "102928.12",
|
1698
|
+
# "openPrice": "142.994",
|
1699
|
+
# "closeTime": "1720647284976",
|
1700
|
+
# "bidPrice": "140.573",
|
1701
|
+
# "bidQty": "372",
|
1702
|
+
# "askPrice": "140.577",
|
1703
|
+
# "askQty": "58"
|
1704
|
+
# },
|
1705
|
+
# ...
|
1706
|
+
# ]
|
1707
|
+
# }
|
1708
|
+
#
|
1709
|
+
tickers = self.safe_list(response, 'data')
|
1710
|
+
return self.parse_tickers(tickers, symbols)
|
1711
|
+
|
1657
1712
|
def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
|
1713
|
+
#
|
1714
|
+
# mark price
|
1715
|
+
# {
|
1716
|
+
# "symbol": "string",
|
1717
|
+
# "lastFundingRate": "string",
|
1718
|
+
# "markPrice": "string",
|
1719
|
+
# "indexPrice": "string",
|
1720
|
+
# "nextFundingTime": "int64"
|
1721
|
+
# }
|
1658
1722
|
#
|
1659
1723
|
# spot
|
1660
1724
|
# {
|
@@ -1740,6 +1804,8 @@ class bingx(Exchange, ImplicitAPI):
|
|
1740
1804
|
'average': None,
|
1741
1805
|
'baseVolume': baseVolume,
|
1742
1806
|
'quoteVolume': quoteVolume,
|
1807
|
+
'markPrice': self.safe_string(ticker, 'markPrice'),
|
1808
|
+
'indexPrice': self.safe_string(ticker, 'indexPrice'),
|
1743
1809
|
'info': ticker,
|
1744
1810
|
}, market)
|
1745
1811
|
|
ccxt/bitget.py
CHANGED
@@ -2569,6 +2569,7 @@ class bitget(Exchange, ImplicitAPI):
|
|
2569
2569
|
'average': None,
|
2570
2570
|
'baseVolume': self.safe_string(ticker, 'baseVolume'),
|
2571
2571
|
'quoteVolume': self.safe_string(ticker, 'quoteVolume'),
|
2572
|
+
'indexPrice': self.safe_string(ticker, 'indexPrice'),
|
2572
2573
|
'info': ticker,
|
2573
2574
|
}, market)
|
2574
2575
|
|
ccxt/bitmex.py
CHANGED
@@ -1370,6 +1370,7 @@ class bitmex(Exchange, ImplicitAPI):
|
|
1370
1370
|
'average': None,
|
1371
1371
|
'baseVolume': self.safe_string(ticker, 'homeNotional24h'),
|
1372
1372
|
'quoteVolume': self.safe_string(ticker, 'foreignNotional24h'),
|
1373
|
+
'markPrice': self.safe_string(ticker, 'markPrice'),
|
1373
1374
|
'info': ticker,
|
1374
1375
|
}, market)
|
1375
1376
|
|
ccxt/bybit.py
CHANGED
@@ -2053,6 +2053,8 @@ class bybit(Exchange, ImplicitAPI):
|
|
2053
2053
|
'average': None,
|
2054
2054
|
'baseVolume': baseVolume,
|
2055
2055
|
'quoteVolume': quoteVolume,
|
2056
|
+
'markPrice': self.safe_string(ticker, 'markPrice'),
|
2057
|
+
'indexPrice': self.safe_string(ticker, 'indexPrice'),
|
2056
2058
|
'info': ticker,
|
2057
2059
|
}, market)
|
2058
2060
|
|
ccxt/coinbaseinternational.py
CHANGED
@@ -1426,6 +1426,8 @@ class coinbaseinternational(Exchange, ImplicitAPI):
|
|
1426
1426
|
'baseVolume': None,
|
1427
1427
|
'quoteVolume': None,
|
1428
1428
|
'previousClose': None,
|
1429
|
+
'markPrice': self.safe_number(ticker, 'mark_price'),
|
1430
|
+
'indexPrice': self.safe_number(ticker, 'index_price'),
|
1429
1431
|
})
|
1430
1432
|
|
1431
1433
|
def fetch_balance(self, params={}) -> Balances:
|
ccxt/coinex.py
CHANGED
@@ -921,6 +921,8 @@ class coinex(Exchange, ImplicitAPI):
|
|
921
921
|
'average': None,
|
922
922
|
'baseVolume': self.safe_string(ticker, 'volume'),
|
923
923
|
'quoteVolume': None,
|
924
|
+
'markPrice': self.safe_string(ticker, 'mark_price'),
|
925
|
+
'indexPrice': self.safe_string(ticker, 'index_price'),
|
924
926
|
'info': ticker,
|
925
927
|
}, market)
|
926
928
|
|
ccxt/delta.py
CHANGED
@@ -946,6 +946,8 @@ class delta(Exchange, ImplicitAPI):
|
|
946
946
|
'average': None,
|
947
947
|
'baseVolume': self.safe_number(ticker, 'volume'),
|
948
948
|
'quoteVolume': self.safe_number(ticker, 'turnover'),
|
949
|
+
'markPrice': self.safe_number(ticker, 'mark_price'),
|
950
|
+
'indexPrice': self.safe_number(ticker, 'spot_price'),
|
949
951
|
'info': ticker,
|
950
952
|
}, market)
|
951
953
|
|
ccxt/deribit.py
CHANGED
@@ -1133,6 +1133,8 @@ class deribit(Exchange, ImplicitAPI):
|
|
1133
1133
|
'average': None,
|
1134
1134
|
'baseVolume': None,
|
1135
1135
|
'quoteVolume': self.safe_string(stats, 'volume'),
|
1136
|
+
'markPrice': self.safe_string(ticker, 'mark_price'),
|
1137
|
+
'indexPrice': self.safe_string(ticker, 'index_price'),
|
1136
1138
|
'info': ticker,
|
1137
1139
|
}, market)
|
1138
1140
|
|
ccxt/digifinex.py
CHANGED
@@ -1163,6 +1163,8 @@ class digifinex(Exchange, ImplicitAPI):
|
|
1163
1163
|
'average': None,
|
1164
1164
|
'baseVolume': self.safe_string_2(ticker, 'vol', 'volume_24h'),
|
1165
1165
|
'quoteVolume': self.safe_string(ticker, 'base_vol'),
|
1166
|
+
'markPrice': self.safe_string(ticker, 'mark_price'),
|
1167
|
+
'indexPrice': indexPrice,
|
1166
1168
|
'info': ticker,
|
1167
1169
|
}, market)
|
1168
1170
|
|
ccxt/gate.py
CHANGED
@@ -2514,6 +2514,8 @@ class gate(Exchange, ImplicitAPI):
|
|
2514
2514
|
'average': None,
|
2515
2515
|
'baseVolume': baseVolume,
|
2516
2516
|
'quoteVolume': quoteVolume,
|
2517
|
+
'markPrice': self.safe_string(ticker, 'mark_price'),
|
2518
|
+
'indexPrice': self.safe_string(ticker, 'index_price'),
|
2517
2519
|
'info': ticker,
|
2518
2520
|
}, market)
|
2519
2521
|
|
ccxt/htx.py
CHANGED
@@ -4087,7 +4087,7 @@ class htx(Exchange, ImplicitAPI):
|
|
4087
4087
|
self.load_accounts()
|
4088
4088
|
for i in range(0, len(self.accounts)):
|
4089
4089
|
account = self.accounts[i]
|
4090
|
-
if account
|
4090
|
+
if self.safe_string(account, 'type') == 'spot':
|
4091
4091
|
accountId = self.safe_string(account, 'id')
|
4092
4092
|
if accountId is not None:
|
4093
4093
|
break
|
@@ -4742,7 +4742,7 @@ class htx(Exchange, ImplicitAPI):
|
|
4742
4742
|
cost = self.safe_string(order, 'amount')
|
4743
4743
|
else:
|
4744
4744
|
amount = self.safe_string_2(order, 'volume', 'amount')
|
4745
|
-
cost = self.safe_string_n(order, ['filled-cash-amount', 'field-cash-amount', 'trade_turnover']) # same typo
|
4745
|
+
cost = self.safe_string_n(order, ['filled-cash-amount', 'field-cash-amount', 'trade_turnover']) # same typo here
|
4746
4746
|
filled = self.safe_string_n(order, ['filled-amount', 'field-amount', 'trade_volume']) # typo in their API, filled amount
|
4747
4747
|
price = self.safe_string_2(order, 'price', 'order_price')
|
4748
4748
|
feeCost = self.safe_string_2(order, 'filled-fees', 'field-fees') # typo in their API, filled feeSide
|
ccxt/krakenfutures.py
CHANGED
@@ -611,6 +611,8 @@ class krakenfutures(Exchange, ImplicitAPI):
|
|
611
611
|
'average': average,
|
612
612
|
'baseVolume': baseVolume,
|
613
613
|
'quoteVolume': quoteVolume,
|
614
|
+
'markPrice': self.safe_string(ticker, 'markPrice'),
|
615
|
+
'indexPrice': self.safe_string(ticker, 'indexPrice'),
|
614
616
|
'info': ticker,
|
615
617
|
})
|
616
618
|
|
ccxt/kucoinfutures.py
CHANGED
@@ -944,6 +944,8 @@ class kucoinfutures(kucoin, ImplicitAPI):
|
|
944
944
|
'average': None,
|
945
945
|
'baseVolume': self.safe_string(ticker, 'volumeOf24h'),
|
946
946
|
'quoteVolume': self.safe_string(ticker, 'turnoverOf24h'),
|
947
|
+
'markPrice': self.safe_string(ticker, 'markPrice'),
|
948
|
+
'indexPrice': self.safe_string(ticker, 'indexPrice'),
|
947
949
|
'info': ticker,
|
948
950
|
}, market)
|
949
951
|
|
ccxt/okx.py
CHANGED
@@ -120,6 +120,7 @@ class okx(Exchange, ImplicitAPI):
|
|
120
120
|
'fetchMarketLeverageTiers': True,
|
121
121
|
'fetchMarkets': True,
|
122
122
|
'fetchMarkOHLCV': True,
|
123
|
+
'fetchMarkPrices': True,
|
123
124
|
'fetchMySettlementHistory': False,
|
124
125
|
'fetchMyTrades': True,
|
125
126
|
'fetchOHLCV': True,
|
@@ -1784,6 +1785,13 @@ class okx(Exchange, ImplicitAPI):
|
|
1784
1785
|
return self.parse_order_book(first, symbol, timestamp)
|
1785
1786
|
|
1786
1787
|
def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
|
1788
|
+
#
|
1789
|
+
# {
|
1790
|
+
# "instType":"SWAP",
|
1791
|
+
# "instId":"BTC-USDT-SWAP",
|
1792
|
+
# "markPx":"200",
|
1793
|
+
# "ts":"1597026383085"
|
1794
|
+
# }
|
1787
1795
|
#
|
1788
1796
|
# {
|
1789
1797
|
# "instType": "SPOT",
|
@@ -1835,6 +1843,7 @@ class okx(Exchange, ImplicitAPI):
|
|
1835
1843
|
'average': None,
|
1836
1844
|
'baseVolume': baseVolume,
|
1837
1845
|
'quoteVolume': quoteVolume,
|
1846
|
+
'markPrice': self.safe_string(ticker, 'markPx'),
|
1838
1847
|
'info': ticker,
|
1839
1848
|
}, market)
|
1840
1849
|
|
@@ -1935,6 +1944,33 @@ class okx(Exchange, ImplicitAPI):
|
|
1935
1944
|
tickers = self.safe_list(response, 'data', [])
|
1936
1945
|
return self.parse_tickers(tickers, symbols)
|
1937
1946
|
|
1947
|
+
def fetch_mark_prices(self, symbols: Strings = None, params={}) -> Tickers:
|
1948
|
+
"""
|
1949
|
+
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
1950
|
+
:see: https://www.okx.com/docs-v5/en/#public-data-rest-api-get-mark-price
|
1951
|
+
:param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
1952
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1953
|
+
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
1954
|
+
"""
|
1955
|
+
self.load_markets()
|
1956
|
+
symbols = self.market_symbols(symbols)
|
1957
|
+
market = self.get_market_from_symbols(symbols)
|
1958
|
+
marketType = None
|
1959
|
+
marketType, params = self.handle_market_type_and_params('fetchTickers', market, params, 'swap')
|
1960
|
+
request: dict = {
|
1961
|
+
'instType': self.convert_to_instrument_type(marketType),
|
1962
|
+
}
|
1963
|
+
if marketType == 'option':
|
1964
|
+
defaultUnderlying = self.safe_string(self.options, 'defaultUnderlying', 'BTC-USD')
|
1965
|
+
currencyId = self.safe_string_2(params, 'uly', 'marketId', defaultUnderlying)
|
1966
|
+
if currencyId is None:
|
1967
|
+
raise ArgumentsRequired(self.id + ' fetchTickers() requires an underlying uly or marketId parameter for options markets')
|
1968
|
+
else:
|
1969
|
+
request['uly'] = currencyId
|
1970
|
+
response = self.publicGetPublicMarkPrice(self.extend(request, params))
|
1971
|
+
tickers = self.safe_list(response, 'data', [])
|
1972
|
+
return self.parse_tickers(tickers, symbols)
|
1973
|
+
|
1938
1974
|
def parse_trade(self, trade: dict, market: Market = None) -> Trade:
|
1939
1975
|
#
|
1940
1976
|
# public fetchTrades
|
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/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/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
|
ccxt/pro/woo.py
CHANGED
@@ -27,6 +27,7 @@ class woo(ccxt.async_support.woo):
|
|
27
27
|
'watchOrders': True,
|
28
28
|
'watchTicker': True,
|
29
29
|
'watchTickers': True,
|
30
|
+
'watchBidsAsks': True,
|
30
31
|
'watchTrades': True,
|
31
32
|
'watchTradesForSymbols': False,
|
32
33
|
'watchPositions': True,
|
@@ -383,6 +384,73 @@ class woo(ccxt.async_support.woo):
|
|
383
384
|
result.append(ticker)
|
384
385
|
client.resolve(result, topic)
|
385
386
|
|
387
|
+
async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
|
388
|
+
"""
|
389
|
+
:see: https://docs.woox.io/#bbos
|
390
|
+
watches best bid & ask for symbols
|
391
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
392
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
393
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
394
|
+
"""
|
395
|
+
await self.load_markets()
|
396
|
+
symbols = self.market_symbols(symbols, None, False)
|
397
|
+
name = 'bbos'
|
398
|
+
topic = name
|
399
|
+
request: dict = {
|
400
|
+
'event': 'subscribe',
|
401
|
+
'topic': topic,
|
402
|
+
}
|
403
|
+
message = self.extend(request, params)
|
404
|
+
tickers = await self.watch_public(topic, message)
|
405
|
+
if self.newUpdates:
|
406
|
+
return tickers
|
407
|
+
return self.filter_by_array(self.bidsasks, 'symbol', symbols)
|
408
|
+
|
409
|
+
def handle_bid_ask(self, client: Client, message):
|
410
|
+
#
|
411
|
+
# {
|
412
|
+
# "topic": "bbos",
|
413
|
+
# "ts": 1618822376000,
|
414
|
+
# "data": [
|
415
|
+
# {
|
416
|
+
# "symbol": "SPOT_FIL_USDT",
|
417
|
+
# "ask": 159.0318,
|
418
|
+
# "askSize": 370.43,
|
419
|
+
# "bid": 158.9158,
|
420
|
+
# "bidSize": 16
|
421
|
+
# }
|
422
|
+
# ]
|
423
|
+
# }
|
424
|
+
#
|
425
|
+
topic = self.safe_string(message, 'topic')
|
426
|
+
data = self.safe_list(message, 'data', [])
|
427
|
+
timestamp = self.safe_integer(message, 'ts')
|
428
|
+
result: dict = {}
|
429
|
+
for i in range(0, len(data)):
|
430
|
+
ticker = self.safe_dict(data, i)
|
431
|
+
ticker['ts'] = timestamp
|
432
|
+
parsedTicker = self.parse_ws_bid_ask(ticker)
|
433
|
+
symbol = parsedTicker['symbol']
|
434
|
+
self.bidsasks[symbol] = parsedTicker
|
435
|
+
result[symbol] = parsedTicker
|
436
|
+
client.resolve(result, topic)
|
437
|
+
|
438
|
+
def parse_ws_bid_ask(self, ticker, market=None):
|
439
|
+
marketId = self.safe_string(ticker, 'symbol')
|
440
|
+
market = self.safe_market(marketId, market)
|
441
|
+
symbol = self.safe_string(market, 'symbol')
|
442
|
+
timestamp = self.safe_integer(ticker, 'ts')
|
443
|
+
return self.safe_ticker({
|
444
|
+
'symbol': symbol,
|
445
|
+
'timestamp': timestamp,
|
446
|
+
'datetime': self.iso8601(timestamp),
|
447
|
+
'ask': self.safe_string(ticker, 'ask'),
|
448
|
+
'askVolume': self.safe_string(ticker, 'askSize'),
|
449
|
+
'bid': self.safe_string(ticker, 'bid'),
|
450
|
+
'bidVolume': self.safe_string(ticker, 'bidSize'),
|
451
|
+
'info': ticker,
|
452
|
+
}, market)
|
453
|
+
|
386
454
|
async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
387
455
|
"""
|
388
456
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
@@ -1101,6 +1169,7 @@ class woo(ccxt.async_support.woo):
|
|
1101
1169
|
'trade': self.handle_trade,
|
1102
1170
|
'balance': self.handle_balance,
|
1103
1171
|
'position': self.handle_positions,
|
1172
|
+
'bbos': self.handle_bid_ask,
|
1104
1173
|
}
|
1105
1174
|
event = self.safe_string(message, 'event')
|
1106
1175
|
method = self.safe_value(methods, event)
|