ccxt 4.2.100__py2.py3-none-any.whl → 4.3.1__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/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/binance.py +55 -1
- ccxt/async_support/bitget.py +60 -2
- ccxt/async_support/bybit.py +1 -1
- ccxt/async_support/coinex.py +54 -58
- ccxt/async_support/okx.py +74 -5
- ccxt/async_support/woo.py +38 -0
- ccxt/base/exchange.py +1 -1
- ccxt/binance.py +55 -1
- ccxt/bitget.py +60 -2
- ccxt/bybit.py +1 -1
- ccxt/coinex.py +54 -58
- ccxt/okx.py +74 -5
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/kraken.py +2 -2
- ccxt/woo.py +38 -0
- {ccxt-4.2.100.dist-info → ccxt-4.3.1.dist-info}/METADATA +4 -4
- {ccxt-4.2.100.dist-info → ccxt-4.3.1.dist-info}/RECORD +22 -22
- {ccxt-4.2.100.dist-info → ccxt-4.3.1.dist-info}/WHEEL +0 -0
- {ccxt-4.2.100.dist-info → ccxt-4.3.1.dist-info}/top_level.txt +0 -0
ccxt/__init__.py
CHANGED
ccxt/async_support/__init__.py
CHANGED
ccxt/async_support/binance.py
CHANGED
@@ -8,7 +8,7 @@ from ccxt.abstract.binance import ImplicitAPI
|
|
8
8
|
import asyncio
|
9
9
|
import hashlib
|
10
10
|
import json
|
11
|
-
from ccxt.base.types import Balances, Currencies, Currency, Greeks, Int, Leverage, Leverages, MarginMode, MarginModes, MarginModification, Market, MarketInterface, Num, Option, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
|
11
|
+
from ccxt.base.types import Balances, Conversion, Currencies, Currency, Greeks, Int, Leverage, Leverages, MarginMode, MarginModes, MarginModification, Market, MarketInterface, Num, Option, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
|
12
12
|
from typing import List
|
13
13
|
from ccxt.base.errors import ExchangeError
|
14
14
|
from ccxt.base.errors import AuthenticationError
|
@@ -63,6 +63,7 @@ class binance(Exchange, ImplicitAPI):
|
|
63
63
|
'cancelOrders': True, # contract only
|
64
64
|
'closeAllPositions': False,
|
65
65
|
'closePosition': False, # exchange specific closePosition parameter for binance createOrder is not synonymous with how CCXT uses closePositions
|
66
|
+
'createConvertTrade': True,
|
66
67
|
'createDepositAddress': False,
|
67
68
|
'createLimitBuyOrder': True,
|
68
69
|
'createLimitSellOrder': True,
|
@@ -11636,3 +11637,56 @@ class binance(Exchange, ImplicitAPI):
|
|
11636
11637
|
'created': None,
|
11637
11638
|
}
|
11638
11639
|
return result
|
11640
|
+
|
11641
|
+
async def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
|
11642
|
+
"""
|
11643
|
+
convert from one currency to another
|
11644
|
+
:see: https://binance-docs.github.io/apidocs/spot/en/#busd-convert-trade
|
11645
|
+
:param str id: the id of the trade that you want to make
|
11646
|
+
:param str fromCode: the currency that you want to sell and convert from
|
11647
|
+
:param str toCode: the currency that you want to buy and convert into
|
11648
|
+
:param float [amount]: how much you want to trade in units of the from currency
|
11649
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
11650
|
+
:returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
|
11651
|
+
"""
|
11652
|
+
await self.load_markets()
|
11653
|
+
request = {
|
11654
|
+
'clientTranId': id,
|
11655
|
+
'asset': fromCode,
|
11656
|
+
'targetAsset': toCode,
|
11657
|
+
'amount': amount,
|
11658
|
+
}
|
11659
|
+
response = await self.sapiPostAssetConvertTransfer(self.extend(request, params))
|
11660
|
+
#
|
11661
|
+
# {
|
11662
|
+
# "tranId": 118263407119,
|
11663
|
+
# "status": "S"
|
11664
|
+
# }
|
11665
|
+
#
|
11666
|
+
fromCurrency = self.currency(fromCode)
|
11667
|
+
toCurrency = self.currency(toCode)
|
11668
|
+
return self.parse_conversion(response, fromCurrency, toCurrency)
|
11669
|
+
|
11670
|
+
def parse_conversion(self, conversion, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
|
11671
|
+
#
|
11672
|
+
# createConvertTrade
|
11673
|
+
#
|
11674
|
+
# {
|
11675
|
+
# "tranId": 118263407119,
|
11676
|
+
# "status": "S"
|
11677
|
+
# }
|
11678
|
+
#
|
11679
|
+
fromCode = self.safe_currency_code(None, fromCurrency)
|
11680
|
+
toCode = self.safe_currency_code(None, toCurrency)
|
11681
|
+
return {
|
11682
|
+
'info': conversion,
|
11683
|
+
'timestamp': None,
|
11684
|
+
'datetime': None,
|
11685
|
+
'id': self.safe_string(conversion, 'tranId'),
|
11686
|
+
'fromCurrency': fromCode,
|
11687
|
+
'fromAmount': None,
|
11688
|
+
'toCurrency': toCode,
|
11689
|
+
'toAmount': None,
|
11690
|
+
'price': None,
|
11691
|
+
'fee': None,
|
11692
|
+
}
|
ccxt/async_support/bitget.py
CHANGED
@@ -59,6 +59,7 @@ class bitget(Exchange, ImplicitAPI):
|
|
59
59
|
'cancelOrders': True,
|
60
60
|
'closeAllPositions': True,
|
61
61
|
'closePosition': True,
|
62
|
+
'createConvertTrade': True,
|
62
63
|
'createDepositAddress': False,
|
63
64
|
'createMarketBuyOrderWithCost': True,
|
64
65
|
'createMarketOrderWithCost': False,
|
@@ -7867,8 +7868,8 @@ class bitget(Exchange, ImplicitAPI):
|
|
7867
7868
|
"""
|
7868
7869
|
await self.load_markets()
|
7869
7870
|
request = {
|
7870
|
-
'fromCoin': fromCode
|
7871
|
-
'toCoin': toCode
|
7871
|
+
'fromCoin': fromCode,
|
7872
|
+
'toCoin': toCode,
|
7872
7873
|
'fromCoinSize': self.number_to_string(amount),
|
7873
7874
|
}
|
7874
7875
|
response = await self.privateConvertGetV2ConvertQuotedPrice(self.extend(request, params))
|
@@ -7895,6 +7896,54 @@ class bitget(Exchange, ImplicitAPI):
|
|
7895
7896
|
toCurrency = self.currency(toCurrencyId)
|
7896
7897
|
return self.parse_conversion(data, fromCurrency, toCurrency)
|
7897
7898
|
|
7899
|
+
async def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
|
7900
|
+
"""
|
7901
|
+
convert from one currency to another
|
7902
|
+
:see: https://www.bitget.com/api-doc/common/convert/Trade
|
7903
|
+
:param str id: the id of the trade that you want to make
|
7904
|
+
:param str fromCode: the currency that you want to sell and convert from
|
7905
|
+
:param str toCode: the currency that you want to buy and convert into
|
7906
|
+
:param float amount: how much you want to trade in units of the from currency
|
7907
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7908
|
+
:param str params['price']: the price of the conversion, obtained from fetchConvertQuote()
|
7909
|
+
:param str params['toAmount']: the amount you want to trade in units of the toCurrency, obtained from fetchConvertQuote()
|
7910
|
+
:returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
|
7911
|
+
"""
|
7912
|
+
await self.load_markets()
|
7913
|
+
price = self.safe_string_2(params, 'price', 'cnvtPrice')
|
7914
|
+
if price is None:
|
7915
|
+
raise ArgumentsRequired(self.id + ' createConvertTrade() requires a price parameter')
|
7916
|
+
toAmount = self.safe_string_2(params, 'toAmount', 'toCoinSize')
|
7917
|
+
if toAmount is None:
|
7918
|
+
raise ArgumentsRequired(self.id + ' createConvertTrade() requires a toAmount parameter')
|
7919
|
+
params = self.omit(params, ['price', 'toAmount'])
|
7920
|
+
request = {
|
7921
|
+
'traceId': id,
|
7922
|
+
'fromCoin': fromCode,
|
7923
|
+
'toCoin': toCode,
|
7924
|
+
'fromCoinSize': self.number_to_string(amount),
|
7925
|
+
'toCoinSize': toAmount,
|
7926
|
+
'cnvtPrice': price,
|
7927
|
+
}
|
7928
|
+
response = await self.privateConvertPostV2ConvertTrade(self.extend(request, params))
|
7929
|
+
#
|
7930
|
+
# {
|
7931
|
+
# "code": "00000",
|
7932
|
+
# "msg": "success",
|
7933
|
+
# "requestTime": 1712123746203,
|
7934
|
+
# "data": {
|
7935
|
+
# "cnvtPrice": "0.99940076",
|
7936
|
+
# "toCoin": "USDC",
|
7937
|
+
# "toCoinSize": "4.99700379",
|
7938
|
+
# "ts": "1712123746217"
|
7939
|
+
# }
|
7940
|
+
# }
|
7941
|
+
#
|
7942
|
+
data = self.safe_dict(response, 'data', {})
|
7943
|
+
toCurrencyId = self.safe_string(data, 'toCoin', toCode)
|
7944
|
+
toCurrency = self.currency(toCurrencyId)
|
7945
|
+
return self.parse_conversion(data, None, toCurrency)
|
7946
|
+
|
7898
7947
|
def parse_conversion(self, conversion, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
|
7899
7948
|
#
|
7900
7949
|
# fetchConvertQuote
|
@@ -7909,6 +7958,15 @@ class bitget(Exchange, ImplicitAPI):
|
|
7909
7958
|
# "fee": "0"
|
7910
7959
|
# }
|
7911
7960
|
#
|
7961
|
+
# createConvertTrade
|
7962
|
+
#
|
7963
|
+
# {
|
7964
|
+
# "cnvtPrice": "0.99940076",
|
7965
|
+
# "toCoin": "USDC",
|
7966
|
+
# "toCoinSize": "4.99700379",
|
7967
|
+
# "ts": "1712123746217"
|
7968
|
+
# }
|
7969
|
+
#
|
7912
7970
|
timestamp = self.safe_integer(conversion, 'ts')
|
7913
7971
|
fromCoin = self.safe_string(conversion, 'fromCoin')
|
7914
7972
|
fromCode = self.safe_currency_code(fromCoin, fromCurrency)
|
ccxt/async_support/bybit.py
CHANGED
@@ -4998,7 +4998,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
4998
4998
|
coin = self.safe_string(result, 'coin')
|
4999
4999
|
currency = self.currency(coin)
|
5000
5000
|
parsed = self.parse_deposit_addresses(chains, [currency['code']], False, {
|
5001
|
-
'currency': currency['
|
5001
|
+
'currency': currency['code'],
|
5002
5002
|
})
|
5003
5003
|
return self.index_by(parsed, 'network')
|
5004
5004
|
|
ccxt/async_support/coinex.py
CHANGED
@@ -617,54 +617,52 @@ class coinex(Exchange, ImplicitAPI):
|
|
617
617
|
async def fetch_markets(self, params={}) -> List[Market]:
|
618
618
|
"""
|
619
619
|
retrieves data on all markets for coinex
|
620
|
-
:see: https://
|
621
|
-
:see: https://
|
620
|
+
:see: https://docs.coinex.com/api/v2/spot/market/http/list-market
|
621
|
+
:see: https://docs.coinex.com/api/v2/futures/market/http/list-market
|
622
622
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
623
623
|
:returns dict[]: an array of objects representing market data
|
624
624
|
"""
|
625
|
-
|
625
|
+
promisesUnresolved = [
|
626
626
|
self.fetch_spot_markets(params),
|
627
627
|
self.fetch_contract_markets(params),
|
628
628
|
]
|
629
|
-
promises = await asyncio.gather(*
|
629
|
+
promises = await asyncio.gather(*promisesUnresolved)
|
630
630
|
spotMarkets = promises[0]
|
631
631
|
swapMarkets = promises[1]
|
632
632
|
return self.array_concat(spotMarkets, swapMarkets)
|
633
633
|
|
634
634
|
async def fetch_spot_markets(self, params):
|
635
|
-
response = await self.
|
635
|
+
response = await self.v2PublicGetSpotMarket(params)
|
636
636
|
#
|
637
637
|
# {
|
638
638
|
# "code": 0,
|
639
|
-
# "data":
|
640
|
-
#
|
641
|
-
# "
|
642
|
-
# "
|
643
|
-
# "
|
644
|
-
# "
|
645
|
-
# "
|
646
|
-
# "
|
647
|
-
# "
|
648
|
-
# "
|
649
|
-
#
|
650
|
-
#
|
639
|
+
# "data": [
|
640
|
+
# {
|
641
|
+
# "base_ccy": "SORA",
|
642
|
+
# "base_ccy_precision": 8,
|
643
|
+
# "is_amm_available": True,
|
644
|
+
# "is_margin_available": False,
|
645
|
+
# "maker_fee_rate": "0.003",
|
646
|
+
# "market": "SORAUSDT",
|
647
|
+
# "min_amount": "500",
|
648
|
+
# "quote_ccy": "USDT",
|
649
|
+
# "quote_ccy_precision": 6,
|
650
|
+
# "taker_fee_rate": "0.003"
|
651
|
+
# },
|
652
|
+
# ],
|
653
|
+
# "message": "OK"
|
651
654
|
# }
|
652
655
|
#
|
653
|
-
markets = self.
|
656
|
+
markets = self.safe_list(response, 'data', [])
|
654
657
|
result = []
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
tradingName = self.safe_string(market, 'trading_name')
|
661
|
-
baseId = tradingName
|
662
|
-
quoteId = self.safe_string(market, 'pricing_name')
|
658
|
+
for i in range(0, len(markets)):
|
659
|
+
market = markets[i]
|
660
|
+
id = self.safe_string(market, 'market')
|
661
|
+
baseId = self.safe_string(market, 'base_ccy')
|
662
|
+
quoteId = self.safe_string(market, 'quote_ccy')
|
663
663
|
base = self.safe_currency_code(baseId)
|
664
664
|
quote = self.safe_currency_code(quoteId)
|
665
665
|
symbol = base + '/' + quote
|
666
|
-
if tradingName == id:
|
667
|
-
symbol = id
|
668
666
|
result.append({
|
669
667
|
'id': id,
|
670
668
|
'symbol': symbol,
|
@@ -692,8 +690,8 @@ class coinex(Exchange, ImplicitAPI):
|
|
692
690
|
'strike': None,
|
693
691
|
'optionType': None,
|
694
692
|
'precision': {
|
695
|
-
'amount': self.parse_number(self.parse_precision(self.safe_string(market, '
|
696
|
-
'price': self.parse_number(self.parse_precision(self.safe_string(market, '
|
693
|
+
'amount': self.parse_number(self.parse_precision(self.safe_string(market, 'base_ccy_precision'))),
|
694
|
+
'price': self.parse_number(self.parse_precision(self.safe_string(market, 'quote_ccy_precision'))),
|
697
695
|
},
|
698
696
|
'limits': {
|
699
697
|
'leverage': {
|
@@ -719,45 +717,43 @@ class coinex(Exchange, ImplicitAPI):
|
|
719
717
|
return result
|
720
718
|
|
721
719
|
async def fetch_contract_markets(self, params):
|
722
|
-
response = await self.
|
720
|
+
response = await self.v2PublicGetFuturesMarket(params)
|
723
721
|
#
|
724
722
|
# {
|
725
723
|
# "code": 0,
|
726
724
|
# "data": [
|
727
725
|
# {
|
728
|
-
# "
|
729
|
-
# "
|
730
|
-
# "
|
731
|
-
# "
|
732
|
-
# "
|
733
|
-
# "
|
734
|
-
# "
|
735
|
-
# "
|
736
|
-
# "
|
737
|
-
# "
|
738
|
-
# "
|
739
|
-
# "tick_size": "0.1", # Min. Price Increment
|
740
|
-
# "available": True
|
726
|
+
# "base_ccy": "BTC",
|
727
|
+
# "base_ccy_precision": 8,
|
728
|
+
# "contract_type": "inverse",
|
729
|
+
# "leverage": ["1","2","3","5","8","10","15","20","30","50","100"],
|
730
|
+
# "maker_fee_rate": "0",
|
731
|
+
# "market": "BTCUSD",
|
732
|
+
# "min_amount": "10",
|
733
|
+
# "open_interest_volume": "2566879",
|
734
|
+
# "quote_ccy": "USD",
|
735
|
+
# "quote_ccy_precision": 2,
|
736
|
+
# "taker_fee_rate": "0"
|
741
737
|
# },
|
742
738
|
# ],
|
743
739
|
# "message": "OK"
|
744
740
|
# }
|
745
741
|
#
|
746
|
-
markets = self.
|
742
|
+
markets = self.safe_list(response, 'data', [])
|
747
743
|
result = []
|
748
744
|
for i in range(0, len(markets)):
|
749
745
|
entry = markets[i]
|
750
746
|
fees = self.fees
|
751
|
-
leverages = self.
|
752
|
-
subType = self.
|
753
|
-
linear = (subType ==
|
754
|
-
inverse = (subType ==
|
755
|
-
id = self.safe_string(entry, '
|
756
|
-
baseId = self.safe_string(entry, '
|
757
|
-
quoteId = self.safe_string(entry, '
|
747
|
+
leverages = self.safe_list(entry, 'leverage', [])
|
748
|
+
subType = self.safe_string(entry, 'contract_type')
|
749
|
+
linear = (subType == 'linear')
|
750
|
+
inverse = (subType == 'inverse')
|
751
|
+
id = self.safe_string(entry, 'market')
|
752
|
+
baseId = self.safe_string(entry, 'base_ccy')
|
753
|
+
quoteId = self.safe_string(entry, 'quote_ccy')
|
758
754
|
base = self.safe_currency_code(baseId)
|
759
755
|
quote = self.safe_currency_code(quoteId)
|
760
|
-
settleId = 'USDT' if (subType ==
|
756
|
+
settleId = 'USDT' if (subType == 'linear') else baseId
|
761
757
|
settle = self.safe_currency_code(settleId)
|
762
758
|
symbol = base + '/' + quote + ':' + settle
|
763
759
|
leveragesLength = len(leverages)
|
@@ -776,20 +772,20 @@ class coinex(Exchange, ImplicitAPI):
|
|
776
772
|
'swap': True,
|
777
773
|
'future': False,
|
778
774
|
'option': False,
|
779
|
-
'active':
|
775
|
+
'active': None,
|
780
776
|
'contract': True,
|
781
777
|
'linear': linear,
|
782
778
|
'inverse': inverse,
|
783
779
|
'taker': fees['trading']['taker'],
|
784
780
|
'maker': fees['trading']['maker'],
|
785
|
-
'contractSize': self.
|
781
|
+
'contractSize': self.parse_number('1'),
|
786
782
|
'expiry': None,
|
787
783
|
'expiryDatetime': None,
|
788
784
|
'strike': None,
|
789
785
|
'optionType': None,
|
790
786
|
'precision': {
|
791
|
-
'amount': self.parse_number(self.parse_precision(self.safe_string(entry, '
|
792
|
-
'price': self.parse_number(self.parse_precision(self.safe_string(entry, '
|
787
|
+
'amount': self.parse_number(self.parse_precision(self.safe_string(entry, 'base_ccy_precision'))),
|
788
|
+
'price': self.parse_number(self.parse_precision(self.safe_string(entry, 'quote_ccy_precision'))),
|
793
789
|
},
|
794
790
|
'limits': {
|
795
791
|
'leverage': {
|
@@ -797,7 +793,7 @@ class coinex(Exchange, ImplicitAPI):
|
|
797
793
|
'max': self.safe_number(leverages, leveragesLength - 1),
|
798
794
|
},
|
799
795
|
'amount': {
|
800
|
-
'min': self.safe_number(entry, '
|
796
|
+
'min': self.safe_number(entry, 'min_amount'),
|
801
797
|
'max': None,
|
802
798
|
},
|
803
799
|
'price': {
|
ccxt/async_support/okx.py
CHANGED
@@ -59,6 +59,7 @@ class okx(Exchange, ImplicitAPI):
|
|
59
59
|
'cancelOrders': True,
|
60
60
|
'closeAllPositions': False,
|
61
61
|
'closePosition': True,
|
62
|
+
'createConvertTrade': True,
|
62
63
|
'createDepositAddress': False,
|
63
64
|
'createMarketBuyOrderWithCost': True,
|
64
65
|
'createMarketSellOrderWithCost': True,
|
@@ -7151,6 +7152,57 @@ class okx(Exchange, ImplicitAPI):
|
|
7151
7152
|
toCurrency = self.currency(toCurrencyId)
|
7152
7153
|
return self.parse_conversion(result, fromCurrency, toCurrency)
|
7153
7154
|
|
7155
|
+
async def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
|
7156
|
+
"""
|
7157
|
+
convert from one currency to another
|
7158
|
+
:see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-convert-trade
|
7159
|
+
:param str id: the id of the trade that you want to make
|
7160
|
+
:param str fromCode: the currency that you want to sell and convert from
|
7161
|
+
:param str toCode: the currency that you want to buy and convert into
|
7162
|
+
:param float [amount]: how much you want to trade in units of the from currency
|
7163
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7164
|
+
:returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
|
7165
|
+
"""
|
7166
|
+
await self.load_markets()
|
7167
|
+
request = {
|
7168
|
+
'quoteId': id,
|
7169
|
+
'baseCcy': fromCode,
|
7170
|
+
'quoteCcy': toCode,
|
7171
|
+
'szCcy': fromCode,
|
7172
|
+
'sz': self.number_to_string(amount),
|
7173
|
+
'side': 'sell',
|
7174
|
+
}
|
7175
|
+
response = await self.privatePostAssetConvertTrade(self.extend(request, params))
|
7176
|
+
#
|
7177
|
+
# {
|
7178
|
+
# "code": "0",
|
7179
|
+
# "data": [
|
7180
|
+
# {
|
7181
|
+
# "baseCcy": "ETH",
|
7182
|
+
# "clTReqId": "",
|
7183
|
+
# "fillBaseSz": "0.01023052",
|
7184
|
+
# "fillPx": "2932.40104429",
|
7185
|
+
# "fillQuoteSz": "30",
|
7186
|
+
# "instId": "ETH-USDT",
|
7187
|
+
# "quoteCcy": "USDT",
|
7188
|
+
# "quoteId": "quoterETH-USDT16461885104612381",
|
7189
|
+
# "side": "buy",
|
7190
|
+
# "state": "fullyFilled",
|
7191
|
+
# "tradeId": "trader16461885203381437",
|
7192
|
+
# "ts": "1646188520338"
|
7193
|
+
# }
|
7194
|
+
# ],
|
7195
|
+
# "msg": ""
|
7196
|
+
# }
|
7197
|
+
#
|
7198
|
+
data = self.safe_list(response, 'data', [])
|
7199
|
+
result = self.safe_dict(data, 0, {})
|
7200
|
+
fromCurrencyId = self.safe_string(result, 'baseCcy', fromCode)
|
7201
|
+
fromCurrency = self.currency(fromCurrencyId)
|
7202
|
+
toCurrencyId = self.safe_string(result, 'quoteCcy', toCode)
|
7203
|
+
toCurrency = self.currency(toCurrencyId)
|
7204
|
+
return self.parse_conversion(result, fromCurrency, toCurrency)
|
7205
|
+
|
7154
7206
|
def parse_conversion(self, conversion, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
|
7155
7207
|
#
|
7156
7208
|
# fetchConvertQuote
|
@@ -7171,7 +7223,24 @@ class okx(Exchange, ImplicitAPI):
|
|
7171
7223
|
# "ttlMs": "10000"
|
7172
7224
|
# }
|
7173
7225
|
#
|
7174
|
-
|
7226
|
+
# createConvertTrade
|
7227
|
+
#
|
7228
|
+
# {
|
7229
|
+
# "baseCcy": "ETH",
|
7230
|
+
# "clTReqId": "",
|
7231
|
+
# "fillBaseSz": "0.01023052",
|
7232
|
+
# "fillPx": "2932.40104429",
|
7233
|
+
# "fillQuoteSz": "30",
|
7234
|
+
# "instId": "ETH-USDT",
|
7235
|
+
# "quoteCcy": "USDT",
|
7236
|
+
# "quoteId": "quoterETH-USDT16461885104612381",
|
7237
|
+
# "side": "buy",
|
7238
|
+
# "state": "fullyFilled",
|
7239
|
+
# "tradeId": "trader16461885203381437",
|
7240
|
+
# "ts": "1646188520338"
|
7241
|
+
# }
|
7242
|
+
#
|
7243
|
+
timestamp = self.safe_integer_2(conversion, 'quoteTime', 'ts')
|
7175
7244
|
fromCoin = self.safe_string(conversion, 'baseCcy')
|
7176
7245
|
fromCode = self.safe_currency_code(fromCoin, fromCurrency)
|
7177
7246
|
to = self.safe_string(conversion, 'quoteCcy')
|
@@ -7180,12 +7249,12 @@ class okx(Exchange, ImplicitAPI):
|
|
7180
7249
|
'info': conversion,
|
7181
7250
|
'timestamp': timestamp,
|
7182
7251
|
'datetime': self.iso8601(timestamp),
|
7183
|
-
'id': self.
|
7252
|
+
'id': self.safe_string_n(conversion, ['clQReqId', 'tradeId', 'quoteId']),
|
7184
7253
|
'fromCurrency': fromCode,
|
7185
|
-
'fromAmount': self.
|
7254
|
+
'fromAmount': self.safe_number_2(conversion, 'baseSz', 'fillBaseSz'),
|
7186
7255
|
'toCurrency': toCode,
|
7187
|
-
'toAmount': self.
|
7188
|
-
'price': self.
|
7256
|
+
'toAmount': self.safe_number_2(conversion, 'quoteSz', 'fillQuoteSz'),
|
7257
|
+
'price': self.safe_number_2(conversion, 'cnvtPx', 'fillPx'),
|
7189
7258
|
'fee': None,
|
7190
7259
|
}
|
7191
7260
|
|
ccxt/async_support/woo.py
CHANGED
@@ -45,6 +45,7 @@ class woo(Exchange, ImplicitAPI):
|
|
45
45
|
'cancelWithdraw': False, # exchange have that endpoint disabled atm, but was once implemented in ccxt per old docs: https://kronosresearch.github.io/wootrade-documents/#cancel-withdraw-request
|
46
46
|
'closeAllPositions': False,
|
47
47
|
'closePosition': False,
|
48
|
+
'createConvertTrade': True,
|
48
49
|
'createDepositAddress': False,
|
49
50
|
'createMarketBuyOrderWithCost': True,
|
50
51
|
'createMarketOrder': False,
|
@@ -2823,6 +2824,35 @@ class woo(Exchange, ImplicitAPI):
|
|
2823
2824
|
toCurrency = self.currency(toCurrencyId)
|
2824
2825
|
return self.parse_conversion(data, fromCurrency, toCurrency)
|
2825
2826
|
|
2827
|
+
async def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
|
2828
|
+
"""
|
2829
|
+
convert from one currency to another
|
2830
|
+
:see: https://docs.woo.org/#send-quote-rft
|
2831
|
+
:param str id: the id of the trade that you want to make
|
2832
|
+
:param str fromCode: the currency that you want to sell and convert from
|
2833
|
+
:param str toCode: the currency that you want to buy and convert into
|
2834
|
+
:param float [amount]: how much you want to trade in units of the from currency
|
2835
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2836
|
+
:returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
|
2837
|
+
"""
|
2838
|
+
await self.load_markets()
|
2839
|
+
request = {
|
2840
|
+
'quoteId': id,
|
2841
|
+
}
|
2842
|
+
response = await self.v3PrivatePostConvertRft(self.extend(request, params))
|
2843
|
+
#
|
2844
|
+
# {
|
2845
|
+
# "success": True,
|
2846
|
+
# "data": {
|
2847
|
+
# "quoteId": 123123123,
|
2848
|
+
# "counterPartyId": "",
|
2849
|
+
# "rftAccepted": 1 # 1 -> success; 2 -> processing; 3 -> fail
|
2850
|
+
# }
|
2851
|
+
# }
|
2852
|
+
#
|
2853
|
+
data = self.safe_dict(response, 'data', {})
|
2854
|
+
return self.parse_conversion(data)
|
2855
|
+
|
2826
2856
|
def parse_conversion(self, conversion, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
|
2827
2857
|
#
|
2828
2858
|
# fetchConvertQuote
|
@@ -2839,6 +2869,14 @@ class woo(Exchange, ImplicitAPI):
|
|
2839
2869
|
# "message": 1659084466000
|
2840
2870
|
# }
|
2841
2871
|
#
|
2872
|
+
# createConvertTrade
|
2873
|
+
#
|
2874
|
+
# {
|
2875
|
+
# "quoteId": 123123123,
|
2876
|
+
# "counterPartyId": "",
|
2877
|
+
# "rftAccepted": 1 # 1 -> success; 2 -> processing; 3 -> fail
|
2878
|
+
# }
|
2879
|
+
#
|
2842
2880
|
timestamp = self.safe_integer(conversion, 'expireTimestamp')
|
2843
2881
|
fromCoin = self.safe_string(conversion, 'sellToken')
|
2844
2882
|
fromCode = self.safe_currency_code(fromCoin, fromCurrency)
|
ccxt/base/exchange.py
CHANGED
ccxt/binance.py
CHANGED
@@ -7,7 +7,7 @@ from ccxt.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.binance import ImplicitAPI
|
8
8
|
import hashlib
|
9
9
|
import json
|
10
|
-
from ccxt.base.types import Balances, Currencies, Currency, Greeks, Int, Leverage, Leverages, MarginMode, MarginModes, MarginModification, Market, MarketInterface, Num, Option, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
|
10
|
+
from ccxt.base.types import Balances, Conversion, Currencies, Currency, Greeks, Int, Leverage, Leverages, MarginMode, MarginModes, MarginModification, Market, MarketInterface, Num, Option, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ExchangeError
|
13
13
|
from ccxt.base.errors import AuthenticationError
|
@@ -62,6 +62,7 @@ class binance(Exchange, ImplicitAPI):
|
|
62
62
|
'cancelOrders': True, # contract only
|
63
63
|
'closeAllPositions': False,
|
64
64
|
'closePosition': False, # exchange specific closePosition parameter for binance createOrder is not synonymous with how CCXT uses closePositions
|
65
|
+
'createConvertTrade': True,
|
65
66
|
'createDepositAddress': False,
|
66
67
|
'createLimitBuyOrder': True,
|
67
68
|
'createLimitSellOrder': True,
|
@@ -11635,3 +11636,56 @@ class binance(Exchange, ImplicitAPI):
|
|
11635
11636
|
'created': None,
|
11636
11637
|
}
|
11637
11638
|
return result
|
11639
|
+
|
11640
|
+
def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
|
11641
|
+
"""
|
11642
|
+
convert from one currency to another
|
11643
|
+
:see: https://binance-docs.github.io/apidocs/spot/en/#busd-convert-trade
|
11644
|
+
:param str id: the id of the trade that you want to make
|
11645
|
+
:param str fromCode: the currency that you want to sell and convert from
|
11646
|
+
:param str toCode: the currency that you want to buy and convert into
|
11647
|
+
:param float [amount]: how much you want to trade in units of the from currency
|
11648
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
11649
|
+
:returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
|
11650
|
+
"""
|
11651
|
+
self.load_markets()
|
11652
|
+
request = {
|
11653
|
+
'clientTranId': id,
|
11654
|
+
'asset': fromCode,
|
11655
|
+
'targetAsset': toCode,
|
11656
|
+
'amount': amount,
|
11657
|
+
}
|
11658
|
+
response = self.sapiPostAssetConvertTransfer(self.extend(request, params))
|
11659
|
+
#
|
11660
|
+
# {
|
11661
|
+
# "tranId": 118263407119,
|
11662
|
+
# "status": "S"
|
11663
|
+
# }
|
11664
|
+
#
|
11665
|
+
fromCurrency = self.currency(fromCode)
|
11666
|
+
toCurrency = self.currency(toCode)
|
11667
|
+
return self.parse_conversion(response, fromCurrency, toCurrency)
|
11668
|
+
|
11669
|
+
def parse_conversion(self, conversion, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
|
11670
|
+
#
|
11671
|
+
# createConvertTrade
|
11672
|
+
#
|
11673
|
+
# {
|
11674
|
+
# "tranId": 118263407119,
|
11675
|
+
# "status": "S"
|
11676
|
+
# }
|
11677
|
+
#
|
11678
|
+
fromCode = self.safe_currency_code(None, fromCurrency)
|
11679
|
+
toCode = self.safe_currency_code(None, toCurrency)
|
11680
|
+
return {
|
11681
|
+
'info': conversion,
|
11682
|
+
'timestamp': None,
|
11683
|
+
'datetime': None,
|
11684
|
+
'id': self.safe_string(conversion, 'tranId'),
|
11685
|
+
'fromCurrency': fromCode,
|
11686
|
+
'fromAmount': None,
|
11687
|
+
'toCurrency': toCode,
|
11688
|
+
'toAmount': None,
|
11689
|
+
'price': None,
|
11690
|
+
'fee': None,
|
11691
|
+
}
|