ccxt 4.2.93__py2.py3-none-any.whl → 4.2.94__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.
Potentially problematic release.
This version of ccxt might be problematic. Click here for more details.
- ccxt/__init__.py +1 -1
- ccxt/abstract/binance.py +1 -0
- ccxt/abstract/binancecoinm.py +1 -0
- ccxt/abstract/binanceus.py +1 -0
- ccxt/abstract/binanceusdm.py +1 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +7 -1
- ccxt/async_support/binance.py +60 -2
- ccxt/async_support/bitget.py +135 -1
- ccxt/async_support/okx.py +149 -1
- ccxt/async_support/woo.py +135 -1
- ccxt/base/exchange.py +18 -1
- ccxt/base/types.py +13 -0
- ccxt/binance.py +60 -2
- ccxt/bitget.py +135 -1
- ccxt/okx.py +149 -1
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/kraken.py +96 -18
- ccxt/pro/krakenfutures.py +104 -39
- ccxt/pro/kucoin.py +25 -16
- ccxt/woo.py +135 -1
- {ccxt-4.2.93.dist-info → ccxt-4.2.94.dist-info}/METADATA +4 -4
- {ccxt-4.2.93.dist-info → ccxt-4.2.94.dist-info}/RECORD +25 -25
- {ccxt-4.2.93.dist-info → ccxt-4.2.94.dist-info}/WHEEL +0 -0
- {ccxt-4.2.93.dist-info → ccxt-4.2.94.dist-info}/top_level.txt +0 -0
ccxt/__init__.py
CHANGED
ccxt/abstract/binance.py
CHANGED
@@ -608,6 +608,7 @@ class ImplicitAPI:
|
|
608
608
|
private_get_myallocations = privateGetMyAllocations = Entry('myAllocations', 'private', 'GET', {'cost': 4})
|
609
609
|
private_get_account_commission = privateGetAccountCommission = Entry('account/commission', 'private', 'GET', {'cost': 4})
|
610
610
|
private_post_order_oco = privatePostOrderOco = Entry('order/oco', 'private', 'POST', {'cost': 0.2})
|
611
|
+
private_post_orderlist_oco = privatePostOrderListOco = Entry('orderList/oco', 'private', 'POST', {'cost': 0.2})
|
611
612
|
private_post_sor_order = privatePostSorOrder = Entry('sor/order', 'private', 'POST', {'cost': 0.2})
|
612
613
|
private_post_sor_order_test = privatePostSorOrderTest = Entry('sor/order/test', 'private', 'POST', {'cost': 0.2})
|
613
614
|
private_post_order = privatePostOrder = Entry('order', 'private', 'POST', {'cost': 0.2})
|
ccxt/abstract/binancecoinm.py
CHANGED
@@ -608,6 +608,7 @@ class ImplicitAPI:
|
|
608
608
|
private_get_myallocations = privateGetMyAllocations = Entry('myAllocations', 'private', 'GET', {'cost': 4})
|
609
609
|
private_get_account_commission = privateGetAccountCommission = Entry('account/commission', 'private', 'GET', {'cost': 4})
|
610
610
|
private_post_order_oco = privatePostOrderOco = Entry('order/oco', 'private', 'POST', {'cost': 0.2})
|
611
|
+
private_post_orderlist_oco = privatePostOrderListOco = Entry('orderList/oco', 'private', 'POST', {'cost': 0.2})
|
611
612
|
private_post_sor_order = privatePostSorOrder = Entry('sor/order', 'private', 'POST', {'cost': 0.2})
|
612
613
|
private_post_sor_order_test = privatePostSorOrderTest = Entry('sor/order/test', 'private', 'POST', {'cost': 0.2})
|
613
614
|
private_post_order = privatePostOrder = Entry('order', 'private', 'POST', {'cost': 0.2})
|
ccxt/abstract/binanceus.py
CHANGED
@@ -660,6 +660,7 @@ class ImplicitAPI:
|
|
660
660
|
private_get_myallocations = privateGetMyAllocations = Entry('myAllocations', 'private', 'GET', {'cost': 4})
|
661
661
|
private_get_account_commission = privateGetAccountCommission = Entry('account/commission', 'private', 'GET', {'cost': 4})
|
662
662
|
private_post_order_oco = privatePostOrderOco = Entry('order/oco', 'private', 'POST', {'cost': 0.2})
|
663
|
+
private_post_orderlist_oco = privatePostOrderListOco = Entry('orderList/oco', 'private', 'POST', {'cost': 0.2})
|
663
664
|
private_post_sor_order = privatePostSorOrder = Entry('sor/order', 'private', 'POST', {'cost': 0.2})
|
664
665
|
private_post_sor_order_test = privatePostSorOrderTest = Entry('sor/order/test', 'private', 'POST', {'cost': 0.2})
|
665
666
|
private_post_order = privatePostOrder = Entry('order', 'private', 'POST', {'cost': 0.2})
|
ccxt/abstract/binanceusdm.py
CHANGED
@@ -608,6 +608,7 @@ class ImplicitAPI:
|
|
608
608
|
private_get_myallocations = privateGetMyAllocations = Entry('myAllocations', 'private', 'GET', {'cost': 4})
|
609
609
|
private_get_account_commission = privateGetAccountCommission = Entry('account/commission', 'private', 'GET', {'cost': 4})
|
610
610
|
private_post_order_oco = privatePostOrderOco = Entry('order/oco', 'private', 'POST', {'cost': 0.2})
|
611
|
+
private_post_orderlist_oco = privatePostOrderListOco = Entry('orderList/oco', 'private', 'POST', {'cost': 0.2})
|
611
612
|
private_post_sor_order = privatePostSorOrder = Entry('sor/order', 'private', 'POST', {'cost': 0.2})
|
612
613
|
private_post_sor_order_test = privatePostSorOrderTest = Entry('sor/order/test', 'private', 'POST', {'cost': 0.2})
|
613
614
|
private_post_order = privatePostOrder = Entry('order', 'private', 'POST', {'cost': 0.2})
|
ccxt/async_support/__init__.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# -----------------------------------------------------------------------------
|
4
4
|
|
5
|
-
__version__ = '4.2.
|
5
|
+
__version__ = '4.2.94'
|
6
6
|
|
7
7
|
# -----------------------------------------------------------------------------
|
8
8
|
|
@@ -1281,6 +1281,9 @@ class Exchange(BaseExchange):
|
|
1281
1281
|
async def fetch_option(self, symbol: str, params={}):
|
1282
1282
|
raise NotSupported(self.id + ' fetchOption() is not supported yet')
|
1283
1283
|
|
1284
|
+
async def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}):
|
1285
|
+
raise NotSupported(self.id + ' fetchConvertQuote() is not supported yet')
|
1286
|
+
|
1284
1287
|
async def fetch_deposits_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
|
1285
1288
|
"""
|
1286
1289
|
fetch history of deposits and withdrawals
|
@@ -1421,6 +1424,9 @@ class Exchange(BaseExchange):
|
|
1421
1424
|
fees = await self.fetch_trading_fees(params)
|
1422
1425
|
return self.safe_dict(fees, symbol)
|
1423
1426
|
|
1427
|
+
async def fetch_convert_currencies(self, params={}):
|
1428
|
+
raise NotSupported(self.id + ' fetchConvertCurrencies() is not supported yet')
|
1429
|
+
|
1424
1430
|
async def fetch_funding_rate(self, symbol: str, params={}):
|
1425
1431
|
if self.has['fetchFundingRates']:
|
1426
1432
|
await self.load_markets()
|
ccxt/async_support/binance.py
CHANGED
@@ -94,6 +94,8 @@ class binance(Exchange, ImplicitAPI):
|
|
94
94
|
'fetchCanceledOrders': 'emulated',
|
95
95
|
'fetchClosedOrder': False,
|
96
96
|
'fetchClosedOrders': 'emulated',
|
97
|
+
'fetchConvertCurrencies': True,
|
98
|
+
'fetchConvertQuote': False,
|
97
99
|
'fetchCrossBorrowRate': True,
|
98
100
|
'fetchCrossBorrowRates': False,
|
99
101
|
'fetchCurrencies': True,
|
@@ -993,6 +995,7 @@ class binance(Exchange, ImplicitAPI):
|
|
993
995
|
},
|
994
996
|
'post': {
|
995
997
|
'order/oco': 0.2,
|
998
|
+
'orderList/oco': 0.2,
|
996
999
|
'sor/order': 0.2,
|
997
1000
|
'sor/order/test': 0.2,
|
998
1001
|
'order': 0.2,
|
@@ -4109,10 +4112,13 @@ class binance(Exchange, ImplicitAPI):
|
|
4109
4112
|
'interval': self.safe_string(self.timeframes, timeframe, timeframe),
|
4110
4113
|
'limit': limit,
|
4111
4114
|
}
|
4115
|
+
marketId = market['id']
|
4112
4116
|
if price == 'index':
|
4113
|
-
|
4117
|
+
parts = marketId.split('_')
|
4118
|
+
pair = self.safe_string(parts, 0)
|
4119
|
+
request['pair'] = pair # Index price takes self argument instead of symbol
|
4114
4120
|
else:
|
4115
|
-
request['symbol'] =
|
4121
|
+
request['symbol'] = marketId
|
4116
4122
|
# duration = self.parse_timeframe(timeframe)
|
4117
4123
|
if since is not None:
|
4118
4124
|
request['startTime'] = since
|
@@ -11578,3 +11584,55 @@ class binance(Exchange, ImplicitAPI):
|
|
11578
11584
|
#
|
11579
11585
|
modifications = self.parse_margin_modifications(response)
|
11580
11586
|
return self.filter_by_symbol_since_limit(modifications, symbol, since, limit)
|
11587
|
+
|
11588
|
+
async def fetch_convert_currencies(self, params={}) -> Currencies:
|
11589
|
+
"""
|
11590
|
+
fetches all available currencies that can be converted
|
11591
|
+
:see: https://binance-docs.github.io/apidocs/spot/en/#query-order-quantity-precision-per-asset-user_data
|
11592
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
11593
|
+
:returns dict: an associative dictionary of currencies
|
11594
|
+
"""
|
11595
|
+
await self.load_markets()
|
11596
|
+
response = await self.sapiGetConvertAssetInfo(params)
|
11597
|
+
#
|
11598
|
+
# [
|
11599
|
+
# {
|
11600
|
+
# "asset": "BTC",
|
11601
|
+
# "fraction": 8
|
11602
|
+
# },
|
11603
|
+
# ]
|
11604
|
+
#
|
11605
|
+
result = {}
|
11606
|
+
for i in range(0, len(response)):
|
11607
|
+
entry = response[i]
|
11608
|
+
id = self.safe_string(entry, 'asset')
|
11609
|
+
code = self.safe_currency_code(id)
|
11610
|
+
result[code] = {
|
11611
|
+
'info': entry,
|
11612
|
+
'id': id,
|
11613
|
+
'code': code,
|
11614
|
+
'networks': None,
|
11615
|
+
'type': None,
|
11616
|
+
'name': None,
|
11617
|
+
'active': None,
|
11618
|
+
'deposit': None,
|
11619
|
+
'withdraw': None,
|
11620
|
+
'fee': None,
|
11621
|
+
'precision': self.safe_integer(entry, 'fraction'),
|
11622
|
+
'limits': {
|
11623
|
+
'amount': {
|
11624
|
+
'min': None,
|
11625
|
+
'max': None,
|
11626
|
+
},
|
11627
|
+
'withdraw': {
|
11628
|
+
'min': None,
|
11629
|
+
'max': None,
|
11630
|
+
},
|
11631
|
+
'deposit': {
|
11632
|
+
'min': None,
|
11633
|
+
'max': None,
|
11634
|
+
},
|
11635
|
+
},
|
11636
|
+
'created': None,
|
11637
|
+
}
|
11638
|
+
return result
|
ccxt/async_support/bitget.py
CHANGED
@@ -8,7 +8,7 @@ from ccxt.abstract.bitget import ImplicitAPI
|
|
8
8
|
import asyncio
|
9
9
|
import hashlib
|
10
10
|
import json
|
11
|
-
from ccxt.base.types import Balances, Currencies, Currency, FundingHistory, Int, Liquidation, Leverage, MarginMode, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
|
11
|
+
from ccxt.base.types import Balances, Conversion, Currencies, Currency, FundingHistory, Int, Liquidation, Leverage, MarginMode, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, 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 PermissionDenied
|
@@ -85,6 +85,8 @@ class bitget(Exchange, ImplicitAPI):
|
|
85
85
|
'fetchCanceledAndClosedOrders': True,
|
86
86
|
'fetchCanceledOrders': True,
|
87
87
|
'fetchClosedOrders': True,
|
88
|
+
'fetchConvertCurrencies': True,
|
89
|
+
'fetchConvertQuote': True,
|
88
90
|
'fetchCrossBorrowRate': True,
|
89
91
|
'fetchCrossBorrowRates': False,
|
90
92
|
'fetchCurrencies': True,
|
@@ -7853,6 +7855,138 @@ class bitget(Exchange, ImplicitAPI):
|
|
7853
7855
|
'marginMode': marginType,
|
7854
7856
|
}
|
7855
7857
|
|
7858
|
+
async def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
|
7859
|
+
"""
|
7860
|
+
fetch a quote for converting from one currency to another
|
7861
|
+
:see: https://www.bitget.com/api-doc/common/convert/Get-Quoted-Price
|
7862
|
+
:param str fromCode: the currency that you want to sell and convert from
|
7863
|
+
:param str toCode: the currency that you want to buy and convert into
|
7864
|
+
:param float [amount]: how much you want to trade in units of the from currency
|
7865
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7866
|
+
:returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
|
7867
|
+
"""
|
7868
|
+
await self.load_markets()
|
7869
|
+
request = {
|
7870
|
+
'fromCoin': fromCode.upper(),
|
7871
|
+
'toCoin': toCode.upper(),
|
7872
|
+
'fromCoinSize': self.number_to_string(amount),
|
7873
|
+
}
|
7874
|
+
response = await self.privateConvertGetV2ConvertQuotedPrice(self.extend(request, params))
|
7875
|
+
#
|
7876
|
+
# {
|
7877
|
+
# "code": "00000",
|
7878
|
+
# "msg": "success",
|
7879
|
+
# "requestTime": 1712121940158,
|
7880
|
+
# "data": {
|
7881
|
+
# "fromCoin": "USDT",
|
7882
|
+
# "fromCoinSize": "5",
|
7883
|
+
# "cnvtPrice": "0.9993007892377704",
|
7884
|
+
# "toCoin": "USDC",
|
7885
|
+
# "toCoinSize": "4.99650394",
|
7886
|
+
# "traceId": "1159288930228187140",
|
7887
|
+
# "fee": "0"
|
7888
|
+
# }
|
7889
|
+
# }
|
7890
|
+
#
|
7891
|
+
data = self.safe_dict(response, 'data', {})
|
7892
|
+
fromCurrencyId = self.safe_string(data, 'fromCoin', fromCode)
|
7893
|
+
fromCurrency = self.currency(fromCurrencyId)
|
7894
|
+
toCurrencyId = self.safe_string(data, 'toCoin', toCode)
|
7895
|
+
toCurrency = self.currency(toCurrencyId)
|
7896
|
+
return self.parse_conversion(data, fromCurrency, toCurrency)
|
7897
|
+
|
7898
|
+
def parse_conversion(self, conversion, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
|
7899
|
+
#
|
7900
|
+
# fetchConvertQuote
|
7901
|
+
#
|
7902
|
+
# {
|
7903
|
+
# "fromCoin": "USDT",
|
7904
|
+
# "fromCoinSize": "5",
|
7905
|
+
# "cnvtPrice": "0.9993007892377704",
|
7906
|
+
# "toCoin": "USDC",
|
7907
|
+
# "toCoinSize": "4.99650394",
|
7908
|
+
# "traceId": "1159288930228187140",
|
7909
|
+
# "fee": "0"
|
7910
|
+
# }
|
7911
|
+
#
|
7912
|
+
timestamp = self.safe_integer(conversion, 'ts')
|
7913
|
+
fromCoin = self.safe_string(conversion, 'fromCoin')
|
7914
|
+
fromCode = self.safe_currency_code(fromCoin, fromCurrency)
|
7915
|
+
to = self.safe_string(conversion, 'toCoin')
|
7916
|
+
toCode = self.safe_currency_code(to, toCurrency)
|
7917
|
+
return {
|
7918
|
+
'info': conversion,
|
7919
|
+
'timestamp': timestamp,
|
7920
|
+
'datetime': self.iso8601(timestamp),
|
7921
|
+
'id': self.safe_string(conversion, 'traceId'),
|
7922
|
+
'fromCurrency': fromCode,
|
7923
|
+
'fromAmount': self.safe_number(conversion, 'fromCoinSize'),
|
7924
|
+
'toCurrency': toCode,
|
7925
|
+
'toAmount': self.safe_number(conversion, 'toCoinSize'),
|
7926
|
+
'price': self.safe_number(conversion, 'cnvtPrice'),
|
7927
|
+
'fee': self.safe_number(conversion, 'fee'),
|
7928
|
+
}
|
7929
|
+
|
7930
|
+
async def fetch_convert_currencies(self, params={}) -> Currencies:
|
7931
|
+
"""
|
7932
|
+
fetches all available currencies that can be converted
|
7933
|
+
:see: https://www.bitget.com/api-doc/common/convert/Get-Convert-Currencies
|
7934
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7935
|
+
:returns dict: an associative dictionary of currencies
|
7936
|
+
"""
|
7937
|
+
await self.load_markets()
|
7938
|
+
response = await self.privateConvertGetV2ConvertCurrencies(params)
|
7939
|
+
#
|
7940
|
+
# {
|
7941
|
+
# "code": "00000",
|
7942
|
+
# "msg": "success",
|
7943
|
+
# "requestTime": 1712121755897,
|
7944
|
+
# "data": [
|
7945
|
+
# {
|
7946
|
+
# "coin": "BTC",
|
7947
|
+
# "available": "0.00009850",
|
7948
|
+
# "maxAmount": "0.756266",
|
7949
|
+
# "minAmount": "0.00001"
|
7950
|
+
# },
|
7951
|
+
# ]
|
7952
|
+
# }
|
7953
|
+
#
|
7954
|
+
result = {}
|
7955
|
+
data = self.safe_list(response, 'data', [])
|
7956
|
+
for i in range(0, len(data)):
|
7957
|
+
entry = data[i]
|
7958
|
+
id = self.safe_string(entry, 'coin')
|
7959
|
+
code = self.safe_currency_code(id)
|
7960
|
+
result[code] = {
|
7961
|
+
'info': entry,
|
7962
|
+
'id': id,
|
7963
|
+
'code': code,
|
7964
|
+
'networks': None,
|
7965
|
+
'type': None,
|
7966
|
+
'name': None,
|
7967
|
+
'active': None,
|
7968
|
+
'deposit': None,
|
7969
|
+
'withdraw': self.safe_number(entry, 'available'),
|
7970
|
+
'fee': None,
|
7971
|
+
'precision': None,
|
7972
|
+
'limits': {
|
7973
|
+
'amount': {
|
7974
|
+
'min': self.safe_number(entry, 'minAmount'),
|
7975
|
+
'max': self.safe_number(entry, 'maxAmount'),
|
7976
|
+
},
|
7977
|
+
'withdraw': {
|
7978
|
+
'min': None,
|
7979
|
+
'max': None,
|
7980
|
+
},
|
7981
|
+
'deposit': {
|
7982
|
+
'min': None,
|
7983
|
+
'max': None,
|
7984
|
+
},
|
7985
|
+
},
|
7986
|
+
'created': None,
|
7987
|
+
}
|
7988
|
+
return result
|
7989
|
+
|
7856
7990
|
def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
|
7857
7991
|
if not response:
|
7858
7992
|
return None # fallback to default error handler
|
ccxt/async_support/okx.py
CHANGED
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.okx import ImplicitAPI
|
8
8
|
import asyncio
|
9
9
|
import hashlib
|
10
|
-
from ccxt.base.types import Account, Balances, Currencies, Currency, Greeks, Int, Leverage, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
|
10
|
+
from ccxt.base.types import Account, Balances, Conversion, Currencies, Currency, Greeks, Int, Leverage, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ExchangeError
|
13
13
|
from ccxt.base.errors import PermissionDenied
|
@@ -83,6 +83,8 @@ class okx(Exchange, ImplicitAPI):
|
|
83
83
|
'fetchCanceledOrders': True,
|
84
84
|
'fetchClosedOrder': None,
|
85
85
|
'fetchClosedOrders': True,
|
86
|
+
'fetchConvertCurrencies': True,
|
87
|
+
'fetchConvertQuote': True,
|
86
88
|
'fetchCrossBorrowRate': True,
|
87
89
|
'fetchCrossBorrowRates': True,
|
88
90
|
'fetchCurrencies': True,
|
@@ -7098,6 +7100,152 @@ class okx(Exchange, ImplicitAPI):
|
|
7098
7100
|
'quoteVolume': None,
|
7099
7101
|
}
|
7100
7102
|
|
7103
|
+
async def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
|
7104
|
+
"""
|
7105
|
+
fetch a quote for converting from one currency to another
|
7106
|
+
:see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-estimate-quote
|
7107
|
+
:param str fromCode: the currency that you want to sell and convert from
|
7108
|
+
:param str toCode: the currency that you want to buy and convert into
|
7109
|
+
:param float [amount]: how much you want to trade in units of the from currency
|
7110
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7111
|
+
:returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
|
7112
|
+
"""
|
7113
|
+
await self.load_markets()
|
7114
|
+
request = {
|
7115
|
+
'baseCcy': fromCode.upper(),
|
7116
|
+
'quoteCcy': toCode.upper(),
|
7117
|
+
'rfqSzCcy': fromCode.upper(),
|
7118
|
+
'rfqSz': self.number_to_string(amount),
|
7119
|
+
'side': 'sell',
|
7120
|
+
}
|
7121
|
+
response = await self.privatePostAssetConvertEstimateQuote(self.extend(request, params))
|
7122
|
+
#
|
7123
|
+
# {
|
7124
|
+
# "code": "0",
|
7125
|
+
# "data": [
|
7126
|
+
# {
|
7127
|
+
# "baseCcy": "ETH",
|
7128
|
+
# "baseSz": "0.01023052",
|
7129
|
+
# "clQReqId": "",
|
7130
|
+
# "cnvtPx": "2932.40104429",
|
7131
|
+
# "origRfqSz": "30",
|
7132
|
+
# "quoteCcy": "USDT",
|
7133
|
+
# "quoteId": "quoterETH-USDT16461885104612381",
|
7134
|
+
# "quoteSz": "30",
|
7135
|
+
# "quoteTime": "1646188510461",
|
7136
|
+
# "rfqSz": "30",
|
7137
|
+
# "rfqSzCcy": "USDT",
|
7138
|
+
# "side": "buy",
|
7139
|
+
# "ttlMs": "10000"
|
7140
|
+
# }
|
7141
|
+
# ],
|
7142
|
+
# "msg": ""
|
7143
|
+
# }
|
7144
|
+
#
|
7145
|
+
data = self.safe_list(response, 'data', [])
|
7146
|
+
result = self.safe_dict(data, 0, {})
|
7147
|
+
fromCurrencyId = self.safe_string(result, 'baseCcy', fromCode)
|
7148
|
+
fromCurrency = self.currency(fromCurrencyId)
|
7149
|
+
toCurrencyId = self.safe_string(result, 'quoteCcy', toCode)
|
7150
|
+
toCurrency = self.currency(toCurrencyId)
|
7151
|
+
return self.parse_conversion(result, fromCurrency, toCurrency)
|
7152
|
+
|
7153
|
+
def parse_conversion(self, conversion, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
|
7154
|
+
#
|
7155
|
+
# fetchConvertQuote
|
7156
|
+
#
|
7157
|
+
# {
|
7158
|
+
# "baseCcy": "ETH",
|
7159
|
+
# "baseSz": "0.01023052",
|
7160
|
+
# "clQReqId": "",
|
7161
|
+
# "cnvtPx": "2932.40104429",
|
7162
|
+
# "origRfqSz": "30",
|
7163
|
+
# "quoteCcy": "USDT",
|
7164
|
+
# "quoteId": "quoterETH-USDT16461885104612381",
|
7165
|
+
# "quoteSz": "30",
|
7166
|
+
# "quoteTime": "1646188510461",
|
7167
|
+
# "rfqSz": "30",
|
7168
|
+
# "rfqSzCcy": "USDT",
|
7169
|
+
# "side": "buy",
|
7170
|
+
# "ttlMs": "10000"
|
7171
|
+
# }
|
7172
|
+
#
|
7173
|
+
timestamp = self.safe_integer(conversion, 'quoteTime')
|
7174
|
+
fromCoin = self.safe_string(conversion, 'baseCcy')
|
7175
|
+
fromCode = self.safe_currency_code(fromCoin, fromCurrency)
|
7176
|
+
to = self.safe_string(conversion, 'quoteCcy')
|
7177
|
+
toCode = self.safe_currency_code(to, toCurrency)
|
7178
|
+
return {
|
7179
|
+
'info': conversion,
|
7180
|
+
'timestamp': timestamp,
|
7181
|
+
'datetime': self.iso8601(timestamp),
|
7182
|
+
'id': self.safe_string(conversion, 'clQReqId'),
|
7183
|
+
'fromCurrency': fromCode,
|
7184
|
+
'fromAmount': self.safe_number(conversion, 'baseSz'),
|
7185
|
+
'toCurrency': toCode,
|
7186
|
+
'toAmount': self.safe_number(conversion, 'quoteSz'),
|
7187
|
+
'price': self.safe_number(conversion, 'cnvtPx'),
|
7188
|
+
'fee': None,
|
7189
|
+
}
|
7190
|
+
|
7191
|
+
async def fetch_convert_currencies(self, params={}) -> Currencies:
|
7192
|
+
"""
|
7193
|
+
fetches all available currencies that can be converted
|
7194
|
+
:see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-convert-currencies
|
7195
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7196
|
+
:returns dict: an associative dictionary of currencies
|
7197
|
+
"""
|
7198
|
+
await self.load_markets()
|
7199
|
+
response = await self.privateGetAssetConvertCurrencies(params)
|
7200
|
+
#
|
7201
|
+
# {
|
7202
|
+
# "code": "0",
|
7203
|
+
# "data": [
|
7204
|
+
# {
|
7205
|
+
# "ccy": "BTC",
|
7206
|
+
# "max": "",
|
7207
|
+
# "min": ""
|
7208
|
+
# },
|
7209
|
+
# ],
|
7210
|
+
# "msg": ""
|
7211
|
+
# }
|
7212
|
+
#
|
7213
|
+
result = {}
|
7214
|
+
data = self.safe_list(response, 'data', [])
|
7215
|
+
for i in range(0, len(data)):
|
7216
|
+
entry = data[i]
|
7217
|
+
id = self.safe_string(entry, 'ccy')
|
7218
|
+
code = self.safe_currency_code(id)
|
7219
|
+
result[code] = {
|
7220
|
+
'info': entry,
|
7221
|
+
'id': id,
|
7222
|
+
'code': code,
|
7223
|
+
'networks': None,
|
7224
|
+
'type': None,
|
7225
|
+
'name': None,
|
7226
|
+
'active': None,
|
7227
|
+
'deposit': None,
|
7228
|
+
'withdraw': None,
|
7229
|
+
'fee': None,
|
7230
|
+
'precision': None,
|
7231
|
+
'limits': {
|
7232
|
+
'amount': {
|
7233
|
+
'min': self.safe_number(entry, 'min'),
|
7234
|
+
'max': self.safe_number(entry, 'max'),
|
7235
|
+
},
|
7236
|
+
'withdraw': {
|
7237
|
+
'min': None,
|
7238
|
+
'max': None,
|
7239
|
+
},
|
7240
|
+
'deposit': {
|
7241
|
+
'min': None,
|
7242
|
+
'max': None,
|
7243
|
+
},
|
7244
|
+
},
|
7245
|
+
'created': None,
|
7246
|
+
}
|
7247
|
+
return result
|
7248
|
+
|
7101
7249
|
def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
|
7102
7250
|
if not response:
|
7103
7251
|
return None # fallback to default error handler
|
ccxt/async_support/woo.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.woo import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Account, Balances, Bool, Currencies, Currency, Int, Leverage, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Trade, TradingFees, Transaction, TransferEntry
|
9
|
+
from ccxt.base.types import Account, Balances, Bool, Conversion, Currencies, Currency, Int, Leverage, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Trade, TradingFees, Transaction, TransferEntry
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
12
|
from ccxt.base.errors import ArgumentsRequired
|
@@ -66,6 +66,8 @@ class woo(Exchange, ImplicitAPI):
|
|
66
66
|
'fetchCanceledOrders': False,
|
67
67
|
'fetchClosedOrder': False,
|
68
68
|
'fetchClosedOrders': True,
|
69
|
+
'fetchConvertCurrencies': True,
|
70
|
+
'fetchConvertQuote': True,
|
69
71
|
'fetchCurrencies': True,
|
70
72
|
'fetchDepositAddress': True,
|
71
73
|
'fetchDeposits': True,
|
@@ -2781,6 +2783,138 @@ class woo(Exchange, ImplicitAPI):
|
|
2781
2783
|
'takeProfitPrice': None,
|
2782
2784
|
})
|
2783
2785
|
|
2786
|
+
async def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
|
2787
|
+
"""
|
2788
|
+
fetch a quote for converting from one currency to another
|
2789
|
+
:see: https://docs.woo.org/#get-quote-rfq
|
2790
|
+
:param str fromCode: the currency that you want to sell and convert from
|
2791
|
+
:param str toCode: the currency that you want to buy and convert into
|
2792
|
+
:param float [amount]: how much you want to trade in units of the from currency
|
2793
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2794
|
+
:returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
|
2795
|
+
"""
|
2796
|
+
await self.load_markets()
|
2797
|
+
request = {
|
2798
|
+
'sellToken': fromCode.upper(),
|
2799
|
+
'buyToken': toCode.upper(),
|
2800
|
+
'sellQuantity': self.number_to_string(amount),
|
2801
|
+
}
|
2802
|
+
response = await self.v3PrivateGetConvertRfq(self.extend(request, params))
|
2803
|
+
#
|
2804
|
+
# {
|
2805
|
+
# "success": True,
|
2806
|
+
# "data": {
|
2807
|
+
# "quoteId": 123123123,
|
2808
|
+
# "counterPartyId": "",
|
2809
|
+
# "sellToken": "ETH",
|
2810
|
+
# "sellQuantity": "0.0445",
|
2811
|
+
# "buyToken": "USDT",
|
2812
|
+
# "buyQuantity": "33.45",
|
2813
|
+
# "buyPrice": "6.77",
|
2814
|
+
# "expireTimestamp": 1659084466000,
|
2815
|
+
# "message": 1659084466000
|
2816
|
+
# }
|
2817
|
+
# }
|
2818
|
+
#
|
2819
|
+
data = self.safe_dict(response, 'data', {})
|
2820
|
+
fromCurrencyId = self.safe_string(data, 'sellToken', fromCode)
|
2821
|
+
fromCurrency = self.currency(fromCurrencyId)
|
2822
|
+
toCurrencyId = self.safe_string(data, 'buyToken', toCode)
|
2823
|
+
toCurrency = self.currency(toCurrencyId)
|
2824
|
+
return self.parse_conversion(data, fromCurrency, toCurrency)
|
2825
|
+
|
2826
|
+
def parse_conversion(self, conversion, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
|
2827
|
+
#
|
2828
|
+
# fetchConvertQuote
|
2829
|
+
#
|
2830
|
+
# {
|
2831
|
+
# "quoteId": 123123123,
|
2832
|
+
# "counterPartyId": "",
|
2833
|
+
# "sellToken": "ETH",
|
2834
|
+
# "sellQuantity": "0.0445",
|
2835
|
+
# "buyToken": "USDT",
|
2836
|
+
# "buyQuantity": "33.45",
|
2837
|
+
# "buyPrice": "6.77",
|
2838
|
+
# "expireTimestamp": 1659084466000,
|
2839
|
+
# "message": 1659084466000
|
2840
|
+
# }
|
2841
|
+
#
|
2842
|
+
timestamp = self.safe_integer(conversion, 'expireTimestamp')
|
2843
|
+
fromCoin = self.safe_string(conversion, 'sellToken')
|
2844
|
+
fromCode = self.safe_currency_code(fromCoin, fromCurrency)
|
2845
|
+
to = self.safe_string(conversion, 'buyToken')
|
2846
|
+
toCode = self.safe_currency_code(to, toCurrency)
|
2847
|
+
return {
|
2848
|
+
'info': conversion,
|
2849
|
+
'timestamp': timestamp,
|
2850
|
+
'datetime': self.iso8601(timestamp),
|
2851
|
+
'id': self.safe_string(conversion, 'quoteId'),
|
2852
|
+
'fromCurrency': fromCode,
|
2853
|
+
'fromAmount': self.safe_number(conversion, 'sellQuantity'),
|
2854
|
+
'toCurrency': toCode,
|
2855
|
+
'toAmount': self.safe_number(conversion, 'buyQuantity'),
|
2856
|
+
'price': self.safe_number(conversion, 'buyPrice'),
|
2857
|
+
'fee': None,
|
2858
|
+
}
|
2859
|
+
|
2860
|
+
async def fetch_convert_currencies(self, params={}) -> Currencies:
|
2861
|
+
"""
|
2862
|
+
fetches all available currencies that can be converted
|
2863
|
+
:see: https://docs.woo.org/#get-quote-asset-info
|
2864
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2865
|
+
:returns dict: an associative dictionary of currencies
|
2866
|
+
"""
|
2867
|
+
await self.load_markets()
|
2868
|
+
response = await self.v3PrivateGetConvertAssetInfo(params)
|
2869
|
+
#
|
2870
|
+
# {
|
2871
|
+
# "success": True,
|
2872
|
+
# "rows": [
|
2873
|
+
# {
|
2874
|
+
# "token": "BTC",
|
2875
|
+
# "tick": 0.0001,
|
2876
|
+
# "createdTime": "1575014248.99", # Unix epoch time in seconds
|
2877
|
+
# "updatedTime": "1575014248.99" # Unix epoch time in seconds
|
2878
|
+
# },
|
2879
|
+
# ]
|
2880
|
+
# }
|
2881
|
+
#
|
2882
|
+
result = {}
|
2883
|
+
data = self.safe_list(response, 'rows', [])
|
2884
|
+
for i in range(0, len(data)):
|
2885
|
+
entry = data[i]
|
2886
|
+
id = self.safe_string(entry, 'token')
|
2887
|
+
code = self.safe_currency_code(id)
|
2888
|
+
result[code] = {
|
2889
|
+
'info': entry,
|
2890
|
+
'id': id,
|
2891
|
+
'code': code,
|
2892
|
+
'networks': None,
|
2893
|
+
'type': None,
|
2894
|
+
'name': None,
|
2895
|
+
'active': None,
|
2896
|
+
'deposit': None,
|
2897
|
+
'withdraw': None,
|
2898
|
+
'fee': None,
|
2899
|
+
'precision': self.safe_number(entry, 'tick'),
|
2900
|
+
'limits': {
|
2901
|
+
'amount': {
|
2902
|
+
'min': None,
|
2903
|
+
'max': None,
|
2904
|
+
},
|
2905
|
+
'withdraw': {
|
2906
|
+
'min': None,
|
2907
|
+
'max': None,
|
2908
|
+
},
|
2909
|
+
'deposit': {
|
2910
|
+
'min': None,
|
2911
|
+
'max': None,
|
2912
|
+
},
|
2913
|
+
},
|
2914
|
+
'created': self.safe_timestamp(entry, 'createdTime'),
|
2915
|
+
}
|
2916
|
+
return result
|
2917
|
+
|
2784
2918
|
def default_network_code_for_currency(self, code):
|
2785
2919
|
currencyItem = self.currency(code)
|
2786
2920
|
networks = currencyItem['networks']
|