ccxt 4.3.23__py2.py3-none-any.whl → 4.3.27__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 +5 -3
- ccxt/abstract/coinbaseadvanced.py +94 -0
- ccxt/async_support/__init__.py +5 -3
- ccxt/async_support/base/exchange.py +5 -4
- ccxt/async_support/bitrue.py +5 -1
- ccxt/async_support/coinbaseadvanced.py +17 -0
- ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +13 -13
- ccxt/async_support/coinex.py +78 -139
- ccxt/async_support/kraken.py +52 -7
- ccxt/async_support/kucoin.py +1 -0
- ccxt/async_support/phemex.py +16 -2
- ccxt/base/exchange.py +32 -28
- ccxt/bitrue.py +5 -1
- ccxt/coinbaseadvanced.py +17 -0
- ccxt/{coinbasepro.py → coinbaseexchange.py} +13 -13
- ccxt/coinex.py +78 -139
- ccxt/kraken.py +52 -7
- ccxt/kucoin.py +1 -0
- ccxt/phemex.py +16 -2
- ccxt/pro/__init__.py +3 -3
- ccxt/pro/binance.py +1 -1
- ccxt/pro/bitget.py +10 -3
- ccxt/pro/{coinbasepro.py → coinbaseexchange.py} +5 -5
- ccxt/pro/cryptocom.py +9 -6
- ccxt/pro/kraken.py +7 -6
- ccxt/pro/okx.py +1 -1
- {ccxt-4.3.23.dist-info → ccxt-4.3.27.dist-info}/METADATA +6 -6
- {ccxt-4.3.23.dist-info → ccxt-4.3.27.dist-info}/RECORD +31 -28
- /ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +0 -0
- {ccxt-4.3.23.dist-info → ccxt-4.3.27.dist-info}/WHEEL +0 -0
- {ccxt-4.3.23.dist-info → ccxt-4.3.27.dist-info}/top_level.txt +0 -0
ccxt/coinex.py
CHANGED
@@ -457,8 +457,15 @@ class coinex(Exchange, ImplicitAPI):
|
|
457
457
|
'fetchDepositAddress': {
|
458
458
|
'fillResponseFromRequest': True,
|
459
459
|
},
|
460
|
+
'accountsByType': {
|
461
|
+
'spot': 'SPOT',
|
462
|
+
'margin': 'MARGIN',
|
463
|
+
'swap': 'FUTURES',
|
464
|
+
},
|
460
465
|
'accountsById': {
|
461
|
-
'
|
466
|
+
'SPOT': 'spot',
|
467
|
+
'MARGIN': 'margin',
|
468
|
+
'FUTURES': 'swap',
|
462
469
|
},
|
463
470
|
'networks': {
|
464
471
|
'BEP20': 'BSC',
|
@@ -3453,7 +3460,10 @@ class coinex(Exchange, ImplicitAPI):
|
|
3453
3460
|
:param str [params.marginMode]: 'cross' or 'isolated' for fetching spot margin orders
|
3454
3461
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
3455
3462
|
"""
|
3456
|
-
|
3463
|
+
openOrders = self.fetch_orders_by_status('pending', symbol, since, limit, params)
|
3464
|
+
for i in range(0, len(openOrders)):
|
3465
|
+
openOrders[i]['status'] = 'open'
|
3466
|
+
return openOrders
|
3457
3467
|
|
3458
3468
|
def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
3459
3469
|
"""
|
@@ -4598,40 +4608,42 @@ class coinex(Exchange, ImplicitAPI):
|
|
4598
4608
|
def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
4599
4609
|
"""
|
4600
4610
|
transfer currency internally between wallets on the same account
|
4601
|
-
:see: https://
|
4602
|
-
:see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot002_account013_margin_transfer
|
4611
|
+
:see: https://docs.coinex.com/api/v2/assets/transfer/http/transfer
|
4603
4612
|
:param str code: unified currency code
|
4604
4613
|
:param float amount: amount to transfer
|
4605
4614
|
:param str fromAccount: account to transfer from
|
4606
4615
|
:param str toAccount: account to transfer to
|
4607
4616
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4617
|
+
:param str [params.symbol]: unified ccxt symbol, required when either the fromAccount or toAccount is margin
|
4608
4618
|
:returns dict: a `transfer structure <https://docs.ccxt.com/#/?id=transfer-structure>`
|
4609
4619
|
"""
|
4610
4620
|
self.load_markets()
|
4611
4621
|
currency = self.currency(code)
|
4612
4622
|
amountToPrecision = self.currency_to_precision(code, amount)
|
4623
|
+
accountsByType = self.safe_dict(self.options, 'accountsById', {})
|
4624
|
+
fromId = self.safe_string(accountsByType, fromAccount, fromAccount)
|
4625
|
+
toId = self.safe_string(accountsByType, toAccount, toAccount)
|
4613
4626
|
request = {
|
4627
|
+
'ccy': currency['id'],
|
4614
4628
|
'amount': amountToPrecision,
|
4615
|
-
'
|
4629
|
+
'from_account_type': fromId,
|
4630
|
+
'to_account_type': toId,
|
4616
4631
|
}
|
4617
|
-
|
4618
|
-
|
4619
|
-
|
4620
|
-
|
4621
|
-
|
4622
|
-
request['
|
4623
|
-
|
4624
|
-
|
4625
|
-
|
4626
|
-
fromId = self.safe_string(accountsById, fromAccount, fromAccount)
|
4627
|
-
toId = self.safe_string(accountsById, toAccount, toAccount)
|
4628
|
-
# fromAccount and toAccount must be integers for margin transfers
|
4629
|
-
# spot is 0, use fetchBalance() to find the margin account id
|
4630
|
-
request['from_account'] = int(fromId)
|
4631
|
-
request['to_account'] = int(toId)
|
4632
|
-
response = self.v1PrivatePostMarginTransfer(self.extend(request, params))
|
4632
|
+
if (fromAccount == 'margin') or (toAccount == 'margin'):
|
4633
|
+
symbol = self.safe_string(params, 'symbol')
|
4634
|
+
if symbol is None:
|
4635
|
+
raise ArgumentsRequired(self.id + ' transfer() the symbol parameter must be defined for a margin account')
|
4636
|
+
params = self.omit(params, 'symbol')
|
4637
|
+
request['market'] = self.market_id(symbol)
|
4638
|
+
if (fromAccount != 'spot') and (toAccount != 'spot'):
|
4639
|
+
raise BadRequest(self.id + ' transfer() can only be between spot and swap, or spot and margin, either the fromAccount or toAccount must be spot')
|
4640
|
+
response = self.v2PrivatePostAssetsTransfer(self.extend(request, params))
|
4633
4641
|
#
|
4634
|
-
# {
|
4642
|
+
# {
|
4643
|
+
# "code": 0,
|
4644
|
+
# "data": {},
|
4645
|
+
# "message": "OK"
|
4646
|
+
# }
|
4635
4647
|
#
|
4636
4648
|
return self.extend(self.parse_transfer(response, currency), {
|
4637
4649
|
'amount': self.parse_number(amountToPrecision),
|
@@ -4639,158 +4651,85 @@ class coinex(Exchange, ImplicitAPI):
|
|
4639
4651
|
'toAccount': toAccount,
|
4640
4652
|
})
|
4641
4653
|
|
4642
|
-
def parse_transfer_status(self, status
|
4654
|
+
def parse_transfer_status(self, status):
|
4643
4655
|
statuses = {
|
4644
4656
|
'0': 'ok',
|
4645
4657
|
'SUCCESS': 'ok',
|
4658
|
+
'OK': 'ok',
|
4659
|
+
'finished': 'ok',
|
4660
|
+
'FINISHED': 'ok',
|
4646
4661
|
}
|
4647
4662
|
return self.safe_string(statuses, status, status)
|
4648
4663
|
|
4649
4664
|
def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
|
4650
|
-
|
4651
|
-
|
4652
|
-
|
4653
|
-
|
4654
|
-
|
4655
|
-
# "asset": "USDT",
|
4656
|
-
# "transfer_type": "transfer_out", # from swap to spot
|
4657
|
-
# "created_at": 1651633422
|
4658
|
-
# },
|
4659
|
-
#
|
4660
|
-
# fetchTransfers Margin
|
4661
|
-
#
|
4662
|
-
# {
|
4663
|
-
# "id": 7580062,
|
4664
|
-
# "updated_at": 1653684379,
|
4665
|
-
# "user_id": 3620173,
|
4666
|
-
# "from_account_id": 0,
|
4667
|
-
# "to_account_id": 1,
|
4668
|
-
# "asset": "BTC",
|
4669
|
-
# "amount": "0.00160829",
|
4670
|
-
# "balance": "0.00160829",
|
4671
|
-
# "transfer_type": "IN",
|
4672
|
-
# "status": "SUCCESS",
|
4673
|
-
# "created_at": 1653684379
|
4674
|
-
# },
|
4675
|
-
#
|
4676
|
-
timestamp = self.safe_timestamp(transfer, 'created_at')
|
4677
|
-
transferType = self.safe_string(transfer, 'transfer_type')
|
4678
|
-
fromAccount = None
|
4679
|
-
toAccount = None
|
4680
|
-
if transferType == 'transfer_out':
|
4681
|
-
fromAccount = 'swap'
|
4682
|
-
toAccount = 'spot'
|
4683
|
-
elif transferType == 'transfer_in':
|
4684
|
-
fromAccount = 'spot'
|
4685
|
-
toAccount = 'swap'
|
4686
|
-
elif transferType == 'IN':
|
4687
|
-
fromAccount = 'spot'
|
4688
|
-
toAccount = 'margin'
|
4689
|
-
elif transferType == 'OUT':
|
4690
|
-
fromAccount = 'margin'
|
4691
|
-
toAccount = 'spot'
|
4692
|
-
currencyId = self.safe_string(transfer, 'asset')
|
4693
|
-
currencyCode = self.safe_currency_code(currencyId, currency)
|
4665
|
+
timestamp = self.safe_integer(transfer, 'created_at')
|
4666
|
+
currencyId = self.safe_string(transfer, 'ccy')
|
4667
|
+
fromId = self.safe_string(transfer, 'from_account_type')
|
4668
|
+
toId = self.safe_string(transfer, 'to_account_type')
|
4669
|
+
accountsById = self.safe_value(self.options, 'accountsById', {})
|
4694
4670
|
return {
|
4695
|
-
'
|
4696
|
-
'id': self.safe_string(transfer, 'id'),
|
4671
|
+
'id': None,
|
4697
4672
|
'timestamp': timestamp,
|
4698
4673
|
'datetime': self.iso8601(timestamp),
|
4699
|
-
'currency':
|
4674
|
+
'currency': self.safe_currency_code(currencyId, currency),
|
4700
4675
|
'amount': self.safe_number(transfer, 'amount'),
|
4701
|
-
'fromAccount':
|
4702
|
-
'toAccount':
|
4676
|
+
'fromAccount': self.safe_string(accountsById, fromId, fromId),
|
4677
|
+
'toAccount': self.safe_string(accountsById, toId, toId),
|
4703
4678
|
'status': self.parse_transfer_status(self.safe_string_2(transfer, 'code', 'status')),
|
4704
4679
|
}
|
4705
4680
|
|
4706
4681
|
def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> TransferEntries:
|
4707
4682
|
"""
|
4708
4683
|
fetch a history of internal transfers made on an account
|
4709
|
-
:see: https://
|
4710
|
-
:see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot002_account024_contract_transfer_history
|
4684
|
+
:see: https://docs.coinex.com/api/v2/assets/transfer/http/list-transfer-history
|
4711
4685
|
:param str code: unified currency code of the currency transferred
|
4712
4686
|
:param int [since]: the earliest time in ms to fetch transfers for
|
4713
|
-
:param int [limit]: the maximum number of
|
4687
|
+
:param int [limit]: the maximum number of transfer structures to retrieve
|
4714
4688
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4689
|
+
:param str [params.marginMode]: 'cross' or 'isolated' for fetching transfers to and from your margin account
|
4715
4690
|
:returns dict[]: a list of `transfer structures <https://docs.ccxt.com/#/?id=transfer-structure>`
|
4716
4691
|
"""
|
4717
4692
|
self.load_markets()
|
4718
|
-
|
4693
|
+
if code is None:
|
4694
|
+
raise ArgumentsRequired(self.id + ' fetchTransfers() requires a code argument')
|
4695
|
+
currency = self.currency(code)
|
4719
4696
|
request = {
|
4720
|
-
'
|
4721
|
-
# 'limit': limit,
|
4722
|
-
# 'asset': 'USDT',
|
4723
|
-
# 'start_time': since,
|
4724
|
-
# 'end_time': 1515806440,
|
4725
|
-
# 'transfer_type': 'transfer_in', # transfer_in: from Spot to Swap Account, transfer_out: from Swap to Spot Account
|
4697
|
+
'ccy': currency['id'],
|
4726
4698
|
}
|
4727
|
-
page = self.safe_integer(params, 'page')
|
4728
|
-
if page is not None:
|
4729
|
-
request['page'] = page
|
4730
|
-
if code is not None:
|
4731
|
-
currency = self.currency(code)
|
4732
|
-
request['asset'] = currency['id']
|
4733
|
-
if since is not None:
|
4734
|
-
request['start_time'] = since
|
4735
|
-
if limit is not None:
|
4736
|
-
request['limit'] = limit
|
4737
|
-
else:
|
4738
|
-
request['limit'] = 100
|
4739
|
-
params = self.omit(params, 'page')
|
4740
4699
|
marginMode = None
|
4741
4700
|
marginMode, params = self.handle_margin_mode_and_params('fetchTransfers', params)
|
4742
|
-
response = None
|
4743
4701
|
if marginMode is not None:
|
4744
|
-
|
4702
|
+
request['transfer_type'] = 'MARGIN'
|
4745
4703
|
else:
|
4746
|
-
|
4747
|
-
|
4748
|
-
|
4704
|
+
request['transfer_type'] = 'FUTURES'
|
4705
|
+
if since is not None:
|
4706
|
+
request['start_time'] = since
|
4707
|
+
if limit is not None:
|
4708
|
+
request['limit'] = limit
|
4709
|
+
request, params = self.handle_until_option('end_time', request, params)
|
4710
|
+
response = self.v2PrivateGetAssetsTransferHistory(self.extend(request, params))
|
4749
4711
|
#
|
4750
4712
|
# {
|
4751
|
-
# "
|
4752
|
-
#
|
4753
|
-
#
|
4754
|
-
#
|
4755
|
-
#
|
4756
|
-
#
|
4757
|
-
#
|
4758
|
-
#
|
4759
|
-
#
|
4760
|
-
#
|
4761
|
-
#
|
4713
|
+
# "data": [
|
4714
|
+
# {
|
4715
|
+
# "created_at": 1715848480646,
|
4716
|
+
# "from_account_type": "SPOT",
|
4717
|
+
# "to_account_type": "FUTURES",
|
4718
|
+
# "ccy": "USDT",
|
4719
|
+
# "amount": "10",
|
4720
|
+
# "status": "finished"
|
4721
|
+
# },
|
4722
|
+
# ],
|
4723
|
+
# "pagination": {
|
4724
|
+
# "total": 8,
|
4725
|
+
# "has_next": False
|
4762
4726
|
# },
|
4763
|
-
# "message": "Success"
|
4764
|
-
# }
|
4765
|
-
#
|
4766
|
-
# Margin
|
4767
|
-
#
|
4768
|
-
# {
|
4769
4727
|
# "code": 0,
|
4770
|
-
# "
|
4771
|
-
# "records": [
|
4772
|
-
# {
|
4773
|
-
# "id": 7580062,
|
4774
|
-
# "updated_at": 1653684379,
|
4775
|
-
# "user_id": 3620173,
|
4776
|
-
# "from_account_id": 0,
|
4777
|
-
# "to_account_id": 1,
|
4778
|
-
# "asset": "BTC",
|
4779
|
-
# "amount": "0.00160829",
|
4780
|
-
# "balance": "0.00160829",
|
4781
|
-
# "transfer_type": "IN",
|
4782
|
-
# "status": "SUCCESS",
|
4783
|
-
# "created_at": 1653684379
|
4784
|
-
# }
|
4785
|
-
# ],
|
4786
|
-
# "total": 1
|
4787
|
-
# },
|
4788
|
-
# "message": "Success"
|
4728
|
+
# "message": "OK"
|
4789
4729
|
# }
|
4790
4730
|
#
|
4791
|
-
data = self.
|
4792
|
-
|
4793
|
-
return self.parse_transfers(transfers, currency, since, limit)
|
4731
|
+
data = self.safe_list(response, 'data', [])
|
4732
|
+
return self.parse_transfers(data, currency, since, limit)
|
4794
4733
|
|
4795
4734
|
def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
4796
4735
|
"""
|
ccxt/kraken.py
CHANGED
@@ -58,6 +58,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
58
58
|
'cancelOrder': True,
|
59
59
|
'cancelOrders': True,
|
60
60
|
'createDepositAddress': True,
|
61
|
+
'createMarketBuyOrderWithCost': True,
|
62
|
+
'createMarketOrderWithCost': False,
|
63
|
+
'createMarketSellOrderWithCost': False,
|
61
64
|
'createOrder': True,
|
62
65
|
'createStopLimitOrder': True,
|
63
66
|
'createStopMarketOrder': True,
|
@@ -1308,6 +1311,33 @@ class kraken(Exchange, ImplicitAPI):
|
|
1308
1311
|
#
|
1309
1312
|
return self.parse_balance(response)
|
1310
1313
|
|
1314
|
+
def create_market_order_with_cost(self, symbol: str, side: OrderSide, cost: float, params={}):
|
1315
|
+
"""
|
1316
|
+
create a market order by providing the symbol, side and cost
|
1317
|
+
:see: https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
|
1318
|
+
:param str symbol: unified symbol of the market to create an order in(only USD markets are supported)
|
1319
|
+
:param str side: 'buy' or 'sell'
|
1320
|
+
:param float cost: how much you want to trade in units of the quote currency
|
1321
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1322
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1323
|
+
"""
|
1324
|
+
self.load_markets()
|
1325
|
+
# only buy orders are supported by the endpoint
|
1326
|
+
params['cost'] = cost
|
1327
|
+
return self.create_order(symbol, 'market', side, cost, None, params)
|
1328
|
+
|
1329
|
+
def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
|
1330
|
+
"""
|
1331
|
+
create a market buy order by providing the symbol, side and cost
|
1332
|
+
:see: https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
|
1333
|
+
:param str symbol: unified symbol of the market to create an order in
|
1334
|
+
:param float cost: how much you want to trade in units of the quote currency
|
1335
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1336
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1337
|
+
"""
|
1338
|
+
self.load_markets()
|
1339
|
+
return self.create_market_order_with_cost(symbol, 'buy', cost, params)
|
1340
|
+
|
1311
1341
|
def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
1312
1342
|
"""
|
1313
1343
|
:see: https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
|
@@ -1336,7 +1366,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
1336
1366
|
'ordertype': type,
|
1337
1367
|
'volume': self.amount_to_precision(symbol, amount),
|
1338
1368
|
}
|
1339
|
-
orderRequest = self.order_request('createOrder', symbol, type, request, price, params)
|
1369
|
+
orderRequest = self.order_request('createOrder', symbol, type, request, amount, price, params)
|
1340
1370
|
response = self.privatePostAddOrder(self.extend(orderRequest[0], orderRequest[1]))
|
1341
1371
|
#
|
1342
1372
|
# {
|
@@ -1616,7 +1646,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
1616
1646
|
'trades': trades,
|
1617
1647
|
}, market)
|
1618
1648
|
|
1619
|
-
def order_request(self, method, symbol, type, request, price=None, params={}):
|
1649
|
+
def order_request(self, method: str, symbol: str, type: str, request: dict, amount: Num, price: Num = None, params={}):
|
1620
1650
|
clientOrderId = self.safe_string_2(params, 'userref', 'clientOrderId')
|
1621
1651
|
params = self.omit(params, ['userref', 'clientOrderId'])
|
1622
1652
|
if clientOrderId is not None:
|
@@ -1630,9 +1660,21 @@ class kraken(Exchange, ImplicitAPI):
|
|
1630
1660
|
trailingLimitAmount = self.safe_string(params, 'trailingLimitAmount')
|
1631
1661
|
isTrailingAmountOrder = trailingAmount is not None
|
1632
1662
|
isLimitOrder = type.endswith('limit') # supporting limit, stop-loss-limit, take-profit-limit, etc
|
1633
|
-
|
1663
|
+
isMarketOrder = type == 'market'
|
1664
|
+
cost = self.safe_string(params, 'cost')
|
1665
|
+
flags = self.safe_string(params, 'oflags')
|
1666
|
+
params = self.omit(params, ['cost', 'oflags'])
|
1667
|
+
isViqcOrder = (flags is not None) and (flags.find('viqc') > -1) # volume in quote currency
|
1668
|
+
if isMarketOrder and (cost is not None or isViqcOrder):
|
1669
|
+
if cost is None and (amount is not None):
|
1670
|
+
request['volume'] = self.cost_to_precision(symbol, self.number_to_string(amount))
|
1671
|
+
else:
|
1672
|
+
request['volume'] = self.cost_to_precision(symbol, cost)
|
1673
|
+
extendedOflags = flags + ',viqc' if (flags is not None) else 'viqc'
|
1674
|
+
request['oflags'] = extendedOflags
|
1675
|
+
elif isLimitOrder and not isTrailingAmountOrder:
|
1634
1676
|
request['price'] = self.price_to_precision(symbol, price)
|
1635
|
-
reduceOnly = self.
|
1677
|
+
reduceOnly = self.safe_bool_2(params, 'reduceOnly', 'reduce_only')
|
1636
1678
|
if isStopLossOrTakeProfitTrigger:
|
1637
1679
|
if isStopLossTriggerOrder:
|
1638
1680
|
request['price'] = self.price_to_precision(symbol, stopLossTriggerPrice)
|
@@ -1666,7 +1708,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
1666
1708
|
request['reduce_only'] = True # ws request can't have stringified bool
|
1667
1709
|
else:
|
1668
1710
|
request['reduce_only'] = 'true' # not using hasattr(self, boolean) case, because the urlencodedNested transforms it into 'True' string
|
1669
|
-
close = self.
|
1711
|
+
close = self.safe_dict(params, 'close')
|
1670
1712
|
if close is not None:
|
1671
1713
|
close = self.extend({}, close)
|
1672
1714
|
closePrice = self.safe_value(close, 'price')
|
@@ -1683,7 +1725,8 @@ class kraken(Exchange, ImplicitAPI):
|
|
1683
1725
|
postOnly = None
|
1684
1726
|
postOnly, params = self.handle_post_only(isMarket, False, params)
|
1685
1727
|
if postOnly:
|
1686
|
-
|
1728
|
+
extendedPostFlags = flags + ',post' if (flags is not None) else 'post'
|
1729
|
+
request['oflags'] = extendedPostFlags
|
1687
1730
|
params = self.omit(params, ['timeInForce', 'reduceOnly', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingLimitAmount', 'offset'])
|
1688
1731
|
return [request, params]
|
1689
1732
|
|
@@ -1716,7 +1759,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
1716
1759
|
}
|
1717
1760
|
if amount is not None:
|
1718
1761
|
request['volume'] = self.amount_to_precision(symbol, amount)
|
1719
|
-
orderRequest = self.order_request('editOrder', symbol, type, request, price, params)
|
1762
|
+
orderRequest = self.order_request('editOrder', symbol, type, request, amount, price, params)
|
1720
1763
|
response = self.privatePostEditOrder(self.extend(orderRequest[0], orderRequest[1]))
|
1721
1764
|
#
|
1722
1765
|
# {
|
@@ -2808,6 +2851,8 @@ class kraken(Exchange, ImplicitAPI):
|
|
2808
2851
|
raise CancelPending(self.id + ' ' + body)
|
2809
2852
|
if body.find('Invalid arguments:volume') >= 0:
|
2810
2853
|
raise InvalidOrder(self.id + ' ' + body)
|
2854
|
+
if body.find('Invalid arguments:viqc') >= 0:
|
2855
|
+
raise InvalidOrder(self.id + ' ' + body)
|
2811
2856
|
if body.find('Rate limit exceeded') >= 0:
|
2812
2857
|
raise RateLimitExceeded(self.id + ' ' + body)
|
2813
2858
|
if response is None:
|
ccxt/kucoin.py
CHANGED
@@ -4489,6 +4489,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4489
4489
|
partnerSignature = self.hmac(self.encode(partnerPayload), self.encode(partnerSecret), hashlib.sha256, 'base64')
|
4490
4490
|
headers['KC-API-PARTNER-SIGN'] = partnerSignature
|
4491
4491
|
headers['KC-API-PARTNER'] = partnerId
|
4492
|
+
headers['KC-API-PARTNER-VERIFY'] = 'true'
|
4492
4493
|
if isBroker:
|
4493
4494
|
brokerName = self.safe_string(partner, 'name')
|
4494
4495
|
if brokerName is not None:
|
ccxt/phemex.py
CHANGED
@@ -2168,7 +2168,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2168
2168
|
if feeCost is not None:
|
2169
2169
|
fee = {
|
2170
2170
|
'cost': feeCost,
|
2171
|
-
'currency':
|
2171
|
+
'currency': self.safe_currency_code(self.safe_string(order, 'feeCurrency')),
|
2172
2172
|
}
|
2173
2173
|
timeInForce = self.parse_time_in_force(self.safe_string(order, 'timeInForce'))
|
2174
2174
|
stopPrice = self.parse_number(self.omit_zero(self.from_ep(self.safe_string(order, 'stopPxEp'))))
|
@@ -2313,6 +2313,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2313
2313
|
clientOrderId = None
|
2314
2314
|
marketId = self.safe_string(order, 'symbol')
|
2315
2315
|
symbol = self.safe_symbol(marketId, market)
|
2316
|
+
market = self.safe_market(marketId, market)
|
2316
2317
|
status = self.parse_order_status(self.safe_string(order, 'ordStatus'))
|
2317
2318
|
side = self.parse_order_side(self.safe_string_lower(order, 'side'))
|
2318
2319
|
type = self.parse_order_type(self.safe_string(order, 'orderType'))
|
@@ -2338,6 +2339,19 @@ class phemex(Exchange, ImplicitAPI):
|
|
2338
2339
|
reduceOnly = True
|
2339
2340
|
takeProfit = self.safe_string(order, 'takeProfitRp')
|
2340
2341
|
stopLoss = self.safe_string(order, 'stopLossRp')
|
2342
|
+
feeValue = self.omit_zero(self.safe_string(order, 'execFeeRv'))
|
2343
|
+
ptFeeRv = self.omit_zero(self.safe_string(order, 'ptFeeRv'))
|
2344
|
+
fee = None
|
2345
|
+
if feeValue is not None:
|
2346
|
+
fee = {
|
2347
|
+
'cost': feeValue,
|
2348
|
+
'currency': market['quote'],
|
2349
|
+
}
|
2350
|
+
elif ptFeeRv is not None:
|
2351
|
+
fee = {
|
2352
|
+
'cost': ptFeeRv,
|
2353
|
+
'currency': 'PT',
|
2354
|
+
}
|
2341
2355
|
return self.safe_order({
|
2342
2356
|
'info': order,
|
2343
2357
|
'id': id,
|
@@ -2362,7 +2376,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2362
2376
|
'cost': cost,
|
2363
2377
|
'average': None,
|
2364
2378
|
'status': status,
|
2365
|
-
'fee':
|
2379
|
+
'fee': fee,
|
2366
2380
|
'trades': None,
|
2367
2381
|
})
|
2368
2382
|
|
ccxt/pro/__init__.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
# ----------------------------------------------------------------------------
|
6
6
|
|
7
|
-
__version__ = '4.3.
|
7
|
+
__version__ = '4.3.27'
|
8
8
|
|
9
9
|
# ----------------------------------------------------------------------------
|
10
10
|
|
@@ -36,8 +36,8 @@ from ccxt.pro.blockchaincom import blockchaincom # noqa
|
|
36
36
|
from ccxt.pro.bybit import bybit # noqa: F401
|
37
37
|
from ccxt.pro.cex import cex # noqa: F401
|
38
38
|
from ccxt.pro.coinbase import coinbase # noqa: F401
|
39
|
+
from ccxt.pro.coinbaseexchange import coinbaseexchange # noqa: F401
|
39
40
|
from ccxt.pro.coinbaseinternational import coinbaseinternational # noqa: F401
|
40
|
-
from ccxt.pro.coinbasepro import coinbasepro # noqa: F401
|
41
41
|
from ccxt.pro.coincheck import coincheck # noqa: F401
|
42
42
|
from ccxt.pro.coinex import coinex # noqa: F401
|
43
43
|
from ccxt.pro.coinone import coinone # noqa: F401
|
@@ -103,8 +103,8 @@ exchanges = [
|
|
103
103
|
'bybit',
|
104
104
|
'cex',
|
105
105
|
'coinbase',
|
106
|
+
'coinbaseexchange',
|
106
107
|
'coinbaseinternational',
|
107
|
-
'coinbasepro',
|
108
108
|
'coincheck',
|
109
109
|
'coinex',
|
110
110
|
'coinone',
|
ccxt/pro/binance.py
CHANGED
@@ -1951,7 +1951,7 @@ class binance(ccxt.async_support.binance):
|
|
1951
1951
|
orders = self.parse_orders(result)
|
1952
1952
|
client.resolve(orders, messageHash)
|
1953
1953
|
|
1954
|
-
async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount:
|
1954
|
+
async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}) -> Order:
|
1955
1955
|
"""
|
1956
1956
|
edit a trade order
|
1957
1957
|
:see: https://binance-docs.github.io/apidocs/websocket_api/en/#cancel-and-replace-order-trade
|
ccxt/pro/bitget.py
CHANGED
@@ -1060,7 +1060,7 @@ class bitget(ccxt.async_support.bitget):
|
|
1060
1060
|
# "executePrice": "35123", # self is limit price
|
1061
1061
|
# "triggerType": "fill_price",
|
1062
1062
|
# "planType": "amount",
|
1063
|
-
# #### in case order had fill: ####
|
1063
|
+
# #### in case order had a partial fill: ####
|
1064
1064
|
# fillPrice: '35123',
|
1065
1065
|
# tradeId: '1171775539946528779',
|
1066
1066
|
# baseVolume: '7', # field present in market order
|
@@ -1177,13 +1177,19 @@ class bitget(ccxt.async_support.bitget):
|
|
1177
1177
|
totalAmount = None
|
1178
1178
|
filledAmount = None
|
1179
1179
|
cost = None
|
1180
|
+
remaining = None
|
1181
|
+
totalFilled = self.safe_string(order, 'accBaseVolume')
|
1180
1182
|
if isSpot:
|
1181
1183
|
if isMargin:
|
1182
1184
|
filledAmount = self.omit_zero(self.safe_string(order, 'fillTotalAmount'))
|
1183
1185
|
totalAmount = self.omit_zero(self.safe_string(order, 'baseSize')) # for margin trading
|
1184
1186
|
cost = self.safe_string(order, 'quoteSize')
|
1185
1187
|
else:
|
1186
|
-
|
1188
|
+
partialFillAmount = self.safe_string(order, 'baseVolume')
|
1189
|
+
if partialFillAmount is not None:
|
1190
|
+
filledAmount = partialFillAmount
|
1191
|
+
else:
|
1192
|
+
filledAmount = totalFilled
|
1187
1193
|
if isMarketOrder:
|
1188
1194
|
if isBuy:
|
1189
1195
|
totalAmount = accBaseVolume
|
@@ -1199,6 +1205,7 @@ class bitget(ccxt.async_support.bitget):
|
|
1199
1205
|
filledAmount = self.safe_string(order, 'baseVolume')
|
1200
1206
|
totalAmount = self.safe_string(order, 'size')
|
1201
1207
|
cost = self.safe_string(order, 'fillNotionalUsd')
|
1208
|
+
remaining = self.omit_zero(Precise.string_sub(totalAmount, totalFilled))
|
1202
1209
|
return self.safe_order({
|
1203
1210
|
'info': order,
|
1204
1211
|
'symbol': symbol,
|
@@ -1217,7 +1224,7 @@ class bitget(ccxt.async_support.bitget):
|
|
1217
1224
|
'cost': cost,
|
1218
1225
|
'average': avgPrice,
|
1219
1226
|
'filled': filledAmount,
|
1220
|
-
'remaining':
|
1227
|
+
'remaining': remaining,
|
1221
1228
|
'status': self.parse_ws_order_status(rawStatus),
|
1222
1229
|
'fee': feeObject,
|
1223
1230
|
'trades': None,
|
@@ -16,10 +16,10 @@ from ccxt.base.errors import BadRequest
|
|
16
16
|
from ccxt.base.errors import BadSymbol
|
17
17
|
|
18
18
|
|
19
|
-
class
|
19
|
+
class coinbaseexchange(ccxt.async_support.coinbaseexchange):
|
20
20
|
|
21
21
|
def describe(self):
|
22
|
-
return self.deep_extend(super(
|
22
|
+
return self.deep_extend(super(coinbaseexchange, self).describe(), {
|
23
23
|
'has': {
|
24
24
|
'ws': True,
|
25
25
|
'watchOHLCV': False, # missing on the exchange side
|
@@ -38,7 +38,7 @@ class coinbasepro(ccxt.async_support.coinbasepro):
|
|
38
38
|
},
|
39
39
|
'urls': {
|
40
40
|
'api': {
|
41
|
-
'ws': 'wss://ws-feed.
|
41
|
+
'ws': 'wss://ws-feed.exchange.coinbase.com',
|
42
42
|
},
|
43
43
|
'test': {
|
44
44
|
'ws': 'wss://ws-feed-public.sandbox.exchange.coinbase.com',
|
@@ -437,7 +437,7 @@ class coinbasepro(ccxt.async_support.coinbasepro):
|
|
437
437
|
# "side": "buy",
|
438
438
|
# "order_type": "limit"
|
439
439
|
# }
|
440
|
-
parsed = super(
|
440
|
+
parsed = super(coinbaseexchange, self).parse_trade(trade)
|
441
441
|
feeRate = None
|
442
442
|
isMaker = False
|
443
443
|
if 'maker_fee_rate' in trade:
|
@@ -727,7 +727,7 @@ class coinbasepro(ccxt.async_support.coinbasepro):
|
|
727
727
|
#
|
728
728
|
type = self.safe_string(ticker, 'type')
|
729
729
|
if type is None:
|
730
|
-
return super(
|
730
|
+
return super(coinbaseexchange, self).parse_ticker(ticker, market)
|
731
731
|
marketId = self.safe_string(ticker, 'product_id')
|
732
732
|
symbol = self.safe_symbol(marketId, market, '-')
|
733
733
|
timestamp = self.parse8601(self.safe_string(ticker, 'time'))
|
ccxt/pro/cryptocom.py
CHANGED
@@ -103,13 +103,16 @@ class cryptocom(ccxt.async_support.cryptocom):
|
|
103
103
|
if topicParams is None:
|
104
104
|
params['params'] = {}
|
105
105
|
bookSubscriptionType = None
|
106
|
-
|
107
|
-
|
108
|
-
|
106
|
+
bookSubscriptionType2 = None
|
107
|
+
bookSubscriptionType, params = self.handle_option_and_params(params, 'watchOrderBook', 'bookSubscriptionType', 'SNAPSHOT_AND_UPDATE')
|
108
|
+
bookSubscriptionType2, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'bookSubscriptionType', bookSubscriptionType)
|
109
|
+
params['params']['bookSubscriptionType'] = bookSubscriptionType2
|
109
110
|
bookUpdateFrequency = None
|
110
|
-
|
111
|
-
|
112
|
-
|
111
|
+
bookUpdateFrequency2 = None
|
112
|
+
bookUpdateFrequency, params = self.handle_option_and_params(params, 'watchOrderBook', 'bookUpdateFrequency')
|
113
|
+
bookUpdateFrequency2, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'bookUpdateFrequency', bookUpdateFrequency)
|
114
|
+
if bookUpdateFrequency2 is not None:
|
115
|
+
params['params']['bookSubscriptionType'] = bookUpdateFrequency2
|
113
116
|
for i in range(0, len(symbols)):
|
114
117
|
symbol = symbols[i]
|
115
118
|
market = self.market(symbol)
|