ccxt 4.4.78__py2.py3-none-any.whl → 4.4.82__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ccxt/__init__.py +1 -1
- ccxt/abstract/bitmart.py +1 -0
- ccxt/apex.py +21 -31
- ccxt/ascendex.py +23 -6
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/apex.py +21 -31
- ccxt/async_support/ascendex.py +23 -6
- ccxt/async_support/base/exchange.py +5 -1
- ccxt/async_support/bigone.py +17 -14
- ccxt/async_support/binance.py +6 -0
- ccxt/async_support/bingx.py +16 -35
- ccxt/async_support/bitfinex.py +120 -82
- ccxt/async_support/bitget.py +58 -66
- ccxt/async_support/bitmart.py +7 -2
- ccxt/async_support/bitmex.py +8 -1
- ccxt/async_support/bitopro.py +5 -1
- ccxt/async_support/bitrue.py +2 -1
- ccxt/async_support/bitso.py +1 -1
- ccxt/async_support/bitteam.py +2 -0
- ccxt/async_support/bitvavo.py +25 -10
- ccxt/async_support/btcalpha.py +1 -1
- ccxt/async_support/btcmarkets.py +1 -1
- ccxt/async_support/btcturk.py +1 -1
- ccxt/async_support/bybit.py +29 -15
- ccxt/async_support/coinbase.py +3 -15
- ccxt/async_support/coinex.py +1 -0
- ccxt/async_support/coinlist.py +1 -0
- ccxt/async_support/coinone.py +1 -0
- ccxt/async_support/delta.py +3 -0
- ccxt/async_support/deribit.py +1 -0
- ccxt/async_support/hollaex.py +1 -0
- ccxt/async_support/htx.py +9 -5
- ccxt/async_support/huobijp.py +1 -0
- ccxt/async_support/hyperliquid.py +14 -0
- ccxt/async_support/kraken.py +2 -0
- ccxt/async_support/okx.py +2 -3
- ccxt/async_support/oxfun.py +21 -1
- ccxt/async_support/poloniex.py +1 -0
- ccxt/async_support/timex.py +2 -2
- ccxt/async_support/upbit.py +43 -21
- ccxt/async_support/whitebit.py +65 -12
- ccxt/base/exchange.py +20 -2
- ccxt/bigone.py +17 -14
- ccxt/binance.py +6 -0
- ccxt/bingx.py +16 -35
- ccxt/bitfinex.py +120 -82
- ccxt/bitget.py +58 -66
- ccxt/bitmart.py +7 -2
- ccxt/bitmex.py +8 -1
- ccxt/bitopro.py +5 -1
- ccxt/bitrue.py +2 -1
- ccxt/bitso.py +1 -1
- ccxt/bitteam.py +2 -0
- ccxt/bitvavo.py +25 -10
- ccxt/btcalpha.py +1 -1
- ccxt/btcmarkets.py +1 -1
- ccxt/btcturk.py +1 -1
- ccxt/bybit.py +29 -15
- ccxt/coinbase.py +3 -15
- ccxt/coinex.py +1 -0
- ccxt/coinlist.py +1 -0
- ccxt/coinone.py +1 -0
- ccxt/delta.py +3 -0
- ccxt/deribit.py +1 -0
- ccxt/hollaex.py +1 -0
- ccxt/htx.py +9 -5
- ccxt/huobijp.py +1 -0
- ccxt/hyperliquid.py +14 -0
- ccxt/kraken.py +2 -0
- ccxt/okx.py +2 -3
- ccxt/oxfun.py +21 -1
- ccxt/poloniex.py +1 -0
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +3 -3
- ccxt/pro/coinbase.py +41 -53
- ccxt/pro/hyperliquid.py +10 -2
- ccxt/pro/upbit.py +42 -0
- ccxt/test/tests_async.py +0 -1
- ccxt/test/tests_sync.py +0 -1
- ccxt/timex.py +2 -2
- ccxt/upbit.py +43 -21
- ccxt/whitebit.py +65 -12
- {ccxt-4.4.78.dist-info → ccxt-4.4.82.dist-info}/METADATA +9 -13
- {ccxt-4.4.78.dist-info → ccxt-4.4.82.dist-info}/RECORD +87 -87
- {ccxt-4.4.78.dist-info → ccxt-4.4.82.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.78.dist-info → ccxt-4.4.82.dist-info}/WHEEL +0 -0
- {ccxt-4.4.78.dist-info → ccxt-4.4.82.dist-info}/top_level.txt +0 -0
ccxt/bitso.py
CHANGED
@@ -742,7 +742,7 @@ class bitso(Exchange, ImplicitAPI):
|
|
742
742
|
# {
|
743
743
|
# "bucket_start_time":1648219140000,
|
744
744
|
# "first_trade_time":1648219154990,
|
745
|
-
# "last_trade_time":
|
745
|
+
# "last_trade_time":1648219189442,
|
746
746
|
# "first_rate":"44958.60",
|
747
747
|
# "last_rate":"44979.88",
|
748
748
|
# "min_rate":"44957.33",
|
ccxt/bitteam.py
CHANGED
@@ -650,6 +650,7 @@ class bitteam(Exchange, ImplicitAPI):
|
|
650
650
|
networkIds = list(feesByNetworkId.keys())
|
651
651
|
networks: dict = {}
|
652
652
|
networkPrecision = self.parse_number(self.parse_precision(self.safe_string(currency, 'decimals')))
|
653
|
+
typeRaw = self.safe_string(currency, 'type')
|
653
654
|
for j in range(0, len(networkIds)):
|
654
655
|
networkId = networkIds[j]
|
655
656
|
networkCode = self.network_id_to_code(networkId, code)
|
@@ -703,6 +704,7 @@ class bitteam(Exchange, ImplicitAPI):
|
|
703
704
|
'max': None,
|
704
705
|
},
|
705
706
|
},
|
707
|
+
'type': typeRaw, # 'crypto' or 'fiat'
|
706
708
|
'networks': networks,
|
707
709
|
}
|
708
710
|
return result
|
ccxt/bitvavo.py
CHANGED
@@ -361,6 +361,8 @@ class bitvavo(Exchange, ImplicitAPI):
|
|
361
361
|
'ERC20': 'ETH',
|
362
362
|
'TRC20': 'TRX',
|
363
363
|
},
|
364
|
+
'operatorId': None, # self will be required soon for order-related endpoints
|
365
|
+
'fiatCurrencies': ['EUR'], # only fiat atm
|
364
366
|
},
|
365
367
|
'precisionMode': SIGNIFICANT_DIGITS,
|
366
368
|
'commonCurrencies': {
|
@@ -567,24 +569,24 @@ class bitvavo(Exchange, ImplicitAPI):
|
|
567
569
|
# },
|
568
570
|
# ]
|
569
571
|
#
|
572
|
+
fiatCurrencies = self.safe_list(self.options, 'fiatCurrencies', [])
|
570
573
|
result: dict = {}
|
571
574
|
for i in range(0, len(currencies)):
|
572
575
|
currency = currencies[i]
|
573
576
|
id = self.safe_string(currency, 'symbol')
|
574
577
|
code = self.safe_currency_code(id)
|
578
|
+
isFiat = self.in_array(code, fiatCurrencies)
|
575
579
|
networks: dict = {}
|
576
|
-
networksArray = self.
|
577
|
-
|
578
|
-
|
579
|
-
deposit = (self.safe_value(currency, 'depositStatus') == 'OK')
|
580
|
-
withdrawal = (self.safe_value(currency, 'withdrawalStatus') == 'OK')
|
580
|
+
networksArray = self.safe_list(currency, 'networks', [])
|
581
|
+
deposit = self.safe_string(currency, 'depositStatus') == 'OK'
|
582
|
+
withdrawal = self.safe_string(currency, 'withdrawalStatus') == 'OK'
|
581
583
|
active = deposit and withdrawal
|
582
584
|
withdrawFee = self.safe_number(currency, 'withdrawalFee')
|
583
585
|
precision = self.safe_integer(currency, 'decimals', 8)
|
584
586
|
minWithdraw = self.safe_number(currency, 'withdrawalMinAmount')
|
585
|
-
# absolutely all of them have 1 network atm
|
586
|
-
|
587
|
-
networkId = networksArray[
|
587
|
+
# btw, absolutely all of them have 1 network atm
|
588
|
+
for j in range(0, len(networksArray)):
|
589
|
+
networkId = networksArray[j]
|
588
590
|
networkCode = self.network_id_to_code(networkId)
|
589
591
|
networks[networkCode] = {
|
590
592
|
'info': currency,
|
@@ -602,7 +604,7 @@ class bitvavo(Exchange, ImplicitAPI):
|
|
602
604
|
},
|
603
605
|
},
|
604
606
|
}
|
605
|
-
result[code] = {
|
607
|
+
result[code] = self.safe_currency_structure({
|
606
608
|
'info': currency,
|
607
609
|
'id': id,
|
608
610
|
'code': code,
|
@@ -613,6 +615,7 @@ class bitvavo(Exchange, ImplicitAPI):
|
|
613
615
|
'networks': networks,
|
614
616
|
'fee': withdrawFee,
|
615
617
|
'precision': precision,
|
618
|
+
'type': 'fiat' if isFiat else 'crypto',
|
616
619
|
'limits': {
|
617
620
|
'amount': {
|
618
621
|
'min': None,
|
@@ -627,7 +630,7 @@ class bitvavo(Exchange, ImplicitAPI):
|
|
627
630
|
'max': None,
|
628
631
|
},
|
629
632
|
},
|
630
|
-
}
|
633
|
+
})
|
631
634
|
# set currencies here to avoid calling publicGetAssets twice
|
632
635
|
self.currencies = self.deep_extend(self.currencies, result)
|
633
636
|
return result
|
@@ -1166,6 +1169,10 @@ class bitvavo(Exchange, ImplicitAPI):
|
|
1166
1169
|
request['timeInForce'] = timeInForce
|
1167
1170
|
if postOnly:
|
1168
1171
|
request['postOnly'] = True
|
1172
|
+
operatorId = None
|
1173
|
+
operatorId, params = self.handle_option_and_params(params, 'createOrder', 'operatorId')
|
1174
|
+
if operatorId is not None:
|
1175
|
+
request['operatorId'] = self.parse_to_int(operatorId)
|
1169
1176
|
return self.extend(request, params)
|
1170
1177
|
|
1171
1178
|
def create_order(self, symbol: Str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
@@ -1259,6 +1266,10 @@ class bitvavo(Exchange, ImplicitAPI):
|
|
1259
1266
|
clientOrderId = self.safe_string(params, 'clientOrderId')
|
1260
1267
|
if clientOrderId is None:
|
1261
1268
|
request['orderId'] = id
|
1269
|
+
operatorId = None
|
1270
|
+
operatorId, params = self.handle_option_and_params(params, 'editOrder', 'operatorId')
|
1271
|
+
if operatorId is not None:
|
1272
|
+
request['operatorId'] = self.parse_to_int(operatorId)
|
1262
1273
|
request['market'] = market['id']
|
1263
1274
|
return request
|
1264
1275
|
|
@@ -1293,6 +1304,10 @@ class bitvavo(Exchange, ImplicitAPI):
|
|
1293
1304
|
clientOrderId = self.safe_string(params, 'clientOrderId')
|
1294
1305
|
if clientOrderId is None:
|
1295
1306
|
request['orderId'] = id
|
1307
|
+
operatorId = None
|
1308
|
+
operatorId, params = self.handle_option_and_params(params, 'cancelOrder', 'operatorId')
|
1309
|
+
if operatorId is not None:
|
1310
|
+
request['operatorId'] = self.parse_to_int(operatorId)
|
1296
1311
|
return self.extend(request, params)
|
1297
1312
|
|
1298
1313
|
def cancel_order(self, id: str, symbol: Str = None, params={}):
|
ccxt/btcalpha.py
CHANGED
ccxt/btcmarkets.py
CHANGED
@@ -455,7 +455,7 @@ class btcmarkets(Exchange, ImplicitAPI):
|
|
455
455
|
# "marketId":"COMP-AUD",
|
456
456
|
# "baseAssetName":"COMP",
|
457
457
|
# "quoteAssetName":"AUD",
|
458
|
-
# "minOrderAmount":"0.
|
458
|
+
# "minOrderAmount":"0.00006",
|
459
459
|
# "maxOrderAmount":"1000000",
|
460
460
|
# "amountDecimals":"8",
|
461
461
|
# "priceDecimals":"2",
|
ccxt/btcturk.py
CHANGED
@@ -248,7 +248,7 @@ class btcturk(Exchange, ImplicitAPI):
|
|
248
248
|
# "minPrice": "0.0000000000001",
|
249
249
|
# "maxPrice": "10000000",
|
250
250
|
# "tickSize": "10",
|
251
|
-
# "minExchangeValue": "99.
|
251
|
+
# "minExchangeValue": "99.92",
|
252
252
|
# "minAmount": null,
|
253
253
|
# "maxAmount": null
|
254
254
|
# }
|
ccxt/bybit.py
CHANGED
@@ -1040,9 +1040,6 @@ class bybit(Exchange, ImplicitAPI):
|
|
1040
1040
|
'usePrivateInstrumentsInfo': False,
|
1041
1041
|
'enableDemoTrading': False,
|
1042
1042
|
'fetchMarkets': ['spot', 'linear', 'inverse', 'option'],
|
1043
|
-
'createOrder': {
|
1044
|
-
'method': 'privatePostV5OrderCreate', # 'privatePostV5PositionTradingStop'
|
1045
|
-
},
|
1046
1043
|
'enableUnifiedMargin': None,
|
1047
1044
|
'enableUnifiedAccount': None,
|
1048
1045
|
'unifiedMarginStatus': None,
|
@@ -1707,6 +1704,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
1707
1704
|
},
|
1708
1705
|
},
|
1709
1706
|
'networks': networks,
|
1707
|
+
'type': 'crypto', # atm exchange api provides only cryptos
|
1710
1708
|
}
|
1711
1709
|
return result
|
1712
1710
|
|
@@ -2130,6 +2128,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
2130
2128
|
strike = self.safe_string(splitId, 2)
|
2131
2129
|
optionLetter = self.safe_string(splitId, 3)
|
2132
2130
|
isActive = (status == 'Trading')
|
2131
|
+
isInverse = base == settle
|
2133
2132
|
if isActive or (self.options['loadAllOptions']) or (self.options['loadExpiredOptions']):
|
2134
2133
|
result.append(self.safe_market_structure({
|
2135
2134
|
'id': id,
|
@@ -2141,7 +2140,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
2141
2140
|
'quoteId': quoteId,
|
2142
2141
|
'settleId': settleId,
|
2143
2142
|
'type': 'option',
|
2144
|
-
'subType':
|
2143
|
+
'subType': None,
|
2145
2144
|
'spot': False,
|
2146
2145
|
'margin': False,
|
2147
2146
|
'swap': False,
|
@@ -2149,8 +2148,8 @@ class bybit(Exchange, ImplicitAPI):
|
|
2149
2148
|
'option': True,
|
2150
2149
|
'active': isActive,
|
2151
2150
|
'contract': True,
|
2152
|
-
'linear':
|
2153
|
-
'inverse':
|
2151
|
+
'linear': not isInverse,
|
2152
|
+
'inverse': isInverse,
|
2154
2153
|
'taker': self.safe_number(market, 'takerFee', self.parse_number('0.0006')),
|
2155
2154
|
'maker': self.safe_number(market, 'makerFee', self.parse_number('0.0001')),
|
2156
2155
|
'contractSize': self.parse_number('1'),
|
@@ -3774,12 +3773,21 @@ class bybit(Exchange, ImplicitAPI):
|
|
3774
3773
|
parts = self.is_unified_enabled()
|
3775
3774
|
enableUnifiedAccount = parts[1]
|
3776
3775
|
trailingAmount = self.safe_string_2(params, 'trailingAmount', 'trailingStop')
|
3776
|
+
stopLossPrice = self.safe_string(params, 'stopLossPrice')
|
3777
|
+
takeProfitPrice = self.safe_string(params, 'takeProfitPrice')
|
3777
3778
|
isTrailingAmountOrder = trailingAmount is not None
|
3779
|
+
isStopLoss = stopLossPrice is not None
|
3780
|
+
isTakeProfit = takeProfitPrice is not None
|
3778
3781
|
orderRequest = self.create_order_request(symbol, type, side, amount, price, params, enableUnifiedAccount)
|
3779
|
-
|
3780
|
-
|
3782
|
+
defaultMethod = None
|
3783
|
+
if isTrailingAmountOrder or isStopLoss or isTakeProfit:
|
3784
|
+
defaultMethod = 'privatePostV5PositionTradingStop'
|
3785
|
+
else:
|
3786
|
+
defaultMethod = 'privatePostV5OrderCreate'
|
3787
|
+
method = None
|
3788
|
+
method, params = self.handle_option_and_params(params, 'createOrder', 'method', defaultMethod)
|
3781
3789
|
response = None
|
3782
|
-
if
|
3790
|
+
if method == 'privatePostV5PositionTradingStop':
|
3783
3791
|
response = self.privatePostV5PositionTradingStop(orderRequest)
|
3784
3792
|
else:
|
3785
3793
|
response = self.privatePostV5OrderCreate(orderRequest) # already extended inside createOrderRequest
|
@@ -3804,8 +3812,6 @@ class bybit(Exchange, ImplicitAPI):
|
|
3804
3812
|
lowerCaseType = type.lower()
|
3805
3813
|
if (price is None) and (lowerCaseType == 'limit'):
|
3806
3814
|
raise ArgumentsRequired(self.id + ' createOrder requires a price argument for limit orders')
|
3807
|
-
defaultMethod = None
|
3808
|
-
defaultMethod, params = self.handle_option_and_params(params, 'createOrder', 'method', 'privatePostV5OrderCreate')
|
3809
3815
|
request: dict = {
|
3810
3816
|
'symbol': market['id'],
|
3811
3817
|
# 'side': self.capitalize(side),
|
@@ -3849,7 +3855,14 @@ class bybit(Exchange, ImplicitAPI):
|
|
3849
3855
|
isMarket = lowerCaseType == 'market'
|
3850
3856
|
isLimit = lowerCaseType == 'limit'
|
3851
3857
|
isBuy = side == 'buy'
|
3852
|
-
|
3858
|
+
defaultMethod = None
|
3859
|
+
if isTrailingAmountOrder or isStopLossTriggerOrder or isTakeProfitTriggerOrder:
|
3860
|
+
defaultMethod = 'privatePostV5PositionTradingStop'
|
3861
|
+
else:
|
3862
|
+
defaultMethod = 'privatePostV5OrderCreate'
|
3863
|
+
method = None
|
3864
|
+
method, params = self.handle_option_and_params(params, 'createOrder', 'method', defaultMethod)
|
3865
|
+
isAlternativeEndpoint = method == 'privatePostV5PositionTradingStop'
|
3853
3866
|
amountString = self.get_amount(symbol, amount)
|
3854
3867
|
priceString = self.get_price(symbol, self.number_to_string(price)) if (price is not None) else None
|
3855
3868
|
if isTrailingAmountOrder or isAlternativeEndpoint:
|
@@ -3900,12 +3913,12 @@ class bybit(Exchange, ImplicitAPI):
|
|
3900
3913
|
request['price'] = priceString
|
3901
3914
|
if market['spot']:
|
3902
3915
|
request['category'] = 'spot'
|
3916
|
+
elif market['option']:
|
3917
|
+
request['category'] = 'option'
|
3903
3918
|
elif market['linear']:
|
3904
3919
|
request['category'] = 'linear'
|
3905
3920
|
elif market['inverse']:
|
3906
3921
|
request['category'] = 'inverse'
|
3907
|
-
elif market['option']:
|
3908
|
-
request['category'] = 'option'
|
3909
3922
|
cost = self.safe_string(params, 'cost')
|
3910
3923
|
params = self.omit(params, 'cost')
|
3911
3924
|
# if the cost is inferable, let's keep the old logic and ignore marketUnit, to minimize the impact of the changes
|
@@ -5650,7 +5663,8 @@ classic accounts only/ spot not supported* fetches information on an order made
|
|
5650
5663
|
subType, params = self.handle_sub_type_and_params('fetchLedger', None, params)
|
5651
5664
|
response = None
|
5652
5665
|
if enableUnified[1]:
|
5653
|
-
|
5666
|
+
unifiedMarginStatus = self.safe_integer(self.options, 'unifiedMarginStatus', 5) # 3/4 uta 1.0, 5/6 uta 2.0
|
5667
|
+
if subType == 'inverse' and (unifiedMarginStatus < 5):
|
5654
5668
|
response = self.privateGetV5AccountContractTransactionLog(self.extend(request, params))
|
5655
5669
|
else:
|
5656
5670
|
response = self.privateGetV5AccountTransactionLog(self.extend(request, params))
|
ccxt/coinbase.py
CHANGED
@@ -386,7 +386,6 @@ class coinbase(Exchange, ImplicitAPI):
|
|
386
386
|
'fetchBalance': 'v2PrivateGetAccounts', # 'v2PrivateGetAccounts' or 'v3PrivateGetBrokerageAccounts'
|
387
387
|
'fetchTime': 'v2PublicGetTime', # 'v2PublicGetTime' or 'v3PublicGetBrokerageTime'
|
388
388
|
'user_native_currency': 'USD', # needed to get fees for v3
|
389
|
-
'aliasCbMarketIds': {},
|
390
389
|
},
|
391
390
|
'features': {
|
392
391
|
'default': {
|
@@ -1474,8 +1473,6 @@ class coinbase(Exchange, ImplicitAPI):
|
|
1474
1473
|
perpetualData = self.safe_list(perpetualFutures, 'products', [])
|
1475
1474
|
for i in range(0, len(perpetualData)):
|
1476
1475
|
result.append(self.parse_contract_market(perpetualData[i], perpetualFeeTier))
|
1477
|
-
# remove aliases
|
1478
|
-
self.options['aliasCbMarketIds'] = {}
|
1479
1476
|
newMarkets = []
|
1480
1477
|
for i in range(0, len(result)):
|
1481
1478
|
market = result[i]
|
@@ -1483,21 +1480,12 @@ class coinbase(Exchange, ImplicitAPI):
|
|
1483
1480
|
realMarketIds = self.safe_list(info, 'alias_to', [])
|
1484
1481
|
length = len(realMarketIds)
|
1485
1482
|
if length > 0:
|
1486
|
-
|
1487
|
-
self.options['aliasCbMarketIds'][market['symbol']] = realMarketIds[0]
|
1483
|
+
market['alias'] = realMarketIds[0]
|
1488
1484
|
else:
|
1489
|
-
|
1485
|
+
market['alias'] = None
|
1486
|
+
newMarkets.append(market)
|
1490
1487
|
return newMarkets
|
1491
1488
|
|
1492
|
-
def market(self, symbol: str) -> MarketInterface:
|
1493
|
-
finalSymbol = self.safe_string(self.options['aliasCbMarketIds'], symbol, symbol)
|
1494
|
-
return super(coinbase, self).market(finalSymbol)
|
1495
|
-
|
1496
|
-
def safe_market(self, marketId: Str = None, market: Market = None, delimiter: Str = None, marketType: Str = None) -> MarketInterface:
|
1497
|
-
if marketId in self.options['aliasCbMarketIds']:
|
1498
|
-
return self.market(marketId)
|
1499
|
-
return super(coinbase, self).safe_market(marketId, market, delimiter, marketType)
|
1500
|
-
|
1501
1489
|
def parse_spot_market(self, market, feeTier) -> MarketInterface:
|
1502
1490
|
#
|
1503
1491
|
# {
|
ccxt/coinex.py
CHANGED
ccxt/coinlist.py
CHANGED
ccxt/coinone.py
CHANGED
ccxt/delta.py
CHANGED
@@ -357,6 +357,8 @@ class delta(Exchange, ImplicitAPI):
|
|
357
357
|
base = self.safe_string(optionParts, 1)
|
358
358
|
expiry = self.safe_string(optionParts, 3)
|
359
359
|
optionType = self.safe_string(optionParts, 0)
|
360
|
+
if expiry is not None:
|
361
|
+
expiry = expiry[4:] + expiry[2:4] + expiry[0:2]
|
360
362
|
settle = quote
|
361
363
|
strike = self.safe_string(optionParts, 2)
|
362
364
|
datetime = self.convert_expire_date(expiry)
|
@@ -567,6 +569,7 @@ class delta(Exchange, ImplicitAPI):
|
|
567
569
|
},
|
568
570
|
},
|
569
571
|
'networks': {},
|
572
|
+
'type': 'crypto',
|
570
573
|
}
|
571
574
|
return result
|
572
575
|
|
ccxt/deribit.py
CHANGED
@@ -655,6 +655,7 @@ class deribit(Exchange, ImplicitAPI):
|
|
655
655
|
'active': None,
|
656
656
|
'deposit': None,
|
657
657
|
'withdraw': None,
|
658
|
+
'type': 'crypto',
|
658
659
|
'fee': self.safe_number(currency, 'withdrawal_fee'),
|
659
660
|
'precision': self.parse_number(self.parse_precision(self.safe_string(currency, 'fee_precision'))),
|
660
661
|
'limits': {
|
ccxt/hollaex.py
CHANGED
ccxt/htx.py
CHANGED
@@ -962,6 +962,7 @@ class htx(Exchange, ImplicitAPI):
|
|
962
962
|
},
|
963
963
|
'precisionMode': TICK_SIZE,
|
964
964
|
'options': {
|
965
|
+
'include_OS_certificates': False, # temporarily leave self, remove in future
|
965
966
|
'fetchMarkets': {
|
966
967
|
'types': {
|
967
968
|
'spot': True,
|
@@ -2172,14 +2173,14 @@ class htx(Exchange, ImplicitAPI):
|
|
2172
2173
|
ask = None
|
2173
2174
|
askVolume = None
|
2174
2175
|
if 'bid' in ticker:
|
2175
|
-
if isinstance(ticker['bid'], list):
|
2176
|
+
if ticker['bid'] is not None and isinstance(ticker['bid'], list):
|
2176
2177
|
bid = self.safe_string(ticker['bid'], 0)
|
2177
2178
|
bidVolume = self.safe_string(ticker['bid'], 1)
|
2178
2179
|
else:
|
2179
2180
|
bid = self.safe_string(ticker, 'bid')
|
2180
2181
|
bidVolume = self.safe_string(ticker, 'bidSize')
|
2181
2182
|
if 'ask' in ticker:
|
2182
|
-
if isinstance(ticker['ask'], list):
|
2183
|
+
if ticker['ask'] is not None and isinstance(ticker['ask'], list):
|
2183
2184
|
ask = self.safe_string(ticker['ask'], 0)
|
2184
2185
|
askVolume = self.safe_string(ticker['ask'], 1)
|
2185
2186
|
else:
|
@@ -3270,7 +3271,7 @@ class htx(Exchange, ImplicitAPI):
|
|
3270
3271
|
# "withdrawQuotaPerYear": null,
|
3271
3272
|
# "withdrawQuotaTotal": null,
|
3272
3273
|
# "withdrawFeeType": "fixed",
|
3273
|
-
# "transactFeeWithdraw": "11.
|
3274
|
+
# "transactFeeWithdraw": "11.1654",
|
3274
3275
|
# "addrWithTag": False,
|
3275
3276
|
# "addrDepositTag": False
|
3276
3277
|
# }
|
@@ -3293,6 +3294,8 @@ class htx(Exchange, ImplicitAPI):
|
|
3293
3294
|
chains = self.safe_value(entry, 'chains', [])
|
3294
3295
|
networks: dict = {}
|
3295
3296
|
instStatus = self.safe_string(entry, 'instStatus')
|
3297
|
+
assetType = self.safe_string(entry, 'assetType')
|
3298
|
+
type = assetType == 'crypto' if '1' else 'fiat'
|
3296
3299
|
currencyActive = instStatus == 'normal'
|
3297
3300
|
minPrecision = None
|
3298
3301
|
minDeposit = None
|
@@ -3350,6 +3353,7 @@ class htx(Exchange, ImplicitAPI):
|
|
3350
3353
|
'withdraw': withdraw,
|
3351
3354
|
'fee': None,
|
3352
3355
|
'name': None,
|
3356
|
+
'type': type,
|
3353
3357
|
'limits': {
|
3354
3358
|
'amount': {
|
3355
3359
|
'min': None,
|
@@ -6941,7 +6945,7 @@ class htx(Exchange, ImplicitAPI):
|
|
6941
6945
|
if method != 'POST':
|
6942
6946
|
request = self.extend(request, query)
|
6943
6947
|
sortedRequest = self.keysort(request)
|
6944
|
-
auth = self.urlencode(sortedRequest)
|
6948
|
+
auth = self.urlencode(sortedRequest, True) # True is a go only requirment
|
6945
6949
|
# unfortunately, PHP demands double quotes for the escaped newline symbol
|
6946
6950
|
payload = "\n".join([method, self.hostname, url, auth]) # eslint-disable-line quotes
|
6947
6951
|
signature = self.hmac(self.encode(payload), self.encode(self.secret), hashlib.sha256, 'base64')
|
@@ -7007,7 +7011,7 @@ class htx(Exchange, ImplicitAPI):
|
|
7007
7011
|
if method != 'POST':
|
7008
7012
|
sortedQuery = self.keysort(query)
|
7009
7013
|
request = self.extend(request, sortedQuery)
|
7010
|
-
auth = self.urlencode(request).replace('%2c', '%2C') # in c# it manually needs to be uppercased
|
7014
|
+
auth = self.urlencode(request, True).replace('%2c', '%2C') # in c# it manually needs to be uppercased
|
7011
7015
|
# unfortunately, PHP demands double quotes for the escaped newline symbol
|
7012
7016
|
payload = "\n".join([method, hostname, url, auth]) # eslint-disable-line quotes
|
7013
7017
|
signature = self.hmac(self.encode(payload), self.encode(self.secret), hashlib.sha256, 'base64')
|
ccxt/huobijp.py
CHANGED
ccxt/hyperliquid.py
CHANGED
@@ -379,6 +379,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
379
379
|
'withdraw': None,
|
380
380
|
'networks': None,
|
381
381
|
'fee': None,
|
382
|
+
'type': 'crypto',
|
382
383
|
'limits': {
|
383
384
|
'amount': {
|
384
385
|
'min': None,
|
@@ -2177,6 +2178,10 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2177
2178
|
return self.parse_order(data, market)
|
2178
2179
|
|
2179
2180
|
def parse_order(self, order: dict, market: Market = None) -> Order:
|
2181
|
+
#
|
2182
|
+
# createOrdersWs error
|
2183
|
+
#
|
2184
|
+
# {error: 'Insufficient margin to place order. asset=159'}
|
2180
2185
|
#
|
2181
2186
|
# fetchOpenOrders
|
2182
2187
|
#
|
@@ -2268,6 +2273,12 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2268
2273
|
# "triggerPx": "0.6"
|
2269
2274
|
# }
|
2270
2275
|
#
|
2276
|
+
error = self.safe_string(order, 'error')
|
2277
|
+
if error is not None:
|
2278
|
+
return self.safe_order({
|
2279
|
+
'info': order,
|
2280
|
+
'status': 'rejected',
|
2281
|
+
})
|
2271
2282
|
entry = self.safe_dict_n(order, ['order', 'resting', 'filled'])
|
2272
2283
|
if entry is None:
|
2273
2284
|
entry = order
|
@@ -3443,9 +3454,12 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
3443
3454
|
# {"status":"ok","response":{"type":"order","data":{"statuses":[{"error":"Insufficient margin to place order. asset=84"}]}}}
|
3444
3455
|
#
|
3445
3456
|
status = self.safe_string(response, 'status', '')
|
3457
|
+
error = self.safe_string(response, 'error')
|
3446
3458
|
message = None
|
3447
3459
|
if status == 'err':
|
3448
3460
|
message = self.safe_string(response, 'response')
|
3461
|
+
elif error is not None:
|
3462
|
+
message = error
|
3449
3463
|
else:
|
3450
3464
|
responsePayload = self.safe_dict(response, 'response', {})
|
3451
3465
|
data = self.safe_dict(responsePayload, 'data', {})
|
ccxt/kraken.py
CHANGED
@@ -864,12 +864,14 @@ class kraken(Exchange, ImplicitAPI):
|
|
864
864
|
precision = self.parse_number(self.parse_precision(self.safe_string(currency, 'decimals')))
|
865
865
|
# assumes all currencies are active except those listed above
|
866
866
|
active = self.safe_string(currency, 'status') == 'enabled'
|
867
|
+
isFiat = code.find('.HOLD') >= 0
|
867
868
|
result[code] = {
|
868
869
|
'id': id,
|
869
870
|
'code': code,
|
870
871
|
'info': currency,
|
871
872
|
'name': self.safe_string(currency, 'altname'),
|
872
873
|
'active': active,
|
874
|
+
'type': 'fiat' if isFiat else 'crypto',
|
873
875
|
'deposit': None,
|
874
876
|
'withdraw': None,
|
875
877
|
'fee': None,
|
ccxt/okx.py
CHANGED
@@ -1647,7 +1647,6 @@ class okx(Exchange, ImplicitAPI):
|
|
1647
1647
|
ymd = self.yymmdd(expiry)
|
1648
1648
|
symbol = symbol + '-' + ymd + '-' + strikePrice + '-' + optionType
|
1649
1649
|
optionType = 'put' if (optionType == 'P') else 'call'
|
1650
|
-
tickSize = self.safe_string(market, 'tickSz')
|
1651
1650
|
fees = self.safe_dict_2(self.fees, type, 'trading', {})
|
1652
1651
|
maxLeverage = self.safe_string(market, 'lever', '1')
|
1653
1652
|
maxLeverage = Precise.string_max(maxLeverage, '1')
|
@@ -1679,7 +1678,7 @@ class okx(Exchange, ImplicitAPI):
|
|
1679
1678
|
'created': self.safe_integer(market, 'listTime'),
|
1680
1679
|
'precision': {
|
1681
1680
|
'amount': self.safe_number(market, 'lotSz'),
|
1682
|
-
'price': self.
|
1681
|
+
'price': self.safe_number(market, 'tickSz'),
|
1683
1682
|
},
|
1684
1683
|
'limits': {
|
1685
1684
|
'leverage': {
|
@@ -4831,7 +4830,7 @@ class okx(Exchange, ImplicitAPI):
|
|
4831
4830
|
:returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
|
4832
4831
|
"""
|
4833
4832
|
self.load_markets()
|
4834
|
-
rawNetwork = self.
|
4833
|
+
rawNetwork = self.safe_string(params, 'network') # some networks are like "Dora Vota Mainnet"
|
4835
4834
|
params = self.omit(params, 'network')
|
4836
4835
|
code = self.safe_currency_code(code)
|
4837
4836
|
network = self.network_id_to_code(rawNetwork, code)
|
ccxt/oxfun.py
CHANGED
@@ -83,7 +83,7 @@ class oxfun(Exchange, ImplicitAPI):
|
|
83
83
|
'fetchDepositWithdrawFee': False,
|
84
84
|
'fetchDepositWithdrawFees': False,
|
85
85
|
'fetchFundingHistory': True,
|
86
|
-
'fetchFundingRate':
|
86
|
+
'fetchFundingRate': True,
|
87
87
|
'fetchFundingRateHistory': True,
|
88
88
|
'fetchFundingRates': True,
|
89
89
|
'fetchIndexOHLCV': False,
|
@@ -1103,6 +1103,26 @@ class oxfun(Exchange, ImplicitAPI):
|
|
1103
1103
|
data = self.safe_list(response, 'data', [])
|
1104
1104
|
return self.parse_funding_rates(data, symbols)
|
1105
1105
|
|
1106
|
+
def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
|
1107
|
+
"""
|
1108
|
+
fetch the current funding rates for a symbol
|
1109
|
+
|
1110
|
+
https://docs.ox.fun/?json#get-v3-funding-estimates
|
1111
|
+
|
1112
|
+
:param str symbol: unified market symbols
|
1113
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1114
|
+
:returns Order[]: an array of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
1115
|
+
"""
|
1116
|
+
self.load_markets()
|
1117
|
+
request: dict = {
|
1118
|
+
'marketCode': self.market_id(symbol),
|
1119
|
+
}
|
1120
|
+
response = self.publicGetV3FundingEstimates(self.extend(request, params))
|
1121
|
+
#
|
1122
|
+
data = self.safe_list(response, 'data', [])
|
1123
|
+
first = self.safe_dict(data, 0, {})
|
1124
|
+
return self.parse_funding_rate(first, self.market(symbol))
|
1125
|
+
|
1106
1126
|
def parse_funding_rate(self, fundingRate, market: Market = None) -> FundingRate:
|
1107
1127
|
#
|
1108
1128
|
# {
|
ccxt/poloniex.py
CHANGED
ccxt/pro/__init__.py
CHANGED
ccxt/pro/binance.py
CHANGED
@@ -71,12 +71,12 @@ class binance(ccxt.async_support.binance):
|
|
71
71
|
'urls': {
|
72
72
|
'test': {
|
73
73
|
'ws': {
|
74
|
-
'spot': 'wss://testnet.binance.vision/ws',
|
75
|
-
'margin': 'wss://testnet.binance.vision/ws',
|
74
|
+
'spot': 'wss://stream.testnet.binance.vision/ws',
|
75
|
+
'margin': 'wss://stream.testnet.binance.vision/ws',
|
76
76
|
'future': 'wss://fstream.binancefuture.com/ws',
|
77
77
|
'delivery': 'wss://dstream.binancefuture.com/ws',
|
78
78
|
'ws-api': {
|
79
|
-
'spot': 'wss://testnet.binance.vision/ws-api/v3',
|
79
|
+
'spot': 'wss://ws-api.testnet.binance.vision/ws-api/v3',
|
80
80
|
'future': 'wss://testnet.binancefuture.com/ws-fapi/v1',
|
81
81
|
'delivery': 'wss://testnet.binancefuture.com/ws-dapi/v1',
|
82
82
|
},
|