ccxt 4.4.75__py2.py3-none-any.whl → 4.4.78__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ccxt/__init__.py +3 -3
- ccxt/abstract/apex.py +31 -0
- ccxt/abstract/myokx.py +4 -0
- ccxt/abstract/okx.py +4 -0
- ccxt/abstract/upbit.py +51 -37
- ccxt/abstract/xt.py +3 -0
- ccxt/apex.py +1884 -0
- ccxt/ascendex.py +2 -2
- ccxt/async_support/__init__.py +3 -3
- ccxt/async_support/apex.py +1884 -0
- ccxt/async_support/ascendex.py +2 -2
- ccxt/async_support/base/exchange.py +2 -2
- ccxt/async_support/binance.py +39 -217
- ccxt/async_support/bingx.py +1 -1
- ccxt/async_support/bitfinex.py +2 -2
- ccxt/async_support/bitflyer.py +2 -2
- ccxt/async_support/bitget.py +135 -65
- ccxt/async_support/bitmart.py +2 -2
- ccxt/async_support/bitmex.py +6 -6
- ccxt/async_support/bitrue.py +48 -0
- ccxt/async_support/cex.py +1 -1
- ccxt/async_support/coinbase.py +29 -4
- ccxt/async_support/coincatch.py +66 -0
- ccxt/async_support/coinex.py +3 -1
- ccxt/async_support/coinlist.py +85 -2
- ccxt/async_support/cryptocom.py +2 -2
- ccxt/async_support/defx.py +1 -1
- ccxt/async_support/delta.py +1 -1
- ccxt/async_support/deribit.py +2 -2
- ccxt/async_support/derive.py +2 -2
- ccxt/async_support/digifinex.py +2 -2
- ccxt/async_support/gate.py +1 -1
- ccxt/async_support/hitbtc.py +5 -2
- ccxt/async_support/htx.py +2 -2
- ccxt/async_support/hyperliquid.py +13 -6
- ccxt/async_support/kraken.py +2 -2
- ccxt/async_support/krakenfutures.py +2 -2
- ccxt/async_support/kucoinfutures.py +2 -2
- ccxt/async_support/mexc.py +50 -52
- ccxt/async_support/okx.py +21 -9
- ccxt/async_support/oxfun.py +2 -2
- ccxt/async_support/paradex.py +5 -10
- ccxt/async_support/phemex.py +4 -3
- ccxt/async_support/poloniex.py +3 -3
- ccxt/async_support/probit.py +1 -0
- ccxt/async_support/tradeogre.py +2 -1
- ccxt/async_support/upbit.py +265 -89
- ccxt/async_support/vertex.py +2 -2
- ccxt/async_support/whitebit.py +1 -0
- ccxt/async_support/woo.py +5 -3
- ccxt/async_support/woofipro.py +2 -2
- ccxt/async_support/xt.py +115 -5
- ccxt/base/exchange.py +76 -3
- ccxt/binance.py +39 -217
- ccxt/bingx.py +1 -1
- ccxt/bitfinex.py +2 -2
- ccxt/bitflyer.py +2 -2
- ccxt/bitget.py +135 -65
- ccxt/bitmart.py +2 -2
- ccxt/bitmex.py +6 -6
- ccxt/bitrue.py +48 -0
- ccxt/cex.py +1 -1
- ccxt/coinbase.py +29 -4
- ccxt/coincatch.py +66 -0
- ccxt/coinex.py +3 -1
- ccxt/coinlist.py +85 -2
- ccxt/cryptocom.py +2 -2
- ccxt/defx.py +1 -1
- ccxt/delta.py +1 -1
- ccxt/deribit.py +2 -2
- ccxt/derive.py +2 -2
- ccxt/digifinex.py +2 -2
- ccxt/gate.py +1 -1
- ccxt/hitbtc.py +5 -2
- ccxt/htx.py +2 -2
- ccxt/hyperliquid.py +13 -6
- ccxt/kraken.py +2 -2
- ccxt/krakenfutures.py +2 -2
- ccxt/kucoinfutures.py +2 -2
- ccxt/mexc.py +50 -52
- ccxt/okx.py +21 -9
- ccxt/oxfun.py +2 -2
- ccxt/paradex.py +5 -10
- ccxt/phemex.py +4 -3
- ccxt/poloniex.py +3 -3
- ccxt/pro/__init__.py +5 -1
- ccxt/pro/apex.py +984 -0
- ccxt/pro/coinbase.py +4 -6
- ccxt/pro/gate.py +22 -2
- ccxt/pro/hollaex.py +2 -2
- ccxt/pro/hyperliquid.py +1 -1
- ccxt/pro/p2b.py +2 -2
- ccxt/pro/tradeogre.py +272 -0
- ccxt/probit.py +1 -0
- ccxt/test/tests_async.py +27 -0
- ccxt/test/tests_sync.py +27 -0
- ccxt/tradeogre.py +2 -1
- ccxt/upbit.py +265 -89
- ccxt/vertex.py +2 -2
- ccxt/whitebit.py +1 -0
- ccxt/woo.py +5 -3
- ccxt/woofipro.py +2 -2
- ccxt/xt.py +115 -5
- {ccxt-4.4.75.dist-info → ccxt-4.4.78.dist-info}/METADATA +4 -4
- {ccxt-4.4.75.dist-info → ccxt-4.4.78.dist-info}/RECORD +108 -106
- ccxt/abstract/ace.py +0 -15
- ccxt/ace.py +0 -1152
- ccxt/async_support/ace.py +0 -1152
- {ccxt-4.4.75.dist-info → ccxt-4.4.78.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.75.dist-info → ccxt-4.4.78.dist-info}/WHEEL +0 -0
- {ccxt-4.4.75.dist-info → ccxt-4.4.78.dist-info}/top_level.txt +0 -0
ccxt/pro/coinbase.py
CHANGED
@@ -641,10 +641,12 @@ class coinbase(ccxt.async_support.coinbase):
|
|
641
641
|
event = events[i]
|
642
642
|
updates = self.safe_value(event, 'updates', [])
|
643
643
|
marketId = self.safe_string(event, 'product_id')
|
644
|
-
|
644
|
+
# sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD, are aliases
|
645
|
+
market = self.safe_market(marketId)
|
646
|
+
messageHash = 'level2::' + market['id']
|
647
|
+
symbol = market['symbol']
|
645
648
|
subscription = self.safe_value(client.subscriptions, messageHash, {})
|
646
649
|
limit = self.safe_integer(subscription, 'limit')
|
647
|
-
symbol = self.safe_symbol(marketId)
|
648
650
|
type = self.safe_string(event, 'type')
|
649
651
|
if type == 'snapshot':
|
650
652
|
self.orderbooks[symbol] = self.order_book({}, limit)
|
@@ -654,8 +656,6 @@ class coinbase(ccxt.async_support.coinbase):
|
|
654
656
|
orderbook['datetime'] = datetime
|
655
657
|
orderbook['symbol'] = symbol
|
656
658
|
client.resolve(orderbook, messageHash)
|
657
|
-
if messageHash.endswith('USD'):
|
658
|
-
client.resolve(orderbook, messageHash + 'C') # sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
|
659
659
|
elif type == 'update':
|
660
660
|
orderbook = self.orderbooks[symbol]
|
661
661
|
self.handle_order_book_helper(orderbook, updates)
|
@@ -663,8 +663,6 @@ class coinbase(ccxt.async_support.coinbase):
|
|
663
663
|
orderbook['timestamp'] = self.parse8601(datetime)
|
664
664
|
orderbook['symbol'] = symbol
|
665
665
|
client.resolve(orderbook, messageHash)
|
666
|
-
if messageHash.endswith('USD'):
|
667
|
-
client.resolve(orderbook, messageHash + 'C') # sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
|
668
666
|
|
669
667
|
def handle_subscription_status(self, client, message):
|
670
668
|
#
|
ccxt/pro/gate.py
CHANGED
@@ -1175,8 +1175,28 @@ class gate(ccxt.async_support.gate):
|
|
1175
1175
|
for i in range(0, len(data)):
|
1176
1176
|
rawPosition = data[i]
|
1177
1177
|
position = self.parse_position(rawPosition)
|
1178
|
-
|
1179
|
-
|
1178
|
+
symbol = self.safe_string(position, 'symbol')
|
1179
|
+
side = self.safe_string(position, 'side')
|
1180
|
+
# Control when position is closed no side is returned
|
1181
|
+
if side is None:
|
1182
|
+
prevLongPosition = self.safe_dict(cache, symbol + 'long')
|
1183
|
+
if prevLongPosition is not None:
|
1184
|
+
position['side'] = prevLongPosition['side']
|
1185
|
+
newPositions.append(position)
|
1186
|
+
cache.append(position)
|
1187
|
+
prevShortPosition = self.safe_dict(cache, symbol + 'short')
|
1188
|
+
if prevShortPosition is not None:
|
1189
|
+
position['side'] = prevShortPosition['side']
|
1190
|
+
newPositions.append(position)
|
1191
|
+
cache.append(position)
|
1192
|
+
# if no prev position is found, default to long
|
1193
|
+
if prevLongPosition is None and prevShortPosition is None:
|
1194
|
+
position['side'] = 'long'
|
1195
|
+
newPositions.append(position)
|
1196
|
+
cache.append(position)
|
1197
|
+
else:
|
1198
|
+
newPositions.append(position)
|
1199
|
+
cache.append(position)
|
1180
1200
|
messageHashes = self.find_message_hashes(client, type + ':positions::')
|
1181
1201
|
for i in range(0, len(messageHashes)):
|
1182
1202
|
messageHash = messageHashes[i]
|
ccxt/pro/hollaex.py
CHANGED
@@ -572,8 +572,8 @@ class hollaex(ccxt.async_support.hollaex):
|
|
572
572
|
|
573
573
|
def on_error(self, client: Client, error):
|
574
574
|
self.options['ws-expires'] = None
|
575
|
-
self.on_error(client, error)
|
575
|
+
super(hollaex, self).on_error(client, error)
|
576
576
|
|
577
577
|
def on_close(self, client: Client, error):
|
578
578
|
self.options['ws-expires'] = None
|
579
|
-
self.on_close(client, error)
|
579
|
+
super(hollaex, self).on_close(client, error)
|
ccxt/pro/hyperliquid.py
CHANGED
@@ -614,7 +614,7 @@ class hyperliquid(ccxt.async_support.hyperliquid):
|
|
614
614
|
'datetime': self.iso8601(timestamp),
|
615
615
|
'symbol': symbol,
|
616
616
|
'id': id,
|
617
|
-
'order':
|
617
|
+
'order': self.safe_string(trade, 'oid'),
|
618
618
|
'type': None,
|
619
619
|
'side': side,
|
620
620
|
'takerOrMaker': None,
|
ccxt/pro/p2b.py
CHANGED
@@ -478,8 +478,8 @@ class p2b(ccxt.async_support.p2b):
|
|
478
478
|
|
479
479
|
def on_error(self, client: Client, error):
|
480
480
|
self.options['tickerSubs'] = self.create_safe_dictionary()
|
481
|
-
self.on_error(client, error)
|
481
|
+
super(p2b, self).on_error(client, error)
|
482
482
|
|
483
483
|
def on_close(self, client: Client, error):
|
484
484
|
self.options['tickerSubs'] = self.create_safe_dictionary()
|
485
|
-
self.on_close(client, error)
|
485
|
+
super(p2b, self).on_close(client, error)
|
ccxt/pro/tradeogre.py
ADDED
@@ -0,0 +1,272 @@
|
|
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 Any, Int, OrderBook, Trade
|
9
|
+
from ccxt.async_support.base.ws.client import Client
|
10
|
+
from typing import List
|
11
|
+
|
12
|
+
|
13
|
+
class tradeogre(ccxt.async_support.tradeogre):
|
14
|
+
|
15
|
+
def describe(self) -> Any:
|
16
|
+
return self.deep_extend(super(tradeogre, self).describe(), {
|
17
|
+
'has': {
|
18
|
+
'ws': True,
|
19
|
+
'watchTrades': True,
|
20
|
+
'watchTradesForSymbols': True,
|
21
|
+
'watchOrderBook': True,
|
22
|
+
'watchOrderBookForSymbols': False,
|
23
|
+
'watchOHLCV': False,
|
24
|
+
'watchOHLCVForSymbols': False,
|
25
|
+
'watchOrders': False,
|
26
|
+
'watchMyTrades': False,
|
27
|
+
'watchTicker': False,
|
28
|
+
'watchTickers': False,
|
29
|
+
'watchBidsAsks': False,
|
30
|
+
'watchBalance': False,
|
31
|
+
'createOrderWs': False,
|
32
|
+
'editOrderWs': False,
|
33
|
+
'cancelOrderWs': False,
|
34
|
+
'cancelOrdersWs': False,
|
35
|
+
},
|
36
|
+
'urls': {
|
37
|
+
'api': {
|
38
|
+
'ws': 'wss://tradeogre.com:8443',
|
39
|
+
},
|
40
|
+
},
|
41
|
+
'options': {
|
42
|
+
},
|
43
|
+
'streaming': {
|
44
|
+
},
|
45
|
+
})
|
46
|
+
|
47
|
+
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
48
|
+
"""
|
49
|
+
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
50
|
+
|
51
|
+
https://tradeogre.com/help/api
|
52
|
+
|
53
|
+
:param str symbol: unified symbol of the market to fetch the order book for
|
54
|
+
:param int [limit]: the maximum amount of order book entries to return(not used by the exchange)
|
55
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
56
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
57
|
+
"""
|
58
|
+
await self.load_markets()
|
59
|
+
market = self.market(symbol)
|
60
|
+
url = self.urls['api']['ws']
|
61
|
+
messageHash = 'orderbook' + ':' + market['symbol']
|
62
|
+
request: dict = {
|
63
|
+
'a': 'subscribe',
|
64
|
+
'e': 'book',
|
65
|
+
't': market['id'],
|
66
|
+
}
|
67
|
+
orderbook = await self.watch(url, messageHash, self.extend(request, params), messageHash)
|
68
|
+
return orderbook.limit()
|
69
|
+
|
70
|
+
def handle_order_book(self, client: Client, message):
|
71
|
+
#
|
72
|
+
# initial snapshot is fetched with ccxt's fetchOrderBook
|
73
|
+
# the feed does not include a snapshot, just the deltas
|
74
|
+
#
|
75
|
+
# {
|
76
|
+
# "e": "book",
|
77
|
+
# "t": "ETH-USDT",
|
78
|
+
# "s": "10752324",
|
79
|
+
# "d": {
|
80
|
+
# "bids": {"1787.02497915": "0"},
|
81
|
+
# "asks": {}
|
82
|
+
# }
|
83
|
+
# }
|
84
|
+
#
|
85
|
+
marketId = self.safe_string(message, 't')
|
86
|
+
symbol = self.safe_symbol(marketId)
|
87
|
+
if not (symbol in self.orderbooks):
|
88
|
+
self.orderbooks[symbol] = self.order_book({})
|
89
|
+
storedOrderBook = self.orderbooks[symbol]
|
90
|
+
nonce = self.safe_integer(storedOrderBook, 'nonce')
|
91
|
+
deltaNonce = self.safe_integer(message, 's')
|
92
|
+
messageHash = 'orderbook:' + symbol
|
93
|
+
if nonce is None:
|
94
|
+
cacheLength = len(storedOrderBook.cache)
|
95
|
+
snapshotDelay = self.handle_option('watchOrderBook', 'snapshotDelay', 6)
|
96
|
+
if cacheLength == snapshotDelay:
|
97
|
+
self.spawn(self.load_order_book, client, messageHash, symbol, None, {})
|
98
|
+
storedOrderBook.cache.append(message)
|
99
|
+
return
|
100
|
+
elif nonce >= deltaNonce:
|
101
|
+
return
|
102
|
+
self.handle_delta(storedOrderBook, message)
|
103
|
+
client.resolve(storedOrderBook, messageHash)
|
104
|
+
|
105
|
+
def handle_delta(self, orderbook, delta):
|
106
|
+
# timestamp = self.milliseconds() # todo check if self is correct
|
107
|
+
# orderbook['timestamp'] = timestamp
|
108
|
+
# orderbook['datetime'] = self.iso8601(timestamp)
|
109
|
+
orderbook['nonce'] = self.safe_integer(delta, 's')
|
110
|
+
data = self.safe_dict(delta, 'd', {})
|
111
|
+
bids = self.safe_dict(data, 'bids', {})
|
112
|
+
asks = self.safe_dict(data, 'asks', {})
|
113
|
+
storedBids = orderbook['bids']
|
114
|
+
storedAsks = orderbook['asks']
|
115
|
+
self.handle_bid_asks(storedBids, bids)
|
116
|
+
self.handle_bid_asks(storedAsks, asks)
|
117
|
+
|
118
|
+
def handle_bid_asks(self, bookSide, bidAsks):
|
119
|
+
keys = list(bidAsks.keys())
|
120
|
+
for i in range(0, len(keys)):
|
121
|
+
price = self.safe_string(keys, i)
|
122
|
+
amount = self.safe_number(bidAsks, price)
|
123
|
+
bidAsk = [self.parse_number(price), amount]
|
124
|
+
bookSide.storeArray(bidAsk)
|
125
|
+
# for i in range(0, len(bidAsks)):
|
126
|
+
# bidAsk = self.parse_bid_ask(bidAsks[i])
|
127
|
+
# bookSide.storeArray(bidAsk)
|
128
|
+
# }
|
129
|
+
|
130
|
+
def get_cache_index(self, orderbook, deltas):
|
131
|
+
firstElement = deltas[0]
|
132
|
+
firstElementNonce = self.safe_integer(firstElement, 's')
|
133
|
+
nonce = self.safe_integer(orderbook, 'nonce')
|
134
|
+
if nonce < firstElementNonce:
|
135
|
+
return -1
|
136
|
+
for i in range(0, len(deltas)):
|
137
|
+
delta = deltas[i]
|
138
|
+
deltaNonce = self.safe_integer(delta, 's')
|
139
|
+
if deltaNonce == nonce:
|
140
|
+
return i + 1
|
141
|
+
return len(deltas)
|
142
|
+
|
143
|
+
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
144
|
+
"""
|
145
|
+
watches information on multiple trades made in a market
|
146
|
+
|
147
|
+
https://tradeogre.com/help/api
|
148
|
+
|
149
|
+
:param str symbol: unified market symbol of the market trades were made in
|
150
|
+
:param int [since]: the earliest time in ms to fetch trades for
|
151
|
+
:param int [limit]: the maximum number of trade structures to retrieve
|
152
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
153
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
154
|
+
"""
|
155
|
+
await self.load_markets()
|
156
|
+
market = self.market(symbol)
|
157
|
+
symbol = market['symbol']
|
158
|
+
return await self.watch_trades_for_symbols([symbol], since, limit, params)
|
159
|
+
|
160
|
+
async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
161
|
+
"""
|
162
|
+
|
163
|
+
https://tradeogre.com/help/api
|
164
|
+
|
165
|
+
get the list of most recent trades for a list of symbols
|
166
|
+
:param str[] symbols: unified symbol of the market to fetch trades for(empty array means all markets)
|
167
|
+
:param int [since]: timestamp in ms of the earliest trade to fetch
|
168
|
+
:param int [limit]: the maximum amount of trades to fetch
|
169
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
170
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
171
|
+
"""
|
172
|
+
await self.load_markets()
|
173
|
+
symbols = self.market_symbols(symbols, None, True)
|
174
|
+
messageHashes = []
|
175
|
+
symbolsLength = 0
|
176
|
+
if symbols is not None:
|
177
|
+
symbolsLength = len(symbols)
|
178
|
+
if symbolsLength > 0:
|
179
|
+
for i in range(0, len(symbols)):
|
180
|
+
symbol = symbols[i]
|
181
|
+
messageHash = 'trades:' + symbol
|
182
|
+
messageHashes.append(messageHash)
|
183
|
+
else:
|
184
|
+
messageHash = 'trades'
|
185
|
+
messageHashes.append(messageHash)
|
186
|
+
request: dict = {
|
187
|
+
'a': 'subscribe',
|
188
|
+
'e': 'trade',
|
189
|
+
't': '*',
|
190
|
+
}
|
191
|
+
url = self.urls['api']['ws']
|
192
|
+
trades = await self.watch_multiple(url, messageHashes, self.extend(request, params), ['trades'])
|
193
|
+
if self.newUpdates:
|
194
|
+
first = self.safe_dict(trades, 0)
|
195
|
+
tradeSymbol = self.safe_string(first, 'symbol')
|
196
|
+
limit = trades.getLimit(tradeSymbol, limit)
|
197
|
+
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
198
|
+
|
199
|
+
def handle_trade(self, client: Client, message):
|
200
|
+
#
|
201
|
+
# {
|
202
|
+
# "e": "trade",
|
203
|
+
# "t": "LTC-USDT",
|
204
|
+
# "d": {
|
205
|
+
# "t": 0,
|
206
|
+
# "p": "84.50000000",
|
207
|
+
# "q": "1.28471270",
|
208
|
+
# "d": "1745392002"
|
209
|
+
# }
|
210
|
+
# }
|
211
|
+
#
|
212
|
+
marketId = self.safe_string(message, 't')
|
213
|
+
market = self.safe_market(marketId)
|
214
|
+
data = self.safe_dict(message, 'd', {})
|
215
|
+
symbol = market['symbol']
|
216
|
+
if not (symbol in self.trades):
|
217
|
+
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
218
|
+
stored = ArrayCache(limit)
|
219
|
+
self.trades[symbol] = stored
|
220
|
+
cache = self.trades[symbol]
|
221
|
+
trade = self.parse_ws_trade(data, market)
|
222
|
+
cache.append(trade)
|
223
|
+
messageHash = 'trades:' + symbol
|
224
|
+
client.resolve(cache, messageHash)
|
225
|
+
client.resolve(cache, 'trades')
|
226
|
+
|
227
|
+
def parse_ws_trade(self, trade, market=None):
|
228
|
+
#
|
229
|
+
# {
|
230
|
+
# "t": 0,
|
231
|
+
# "p": "84.50000000",
|
232
|
+
# "q": "1.28471270",
|
233
|
+
# "d": "1745392002"
|
234
|
+
# }
|
235
|
+
#
|
236
|
+
timestamp = self.safe_integer_product(trade, 'd', 1000)
|
237
|
+
sideEnum = self.safe_string(trade, 't')
|
238
|
+
return self.safe_trade({
|
239
|
+
'info': trade,
|
240
|
+
'id': None,
|
241
|
+
'timestamp': timestamp,
|
242
|
+
'datetime': self.iso8601(timestamp),
|
243
|
+
'symbol': self.safe_string(market, 'symbol'),
|
244
|
+
'order': None,
|
245
|
+
'type': None,
|
246
|
+
'side': self.parse_ws_trade_side(sideEnum),
|
247
|
+
'takerOrMaker': None,
|
248
|
+
'price': self.safe_string(trade, 'p'),
|
249
|
+
'amount': self.safe_string(trade, 'q'),
|
250
|
+
'cost': None,
|
251
|
+
'fee': {
|
252
|
+
'currency': None,
|
253
|
+
'cost': None,
|
254
|
+
},
|
255
|
+
}, market)
|
256
|
+
|
257
|
+
def parse_ws_trade_side(self, side):
|
258
|
+
sides = {
|
259
|
+
'0': 'buy',
|
260
|
+
'1': 'sell',
|
261
|
+
}
|
262
|
+
return self.safe_string(sides, side, side)
|
263
|
+
|
264
|
+
def handle_message(self, client: Client, message):
|
265
|
+
methods: dict = {
|
266
|
+
'book': self.handle_order_book,
|
267
|
+
'trade': self.handle_trade,
|
268
|
+
}
|
269
|
+
event = self.safe_string(message, 'e')
|
270
|
+
method = self.safe_value(methods, event)
|
271
|
+
if method is not None:
|
272
|
+
method(client, message)
|
ccxt/probit.py
CHANGED
@@ -563,6 +563,7 @@ class probit(Exchange, ImplicitAPI):
|
|
563
563
|
'active': active,
|
564
564
|
'deposit': deposit,
|
565
565
|
'withdraw': withdraw,
|
566
|
+
'type': 'crypto',
|
566
567
|
'fee': fee,
|
567
568
|
'precision': self.parse_number(self.parse_precision(self.safe_string(platform, 'precision'))),
|
568
569
|
'limits': {
|
ccxt/test/tests_async.py
CHANGED
@@ -896,6 +896,8 @@ class testMainClass:
|
|
896
896
|
async def test_request_statically(self, exchange, method, data, type, skip_keys):
|
897
897
|
output = None
|
898
898
|
request_url = None
|
899
|
+
if self.info:
|
900
|
+
dump('[INFO] STATIC REQUEST TEST:', method, ':', data['description'])
|
899
901
|
try:
|
900
902
|
if not is_sync():
|
901
903
|
await call_exchange_method_dynamically(exchange, method, self.sanitize_data_input(data['input']))
|
@@ -918,6 +920,8 @@ class testMainClass:
|
|
918
920
|
async def test_response_statically(self, exchange, method, skip_keys, data):
|
919
921
|
expected_result = exchange.safe_value(data, 'parsedResponse')
|
920
922
|
mocked_exchange = set_fetch_response(exchange, data['httpResponse'])
|
923
|
+
if self.info:
|
924
|
+
dump('[INFO] STATIC RESPONSE TEST:', method, ':', data['description'])
|
921
925
|
try:
|
922
926
|
if not is_sync():
|
923
927
|
unified_result = await call_exchange_method_dynamically(exchange, method, self.sanitize_data_input(data['input']))
|
@@ -1094,6 +1098,26 @@ class testMainClass:
|
|
1094
1098
|
sum = exchange.sum(sum, results_length)
|
1095
1099
|
return sum
|
1096
1100
|
|
1101
|
+
def check_if_exchange_is_disabled(self, exchange_name, exchange_data):
|
1102
|
+
exchange = init_exchange('Exchange', {})
|
1103
|
+
is_disabled_py = exchange.safe_bool(exchange_data, 'disabledPy', False)
|
1104
|
+
if is_disabled_py and (self.lang == 'PY'):
|
1105
|
+
dump('[TEST_WARNING] Exchange ' + exchange_name + ' is disabled in python')
|
1106
|
+
return True
|
1107
|
+
is_disabled_php = exchange.safe_bool(exchange_data, 'disabledPHP', False)
|
1108
|
+
if is_disabled_php and (self.lang == 'PHP'):
|
1109
|
+
dump('[TEST_WARNING] Exchange ' + exchange_name + ' is disabled in php')
|
1110
|
+
return True
|
1111
|
+
is_disabled_c_sharp = exchange.safe_bool(exchange_data, 'disabledCS', False)
|
1112
|
+
if is_disabled_c_sharp and (self.lang == 'C#'):
|
1113
|
+
dump('[TEST_WARNING] Exchange ' + exchange_name + ' is disabled in c#')
|
1114
|
+
return True
|
1115
|
+
is_disabled_go = exchange.safe_bool(exchange_data, 'disabledGO', False)
|
1116
|
+
if is_disabled_go and (self.lang == 'GO'):
|
1117
|
+
dump('[TEST_WARNING] Exchange ' + exchange_name + ' is disabled in go')
|
1118
|
+
return True
|
1119
|
+
return False
|
1120
|
+
|
1097
1121
|
async def run_static_request_tests(self, target_exchange=None, test_name=None):
|
1098
1122
|
await self.run_static_tests('request', target_exchange, test_name)
|
1099
1123
|
return True
|
@@ -1114,6 +1138,9 @@ class testMainClass:
|
|
1114
1138
|
for i in range(0, len(exchanges)):
|
1115
1139
|
exchange_name = exchanges[i]
|
1116
1140
|
exchange_data = static_data[exchange_name]
|
1141
|
+
disabled = self.check_if_exchange_is_disabled(exchange_name, exchange_data)
|
1142
|
+
if disabled:
|
1143
|
+
continue
|
1117
1144
|
number_of_tests = self.get_number_of_tests_from_exchange(exchange, exchange_data, test_name)
|
1118
1145
|
sum = exchange.sum(sum, number_of_tests)
|
1119
1146
|
if type == 'request':
|
ccxt/test/tests_sync.py
CHANGED
@@ -893,6 +893,8 @@ class testMainClass:
|
|
893
893
|
def test_request_statically(self, exchange, method, data, type, skip_keys):
|
894
894
|
output = None
|
895
895
|
request_url = None
|
896
|
+
if self.info:
|
897
|
+
dump('[INFO] STATIC REQUEST TEST:', method, ':', data['description'])
|
896
898
|
try:
|
897
899
|
if not is_sync():
|
898
900
|
call_exchange_method_dynamically(exchange, method, self.sanitize_data_input(data['input']))
|
@@ -915,6 +917,8 @@ class testMainClass:
|
|
915
917
|
def test_response_statically(self, exchange, method, skip_keys, data):
|
916
918
|
expected_result = exchange.safe_value(data, 'parsedResponse')
|
917
919
|
mocked_exchange = set_fetch_response(exchange, data['httpResponse'])
|
920
|
+
if self.info:
|
921
|
+
dump('[INFO] STATIC RESPONSE TEST:', method, ':', data['description'])
|
918
922
|
try:
|
919
923
|
if not is_sync():
|
920
924
|
unified_result = call_exchange_method_dynamically(exchange, method, self.sanitize_data_input(data['input']))
|
@@ -1091,6 +1095,26 @@ class testMainClass:
|
|
1091
1095
|
sum = exchange.sum(sum, results_length)
|
1092
1096
|
return sum
|
1093
1097
|
|
1098
|
+
def check_if_exchange_is_disabled(self, exchange_name, exchange_data):
|
1099
|
+
exchange = init_exchange('Exchange', {})
|
1100
|
+
is_disabled_py = exchange.safe_bool(exchange_data, 'disabledPy', False)
|
1101
|
+
if is_disabled_py and (self.lang == 'PY'):
|
1102
|
+
dump('[TEST_WARNING] Exchange ' + exchange_name + ' is disabled in python')
|
1103
|
+
return True
|
1104
|
+
is_disabled_php = exchange.safe_bool(exchange_data, 'disabledPHP', False)
|
1105
|
+
if is_disabled_php and (self.lang == 'PHP'):
|
1106
|
+
dump('[TEST_WARNING] Exchange ' + exchange_name + ' is disabled in php')
|
1107
|
+
return True
|
1108
|
+
is_disabled_c_sharp = exchange.safe_bool(exchange_data, 'disabledCS', False)
|
1109
|
+
if is_disabled_c_sharp and (self.lang == 'C#'):
|
1110
|
+
dump('[TEST_WARNING] Exchange ' + exchange_name + ' is disabled in c#')
|
1111
|
+
return True
|
1112
|
+
is_disabled_go = exchange.safe_bool(exchange_data, 'disabledGO', False)
|
1113
|
+
if is_disabled_go and (self.lang == 'GO'):
|
1114
|
+
dump('[TEST_WARNING] Exchange ' + exchange_name + ' is disabled in go')
|
1115
|
+
return True
|
1116
|
+
return False
|
1117
|
+
|
1094
1118
|
def run_static_request_tests(self, target_exchange=None, test_name=None):
|
1095
1119
|
self.run_static_tests('request', target_exchange, test_name)
|
1096
1120
|
return True
|
@@ -1111,6 +1135,9 @@ class testMainClass:
|
|
1111
1135
|
for i in range(0, len(exchanges)):
|
1112
1136
|
exchange_name = exchanges[i]
|
1113
1137
|
exchange_data = static_data[exchange_name]
|
1138
|
+
disabled = self.check_if_exchange_is_disabled(exchange_name, exchange_data)
|
1139
|
+
if disabled:
|
1140
|
+
continue
|
1114
1141
|
number_of_tests = self.get_number_of_tests_from_exchange(exchange, exchange_data, test_name)
|
1115
1142
|
sum = exchange.sum(sum, number_of_tests)
|
1116
1143
|
if type == 'request':
|
ccxt/tradeogre.py
CHANGED
@@ -24,7 +24,7 @@ class tradeogre(Exchange, ImplicitAPI):
|
|
24
24
|
'countries': [],
|
25
25
|
'rateLimit': 100,
|
26
26
|
'version': 'v2',
|
27
|
-
'pro':
|
27
|
+
'pro': True,
|
28
28
|
'has': {
|
29
29
|
'CORS': None,
|
30
30
|
'spot': True,
|
@@ -525,6 +525,7 @@ class tradeogre(Exchange, ImplicitAPI):
|
|
525
525
|
'asks': rawAsks,
|
526
526
|
}
|
527
527
|
orderbook = self.parse_order_book(rawOrderbook, symbol)
|
528
|
+
orderbook['nonce'] = self.safe_integer(response, 's')
|
528
529
|
return orderbook
|
529
530
|
|
530
531
|
def parse_bids_asks(self, bidasks, priceKey: IndexType = 0, amountKey: IndexType = 1, countOrIdKey: IndexType = 2):
|