ccxt 4.4.10__py2.py3-none-any.whl → 4.4.12__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/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 +1 -1
- ccxt/async_support/binance.py +11 -2
- ccxt/async_support/bingx.py +15 -2
- ccxt/async_support/bitget.py +2 -1
- ccxt/async_support/bybit.py +2 -1
- ccxt/async_support/htx.py +12 -0
- ccxt/async_support/kraken.py +36 -14
- ccxt/async_support/mexc.py +26 -8
- ccxt/async_support/okx.py +17 -20
- ccxt/async_support/phemex.py +10 -3
- ccxt/base/exchange.py +1 -1
- ccxt/binance.py +11 -2
- ccxt/bingx.py +15 -2
- ccxt/bitget.py +2 -1
- ccxt/bybit.py +2 -1
- ccxt/htx.py +12 -0
- ccxt/kraken.py +36 -14
- ccxt/mexc.py +26 -8
- ccxt/okx.py +17 -20
- ccxt/phemex.py +10 -3
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/deribit.py +75 -0
- ccxt/pro/exmo.py +29 -2
- ccxt/pro/okx.py +1 -1
- {ccxt-4.4.10.dist-info → ccxt-4.4.12.dist-info}/METADATA +4 -4
- {ccxt-4.4.10.dist-info → ccxt-4.4.12.dist-info}/RECORD +35 -35
- {ccxt-4.4.10.dist-info → ccxt-4.4.12.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.10.dist-info → ccxt-4.4.12.dist-info}/WHEEL +0 -0
- {ccxt-4.4.10.dist-info → ccxt-4.4.12.dist-info}/top_level.txt +0 -0
ccxt/bingx.py
CHANGED
@@ -2457,6 +2457,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
2457
2457
|
:param dict [params.stopLoss]: *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered
|
2458
2458
|
:param float [params.stopLoss.triggerPrice]: stop loss trigger price
|
2459
2459
|
:param boolean [params.test]: *swap only* whether to use the test endpoint or not, default is False
|
2460
|
+
:param str [params.positionSide]: *contracts only* "BOTH" for one way mode, "LONG" for buy side of hedged mode, "SHORT" for sell side of hedged mode
|
2460
2461
|
:param boolean [params.hedged]: *swap only* whether the order is in hedged mode or one way mode
|
2461
2462
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2462
2463
|
"""
|
@@ -4183,13 +4184,25 @@ class bingx(Exchange, ImplicitAPI):
|
|
4183
4184
|
currencyId = self.safe_string(depositAddress, 'coin')
|
4184
4185
|
currency = self.safe_currency(currencyId, currency)
|
4185
4186
|
code = currency['code']
|
4186
|
-
|
4187
|
+
# the exchange API returns deposit addresses without the leading '0x' prefix
|
4188
|
+
# however, the exchange API does require the 0x prefix to withdraw
|
4189
|
+
# so we append the prefix before returning the address to the user
|
4190
|
+
# that is only if the underlying contract address has the 0x prefix
|
4191
|
+
networkCode = self.safe_string(depositAddress, 'network')
|
4192
|
+
if networkCode is not None:
|
4193
|
+
if networkCode in currency['networks']:
|
4194
|
+
network = currency['networks'][networkCode]
|
4195
|
+
contractAddress = self.safe_string(network['info'], 'contractAddress')
|
4196
|
+
if contractAddress is not None:
|
4197
|
+
if contractAddress[0] == '0' and contractAddress[1] == 'x':
|
4198
|
+
if address[0] != '0' or address[1] != 'x':
|
4199
|
+
address = '0x' + address
|
4187
4200
|
self.check_address(address)
|
4188
4201
|
return {
|
4189
4202
|
'currency': code,
|
4190
4203
|
'address': address,
|
4191
4204
|
'tag': tag,
|
4192
|
-
'network':
|
4205
|
+
'network': networkCode,
|
4193
4206
|
'info': depositAddress,
|
4194
4207
|
}
|
4195
4208
|
|
ccxt/bitget.py
CHANGED
@@ -1434,7 +1434,7 @@ class bitget(Exchange, ImplicitAPI):
|
|
1434
1434
|
},
|
1435
1435
|
'sandboxMode': False,
|
1436
1436
|
'networks': {
|
1437
|
-
'
|
1437
|
+
'TRC20': 'TRC20',
|
1438
1438
|
'ERC20': 'ERC20',
|
1439
1439
|
'BEP20': 'BSC',
|
1440
1440
|
'ARB': 'ArbitrumOne',
|
@@ -3947,6 +3947,7 @@ class bitget(Exchange, ImplicitAPI):
|
|
3947
3947
|
:param str [params.trailingTriggerPrice]: *swap and future only* the price to trigger a trailing stop order, default uses the price argument
|
3948
3948
|
:param str [params.triggerType]: *swap and future only* 'fill_price', 'mark_price' or 'index_price'
|
3949
3949
|
:param boolean [params.oneWayMode]: *swap and future only* required to set self to True in one_way_mode and you can leave self in hedge_mode, can adjust the mode using the setPositionMode() method
|
3950
|
+
:param bool [params.hedged]: *swap and future only* True for hedged mode, False for one way mode, default is False
|
3950
3951
|
:param bool [params.reduceOnly]: True or False whether the order is reduce-only
|
3951
3952
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
3952
3953
|
"""
|
ccxt/bybit.py
CHANGED
@@ -3430,7 +3430,8 @@ class bybit(Exchange, ImplicitAPI):
|
|
3430
3430
|
:param str [params.timeInForce]: "GTC", "IOC", "FOK"
|
3431
3431
|
:param bool [params.postOnly]: True or False whether the order is post-only
|
3432
3432
|
:param bool [params.reduceOnly]: True or False whether the order is reduce-only
|
3433
|
-
:param str [params.positionIdx]: *contracts only*
|
3433
|
+
:param str [params.positionIdx]: *contracts only* 0 for one-way mode, 1 buy side of hedged mode, 2 sell side of hedged mode
|
3434
|
+
:param bool [params.hedged]: *contracts only* True for hedged mode, False for one way mode, default is False
|
3434
3435
|
:param boolean [params.isLeverage]: *unified spot only* False then spot trading True then margin trading
|
3435
3436
|
:param str [params.tpslMode]: *contract only* 'full' or 'partial'
|
3436
3437
|
:param str [params.mmp]: *option only* market maker protection
|
ccxt/htx.py
CHANGED
@@ -1236,6 +1236,7 @@ class htx(Exchange, ImplicitAPI):
|
|
1236
1236
|
# https://github.com/ccxt/ccxt/issues/6081
|
1237
1237
|
# https://github.com/ccxt/ccxt/issues/3365
|
1238
1238
|
# https://github.com/ccxt/ccxt/issues/2873
|
1239
|
+
'NGL': 'GFNGL',
|
1239
1240
|
'GET': 'THEMIS', # conflict with GET(Guaranteed Entrance Token, GET Protocol)
|
1240
1241
|
'GTC': 'GAMECOM', # conflict with Gitcoin and Gastrocoin
|
1241
1242
|
'HIT': 'HITCHAIN',
|
@@ -1247,6 +1248,7 @@ class htx(Exchange, ImplicitAPI):
|
|
1247
1248
|
'SBTC': 'SUPERBITCOIN',
|
1248
1249
|
'SOUL': 'SOULSAVER',
|
1249
1250
|
'BIFI': 'BITCOINFILE', # conflict with Beefy.Finance https://github.com/ccxt/ccxt/issues/8706
|
1251
|
+
'FUD': 'FTX Users\' Debt',
|
1250
1252
|
},
|
1251
1253
|
})
|
1252
1254
|
|
@@ -3479,6 +3481,12 @@ class htx(Exchange, ImplicitAPI):
|
|
3479
3481
|
def fetch_order(self, id: str, symbol: Str = None, params={}):
|
3480
3482
|
"""
|
3481
3483
|
fetches information on an order made by the user
|
3484
|
+
:see: https://huobiapi.github.io/docs/spot/v1/en/#get-the-order-detail-of-an-order-based-on-client-order-id
|
3485
|
+
:see: https://huobiapi.github.io/docs/spot/v1/en/#get-the-order-detail-of-an-order
|
3486
|
+
:see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-information-of-an-order
|
3487
|
+
:see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-information-of-order
|
3488
|
+
:see: https://huobiapi.github.io/docs/dm/v1/en/#get-information-of-an-order
|
3489
|
+
:see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-information-of-an-order
|
3482
3490
|
:param str symbol: unified symbol of the market the order was made in
|
3483
3491
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3484
3492
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
@@ -6853,6 +6861,10 @@ class htx(Exchange, ImplicitAPI):
|
|
6853
6861
|
def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
|
6854
6862
|
"""
|
6855
6863
|
set the level of leverage for a market
|
6864
|
+
:see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-switch-leverage
|
6865
|
+
:see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-switch-leverage
|
6866
|
+
:see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#switch-leverage
|
6867
|
+
:see: https://huobiapi.github.io/docs/dm/v1/en/#switch-leverage # Coin-m futures
|
6856
6868
|
:param float leverage: the rate of leverage
|
6857
6869
|
:param str symbol: unified market symbol
|
6858
6870
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
ccxt/kraken.py
CHANGED
@@ -66,6 +66,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
66
66
|
'createStopMarketOrder': True,
|
67
67
|
'createStopOrder': True,
|
68
68
|
'createTrailingAmountOrder': True,
|
69
|
+
'createTrailingPercentOrder': True,
|
69
70
|
'editOrder': True,
|
70
71
|
'fetchBalance': True,
|
71
72
|
'fetchBorrowInterest': False,
|
@@ -456,7 +457,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
456
457
|
'EGeneral:Internal error': ExchangeNotAvailable,
|
457
458
|
'EGeneral:Temporary lockout': DDoSProtection,
|
458
459
|
'EGeneral:Permission denied': PermissionDenied,
|
460
|
+
'EGeneral:Invalid arguments:price': InvalidOrder,
|
459
461
|
'EOrder:Unknown order': InvalidOrder,
|
462
|
+
'EOrder:Invalid price:Invalid price argument': InvalidOrder,
|
460
463
|
'EOrder:Order minimum not met': InvalidOrder,
|
461
464
|
'EGeneral:Invalid arguments': BadRequest,
|
462
465
|
'ESession:Invalid session': AuthenticationError,
|
@@ -1397,8 +1400,8 @@ class kraken(Exchange, ImplicitAPI):
|
|
1397
1400
|
|
1398
1401
|
def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
1399
1402
|
"""
|
1400
|
-
:see: https://docs.kraken.com/rest/#tag/Spot-Trading/operation/addOrder
|
1401
1403
|
create a trade order
|
1404
|
+
:see: https://docs.kraken.com/api/docs/rest-api/add-order
|
1402
1405
|
:param str symbol: unified symbol of the market to create an order in
|
1403
1406
|
:param str type: 'market' or 'limit'
|
1404
1407
|
:param str side: 'buy' or 'sell'
|
@@ -1410,7 +1413,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
1410
1413
|
:param float [params.stopLossPrice]: *margin only* the price that a stop loss order is triggered at
|
1411
1414
|
:param float [params.takeProfitPrice]: *margin only* the price that a take profit order is triggered at
|
1412
1415
|
:param str [params.trailingAmount]: *margin only* the quote amount to trail away from the current market price
|
1416
|
+
:param str [params.trailingPercent]: *margin only* the percent to trail away from the current market price
|
1413
1417
|
:param str [params.trailingLimitAmount]: *margin only* the quote amount away from the trailingAmount
|
1418
|
+
:param str [params.trailingLimitPercent]: *margin only* the percent away from the trailingAmount
|
1414
1419
|
:param str [params.offset]: *margin only* '+' or '-' whether you want the trailingLimitAmount value to be positive or negative, default is negative '-'
|
1415
1420
|
:param str [params.trigger]: *margin only* the activation price type, 'last' or 'index', default is 'last'
|
1416
1421
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
@@ -1717,8 +1722,11 @@ class kraken(Exchange, ImplicitAPI):
|
|
1717
1722
|
isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
|
1718
1723
|
isStopLossOrTakeProfitTrigger = isStopLossTriggerOrder or isTakeProfitTriggerOrder
|
1719
1724
|
trailingAmount = self.safe_string(params, 'trailingAmount')
|
1725
|
+
trailingPercent = self.safe_string(params, 'trailingPercent')
|
1720
1726
|
trailingLimitAmount = self.safe_string(params, 'trailingLimitAmount')
|
1727
|
+
trailingLimitPercent = self.safe_string(params, 'trailingLimitPercent')
|
1721
1728
|
isTrailingAmountOrder = trailingAmount is not None
|
1729
|
+
isTrailingPercentOrder = trailingPercent is not None
|
1722
1730
|
isLimitOrder = type.endswith('limit') # supporting limit, stop-loss-limit, take-profit-limit, etc
|
1723
1731
|
isMarketOrder = type == 'market'
|
1724
1732
|
cost = self.safe_string(params, 'cost')
|
@@ -1732,7 +1740,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
1732
1740
|
request['volume'] = self.cost_to_precision(symbol, cost)
|
1733
1741
|
extendedOflags = flags + ',viqc' if (flags is not None) else 'viqc'
|
1734
1742
|
request['oflags'] = extendedOflags
|
1735
|
-
elif isLimitOrder and not isTrailingAmountOrder:
|
1743
|
+
elif isLimitOrder and not isTrailingAmountOrder and not isTrailingPercentOrder:
|
1736
1744
|
request['price'] = self.price_to_precision(symbol, price)
|
1737
1745
|
reduceOnly = self.safe_bool_2(params, 'reduceOnly', 'reduce_only')
|
1738
1746
|
if isStopLossOrTakeProfitTrigger:
|
@@ -1750,19 +1758,30 @@ class kraken(Exchange, ImplicitAPI):
|
|
1750
1758
|
request['ordertype'] = 'take-profit'
|
1751
1759
|
if isLimitOrder:
|
1752
1760
|
request['price2'] = self.price_to_precision(symbol, price)
|
1753
|
-
elif isTrailingAmountOrder:
|
1761
|
+
elif isTrailingAmountOrder or isTrailingPercentOrder:
|
1762
|
+
trailingPercentString = None
|
1763
|
+
if trailingPercent is not None:
|
1764
|
+
trailingPercentString = ('+' + trailingPercent) if (trailingPercent.endswith('%')) else ('+' + trailingPercent + '%')
|
1765
|
+
trailingAmountString = '+' + trailingAmount if (trailingAmount is not None) else None # must use + for self
|
1766
|
+
offset = self.safe_string(params, 'offset', '-') # can use + or - for self
|
1767
|
+
trailingLimitAmountString = offset + self.number_to_string(trailingLimitAmount) if (trailingLimitAmount is not None) else None
|
1754
1768
|
trailingActivationPriceType = self.safe_string(params, 'trigger', 'last')
|
1755
|
-
trailingAmountString = '+' + trailingAmount
|
1756
1769
|
request['trigger'] = trailingActivationPriceType
|
1757
|
-
if isLimitOrder or (trailingLimitAmount is not None):
|
1758
|
-
offset = self.safe_string(params, 'offset', '-')
|
1759
|
-
trailingLimitAmountString = offset + self.number_to_string(trailingLimitAmount)
|
1760
|
-
request['price'] = trailingAmountString
|
1761
|
-
request['price2'] = trailingLimitAmountString
|
1770
|
+
if isLimitOrder or (trailingLimitAmount is not None) or (trailingLimitPercent is not None):
|
1762
1771
|
request['ordertype'] = 'trailing-stop-limit'
|
1772
|
+
if trailingLimitPercent is not None:
|
1773
|
+
trailingLimitPercentString = (offset + trailingLimitPercent) if (trailingLimitPercent.endswith('%')) else (offset + trailingLimitPercent + '%')
|
1774
|
+
request['price'] = trailingPercentString
|
1775
|
+
request['price2'] = trailingLimitPercentString
|
1776
|
+
elif trailingLimitAmount is not None:
|
1777
|
+
request['price'] = trailingAmountString
|
1778
|
+
request['price2'] = trailingLimitAmountString
|
1763
1779
|
else:
|
1764
|
-
request['price'] = trailingAmountString
|
1765
1780
|
request['ordertype'] = 'trailing-stop'
|
1781
|
+
if trailingPercent is not None:
|
1782
|
+
request['price'] = trailingPercentString
|
1783
|
+
else:
|
1784
|
+
request['price'] = trailingAmountString
|
1766
1785
|
if reduceOnly:
|
1767
1786
|
if method == 'createOrderWs':
|
1768
1787
|
request['reduce_only'] = True # ws request can't have stringified bool
|
@@ -1789,7 +1808,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
1789
1808
|
request['oflags'] = extendedPostFlags
|
1790
1809
|
if (flags is not None) and not ('oflags' in request):
|
1791
1810
|
request['oflags'] = flags
|
1792
|
-
params = self.omit(params, ['timeInForce', 'reduceOnly', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingLimitAmount', 'offset'])
|
1811
|
+
params = self.omit(params, ['timeInForce', 'reduceOnly', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingPercent', 'trailingLimitAmount', 'trailingLimitPercent', 'offset'])
|
1793
1812
|
return [request, params]
|
1794
1813
|
|
1795
1814
|
def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
|
@@ -2916,11 +2935,15 @@ class kraken(Exchange, ImplicitAPI):
|
|
2916
2935
|
# urlencodeNested is used to address https://github.com/ccxt/ccxt/issues/12872
|
2917
2936
|
url += '?' + self.urlencode_nested(params)
|
2918
2937
|
elif api == 'private':
|
2938
|
+
price = self.safe_string(params, 'price')
|
2939
|
+
isTriggerPercent = False
|
2940
|
+
if price is not None:
|
2941
|
+
isTriggerPercent = True if (price.endswith('%')) else False
|
2919
2942
|
isCancelOrderBatch = (path == 'CancelOrderBatch')
|
2920
2943
|
self.check_required_credentials()
|
2921
2944
|
nonce = str(self.nonce())
|
2922
2945
|
# urlencodeNested is used to address https://github.com/ccxt/ccxt/issues/12872
|
2923
|
-
if isCancelOrderBatch:
|
2946
|
+
if isCancelOrderBatch or isTriggerPercent:
|
2924
2947
|
body = self.json(self.extend({'nonce': nonce}, params))
|
2925
2948
|
else:
|
2926
2949
|
body = self.urlencode_nested(self.extend({'nonce': nonce}, params))
|
@@ -2933,9 +2956,8 @@ class kraken(Exchange, ImplicitAPI):
|
|
2933
2956
|
headers = {
|
2934
2957
|
'API-Key': self.apiKey,
|
2935
2958
|
'API-Sign': signature,
|
2936
|
-
# 'Content-Type': 'application/x-www-form-urlencoded',
|
2937
2959
|
}
|
2938
|
-
if isCancelOrderBatch:
|
2960
|
+
if isCancelOrderBatch or isTriggerPercent:
|
2939
2961
|
headers['Content-Type'] = 'application/json'
|
2940
2962
|
else:
|
2941
2963
|
headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
ccxt/mexc.py
CHANGED
@@ -2054,6 +2054,7 @@ class mexc(Exchange, ImplicitAPI):
|
|
2054
2054
|
:param float [params.triggerPrice]: The price at which a trigger order is triggered at
|
2055
2055
|
:param bool [params.postOnly]: if True, the order will only be posted if it will be a maker order
|
2056
2056
|
:param bool [params.reduceOnly]: *contract only* indicates if self order is to reduce the size of a position
|
2057
|
+
:param bool [params.hedged]: *swap only* True for hedged mode, False for one way mode, default is False
|
2057
2058
|
*
|
2058
2059
|
* EXCHANGE SPECIFIC PARAMETERS
|
2059
2060
|
:param int [params.leverage]: *contract only* leverage is necessary on isolated margin
|
@@ -2179,6 +2180,7 @@ class mexc(Exchange, ImplicitAPI):
|
|
2179
2180
|
:param float [params.triggerPrice]: The price at which a trigger order is triggered at
|
2180
2181
|
:param bool [params.postOnly]: if True, the order will only be posted if it will be a maker order
|
2181
2182
|
:param bool [params.reduceOnly]: indicates if self order is to reduce the size of a position
|
2183
|
+
:param bool [params.hedged]: *swap only* True for hedged mode, False for one way mode, default is False
|
2182
2184
|
*
|
2183
2185
|
* EXCHANGE SPECIFIC PARAMETERS
|
2184
2186
|
:param int [params.leverage]: leverage is necessary on isolated margin
|
@@ -2246,15 +2248,25 @@ class mexc(Exchange, ImplicitAPI):
|
|
2246
2248
|
if leverage is None:
|
2247
2249
|
raise ArgumentsRequired(self.id + ' createSwapOrder() requires a leverage parameter for isolated margin orders')
|
2248
2250
|
reduceOnly = self.safe_bool(params, 'reduceOnly', False)
|
2249
|
-
|
2250
|
-
|
2251
|
+
hedged = self.safe_bool(params, 'hedged', False)
|
2252
|
+
sideInteger = None
|
2253
|
+
if hedged:
|
2254
|
+
if reduceOnly:
|
2255
|
+
params = self.omit(params, 'reduceOnly') # hedged mode does not accept self parameter
|
2256
|
+
side = 'sell' if (side == 'buy') else 'buy'
|
2257
|
+
sideInteger = 1 if (side == 'buy') else 3
|
2258
|
+
request['positionMode'] = 1
|
2251
2259
|
else:
|
2252
|
-
|
2260
|
+
if reduceOnly:
|
2261
|
+
sideInteger = 2 if (side == 'buy') else 4
|
2262
|
+
else:
|
2263
|
+
sideInteger = 1 if (side == 'buy') else 3
|
2264
|
+
request['side'] = sideInteger
|
2253
2265
|
clientOrderId = self.safe_string_2(params, 'clientOrderId', 'externalOid')
|
2254
2266
|
if clientOrderId is not None:
|
2255
2267
|
request['externalOid'] = clientOrderId
|
2256
2268
|
stopPrice = self.safe_number_2(params, 'triggerPrice', 'stopPrice')
|
2257
|
-
params = self.omit(params, ['clientOrderId', 'externalOid', 'postOnly', 'stopPrice', 'triggerPrice'])
|
2269
|
+
params = self.omit(params, ['clientOrderId', 'externalOid', 'postOnly', 'stopPrice', 'triggerPrice', 'hedged'])
|
2258
2270
|
response = None
|
2259
2271
|
if stopPrice:
|
2260
2272
|
request['triggerPrice'] = self.price_to_precision(symbol, stopPrice)
|
@@ -3615,23 +3627,29 @@ class mexc(Exchange, ImplicitAPI):
|
|
3615
3627
|
:param int [since]: the earliest time in ms to fetch trades for
|
3616
3628
|
:param int [limit]: the maximum number of trades structures to retrieve
|
3617
3629
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3630
|
+
:param int [params.until]: the latest time in ms to fetch trades for
|
3618
3631
|
:returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
3619
3632
|
"""
|
3620
3633
|
if symbol is None:
|
3621
3634
|
raise ArgumentsRequired(self.id + ' fetchMyTrades() requires a symbol argument')
|
3622
3635
|
self.load_markets()
|
3623
3636
|
market = self.market(symbol)
|
3624
|
-
marketType
|
3637
|
+
marketType: Str = None
|
3638
|
+
marketType, params = self.handle_market_type_and_params('fetchMyTrades', market, params)
|
3625
3639
|
request: dict = {
|
3626
3640
|
'symbol': market['id'],
|
3627
3641
|
}
|
3628
3642
|
trades = None
|
3629
3643
|
if marketType == 'spot':
|
3630
3644
|
if since is not None:
|
3631
|
-
request['
|
3645
|
+
request['startTime'] = since
|
3632
3646
|
if limit is not None:
|
3633
3647
|
request['limit'] = limit
|
3634
|
-
|
3648
|
+
until = self.safe_integer(params, 'until')
|
3649
|
+
if until is not None:
|
3650
|
+
params = self.omit(params, 'until')
|
3651
|
+
request['endTime'] = until
|
3652
|
+
trades = self.spotPrivateGetMyTrades(self.extend(request, params))
|
3635
3653
|
#
|
3636
3654
|
# spot
|
3637
3655
|
#
|
@@ -3661,7 +3679,7 @@ class mexc(Exchange, ImplicitAPI):
|
|
3661
3679
|
request['end_time'] = self.sum(since, self.options['maxTimeTillEnd'])
|
3662
3680
|
if limit is not None:
|
3663
3681
|
request['page_size'] = limit
|
3664
|
-
response = self.contractPrivateGetOrderListOrderDeals(self.extend(request,
|
3682
|
+
response = self.contractPrivateGetOrderListOrderDeals(self.extend(request, params))
|
3665
3683
|
#
|
3666
3684
|
# {
|
3667
3685
|
# "success": True,
|
ccxt/okx.py
CHANGED
@@ -17,6 +17,7 @@ from ccxt.base.errors import AccountSuspended
|
|
17
17
|
from ccxt.base.errors import ArgumentsRequired
|
18
18
|
from ccxt.base.errors import BadRequest
|
19
19
|
from ccxt.base.errors import BadSymbol
|
20
|
+
from ccxt.base.errors import ManualInteractionNeeded
|
20
21
|
from ccxt.base.errors import InsufficientFunds
|
21
22
|
from ccxt.base.errors import InvalidAddress
|
22
23
|
from ccxt.base.errors import InvalidOrder
|
@@ -599,6 +600,7 @@ class okx(Exchange, ImplicitAPI):
|
|
599
600
|
# General Class
|
600
601
|
'1': ExchangeError, # Operation failed
|
601
602
|
'2': ExchangeError, # Bulk operation partially succeeded
|
603
|
+
'4088': ManualInteractionNeeded, # {"code":"4088","data":[],"msg":"You can’t trade or deposit until you’ve verified your identity again. Head to Identity Verification to complete it."}
|
602
604
|
'50000': BadRequest, # Body can not be empty
|
603
605
|
'50001': OnMaintenance, # Matching engine upgrading. Please try again later
|
604
606
|
'50002': BadRequest, # Json data format error
|
@@ -2792,7 +2794,7 @@ class okx(Exchange, ImplicitAPI):
|
|
2792
2794
|
:param str [params.positionSide]: if position mode is one-way: set to 'net', if position mode is hedge-mode: set to 'long' or 'short'
|
2793
2795
|
:param str [params.trailingPercent]: the percent to trail away from the current market price
|
2794
2796
|
:param str [params.tpOrdKind]: 'condition' or 'limit', the default is 'condition'
|
2795
|
-
:param
|
2797
|
+
:param bool [params.hedged]: *swap and future only* True for hedged mode, False for one way mode
|
2796
2798
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2797
2799
|
"""
|
2798
2800
|
self.load_markets()
|
@@ -4525,32 +4527,27 @@ class okx(Exchange, ImplicitAPI):
|
|
4525
4527
|
:see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-deposit-address
|
4526
4528
|
:param str code: unified currency code
|
4527
4529
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4530
|
+
:param str [params.network]: the network name for the deposit address
|
4528
4531
|
:returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
|
4529
4532
|
"""
|
4533
|
+
self.load_markets()
|
4530
4534
|
rawNetwork = self.safe_string_upper(params, 'network')
|
4531
|
-
networks = self.safe_value(self.options, 'networks', {})
|
4532
|
-
network = self.safe_string(networks, rawNetwork, rawNetwork)
|
4533
4535
|
params = self.omit(params, 'network')
|
4536
|
+
code = self.safe_currency_code(code)
|
4537
|
+
network = self.network_id_to_code(rawNetwork, code)
|
4534
4538
|
response = self.fetch_deposit_addresses_by_network(code, params)
|
4535
|
-
|
4536
|
-
|
4537
|
-
result = self.safe_value(response, code)
|
4539
|
+
if network is not None:
|
4540
|
+
result = self.safe_dict(response, network)
|
4538
4541
|
if result is None:
|
4539
|
-
|
4540
|
-
result = self.safe_value(response, alias)
|
4541
|
-
if result is None:
|
4542
|
-
defaultNetwork = self.safe_string(self.options, 'defaultNetwork', 'ERC20')
|
4543
|
-
result = self.safe_value(response, defaultNetwork)
|
4544
|
-
if result is None:
|
4545
|
-
values = list(response.values())
|
4546
|
-
result = self.safe_value(values, 0)
|
4547
|
-
if result is None:
|
4548
|
-
raise InvalidAddress(self.id + ' fetchDepositAddress() cannot find deposit address for ' + code)
|
4542
|
+
raise InvalidAddress(self.id + ' fetchDepositAddress() cannot find ' + network + ' deposit address for ' + code)
|
4549
4543
|
return result
|
4550
|
-
|
4551
|
-
if
|
4552
|
-
|
4553
|
-
return
|
4544
|
+
codeNetwork = self.network_id_to_code(code, code)
|
4545
|
+
if codeNetwork in response:
|
4546
|
+
return response[codeNetwork]
|
4547
|
+
# if the network is not specified, return the first address
|
4548
|
+
keys = list(response.keys())
|
4549
|
+
first = self.safe_string(keys, 0)
|
4550
|
+
return self.safe_dict(response, first)
|
4554
4551
|
|
4555
4552
|
def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
|
4556
4553
|
"""
|
ccxt/phemex.py
CHANGED
@@ -2402,6 +2402,8 @@ class phemex(Exchange, ImplicitAPI):
|
|
2402
2402
|
:param float [params.takeProfit.triggerPrice]: take profit trigger price
|
2403
2403
|
:param dict [params.stopLoss]: *swap only* *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered(perpetual swap markets only)
|
2404
2404
|
:param float [params.stopLoss.triggerPrice]: stop loss trigger price
|
2405
|
+
:param str [params.posSide]: *swap only* "Merged" for one way mode, "Long" for buy side of hedged mode, "Short" for sell side of hedged mode
|
2406
|
+
:param bool [params.hedged]: *swap only* True for hedged mode, False for one way mode, default is False
|
2405
2407
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2406
2408
|
"""
|
2407
2409
|
self.load_markets()
|
@@ -2486,13 +2488,18 @@ class phemex(Exchange, ImplicitAPI):
|
|
2486
2488
|
amountString = self.number_to_string(amount)
|
2487
2489
|
request['baseQtyEv'] = self.to_ev(amountString, market)
|
2488
2490
|
elif market['swap']:
|
2491
|
+
hedged = self.safe_bool(params, 'hedged', False)
|
2492
|
+
params = self.omit(params, 'hedged')
|
2489
2493
|
posSide = self.safe_string_lower(params, 'posSide')
|
2490
2494
|
if posSide is None:
|
2491
|
-
|
2495
|
+
if hedged:
|
2496
|
+
if reduceOnly:
|
2497
|
+
side = 'sell' if (side == 'buy') else 'buy'
|
2498
|
+
posSide = 'Long' if (side == 'buy') else 'Short'
|
2499
|
+
else:
|
2500
|
+
posSide = 'Merged'
|
2492
2501
|
posSide = self.capitalize(posSide)
|
2493
2502
|
request['posSide'] = posSide
|
2494
|
-
if reduceOnly is not None:
|
2495
|
-
request['reduceOnly'] = reduceOnly
|
2496
2503
|
if market['settle'] == 'USDT':
|
2497
2504
|
request['orderQtyRq'] = amount
|
2498
2505
|
else:
|
ccxt/pro/__init__.py
CHANGED
ccxt/pro/deribit.py
CHANGED
@@ -23,6 +23,7 @@ class deribit(ccxt.async_support.deribit):
|
|
23
23
|
'watchBalance': True,
|
24
24
|
'watchTicker': True,
|
25
25
|
'watchTickers': True,
|
26
|
+
'watchBidsAsks': True,
|
26
27
|
'watchTrades': True,
|
27
28
|
'watchTradesForSymbols': True,
|
28
29
|
'watchMyTrades': True,
|
@@ -265,6 +266,79 @@ class deribit(ccxt.async_support.deribit):
|
|
265
266
|
self.tickers[symbol] = ticker
|
266
267
|
client.resolve(ticker, messageHash)
|
267
268
|
|
269
|
+
async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
|
270
|
+
"""
|
271
|
+
:see: https://docs.deribit.com/#quote-instrument_name
|
272
|
+
watches best bid & ask for symbols
|
273
|
+
:param str[] [symbols]: unified symbol of the market to fetch the ticker for
|
274
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
275
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
276
|
+
"""
|
277
|
+
await self.load_markets()
|
278
|
+
symbols = self.market_symbols(symbols, None, False)
|
279
|
+
url = self.urls['api']['ws']
|
280
|
+
channels = []
|
281
|
+
for i in range(0, len(symbols)):
|
282
|
+
market = self.market(symbols[i])
|
283
|
+
channels.append('quote.' + market['id'])
|
284
|
+
message: dict = {
|
285
|
+
'jsonrpc': '2.0',
|
286
|
+
'method': 'public/subscribe',
|
287
|
+
'params': {
|
288
|
+
'channels': channels,
|
289
|
+
},
|
290
|
+
'id': self.request_id(),
|
291
|
+
}
|
292
|
+
request = self.deep_extend(message, params)
|
293
|
+
newTickers = await self.watch_multiple(url, channels, request, channels, request)
|
294
|
+
if self.newUpdates:
|
295
|
+
tickers: dict = {}
|
296
|
+
tickers[newTickers['symbol']] = newTickers
|
297
|
+
return tickers
|
298
|
+
return self.filter_by_array(self.bidsasks, 'symbol', symbols)
|
299
|
+
|
300
|
+
def handle_bid_ask(self, client: Client, message):
|
301
|
+
#
|
302
|
+
# {
|
303
|
+
# "jsonrpc": "2.0",
|
304
|
+
# "method": "subscription",
|
305
|
+
# "params": {
|
306
|
+
# "channel": "quote.BTC_USDT",
|
307
|
+
# "data": {
|
308
|
+
# "best_bid_amount": 0.026,
|
309
|
+
# "best_ask_amount": 0.026,
|
310
|
+
# "best_bid_price": 63908,
|
311
|
+
# "best_ask_price": 63940,
|
312
|
+
# "instrument_name": "BTC_USDT",
|
313
|
+
# "timestamp": 1727765131750
|
314
|
+
# }
|
315
|
+
# }
|
316
|
+
# }
|
317
|
+
#
|
318
|
+
params = self.safe_dict(message, 'params', {})
|
319
|
+
data = self.safe_dict(params, 'data', {})
|
320
|
+
ticker = self.parse_ws_bid_ask(data)
|
321
|
+
symbol = ticker['symbol']
|
322
|
+
self.bidsasks[symbol] = ticker
|
323
|
+
messageHash = self.safe_string(params, 'channel')
|
324
|
+
client.resolve(ticker, messageHash)
|
325
|
+
|
326
|
+
def parse_ws_bid_ask(self, ticker, market=None):
|
327
|
+
marketId = self.safe_string(ticker, 'instrument_name')
|
328
|
+
market = self.safe_market(marketId, market)
|
329
|
+
symbol = self.safe_string(market, 'symbol')
|
330
|
+
timestamp = self.safe_integer(ticker, 'timestamp')
|
331
|
+
return self.safe_ticker({
|
332
|
+
'symbol': symbol,
|
333
|
+
'timestamp': timestamp,
|
334
|
+
'datetime': self.iso8601(timestamp),
|
335
|
+
'ask': self.safe_string(ticker, 'best_ask_price'),
|
336
|
+
'askVolume': self.safe_string(ticker, 'best_ask_amount'),
|
337
|
+
'bid': self.safe_string(ticker, 'best_bid_price'),
|
338
|
+
'bidVolume': self.safe_string(ticker, 'best_bid_amount'),
|
339
|
+
'info': ticker,
|
340
|
+
}, market)
|
341
|
+
|
268
342
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
269
343
|
"""
|
270
344
|
get the list of most recent trades for a particular symbol
|
@@ -862,6 +936,7 @@ class deribit(ccxt.async_support.deribit):
|
|
862
936
|
}
|
863
937
|
handlers: dict = {
|
864
938
|
'ticker': self.handle_ticker,
|
939
|
+
'quote': self.handle_bid_ask,
|
865
940
|
'book': self.handle_order_book,
|
866
941
|
'trades': self.handle_trades,
|
867
942
|
'chart': self.handle_ohlcv,
|
ccxt/pro/exmo.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
import ccxt.async_support
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Int, OrderBook, Str, Ticker, Trade
|
9
|
+
from ccxt.base.types import Balances, Int, OrderBook, Str, Strings, Ticker, Tickers, Trade
|
10
10
|
from ccxt.async_support.base.ws.client import Client
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import NotSupported
|
@@ -20,7 +20,7 @@ class exmo(ccxt.async_support.exmo):
|
|
20
20
|
'ws': True,
|
21
21
|
'watchBalance': True,
|
22
22
|
'watchTicker': True,
|
23
|
-
'watchTickers':
|
23
|
+
'watchTickers': True,
|
24
24
|
'watchTrades': True,
|
25
25
|
'watchMyTrades': True,
|
26
26
|
'watchOrders': False, # TODO
|
@@ -199,6 +199,7 @@ class exmo(ccxt.async_support.exmo):
|
|
199
199
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
200
200
|
"""
|
201
201
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
202
|
+
:see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#fd8f47bc-8517-43c0-bb60-1d61a86d4471
|
202
203
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
203
204
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
204
205
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
@@ -218,6 +219,32 @@ class exmo(ccxt.async_support.exmo):
|
|
218
219
|
request = self.deep_extend(message, params)
|
219
220
|
return await self.watch(url, messageHash, request, messageHash, request)
|
220
221
|
|
222
|
+
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
223
|
+
"""
|
224
|
+
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
225
|
+
:see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#fd8f47bc-8517-43c0-bb60-1d61a86d4471
|
226
|
+
:param str[] [symbols]: unified symbol of the market to fetch the ticker for
|
227
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
228
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
229
|
+
"""
|
230
|
+
await self.load_markets()
|
231
|
+
symbols = self.market_symbols(symbols, None, False)
|
232
|
+
messageHashes = []
|
233
|
+
args = []
|
234
|
+
for i in range(0, len(symbols)):
|
235
|
+
market = self.market(symbols[i])
|
236
|
+
messageHashes.append('ticker:' + market['symbol'])
|
237
|
+
args.append('spot/ticker:' + market['id'])
|
238
|
+
url = self.urls['api']['ws']['public']
|
239
|
+
message: dict = {
|
240
|
+
'method': 'subscribe',
|
241
|
+
'topics': args,
|
242
|
+
'id': self.request_id(),
|
243
|
+
}
|
244
|
+
request = self.deep_extend(message, params)
|
245
|
+
await self.watch_multiple(url, messageHashes, request, messageHashes, request)
|
246
|
+
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
247
|
+
|
221
248
|
def handle_ticker(self, client: Client, message):
|
222
249
|
#
|
223
250
|
# spot
|
ccxt/pro/okx.py
CHANGED
@@ -1813,7 +1813,7 @@ class okx(ccxt.async_support.okx):
|
|
1813
1813
|
tradeSymbols = list(symbols.keys())
|
1814
1814
|
for i in range(0, len(tradeSymbols)):
|
1815
1815
|
symbolMessageHash = messageHash + '::' + tradeSymbols[i]
|
1816
|
-
client.resolve(self.
|
1816
|
+
client.resolve(self.myTrades, symbolMessageHash)
|
1817
1817
|
|
1818
1818
|
def request_id(self):
|
1819
1819
|
ts = str(self.milliseconds())
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ccxt
|
3
|
-
Version: 4.4.
|
3
|
+
Version: 4.4.12
|
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
|
@@ -272,13 +272,13 @@ console.log(version, Object.keys(exchanges));
|
|
272
272
|
|
273
273
|
All-in-one browser bundle (dependencies included), served from a CDN of your choice:
|
274
274
|
|
275
|
-
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.4.
|
276
|
-
* unpkg: https://unpkg.com/ccxt@4.4.
|
275
|
+
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.4.12/dist/ccxt.browser.min.js
|
276
|
+
* unpkg: https://unpkg.com/ccxt@4.4.12/dist/ccxt.browser.min.js
|
277
277
|
|
278
278
|
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.
|
279
279
|
|
280
280
|
```HTML
|
281
|
-
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.4.
|
281
|
+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.4.12/dist/ccxt.browser.min.js"></script>
|
282
282
|
```
|
283
283
|
|
284
284
|
Creates a global `ccxt` object:
|