ccxt 4.4.88__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 +1 -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 +9 -3
- 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/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 +13 -4
- 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 +9 -3
- 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/okx.py +2 -1
- ccxt/phemex.py +16 -8
- ccxt/pro/__init__.py +1 -127
- ccxt/pro/coinbase.py +2 -0
- ccxt/pro/cryptocom.py +27 -0
- ccxt/pro/kraken.py +3 -9
- ccxt/tradeogre.py +3 -3
- ccxt/xt.py +1 -1
- {ccxt-4.4.88.dist-info → ccxt-4.4.90.dist-info}/METADATA +62 -20
- {ccxt-4.4.88.dist-info → ccxt-4.4.90.dist-info}/RECORD +63 -63
- {ccxt-4.4.88.dist-info → ccxt-4.4.90.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.88.dist-info → ccxt-4.4.90.dist-info}/WHEEL +0 -0
- {ccxt-4.4.88.dist-info → ccxt-4.4.90.dist-info}/top_level.txt +0 -0
ccxt/async_support/bybit.py
CHANGED
@@ -3676,7 +3676,10 @@ class bybit(Exchange, ImplicitAPI):
|
|
3676
3676
|
market = self.market(symbol)
|
3677
3677
|
if not market['spot']:
|
3678
3678
|
raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
|
3679
|
-
|
3679
|
+
req = {
|
3680
|
+
'cost': cost,
|
3681
|
+
}
|
3682
|
+
return await self.create_order(symbol, 'market', 'buy', -1, None, self.extend(req, params))
|
3680
3683
|
|
3681
3684
|
async def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}) -> Order:
|
3682
3685
|
"""
|
@@ -3697,7 +3700,10 @@ class bybit(Exchange, ImplicitAPI):
|
|
3697
3700
|
market = self.market(symbol)
|
3698
3701
|
if not market['spot']:
|
3699
3702
|
raise NotSupported(self.id + ' createMarketSellOrderWithCost() supports spot orders only')
|
3700
|
-
|
3703
|
+
req = {
|
3704
|
+
'cost': cost,
|
3705
|
+
}
|
3706
|
+
return await self.create_order(symbol, 'market', 'sell', -1, None, self.extend(req, params))
|
3701
3707
|
|
3702
3708
|
async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
|
3703
3709
|
"""
|
@@ -3905,7 +3911,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
3905
3911
|
if (price is None) and (cost is None):
|
3906
3912
|
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')
|
3907
3913
|
else:
|
3908
|
-
quoteAmount = Precise.string_mul(
|
3914
|
+
quoteAmount = Precise.string_mul(self.number_to_string(amount), priceString)
|
3909
3915
|
costRequest = cost if (cost is not None) else quoteAmount
|
3910
3916
|
request['qty'] = self.get_cost(symbol, costRequest)
|
3911
3917
|
else:
|
ccxt/async_support/coinbase.py
CHANGED
@@ -4409,7 +4409,7 @@ class coinbase(Exchange, ImplicitAPI):
|
|
4409
4409
|
"""
|
4410
4410
|
*futures only* closes open positions for a market
|
4411
4411
|
|
4412
|
-
https://coinbase
|
4412
|
+
https://docs.cdp.coinbase.com/coinbase-app/trade/reference/retailbrokerageapi_closeposition
|
4413
4413
|
|
4414
4414
|
:param str symbol: Unified CCXT market symbol
|
4415
4415
|
:param str [side]: not used by coinbase
|
@@ -4420,8 +4420,6 @@ class coinbase(Exchange, ImplicitAPI):
|
|
4420
4420
|
"""
|
4421
4421
|
await self.load_markets()
|
4422
4422
|
market = self.market(symbol)
|
4423
|
-
if not market['future']:
|
4424
|
-
raise NotSupported(self.id + ' closePosition() only supported for futures markets')
|
4425
4423
|
clientOrderId = self.safe_string_2(params, 'client_order_id', 'clientOrderId')
|
4426
4424
|
params = self.omit(params, 'clientOrderId')
|
4427
4425
|
request: dict = {
|
ccxt/async_support/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
|
+
async 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
|
+
await self.load_markets()
|
1581
|
+
request = self.edit_order_request(id, symbol, amount, price, params)
|
1582
|
+
response = await 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
|
async def cancel_all_orders(self, symbol: Str = None, params={}):
|
1555
1604
|
"""
|
1556
1605
|
cancel all open orders
|
ccxt/async_support/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/async_support/digifinex.py
CHANGED
@@ -467,6 +467,16 @@ class digifinex(Exchange, ImplicitAPI):
|
|
467
467
|
'TRX': 'TRC20',
|
468
468
|
'VECHAIN': 'Vechain', # VET
|
469
469
|
},
|
470
|
+
'networksById': {
|
471
|
+
'TRC20': 'TRC20',
|
472
|
+
'TRX': 'TRC20',
|
473
|
+
'BEP20': 'BEP20',
|
474
|
+
'BSC': 'BEP20',
|
475
|
+
'ERC20': 'ERC20',
|
476
|
+
'ETH': 'ERC20',
|
477
|
+
'Polygon': 'POLYGON',
|
478
|
+
'Crypto.com': 'CRONOS',
|
479
|
+
},
|
470
480
|
},
|
471
481
|
'commonCurrencies': {
|
472
482
|
'BHT': 'Black House Test',
|
@@ -494,6 +504,7 @@ class digifinex(Exchange, ImplicitAPI):
|
|
494
504
|
# "min_withdraw_amount":10,
|
495
505
|
# "min_withdraw_fee":5,
|
496
506
|
# "currency":"USDT",
|
507
|
+
# "withdraw_fee_currency":"USDT",
|
497
508
|
# "withdraw_status":0,
|
498
509
|
# "chain":"OMNI"
|
499
510
|
# },
|
@@ -504,6 +515,7 @@ class digifinex(Exchange, ImplicitAPI):
|
|
504
515
|
# "min_withdraw_amount":10,
|
505
516
|
# "min_withdraw_fee":3,
|
506
517
|
# "currency":"USDT",
|
518
|
+
# "withdraw_fee_currency":"USDT",
|
507
519
|
# "withdraw_status":1,
|
508
520
|
# "chain":"ERC20"
|
509
521
|
# },
|
@@ -514,6 +526,7 @@ class digifinex(Exchange, ImplicitAPI):
|
|
514
526
|
# "min_withdraw_amount":0,
|
515
527
|
# "min_withdraw_fee":0,
|
516
528
|
# "currency":"DGF13",
|
529
|
+
# "withdraw_fee_currency":"DGF13",
|
517
530
|
# "withdraw_status":0,
|
518
531
|
# "chain":""
|
519
532
|
# },
|
@@ -521,118 +534,45 @@ class digifinex(Exchange, ImplicitAPI):
|
|
521
534
|
# "code":200
|
522
535
|
# }
|
523
536
|
#
|
524
|
-
data = self.
|
537
|
+
data = self.safe_list(response, 'data', [])
|
538
|
+
groupedById = self.group_by(data, 'currency')
|
539
|
+
keys = list(groupedById.keys())
|
525
540
|
result: dict = {}
|
526
|
-
for i in range(0, len(
|
527
|
-
|
528
|
-
|
541
|
+
for i in range(0, len(keys)):
|
542
|
+
id = keys[i]
|
543
|
+
networkEntries = groupedById[id]
|
529
544
|
code = self.safe_currency_code(id)
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
active = deposit and withdraw
|
535
|
-
feeString = self.safe_string(currency, 'min_withdraw_fee') # withdraw_fee_rate was zero for all currencies, so self was the worst case scenario
|
536
|
-
minWithdrawString = self.safe_string(currency, 'min_withdraw_amount')
|
537
|
-
minDepositString = self.safe_string(currency, 'min_deposit_amount')
|
538
|
-
minDeposit = self.parse_number(minDepositString)
|
539
|
-
minWithdraw = self.parse_number(minWithdrawString)
|
540
|
-
fee = self.parse_number(feeString)
|
541
|
-
# define precision with temporary way
|
542
|
-
minFoundPrecision = Precise.string_min(feeString, Precise.string_min(minDepositString, minWithdrawString))
|
543
|
-
precision = self.parse_number(minFoundPrecision)
|
544
|
-
networkId = self.safe_string(currency, 'chain')
|
545
|
-
networkCode = None
|
546
|
-
if networkId is not None:
|
545
|
+
networks = {}
|
546
|
+
for j in range(0, len(networkEntries)):
|
547
|
+
networkEntry = networkEntries[j]
|
548
|
+
networkId = self.safe_string(networkEntry, 'chain')
|
547
549
|
networkCode = self.network_id_to_code(networkId)
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
'deposit': deposit,
|
556
|
-
'withdraw': withdraw,
|
557
|
-
'limits': {
|
558
|
-
'amount': {
|
559
|
-
'min': None,
|
560
|
-
'max': None,
|
561
|
-
},
|
562
|
-
'withdraw': {
|
563
|
-
'min': minWithdraw,
|
564
|
-
'max': None,
|
565
|
-
},
|
566
|
-
'deposit': {
|
567
|
-
'min': minDeposit,
|
568
|
-
'max': None,
|
569
|
-
},
|
570
|
-
},
|
571
|
-
}
|
572
|
-
if code in result:
|
573
|
-
resultCodeInfo = result[code]['info']
|
574
|
-
if isinstance(resultCodeInfo, list):
|
575
|
-
resultCodeInfo.append(currency)
|
576
|
-
else:
|
577
|
-
resultCodeInfo = [resultCodeInfo, currency]
|
578
|
-
if withdraw:
|
579
|
-
result[code]['withdraw'] = True
|
580
|
-
result[code]['limits']['withdraw']['min'] = min(result[code]['limits']['withdraw']['min'], minWithdraw)
|
581
|
-
if deposit:
|
582
|
-
result[code]['deposit'] = True
|
583
|
-
result[code]['limits']['deposit']['min'] = min(result[code]['limits']['deposit']['min'], minDeposit)
|
584
|
-
if active:
|
585
|
-
result[code]['active'] = True
|
586
|
-
else:
|
587
|
-
result[code] = {
|
588
|
-
'id': id,
|
589
|
-
'code': code,
|
590
|
-
'info': currency,
|
591
|
-
'type': None,
|
592
|
-
'name': None,
|
593
|
-
'active': active,
|
594
|
-
'deposit': deposit,
|
595
|
-
'withdraw': withdraw,
|
596
|
-
'fee': self.parse_number(feeString),
|
550
|
+
networks[networkCode] = {
|
551
|
+
'id': networkId,
|
552
|
+
'network': networkCode,
|
553
|
+
'active': None,
|
554
|
+
'deposit': self.safe_integer(networkEntry, 'deposit_status') == 1,
|
555
|
+
'withdraw': self.safe_integer(networkEntry, 'withdraw_status') == 1,
|
556
|
+
'fee': self.safe_number(networkEntry, 'min_withdraw_fee'),
|
597
557
|
'precision': None,
|
598
558
|
'limits': {
|
599
|
-
'amount': {
|
600
|
-
'min': None,
|
601
|
-
'max': None,
|
602
|
-
},
|
603
559
|
'withdraw': {
|
604
|
-
'min':
|
560
|
+
'min': self.safe_number(networkEntry, 'min_withdraw_amount'),
|
605
561
|
'max': None,
|
606
562
|
},
|
607
563
|
'deposit': {
|
608
|
-
'min':
|
564
|
+
'min': self.safe_number(networkEntry, 'min_deposit_amount'),
|
609
565
|
'max': None,
|
610
566
|
},
|
611
567
|
},
|
612
|
-
'
|
613
|
-
}
|
614
|
-
if networkId is not None:
|
615
|
-
result[code]['networks'][networkId] = network
|
616
|
-
else:
|
617
|
-
result[code]['active'] = active
|
618
|
-
result[code]['fee'] = self.parse_number(feeString)
|
619
|
-
result[code]['deposit'] = deposit
|
620
|
-
result[code]['withdraw'] = withdraw
|
621
|
-
result[code]['limits'] = {
|
622
|
-
'amount': {
|
623
|
-
'min': None,
|
624
|
-
'max': None,
|
625
|
-
},
|
626
|
-
'withdraw': {
|
627
|
-
'min': minWithdraw,
|
628
|
-
'max': None,
|
629
|
-
},
|
630
|
-
'deposit': {
|
631
|
-
'min': minDeposit,
|
632
|
-
'max': None,
|
633
|
-
},
|
568
|
+
'info': networkEntry,
|
634
569
|
}
|
635
|
-
result[code]
|
570
|
+
result[code] = self.safe_currency_structure({
|
571
|
+
'id': id,
|
572
|
+
'code': code,
|
573
|
+
'info': networkEntries,
|
574
|
+
'networks': networks,
|
575
|
+
})
|
636
576
|
return result
|
637
577
|
|
638
578
|
async def fetch_markets(self, params={}) -> List[Market]:
|
ccxt/async_support/gate.py
CHANGED
@@ -1264,17 +1264,21 @@ class gate(Exchange, ImplicitAPI):
|
|
1264
1264
|
# {
|
1265
1265
|
# "id": "QTUM_ETH",
|
1266
1266
|
# "base": "QTUM",
|
1267
|
+
# "base_name": "Quantum",
|
1267
1268
|
# "quote": "ETH",
|
1269
|
+
# "quote_name": "Ethereum",
|
1268
1270
|
# "fee": "0.2",
|
1269
1271
|
# "min_base_amount": "0.01",
|
1270
1272
|
# "min_quote_amount": "0.001",
|
1273
|
+
# "max_quote_amount": "50000",
|
1271
1274
|
# "amount_precision": 3,
|
1272
1275
|
# "precision": 6,
|
1273
1276
|
# "trade_status": "tradable",
|
1274
|
-
# "sell_start":
|
1275
|
-
# "buy_start":
|
1277
|
+
# "sell_start": 1607313600,
|
1278
|
+
# "buy_start": 1700492400,
|
1279
|
+
# "type": "normal",
|
1280
|
+
# "trade_url": "https://www.gate.io/trade/QTUM_ETH",
|
1276
1281
|
# }
|
1277
|
-
# ]
|
1278
1282
|
#
|
1279
1283
|
# Margin
|
1280
1284
|
#
|
@@ -1305,6 +1309,8 @@ class gate(Exchange, ImplicitAPI):
|
|
1305
1309
|
tradeStatus = self.safe_string(market, 'trade_status')
|
1306
1310
|
leverage = self.safe_number(market, 'leverage')
|
1307
1311
|
margin = leverage is not None
|
1312
|
+
buyStart = self.safe_integer_product(spotMarket, 'buy_start', 1000) # buy_start is the trading start time, while sell_start is offline orders start time
|
1313
|
+
createdTs = buyStart if (buyStart != 0) else None
|
1308
1314
|
result.append({
|
1309
1315
|
'id': id,
|
1310
1316
|
'symbol': base + '/' + quote,
|
@@ -1354,7 +1360,7 @@ class gate(Exchange, ImplicitAPI):
|
|
1354
1360
|
'max': self.safe_number(market, 'max_quote_amount') if margin else None,
|
1355
1361
|
},
|
1356
1362
|
},
|
1357
|
-
'created':
|
1363
|
+
'created': createdTs,
|
1358
1364
|
'info': market,
|
1359
1365
|
})
|
1360
1366
|
return result
|
@@ -1419,6 +1425,7 @@ class gate(Exchange, ImplicitAPI):
|
|
1419
1425
|
# "funding_next_apply": 1610035200,
|
1420
1426
|
# "short_users": 977,
|
1421
1427
|
# "config_change_time": 1609899548,
|
1428
|
+
# "create_time": 1609800048,
|
1422
1429
|
# "trade_size": 28530850594,
|
1423
1430
|
# "position_size": 5223816,
|
1424
1431
|
# "long_users": 455,
|
@@ -1549,7 +1556,7 @@ class gate(Exchange, ImplicitAPI):
|
|
1549
1556
|
'max': None,
|
1550
1557
|
},
|
1551
1558
|
},
|
1552
|
-
'created':
|
1559
|
+
'created': self.safe_integer_product(market, 'create_time', 1000),
|
1553
1560
|
'info': market,
|
1554
1561
|
}
|
1555
1562
|
|
ccxt/async_support/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
|
async 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
|
ccxt/async_support/hollaex.py
CHANGED
@@ -15,6 +15,7 @@ from ccxt.base.errors import InsufficientFunds
|
|
15
15
|
from ccxt.base.errors import OrderNotFound
|
16
16
|
from ccxt.base.errors import OrderImmediatelyFillable
|
17
17
|
from ccxt.base.errors import NetworkError
|
18
|
+
from ccxt.base.errors import InvalidNonce
|
18
19
|
from ccxt.base.decimal_to_precision import TICK_SIZE
|
19
20
|
from ccxt.base.precise import Precise
|
20
21
|
|
@@ -262,6 +263,7 @@ class hollaex(Exchange, ImplicitAPI):
|
|
262
263
|
},
|
263
264
|
'exceptions': {
|
264
265
|
'broad': {
|
266
|
+
'API request is expired': InvalidNonce,
|
265
267
|
'Invalid token': AuthenticationError,
|
266
268
|
'Order not found': OrderNotFound,
|
267
269
|
'Insufficient balance': InsufficientFunds,
|
@@ -796,7 +798,8 @@ class hollaex(Exchange, ImplicitAPI):
|
|
796
798
|
# "price":0.147411,
|
797
799
|
# "timestamp":"2022-01-26T17:53:34.650Z",
|
798
800
|
# "order_id":"cba78ecb-4187-4da2-9d2f-c259aa693b5a",
|
799
|
-
# "fee":0.01031877,
|
801
|
+
# "fee":0.01031877,
|
802
|
+
# "fee_coin":"usdt"
|
800
803
|
# }
|
801
804
|
#
|
802
805
|
marketId = self.safe_string(trade, 'symbol')
|
@@ -809,11 +812,12 @@ class hollaex(Exchange, ImplicitAPI):
|
|
809
812
|
priceString = self.safe_string(trade, 'price')
|
810
813
|
amountString = self.safe_string(trade, 'size')
|
811
814
|
feeCostString = self.safe_string(trade, 'fee')
|
815
|
+
feeCoin = self.safe_string(trade, 'fee_coin')
|
812
816
|
fee = None
|
813
817
|
if feeCostString is not None:
|
814
818
|
fee = {
|
815
819
|
'cost': feeCostString,
|
816
|
-
'currency':
|
820
|
+
'currency': self.safe_currency_code(feeCoin),
|
817
821
|
}
|
818
822
|
return self.safe_trade({
|
819
823
|
'info': trade,
|
@@ -899,7 +903,7 @@ class hollaex(Exchange, ImplicitAPI):
|
|
899
903
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
900
904
|
:param str timeframe: the length of time each candle represents
|
901
905
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
902
|
-
:param int [limit]: the maximum amount of candles to fetch
|
906
|
+
:param int [limit]: the maximum amount of candles to fetch(max 500)
|
903
907
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
904
908
|
:param int [params.until]: timestamp in ms of the latest candle to fetch
|
905
909
|
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
@@ -910,16 +914,24 @@ class hollaex(Exchange, ImplicitAPI):
|
|
910
914
|
'symbol': market['id'],
|
911
915
|
'resolution': self.safe_string(self.timeframes, timeframe, timeframe),
|
912
916
|
}
|
917
|
+
paginate = False
|
918
|
+
maxLimit = 500
|
919
|
+
paginate, params = self.handle_option_and_params(params, 'fetchOHLCV', 'paginate', paginate)
|
920
|
+
if paginate:
|
921
|
+
return await self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimit)
|
913
922
|
until = self.safe_integer(params, 'until')
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
+
timeDelta = self.parse_timeframe(timeframe) * maxLimit * 1000
|
924
|
+
start = since
|
925
|
+
now = self.milliseconds()
|
926
|
+
if until is None and start is None:
|
927
|
+
until = now
|
928
|
+
start = until - timeDelta
|
929
|
+
elif until is None:
|
930
|
+
until = now # the exchange has not a lot of trades, so if we count until by limit and limit is small, it may return empty result
|
931
|
+
elif start is None:
|
932
|
+
start = until - timeDelta
|
933
|
+
request['from'] = self.parse_to_int(start / 1000) # convert to seconds
|
934
|
+
request['to'] = self.parse_to_int(until / 1000) # convert to seconds
|
923
935
|
params = self.omit(params, 'until')
|
924
936
|
response = await self.publicGetChart(self.extend(request, params))
|
925
937
|
#
|
@@ -1277,11 +1289,10 @@ class hollaex(Exchange, ImplicitAPI):
|
|
1277
1289
|
"""
|
1278
1290
|
await self.load_markets()
|
1279
1291
|
market = self.market(symbol)
|
1280
|
-
convertedAmount = float(self.amount_to_precision(symbol, amount))
|
1281
1292
|
request: dict = {
|
1282
1293
|
'symbol': market['id'],
|
1283
1294
|
'side': side,
|
1284
|
-
'size': self.
|
1295
|
+
'size': self.amount_to_precision(symbol, amount),
|
1285
1296
|
'type': type,
|
1286
1297
|
# 'stop': float(self.price_to_precision(symbol, stopPrice)),
|
1287
1298
|
# 'meta': {}, # other options such
|
@@ -1292,10 +1303,9 @@ class hollaex(Exchange, ImplicitAPI):
|
|
1292
1303
|
isMarketOrder = type == 'market'
|
1293
1304
|
postOnly = self.is_post_only(isMarketOrder, exchangeSpecificParam, params)
|
1294
1305
|
if not isMarketOrder:
|
1295
|
-
|
1296
|
-
request['price'] = self.normalize_number_if_needed(convertedPrice)
|
1306
|
+
request['price'] = self.price_to_precision(symbol, price)
|
1297
1307
|
if triggerPrice is not None:
|
1298
|
-
request['stop'] = self.
|
1308
|
+
request['stop'] = self.price_to_precision(symbol, triggerPrice)
|
1299
1309
|
if postOnly:
|
1300
1310
|
request['meta'] = {'post_only': True}
|
1301
1311
|
params = self.omit(params, ['postOnly', 'timeInForce', 'stopPrice', 'triggerPrice', 'stop'])
|
@@ -1943,11 +1953,6 @@ class hollaex(Exchange, ImplicitAPI):
|
|
1943
1953
|
coins = self.safe_dict(response, 'coins', {})
|
1944
1954
|
return self.parse_deposit_withdraw_fees(coins, codes, 'symbol')
|
1945
1955
|
|
1946
|
-
def normalize_number_if_needed(self, number):
|
1947
|
-
if self.is_round_number(number):
|
1948
|
-
number = int(number)
|
1949
|
-
return number
|
1950
|
-
|
1951
1956
|
def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
|
1952
1957
|
query = self.omit(params, self.extract_params(path))
|
1953
1958
|
path = '/' + self.version + '/' + self.implode_params(path, params)
|