ccxt 4.2.82__py2.py3-none-any.whl → 4.2.84__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.
Potentially problematic release.
This version of ccxt might be problematic. Click here for more details.
- ccxt/__init__.py +1 -1
- ccxt/abstract/bitstamp.py +1 -1
- ccxt/abstract/bybit.py +1 -1
- ccxt/ace.py +1 -1
- ccxt/alpaca.py +1 -1
- ccxt/ascendex.py +1 -1
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ace.py +1 -1
- ccxt/async_support/alpaca.py +1 -1
- ccxt/async_support/ascendex.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/bigone.py +1 -1
- ccxt/async_support/binance.py +1 -1
- ccxt/async_support/bingx.py +1 -1
- ccxt/async_support/bitbank.py +1 -1
- ccxt/async_support/bitbns.py +1 -1
- ccxt/async_support/bitfinex.py +1 -1
- ccxt/async_support/bitfinex2.py +1 -1
- ccxt/async_support/bitflyer.py +1 -1
- ccxt/async_support/bitget.py +12 -5
- ccxt/async_support/bithumb.py +2 -1
- ccxt/async_support/bitmart.py +1 -1
- ccxt/async_support/bitmex.py +1 -1
- ccxt/async_support/bitopro.py +1 -1
- ccxt/async_support/bitrue.py +1 -1
- ccxt/async_support/bitso.py +1 -1
- ccxt/async_support/bitstamp.py +43 -16
- ccxt/async_support/bitteam.py +1 -1
- ccxt/async_support/bitvavo.py +1 -1
- ccxt/async_support/blockchaincom.py +1 -1
- ccxt/async_support/blofin.py +1 -1
- 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 +5 -5
- ccxt/async_support/cex.py +1 -1
- ccxt/async_support/coinbase.py +1 -1
- ccxt/async_support/coinbaseinternational.py +1 -1
- ccxt/async_support/coinbasepro.py +1 -1
- ccxt/async_support/coinex.py +2 -3
- ccxt/async_support/coinlist.py +1 -1
- ccxt/async_support/coinmate.py +1 -1
- ccxt/async_support/coinmetro.py +1 -1
- ccxt/async_support/coinone.py +1 -1
- ccxt/async_support/coinsph.py +1 -1
- ccxt/async_support/cryptocom.py +1 -1
- ccxt/async_support/currencycom.py +1 -1
- ccxt/async_support/delta.py +1 -1
- ccxt/async_support/deribit.py +17 -2
- ccxt/async_support/digifinex.py +1 -1
- ccxt/async_support/exmo.py +1 -1
- ccxt/async_support/gate.py +1 -1
- ccxt/async_support/gemini.py +2 -1
- ccxt/async_support/hitbtc.py +1 -1
- ccxt/async_support/hollaex.py +1 -1
- ccxt/async_support/htx.py +6 -28
- ccxt/async_support/huobijp.py +1 -1
- ccxt/async_support/hyperliquid.py +6 -5
- ccxt/async_support/idex.py +1 -1
- ccxt/async_support/independentreserve.py +1 -1
- ccxt/async_support/indodax.py +1 -1
- ccxt/async_support/kraken.py +1 -1
- ccxt/async_support/krakenfutures.py +1 -1
- ccxt/async_support/kucoin.py +11 -2
- ccxt/async_support/kucoinfutures.py +147 -10
- ccxt/async_support/kuna.py +1 -1
- ccxt/async_support/latoken.py +1 -1
- ccxt/async_support/lbank.py +1 -1
- ccxt/async_support/luno.py +1 -1
- ccxt/async_support/lykke.py +1 -1
- ccxt/async_support/mercado.py +1 -1
- ccxt/async_support/mexc.py +1 -1
- ccxt/async_support/ndax.py +1 -1
- ccxt/async_support/novadax.py +1 -1
- ccxt/async_support/oceanex.py +1 -1
- ccxt/async_support/okcoin.py +1 -1
- ccxt/async_support/okx.py +1 -1
- ccxt/async_support/onetrading.py +1 -1
- ccxt/async_support/p2b.py +1 -1
- ccxt/async_support/phemex.py +1 -1
- ccxt/async_support/poloniex.py +1 -1
- ccxt/async_support/poloniexfutures.py +1 -1
- ccxt/async_support/probit.py +1 -1
- ccxt/async_support/timex.py +1 -1
- ccxt/async_support/tokocrypto.py +1 -1
- ccxt/async_support/tradeogre.py +2 -1
- ccxt/async_support/upbit.py +1 -1
- ccxt/async_support/wavesexchange.py +1 -1
- ccxt/async_support/wazirx.py +1 -1
- ccxt/async_support/whitebit.py +1 -1
- ccxt/async_support/woo.py +1 -1
- ccxt/async_support/yobit.py +1 -1
- ccxt/async_support/zaif.py +1 -1
- ccxt/async_support/zonda.py +1 -1
- ccxt/base/exchange.py +1 -1
- ccxt/bigone.py +1 -1
- ccxt/binance.py +1 -1
- ccxt/bingx.py +1 -1
- ccxt/bitbank.py +1 -1
- ccxt/bitbns.py +1 -1
- ccxt/bitfinex.py +1 -1
- ccxt/bitfinex2.py +1 -1
- ccxt/bitflyer.py +1 -1
- ccxt/bitget.py +12 -5
- ccxt/bithumb.py +2 -1
- ccxt/bitmart.py +1 -1
- ccxt/bitmex.py +1 -1
- ccxt/bitopro.py +1 -1
- ccxt/bitrue.py +1 -1
- ccxt/bitso.py +1 -1
- ccxt/bitstamp.py +43 -16
- ccxt/bitteam.py +1 -1
- ccxt/bitvavo.py +1 -1
- ccxt/blockchaincom.py +1 -1
- ccxt/blofin.py +1 -1
- ccxt/btcalpha.py +1 -1
- ccxt/btcmarkets.py +1 -1
- ccxt/btcturk.py +1 -1
- ccxt/bybit.py +5 -5
- ccxt/cex.py +1 -1
- ccxt/coinbase.py +1 -1
- ccxt/coinbaseinternational.py +1 -1
- ccxt/coinbasepro.py +1 -1
- ccxt/coinex.py +2 -3
- ccxt/coinlist.py +1 -1
- ccxt/coinmate.py +1 -1
- ccxt/coinmetro.py +1 -1
- ccxt/coinone.py +1 -1
- ccxt/coinsph.py +1 -1
- ccxt/cryptocom.py +1 -1
- ccxt/currencycom.py +1 -1
- ccxt/delta.py +1 -1
- ccxt/deribit.py +17 -2
- ccxt/digifinex.py +1 -1
- ccxt/exmo.py +1 -1
- ccxt/gate.py +1 -1
- ccxt/gemini.py +2 -1
- ccxt/hitbtc.py +1 -1
- ccxt/hollaex.py +1 -1
- ccxt/htx.py +6 -28
- ccxt/huobijp.py +1 -1
- ccxt/hyperliquid.py +6 -5
- ccxt/idex.py +1 -1
- ccxt/independentreserve.py +1 -1
- ccxt/indodax.py +1 -1
- ccxt/kraken.py +1 -1
- ccxt/krakenfutures.py +1 -1
- ccxt/kucoin.py +11 -2
- ccxt/kucoinfutures.py +147 -10
- ccxt/kuna.py +1 -1
- ccxt/latoken.py +1 -1
- ccxt/lbank.py +1 -1
- ccxt/luno.py +1 -1
- ccxt/lykke.py +1 -1
- ccxt/mercado.py +1 -1
- ccxt/mexc.py +1 -1
- ccxt/ndax.py +1 -1
- ccxt/novadax.py +1 -1
- ccxt/oceanex.py +1 -1
- ccxt/okcoin.py +1 -1
- ccxt/okx.py +1 -1
- ccxt/onetrading.py +1 -1
- ccxt/p2b.py +1 -1
- ccxt/phemex.py +1 -1
- ccxt/poloniex.py +1 -1
- ccxt/poloniexfutures.py +1 -1
- ccxt/pro/__init__.py +3 -1
- ccxt/pro/bithumb.py +368 -0
- ccxt/pro/bitmart.py +1 -1
- ccxt/pro/bybit.py +1 -1
- ccxt/pro/cex.py +15 -5
- ccxt/pro/okx.py +2 -1
- ccxt/pro/p2b.py +14 -4
- ccxt/pro/woo.py +1 -1
- ccxt/probit.py +1 -1
- ccxt/test/base/test_market.py +3 -0
- ccxt/timex.py +1 -1
- ccxt/tokocrypto.py +1 -1
- ccxt/tradeogre.py +2 -1
- ccxt/upbit.py +1 -1
- ccxt/wavesexchange.py +1 -1
- ccxt/wazirx.py +1 -1
- ccxt/whitebit.py +1 -1
- ccxt/woo.py +1 -1
- ccxt/yobit.py +1 -1
- ccxt/zaif.py +1 -1
- ccxt/zonda.py +1 -1
- {ccxt-4.2.82.dist-info → ccxt-4.2.84.dist-info}/METADATA +5 -5
- {ccxt-4.2.82.dist-info → ccxt-4.2.84.dist-info}/RECORD +191 -190
- {ccxt-4.2.82.dist-info → ccxt-4.2.84.dist-info}/WHEEL +0 -0
- {ccxt-4.2.82.dist-info → ccxt-4.2.84.dist-info}/top_level.txt +0 -0
ccxt/pro/bithumb.py
ADDED
@@ -0,0 +1,368 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
4
|
+
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
5
|
+
|
6
|
+
import ccxt.async_support
|
7
|
+
from ccxt.async_support.base.ws.cache import ArrayCache
|
8
|
+
from ccxt.base.types import Int, OrderBook, Strings, Ticker, Tickers, Trade
|
9
|
+
from ccxt.async_support.base.ws.client import Client
|
10
|
+
from typing import List
|
11
|
+
from ccxt.base.errors import ExchangeError
|
12
|
+
|
13
|
+
|
14
|
+
class bithumb(ccxt.async_support.bithumb):
|
15
|
+
|
16
|
+
def describe(self):
|
17
|
+
return self.deep_extend(super(bithumb, self).describe(), {
|
18
|
+
'has': {
|
19
|
+
'ws': True,
|
20
|
+
'watchBalance': False,
|
21
|
+
'watchTicker': True,
|
22
|
+
'watchTickers': True,
|
23
|
+
'watchTrades': True,
|
24
|
+
'watchOrderBook': True,
|
25
|
+
'watchOHLCV': False,
|
26
|
+
},
|
27
|
+
'urls': {
|
28
|
+
'api': {
|
29
|
+
'ws': 'wss://pubwss.bithumb.com/pub/ws',
|
30
|
+
},
|
31
|
+
},
|
32
|
+
'options': {},
|
33
|
+
'streaming': {},
|
34
|
+
'exceptions': {},
|
35
|
+
})
|
36
|
+
|
37
|
+
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
38
|
+
"""
|
39
|
+
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
40
|
+
:param str symbol: unified symbol of the market to fetch the ticker for
|
41
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
42
|
+
:param str [params.channel]: the channel to subscribe to, tickers by default. Can be tickers, sprd-tickers, index-tickers, block-tickers
|
43
|
+
:returns dict: a `ticker structure <https://github.com/ccxt/ccxt/wiki/Manual#ticker-structure>`
|
44
|
+
"""
|
45
|
+
url = self.urls['api']['ws']
|
46
|
+
await self.load_markets()
|
47
|
+
market = self.market(symbol)
|
48
|
+
messageHash = 'ticker:' + market['symbol']
|
49
|
+
request = {
|
50
|
+
'type': 'ticker',
|
51
|
+
'symbols': [market['base'] + '_' + market['quote']],
|
52
|
+
'tickTypes': [self.safe_string(params, 'tickTypes', '24H')],
|
53
|
+
}
|
54
|
+
return await self.watch(url, messageHash, self.extend(request, params), messageHash)
|
55
|
+
|
56
|
+
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
57
|
+
"""
|
58
|
+
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
59
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
60
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
61
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
62
|
+
"""
|
63
|
+
await self.load_markets()
|
64
|
+
url = self.urls['api']['ws']
|
65
|
+
marketIds = []
|
66
|
+
messageHashes = []
|
67
|
+
symbols = self.market_symbols(symbols, None, False, True, True)
|
68
|
+
for i in range(0, len(symbols)):
|
69
|
+
symbol = symbols[i]
|
70
|
+
market = self.market(symbol)
|
71
|
+
marketIds.append(market['base'] + '_' + market['quote'])
|
72
|
+
messageHashes.append('ticker:' + market['symbol'])
|
73
|
+
request = {
|
74
|
+
'type': 'ticker',
|
75
|
+
'symbols': marketIds,
|
76
|
+
'tickTypes': [self.safe_string(params, 'tickTypes', '24H')],
|
77
|
+
}
|
78
|
+
message = self.extend(request, params)
|
79
|
+
newTicker = await self.watch_multiple(url, messageHashes, message, messageHashes)
|
80
|
+
if self.newUpdates:
|
81
|
+
result = {}
|
82
|
+
result[newTicker['symbol']] = newTicker
|
83
|
+
return result
|
84
|
+
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
85
|
+
|
86
|
+
def handle_ticker(self, client: Client, message):
|
87
|
+
#
|
88
|
+
# {
|
89
|
+
# "type" : "ticker",
|
90
|
+
# "content" : {
|
91
|
+
# "symbol" : "BTC_KRW", # 통화코드
|
92
|
+
# "tickType" : "24H", # 변동 기준시간- 30M, 1H, 12H, 24H, MID
|
93
|
+
# "date" : "20200129", # 일자
|
94
|
+
# "time" : "121844", # 시간
|
95
|
+
# "openPrice" : "2302", # 시가
|
96
|
+
# "closePrice" : "2317", # 종가
|
97
|
+
# "lowPrice" : "2272", # 저가
|
98
|
+
# "highPrice" : "2344", # 고가
|
99
|
+
# "value" : "2831915078.07065789", # 누적거래금액
|
100
|
+
# "volume" : "1222314.51355788", # 누적거래량
|
101
|
+
# "sellVolume" : "760129.34079004", # 매도누적거래량
|
102
|
+
# "buyVolume" : "462185.17276784", # 매수누적거래량
|
103
|
+
# "prevClosePrice" : "2326", # 전일종가
|
104
|
+
# "chgRate" : "0.65", # 변동률
|
105
|
+
# "chgAmt" : "15", # 변동금액
|
106
|
+
# "volumePower" : "60.80" # 체결강도
|
107
|
+
# }
|
108
|
+
# }
|
109
|
+
#
|
110
|
+
content = self.safe_dict(message, 'content', {})
|
111
|
+
marketId = self.safe_string(content, 'symbol')
|
112
|
+
symbol = self.safe_symbol(marketId, None, '_')
|
113
|
+
ticker = self.parse_ws_ticker(content)
|
114
|
+
messageHash = 'ticker:' + symbol
|
115
|
+
self.tickers[symbol] = ticker
|
116
|
+
client.resolve(self.tickers[symbol], messageHash)
|
117
|
+
|
118
|
+
def parse_ws_ticker(self, ticker, market=None):
|
119
|
+
#
|
120
|
+
# {
|
121
|
+
# "symbol" : "BTC_KRW", # 통화코드
|
122
|
+
# "tickType" : "24H", # 변동 기준시간- 30M, 1H, 12H, 24H, MID
|
123
|
+
# "date" : "20200129", # 일자
|
124
|
+
# "time" : "121844", # 시간
|
125
|
+
# "openPrice" : "2302", # 시가
|
126
|
+
# "closePrice" : "2317", # 종가
|
127
|
+
# "lowPrice" : "2272", # 저가
|
128
|
+
# "highPrice" : "2344", # 고가
|
129
|
+
# "value" : "2831915078.07065789", # 누적거래금액
|
130
|
+
# "volume" : "1222314.51355788", # 누적거래량
|
131
|
+
# "sellVolume" : "760129.34079004", # 매도누적거래량
|
132
|
+
# "buyVolume" : "462185.17276784", # 매수누적거래량
|
133
|
+
# "prevClosePrice" : "2326", # 전일종가
|
134
|
+
# "chgRate" : "0.65", # 변동률
|
135
|
+
# "chgAmt" : "15", # 변동금액
|
136
|
+
# "volumePower" : "60.80" # 체결강도
|
137
|
+
# }
|
138
|
+
#
|
139
|
+
date = self.safe_string(ticker, 'date', '')
|
140
|
+
time = self.safe_string(ticker, 'time', '')
|
141
|
+
datetime = date[0:4] + '-' + date[4:6] + '-' + date[6:8] + 'T' + time[0:2] + ':' + time[2:4] + ':' + time[4:6]
|
142
|
+
marketId = self.safe_string(ticker, 'symbol')
|
143
|
+
return self.safe_ticker({
|
144
|
+
'symbol': self.safe_symbol(marketId, market, '_'),
|
145
|
+
'timestamp': self.parse8601(datetime),
|
146
|
+
'datetime': datetime,
|
147
|
+
'high': self.safe_string(ticker, 'highPrice'),
|
148
|
+
'low': self.safe_string(ticker, 'lowPrice'),
|
149
|
+
'bid': None,
|
150
|
+
'bidVolume': self.safe_string(ticker, 'buyVolume'),
|
151
|
+
'ask': None,
|
152
|
+
'askVolume': self.safe_string(ticker, 'sellVolume'),
|
153
|
+
'vwap': None,
|
154
|
+
'open': self.safe_string(ticker, 'openPrice'),
|
155
|
+
'close': self.safe_string(ticker, 'closePrice'),
|
156
|
+
'last': None,
|
157
|
+
'previousClose': self.safe_string(ticker, 'prevClosePrice'),
|
158
|
+
'change': self.safe_string(ticker, 'chgAmt'),
|
159
|
+
'percentage': self.safe_string(ticker, 'chgRate'),
|
160
|
+
'average': None,
|
161
|
+
'baseVolume': self.safe_string(ticker, 'volume'),
|
162
|
+
'quoteVolume': self.safe_string(ticker, 'value'),
|
163
|
+
'info': ticker,
|
164
|
+
}, market)
|
165
|
+
|
166
|
+
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
167
|
+
"""
|
168
|
+
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
169
|
+
:param str symbol: unified symbol of the market to fetch the order book for
|
170
|
+
:param int [limit]: the maximum amount of order book entries to return
|
171
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
172
|
+
:returns dict: A dictionary of `order book structures <https://github.com/ccxt/ccxt/wiki/Manual#order-book-structure>` indexed by market symbols
|
173
|
+
"""
|
174
|
+
await self.load_markets()
|
175
|
+
url = self.urls['api']['ws']
|
176
|
+
market = self.market(symbol)
|
177
|
+
symbol = market['symbol']
|
178
|
+
messageHash = 'orderbook' + ':' + symbol
|
179
|
+
request = {
|
180
|
+
'type': 'orderbookdepth',
|
181
|
+
'symbols': [market['base'] + '_' + market['quote']],
|
182
|
+
}
|
183
|
+
orderbook = await self.watch(url, messageHash, self.extend(request, params), messageHash)
|
184
|
+
return orderbook.limit()
|
185
|
+
|
186
|
+
def handle_order_book(self, client: Client, message):
|
187
|
+
#
|
188
|
+
# {
|
189
|
+
# "type" : "orderbookdepth",
|
190
|
+
# "content" : {
|
191
|
+
# "list" : [
|
192
|
+
# {
|
193
|
+
# "symbol" : "BTC_KRW",
|
194
|
+
# "orderType" : "ask", # 주문타입 – bid / ask
|
195
|
+
# "price" : "10593000", # 호가
|
196
|
+
# "quantity" : "1.11223318", # 잔량
|
197
|
+
# "total" : "3" # 건수
|
198
|
+
# },
|
199
|
+
# {"symbol" : "BTC_KRW", "orderType" : "ask", "price" : "10596000", "quantity" : "0.5495", "total" : "8"},
|
200
|
+
# {"symbol" : "BTC_KRW", "orderType" : "ask", "price" : "10598000", "quantity" : "18.2085", "total" : "10"},
|
201
|
+
# {"symbol" : "BTC_KRW", "orderType" : "bid", "price" : "10532000", "quantity" : "0", "total" : "0"},
|
202
|
+
# {"symbol" : "BTC_KRW", "orderType" : "bid", "price" : "10572000", "quantity" : "2.3324", "total" : "4"},
|
203
|
+
# {"symbol" : "BTC_KRW", "orderType" : "bid", "price" : "10571000", "quantity" : "1.469", "total" : "3"},
|
204
|
+
# {"symbol" : "BTC_KRW", "orderType" : "bid", "price" : "10569000", "quantity" : "0.5152", "total" : "2"}
|
205
|
+
# ],
|
206
|
+
# "datetime":1580268255864325 # 일시
|
207
|
+
# }
|
208
|
+
# }
|
209
|
+
#
|
210
|
+
content = self.safe_dict(message, 'content', {})
|
211
|
+
list = self.safe_list(content, 'list', [])
|
212
|
+
first = self.safe_dict(list, 0, {})
|
213
|
+
marketId = self.safe_string(first, 'symbol')
|
214
|
+
symbol = self.safe_symbol(marketId, None, '_')
|
215
|
+
timestampStr = self.safe_string(content, 'datetime')
|
216
|
+
timestamp = self.parse_to_int(timestampStr[0:13])
|
217
|
+
if not (symbol in self.orderbooks):
|
218
|
+
ob = self.order_book()
|
219
|
+
ob['symbol'] = symbol
|
220
|
+
self.orderbooks[symbol] = ob
|
221
|
+
orderbook = self.orderbooks[symbol]
|
222
|
+
self.handle_deltas(orderbook, list)
|
223
|
+
orderbook['timestamp'] = timestamp
|
224
|
+
orderbook['datetime'] = self.iso8601(timestamp)
|
225
|
+
messageHash = 'orderbook' + ':' + symbol
|
226
|
+
client.resolve(orderbook, messageHash)
|
227
|
+
|
228
|
+
def handle_delta(self, orderbook, delta):
|
229
|
+
#
|
230
|
+
# {
|
231
|
+
# symbol: "ETH_BTC",
|
232
|
+
# orderType: "bid",
|
233
|
+
# price: "0.07349517",
|
234
|
+
# quantity: "0",
|
235
|
+
# total: "0",
|
236
|
+
# }
|
237
|
+
#
|
238
|
+
sideId = self.safe_string(delta, 'orderType')
|
239
|
+
side = 'bids' if (sideId == 'bid') else 'asks'
|
240
|
+
bidAsk = self.parse_bid_ask(delta, 'price', 'quantity')
|
241
|
+
orderbookSide = orderbook[side]
|
242
|
+
orderbookSide.storeArray(bidAsk)
|
243
|
+
|
244
|
+
def handle_deltas(self, orderbook, deltas):
|
245
|
+
for i in range(0, len(deltas)):
|
246
|
+
self.handle_delta(orderbook, deltas[i])
|
247
|
+
|
248
|
+
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
249
|
+
"""
|
250
|
+
get the list of most recent trades for a particular symbol
|
251
|
+
:param str symbol: unified symbol of the market to fetch trades for
|
252
|
+
:param int [since]: timestamp in ms of the earliest trade to fetch
|
253
|
+
:param int [limit]: the maximum amount of trades to fetch
|
254
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
255
|
+
:returns dict[]: a list of `trade structures <https://github.com/ccxt/ccxt/wiki/Manual#public-trades>`
|
256
|
+
"""
|
257
|
+
await self.load_markets()
|
258
|
+
url = self.urls['api']['ws']
|
259
|
+
market = self.market(symbol)
|
260
|
+
symbol = market['symbol']
|
261
|
+
messageHash = 'trade:' + symbol
|
262
|
+
request = {
|
263
|
+
'type': 'transaction',
|
264
|
+
'symbols': [market['base'] + '_' + market['quote']],
|
265
|
+
}
|
266
|
+
trades = await self.watch(url, messageHash, self.extend(request, params), messageHash)
|
267
|
+
if self.newUpdates:
|
268
|
+
limit = trades.getLimit(symbol, limit)
|
269
|
+
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
270
|
+
|
271
|
+
def handle_trades(self, client, message):
|
272
|
+
#
|
273
|
+
# {
|
274
|
+
# "type" : "transaction",
|
275
|
+
# "content" : {
|
276
|
+
# "list" : [
|
277
|
+
# {
|
278
|
+
# "symbol" : "BTC_KRW",
|
279
|
+
# "buySellGb" : "1",
|
280
|
+
# "contPrice" : "10579000",
|
281
|
+
# "contQty" : "0.01",
|
282
|
+
# "contAmt" : "105790.00",
|
283
|
+
# "contDtm" : "2020-01-29 12:24:18.830039",
|
284
|
+
# "updn" : "dn"
|
285
|
+
# }
|
286
|
+
# ]
|
287
|
+
# }
|
288
|
+
# }
|
289
|
+
#
|
290
|
+
content = self.safe_dict(message, 'content', {})
|
291
|
+
rawTrades = self.safe_list(content, 'list', [])
|
292
|
+
for i in range(0, len(rawTrades)):
|
293
|
+
rawTrade = rawTrades[i]
|
294
|
+
marketId = self.safe_string(rawTrade, 'symbol')
|
295
|
+
symbol = self.safe_symbol(marketId, None, '_')
|
296
|
+
if not (symbol in self.trades):
|
297
|
+
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
298
|
+
stored = ArrayCache(limit)
|
299
|
+
self.trades[symbol] = stored
|
300
|
+
trades = self.trades[symbol]
|
301
|
+
parsed = self.parse_ws_trade(rawTrade)
|
302
|
+
trades.append(parsed)
|
303
|
+
messageHash = 'trade' + ':' + symbol
|
304
|
+
client.resolve(trades, messageHash)
|
305
|
+
|
306
|
+
def parse_ws_trade(self, trade, market=None):
|
307
|
+
#
|
308
|
+
# {
|
309
|
+
# "symbol" : "BTC_KRW",
|
310
|
+
# "buySellGb" : "1",
|
311
|
+
# "contPrice" : "10579000",
|
312
|
+
# "contQty" : "0.01",
|
313
|
+
# "contAmt" : "105790.00",
|
314
|
+
# "contDtm" : "2020-01-29 12:24:18.830039",
|
315
|
+
# "updn" : "dn"
|
316
|
+
# }
|
317
|
+
#
|
318
|
+
marketId = self.safe_string(trade, 'symbol')
|
319
|
+
datetime = self.safe_string(trade, 'contDtm')
|
320
|
+
sideId = self.safe_string(trade, 'buySellGb')
|
321
|
+
return self.safe_trade({
|
322
|
+
'id': None,
|
323
|
+
'info': trade,
|
324
|
+
'timestamp': self.parse8601(datetime),
|
325
|
+
'datetime': datetime,
|
326
|
+
'symbol': self.safe_symbol(marketId, market, '_'),
|
327
|
+
'order': None,
|
328
|
+
'type': None,
|
329
|
+
'side': 'buy' if (sideId == '1') else 'sell',
|
330
|
+
'takerOrMaker': None,
|
331
|
+
'price': self.safe_string(trade, 'contPrice'),
|
332
|
+
'amount': self.safe_string(trade, 'contQty'),
|
333
|
+
'cost': self.safe_string(trade, 'contAmt'),
|
334
|
+
'fee': None,
|
335
|
+
}, market)
|
336
|
+
|
337
|
+
def handle_error_message(self, client: Client, message):
|
338
|
+
#
|
339
|
+
# {
|
340
|
+
# "status" : "5100",
|
341
|
+
# "resmsg" : "Invalid Filter Syntax"
|
342
|
+
# }
|
343
|
+
#
|
344
|
+
if not ('status' in message):
|
345
|
+
return True
|
346
|
+
errorCode = self.safe_string(message, 'status')
|
347
|
+
try:
|
348
|
+
if errorCode != '0000':
|
349
|
+
msg = self.safe_string(message, 'resmsg')
|
350
|
+
raise ExchangeError(self.id + ' ' + msg)
|
351
|
+
return True
|
352
|
+
except Exception as e:
|
353
|
+
client.reject(e)
|
354
|
+
return True
|
355
|
+
|
356
|
+
def handle_message(self, client: Client, message):
|
357
|
+
if not self.handle_error_message(client, message):
|
358
|
+
return
|
359
|
+
topic = self.safe_string(message, 'type')
|
360
|
+
if topic is not None:
|
361
|
+
methods = {
|
362
|
+
'ticker': self.handle_ticker,
|
363
|
+
'orderbookdepth': self.handle_order_book,
|
364
|
+
'transaction': self.handle_trades,
|
365
|
+
}
|
366
|
+
method = self.safe_value(methods, topic)
|
367
|
+
if method is not None:
|
368
|
+
method(client, message)
|
ccxt/pro/bitmart.py
CHANGED
@@ -663,9 +663,9 @@ class bitmart(ccxt.async_support.bitmart):
|
|
663
663
|
# }
|
664
664
|
#
|
665
665
|
data = self.safe_value(message, 'data', [])
|
666
|
-
cache = self.positions
|
667
666
|
if self.positions is None:
|
668
667
|
self.positions = ArrayCacheBySymbolBySide()
|
668
|
+
cache = self.positions
|
669
669
|
newPositions = []
|
670
670
|
for i in range(0, len(data)):
|
671
671
|
rawPosition = data[i]
|
ccxt/pro/bybit.py
CHANGED
@@ -197,7 +197,7 @@ class bybit(ccxt.async_support.bybit):
|
|
197
197
|
|
198
198
|
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
199
199
|
"""
|
200
|
-
|
200
|
+
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
201
201
|
:see: https://bybit-exchange.github.io/docs/v5/websocket/public/ticker
|
202
202
|
:see: https://bybit-exchange.github.io/docs/v5/websocket/public/etp-ticker
|
203
203
|
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
ccxt/pro/cex.py
CHANGED
@@ -131,6 +131,7 @@ class cex(ccxt.async_support.cex):
|
|
131
131
|
url = self.urls['api']['ws']
|
132
132
|
messageHash = 'trades'
|
133
133
|
subscriptionHash = 'old:' + symbol
|
134
|
+
self.options['currentWatchTradeSymbol'] = symbol # exchange supports only 1 symbol for self watchTrades channel
|
134
135
|
client = self.safe_value(self.clients, url)
|
135
136
|
if client is not None:
|
136
137
|
subscriptionKeys = list(client.subscriptions.keys())
|
@@ -167,11 +168,15 @@ class cex(ccxt.async_support.cex):
|
|
167
168
|
data = self.safe_list(message, 'data', [])
|
168
169
|
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
169
170
|
stored = ArrayCache(limit)
|
171
|
+
symbol = self.safe_string(self.options, 'currentWatchTradeSymbol')
|
172
|
+
if symbol is None:
|
173
|
+
return
|
174
|
+
market = self.market(symbol)
|
170
175
|
dataLength = len(data)
|
171
176
|
for i in range(0, dataLength):
|
172
177
|
index = dataLength - 1 - i
|
173
178
|
rawTrade = data[index]
|
174
|
-
parsed = self.parse_ws_old_trade(rawTrade)
|
179
|
+
parsed = self.parse_ws_old_trade(rawTrade, market)
|
175
180
|
stored.append(parsed)
|
176
181
|
messageHash = 'trades'
|
177
182
|
self.trades = stored # trades don't have symbol
|
@@ -196,7 +201,7 @@ class cex(ccxt.async_support.cex):
|
|
196
201
|
'id': id,
|
197
202
|
'timestamp': timestamp,
|
198
203
|
'datetime': self.iso8601(timestamp),
|
199
|
-
'symbol':
|
204
|
+
'symbol': self.safe_string(market, 'symbol'),
|
200
205
|
'type': None,
|
201
206
|
'side': side,
|
202
207
|
'order': None,
|
@@ -218,8 +223,10 @@ class cex(ccxt.async_support.cex):
|
|
218
223
|
#
|
219
224
|
data = self.safe_value(message, 'data', [])
|
220
225
|
stored = self.trades # to do fix self, self.trades is not meant to be used like self
|
221
|
-
|
222
|
-
|
226
|
+
dataLength = len(data)
|
227
|
+
for i in range(0, dataLength):
|
228
|
+
index = dataLength - 1 - i
|
229
|
+
rawTrade = data[index]
|
223
230
|
parsed = self.parse_ws_old_trade(rawTrade)
|
224
231
|
stored.append(parsed)
|
225
232
|
messageHash = 'trades'
|
@@ -325,12 +332,15 @@ class cex(ccxt.async_support.cex):
|
|
325
332
|
data = self.safe_value(message, 'data', {})
|
326
333
|
ticker = self.parse_ws_ticker(data)
|
327
334
|
symbol = ticker['symbol']
|
335
|
+
if symbol is None:
|
336
|
+
return
|
328
337
|
self.tickers[symbol] = ticker
|
329
338
|
messageHash = 'ticker:' + symbol
|
330
339
|
client.resolve(ticker, messageHash)
|
331
340
|
client.resolve(ticker, 'tickers')
|
332
341
|
messageHash = self.safe_string(message, 'oid')
|
333
|
-
|
342
|
+
if messageHash is not None:
|
343
|
+
client.resolve(ticker, messageHash)
|
334
344
|
|
335
345
|
def parse_ws_ticker(self, ticker, market=None):
|
336
346
|
#
|
ccxt/pro/okx.py
CHANGED
@@ -1236,7 +1236,8 @@ class okx(ccxt.async_support.okx):
|
|
1236
1236
|
stringMsg = self.json(message)
|
1237
1237
|
self.handle_errors(None, None, client.url, method, None, stringMsg, stringMsg, None, None)
|
1238
1238
|
orders = self.parse_orders(args, None, None, None)
|
1239
|
-
|
1239
|
+
first = self.safe_dict(orders, 0, {})
|
1240
|
+
client.resolve(first, messageHash)
|
1240
1241
|
|
1241
1242
|
async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
|
1242
1243
|
"""
|
ccxt/pro/p2b.py
CHANGED
@@ -57,6 +57,7 @@ class p2b(ccxt.async_support.p2b):
|
|
57
57
|
'watchTickers': {
|
58
58
|
'name': 'state', # or 'price'
|
59
59
|
},
|
60
|
+
'tickerSubs': self.create_safe_dictionary(),
|
60
61
|
},
|
61
62
|
'streaming': {
|
62
63
|
'ping': self.ping,
|
@@ -120,13 +121,14 @@ class p2b(ccxt.async_support.p2b):
|
|
120
121
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
121
122
|
"""
|
122
123
|
await self.load_markets()
|
123
|
-
watchTickerOptions = self.
|
124
|
+
watchTickerOptions = self.safe_dict(self.options, 'watchTicker')
|
124
125
|
name = self.safe_string(watchTickerOptions, 'name', 'state') # or price
|
125
126
|
name, params = self.handle_option_and_params(params, 'method', 'name', name)
|
126
127
|
market = self.market(symbol)
|
127
|
-
|
128
|
-
|
129
|
-
]
|
128
|
+
symbol = market['symbol']
|
129
|
+
self.options['tickerSubs'][market['id']] = True # we need to re-subscribe to all tickers upon watching a new ticker
|
130
|
+
tickerSubs = self.options['tickerSubs']
|
131
|
+
request = list(tickerSubs.keys())
|
130
132
|
messageHash = name + '::' + market['symbol']
|
131
133
|
return await self.subscribe(name + '.subscribe', messageHash, request, params)
|
132
134
|
|
@@ -407,3 +409,11 @@ class p2b(ccxt.async_support.p2b):
|
|
407
409
|
#
|
408
410
|
client.lastPong = self.safe_integer(message, 'id')
|
409
411
|
return message
|
412
|
+
|
413
|
+
def on_error(self, client: Client, error):
|
414
|
+
self.options['tickerSubs'] = self.create_safe_dictionary()
|
415
|
+
self.on_error(client, error)
|
416
|
+
|
417
|
+
def on_close(self, client: Client, error):
|
418
|
+
self.options['tickerSubs'] = self.create_safe_dictionary()
|
419
|
+
self.on_close(client, error)
|
ccxt/pro/woo.py
CHANGED
@@ -229,7 +229,7 @@ class woo(ccxt.async_support.woo):
|
|
229
229
|
|
230
230
|
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
231
231
|
"""
|
232
|
-
|
232
|
+
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
233
233
|
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
234
234
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
235
235
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
ccxt/probit.py
CHANGED
@@ -256,7 +256,7 @@ class probit(Exchange, ImplicitAPI):
|
|
256
256
|
},
|
257
257
|
})
|
258
258
|
|
259
|
-
def fetch_markets(self, params={}):
|
259
|
+
def fetch_markets(self, params={}) -> List[Market]:
|
260
260
|
"""
|
261
261
|
:see: https://docs-en.probit.com/reference/market
|
262
262
|
retrieves data on all markets for probit
|
ccxt/test/base/test_market.py
CHANGED
@@ -91,6 +91,9 @@ def test_market(exchange, skipped_properties, method, market):
|
|
91
91
|
# otherwise, it must be false or undefined
|
92
92
|
test_shared_methods.assert_in_array(exchange, skipped_properties, method, market, 'margin', [False, None])
|
93
93
|
if not ('contractSize' in skipped_properties):
|
94
|
+
if not market['spot']:
|
95
|
+
# if not spot, then contractSize should be defined
|
96
|
+
assert market['contractSize'] is not None, '\"contractSize\" must be defined when \"spot\" is false' + log_text
|
94
97
|
test_shared_methods.assert_greater(exchange, skipped_properties, method, market, 'contractSize', '0')
|
95
98
|
# typical values
|
96
99
|
test_shared_methods.assert_greater(exchange, skipped_properties, method, market, 'expiry', '0')
|
ccxt/timex.py
CHANGED
@@ -292,7 +292,7 @@ class timex(Exchange, ImplicitAPI):
|
|
292
292
|
#
|
293
293
|
return self.parse_to_int(response) * 1000
|
294
294
|
|
295
|
-
def fetch_markets(self, params={}):
|
295
|
+
def fetch_markets(self, params={}) -> List[Market]:
|
296
296
|
"""
|
297
297
|
retrieves data on all markets for timex
|
298
298
|
:see: https://plasma-relay-backend.timex.io/swagger-ui/index.html?urls.primaryName=Relay#/Public/listMarkets
|
ccxt/tokocrypto.py
CHANGED
@@ -637,7 +637,7 @@ class tokocrypto(Exchange, ImplicitAPI):
|
|
637
637
|
#
|
638
638
|
return self.safe_integer(response, 'serverTime')
|
639
639
|
|
640
|
-
def fetch_markets(self, params={}):
|
640
|
+
def fetch_markets(self, params={}) -> List[Market]:
|
641
641
|
"""
|
642
642
|
:see: https://www.tokocrypto.com/apidocs/#get-all-supported-trading-symbol
|
643
643
|
retrieves data on all markets for tokocrypto
|
ccxt/tradeogre.py
CHANGED
@@ -6,6 +6,7 @@
|
|
6
6
|
from ccxt.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.tradeogre import ImplicitAPI
|
8
8
|
from ccxt.base.types import IndexType, Int, Market, Num, Order, OrderSide, OrderType, Str, Ticker
|
9
|
+
from typing import List
|
9
10
|
from ccxt.base.errors import ExchangeError
|
10
11
|
from ccxt.base.errors import BadRequest
|
11
12
|
from ccxt.base.errors import InsufficientFunds
|
@@ -162,7 +163,7 @@ class tradeogre(Exchange, ImplicitAPI):
|
|
162
163
|
},
|
163
164
|
})
|
164
165
|
|
165
|
-
def fetch_markets(self, params={}):
|
166
|
+
def fetch_markets(self, params={}) -> List[Market]:
|
166
167
|
"""
|
167
168
|
retrieves data on all markets for bigone
|
168
169
|
:see: https://github.com/P2B-team/p2b-api-docs/blob/master/api-doc.md#markets
|
ccxt/upbit.py
CHANGED
@@ -403,7 +403,7 @@ class upbit(Exchange, ImplicitAPI):
|
|
403
403
|
},
|
404
404
|
})
|
405
405
|
|
406
|
-
def fetch_markets(self, params={}):
|
406
|
+
def fetch_markets(self, params={}) -> List[Market]:
|
407
407
|
"""
|
408
408
|
:see: https://docs.upbit.com/reference/%EB%A7%88%EC%BC%93-%EC%BD%94%EB%93%9C-%EC%A1%B0%ED%9A%8C
|
409
409
|
retrieves data on all markets for upbit
|
ccxt/wavesexchange.py
CHANGED
@@ -494,7 +494,7 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
494
494
|
self.options['quotes'] = quotes
|
495
495
|
return quotes
|
496
496
|
|
497
|
-
def fetch_markets(self, params={}):
|
497
|
+
def fetch_markets(self, params={}) -> List[Market]:
|
498
498
|
"""
|
499
499
|
retrieves data on all markets for wavesexchange
|
500
500
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
ccxt/wazirx.py
CHANGED
@@ -196,7 +196,7 @@ class wazirx(Exchange, ImplicitAPI):
|
|
196
196
|
},
|
197
197
|
})
|
198
198
|
|
199
|
-
def fetch_markets(self, params={}):
|
199
|
+
def fetch_markets(self, params={}) -> List[Market]:
|
200
200
|
"""
|
201
201
|
:see: https://docs.wazirx.com/#exchange-info
|
202
202
|
retrieves data on all markets for wazirx
|
ccxt/whitebit.py
CHANGED
@@ -281,7 +281,7 @@ class whitebit(Exchange, ImplicitAPI):
|
|
281
281
|
},
|
282
282
|
})
|
283
283
|
|
284
|
-
def fetch_markets(self, params={}):
|
284
|
+
def fetch_markets(self, params={}) -> List[Market]:
|
285
285
|
"""
|
286
286
|
retrieves data on all markets for whitebit
|
287
287
|
:see: https://docs.whitebit.com/public/http-v4/#market-info
|
ccxt/woo.py
CHANGED
@@ -387,7 +387,7 @@ class woo(Exchange, ImplicitAPI):
|
|
387
387
|
#
|
388
388
|
return self.safe_integer(response, 'timestamp')
|
389
389
|
|
390
|
-
def fetch_markets(self, params={}):
|
390
|
+
def fetch_markets(self, params={}) -> List[Market]:
|
391
391
|
"""
|
392
392
|
retrieves data on all markets for woo
|
393
393
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
ccxt/yobit.py
CHANGED
@@ -347,7 +347,7 @@ class yobit(Exchange, ImplicitAPI):
|
|
347
347
|
#
|
348
348
|
return self.parse_balance(response)
|
349
349
|
|
350
|
-
def fetch_markets(self, params={}):
|
350
|
+
def fetch_markets(self, params={}) -> List[Market]:
|
351
351
|
"""
|
352
352
|
:see: https://yobit.net/en/api
|
353
353
|
retrieves data on all markets for yobit
|
ccxt/zaif.py
CHANGED
@@ -143,7 +143,7 @@ class zaif(Exchange, ImplicitAPI):
|
|
143
143
|
},
|
144
144
|
})
|
145
145
|
|
146
|
-
def fetch_markets(self, params={}):
|
146
|
+
def fetch_markets(self, params={}) -> List[Market]:
|
147
147
|
"""
|
148
148
|
:see: https://zaif-api-document.readthedocs.io/ja/latest/PublicAPI.html#id12
|
149
149
|
retrieves data on all markets for zaif
|
ccxt/zonda.py
CHANGED
@@ -311,7 +311,7 @@ class zonda(Exchange, ImplicitAPI):
|
|
311
311
|
},
|
312
312
|
})
|
313
313
|
|
314
|
-
def fetch_markets(self, params={}):
|
314
|
+
def fetch_markets(self, params={}) -> List[Market]:
|
315
315
|
"""
|
316
316
|
:see: https://docs.zondacrypto.exchange/reference/ticker-1
|
317
317
|
retrieves data on all markets for zonda
|