ccxt 4.4.87__py2.py3-none-any.whl → 4.4.90__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ccxt/__init__.py +1 -1
- ccxt/abstract/bitget.py +58 -0
- ccxt/abstract/bitrue.py +65 -65
- ccxt/abstract/cryptocom.py +2 -0
- ccxt/abstract/luno.py +1 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +4 -1
- ccxt/async_support/binance.py +1 -1
- ccxt/async_support/bingx.py +55 -29
- ccxt/async_support/bitget.py +469 -147
- ccxt/async_support/bitrue.py +72 -66
- ccxt/async_support/bitvavo.py +34 -0
- ccxt/async_support/btcalpha.py +35 -0
- ccxt/async_support/btcbox.py +35 -0
- ccxt/async_support/btcmarkets.py +35 -0
- ccxt/async_support/btcturk.py +35 -0
- ccxt/async_support/bybit.py +28 -60
- ccxt/async_support/coinbase.py +1 -3
- ccxt/async_support/cryptocom.py +49 -0
- ccxt/async_support/delta.py +2 -2
- ccxt/async_support/digifinex.py +39 -99
- ccxt/async_support/gate.py +12 -5
- ccxt/async_support/hashkey.py +15 -28
- ccxt/async_support/hollaex.py +27 -22
- ccxt/async_support/kraken.py +28 -49
- ccxt/async_support/luno.py +87 -1
- ccxt/async_support/modetrade.py +7 -7
- ccxt/async_support/okx.py +2 -1
- ccxt/async_support/phemex.py +16 -8
- ccxt/async_support/tradeogre.py +3 -3
- ccxt/async_support/xt.py +1 -1
- ccxt/base/exchange.py +15 -5
- ccxt/binance.py +1 -1
- ccxt/bingx.py +55 -29
- ccxt/bitget.py +469 -147
- ccxt/bitrue.py +72 -66
- ccxt/bitvavo.py +34 -0
- ccxt/btcalpha.py +35 -0
- ccxt/btcbox.py +35 -0
- ccxt/btcmarkets.py +35 -0
- ccxt/btcturk.py +35 -0
- ccxt/bybit.py +28 -60
- ccxt/coinbase.py +1 -3
- ccxt/cryptocom.py +49 -0
- ccxt/delta.py +2 -2
- ccxt/digifinex.py +39 -99
- ccxt/gate.py +12 -5
- ccxt/hashkey.py +15 -28
- ccxt/hollaex.py +27 -22
- ccxt/kraken.py +27 -49
- ccxt/luno.py +87 -1
- ccxt/modetrade.py +7 -7
- ccxt/okx.py +2 -1
- ccxt/phemex.py +16 -8
- ccxt/pro/__init__.py +1 -119
- ccxt/pro/coinbase.py +2 -0
- ccxt/pro/cryptocom.py +27 -0
- ccxt/pro/kraken.py +3 -9
- ccxt/test/tests_async.py +1 -1
- ccxt/test/tests_sync.py +1 -1
- ccxt/tradeogre.py +3 -3
- ccxt/xt.py +1 -1
- {ccxt-4.4.87.dist-info → ccxt-4.4.90.dist-info}/METADATA +62 -20
- {ccxt-4.4.87.dist-info → ccxt-4.4.90.dist-info}/RECORD +67 -67
- {ccxt-4.4.87.dist-info → ccxt-4.4.90.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.87.dist-info → ccxt-4.4.90.dist-info}/WHEEL +0 -0
- {ccxt-4.4.87.dist-info → ccxt-4.4.90.dist-info}/top_level.txt +0 -0
ccxt/bybit.py
CHANGED
@@ -2301,15 +2301,9 @@ class bybit(Exchange, ImplicitAPI):
|
|
2301
2301
|
# 'baseCoin': '', Base coin. For option only
|
2302
2302
|
# 'expDate': '', Expiry date. e.g., 25DEC22. For option only
|
2303
2303
|
}
|
2304
|
-
|
2305
|
-
|
2306
|
-
|
2307
|
-
if market['option']:
|
2308
|
-
request['category'] = 'option'
|
2309
|
-
elif market['linear']:
|
2310
|
-
request['category'] = 'linear'
|
2311
|
-
elif market['inverse']:
|
2312
|
-
request['category'] = 'inverse'
|
2304
|
+
category = None
|
2305
|
+
category, params = self.get_bybit_type('fetchTicker', market, params)
|
2306
|
+
request['category'] = category
|
2313
2307
|
response = self.publicGetV5MarketTickers(self.extend(request, params))
|
2314
2308
|
#
|
2315
2309
|
# {
|
@@ -2401,24 +2395,14 @@ class bybit(Exchange, ImplicitAPI):
|
|
2401
2395
|
# 'baseCoin': '', # Base coin. For option only
|
2402
2396
|
# 'expDate': '', # Expiry date. e.g., 25DEC22. For option only
|
2403
2397
|
}
|
2404
|
-
|
2405
|
-
|
2406
|
-
|
2407
|
-
|
2408
|
-
# with higher priority and only default to spot, if `subType` is not set in params
|
2409
|
-
passedSubType = self.safe_string(params, 'subType')
|
2410
|
-
subType = None
|
2411
|
-
subType, params = self.handle_sub_type_and_params('fetchTickers', market, params, 'linear')
|
2412
|
-
# only if passedSubType is None, then use spot
|
2413
|
-
if type == 'spot' and passedSubType is None:
|
2414
|
-
request['category'] = 'spot'
|
2415
|
-
elif type == 'option':
|
2398
|
+
category = None
|
2399
|
+
category, params = self.get_bybit_type('fetchTickers', market, params)
|
2400
|
+
request['category'] = category
|
2401
|
+
if category == 'option':
|
2416
2402
|
request['category'] = 'option'
|
2417
2403
|
if code is None:
|
2418
2404
|
code = 'BTC'
|
2419
2405
|
request['baseCoin'] = code
|
2420
|
-
elif type == 'swap' or type == 'future' or subType is not None:
|
2421
|
-
request['category'] = subType
|
2422
2406
|
response = self.publicGetV5MarketTickers(self.extend(request, params))
|
2423
2407
|
#
|
2424
2408
|
# {
|
@@ -3691,7 +3675,10 @@ class bybit(Exchange, ImplicitAPI):
|
|
3691
3675
|
market = self.market(symbol)
|
3692
3676
|
if not market['spot']:
|
3693
3677
|
raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
|
3694
|
-
|
3678
|
+
req = {
|
3679
|
+
'cost': cost,
|
3680
|
+
}
|
3681
|
+
return self.create_order(symbol, 'market', 'buy', -1, None, self.extend(req, params))
|
3695
3682
|
|
3696
3683
|
def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}) -> Order:
|
3697
3684
|
"""
|
@@ -3712,7 +3699,10 @@ class bybit(Exchange, ImplicitAPI):
|
|
3712
3699
|
market = self.market(symbol)
|
3713
3700
|
if not market['spot']:
|
3714
3701
|
raise NotSupported(self.id + ' createMarketSellOrderWithCost() supports spot orders only')
|
3715
|
-
|
3702
|
+
req = {
|
3703
|
+
'cost': cost,
|
3704
|
+
}
|
3705
|
+
return self.create_order(symbol, 'market', 'sell', -1, None, self.extend(req, params))
|
3716
3706
|
|
3717
3707
|
def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
|
3718
3708
|
"""
|
@@ -3890,14 +3880,9 @@ class bybit(Exchange, ImplicitAPI):
|
|
3890
3880
|
request['orderLinkId'] = self.uuid16()
|
3891
3881
|
if isLimit:
|
3892
3882
|
request['price'] = priceString
|
3893
|
-
|
3894
|
-
|
3895
|
-
|
3896
|
-
request['category'] = 'option'
|
3897
|
-
elif market['linear']:
|
3898
|
-
request['category'] = 'linear'
|
3899
|
-
elif market['inverse']:
|
3900
|
-
request['category'] = 'inverse'
|
3883
|
+
category = None
|
3884
|
+
category, params = self.get_bybit_type('createOrderRequest', market, params)
|
3885
|
+
request['category'] = category
|
3901
3886
|
cost = self.safe_string(params, 'cost')
|
3902
3887
|
params = self.omit(params, 'cost')
|
3903
3888
|
# if the cost is inferable, let's keep the old logic and ignore marketUnit, to minimize the impact of the changes
|
@@ -3925,7 +3910,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
3925
3910
|
if (price is None) and (cost is None):
|
3926
3911
|
raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend in the amount argument')
|
3927
3912
|
else:
|
3928
|
-
quoteAmount = Precise.string_mul(
|
3913
|
+
quoteAmount = Precise.string_mul(self.number_to_string(amount), priceString)
|
3929
3914
|
costRequest = cost if (cost is not None) else quoteAmount
|
3930
3915
|
request['qty'] = self.get_cost(symbol, costRequest)
|
3931
3916
|
else:
|
@@ -4090,14 +4075,9 @@ class bybit(Exchange, ImplicitAPI):
|
|
4090
4075
|
# Valid for option only.
|
4091
4076
|
# 'orderIv': '0', # Implied volatility; parameters are passed according to the real value; for example, for 10%, 0.1 is passed
|
4092
4077
|
}
|
4093
|
-
|
4094
|
-
|
4095
|
-
|
4096
|
-
request['category'] = 'linear'
|
4097
|
-
elif market['inverse']:
|
4098
|
-
request['category'] = 'inverse'
|
4099
|
-
elif market['option']:
|
4100
|
-
request['category'] = 'option'
|
4078
|
+
category = None
|
4079
|
+
category, params = self.get_bybit_type('editOrderRequest', market, params)
|
4080
|
+
request['category'] = category
|
4101
4081
|
if amount is not None:
|
4102
4082
|
request['qty'] = self.get_amount(symbol, amount)
|
4103
4083
|
if price is not None:
|
@@ -4288,14 +4268,9 @@ class bybit(Exchange, ImplicitAPI):
|
|
4288
4268
|
request['orderFilter'] = 'StopOrder' if isTrigger else 'Order'
|
4289
4269
|
if id is not None: # The user can also use argument params["orderLinkId"]
|
4290
4270
|
request['orderId'] = id
|
4291
|
-
|
4292
|
-
|
4293
|
-
|
4294
|
-
request['category'] = 'linear'
|
4295
|
-
elif market['inverse']:
|
4296
|
-
request['category'] = 'inverse'
|
4297
|
-
elif market['option']:
|
4298
|
-
request['category'] = 'option'
|
4271
|
+
category = None
|
4272
|
+
category, params = self.get_bybit_type('cancelOrderRequest', market, params)
|
4273
|
+
request['category'] = category
|
4299
4274
|
return self.extend(request, params)
|
4300
4275
|
|
4301
4276
|
def cancel_order(self, id: str, symbol: Str = None, params={}) -> Order:
|
@@ -7188,14 +7163,7 @@ classic accounts only/ spot not supported* fetches information on an order made
|
|
7188
7163
|
'symbol': market['id'],
|
7189
7164
|
}
|
7190
7165
|
category = None
|
7191
|
-
|
7192
|
-
category = 'linear'
|
7193
|
-
elif market['inverse']:
|
7194
|
-
category = 'inverse'
|
7195
|
-
elif market['spot']:
|
7196
|
-
category = 'spot'
|
7197
|
-
else:
|
7198
|
-
category = 'option'
|
7166
|
+
category, params = self.get_bybit_type('fetchTradingFee', market, params)
|
7199
7167
|
request['category'] = category
|
7200
7168
|
response = self.privateGetV5AccountFeeRate(self.extend(request, params))
|
7201
7169
|
#
|
@@ -7434,9 +7402,9 @@ classic accounts only/ spot not supported* fetches information on an order made
|
|
7434
7402
|
request['symbol'] = market['id']
|
7435
7403
|
type = None
|
7436
7404
|
type, params = self.get_bybit_type('fetchMySettlementHistory', market, params)
|
7437
|
-
if type == 'spot'
|
7405
|
+
if type == 'spot':
|
7438
7406
|
raise NotSupported(self.id + ' fetchMySettlementHistory() is not supported for spot market')
|
7439
|
-
request['category'] =
|
7407
|
+
request['category'] = type
|
7440
7408
|
if limit is not None:
|
7441
7409
|
request['limit'] = limit
|
7442
7410
|
response = self.privateGetV5AssetDeliveryRecord(self.extend(request, params))
|
ccxt/coinbase.py
CHANGED
@@ -4408,7 +4408,7 @@ class coinbase(Exchange, ImplicitAPI):
|
|
4408
4408
|
"""
|
4409
4409
|
*futures only* closes open positions for a market
|
4410
4410
|
|
4411
|
-
https://coinbase
|
4411
|
+
https://docs.cdp.coinbase.com/coinbase-app/trade/reference/retailbrokerageapi_closeposition
|
4412
4412
|
|
4413
4413
|
:param str symbol: Unified CCXT market symbol
|
4414
4414
|
:param str [side]: not used by coinbase
|
@@ -4419,8 +4419,6 @@ class coinbase(Exchange, ImplicitAPI):
|
|
4419
4419
|
"""
|
4420
4420
|
self.load_markets()
|
4421
4421
|
market = self.market(symbol)
|
4422
|
-
if not market['future']:
|
4423
|
-
raise NotSupported(self.id + ' closePosition() only supported for futures markets')
|
4424
4422
|
clientOrderId = self.safe_string_2(params, 'client_order_id', 'clientOrderId')
|
4425
4423
|
params = self.omit(params, 'clientOrderId')
|
4426
4424
|
request: dict = {
|
ccxt/cryptocom.py
CHANGED
@@ -60,6 +60,7 @@ class cryptocom(Exchange, ImplicitAPI):
|
|
60
60
|
'createOrders': True,
|
61
61
|
'createStopOrder': True,
|
62
62
|
'createTriggerOrder': True,
|
63
|
+
'editOrder': True,
|
63
64
|
'fetchAccounts': True,
|
64
65
|
'fetchBalance': True,
|
65
66
|
'fetchBidsAsks': False,
|
@@ -152,6 +153,7 @@ class cryptocom(Exchange, ImplicitAPI):
|
|
152
153
|
'derivatives': 'https://uat-api.3ona.co/v2',
|
153
154
|
},
|
154
155
|
'api': {
|
156
|
+
'base': 'https://api.crypto.com',
|
155
157
|
'v1': 'https://api.crypto.com/exchange/v1',
|
156
158
|
'v2': 'https://api.crypto.com/v2',
|
157
159
|
'derivatives': 'https://deriv-api.crypto.com/v1',
|
@@ -169,6 +171,13 @@ class cryptocom(Exchange, ImplicitAPI):
|
|
169
171
|
'fees': 'https://crypto.com/exchange/document/fees-limits',
|
170
172
|
},
|
171
173
|
'api': {
|
174
|
+
'base': {
|
175
|
+
'public': {
|
176
|
+
'get': {
|
177
|
+
'v1/public/get-announcements': 1, # no description of rate limit
|
178
|
+
},
|
179
|
+
},
|
180
|
+
},
|
172
181
|
'v1': {
|
173
182
|
'public': {
|
174
183
|
'get': {
|
@@ -195,6 +204,7 @@ class cryptocom(Exchange, ImplicitAPI):
|
|
195
204
|
'private/user-balance-history': 10 / 3,
|
196
205
|
'private/get-positions': 10 / 3,
|
197
206
|
'private/create-order': 2 / 3,
|
207
|
+
'private/amend-order': 4 / 3, # no description of rate limit
|
198
208
|
'private/create-order-list': 10 / 3,
|
199
209
|
'private/cancel-order': 2 / 3,
|
200
210
|
'private/cancel-order-list': 10 / 3,
|
@@ -1551,6 +1561,45 @@ class cryptocom(Exchange, ImplicitAPI):
|
|
1551
1561
|
params = self.omit(params, ['postOnly', 'clientOrderId', 'timeInForce', 'stopPrice', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice'])
|
1552
1562
|
return self.extend(request, params)
|
1553
1563
|
|
1564
|
+
def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
|
1565
|
+
"""
|
1566
|
+
edit a trade order
|
1567
|
+
|
1568
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-amend-order
|
1569
|
+
|
1570
|
+
:param str id: order id
|
1571
|
+
:param str symbol: unified market symbol of the order to edit
|
1572
|
+
:param str [type]: not used by cryptocom editOrder
|
1573
|
+
:param str [side]: not used by cryptocom editOrder
|
1574
|
+
:param float amount:(mandatory) how much of the currency you want to trade in units of the base currency
|
1575
|
+
:param float price:(mandatory) the price for the order, in units of the quote currency, ignored in market orders
|
1576
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1577
|
+
:param str [params.clientOrderId]: the original client order id of the order to edit, required if id is not provided
|
1578
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1579
|
+
"""
|
1580
|
+
self.load_markets()
|
1581
|
+
request = self.edit_order_request(id, symbol, amount, price, params)
|
1582
|
+
response = self.v1PrivatePostPrivateAmendOrder(request)
|
1583
|
+
result = self.safe_dict(response, 'result', {})
|
1584
|
+
return self.parse_order(result)
|
1585
|
+
|
1586
|
+
def edit_order_request(self, id: str, symbol: str, amount: float, price: Num = None, params={}):
|
1587
|
+
request: dict = {}
|
1588
|
+
if id is not None:
|
1589
|
+
request['order_id'] = id
|
1590
|
+
else:
|
1591
|
+
originalClientOrderId = self.safe_string_2(params, 'orig_client_oid', 'clientOrderId')
|
1592
|
+
if originalClientOrderId is None:
|
1593
|
+
raise ArgumentsRequired(self.id + ' editOrder() requires an id argument or orig_client_oid parameter')
|
1594
|
+
else:
|
1595
|
+
request['orig_client_oid'] = originalClientOrderId
|
1596
|
+
params = self.omit(params, ['orig_client_oid', 'clientOrderId'])
|
1597
|
+
if (amount is None) or (price is None):
|
1598
|
+
raise ArgumentsRequired(self.id + ' editOrder() requires both amount and price arguments. If you do not want to change the amount or price, you should pass the original values')
|
1599
|
+
request['new_quantity'] = self.amount_to_precision(symbol, amount)
|
1600
|
+
request['new_price'] = self.price_to_precision(symbol, price)
|
1601
|
+
return self.extend(request, params)
|
1602
|
+
|
1554
1603
|
def cancel_all_orders(self, symbol: Str = None, params={}):
|
1555
1604
|
"""
|
1556
1605
|
cancel all open orders
|
ccxt/delta.py
CHANGED
@@ -906,9 +906,9 @@ class delta(Exchange, ImplicitAPI):
|
|
906
906
|
'inverse': None if spot else not linear,
|
907
907
|
'taker': self.safe_number(market, 'taker_commission_rate'),
|
908
908
|
'maker': self.safe_number(market, 'maker_commission_rate'),
|
909
|
-
'contractSize': contractSize,
|
909
|
+
'contractSize': None if spot else contractSize,
|
910
910
|
'expiry': expiry,
|
911
|
-
'expiryDatetime':
|
911
|
+
'expiryDatetime': self.iso8601(expiry), # do not use raw expiry string
|
912
912
|
'strike': self.parse_number(strike),
|
913
913
|
'optionType': optionType,
|
914
914
|
'precision': {
|
ccxt/digifinex.py
CHANGED
@@ -466,6 +466,16 @@ class digifinex(Exchange, ImplicitAPI):
|
|
466
466
|
'TRX': 'TRC20',
|
467
467
|
'VECHAIN': 'Vechain', # VET
|
468
468
|
},
|
469
|
+
'networksById': {
|
470
|
+
'TRC20': 'TRC20',
|
471
|
+
'TRX': 'TRC20',
|
472
|
+
'BEP20': 'BEP20',
|
473
|
+
'BSC': 'BEP20',
|
474
|
+
'ERC20': 'ERC20',
|
475
|
+
'ETH': 'ERC20',
|
476
|
+
'Polygon': 'POLYGON',
|
477
|
+
'Crypto.com': 'CRONOS',
|
478
|
+
},
|
469
479
|
},
|
470
480
|
'commonCurrencies': {
|
471
481
|
'BHT': 'Black House Test',
|
@@ -493,6 +503,7 @@ class digifinex(Exchange, ImplicitAPI):
|
|
493
503
|
# "min_withdraw_amount":10,
|
494
504
|
# "min_withdraw_fee":5,
|
495
505
|
# "currency":"USDT",
|
506
|
+
# "withdraw_fee_currency":"USDT",
|
496
507
|
# "withdraw_status":0,
|
497
508
|
# "chain":"OMNI"
|
498
509
|
# },
|
@@ -503,6 +514,7 @@ class digifinex(Exchange, ImplicitAPI):
|
|
503
514
|
# "min_withdraw_amount":10,
|
504
515
|
# "min_withdraw_fee":3,
|
505
516
|
# "currency":"USDT",
|
517
|
+
# "withdraw_fee_currency":"USDT",
|
506
518
|
# "withdraw_status":1,
|
507
519
|
# "chain":"ERC20"
|
508
520
|
# },
|
@@ -513,6 +525,7 @@ class digifinex(Exchange, ImplicitAPI):
|
|
513
525
|
# "min_withdraw_amount":0,
|
514
526
|
# "min_withdraw_fee":0,
|
515
527
|
# "currency":"DGF13",
|
528
|
+
# "withdraw_fee_currency":"DGF13",
|
516
529
|
# "withdraw_status":0,
|
517
530
|
# "chain":""
|
518
531
|
# },
|
@@ -520,118 +533,45 @@ class digifinex(Exchange, ImplicitAPI):
|
|
520
533
|
# "code":200
|
521
534
|
# }
|
522
535
|
#
|
523
|
-
data = self.
|
536
|
+
data = self.safe_list(response, 'data', [])
|
537
|
+
groupedById = self.group_by(data, 'currency')
|
538
|
+
keys = list(groupedById.keys())
|
524
539
|
result: dict = {}
|
525
|
-
for i in range(0, len(
|
526
|
-
|
527
|
-
|
540
|
+
for i in range(0, len(keys)):
|
541
|
+
id = keys[i]
|
542
|
+
networkEntries = groupedById[id]
|
528
543
|
code = self.safe_currency_code(id)
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
active = deposit and withdraw
|
534
|
-
feeString = self.safe_string(currency, 'min_withdraw_fee') # withdraw_fee_rate was zero for all currencies, so self was the worst case scenario
|
535
|
-
minWithdrawString = self.safe_string(currency, 'min_withdraw_amount')
|
536
|
-
minDepositString = self.safe_string(currency, 'min_deposit_amount')
|
537
|
-
minDeposit = self.parse_number(minDepositString)
|
538
|
-
minWithdraw = self.parse_number(minWithdrawString)
|
539
|
-
fee = self.parse_number(feeString)
|
540
|
-
# define precision with temporary way
|
541
|
-
minFoundPrecision = Precise.string_min(feeString, Precise.string_min(minDepositString, minWithdrawString))
|
542
|
-
precision = self.parse_number(minFoundPrecision)
|
543
|
-
networkId = self.safe_string(currency, 'chain')
|
544
|
-
networkCode = None
|
545
|
-
if networkId is not None:
|
544
|
+
networks = {}
|
545
|
+
for j in range(0, len(networkEntries)):
|
546
|
+
networkEntry = networkEntries[j]
|
547
|
+
networkId = self.safe_string(networkEntry, 'chain')
|
546
548
|
networkCode = self.network_id_to_code(networkId)
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
'deposit': deposit,
|
555
|
-
'withdraw': withdraw,
|
556
|
-
'limits': {
|
557
|
-
'amount': {
|
558
|
-
'min': None,
|
559
|
-
'max': None,
|
560
|
-
},
|
561
|
-
'withdraw': {
|
562
|
-
'min': minWithdraw,
|
563
|
-
'max': None,
|
564
|
-
},
|
565
|
-
'deposit': {
|
566
|
-
'min': minDeposit,
|
567
|
-
'max': None,
|
568
|
-
},
|
569
|
-
},
|
570
|
-
}
|
571
|
-
if code in result:
|
572
|
-
resultCodeInfo = result[code]['info']
|
573
|
-
if isinstance(resultCodeInfo, list):
|
574
|
-
resultCodeInfo.append(currency)
|
575
|
-
else:
|
576
|
-
resultCodeInfo = [resultCodeInfo, currency]
|
577
|
-
if withdraw:
|
578
|
-
result[code]['withdraw'] = True
|
579
|
-
result[code]['limits']['withdraw']['min'] = min(result[code]['limits']['withdraw']['min'], minWithdraw)
|
580
|
-
if deposit:
|
581
|
-
result[code]['deposit'] = True
|
582
|
-
result[code]['limits']['deposit']['min'] = min(result[code]['limits']['deposit']['min'], minDeposit)
|
583
|
-
if active:
|
584
|
-
result[code]['active'] = True
|
585
|
-
else:
|
586
|
-
result[code] = {
|
587
|
-
'id': id,
|
588
|
-
'code': code,
|
589
|
-
'info': currency,
|
590
|
-
'type': None,
|
591
|
-
'name': None,
|
592
|
-
'active': active,
|
593
|
-
'deposit': deposit,
|
594
|
-
'withdraw': withdraw,
|
595
|
-
'fee': self.parse_number(feeString),
|
549
|
+
networks[networkCode] = {
|
550
|
+
'id': networkId,
|
551
|
+
'network': networkCode,
|
552
|
+
'active': None,
|
553
|
+
'deposit': self.safe_integer(networkEntry, 'deposit_status') == 1,
|
554
|
+
'withdraw': self.safe_integer(networkEntry, 'withdraw_status') == 1,
|
555
|
+
'fee': self.safe_number(networkEntry, 'min_withdraw_fee'),
|
596
556
|
'precision': None,
|
597
557
|
'limits': {
|
598
|
-
'amount': {
|
599
|
-
'min': None,
|
600
|
-
'max': None,
|
601
|
-
},
|
602
558
|
'withdraw': {
|
603
|
-
'min':
|
559
|
+
'min': self.safe_number(networkEntry, 'min_withdraw_amount'),
|
604
560
|
'max': None,
|
605
561
|
},
|
606
562
|
'deposit': {
|
607
|
-
'min':
|
563
|
+
'min': self.safe_number(networkEntry, 'min_deposit_amount'),
|
608
564
|
'max': None,
|
609
565
|
},
|
610
566
|
},
|
611
|
-
'
|
612
|
-
}
|
613
|
-
if networkId is not None:
|
614
|
-
result[code]['networks'][networkId] = network
|
615
|
-
else:
|
616
|
-
result[code]['active'] = active
|
617
|
-
result[code]['fee'] = self.parse_number(feeString)
|
618
|
-
result[code]['deposit'] = deposit
|
619
|
-
result[code]['withdraw'] = withdraw
|
620
|
-
result[code]['limits'] = {
|
621
|
-
'amount': {
|
622
|
-
'min': None,
|
623
|
-
'max': None,
|
624
|
-
},
|
625
|
-
'withdraw': {
|
626
|
-
'min': minWithdraw,
|
627
|
-
'max': None,
|
628
|
-
},
|
629
|
-
'deposit': {
|
630
|
-
'min': minDeposit,
|
631
|
-
'max': None,
|
632
|
-
},
|
567
|
+
'info': networkEntry,
|
633
568
|
}
|
634
|
-
result[code]
|
569
|
+
result[code] = self.safe_currency_structure({
|
570
|
+
'id': id,
|
571
|
+
'code': code,
|
572
|
+
'info': networkEntries,
|
573
|
+
'networks': networks,
|
574
|
+
})
|
635
575
|
return result
|
636
576
|
|
637
577
|
def fetch_markets(self, params={}) -> List[Market]:
|
ccxt/gate.py
CHANGED
@@ -1263,17 +1263,21 @@ class gate(Exchange, ImplicitAPI):
|
|
1263
1263
|
# {
|
1264
1264
|
# "id": "QTUM_ETH",
|
1265
1265
|
# "base": "QTUM",
|
1266
|
+
# "base_name": "Quantum",
|
1266
1267
|
# "quote": "ETH",
|
1268
|
+
# "quote_name": "Ethereum",
|
1267
1269
|
# "fee": "0.2",
|
1268
1270
|
# "min_base_amount": "0.01",
|
1269
1271
|
# "min_quote_amount": "0.001",
|
1272
|
+
# "max_quote_amount": "50000",
|
1270
1273
|
# "amount_precision": 3,
|
1271
1274
|
# "precision": 6,
|
1272
1275
|
# "trade_status": "tradable",
|
1273
|
-
# "sell_start":
|
1274
|
-
# "buy_start":
|
1276
|
+
# "sell_start": 1607313600,
|
1277
|
+
# "buy_start": 1700492400,
|
1278
|
+
# "type": "normal",
|
1279
|
+
# "trade_url": "https://www.gate.io/trade/QTUM_ETH",
|
1275
1280
|
# }
|
1276
|
-
# ]
|
1277
1281
|
#
|
1278
1282
|
# Margin
|
1279
1283
|
#
|
@@ -1304,6 +1308,8 @@ class gate(Exchange, ImplicitAPI):
|
|
1304
1308
|
tradeStatus = self.safe_string(market, 'trade_status')
|
1305
1309
|
leverage = self.safe_number(market, 'leverage')
|
1306
1310
|
margin = leverage is not None
|
1311
|
+
buyStart = self.safe_integer_product(spotMarket, 'buy_start', 1000) # buy_start is the trading start time, while sell_start is offline orders start time
|
1312
|
+
createdTs = buyStart if (buyStart != 0) else None
|
1307
1313
|
result.append({
|
1308
1314
|
'id': id,
|
1309
1315
|
'symbol': base + '/' + quote,
|
@@ -1353,7 +1359,7 @@ class gate(Exchange, ImplicitAPI):
|
|
1353
1359
|
'max': self.safe_number(market, 'max_quote_amount') if margin else None,
|
1354
1360
|
},
|
1355
1361
|
},
|
1356
|
-
'created':
|
1362
|
+
'created': createdTs,
|
1357
1363
|
'info': market,
|
1358
1364
|
})
|
1359
1365
|
return result
|
@@ -1418,6 +1424,7 @@ class gate(Exchange, ImplicitAPI):
|
|
1418
1424
|
# "funding_next_apply": 1610035200,
|
1419
1425
|
# "short_users": 977,
|
1420
1426
|
# "config_change_time": 1609899548,
|
1427
|
+
# "create_time": 1609800048,
|
1421
1428
|
# "trade_size": 28530850594,
|
1422
1429
|
# "position_size": 5223816,
|
1423
1430
|
# "long_users": 455,
|
@@ -1548,7 +1555,7 @@ class gate(Exchange, ImplicitAPI):
|
|
1548
1555
|
'max': None,
|
1549
1556
|
},
|
1550
1557
|
},
|
1551
|
-
'created':
|
1558
|
+
'created': self.safe_integer_product(market, 'create_time', 1000),
|
1552
1559
|
'info': market,
|
1553
1560
|
}
|
1554
1561
|
|
ccxt/hashkey.py
CHANGED
@@ -1151,47 +1151,43 @@ class hashkey(Exchange, ImplicitAPI):
|
|
1151
1151
|
currecy = coins[i]
|
1152
1152
|
currencyId = self.safe_string(currecy, 'coinId')
|
1153
1153
|
code = self.safe_currency_code(currencyId)
|
1154
|
-
allowWithdraw = self.safe_bool(currecy, 'allowWithdraw')
|
1155
|
-
allowDeposit = self.safe_bool(currecy, 'allowDeposit')
|
1156
1154
|
networks = self.safe_list(currecy, 'chainTypes')
|
1157
|
-
networksById = self.safe_dict(self.options, 'networksById')
|
1158
1155
|
parsedNetworks: dict = {}
|
1159
1156
|
for j in range(0, len(networks)):
|
1160
1157
|
network = networks[j]
|
1161
1158
|
networkId = self.safe_string(network, 'chainType')
|
1162
|
-
|
1163
|
-
|
1164
|
-
networkDeposit = self.safe_bool(network, 'allowDeposit')
|
1165
|
-
networkWithdraw = self.safe_bool(network, 'allowWithdraw')
|
1166
|
-
parsedNetworks[networkName] = {
|
1159
|
+
networkCode = self.network_code_to_id(networkId)
|
1160
|
+
parsedNetworks[networkCode] = {
|
1167
1161
|
'id': networkId,
|
1168
|
-
'network':
|
1162
|
+
'network': networkCode,
|
1169
1163
|
'limits': {
|
1170
1164
|
'withdraw': {
|
1171
1165
|
'min': self.safe_number(network, 'minWithdrawQuantity'),
|
1172
|
-
'max': self.parse_number(maxWithdrawQuantity),
|
1166
|
+
'max': self.parse_number(self.omit_zero(self.safe_string(network, 'maxWithdrawQuantity'))),
|
1173
1167
|
},
|
1174
1168
|
'deposit': {
|
1175
1169
|
'min': self.safe_number(network, 'minDepositQuantity'),
|
1176
1170
|
'max': None,
|
1177
1171
|
},
|
1178
1172
|
},
|
1179
|
-
'active':
|
1180
|
-
'deposit':
|
1181
|
-
'withdraw':
|
1173
|
+
'active': None,
|
1174
|
+
'deposit': self.safe_bool(network, 'allowDeposit'),
|
1175
|
+
'withdraw': self.safe_bool(network, 'allowWithdraw'),
|
1182
1176
|
'fee': self.safe_number(network, 'withdrawFee'),
|
1183
1177
|
'precision': None,
|
1184
1178
|
'info': network,
|
1185
1179
|
}
|
1186
|
-
|
1180
|
+
rawType = self.safe_string(currecy, 'tokenType')
|
1181
|
+
type = 'fiat' if (rawType == 'REAL_MONEY') else 'crypto'
|
1182
|
+
result[code] = self.safe_currency_structure({
|
1187
1183
|
'id': currencyId,
|
1188
1184
|
'code': code,
|
1189
1185
|
'precision': None,
|
1190
|
-
'type':
|
1186
|
+
'type': type,
|
1191
1187
|
'name': self.safe_string(currecy, 'coinFullName'),
|
1192
|
-
'active':
|
1193
|
-
'deposit': allowDeposit,
|
1194
|
-
'withdraw': allowWithdraw,
|
1188
|
+
'active': None,
|
1189
|
+
'deposit': self.safe_bool(currecy, 'allowDeposit'),
|
1190
|
+
'withdraw': self.safe_bool(currecy, 'allowWithdraw'),
|
1195
1191
|
'fee': None,
|
1196
1192
|
'limits': {
|
1197
1193
|
'deposit': {
|
@@ -1205,18 +1201,9 @@ class hashkey(Exchange, ImplicitAPI):
|
|
1205
1201
|
},
|
1206
1202
|
'networks': parsedNetworks,
|
1207
1203
|
'info': currecy,
|
1208
|
-
}
|
1204
|
+
})
|
1209
1205
|
return result
|
1210
1206
|
|
1211
|
-
def parse_currency_type(self, type):
|
1212
|
-
types = {
|
1213
|
-
'CHAIN_TOKEN': 'crypto',
|
1214
|
-
'ERC20_TOKEN': 'crypto',
|
1215
|
-
'BSC_TOKEN': 'crypto',
|
1216
|
-
'REAL_MONEY': 'fiat',
|
1217
|
-
}
|
1218
|
-
return self.safe_string(types, type)
|
1219
|
-
|
1220
1207
|
def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
1221
1208
|
"""
|
1222
1209
|
fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|