ccxt 4.4.92__py2.py3-none-any.whl → 4.4.94__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 +83 -10
- ccxt/async_support/coinbase.py +4 -1
- ccxt/async_support/coinbaseexchange.py +53 -0
- ccxt/async_support/coincheck.py +45 -4
- ccxt/async_support/coinex.py +16 -12
- ccxt/async_support/coinmetro.py +15 -3
- ccxt/async_support/cryptomus.py +30 -52
- ccxt/async_support/deribit.py +6 -6
- ccxt/async_support/exmo.py +64 -52
- ccxt/async_support/htx.py +5 -1
- ccxt/async_support/hyperliquid.py +126 -33
- 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 +159 -3
- ccxt/async_support/paradex.py +54 -0
- ccxt/async_support/phemex.py +3 -3
- ccxt/async_support/wavesexchange.py +12 -2
- ccxt/base/exchange.py +96 -31
- ccxt/binance.py +42 -1
- ccxt/bitmex.py +3 -3
- ccxt/bybit.py +83 -10
- ccxt/coinbase.py +4 -1
- ccxt/coinbaseexchange.py +53 -0
- ccxt/coincheck.py +45 -4
- ccxt/coinex.py +16 -12
- ccxt/coinmetro.py +14 -3
- ccxt/cryptomus.py +30 -52
- ccxt/deribit.py +6 -6
- ccxt/exmo.py +64 -52
- ccxt/htx.py +5 -1
- ccxt/hyperliquid.py +126 -33
- ccxt/kucoin.py +12 -14
- ccxt/latoken.py +19 -71
- ccxt/lbank.py +2 -2
- ccxt/okx.py +159 -3
- 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/test/tests_async.py +17 -15
- ccxt/test/tests_sync.py +17 -15
- ccxt/wavesexchange.py +12 -2
- {ccxt-4.4.92.dist-info → ccxt-4.4.94.dist-info}/METADATA +4 -4
- {ccxt-4.4.92.dist-info → ccxt-4.4.94.dist-info}/RECORD +58 -58
- {ccxt-4.4.92.dist-info → ccxt-4.4.94.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.92.dist-info → ccxt-4.4.94.dist-info}/WHEEL +0 -0
- {ccxt-4.4.92.dist-info → ccxt-4.4.94.dist-info}/top_level.txt +0 -0
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
|
@@ -3749,7 +3751,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
3749
3751
|
isTakeProfit = takeProfitPrice is not None
|
3750
3752
|
orderRequest = self.create_order_request(symbol, type, side, amount, price, params, enableUnifiedAccount)
|
3751
3753
|
defaultMethod = None
|
3752
|
-
if isTrailingAmountOrder or isStopLoss or isTakeProfit:
|
3754
|
+
if (isTrailingAmountOrder or isStopLoss or isTakeProfit) and not market['spot']:
|
3753
3755
|
defaultMethod = 'privatePostV5PositionTradingStop'
|
3754
3756
|
else:
|
3755
3757
|
defaultMethod = 'privatePostV5OrderCreate'
|
@@ -3825,7 +3827,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
3825
3827
|
isLimit = lowerCaseType == 'limit'
|
3826
3828
|
isBuy = side == 'buy'
|
3827
3829
|
defaultMethod = None
|
3828
|
-
if isTrailingAmountOrder or isStopLossTriggerOrder or isTakeProfitTriggerOrder:
|
3830
|
+
if (isTrailingAmountOrder or isStopLossTriggerOrder or isTakeProfitTriggerOrder) and not market['spot']:
|
3829
3831
|
defaultMethod = 'privatePostV5PositionTradingStop'
|
3830
3832
|
else:
|
3831
3833
|
defaultMethod = 'privatePostV5OrderCreate'
|
@@ -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')
|
ccxt/coinbase.py
CHANGED
@@ -13,6 +13,7 @@ from ccxt.base.errors import AuthenticationError
|
|
13
13
|
from ccxt.base.errors import PermissionDenied
|
14
14
|
from ccxt.base.errors import ArgumentsRequired
|
15
15
|
from ccxt.base.errors import BadRequest
|
16
|
+
from ccxt.base.errors import InsufficientFunds
|
16
17
|
from ccxt.base.errors import InvalidOrder
|
17
18
|
from ccxt.base.errors import OrderNotFound
|
18
19
|
from ccxt.base.errors import NotSupported
|
@@ -332,12 +333,14 @@ class coinbase(Exchange, ImplicitAPI):
|
|
332
333
|
'rate_limit_exceeded': RateLimitExceeded, # 429 Rate limit exceeded
|
333
334
|
'internal_server_error': ExchangeError, # 500 Internal server error
|
334
335
|
'UNSUPPORTED_ORDER_CONFIGURATION': BadRequest,
|
335
|
-
'INSUFFICIENT_FUND':
|
336
|
+
'INSUFFICIENT_FUND': InsufficientFunds,
|
336
337
|
'PERMISSION_DENIED': PermissionDenied,
|
337
338
|
'INVALID_ARGUMENT': BadRequest,
|
338
339
|
'PREVIEW_STOP_PRICE_ABOVE_LAST_TRADE_PRICE': InvalidOrder,
|
340
|
+
'PREVIEW_INSUFFICIENT_FUND': InsufficientFunds,
|
339
341
|
},
|
340
342
|
'broad': {
|
343
|
+
'Insufficient balance in source account': InsufficientFunds,
|
341
344
|
'request timestamp expired': InvalidNonce, # {"errors":[{"id":"authentication_error","message":"request timestamp expired"}]}
|
342
345
|
'order with self orderID was not found': OrderNotFound, # {"error":"unknown","error_details":"order with self orderID was not found","message":"order with self orderID was not found"}
|
343
346
|
},
|
ccxt/coinbaseexchange.py
CHANGED
@@ -39,31 +39,73 @@ class coinbaseexchange(Exchange, ImplicitAPI):
|
|
39
39
|
'swap': False,
|
40
40
|
'future': False,
|
41
41
|
'option': False,
|
42
|
+
'addMargin': False,
|
43
|
+
'borrowCrossMargin': False,
|
44
|
+
'borrowIsolatedMargin': False,
|
45
|
+
'borrowMargin': False,
|
42
46
|
'cancelAllOrders': True,
|
43
47
|
'cancelOrder': True,
|
48
|
+
'closeAllPositions': False,
|
49
|
+
'closePosition': False,
|
44
50
|
'createDepositAddress': True,
|
45
51
|
'createOrder': True,
|
52
|
+
'createOrderWithTakeProfitAndStopLoss': False,
|
53
|
+
'createOrderWithTakeProfitAndStopLossWs': False,
|
54
|
+
'createPostOnlyOrder': False,
|
46
55
|
'createReduceOnlyOrder': False,
|
47
56
|
'createStopLimitOrder': True,
|
48
57
|
'createStopMarketOrder': True,
|
49
58
|
'createStopOrder': True,
|
50
59
|
'fetchAccounts': True,
|
51
60
|
'fetchBalance': True,
|
61
|
+
'fetchBorrowInterest': False,
|
62
|
+
'fetchBorrowRate': False,
|
63
|
+
'fetchBorrowRateHistories': False,
|
64
|
+
'fetchBorrowRateHistory': False,
|
65
|
+
'fetchBorrowRates': False,
|
66
|
+
'fetchBorrowRatesPerSymbol': False,
|
52
67
|
'fetchClosedOrders': True,
|
68
|
+
'fetchCrossBorrowRate': False,
|
69
|
+
'fetchCrossBorrowRates': False,
|
53
70
|
'fetchCurrencies': True,
|
54
71
|
'fetchDepositAddress': False, # the exchange does not have self method, only createDepositAddress, see https://github.com/ccxt/ccxt/pull/7405
|
55
72
|
'fetchDeposits': True,
|
56
73
|
'fetchDepositsWithdrawals': True,
|
57
74
|
'fetchFundingHistory': False,
|
75
|
+
'fetchFundingInterval': False,
|
76
|
+
'fetchFundingIntervals': False,
|
58
77
|
'fetchFundingRate': False,
|
59
78
|
'fetchFundingRateHistory': False,
|
60
79
|
'fetchFundingRates': False,
|
80
|
+
'fetchGreeks': False,
|
81
|
+
'fetchIndexOHLCV': False,
|
82
|
+
'fetchIsolatedBorrowRate': False,
|
83
|
+
'fetchIsolatedBorrowRates': False,
|
84
|
+
'fetchIsolatedPositions': False,
|
61
85
|
'fetchLedger': True,
|
86
|
+
'fetchLeverage': False,
|
87
|
+
'fetchLeverages': False,
|
88
|
+
'fetchLeverageTiers': False,
|
89
|
+
'fetchLiquidations': False,
|
90
|
+
'fetchLongShortRatio': False,
|
91
|
+
'fetchLongShortRatioHistory': False,
|
92
|
+
'fetchMarginAdjustmentHistory': False,
|
62
93
|
'fetchMarginMode': False,
|
94
|
+
'fetchMarginModes': False,
|
95
|
+
'fetchMarketLeverageTiers': False,
|
63
96
|
'fetchMarkets': True,
|
97
|
+
'fetchMarkOHLCV': False,
|
98
|
+
'fetchMarkPrices': False,
|
99
|
+
'fetchMyLiquidations': False,
|
100
|
+
'fetchMySettlementHistory': False,
|
64
101
|
'fetchMyTrades': True,
|
65
102
|
'fetchOHLCV': True,
|
103
|
+
'fetchOpenInterest': False,
|
104
|
+
'fetchOpenInterestHistory': False,
|
105
|
+
'fetchOpenInterests': False,
|
66
106
|
'fetchOpenOrders': True,
|
107
|
+
'fetchOption': False,
|
108
|
+
'fetchOptionChain': False,
|
67
109
|
'fetchOrder': True,
|
68
110
|
'fetchOrderBook': True,
|
69
111
|
'fetchOrders': True,
|
@@ -75,6 +117,8 @@ class coinbaseexchange(Exchange, ImplicitAPI):
|
|
75
117
|
'fetchPositionsForSymbol': False,
|
76
118
|
'fetchPositionsHistory': False,
|
77
119
|
'fetchPositionsRisk': False,
|
120
|
+
'fetchPremiumIndexOHLCV': False,
|
121
|
+
'fetchSettlementHistory': False,
|
78
122
|
'fetchTicker': True,
|
79
123
|
'fetchTickers': True,
|
80
124
|
'fetchTime': True,
|
@@ -82,7 +126,16 @@ class coinbaseexchange(Exchange, ImplicitAPI):
|
|
82
126
|
'fetchTradingFee': False,
|
83
127
|
'fetchTradingFees': True,
|
84
128
|
'fetchTransactions': 'emulated',
|
129
|
+
'fetchVolatilityHistory': False,
|
85
130
|
'fetchWithdrawals': True,
|
131
|
+
'reduceMargin': False,
|
132
|
+
'repayCrossMargin': False,
|
133
|
+
'repayIsolatedMargin': False,
|
134
|
+
'repayMargin': False,
|
135
|
+
'setLeverage': False,
|
136
|
+
'setMargin': False,
|
137
|
+
'setMarginMode': False,
|
138
|
+
'setPositionMode': False,
|
86
139
|
'withdraw': True,
|
87
140
|
},
|
88
141
|
'timeframes': {
|
ccxt/coincheck.py
CHANGED
@@ -10,6 +10,7 @@ from ccxt.base.types import Any, Balances, Currency, Int, Market, Num, Order, Or
|
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
12
|
from ccxt.base.errors import AuthenticationError
|
13
|
+
from ccxt.base.errors import ArgumentsRequired
|
13
14
|
from ccxt.base.errors import BadSymbol
|
14
15
|
from ccxt.base.decimal_to_precision import TICK_SIZE
|
15
16
|
|
@@ -30,30 +31,59 @@ class coincheck(Exchange, ImplicitAPI):
|
|
30
31
|
'future': False,
|
31
32
|
'option': False,
|
32
33
|
'addMargin': False,
|
34
|
+
'borrowCrossMargin': False,
|
35
|
+
'borrowIsolatedMargin': False,
|
36
|
+
'borrowMargin': False,
|
33
37
|
'cancelOrder': True,
|
34
38
|
'closeAllPositions': False,
|
35
39
|
'closePosition': False,
|
36
40
|
'createOrder': True,
|
41
|
+
'createOrderWithTakeProfitAndStopLoss': False,
|
42
|
+
'createOrderWithTakeProfitAndStopLossWs': False,
|
43
|
+
'createPostOnlyOrder': False,
|
37
44
|
'createReduceOnlyOrder': False,
|
38
45
|
'fetchBalance': True,
|
46
|
+
'fetchBorrowInterest': False,
|
47
|
+
'fetchBorrowRate': False,
|
39
48
|
'fetchBorrowRateHistories': False,
|
40
49
|
'fetchBorrowRateHistory': False,
|
50
|
+
'fetchBorrowRates': False,
|
51
|
+
'fetchBorrowRatesPerSymbol': False,
|
41
52
|
'fetchCrossBorrowRate': False,
|
42
53
|
'fetchCrossBorrowRates': False,
|
43
54
|
'fetchDeposits': True,
|
44
55
|
'fetchFundingHistory': False,
|
56
|
+
'fetchFundingInterval': False,
|
57
|
+
'fetchFundingIntervals': False,
|
45
58
|
'fetchFundingRate': False,
|
46
59
|
'fetchFundingRateHistory': False,
|
47
60
|
'fetchFundingRates': False,
|
61
|
+
'fetchGreeks': False,
|
48
62
|
'fetchIndexOHLCV': False,
|
49
63
|
'fetchIsolatedBorrowRate': False,
|
50
64
|
'fetchIsolatedBorrowRates': False,
|
65
|
+
'fetchIsolatedPositions': False,
|
51
66
|
'fetchLeverage': False,
|
67
|
+
'fetchLeverages': False,
|
68
|
+
'fetchLeverageTiers': False,
|
69
|
+
'fetchLiquidations': False,
|
70
|
+
'fetchLongShortRatio': False,
|
71
|
+
'fetchLongShortRatioHistory': False,
|
72
|
+
'fetchMarginAdjustmentHistory': False,
|
52
73
|
'fetchMarginMode': False,
|
74
|
+
'fetchMarginModes': False,
|
75
|
+
'fetchMarketLeverageTiers': False,
|
53
76
|
'fetchMarkOHLCV': False,
|
77
|
+
'fetchMarkPrices': False,
|
78
|
+
'fetchMyLiquidations': False,
|
79
|
+
'fetchMySettlementHistory': False,
|
54
80
|
'fetchMyTrades': True,
|
81
|
+
'fetchOpenInterest': False,
|
55
82
|
'fetchOpenInterestHistory': False,
|
83
|
+
'fetchOpenInterests': False,
|
56
84
|
'fetchOpenOrders': True,
|
85
|
+
'fetchOption': False,
|
86
|
+
'fetchOptionChain': False,
|
57
87
|
'fetchOrderBook': True,
|
58
88
|
'fetchPosition': False,
|
59
89
|
'fetchPositionHistory': False,
|
@@ -63,13 +93,19 @@ class coincheck(Exchange, ImplicitAPI):
|
|
63
93
|
'fetchPositionsHistory': False,
|
64
94
|
'fetchPositionsRisk': False,
|
65
95
|
'fetchPremiumIndexOHLCV': False,
|
96
|
+
'fetchSettlementHistory': False,
|
66
97
|
'fetchTicker': True,
|
67
98
|
'fetchTrades': True,
|
68
99
|
'fetchTradingFee': False,
|
69
100
|
'fetchTradingFees': True,
|
101
|
+
'fetchVolatilityHistory': False,
|
70
102
|
'fetchWithdrawals': True,
|
71
103
|
'reduceMargin': False,
|
104
|
+
'repayCrossMargin': False,
|
105
|
+
'repayIsolatedMargin': False,
|
106
|
+
'repayMargin': False,
|
72
107
|
'setLeverage': False,
|
108
|
+
'setMargin': False,
|
73
109
|
'setMarginMode': False,
|
74
110
|
'setPositionMode': False,
|
75
111
|
'ws': True,
|
@@ -637,10 +673,15 @@ class coincheck(Exchange, ImplicitAPI):
|
|
637
673
|
'pair': market['id'],
|
638
674
|
}
|
639
675
|
if type == 'market':
|
640
|
-
order_type = type + '_' + side
|
641
|
-
|
642
|
-
|
643
|
-
|
676
|
+
request['order_type'] = type + '_' + side
|
677
|
+
if side == 'sell':
|
678
|
+
request['amount'] = amount
|
679
|
+
else:
|
680
|
+
cost = self.safe_number(params, 'cost')
|
681
|
+
params = self.omit(params, 'cost')
|
682
|
+
if cost is not None:
|
683
|
+
raise ArgumentsRequired(self.id + ' createOrder() : you should use "cost" parameter instead of "amount" argument to create market buy orders')
|
684
|
+
request['market_buy_amount'] = cost
|
644
685
|
else:
|
645
686
|
request['order_type'] = side
|
646
687
|
request['rate'] = price
|
ccxt/coinex.py
CHANGED
@@ -18,6 +18,7 @@ from ccxt.base.errors import InsufficientFunds
|
|
18
18
|
from ccxt.base.errors import InvalidOrder
|
19
19
|
from ccxt.base.errors import OrderNotFound
|
20
20
|
from ccxt.base.errors import NotSupported
|
21
|
+
from ccxt.base.errors import OperationFailed
|
21
22
|
from ccxt.base.errors import RateLimitExceeded
|
22
23
|
from ccxt.base.errors import ExchangeNotAvailable
|
23
24
|
from ccxt.base.errors import RequestTimeout
|
@@ -670,6 +671,7 @@ class coinex(Exchange, ImplicitAPI):
|
|
670
671
|
'broad': {
|
671
672
|
'ip not allow visit': PermissionDenied,
|
672
673
|
'service too busy': ExchangeNotAvailable,
|
674
|
+
'Service is not available during funding fee settlement': OperationFailed,
|
673
675
|
},
|
674
676
|
},
|
675
677
|
})
|
@@ -794,7 +796,7 @@ class coinex(Exchange, ImplicitAPI):
|
|
794
796
|
'max': None,
|
795
797
|
},
|
796
798
|
},
|
797
|
-
'networks':
|
799
|
+
'networks': networks,
|
798
800
|
'type': 'crypto',
|
799
801
|
'info': coin,
|
800
802
|
})
|
@@ -826,17 +828,19 @@ class coinex(Exchange, ImplicitAPI):
|
|
826
828
|
# "code": 0,
|
827
829
|
# "data": [
|
828
830
|
# {
|
829
|
-
# "
|
831
|
+
# "market": "BTCUSDT",
|
832
|
+
# "taker_fee_rate": "0.002",
|
833
|
+
# "maker_fee_rate": "0.002",
|
834
|
+
# "min_amount": "0.0005",
|
835
|
+
# "base_ccy": "BTC",
|
836
|
+
# "quote_ccy": "USDT",
|
830
837
|
# "base_ccy_precision": 8,
|
838
|
+
# "quote_ccy_precision": 2,
|
831
839
|
# "is_amm_available": True,
|
832
|
-
# "is_margin_available":
|
833
|
-
# "
|
834
|
-
# "
|
835
|
-
#
|
836
|
-
# "quote_ccy": "USDT",
|
837
|
-
# "quote_ccy_precision": 6,
|
838
|
-
# "taker_fee_rate": "0.003"
|
839
|
-
# },
|
840
|
+
# "is_margin_available": True,
|
841
|
+
# "is_pre_trading_available": True,
|
842
|
+
# "is_api_trading_available": True
|
843
|
+
# }
|
840
844
|
# ],
|
841
845
|
# "message": "OK"
|
842
846
|
# }
|
@@ -862,11 +866,11 @@ class coinex(Exchange, ImplicitAPI):
|
|
862
866
|
'settleId': None,
|
863
867
|
'type': 'spot',
|
864
868
|
'spot': True,
|
865
|
-
'margin':
|
869
|
+
'margin': self.safe_bool(market, 'is_margin_available'),
|
866
870
|
'swap': False,
|
867
871
|
'future': False,
|
868
872
|
'option': False,
|
869
|
-
'active':
|
873
|
+
'active': self.safe_bool(market, 'is_api_trading_available'),
|
870
874
|
'contract': False,
|
871
875
|
'linear': None,
|
872
876
|
'inverse': None,
|
ccxt/coinmetro.py
CHANGED
@@ -220,6 +220,7 @@ class coinmetro(Exchange, ImplicitAPI):
|
|
220
220
|
'options': {
|
221
221
|
'currenciesByIdForParseMarket': None,
|
222
222
|
'currencyIdsListForParseMarket': ['QRDO'],
|
223
|
+
'skippedMarkets': ['VXVUSDT'], # broken markets which do not have enough info in API
|
223
224
|
},
|
224
225
|
'features': {
|
225
226
|
'spot': {
|
@@ -439,9 +440,12 @@ class coinmetro(Exchange, ImplicitAPI):
|
|
439
440
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
440
441
|
:returns dict[]: an array of objects representing market data
|
441
442
|
"""
|
442
|
-
|
443
|
+
promises = []
|
444
|
+
promises.append(self.publicGetMarkets(params))
|
443
445
|
if self.safe_value(self.options, 'currenciesByIdForParseMarket') is None:
|
444
|
-
self.fetch_currencies()
|
446
|
+
promises.append(self.fetch_currencies())
|
447
|
+
responses = promises
|
448
|
+
response = responses[0]
|
445
449
|
#
|
446
450
|
# [
|
447
451
|
# {
|
@@ -457,7 +461,14 @@ class coinmetro(Exchange, ImplicitAPI):
|
|
457
461
|
# ...
|
458
462
|
# ]
|
459
463
|
#
|
460
|
-
|
464
|
+
skippedMarkets = self.safe_list(self.options, 'skippedMarkets', [])
|
465
|
+
result = []
|
466
|
+
for i in range(0, len(response)):
|
467
|
+
market = self.parse_market(response[i])
|
468
|
+
if self.in_array(market['id'], skippedMarkets):
|
469
|
+
continue
|
470
|
+
result.append(market)
|
471
|
+
return result
|
461
472
|
|
462
473
|
def parse_market(self, market: dict) -> Market:
|
463
474
|
id = self.safe_string(market, 'pair')
|
ccxt/cryptomus.py
CHANGED
@@ -367,66 +367,44 @@ class cryptomus(Exchange, ImplicitAPI):
|
|
367
367
|
# }
|
368
368
|
#
|
369
369
|
coins = self.safe_list(response, 'result')
|
370
|
+
groupedById = self.group_by(coins, 'currency_code')
|
371
|
+
keys = list(groupedById.keys())
|
370
372
|
result: dict = {}
|
371
|
-
for i in range(0, len(
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
'
|
382
|
-
'
|
383
|
-
'deposit': None,
|
384
|
-
'withdraw': None,
|
385
|
-
'fee': None,
|
373
|
+
for i in range(0, len(keys)):
|
374
|
+
id = keys[i]
|
375
|
+
code = self.safe_currency_code(id)
|
376
|
+
networks = {}
|
377
|
+
networkEntries = groupedById[id]
|
378
|
+
for j in range(0, len(networkEntries)):
|
379
|
+
networkEntry = networkEntries[j]
|
380
|
+
networkId = self.safe_string(networkEntry, 'network_code')
|
381
|
+
networkCode = self.network_id_to_code(networkId)
|
382
|
+
networks[networkCode] = {
|
383
|
+
'id': networkId,
|
384
|
+
'network': networkCode,
|
386
385
|
'limits': {
|
387
386
|
'withdraw': {
|
388
|
-
'min':
|
389
|
-
'max':
|
387
|
+
'min': self.safe_number(networkEntry, 'min_withdraw'),
|
388
|
+
'max': self.safe_number(networkEntry, 'max_withdraw'),
|
390
389
|
},
|
391
390
|
'deposit': {
|
392
|
-
'min':
|
393
|
-
'max':
|
391
|
+
'min': self.safe_number(networkEntry, 'min_deposit'),
|
392
|
+
'max': self.safe_number(networkEntry, 'max_deposit'),
|
394
393
|
},
|
395
394
|
},
|
396
|
-
'
|
397
|
-
'
|
395
|
+
'active': None,
|
396
|
+
'deposit': self.safe_bool(networkEntry, 'can_withdraw'),
|
397
|
+
'withdraw': self.safe_bool(networkEntry, 'can_deposit'),
|
398
|
+
'fee': None,
|
399
|
+
'precision': None,
|
400
|
+
'info': networkEntry,
|
398
401
|
}
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
'
|
403
|
-
'
|
404
|
-
|
405
|
-
'withdraw': {
|
406
|
-
'min': self.safe_number(networkEntry, 'min_withdraw'),
|
407
|
-
'max': self.safe_number(networkEntry, 'max_withdraw'),
|
408
|
-
},
|
409
|
-
'deposit': {
|
410
|
-
'min': self.safe_number(networkEntry, 'min_deposit'),
|
411
|
-
'max': self.safe_number(networkEntry, 'max_deposit'),
|
412
|
-
},
|
413
|
-
},
|
414
|
-
'active': None,
|
415
|
-
'deposit': self.safe_bool(networkEntry, 'can_withdraw'),
|
416
|
-
'withdraw': self.safe_bool(networkEntry, 'can_deposit'),
|
417
|
-
'fee': None,
|
418
|
-
'precision': None,
|
419
|
-
'info': networkEntry,
|
420
|
-
}
|
421
|
-
# add entry in info
|
422
|
-
info = self.safe_list(result[code], 'info', [])
|
423
|
-
info.append(networkEntry)
|
424
|
-
result[code]['info'] = info
|
425
|
-
# only after all entries are formed in currencies, restructure each entry
|
426
|
-
allKeys = list(result.keys())
|
427
|
-
for i in range(0, len(allKeys)):
|
428
|
-
code = allKeys[i]
|
429
|
-
result[code] = self.safe_currency_structure(result[code]) # self is needed after adding network entry
|
402
|
+
result[code] = self.safe_currency_structure({
|
403
|
+
'id': id,
|
404
|
+
'code': code,
|
405
|
+
'networks': networks,
|
406
|
+
'info': networkEntries,
|
407
|
+
})
|
430
408
|
return result
|
431
409
|
|
432
410
|
def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
ccxt/deribit.py
CHANGED
@@ -2596,21 +2596,21 @@ class deribit(Exchange, ImplicitAPI):
|
|
2596
2596
|
unrealizedPnl = self.safe_string(position, 'floating_profit_loss')
|
2597
2597
|
initialMarginString = self.safe_string(position, 'initial_margin')
|
2598
2598
|
notionalString = self.safe_string(position, 'size_currency')
|
2599
|
+
notionalStringAbs = Precise.string_abs(notionalString)
|
2599
2600
|
maintenanceMarginString = self.safe_string(position, 'maintenance_margin')
|
2600
|
-
currentTime = self.milliseconds()
|
2601
2601
|
return self.safe_position({
|
2602
2602
|
'info': position,
|
2603
2603
|
'id': None,
|
2604
2604
|
'symbol': self.safe_string(market, 'symbol'),
|
2605
|
-
'timestamp':
|
2606
|
-
'datetime':
|
2605
|
+
'timestamp': None,
|
2606
|
+
'datetime': None,
|
2607
2607
|
'lastUpdateTimestamp': None,
|
2608
2608
|
'initialMargin': self.parse_number(initialMarginString),
|
2609
|
-
'initialMarginPercentage': self.parse_number(Precise.string_mul(Precise.string_div(initialMarginString,
|
2609
|
+
'initialMarginPercentage': self.parse_number(Precise.string_mul(Precise.string_div(initialMarginString, notionalStringAbs), '100')),
|
2610
2610
|
'maintenanceMargin': self.parse_number(maintenanceMarginString),
|
2611
|
-
'maintenanceMarginPercentage': self.parse_number(Precise.string_mul(Precise.string_div(maintenanceMarginString,
|
2611
|
+
'maintenanceMarginPercentage': self.parse_number(Precise.string_mul(Precise.string_div(maintenanceMarginString, notionalStringAbs), '100')),
|
2612
2612
|
'entryPrice': self.safe_number(position, 'average_price'),
|
2613
|
-
'notional': self.parse_number(
|
2613
|
+
'notional': self.parse_number(notionalStringAbs),
|
2614
2614
|
'leverage': self.safe_integer(position, 'leverage'),
|
2615
2615
|
'unrealizedPnl': self.parse_number(unrealizedPnl),
|
2616
2616
|
'contracts': None,
|