ccxt 4.3.44__py2.py3-none-any.whl → 4.3.45__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 +3 -1
- ccxt/abstract/bitstamp.py +18 -2
- ccxt/abstract/kucoin.py +14 -0
- ccxt/abstract/kucoinfutures.py +14 -0
- ccxt/abstract/oxfun.py +34 -0
- ccxt/async_support/__init__.py +3 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/bitstamp.py +18 -2
- ccxt/async_support/kucoin.py +27 -1
- ccxt/async_support/luno.py +9 -1
- ccxt/async_support/oxfun.py +2773 -0
- ccxt/async_support/wavesexchange.py +118 -105
- ccxt/async_support/xt.py +1 -1
- ccxt/base/exchange.py +1 -1
- ccxt/bitstamp.py +18 -2
- ccxt/kucoin.py +27 -1
- ccxt/luno.py +9 -1
- ccxt/oxfun.py +2772 -0
- ccxt/pro/__init__.py +3 -1
- ccxt/pro/oxfun.py +950 -0
- ccxt/test/test_async.py +17 -1
- ccxt/test/test_sync.py +17 -1
- ccxt/wavesexchange.py +118 -105
- ccxt/xt.py +1 -1
- {ccxt-4.3.44.dist-info → ccxt-4.3.45.dist-info}/METADATA +8 -8
- {ccxt-4.3.44.dist-info → ccxt-4.3.45.dist-info}/RECORD +28 -24
- {ccxt-4.3.44.dist-info → ccxt-4.3.45.dist-info}/WHEEL +0 -0
- {ccxt-4.3.44.dist-info → ccxt-4.3.45.dist-info}/top_level.txt +0 -0
ccxt/test/test_async.py
CHANGED
@@ -1274,7 +1274,7 @@ class testMainClass(baseMainTestClass):
|
|
1274
1274
|
# -----------------------------------------------------------------------------
|
1275
1275
|
# --- Init of brokerId tests functions-----------------------------------------
|
1276
1276
|
# -----------------------------------------------------------------------------
|
1277
|
-
promises = [self.test_binance(), self.test_okx(), self.test_cryptocom(), self.test_bybit(), self.test_kucoin(), self.test_kucoinfutures(), self.test_bitget(), self.test_mexc(), self.test_htx(), self.test_woo(), self.test_bitmart(), self.test_coinex(), self.test_bingx(), self.test_phemex(), self.test_blofin(), self.test_hyperliquid(), self.test_coinbaseinternational(), self.test_coinbase_advanced(), self.test_woofi_pro(), self.test_xt()]
|
1277
|
+
promises = [self.test_binance(), self.test_okx(), self.test_cryptocom(), self.test_bybit(), self.test_kucoin(), self.test_kucoinfutures(), self.test_bitget(), self.test_mexc(), self.test_htx(), self.test_woo(), self.test_bitmart(), self.test_coinex(), self.test_bingx(), self.test_phemex(), self.test_blofin(), self.test_hyperliquid(), self.test_coinbaseinternational(), self.test_coinbase_advanced(), self.test_woofi_pro(), self.test_oxfun(), self.test_xt()]
|
1278
1278
|
await asyncio.gather(*promises)
|
1279
1279
|
success_message = '[' + self.lang + '][TEST_SUCCESS] brokerId tests passed.'
|
1280
1280
|
dump('[INFO]' + success_message)
|
@@ -1602,6 +1602,22 @@ class testMainClass(baseMainTestClass):
|
|
1602
1602
|
await close(exchange)
|
1603
1603
|
return True
|
1604
1604
|
|
1605
|
+
async def test_oxfun(self):
|
1606
|
+
exchange = self.init_offline_exchange('oxfun')
|
1607
|
+
exchange.secret = 'secretsecretsecretsecretsecretsecretsecrets'
|
1608
|
+
id = 1000
|
1609
|
+
await exchange.load_markets()
|
1610
|
+
request = None
|
1611
|
+
try:
|
1612
|
+
await exchange.create_order('BTC/USD:OX', 'limit', 'buy', 1, 20000)
|
1613
|
+
except Exception as e:
|
1614
|
+
request = json_parse(exchange.last_request_body)
|
1615
|
+
orders = request['orders']
|
1616
|
+
first = orders[0]
|
1617
|
+
broker_id = first['source']
|
1618
|
+
assert broker_id == id, 'oxfun - id: ' + str(id) + ' different from broker_id: ' + str(broker_id)
|
1619
|
+
return True
|
1620
|
+
|
1605
1621
|
async def test_xt(self):
|
1606
1622
|
exchange = self.init_offline_exchange('xt')
|
1607
1623
|
id = 'CCXT'
|
ccxt/test/test_sync.py
CHANGED
@@ -1273,7 +1273,7 @@ class testMainClass(baseMainTestClass):
|
|
1273
1273
|
# -----------------------------------------------------------------------------
|
1274
1274
|
# --- Init of brokerId tests functions-----------------------------------------
|
1275
1275
|
# -----------------------------------------------------------------------------
|
1276
|
-
promises = [self.test_binance(), self.test_okx(), self.test_cryptocom(), self.test_bybit(), self.test_kucoin(), self.test_kucoinfutures(), self.test_bitget(), self.test_mexc(), self.test_htx(), self.test_woo(), self.test_bitmart(), self.test_coinex(), self.test_bingx(), self.test_phemex(), self.test_blofin(), self.test_hyperliquid(), self.test_coinbaseinternational(), self.test_coinbase_advanced(), self.test_woofi_pro(), self.test_xt()]
|
1276
|
+
promises = [self.test_binance(), self.test_okx(), self.test_cryptocom(), self.test_bybit(), self.test_kucoin(), self.test_kucoinfutures(), self.test_bitget(), self.test_mexc(), self.test_htx(), self.test_woo(), self.test_bitmart(), self.test_coinex(), self.test_bingx(), self.test_phemex(), self.test_blofin(), self.test_hyperliquid(), self.test_coinbaseinternational(), self.test_coinbase_advanced(), self.test_woofi_pro(), self.test_oxfun(), self.test_xt()]
|
1277
1277
|
(promises)
|
1278
1278
|
success_message = '[' + self.lang + '][TEST_SUCCESS] brokerId tests passed.'
|
1279
1279
|
dump('[INFO]' + success_message)
|
@@ -1601,6 +1601,22 @@ class testMainClass(baseMainTestClass):
|
|
1601
1601
|
close(exchange)
|
1602
1602
|
return True
|
1603
1603
|
|
1604
|
+
def test_oxfun(self):
|
1605
|
+
exchange = self.init_offline_exchange('oxfun')
|
1606
|
+
exchange.secret = 'secretsecretsecretsecretsecretsecretsecrets'
|
1607
|
+
id = 1000
|
1608
|
+
exchange.load_markets()
|
1609
|
+
request = None
|
1610
|
+
try:
|
1611
|
+
exchange.create_order('BTC/USD:OX', 'limit', 'buy', 1, 20000)
|
1612
|
+
except Exception as e:
|
1613
|
+
request = json_parse(exchange.last_request_body)
|
1614
|
+
orders = request['orders']
|
1615
|
+
first = orders[0]
|
1616
|
+
broker_id = first['source']
|
1617
|
+
assert broker_id == id, 'oxfun - id: ' + str(id) + ' different from broker_id: ' + str(broker_id)
|
1618
|
+
return True
|
1619
|
+
|
1604
1620
|
def test_xt(self):
|
1605
1621
|
exchange = self.init_offline_exchange('xt')
|
1606
1622
|
id = 'CCXT'
|
ccxt/wavesexchange.py
CHANGED
@@ -20,7 +20,7 @@ from ccxt.base.errors import InvalidOrder
|
|
20
20
|
from ccxt.base.errors import OrderNotFound
|
21
21
|
from ccxt.base.errors import DuplicateOrderId
|
22
22
|
from ccxt.base.errors import ExchangeNotAvailable
|
23
|
-
from ccxt.base.decimal_to_precision import
|
23
|
+
from ccxt.base.decimal_to_precision import TICK_SIZE
|
24
24
|
from ccxt.base.precise import Precise
|
25
25
|
|
26
26
|
|
@@ -328,9 +328,9 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
328
328
|
},
|
329
329
|
},
|
330
330
|
'currencies': {
|
331
|
-
'WX': self.safe_currency_structure({'id': 'EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc', 'numericId': None, 'code': 'WX', 'precision': self.
|
331
|
+
'WX': self.safe_currency_structure({'id': 'EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc', 'numericId': None, 'code': 'WX', 'precision': self.parse_number('1e-8')}),
|
332
332
|
},
|
333
|
-
'precisionMode':
|
333
|
+
'precisionMode': TICK_SIZE,
|
334
334
|
'options': {
|
335
335
|
'allowedCandles': 1440,
|
336
336
|
'accessToken': None,
|
@@ -341,7 +341,7 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
341
341
|
'wavesAddress': None,
|
342
342
|
'withdrawFeeUSDN': 7420,
|
343
343
|
'withdrawFeeWAVES': 100000,
|
344
|
-
'wavesPrecision': 8,
|
344
|
+
'wavesPrecision': 1e-8,
|
345
345
|
'messagePrefix': 'W', # W for production, T for testnet
|
346
346
|
'networks': {
|
347
347
|
'ERC20': 'ETH',
|
@@ -389,8 +389,8 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
389
389
|
def get_fees_for_asset(self, symbol: str, side, amount, price, params={}):
|
390
390
|
self.load_markets()
|
391
391
|
market = self.market(symbol)
|
392
|
-
amount = self.
|
393
|
-
price = self.
|
392
|
+
amount = self.to_real_symbol_amount(symbol, amount)
|
393
|
+
price = self.to_real_symbol_price(symbol, price)
|
394
394
|
request = self.extend({
|
395
395
|
'baseId': market['baseId'],
|
396
396
|
'quoteId': market['quoteId'],
|
@@ -421,7 +421,7 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
421
421
|
matcherFee = self.safe_string(mode, 'matcherFee')
|
422
422
|
feeAssetId = self.safe_string(mode, 'feeAssetId')
|
423
423
|
feeAsset = self.safe_currency_code(feeAssetId)
|
424
|
-
adjustedMatcherFee = self.
|
424
|
+
adjustedMatcherFee = self.from_real_currency_amount(feeAsset, matcherFee)
|
425
425
|
amountAsString = self.number_to_string(amount)
|
426
426
|
priceAsString = self.number_to_string(price)
|
427
427
|
feeCost = self.fee_to_precision(symbol, self.parse_number(adjustedMatcherFee))
|
@@ -569,8 +569,8 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
569
569
|
'strike': None,
|
570
570
|
'optionType': None,
|
571
571
|
'precision': {
|
572
|
-
'amount': self.
|
573
|
-
'price': self.
|
572
|
+
'amount': self.parse_number(self.parse_precision(self.safe_string(entry, 'amountAssetDecimals'))),
|
573
|
+
'price': self.parse_number(self.parse_precision(self.safe_string(entry, 'priceAssetDecimals'))),
|
574
574
|
},
|
575
575
|
'limits': {
|
576
576
|
'leverage': {
|
@@ -624,12 +624,11 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
624
624
|
|
625
625
|
def parse_order_book_side(self, bookSide, market=None, limit: Int = None):
|
626
626
|
precision = market['precision']
|
627
|
-
wavesPrecision = self.safe_string(self.options, 'wavesPrecision', '8')
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
pricePrecision = '1e' + Precise.string_sub(wavesPrecision, difference)
|
627
|
+
wavesPrecision = self.safe_string(self.options, 'wavesPrecision', '1e-8')
|
628
|
+
amountPrecisionString = self.safe_string(precision, 'amount')
|
629
|
+
pricePrecisionString = self.safe_string(precision, 'price')
|
630
|
+
difference = Precise.string_div(amountPrecisionString, pricePrecisionString)
|
631
|
+
pricePrecision = Precise.string_div(wavesPrecision, difference)
|
633
632
|
result = []
|
634
633
|
for i in range(0, len(bookSide)):
|
635
634
|
entry = bookSide[i]
|
@@ -638,9 +637,9 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
638
637
|
price = None
|
639
638
|
amount = None
|
640
639
|
if (pricePrecision is not None) and (entryPrice is not None):
|
641
|
-
price = Precise.
|
642
|
-
if (
|
643
|
-
amount = Precise.
|
640
|
+
price = Precise.string_mul(entryPrice, pricePrecision)
|
641
|
+
if (amountPrecisionString is not None) and (entryAmount is not None):
|
642
|
+
amount = Precise.string_mul(entryAmount, amountPrecisionString)
|
644
643
|
if (limit is not None) and (i > limit):
|
645
644
|
break
|
646
645
|
result.append([
|
@@ -1170,50 +1169,35 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
1170
1169
|
return ''
|
1171
1170
|
return currencyId
|
1172
1171
|
|
1173
|
-
def
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
precisionPrice = self.number_to_string(market['precision']['price'])
|
1178
|
-
difference = Precise.string_sub(amount, precisionPrice)
|
1179
|
-
precision = Precise.string_sub(wavesPrecision, difference)
|
1180
|
-
pricePrecision = self.to_precision(price, str(precision))
|
1181
|
-
return self.parse_to_int(float(pricePrecision))
|
1182
|
-
|
1183
|
-
def custom_amount_to_precision(self, symbol, amount):
|
1184
|
-
amountPrecision = self.number_to_string(self.to_precision(amount, self.number_to_string(self.markets[symbol]['precision']['amount'])))
|
1185
|
-
return self.parse_to_int(float(amountPrecision))
|
1172
|
+
def to_real_currency_amount(self, code: str, amount: float, networkCode=None):
|
1173
|
+
currency = self.currency(code)
|
1174
|
+
stringValue = Precise.string_div(self.number_to_string(amount), self.safe_string(currency, 'precision'))
|
1175
|
+
return int(stringValue)
|
1186
1176
|
|
1187
|
-
def
|
1188
|
-
|
1189
|
-
|
1177
|
+
def from_real_currency_amount(self, code: str, amountString: str):
|
1178
|
+
if not (code in self.currencies):
|
1179
|
+
return amountString
|
1180
|
+
currency = self.currency(code)
|
1181
|
+
precisionAmount = self.safe_string(currency, 'precision')
|
1182
|
+
return Precise.string_mul(amountString, precisionAmount)
|
1190
1183
|
|
1191
|
-
def
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
precise.decimals = self.sum(precise.decimals, scale)
|
1196
|
-
precise.reduce()
|
1197
|
-
return str(precise)
|
1184
|
+
def to_real_symbol_price(self, symbol: str, price: float):
|
1185
|
+
market = self.market(symbol)
|
1186
|
+
stringValue = Precise.string_div(self.number_to_string(price), self.safe_string(market['precision'], 'price'))
|
1187
|
+
return int(stringValue)
|
1198
1188
|
|
1199
|
-
def
|
1200
|
-
|
1201
|
-
|
1202
|
-
# precise.decimals should be integer
|
1203
|
-
precise.decimals = self.parse_to_int(Precise.string_sub(self.number_to_string(precise.decimals), self.number_to_string(scale)))
|
1204
|
-
precise.reduce()
|
1205
|
-
stringValue = str(precise)
|
1206
|
-
return stringValue
|
1189
|
+
def from_real_symbol_price(self, symbol: str, priceString: str):
|
1190
|
+
market = self.markets[symbol]
|
1191
|
+
return Precise.string_mul(priceString, self.safe_string(market['precision'], 'price'))
|
1207
1192
|
|
1208
|
-
def
|
1209
|
-
|
1210
|
-
|
1193
|
+
def to_real_symbol_amount(self, symbol: str, amount: float):
|
1194
|
+
market = self.market(symbol)
|
1195
|
+
stringValue = Precise.string_div(self.number_to_string(amount), self.safe_string(market['precision'], 'amount'))
|
1196
|
+
return int(stringValue)
|
1211
1197
|
|
1212
|
-
def
|
1198
|
+
def from_real_symbol_amount(self, symbol: str, amountString: str):
|
1213
1199
|
market = self.markets[symbol]
|
1214
|
-
|
1215
|
-
scale = self.sum(wavesPrecision, market['precision']['price']) - market['precision']['amount']
|
1216
|
-
return self.from_precision(price, scale)
|
1200
|
+
return Precise.string_mul(amountString, market['precision']['amount'])
|
1217
1201
|
|
1218
1202
|
def safe_get_dynamic(self, settings):
|
1219
1203
|
orderFee = self.safe_value(settings, 'orderFee')
|
@@ -1287,26 +1271,26 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
1287
1271
|
raise InvalidOrder(self.id + ' asset fee must be ' + baseFeeAsset + ' or ' + discountFeeAsset)
|
1288
1272
|
matcherFeeAsset = self.safe_currency_code(matcherFeeAssetId)
|
1289
1273
|
rawMatcherFee = baseMatcherFee if (matcherFeeAssetId == baseFeeAssetId) else discountMatcherFee
|
1290
|
-
floatMatcherFee = float(self.
|
1274
|
+
floatMatcherFee = float(self.from_real_currency_amount(matcherFeeAsset, rawMatcherFee))
|
1291
1275
|
if (matcherFeeAsset in balances) and (balances[matcherFeeAsset]['free'] >= floatMatcherFee):
|
1292
1276
|
matcherFee = int(rawMatcherFee)
|
1293
1277
|
else:
|
1294
1278
|
raise InsufficientFunds(self.id + ' not enough funds of the selected asset fee')
|
1279
|
+
floatBaseMatcherFee = self.from_real_currency_amount(baseFeeAsset, baseMatcherFee)
|
1280
|
+
floatDiscountMatcherFee = self.from_real_currency_amount(discountFeeAsset, discountMatcherFee)
|
1295
1281
|
if matcherFeeAssetId is None:
|
1296
1282
|
# try to the pay the fee using the base first then discount asset
|
1297
|
-
|
1298
|
-
if (baseFeeAsset in balances) and (balances[baseFeeAsset]['free'] >= floatBaseMatcherFee):
|
1283
|
+
if (baseFeeAsset in balances) and (balances[baseFeeAsset]['free'] >= float(floatBaseMatcherFee)):
|
1299
1284
|
matcherFeeAssetId = baseFeeAssetId
|
1300
1285
|
matcherFee = int(baseMatcherFee)
|
1301
1286
|
else:
|
1302
|
-
|
1303
|
-
if (discountFeeAsset in balances) and (balances[discountFeeAsset]['free'] >= floatDiscountMatcherFee):
|
1287
|
+
if (discountFeeAsset in balances) and (balances[discountFeeAsset]['free'] >= float(floatDiscountMatcherFee)):
|
1304
1288
|
matcherFeeAssetId = discountFeeAssetId
|
1305
1289
|
matcherFee = int(discountMatcherFee)
|
1306
1290
|
if matcherFeeAssetId is None:
|
1307
|
-
raise InsufficientFunds(self.id + ' not enough funds on none of the eligible asset fees')
|
1308
|
-
amount = self.
|
1309
|
-
price = self.
|
1291
|
+
raise InsufficientFunds(self.id + ' not enough funds on none of the eligible asset fees: ' + baseFeeAsset + ' ' + floatBaseMatcherFee + ' or ' + discountFeeAsset + ' ' + floatDiscountMatcherFee)
|
1292
|
+
amount = self.to_real_symbol_amount(symbol, amount)
|
1293
|
+
price = self.to_real_symbol_price(symbol, price)
|
1310
1294
|
assetPair: dict = {
|
1311
1295
|
'amountAsset': amountAsset,
|
1312
1296
|
'priceAsset': priceAsset,
|
@@ -1344,7 +1328,7 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
1344
1328
|
'c': {
|
1345
1329
|
't': 'sp',
|
1346
1330
|
'v': {
|
1347
|
-
'p': self.
|
1331
|
+
'p': self.to_real_symbol_price(symbol, stopPrice),
|
1348
1332
|
},
|
1349
1333
|
},
|
1350
1334
|
}
|
@@ -1670,23 +1654,23 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
1670
1654
|
elif market is not None:
|
1671
1655
|
symbol = market['symbol']
|
1672
1656
|
amountCurrency = self.safe_currency_code(self.safe_string(assetPair, 'amountAsset', 'WAVES'))
|
1673
|
-
price = self.
|
1674
|
-
amount = self.
|
1675
|
-
filled = self.
|
1676
|
-
average = self.
|
1657
|
+
price = self.from_real_symbol_price(symbol, priceString)
|
1658
|
+
amount = self.from_real_currency_amount(amountCurrency, amountString)
|
1659
|
+
filled = self.from_real_currency_amount(amountCurrency, filledString)
|
1660
|
+
average = self.from_real_symbol_price(symbol, self.safe_string(order, 'avgWeighedPrice'))
|
1677
1661
|
status = self.parse_order_status(self.safe_string(order, 'status'))
|
1678
1662
|
fee = None
|
1679
1663
|
if 'type' in order:
|
1680
|
-
|
1664
|
+
code = self.safe_currency_code(self.safe_string(order, 'feeAsset'))
|
1681
1665
|
fee = {
|
1682
|
-
'currency':
|
1683
|
-
'fee': self.parse_number(self.
|
1666
|
+
'currency': code,
|
1667
|
+
'fee': self.parse_number(self.from_real_currency_amount(code, self.safe_string(order, 'filledFee'))),
|
1684
1668
|
}
|
1685
1669
|
else:
|
1686
|
-
|
1670
|
+
code = self.safe_currency_code(self.safe_string(order, 'matcherFeeAssetId', 'WAVES'))
|
1687
1671
|
fee = {
|
1688
|
-
'currency':
|
1689
|
-
'fee': self.parse_number(self.
|
1672
|
+
'currency': code,
|
1673
|
+
'fee': self.parse_number(self.from_real_currency_amount(code, self.safe_string(order, 'matcherFee'))),
|
1690
1674
|
}
|
1691
1675
|
triggerPrice = None
|
1692
1676
|
attachment = self.safe_string(order, 'attachment')
|
@@ -1801,16 +1785,14 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
1801
1785
|
issueTransaction = self.safe_value(entry, 'issueTransaction')
|
1802
1786
|
currencyId = self.safe_string(entry, 'assetId')
|
1803
1787
|
balance = self.safe_string(entry, 'balance')
|
1804
|
-
|
1805
|
-
|
1806
|
-
nonStandardBalances.append(balance)
|
1807
|
-
continue
|
1808
|
-
decimals = self.safe_integer(issueTransaction, 'decimals')
|
1809
|
-
code = None
|
1810
|
-
if currencyId in self.currencies_by_id:
|
1788
|
+
currencyExists = (currencyId in self.currencies_by_id)
|
1789
|
+
if currencyExists:
|
1811
1790
|
code = self.safe_currency_code(currencyId)
|
1812
1791
|
result[code] = self.account()
|
1813
|
-
result[code]['total'] = self.
|
1792
|
+
result[code]['total'] = self.from_real_currency_amount(code, balance)
|
1793
|
+
elif issueTransaction is None:
|
1794
|
+
assetIds.append(currencyId)
|
1795
|
+
nonStandardBalances.append(balance)
|
1814
1796
|
nonStandardAssets = len(assetIds)
|
1815
1797
|
if nonStandardAssets:
|
1816
1798
|
requestInner: dict = {
|
@@ -1822,11 +1804,11 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
1822
1804
|
entry = data[i]
|
1823
1805
|
balance = nonStandardBalances[i]
|
1824
1806
|
inner = self.safe_value(entry, 'data')
|
1825
|
-
|
1807
|
+
precision = self.parse_precision(self.safe_string(inner, 'precision'))
|
1826
1808
|
ticker = self.safe_string(inner, 'ticker')
|
1827
1809
|
code = self.safe_currency_code(ticker)
|
1828
1810
|
result[code] = self.account()
|
1829
|
-
result[code]['total'] =
|
1811
|
+
result[code]['total'] = Precise.string_mul(balance, precision)
|
1830
1812
|
currentTimestamp = self.milliseconds()
|
1831
1813
|
byteArray = [
|
1832
1814
|
self.base58_to_binary(self.apiKey),
|
@@ -1849,10 +1831,7 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
1849
1831
|
if not (code in result):
|
1850
1832
|
result[code] = self.account()
|
1851
1833
|
amount = self.safe_string(reservedBalance, currencyId)
|
1852
|
-
|
1853
|
-
result[code]['used'] = self.currency_from_precision(code, amount)
|
1854
|
-
else:
|
1855
|
-
result[code]['used'] = amount
|
1834
|
+
result[code]['used'] = self.from_real_currency_amount(code, amount)
|
1856
1835
|
wavesRequest: dict = {
|
1857
1836
|
'address': wavesAddress,
|
1858
1837
|
}
|
@@ -1862,17 +1841,21 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
1862
1841
|
# "confirmations": 0,
|
1863
1842
|
# "balance": 909085978
|
1864
1843
|
# }
|
1865
|
-
result['WAVES'] = self.safe_value(result, 'WAVES',
|
1866
|
-
result['WAVES']['total'] = self.
|
1867
|
-
|
1868
|
-
for i in range(0, len(codes)):
|
1869
|
-
code = codes[i]
|
1870
|
-
if self.safe_value(result[code], 'used') is None:
|
1871
|
-
result[code]['used'] = '0'
|
1844
|
+
result['WAVES'] = self.safe_value(result, 'WAVES', self.account())
|
1845
|
+
result['WAVES']['total'] = self.from_real_currency_amount('WAVES', self.safe_string(wavesTotal, 'balance'))
|
1846
|
+
result = self.set_undefined_balances_to_zero(result)
|
1872
1847
|
result['timestamp'] = timestamp
|
1873
1848
|
result['datetime'] = self.iso8601(timestamp)
|
1874
1849
|
return self.safe_balance(result)
|
1875
1850
|
|
1851
|
+
def set_undefined_balances_to_zero(self, balances, key='used'):
|
1852
|
+
codes = list(balances.keys())
|
1853
|
+
for i in range(0, len(codes)):
|
1854
|
+
code = codes[i]
|
1855
|
+
if self.safe_value(balances[code], 'used') is None:
|
1856
|
+
balances[code][key] = '0'
|
1857
|
+
return balances
|
1858
|
+
|
1876
1859
|
def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
1877
1860
|
"""
|
1878
1861
|
fetch all trades made by the user
|
@@ -2373,7 +2356,7 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
2373
2356
|
feeAssetId = 'WAVES'
|
2374
2357
|
type = 4 # transfer
|
2375
2358
|
version = 2
|
2376
|
-
amountInteger = self.
|
2359
|
+
amountInteger = self.to_real_currency_amount(code, amount)
|
2377
2360
|
currency = self.currency(code)
|
2378
2361
|
timestamp = self.milliseconds()
|
2379
2362
|
byteArray = [
|
@@ -2433,18 +2416,45 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
2433
2416
|
# "amount": 0
|
2434
2417
|
# }
|
2435
2418
|
#
|
2419
|
+
# withdraw new:
|
2420
|
+
# {
|
2421
|
+
# type: "4",
|
2422
|
+
# id: "2xnWTqG9ar7jEDrLxfbVyyspPZ6XZNrrw9ai9sQ81Eya",
|
2423
|
+
# fee: "100000",
|
2424
|
+
# feeAssetId: null,
|
2425
|
+
# timestamp: "1715786263807",
|
2426
|
+
# version: "2",
|
2427
|
+
# sender: "3P81LLX1kk2CSJC9L8C2enxdHB7XvnSGAEE",
|
2428
|
+
# senderPublicKey: "DdmzmXf9mty1FBE8AdVGnrncVLEAzP4gR4nWoTFAJoXz",
|
2429
|
+
# proofs: ["RyoKwdSYv3EqotJCYftfFM9JE2j1ZpDRxKwYfiRhLAFeyNp6VfJUXNDS884XfeCeHeNypNmTCZt5NYR1ekyjCX3",],
|
2430
|
+
# recipient: "3P9tXxu38a8tgewNEKFzourVxeqHd11ppOc",
|
2431
|
+
# assetId: null,
|
2432
|
+
# feeAsset: null,
|
2433
|
+
# amount: "2000000",
|
2434
|
+
# attachment: "",
|
2435
|
+
# }
|
2436
|
+
#
|
2436
2437
|
currency = self.safe_currency(None, currency)
|
2438
|
+
code = currency['code']
|
2439
|
+
typeRaw = self.safe_string(transaction, 'type')
|
2440
|
+
type = 'withdraw' if (typeRaw == '4') else 'deposit'
|
2441
|
+
amount = self.parse_number(self.from_real_currency_amount(code, self.safe_string(transaction, 'amount')))
|
2442
|
+
feeString = self.safe_string(transaction, 'fee')
|
2443
|
+
feeAssetId = self.safe_string(transaction, 'feeAssetId', 'WAVES')
|
2444
|
+
feeCode = self.safe_currency_code(feeAssetId)
|
2445
|
+
feeAmount = self.parse_number(self.from_real_currency_amount(feeCode, feeString))
|
2446
|
+
timestamp = self.safe_integer(transaction, 'timestamp')
|
2437
2447
|
return {
|
2438
|
-
'id':
|
2448
|
+
'id': self.safe_string(transaction, 'id'),
|
2439
2449
|
'txid': None,
|
2440
|
-
'timestamp':
|
2441
|
-
'datetime':
|
2450
|
+
'timestamp': timestamp,
|
2451
|
+
'datetime': self.iso8601(timestamp),
|
2442
2452
|
'network': None,
|
2443
|
-
'addressFrom':
|
2453
|
+
'addressFrom': self.safe_string(transaction, 'sender'),
|
2444
2454
|
'address': None,
|
2445
|
-
'addressTo':
|
2446
|
-
'amount':
|
2447
|
-
'type':
|
2455
|
+
'addressTo': self.safe_string(transaction, 'recipient'),
|
2456
|
+
'amount': amount,
|
2457
|
+
'type': type,
|
2448
2458
|
'currency': currency['code'],
|
2449
2459
|
'status': None,
|
2450
2460
|
'updated': None,
|
@@ -2453,6 +2463,9 @@ class wavesexchange(Exchange, ImplicitAPI):
|
|
2453
2463
|
'tagTo': None,
|
2454
2464
|
'comment': None,
|
2455
2465
|
'internal': None,
|
2456
|
-
'fee':
|
2466
|
+
'fee': {
|
2467
|
+
'currency': feeCode,
|
2468
|
+
'cost': feeAmount,
|
2469
|
+
},
|
2457
2470
|
'info': transaction,
|
2458
2471
|
}
|
ccxt/xt.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ccxt
|
3
|
-
Version: 4.3.
|
3
|
+
Version: 4.3.45
|
4
4
|
Summary: A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges
|
5
5
|
Home-page: https://ccxt.com
|
6
6
|
Author: Igor Kroitor
|
@@ -49,7 +49,7 @@ Requires-Dist: mypy ==1.6.1 ; extra == 'type'
|
|
49
49
|
|
50
50
|
# CCXT – CryptoCurrency eXchange Trading Library
|
51
51
|
|
52
|
-
[](https://travis-ci.com/ccxt/ccxt) [](https://npmjs.com/package/ccxt) [](https://pypi.python.org/pypi/ccxt) [](https://www.npmjs.com/package/ccxt) [](https://discord.gg/ccxt) [](https://travis-ci.com/ccxt/ccxt) [](https://npmjs.com/package/ccxt) [](https://pypi.python.org/pypi/ccxt) [](https://www.npmjs.com/package/ccxt) [](https://discord.gg/ccxt) [](https://github.com/ccxt/ccxt/wiki/Exchange-Markets) [](https://twitter.com/ccxt_official)
|
53
53
|
|
54
54
|
A JavaScript / Python / PHP / C# library for cryptocurrency trading and e-commerce with support for many bitcoin/ether/altcoin exchange markets and merchant APIs.
|
55
55
|
|
@@ -104,11 +104,10 @@ Current feature list:
|
|
104
104
|
| [](https://www.okx.com/join/CCXT2023) | okx | [OKX](https://www.okx.com/join/CCXT2023) | [](https://www.okx.com/docs-v5/en/) | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | [](https://www.okx.com/join/CCXT2023) |
|
105
105
|
| [](https://x.woo.org/register?ref=YWOWC96B) | woo | [WOO X](https://x.woo.org/register?ref=YWOWC96B) | [](https://docs.woo.org/) | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | [](https://x.woo.org/register?ref=YWOWC96B) |
|
106
106
|
| [](https://dex.woo.org/en/trade?ref=CCXT) | woofipro | [WOOFI PRO](https://dex.woo.org/en/trade?ref=CCXT) | [](https://orderly.network/docs/build-on-evm/building-on-evm) | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | [](https://dex.woo.org/en/trade?ref=CCXT) |
|
107
|
-
| [](https://www.xt.com/en/accounts/register?ref=9PTM9VW) | xt | [XT](https://www.xt.com/en/accounts/register?ref=9PTM9VW) | [](https://doc.xt.com/) | [](https://github.com/ccxt/ccxt/wiki/Certification) | | |
|
108
107
|
|
109
108
|
## Supported Cryptocurrency Exchanges
|
110
109
|
|
111
|
-
The CCXT library currently supports the following
|
110
|
+
The CCXT library currently supports the following 100 cryptocurrency exchange markets and trading APIs:
|
112
111
|
|
113
112
|
| logo | id | name | ver | certified | pro |
|
114
113
|
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------|-------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------:|-----------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------|
|
@@ -192,6 +191,7 @@ The CCXT library currently supports the following 99 cryptocurrency exchange mar
|
|
192
191
|
| [](https://www.okcoin.com/account/register?flag=activity&channelId=600001513) | okcoin | [OKCoin](https://www.okcoin.com/account/register?flag=activity&channelId=600001513) | [](https://www.okcoin.com/docs/en/) | | [](https://ccxt.pro) |
|
193
192
|
| [](https://www.okx.com/join/CCXT2023) | okx | [OKX](https://www.okx.com/join/CCXT2023) | [](https://www.okx.com/docs-v5/en/) | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) |
|
194
193
|
| [](https://onetrading.com/) | onetrading | [One Trading](https://onetrading.com/) | [](https://docs.onetrading.com) | | [](https://ccxt.pro) |
|
194
|
+
| [](https://ox.fun/register?shareAccountId=5ZUD4a7G) | oxfun | [Oxfun](https://ox.fun/register?shareAccountId=5ZUD4a7G) | [](https://docs.ox.fun/) | | [](https://ccxt.pro) |
|
195
195
|
| [](https://p2pb2b.com?referral=ee784c53) | p2b | [p2b](https://p2pb2b.com?referral=ee784c53) | [](https://github.com/P2B-team/p2b-api-docs/blob/master/api-doc.md) | | [](https://ccxt.pro) |
|
196
196
|
| [](https://www.paymium.com/page/sign-up?referral=eDAzPoRQFMvaAB8sf-qj) | paymium | [Paymium](https://www.paymium.com/page/sign-up?referral=eDAzPoRQFMvaAB8sf-qj) | [](https://github.com/Paymium/api-documentation) | | |
|
197
197
|
| [](https://phemex.com/register?referralCode=EDNVJ) | phemex | [Phemex](https://phemex.com/register?referralCode=EDNVJ) | [](https://github.com/phemex/phemex-api-docs) | | [](https://ccxt.pro) |
|
@@ -207,7 +207,7 @@ The CCXT library currently supports the following 99 cryptocurrency exchange mar
|
|
207
207
|
| [](https://whitebit.com/referral/d9bdf40e-28f2-4b52-b2f9-cd1415d82963) | whitebit | [WhiteBit](https://whitebit.com/referral/d9bdf40e-28f2-4b52-b2f9-cd1415d82963) | [](https://github.com/whitebit-exchange/api-docs) | | [](https://ccxt.pro) |
|
208
208
|
| [](https://x.woo.org/register?ref=YWOWC96B) | woo | [WOO X](https://x.woo.org/register?ref=YWOWC96B) | [](https://docs.woo.org/) | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) |
|
209
209
|
| [](https://dex.woo.org/en/trade?ref=CCXT) | woofipro | [WOOFI PRO](https://dex.woo.org/en/trade?ref=CCXT) | [](https://orderly.network/docs/build-on-evm/building-on-evm) | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) |
|
210
|
-
| [](https://www.xt.com/en/accounts/register?ref=9PTM9VW) | xt | [XT](https://www.xt.com/en/accounts/register?ref=9PTM9VW) | [](https://doc.xt.com/) |
|
210
|
+
| [](https://www.xt.com/en/accounts/register?ref=9PTM9VW) | xt | [XT](https://www.xt.com/en/accounts/register?ref=9PTM9VW) | [](https://doc.xt.com/) | | |
|
211
211
|
| [](https://www.yobit.net) | yobit | [YoBit](https://www.yobit.net) | [](https://www.yobit.net/en/api/) | | |
|
212
212
|
| [](https://zaif.jp) | zaif | [Zaif](https://zaif.jp) | [](https://techbureau-api-document.readthedocs.io/ja/latest/index.html) | | |
|
213
213
|
| [](https://auth.zondaglobal.com/ref/jHlbB4mIkdS1) | zonda | [Zonda](https://auth.zondaglobal.com/ref/jHlbB4mIkdS1) | [](https://docs.zondacrypto.exchange/) | | |
|
@@ -268,13 +268,13 @@ console.log(version, Object.keys(exchanges));
|
|
268
268
|
|
269
269
|
All-in-one browser bundle (dependencies included), served from a CDN of your choice:
|
270
270
|
|
271
|
-
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.
|
272
|
-
* unpkg: https://unpkg.com/ccxt@4.3.
|
271
|
+
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.45/dist/ccxt.browser.min.js
|
272
|
+
* unpkg: https://unpkg.com/ccxt@4.3.45/dist/ccxt.browser.min.js
|
273
273
|
|
274
274
|
CDNs are not updated in real-time and may have delays. Defaulting to the most recent version without specifying the version number is not recommended. Please, keep in mind that we are not responsible for the correct operation of those CDN servers.
|
275
275
|
|
276
276
|
```HTML
|
277
|
-
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.
|
277
|
+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.45/dist/ccxt.browser.min.js"></script>
|
278
278
|
```
|
279
279
|
|
280
280
|
Creates a global `ccxt` object:
|