ccxt 4.4.92__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 +1 -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 +3 -0
- ccxt/async_support/binance.py +42 -1
- ccxt/async_support/bitmex.py +3 -3
- 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 +64 -52
- ccxt/async_support/hyperliquid.py +2 -1
- ccxt/async_support/kucoin.py +12 -14
- ccxt/async_support/latoken.py +19 -71
- ccxt/async_support/lbank.py +2 -2
- ccxt/async_support/okx.py +149 -0
- ccxt/async_support/paradex.py +54 -0
- ccxt/async_support/phemex.py +3 -3
- ccxt/base/exchange.py +55 -12
- ccxt/binance.py +42 -1
- ccxt/bitmex.py +3 -3
- 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 +64 -52
- ccxt/hyperliquid.py +2 -1
- ccxt/kucoin.py +12 -14
- ccxt/latoken.py +19 -71
- ccxt/lbank.py +2 -2
- ccxt/okx.py +149 -0
- 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 +2 -1
- {ccxt-4.4.92.dist-info → ccxt-4.4.93.dist-info}/METADATA +4 -4
- {ccxt-4.4.92.dist-info → ccxt-4.4.93.dist-info}/RECORD +48 -48
- {ccxt-4.4.92.dist-info → ccxt-4.4.93.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.92.dist-info → ccxt-4.4.93.dist-info}/WHEEL +0 -0
- {ccxt-4.4.92.dist-info → ccxt-4.4.93.dist-info}/top_level.txt +0 -0
ccxt/async_support/okx.py
CHANGED
@@ -81,6 +81,7 @@ class okx(Exchange, ImplicitAPI):
|
|
81
81
|
'createTriggerOrder': True,
|
82
82
|
'editOrder': True,
|
83
83
|
'fetchAccounts': True,
|
84
|
+
'fetchAllGreeks': True,
|
84
85
|
'fetchBalance': True,
|
85
86
|
'fetchBidsAsks': None,
|
86
87
|
'fetchBorrowInterest': True,
|
@@ -3614,6 +3615,84 @@ class okx(Exchange, ImplicitAPI):
|
|
3614
3615
|
# "uTime": "1621910749815"
|
3615
3616
|
# }
|
3616
3617
|
#
|
3618
|
+
# watchOrders & fetchClosedOrders
|
3619
|
+
#
|
3620
|
+
# {
|
3621
|
+
# "algoClOrdId": "",
|
3622
|
+
# "algoId": "",
|
3623
|
+
# "attachAlgoClOrdId": "",
|
3624
|
+
# "attachAlgoOrds": [],
|
3625
|
+
# "cancelSource": "",
|
3626
|
+
# "cancelSourceReason": "", # not present in WS, but present in fetchClosedOrders
|
3627
|
+
# "category": "normal",
|
3628
|
+
# "ccy": "", # empty in WS, but eg. `USDT` in fetchClosedOrders
|
3629
|
+
# "clOrdId": "",
|
3630
|
+
# "cTime": "1751705801423",
|
3631
|
+
# "feeCcy": "USDT",
|
3632
|
+
# "instId": "LINK-USDT-SWAP",
|
3633
|
+
# "instType": "SWAP",
|
3634
|
+
# "isTpLimit": "false",
|
3635
|
+
# "lever": "3",
|
3636
|
+
# "linkedAlgoOrd": {"algoId": ""},
|
3637
|
+
# "ordId": "2657625147249614848",
|
3638
|
+
# "ordType": "limit",
|
3639
|
+
# "posSide": "net",
|
3640
|
+
# "px": "13.142",
|
3641
|
+
# "pxType": "",
|
3642
|
+
# "pxUsd": "",
|
3643
|
+
# "pxVol": "",
|
3644
|
+
# "quickMgnType": "",
|
3645
|
+
# "rebate": "0",
|
3646
|
+
# "rebateCcy": "USDT",
|
3647
|
+
# "reduceOnly": "true",
|
3648
|
+
# "side": "sell",
|
3649
|
+
# "slOrdPx": "",
|
3650
|
+
# "slTriggerPx": "",
|
3651
|
+
# "slTriggerPxType": "",
|
3652
|
+
# "source": "",
|
3653
|
+
# "stpId": "",
|
3654
|
+
# "stpMode": "cancel_maker",
|
3655
|
+
# "sz": "0.1",
|
3656
|
+
# "tag": "",
|
3657
|
+
# "tdMode": "isolated",
|
3658
|
+
# "tgtCcy": "",
|
3659
|
+
# "tpOrdPx": "",
|
3660
|
+
# "tpTriggerPx": "",
|
3661
|
+
# "tpTriggerPxType": "",
|
3662
|
+
# "uTime": "1751705807467",
|
3663
|
+
# "reqId": "", # field present only in WS
|
3664
|
+
# "msg": "", # field present only in WS
|
3665
|
+
# "amendResult": "", # field present only in WS
|
3666
|
+
# "amendSource": "", # field present only in WS
|
3667
|
+
# "code": "0", # field present only in WS
|
3668
|
+
# "fillFwdPx": "", # field present only in WS
|
3669
|
+
# "fillMarkVol": "", # field present only in WS
|
3670
|
+
# "fillPxUsd": "", # field present only in WS
|
3671
|
+
# "fillPxVol": "", # field present only in WS
|
3672
|
+
# "lastPx": "13.142", # field present only in WS
|
3673
|
+
# "notionalUsd": "1.314515408", # field present only in WS
|
3674
|
+
#
|
3675
|
+
# #### these below fields are empty on first omit from websocket, because of "creation" event. however, if order is executed, it also immediately sends another update with these fields filled ###
|
3676
|
+
#
|
3677
|
+
# "pnl": "-0.0001",
|
3678
|
+
# "accFillSz": "0.1",
|
3679
|
+
# "avgPx": "13.142",
|
3680
|
+
# "state": "filled",
|
3681
|
+
# "fee": "-0.00026284",
|
3682
|
+
# "fillPx": "13.142",
|
3683
|
+
# "tradeId": "293429690",
|
3684
|
+
# "fillSz": "0.1",
|
3685
|
+
# "fillTime": "1751705807467",
|
3686
|
+
# "fillNotionalUsd": "1.314515408", # field present only in WS
|
3687
|
+
# "fillPnl": "-0.0001", # field present only in WS
|
3688
|
+
# "fillFee": "-0.00026284", # field present only in WS
|
3689
|
+
# "fillFeeCcy": "USDT", # field present only in WS
|
3690
|
+
# "execType": "M", # field present only in WS
|
3691
|
+
# "fillMarkPx": "13.141", # field present only in WS
|
3692
|
+
# "fillIdxPx": "13.147" # field present only in WS
|
3693
|
+
# }
|
3694
|
+
#
|
3695
|
+
#
|
3617
3696
|
# Algo Order fetchOpenOrders, fetchCanceledOrders, fetchClosedOrders
|
3618
3697
|
#
|
3619
3698
|
# {
|
@@ -7548,6 +7627,76 @@ class okx(Exchange, ImplicitAPI):
|
|
7548
7627
|
return self.parse_greeks(entry, market)
|
7549
7628
|
return None
|
7550
7629
|
|
7630
|
+
async def fetch_all_greeks(self, symbols: Strings = None, params={}) -> List[Greeks]:
|
7631
|
+
"""
|
7632
|
+
fetches all option contracts greeks, financial metrics used to measure the factors that affect the price of an options contract
|
7633
|
+
|
7634
|
+
https://www.okx.com/docs-v5/en/#public-data-rest-api-get-option-market-data
|
7635
|
+
|
7636
|
+
:param str[] [symbols]: unified symbols of the markets to fetch greeks for, all markets are returned if not assigned
|
7637
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7638
|
+
:param str params['uly']: Underlying, either uly or instFamily is required
|
7639
|
+
:param str params['instFamily']: Instrument family, either uly or instFamily is required
|
7640
|
+
:returns dict: a `greeks structure <https://docs.ccxt.com/#/?id=greeks-structure>`
|
7641
|
+
"""
|
7642
|
+
await self.load_markets()
|
7643
|
+
request: dict = {}
|
7644
|
+
symbols = self.market_symbols(symbols, None, True, True, True)
|
7645
|
+
symbolsLength = None
|
7646
|
+
if symbols is not None:
|
7647
|
+
symbolsLength = len(symbols)
|
7648
|
+
if (symbols is None) or (symbolsLength != 1):
|
7649
|
+
uly = self.safe_string(params, 'uly')
|
7650
|
+
if uly is not None:
|
7651
|
+
request['uly'] = uly
|
7652
|
+
instFamily = self.safe_string(params, 'instFamily')
|
7653
|
+
if instFamily is not None:
|
7654
|
+
request['instFamily'] = instFamily
|
7655
|
+
if (uly is None) and (instFamily is None):
|
7656
|
+
raise BadRequest(self.id + ' fetchAllGreeks() requires either a uly or instFamily parameter')
|
7657
|
+
market = None
|
7658
|
+
if symbols is not None:
|
7659
|
+
if symbolsLength == 1:
|
7660
|
+
market = self.market(symbols[0])
|
7661
|
+
marketId = market['id']
|
7662
|
+
optionParts = marketId.split('-')
|
7663
|
+
request['uly'] = market['info']['uly']
|
7664
|
+
request['instFamily'] = market['info']['instFamily']
|
7665
|
+
request['expTime'] = self.safe_string(optionParts, 2)
|
7666
|
+
params = self.omit(params, ['uly', 'instFamily'])
|
7667
|
+
response = await self.publicGetPublicOptSummary(self.extend(request, params))
|
7668
|
+
#
|
7669
|
+
# {
|
7670
|
+
# "code": "0",
|
7671
|
+
# "data": [
|
7672
|
+
# {
|
7673
|
+
# "askVol": "0",
|
7674
|
+
# "bidVol": "0",
|
7675
|
+
# "delta": "0.5105464486882039",
|
7676
|
+
# "deltaBS": "0.7325502184143025",
|
7677
|
+
# "fwdPx": "37675.80158694987186",
|
7678
|
+
# "gamma": "-0.13183515090501083",
|
7679
|
+
# "gammaBS": "0.000024139685826358558",
|
7680
|
+
# "instId": "BTC-USD-240329-32000-C",
|
7681
|
+
# "instType": "OPTION",
|
7682
|
+
# "lever": "4.504428015946619",
|
7683
|
+
# "markVol": "0.5916253554539876",
|
7684
|
+
# "realVol": "0",
|
7685
|
+
# "theta": "-0.0004202992014012855",
|
7686
|
+
# "thetaBS": "-18.52354631567909",
|
7687
|
+
# "ts": "1699586421976",
|
7688
|
+
# "uly": "BTC-USD",
|
7689
|
+
# "vega": "0.0020207455080045846",
|
7690
|
+
# "vegaBS": "74.44022302387287",
|
7691
|
+
# "volLv": "0.5948549730405797"
|
7692
|
+
# },
|
7693
|
+
# ],
|
7694
|
+
# "msg": ""
|
7695
|
+
# }
|
7696
|
+
#
|
7697
|
+
data = self.safe_list(response, 'data', [])
|
7698
|
+
return self.parse_all_greeks(data, symbols)
|
7699
|
+
|
7551
7700
|
def parse_greeks(self, greeks: dict, market: Market = None) -> Greeks:
|
7552
7701
|
#
|
7553
7702
|
# {
|
ccxt/async_support/paradex.py
CHANGED
@@ -57,6 +57,7 @@ class paradex(Exchange, ImplicitAPI):
|
|
57
57
|
'createTriggerOrder': True,
|
58
58
|
'editOrder': False,
|
59
59
|
'fetchAccounts': False,
|
60
|
+
'fetchAllGreeks': True,
|
60
61
|
'fetchBalance': True,
|
61
62
|
'fetchBorrowInterest': False,
|
62
63
|
'fetchBorrowRateHistories': False,
|
@@ -2346,6 +2347,59 @@ class paradex(Exchange, ImplicitAPI):
|
|
2346
2347
|
greeks = self.safe_dict(data, 0, {})
|
2347
2348
|
return self.parse_greeks(greeks, market)
|
2348
2349
|
|
2350
|
+
async def fetch_all_greeks(self, symbols: Strings = None, params={}) -> List[Greeks]:
|
2351
|
+
"""
|
2352
|
+
fetches all option contracts greeks, financial metrics used to measure the factors that affect the price of an options contract
|
2353
|
+
|
2354
|
+
https://docs.api.testnet.paradex.trade/#list-available-markets-summary
|
2355
|
+
|
2356
|
+
:param str[] [symbols]: unified symbols of the markets to fetch greeks for, all markets are returned if not assigned
|
2357
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2358
|
+
:returns dict: a `greeks structure <https://docs.ccxt.com/#/?id=greeks-structure>`
|
2359
|
+
"""
|
2360
|
+
await self.load_markets()
|
2361
|
+
symbols = self.market_symbols(symbols, None, True, True, True)
|
2362
|
+
request: dict = {
|
2363
|
+
'market': 'ALL',
|
2364
|
+
}
|
2365
|
+
response = await self.publicGetMarketsSummary(self.extend(request, params))
|
2366
|
+
#
|
2367
|
+
# {
|
2368
|
+
# "results": [
|
2369
|
+
# {
|
2370
|
+
# "symbol": "BTC-USD-114000-P",
|
2371
|
+
# "mark_price": "10835.66892602",
|
2372
|
+
# "mark_iv": "0.71781855",
|
2373
|
+
# "delta": "-0.98726024",
|
2374
|
+
# "greeks": {
|
2375
|
+
# "delta": "-0.9872602390817709",
|
2376
|
+
# "gamma": "0.000004560958862297231",
|
2377
|
+
# "vega": "227.11344863639806",
|
2378
|
+
# "rho": "-302.0617972461581",
|
2379
|
+
# "vanna": "0.06609830491614832",
|
2380
|
+
# "volga": "925.9501532805552"
|
2381
|
+
# },
|
2382
|
+
# "last_traded_price": "10551.5",
|
2383
|
+
# "bid": "10794.9",
|
2384
|
+
# "bid_iv": "0.05",
|
2385
|
+
# "ask": "10887.3",
|
2386
|
+
# "ask_iv": "0.8783283",
|
2387
|
+
# "last_iv": "0.05",
|
2388
|
+
# "volume_24h": "0",
|
2389
|
+
# "total_volume": "195240.72672261014",
|
2390
|
+
# "created_at": 1747644009995,
|
2391
|
+
# "underlying_price": "103164.79162649",
|
2392
|
+
# "open_interest": "0",
|
2393
|
+
# "funding_rate": "0.000004464241170536191",
|
2394
|
+
# "price_change_rate_24h": "0.074915",
|
2395
|
+
# "future_funding_rate": "0.0001"
|
2396
|
+
# }
|
2397
|
+
# ]
|
2398
|
+
# }
|
2399
|
+
#
|
2400
|
+
results = self.safe_list(response, 'results', [])
|
2401
|
+
return self.parse_all_greeks(results, symbols)
|
2402
|
+
|
2349
2403
|
def parse_greeks(self, greeks: dict, market: Market = None) -> Greeks:
|
2350
2404
|
#
|
2351
2405
|
# {
|
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
|
|
@@ -4229,7 +4229,7 @@ class Exchange(object):
|
|
4229
4229
|
return self.filter_by_since_limit(sorted, since, limit, 0, tail)
|
4230
4230
|
|
4231
4231
|
def parse_leverage_tiers(self, response: Any, symbols: List[str] = None, marketIdKey=None):
|
4232
|
-
# marketIdKey should only be None when response is a dictionary
|
4232
|
+
# marketIdKey should only be None when response is a dictionary.
|
4233
4233
|
symbols = self.market_symbols(symbols)
|
4234
4234
|
tiers = {}
|
4235
4235
|
symbolsLength = 0
|
@@ -5450,6 +5450,9 @@ class Exchange(object):
|
|
5450
5450
|
def fetch_greeks(self, symbol: str, params={}):
|
5451
5451
|
raise NotSupported(self.id + ' fetchGreeks() is not supported yet')
|
5452
5452
|
|
5453
|
+
def fetch_all_greeks(self, symbols: Strings = None, params={}):
|
5454
|
+
raise NotSupported(self.id + ' fetchAllGreeks() is not supported yet')
|
5455
|
+
|
5453
5456
|
def fetch_option_chain(self, code: str, params={}):
|
5454
5457
|
raise NotSupported(self.id + ' fetchOptionChain() is not supported yet')
|
5455
5458
|
|
@@ -5703,10 +5706,16 @@ class Exchange(object):
|
|
5703
5706
|
precisionNumber = int(precision)
|
5704
5707
|
if precisionNumber == 0:
|
5705
5708
|
return '1'
|
5706
|
-
|
5707
|
-
|
5708
|
-
|
5709
|
-
|
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'
|
5710
5719
|
|
5711
5720
|
def integer_precision_to_amount(self, precision: Str):
|
5712
5721
|
"""
|
@@ -6682,6 +6691,27 @@ class Exchange(object):
|
|
6682
6691
|
def parse_greeks(self, greeks: dict, market: Market = None):
|
6683
6692
|
raise NotSupported(self.id + ' parseGreeks() is not supported yet')
|
6684
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
|
+
|
6685
6715
|
def parse_option(self, chain: dict, currency: Currency = None, market: Market = None):
|
6686
6716
|
raise NotSupported(self.id + ' parseOption() is not supported yet')
|
6687
6717
|
|
@@ -6883,14 +6913,27 @@ class Exchange(object):
|
|
6883
6913
|
"""
|
6884
6914
|
raise NotSupported(self.id + ' fetchTransfers() is not supported yet')
|
6885
6915
|
|
6886
|
-
def clean_unsubscription(self, client, subHash: str, unsubHash: str):
|
6916
|
+
def clean_unsubscription(self, client, subHash: str, unsubHash: str, subHashIsPrefix=False):
|
6887
6917
|
if unsubHash in client.subscriptions:
|
6888
6918
|
del client.subscriptions[unsubHash]
|
6889
|
-
if
|
6890
|
-
|
6891
|
-
|
6892
|
-
|
6893
|
-
|
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)
|
6894
6937
|
client.resolve(True, unsubHash)
|
6895
6938
|
|
6896
6939
|
def clean_cache(self, subscription: dict):
|
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/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/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')
|