ccxt 4.4.91__py2.py3-none-any.whl → 4.4.93__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/lbank.py +2 -1
- ccxt/ascendex.py +9 -8
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ascendex.py +9 -8
- ccxt/async_support/base/exchange.py +4 -1
- ccxt/async_support/base/ws/client.py +4 -1
- ccxt/async_support/binance.py +42 -1
- ccxt/async_support/bitmart.py +7 -0
- ccxt/async_support/bitmex.py +3 -3
- ccxt/async_support/bitvavo.py +7 -1
- ccxt/async_support/bybit.py +81 -8
- ccxt/async_support/coinbaseexchange.py +53 -0
- ccxt/async_support/coincheck.py +45 -4
- ccxt/async_support/coinex.py +16 -12
- ccxt/async_support/cryptomus.py +30 -52
- ccxt/async_support/deribit.py +6 -6
- ccxt/async_support/exmo.py +70 -50
- ccxt/async_support/htx.py +1 -1
- ccxt/async_support/hyperliquid.py +2 -1
- ccxt/async_support/krakenfutures.py +1 -1
- ccxt/async_support/kucoin.py +12 -14
- ccxt/async_support/latoken.py +19 -71
- ccxt/async_support/lbank.py +115 -35
- ccxt/async_support/okx.py +151 -2
- ccxt/async_support/paradex.py +54 -0
- ccxt/async_support/phemex.py +3 -3
- ccxt/base/exchange.py +69 -30
- ccxt/base/types.py +1 -0
- ccxt/binance.py +42 -1
- ccxt/bitmart.py +7 -0
- ccxt/bitmex.py +3 -3
- ccxt/bitvavo.py +7 -1
- ccxt/bybit.py +81 -8
- ccxt/coinbaseexchange.py +53 -0
- ccxt/coincheck.py +45 -4
- ccxt/coinex.py +16 -12
- ccxt/cryptomus.py +30 -52
- ccxt/deribit.py +6 -6
- ccxt/exmo.py +70 -50
- ccxt/htx.py +1 -1
- ccxt/hyperliquid.py +2 -1
- ccxt/krakenfutures.py +1 -1
- ccxt/kucoin.py +12 -14
- ccxt/latoken.py +19 -71
- ccxt/lbank.py +115 -35
- ccxt/okx.py +151 -2
- ccxt/paradex.py +54 -0
- ccxt/phemex.py +3 -3
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bitstamp.py +48 -16
- ccxt/pro/bybit.py +5 -5
- {ccxt-4.4.91.dist-info → ccxt-4.4.93.dist-info}/METADATA +4 -4
- {ccxt-4.4.91.dist-info → ccxt-4.4.93.dist-info}/RECORD +57 -57
- {ccxt-4.4.91.dist-info → ccxt-4.4.93.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.91.dist-info → ccxt-4.4.93.dist-info}/WHEEL +0 -0
- {ccxt-4.4.91.dist-info → ccxt-4.4.93.dist-info}/top_level.txt +0 -0
ccxt/async_support/phemex.py
CHANGED
@@ -2659,14 +2659,14 @@ class phemex(Exchange, ImplicitAPI):
|
|
2659
2659
|
triggerDirection = None
|
2660
2660
|
triggerDirection, params = self.handle_param_string(params, 'triggerDirection')
|
2661
2661
|
if triggerDirection is None:
|
2662
|
-
raise ArgumentsRequired(self.id + " createOrder() also requires a 'triggerDirection' parameter with either '
|
2662
|
+
raise ArgumentsRequired(self.id + " createOrder() also requires a 'triggerDirection' parameter with either 'ascending' or 'descending' value")
|
2663
2663
|
# the flow defined per https://phemex-docs.github.io/#more-order-type-examples
|
2664
|
-
if triggerDirection == 'up':
|
2664
|
+
if triggerDirection == 'ascending' or triggerDirection == 'up':
|
2665
2665
|
if side == 'sell':
|
2666
2666
|
request['ordType'] = 'MarketIfTouched' if (type == 'Market') else 'LimitIfTouched'
|
2667
2667
|
elif side == 'buy':
|
2668
2668
|
request['ordType'] = 'Stop' if (type == 'Market') else 'StopLimit'
|
2669
|
-
elif triggerDirection == 'down':
|
2669
|
+
elif triggerDirection == 'descending' or triggerDirection == 'down':
|
2670
2670
|
if side == 'sell':
|
2671
2671
|
request['ordType'] = 'Stop' if (type == 'Market') else 'StopLimit'
|
2672
2672
|
elif side == 'buy':
|
ccxt/base/exchange.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
|
7
|
-
__version__ = '4.4.
|
7
|
+
__version__ = '4.4.93'
|
8
8
|
|
9
9
|
# -----------------------------------------------------------------------------
|
10
10
|
|
@@ -1515,6 +1515,12 @@ class Exchange(object):
|
|
1515
1515
|
parts = re.sub(r'0+$', '', str).split('.')
|
1516
1516
|
return len(parts[1]) if len(parts) > 1 else 0
|
1517
1517
|
|
1518
|
+
def map_to_safe_map(self, dictionary):
|
1519
|
+
return dictionary # wrapper for go
|
1520
|
+
|
1521
|
+
def safe_map_to_map(self, dictionary):
|
1522
|
+
return dictionary # wrapper for go
|
1523
|
+
|
1518
1524
|
def load_markets(self, reload=False, params={}):
|
1519
1525
|
"""
|
1520
1526
|
Loads and prepares the markets for trading.
|
@@ -3222,14 +3228,14 @@ class Exchange(object):
|
|
3222
3228
|
else:
|
3223
3229
|
market['subType'] = None
|
3224
3230
|
values.append(market)
|
3225
|
-
self.markets = self.index_by(values, 'symbol')
|
3231
|
+
self.markets = self.map_to_safe_map(self.index_by(values, 'symbol'))
|
3226
3232
|
marketsSortedBySymbol = self.keysort(self.markets)
|
3227
3233
|
marketsSortedById = self.keysort(self.markets_by_id)
|
3228
3234
|
self.symbols = list(marketsSortedBySymbol.keys())
|
3229
3235
|
self.ids = list(marketsSortedById.keys())
|
3230
3236
|
if currencies is not None:
|
3231
3237
|
# currencies is always None when called in constructor but not when called from loadMarkets
|
3232
|
-
self.currencies = self.deep_extend(self.currencies, currencies)
|
3238
|
+
self.currencies = self.map_to_safe_map(self.deep_extend(self.currencies, currencies))
|
3233
3239
|
else:
|
3234
3240
|
baseCurrencies = []
|
3235
3241
|
quoteCurrencies = []
|
@@ -3255,8 +3261,8 @@ class Exchange(object):
|
|
3255
3261
|
quoteCurrencies.append(currency)
|
3256
3262
|
baseCurrencies = self.sort_by(baseCurrencies, 'code', False, '')
|
3257
3263
|
quoteCurrencies = self.sort_by(quoteCurrencies, 'code', False, '')
|
3258
|
-
self.baseCurrencies = self.index_by(baseCurrencies, 'code')
|
3259
|
-
self.quoteCurrencies = self.index_by(quoteCurrencies, 'code')
|
3264
|
+
self.baseCurrencies = self.map_to_safe_map(self.index_by(baseCurrencies, 'code'))
|
3265
|
+
self.quoteCurrencies = self.map_to_safe_map(self.index_by(quoteCurrencies, 'code'))
|
3260
3266
|
allCurrencies = self.array_concat(baseCurrencies, quoteCurrencies)
|
3261
3267
|
groupedCurrencies = self.group_by(allCurrencies, 'code')
|
3262
3268
|
codes = list(groupedCurrencies.keys())
|
@@ -3273,7 +3279,7 @@ class Exchange(object):
|
|
3273
3279
|
highestPrecisionCurrency = currentCurrency if (currentCurrency['precision'] > highestPrecisionCurrency['precision']) else highestPrecisionCurrency
|
3274
3280
|
resultingCurrencies.append(highestPrecisionCurrency)
|
3275
3281
|
sortedCurrencies = self.sort_by(resultingCurrencies, 'code')
|
3276
|
-
self.currencies = self.deep_extend(self.currencies, self.index_by(sortedCurrencies, 'code'))
|
3282
|
+
self.currencies = self.map_to_safe_map(self.deep_extend(self.currencies, self.index_by(sortedCurrencies, 'code')))
|
3277
3283
|
self.currencies_by_id = self.index_by_safe(self.currencies, 'id')
|
3278
3284
|
currenciesSortedByCode = self.keysort(self.currencies)
|
3279
3285
|
self.codes = list(currenciesSortedByCode.keys())
|
@@ -4223,7 +4229,7 @@ class Exchange(object):
|
|
4223
4229
|
return self.filter_by_since_limit(sorted, since, limit, 0, tail)
|
4224
4230
|
|
4225
4231
|
def parse_leverage_tiers(self, response: Any, symbols: List[str] = None, marketIdKey=None):
|
4226
|
-
# marketIdKey should only be None when response is a dictionary
|
4232
|
+
# marketIdKey should only be None when response is a dictionary.
|
4227
4233
|
symbols = self.market_symbols(symbols)
|
4228
4234
|
tiers = {}
|
4229
4235
|
symbolsLength = 0
|
@@ -5444,6 +5450,9 @@ class Exchange(object):
|
|
5444
5450
|
def fetch_greeks(self, symbol: str, params={}):
|
5445
5451
|
raise NotSupported(self.id + ' fetchGreeks() is not supported yet')
|
5446
5452
|
|
5453
|
+
def fetch_all_greeks(self, symbols: Strings = None, params={}):
|
5454
|
+
raise NotSupported(self.id + ' fetchAllGreeks() is not supported yet')
|
5455
|
+
|
5447
5456
|
def fetch_option_chain(self, code: str, params={}):
|
5448
5457
|
raise NotSupported(self.id + ' fetchOptionChain() is not supported yet')
|
5449
5458
|
|
@@ -5697,10 +5706,16 @@ class Exchange(object):
|
|
5697
5706
|
precisionNumber = int(precision)
|
5698
5707
|
if precisionNumber == 0:
|
5699
5708
|
return '1'
|
5700
|
-
|
5701
|
-
|
5702
|
-
|
5703
|
-
|
5709
|
+
if precisionNumber > 0:
|
5710
|
+
parsedPrecision = '0.'
|
5711
|
+
for i in range(0, precisionNumber - 1):
|
5712
|
+
parsedPrecision = parsedPrecision + '0'
|
5713
|
+
return parsedPrecision + '1'
|
5714
|
+
else:
|
5715
|
+
parsedPrecision = '1'
|
5716
|
+
for i in range(0, precisionNumber * -1 - 1):
|
5717
|
+
parsedPrecision = parsedPrecision + '0'
|
5718
|
+
return parsedPrecision + '0'
|
5704
5719
|
|
5705
5720
|
def integer_precision_to_amount(self, precision: Str):
|
5706
5721
|
"""
|
@@ -6676,6 +6691,27 @@ class Exchange(object):
|
|
6676
6691
|
def parse_greeks(self, greeks: dict, market: Market = None):
|
6677
6692
|
raise NotSupported(self.id + ' parseGreeks() is not supported yet')
|
6678
6693
|
|
6694
|
+
def parse_all_greeks(self, greeks, symbols: Strings = None, params={}):
|
6695
|
+
#
|
6696
|
+
# the value of greeks is either a dict or a list
|
6697
|
+
#
|
6698
|
+
results = []
|
6699
|
+
if isinstance(greeks, list):
|
6700
|
+
for i in range(0, len(greeks)):
|
6701
|
+
parsedTicker = self.parse_greeks(greeks[i])
|
6702
|
+
greek = self.extend(parsedTicker, params)
|
6703
|
+
results.append(greek)
|
6704
|
+
else:
|
6705
|
+
marketIds = list(greeks.keys())
|
6706
|
+
for i in range(0, len(marketIds)):
|
6707
|
+
marketId = marketIds[i]
|
6708
|
+
market = self.safe_market(marketId)
|
6709
|
+
parsed = self.parse_greeks(greeks[marketId], market)
|
6710
|
+
greek = self.extend(parsed, params)
|
6711
|
+
results.append(greek)
|
6712
|
+
symbols = self.market_symbols(symbols)
|
6713
|
+
return self.filter_by_array(results, 'symbol', symbols)
|
6714
|
+
|
6679
6715
|
def parse_option(self, chain: dict, currency: Currency = None, market: Market = None):
|
6680
6716
|
raise NotSupported(self.id + ' parseOption() is not supported yet')
|
6681
6717
|
|
@@ -6792,7 +6828,7 @@ class Exchange(object):
|
|
6792
6828
|
return reconstructedDate
|
6793
6829
|
|
6794
6830
|
def convert_market_id_expire_date(self, date: str):
|
6795
|
-
# parse 03JAN24 to 240103
|
6831
|
+
# parse 03JAN24 to 240103.
|
6796
6832
|
monthMappping = {
|
6797
6833
|
'JAN': '01',
|
6798
6834
|
'FEB': '02',
|
@@ -6877,14 +6913,27 @@ class Exchange(object):
|
|
6877
6913
|
"""
|
6878
6914
|
raise NotSupported(self.id + ' fetchTransfers() is not supported yet')
|
6879
6915
|
|
6880
|
-
def clean_unsubscription(self, client, subHash: str, unsubHash: str):
|
6916
|
+
def clean_unsubscription(self, client, subHash: str, unsubHash: str, subHashIsPrefix=False):
|
6881
6917
|
if unsubHash in client.subscriptions:
|
6882
6918
|
del client.subscriptions[unsubHash]
|
6883
|
-
if
|
6884
|
-
|
6885
|
-
|
6886
|
-
|
6887
|
-
|
6919
|
+
if not subHashIsPrefix:
|
6920
|
+
if subHash in client.subscriptions:
|
6921
|
+
del client.subscriptions[subHash]
|
6922
|
+
if subHash in client.futures:
|
6923
|
+
error = UnsubscribeError(self.id + ' ' + subHash)
|
6924
|
+
client.reject(error, subHash)
|
6925
|
+
else:
|
6926
|
+
clientSubscriptions = list(client.subscriptions.keys())
|
6927
|
+
for i in range(0, len(clientSubscriptions)):
|
6928
|
+
sub = clientSubscriptions[i]
|
6929
|
+
if sub.startswith(subHash):
|
6930
|
+
del client.subscriptions[sub]
|
6931
|
+
clientFutures = list(client.futures.keys())
|
6932
|
+
for i in range(0, len(clientFutures)):
|
6933
|
+
future = clientFutures[i]
|
6934
|
+
if future.startswith(subHash):
|
6935
|
+
error = UnsubscribeError(self.id + ' ' + future)
|
6936
|
+
client.reject(error, future)
|
6888
6937
|
client.resolve(True, unsubHash)
|
6889
6938
|
|
6890
6939
|
def clean_cache(self, subscription: dict):
|
@@ -6914,19 +6963,9 @@ class Exchange(object):
|
|
6914
6963
|
del self.tickers[symbol]
|
6915
6964
|
else:
|
6916
6965
|
if topic == 'myTrades' and (self.myTrades is not None):
|
6917
|
-
|
6918
|
-
# because in c# we need to use a different object(thread-safe dict)
|
6919
|
-
keys = list(self.myTrades.keys())
|
6920
|
-
for i in range(0, len(keys)):
|
6921
|
-
key = keys[i]
|
6922
|
-
if key in self.myTrades:
|
6923
|
-
del self.myTrades[key]
|
6966
|
+
self.myTrades = None
|
6924
6967
|
elif topic == 'orders' and (self.orders is not None):
|
6925
|
-
|
6926
|
-
for i in range(0, len(orderSymbols)):
|
6927
|
-
orderSymbol = orderSymbols[i]
|
6928
|
-
if orderSymbol in self.orders:
|
6929
|
-
del self.orders[orderSymbol]
|
6968
|
+
self.orders = None
|
6930
6969
|
elif topic == 'ticker' and (self.tickers is not None):
|
6931
6970
|
tickerSymbols = list(self.tickers.keys())
|
6932
6971
|
for i in range(0, len(tickerSymbols)):
|
ccxt/base/types.py
CHANGED
ccxt/binance.py
CHANGED
@@ -87,6 +87,7 @@ class binance(Exchange, ImplicitAPI):
|
|
87
87
|
'editOrder': True,
|
88
88
|
'editOrders': True,
|
89
89
|
'fetchAccounts': None,
|
90
|
+
'fetchAllGreeks': True,
|
90
91
|
'fetchBalance': True,
|
91
92
|
'fetchBidsAsks': True,
|
92
93
|
'fetchBorrowInterest': True,
|
@@ -10777,6 +10778,7 @@ class binance(Exchange, ImplicitAPI):
|
|
10777
10778
|
request: dict = {}
|
10778
10779
|
if symbol is not None:
|
10779
10780
|
request['symbol'] = market['id']
|
10781
|
+
symbol = market['symbol']
|
10780
10782
|
if since is not None:
|
10781
10783
|
request['startTime'] = since
|
10782
10784
|
if limit is not None:
|
@@ -10804,7 +10806,7 @@ class binance(Exchange, ImplicitAPI):
|
|
10804
10806
|
#
|
10805
10807
|
settlements = self.parse_settlements(response, market)
|
10806
10808
|
sorted = self.sort_by(settlements, 'timestamp')
|
10807
|
-
return self.filter_by_symbol_since_limit(sorted,
|
10809
|
+
return self.filter_by_symbol_since_limit(sorted, symbol, since, limit)
|
10808
10810
|
|
10809
10811
|
def parse_settlement(self, settlement, market):
|
10810
10812
|
#
|
@@ -12422,6 +12424,45 @@ class binance(Exchange, ImplicitAPI):
|
|
12422
12424
|
#
|
12423
12425
|
return self.parse_greeks(response[0], market)
|
12424
12426
|
|
12427
|
+
def fetch_all_greeks(self, symbols: Strings = None, params={}) -> List[Greeks]:
|
12428
|
+
"""
|
12429
|
+
fetches all option contracts greeks, financial metrics used to measure the factors that affect the price of an options contract
|
12430
|
+
|
12431
|
+
https://developers.binance.com/docs/derivatives/option/market-data/Option-Mark-Price
|
12432
|
+
|
12433
|
+
:param str[] [symbols]: unified symbols of the markets to fetch greeks for, all markets are returned if not assigned
|
12434
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
12435
|
+
:returns dict: a `greeks structure <https://docs.ccxt.com/#/?id=greeks-structure>`
|
12436
|
+
"""
|
12437
|
+
self.load_markets()
|
12438
|
+
symbols = self.market_symbols(symbols, None, True, True, True)
|
12439
|
+
request: dict = {}
|
12440
|
+
market = None
|
12441
|
+
if symbols is not None:
|
12442
|
+
symbolsLength = len(symbols)
|
12443
|
+
if symbolsLength == 1:
|
12444
|
+
market = self.market(symbols[0])
|
12445
|
+
request['symbol'] = market['id']
|
12446
|
+
response = self.eapiPublicGetMark(self.extend(request, params))
|
12447
|
+
#
|
12448
|
+
# [
|
12449
|
+
# {
|
12450
|
+
# "symbol": "BTC-231229-40000-C",
|
12451
|
+
# "markPrice": "2012",
|
12452
|
+
# "bidIV": "0.60236275",
|
12453
|
+
# "askIV": "0.62267244",
|
12454
|
+
# "markIV": "0.6125176",
|
12455
|
+
# "delta": "0.39111646",
|
12456
|
+
# "theta": "-32.13948531",
|
12457
|
+
# "gamma": "0.00004656",
|
12458
|
+
# "vega": "51.70062218",
|
12459
|
+
# "highPriceLimit": "6474",
|
12460
|
+
# "lowPriceLimit": "5"
|
12461
|
+
# }
|
12462
|
+
# ]
|
12463
|
+
#
|
12464
|
+
return self.parse_all_greeks(response, symbols)
|
12465
|
+
|
12425
12466
|
def parse_greeks(self, greeks: dict, market: Market = None) -> Greeks:
|
12426
12467
|
#
|
12427
12468
|
# {
|
ccxt/bitmart.py
CHANGED
@@ -2160,6 +2160,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2160
2160
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2161
2161
|
:param int [params.until]: the latest time in ms to fetch trades for
|
2162
2162
|
:param boolean [params.marginMode]: *spot* whether to fetch trades for margin orders or spot orders, defaults to spot orders(only isolated margin orders are supported)
|
2163
|
+
:param str [params.stpMode]: self-trade prevention only for spot, defaults to none, ['none', 'cancel_maker', 'cancel_taker', 'cancel_both']
|
2163
2164
|
:returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
2164
2165
|
"""
|
2165
2166
|
self.load_markets()
|
@@ -2264,6 +2265,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2264
2265
|
:param int [since]: the earliest time in ms to fetch trades for
|
2265
2266
|
:param int [limit]: the maximum number of trades to retrieve
|
2266
2267
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2268
|
+
:param str [params.stpMode]: self-trade prevention only for spot, defaults to none, ['none', 'cancel_maker', 'cancel_taker', 'cancel_both']
|
2267
2269
|
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
2268
2270
|
"""
|
2269
2271
|
self.load_markets()
|
@@ -2706,6 +2708,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2706
2708
|
:param str [params.stopLossPrice]: *swap only* the price to trigger a stop-loss order
|
2707
2709
|
:param str [params.takeProfitPrice]: *swap only* the price to trigger a take-profit order
|
2708
2710
|
:param int [params.plan_category]: *swap tp/sl only* 1: tp/sl, 2: position tp/sl, default is 1
|
2711
|
+
:param str [params.stpMode]: self-trade prevention only for spot, defaults to none, ['none', 'cancel_maker', 'cancel_taker', 'cancel_both']
|
2709
2712
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2710
2713
|
"""
|
2711
2714
|
self.load_markets()
|
@@ -2768,6 +2771,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2768
2771
|
|
2769
2772
|
:param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
|
2770
2773
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2774
|
+
:param str [params.stpMode]: self-trade prevention only for spot, defaults to none, ['none', 'cancel_maker', 'cancel_taker', 'cancel_both']
|
2771
2775
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2772
2776
|
"""
|
2773
2777
|
self.load_markets()
|
@@ -3270,6 +3274,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3270
3274
|
:param str [params.orderType]: *swap only* 'limit', 'market', or 'trailing'
|
3271
3275
|
:param boolean [params.trailing]: *swap only* set to True if you want to fetch trailing orders
|
3272
3276
|
:param boolean [params.trigger]: *swap only* set to True if you want to fetch trigger orders
|
3277
|
+
:param str [params.stpMode]: self-trade prevention only for spot, defaults to none, ['none', 'cancel_maker', 'cancel_taker', 'cancel_both']
|
3273
3278
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
3274
3279
|
"""
|
3275
3280
|
self.load_markets()
|
@@ -3383,6 +3388,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3383
3388
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3384
3389
|
:param int [params.until]: timestamp in ms of the latest entry
|
3385
3390
|
:param str [params.marginMode]: *spot only* 'cross' or 'isolated', for margin trading
|
3391
|
+
:param str [params.stpMode]: self-trade prevention only for spot, defaults to none, ['none', 'cancel_maker', 'cancel_taker', 'cancel_both']
|
3386
3392
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
3387
3393
|
"""
|
3388
3394
|
self.load_markets()
|
@@ -3441,6 +3447,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3441
3447
|
:param str [params.clientOrderId]: *spot* fetch the order by client order id instead of order id
|
3442
3448
|
:param str [params.orderType]: *swap only* 'limit', 'market', 'liquidate', 'bankruptcy', 'adl' or 'trailing'
|
3443
3449
|
:param boolean [params.trailing]: *swap only* set to True if you want to fetch a trailing order
|
3450
|
+
:param str [params.stpMode]: self-trade prevention only for spot, defaults to none, ['none', 'cancel_maker', 'cancel_taker', 'cancel_both']
|
3444
3451
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
3445
3452
|
"""
|
3446
3453
|
self.load_markets()
|
ccxt/bitmex.py
CHANGED
@@ -1924,7 +1924,7 @@ class bitmex(Exchange, ImplicitAPI):
|
|
1924
1924
|
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
1925
1925
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1926
1926
|
:param dict [params.triggerPrice]: the price at which a trigger order is triggered at
|
1927
|
-
:param dict [params.triggerDirection]: the direction whenever the trigger happens with relation to price - '
|
1927
|
+
:param dict [params.triggerDirection]: the direction whenever the trigger happens with relation to price - 'ascending' or 'descending'
|
1928
1928
|
:param float [params.trailingAmount]: the quote amount to trail away from the current market price
|
1929
1929
|
:returns dict: an `order structure <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
|
1930
1930
|
"""
|
@@ -1951,7 +1951,7 @@ class bitmex(Exchange, ImplicitAPI):
|
|
1951
1951
|
isTrailingAmountOrder = trailingAmount is not None
|
1952
1952
|
if isTriggerOrder or isTrailingAmountOrder:
|
1953
1953
|
triggerDirection = self.safe_string(params, 'triggerDirection')
|
1954
|
-
triggerAbove = (triggerDirection == 'above')
|
1954
|
+
triggerAbove = ((triggerDirection == 'ascending') or (triggerDirection == 'above'))
|
1955
1955
|
if (type == 'limit') or (type == 'market'):
|
1956
1956
|
self.check_required_argument('createOrder', triggerDirection, 'triggerDirection', ['above', 'below'])
|
1957
1957
|
if type == 'limit':
|
@@ -1994,7 +1994,7 @@ class bitmex(Exchange, ImplicitAPI):
|
|
1994
1994
|
isTrailingAmountOrder = trailingAmount is not None
|
1995
1995
|
if isTrailingAmountOrder:
|
1996
1996
|
triggerDirection = self.safe_string(params, 'triggerDirection')
|
1997
|
-
triggerAbove = (triggerDirection == 'above')
|
1997
|
+
triggerAbove = ((triggerDirection == 'ascending') or (triggerDirection == 'above'))
|
1998
1998
|
if (type == 'limit') or (type == 'market'):
|
1999
1999
|
self.check_required_argument('createOrder', triggerDirection, 'triggerDirection', ['above', 'below'])
|
2000
2000
|
orderType = None
|
ccxt/bitvavo.py
CHANGED
@@ -666,7 +666,7 @@ class bitvavo(Exchange, ImplicitAPI):
|
|
666
666
|
},
|
667
667
|
})
|
668
668
|
# set currencies here to avoid calling publicGetAssets twice
|
669
|
-
self.currencies = self.deep_extend(self.currencies, result)
|
669
|
+
self.currencies = self.map_to_safe_map(self.deep_extend(self.currencies, result))
|
670
670
|
return result
|
671
671
|
|
672
672
|
def fetch_ticker(self, symbol: str, params={}) -> Ticker:
|
@@ -1207,6 +1207,8 @@ class bitvavo(Exchange, ImplicitAPI):
|
|
1207
1207
|
operatorId, params = self.handle_option_and_params(params, 'createOrder', 'operatorId')
|
1208
1208
|
if operatorId is not None:
|
1209
1209
|
request['operatorId'] = self.parse_to_int(operatorId)
|
1210
|
+
else:
|
1211
|
+
raise ArgumentsRequired(self.id + ' createOrder() requires an operatorId in params or options, eg: exchange.options[\'operatorId\'] = 1234567890')
|
1210
1212
|
return self.extend(request, params)
|
1211
1213
|
|
1212
1214
|
def create_order(self, symbol: Str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
@@ -1304,6 +1306,8 @@ class bitvavo(Exchange, ImplicitAPI):
|
|
1304
1306
|
operatorId, params = self.handle_option_and_params(params, 'editOrder', 'operatorId')
|
1305
1307
|
if operatorId is not None:
|
1306
1308
|
request['operatorId'] = self.parse_to_int(operatorId)
|
1309
|
+
else:
|
1310
|
+
raise ArgumentsRequired(self.id + ' editOrder() requires an operatorId in params or options, eg: exchange.options[\'operatorId\'] = 1234567890')
|
1307
1311
|
request['market'] = market['id']
|
1308
1312
|
return request
|
1309
1313
|
|
@@ -1342,6 +1346,8 @@ class bitvavo(Exchange, ImplicitAPI):
|
|
1342
1346
|
operatorId, params = self.handle_option_and_params(params, 'cancelOrder', 'operatorId')
|
1343
1347
|
if operatorId is not None:
|
1344
1348
|
request['operatorId'] = self.parse_to_int(operatorId)
|
1349
|
+
else:
|
1350
|
+
raise ArgumentsRequired(self.id + ' cancelOrder() requires an operatorId in params or options, eg: exchange.options[\'operatorId\'] = 1234567890')
|
1345
1351
|
return self.extend(request, params)
|
1346
1352
|
|
1347
1353
|
def cancel_order(self, id: str, symbol: Str = None, params={}):
|
ccxt/bybit.py
CHANGED
@@ -74,6 +74,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
74
74
|
'createTriggerOrder': True,
|
75
75
|
'editOrder': True,
|
76
76
|
'editOrders': True,
|
77
|
+
'fetchAllGreeks': True,
|
77
78
|
'fetchBalance': True,
|
78
79
|
'fetchBidsAsks': 'emulated',
|
79
80
|
'fetchBorrowInterest': False, # temporarily disabled, doesn't work
|
@@ -1172,6 +1173,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
1172
1173
|
'4h': '4h',
|
1173
1174
|
'1d': '1d',
|
1174
1175
|
},
|
1176
|
+
'useMarkPriceForPositionCollateral': False, # use mark price for position collateral
|
1175
1177
|
},
|
1176
1178
|
'features': {
|
1177
1179
|
'default': {
|
@@ -3725,7 +3727,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
3725
3727
|
:param int [params.isLeverage]: *unified spot only* False then spot trading True then margin trading
|
3726
3728
|
:param str [params.tpslMode]: *contract only* 'full' or 'partial'
|
3727
3729
|
:param str [params.mmp]: *option only* market maker protection
|
3728
|
-
:param str [params.triggerDirection]: *contract only* the direction for trigger orders, '
|
3730
|
+
:param str [params.triggerDirection]: *contract only* the direction for trigger orders, 'ascending' or 'descending'
|
3729
3731
|
:param float [params.triggerPrice]: The price at which a trigger order is triggered at
|
3730
3732
|
:param float [params.stopLossPrice]: The price at which a stop loss order is triggered at
|
3731
3733
|
:param float [params.takeProfitPrice]: The price at which a take profit order is triggered at
|
@@ -3935,8 +3937,8 @@ class bybit(Exchange, ImplicitAPI):
|
|
3935
3937
|
raise NotSupported(self.id + ' createOrder() : trigger order does not support triggerDirection for spot markets yet')
|
3936
3938
|
else:
|
3937
3939
|
if triggerDirection is None:
|
3938
|
-
raise ArgumentsRequired(self.id + ' stop/trigger orders require a triggerDirection parameter, either "
|
3939
|
-
isAsending = ((triggerDirection == 'above') or (triggerDirection == '1'))
|
3940
|
+
raise ArgumentsRequired(self.id + ' stop/trigger orders require a triggerDirection parameter, either "ascending" or "descending" to determine the direction of the trigger.')
|
3941
|
+
isAsending = ((triggerDirection == 'ascending') or (triggerDirection == 'above') or (triggerDirection == '1'))
|
3940
3942
|
request['triggerDirection'] = 1 if isAsending else 2
|
3941
3943
|
request['triggerPrice'] = self.get_price(symbol, triggerPrice)
|
3942
3944
|
elif (isStopLossTriggerOrder or isTakeProfitTriggerOrder) and not isAlternativeEndpoint:
|
@@ -6213,12 +6215,14 @@ classic accounts only/ spot not supported* fetches information on an order made
|
|
6213
6215
|
marginMode = 'isolated' if (tradeMode == 1) else 'cross'
|
6214
6216
|
collateralString = self.safe_string(position, 'positionBalance')
|
6215
6217
|
entryPrice = self.omit_zero(self.safe_string_n(position, ['entryPrice', 'avgPrice', 'avgEntryPrice']))
|
6218
|
+
markPrice = self.safe_string(position, 'markPrice')
|
6216
6219
|
liquidationPrice = self.omit_zero(self.safe_string(position, 'liqPrice'))
|
6217
6220
|
leverage = self.safe_string(position, 'leverage')
|
6218
6221
|
if liquidationPrice is not None:
|
6219
6222
|
if market['settle'] == 'USDC':
|
6220
6223
|
# (Entry price - Liq price) * Contracts + Maintenance Margin + (unrealised pnl) = Collateral
|
6221
|
-
|
6224
|
+
price = markPrice if self.safe_bool(self.options, 'useMarkPriceForPositionCollateral', False) else entryPrice
|
6225
|
+
difference = Precise.string_abs(Precise.string_sub(price, liquidationPrice))
|
6222
6226
|
collateralString = Precise.string_add(Precise.string_add(Precise.string_mul(difference, size), maintenanceMarginString), unrealisedPnl)
|
6223
6227
|
else:
|
6224
6228
|
bustPrice = self.safe_string(position, 'bustPrice')
|
@@ -6267,7 +6271,7 @@ classic accounts only/ spot not supported* fetches information on an order made
|
|
6267
6271
|
'contractSize': self.safe_number(market, 'contractSize'),
|
6268
6272
|
'marginRatio': self.parse_number(marginRatio),
|
6269
6273
|
'liquidationPrice': self.parse_number(liquidationPrice),
|
6270
|
-
'markPrice': self.
|
6274
|
+
'markPrice': self.parse_number(markPrice),
|
6271
6275
|
'lastPrice': self.safe_number(position, 'avgExitPrice'),
|
6272
6276
|
'collateral': self.parse_number(collateralString),
|
6273
6277
|
'marginMode': marginMode,
|
@@ -7624,6 +7628,75 @@ classic accounts only/ spot not supported* fetches information on an order made
|
|
7624
7628
|
'datetime': self.iso8601(timestamp),
|
7625
7629
|
})
|
7626
7630
|
|
7631
|
+
def fetch_all_greeks(self, symbols: Strings = None, params={}) -> List[Greeks]:
|
7632
|
+
"""
|
7633
|
+
fetches all option contracts greeks, financial metrics used to measure the factors that affect the price of an options contract
|
7634
|
+
|
7635
|
+
https://bybit-exchange.github.io/docs/api-explorer/v5/market/tickers
|
7636
|
+
|
7637
|
+
:param str[] [symbols]: unified symbols of the markets to fetch greeks for, all markets are returned if not assigned
|
7638
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7639
|
+
:param str [params.baseCoin]: the baseCoin of the symbol, default is BTC
|
7640
|
+
:returns dict: a `greeks structure <https://docs.ccxt.com/#/?id=greeks-structure>`
|
7641
|
+
"""
|
7642
|
+
self.load_markets()
|
7643
|
+
symbols = self.market_symbols(symbols, None, True, True, True)
|
7644
|
+
baseCoin = self.safe_string(params, 'baseCoin', 'BTC')
|
7645
|
+
request: dict = {
|
7646
|
+
'category': 'option',
|
7647
|
+
'baseCoin': baseCoin,
|
7648
|
+
}
|
7649
|
+
market = None
|
7650
|
+
if symbols is not None:
|
7651
|
+
symbolsLength = len(symbols)
|
7652
|
+
if symbolsLength == 1:
|
7653
|
+
market = self.market(symbols[0])
|
7654
|
+
request['symbol'] = market['id']
|
7655
|
+
response = self.publicGetV5MarketTickers(self.extend(request, params))
|
7656
|
+
#
|
7657
|
+
# {
|
7658
|
+
# "retCode": 0,
|
7659
|
+
# "retMsg": "SUCCESS",
|
7660
|
+
# "result": {
|
7661
|
+
# "category": "option",
|
7662
|
+
# "list": [
|
7663
|
+
# {
|
7664
|
+
# "symbol": "BTC-26JAN24-39000-C",
|
7665
|
+
# "bid1Price": "3205",
|
7666
|
+
# "bid1Size": "7.1",
|
7667
|
+
# "bid1Iv": "0.5478",
|
7668
|
+
# "ask1Price": "3315",
|
7669
|
+
# "ask1Size": "1.98",
|
7670
|
+
# "ask1Iv": "0.5638",
|
7671
|
+
# "lastPrice": "3230",
|
7672
|
+
# "highPrice24h": "3255",
|
7673
|
+
# "lowPrice24h": "3200",
|
7674
|
+
# "markPrice": "3273.02263032",
|
7675
|
+
# "indexPrice": "36790.96",
|
7676
|
+
# "markIv": "0.5577",
|
7677
|
+
# "underlyingPrice": "37649.67254894",
|
7678
|
+
# "openInterest": "19.67",
|
7679
|
+
# "turnover24h": "170140.33875912",
|
7680
|
+
# "volume24h": "4.56",
|
7681
|
+
# "totalVolume": "22",
|
7682
|
+
# "totalTurnover": "789305",
|
7683
|
+
# "delta": "0.49640971",
|
7684
|
+
# "gamma": "0.00004131",
|
7685
|
+
# "vega": "69.08651675",
|
7686
|
+
# "theta": "-24.9443226",
|
7687
|
+
# "predictedDeliveryPrice": "0",
|
7688
|
+
# "change24h": "0.18532111"
|
7689
|
+
# }
|
7690
|
+
# ]
|
7691
|
+
# },
|
7692
|
+
# "retExtInfo": {},
|
7693
|
+
# "time": 1699584008326
|
7694
|
+
# }
|
7695
|
+
#
|
7696
|
+
result = self.safe_dict(response, 'result', {})
|
7697
|
+
data = self.safe_list(result, 'list', [])
|
7698
|
+
return self.parse_all_greeks(data, symbols)
|
7699
|
+
|
7627
7700
|
def parse_greeks(self, greeks: dict, market: Market = None) -> Greeks:
|
7628
7701
|
#
|
7629
7702
|
# {
|
@@ -8730,7 +8803,7 @@ classic accounts only/ spot not supported* fetches information on an order made
|
|
8730
8803
|
authFull = auth_base + body
|
8731
8804
|
else:
|
8732
8805
|
authFull = auth_base + queryEncoded
|
8733
|
-
url += '?' +
|
8806
|
+
url += '?' + queryEncoded
|
8734
8807
|
signature = None
|
8735
8808
|
if self.secret.find('PRIVATE KEY') > -1:
|
8736
8809
|
signature = self.rsa(authFull, self.secret, 'sha256')
|
@@ -8744,7 +8817,7 @@ classic accounts only/ spot not supported* fetches information on an order made
|
|
8744
8817
|
'timestamp': timestamp,
|
8745
8818
|
})
|
8746
8819
|
sortedQuery = self.keysort(query)
|
8747
|
-
auth = self.rawencode(sortedQuery)
|
8820
|
+
auth = self.rawencode(sortedQuery, True)
|
8748
8821
|
signature = None
|
8749
8822
|
if self.secret.find('PRIVATE KEY') > -1:
|
8750
8823
|
signature = self.rsa(auth, self.secret, 'sha256')
|
@@ -8766,7 +8839,7 @@ classic accounts only/ spot not supported* fetches information on an order made
|
|
8766
8839
|
'Content-Type': 'application/json',
|
8767
8840
|
}
|
8768
8841
|
else:
|
8769
|
-
url += '?' + self.rawencode(sortedQuery)
|
8842
|
+
url += '?' + self.rawencode(sortedQuery, True)
|
8770
8843
|
url += '&sign=' + signature
|
8771
8844
|
if method == 'POST':
|
8772
8845
|
brokerId = self.safe_string(self.options, 'brokerId')
|