ccxt 4.0.100__py2.py3-none-any.whl → 4.0.102__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 -3
- ccxt/abstract/binance.py +8 -0
- ccxt/abstract/binancecoinm.py +8 -0
- ccxt/abstract/binanceus.py +8 -0
- ccxt/abstract/binanceusdm.py +8 -0
- ccxt/abstract/bingx.py +16 -1
- ccxt/async_support/__init__.py +1 -3
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/binance.py +36 -1
- ccxt/async_support/bingx.py +41 -4
- ccxt/async_support/bitbank.py +11 -0
- ccxt/async_support/bitfinex.py +12 -8
- ccxt/async_support/bitflyer.py +39 -10
- ccxt/async_support/bitforex.py +0 -8
- ccxt/async_support/bitget.py +15 -5
- ccxt/async_support/bitmart.py +66 -0
- ccxt/async_support/bitstamp1.py +22 -0
- ccxt/async_support/bl3p.py +32 -0
- ccxt/async_support/bybit.py +120 -48
- ccxt/async_support/coinbasepro.py +11 -0
- ccxt/async_support/currencycom.py +1 -1
- ccxt/async_support/gemini.py +1 -0
- ccxt/async_support/huobi.py +1 -1
- ccxt/async_support/huobijp.py +1 -1
- ccxt/async_support/idex.py +1 -1
- ccxt/async_support/kucoinfutures.py +46 -51
- ccxt/async_support/lbank.py +1 -1
- ccxt/async_support/lbank2.py +1 -1
- ccxt/base/exchange.py +1 -1
- ccxt/binance.py +36 -1
- ccxt/bingx.py +41 -4
- ccxt/bitbank.py +11 -0
- ccxt/bitfinex.py +12 -8
- ccxt/bitflyer.py +39 -10
- ccxt/bitforex.py +0 -8
- ccxt/bitget.py +15 -5
- ccxt/bitmart.py +66 -0
- ccxt/bitstamp1.py +22 -0
- ccxt/bl3p.py +32 -0
- ccxt/bybit.py +120 -48
- ccxt/coinbasepro.py +11 -0
- ccxt/currencycom.py +1 -1
- ccxt/gemini.py +1 -0
- ccxt/huobi.py +1 -1
- ccxt/huobijp.py +1 -1
- ccxt/idex.py +1 -1
- ccxt/kucoinfutures.py +46 -51
- ccxt/lbank.py +1 -1
- ccxt/lbank2.py +1 -1
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +7 -7
- ccxt/pro/bybit.py +16 -16
- ccxt/pro/coinbasepro.py +10 -10
- ccxt/pro/huobijp.py +1 -2
- ccxt/pro/krakenfutures.py +7 -7
- ccxt/pro/kucoin.py +42 -2
- ccxt/pro/kucoinfutures.py +3 -3
- ccxt/pro/phemex.py +2 -2
- ccxt/test/test_async.py +1 -1
- ccxt/test/test_sync.py +1 -1
- {ccxt-4.0.100.dist-info → ccxt-4.0.102.dist-info}/METADATA +6 -7
- {ccxt-4.0.100.dist-info → ccxt-4.0.102.dist-info}/RECORD +64 -65
- ccxt/abstract/bkex.py +0 -58
- {ccxt-4.0.100.dist-info → ccxt-4.0.102.dist-info}/WHEEL +0 -0
- {ccxt-4.0.100.dist-info → ccxt-4.0.102.dist-info}/top_level.txt +0 -0
ccxt/async_support/bitmart.py
CHANGED
@@ -76,6 +76,9 @@ class bitmart(Exchange, ImplicitAPI):
|
|
76
76
|
'fetchDepositWithdrawFee': True,
|
77
77
|
'fetchDepositWithdrawFees': False,
|
78
78
|
'fetchFundingHistory': None,
|
79
|
+
'fetchFundingRate': True,
|
80
|
+
'fetchFundingRateHistory': False,
|
81
|
+
'fetchFundingRates': False,
|
79
82
|
'fetchMarginMode': False,
|
80
83
|
'fetchMarkets': True,
|
81
84
|
'fetchMyTrades': True,
|
@@ -3084,6 +3087,69 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3084
3087
|
}
|
3085
3088
|
return await self.privatePostContractPrivateSubmitLeverage(self.extend(request, params))
|
3086
3089
|
|
3090
|
+
async def fetch_funding_rate(self, symbol: str, params={}):
|
3091
|
+
"""
|
3092
|
+
fetch the current funding rate
|
3093
|
+
see https://developer-pro.bitmart.com/en/futures/#get-current-funding-rate
|
3094
|
+
:param str symbol: unified market symbol
|
3095
|
+
:param dict [params]: extra parameters specific to the bitmart api endpoint
|
3096
|
+
:returns dict: a `funding rate structure <https://github.com/ccxt/ccxt/wiki/Manual#funding-rate-structure>`
|
3097
|
+
"""
|
3098
|
+
await self.load_markets()
|
3099
|
+
market = self.market(symbol)
|
3100
|
+
if not market['swap']:
|
3101
|
+
raise BadSymbol(self.id + ' fetchFundingRate() supports swap contracts only')
|
3102
|
+
request = {
|
3103
|
+
'symbol': market['id'],
|
3104
|
+
}
|
3105
|
+
response = await self.publicGetContractPublicFundingRate(self.extend(request, params))
|
3106
|
+
#
|
3107
|
+
# {
|
3108
|
+
# "code": 1000,
|
3109
|
+
# "message": "Ok",
|
3110
|
+
# "data": {
|
3111
|
+
# "timestamp": 1695184410697,
|
3112
|
+
# "symbol": "BTCUSDT",
|
3113
|
+
# "rate_value": "-0.00002614",
|
3114
|
+
# "expected_rate": "-0.00002"
|
3115
|
+
# },
|
3116
|
+
# "trace": "4cad855074654097ac7ba5257c47305d.54.16951844206655589"
|
3117
|
+
# }
|
3118
|
+
#
|
3119
|
+
data = self.safe_value(response, 'data', {})
|
3120
|
+
return self.parse_funding_rate(data, market)
|
3121
|
+
|
3122
|
+
def parse_funding_rate(self, contract, market=None):
|
3123
|
+
#
|
3124
|
+
# {
|
3125
|
+
# "timestamp": 1695184410697,
|
3126
|
+
# "symbol": "BTCUSDT",
|
3127
|
+
# "rate_value": "-0.00002614",
|
3128
|
+
# "expected_rate": "-0.00002"
|
3129
|
+
# }
|
3130
|
+
#
|
3131
|
+
marketId = self.safe_string(contract, 'symbol')
|
3132
|
+
timestamp = self.safe_integer(contract, 'timestamp')
|
3133
|
+
return {
|
3134
|
+
'info': contract,
|
3135
|
+
'symbol': self.safe_symbol(marketId, market),
|
3136
|
+
'markPrice': None,
|
3137
|
+
'indexPrice': None,
|
3138
|
+
'interestRate': None,
|
3139
|
+
'estimatedSettlePrice': None,
|
3140
|
+
'timestamp': timestamp,
|
3141
|
+
'datetime': self.iso8601(timestamp),
|
3142
|
+
'fundingRate': self.safe_number(contract, 'expected_rate'),
|
3143
|
+
'fundingTimestamp': None,
|
3144
|
+
'fundingDatetime': None,
|
3145
|
+
'nextFundingRate': None,
|
3146
|
+
'nextFundingTimestamp': None,
|
3147
|
+
'nextFundingDatetime': None,
|
3148
|
+
'previousFundingRate': self.safe_number(contract, 'rate_value'),
|
3149
|
+
'previousFundingTimestamp': None,
|
3150
|
+
'previousFundingDatetime': None,
|
3151
|
+
}
|
3152
|
+
|
3087
3153
|
def nonce(self):
|
3088
3154
|
return self.milliseconds()
|
3089
3155
|
|
ccxt/async_support/bitstamp1.py
CHANGED
@@ -213,6 +213,17 @@ class bitstamp1(Exchange, ImplicitAPI):
|
|
213
213
|
return self.parse_ticker(ticker, market)
|
214
214
|
|
215
215
|
def parse_trade(self, trade, market=None):
|
216
|
+
#
|
217
|
+
# public trade
|
218
|
+
#
|
219
|
+
# {
|
220
|
+
# "amount": "0.00114000",
|
221
|
+
# "date": "1694287856",
|
222
|
+
# "price": "25865",
|
223
|
+
# "tid": 298730788,
|
224
|
+
# "type": 0
|
225
|
+
# }
|
226
|
+
#
|
216
227
|
timestamp = self.safe_timestamp_2(trade, 'date', 'datetime')
|
217
228
|
side = 'buy' if (trade['type'] == 0) else 'sell'
|
218
229
|
orderId = self.safe_string(trade, 'order_id')
|
@@ -254,6 +265,17 @@ class bitstamp1(Exchange, ImplicitAPI):
|
|
254
265
|
'time': 'minute',
|
255
266
|
}
|
256
267
|
response = await self.publicGetTransactions(self.extend(request, params))
|
268
|
+
#
|
269
|
+
# [
|
270
|
+
# {
|
271
|
+
# "amount": "0.00114000",
|
272
|
+
# "date": "1694287856",
|
273
|
+
# "price": "25865",
|
274
|
+
# "tid": 298730788,
|
275
|
+
# "type": 0
|
276
|
+
# },
|
277
|
+
# ]
|
278
|
+
#
|
257
279
|
return self.parse_trades(response, market, since, limit)
|
258
280
|
|
259
281
|
def parse_balance(self, response):
|
ccxt/async_support/bl3p.py
CHANGED
@@ -35,6 +35,9 @@ class bl3p(Exchange, ImplicitAPI):
|
|
35
35
|
'cancelOrder': True,
|
36
36
|
'createOrder': True,
|
37
37
|
'createReduceOnlyOrder': False,
|
38
|
+
'createStopLimitOrder': False,
|
39
|
+
'createStopMarketOrder': False,
|
40
|
+
'createStopOrder': False,
|
38
41
|
'fetchBalance': True,
|
39
42
|
'fetchBorrowRate': False,
|
40
43
|
'fetchBorrowRateHistories': False,
|
@@ -237,6 +240,16 @@ class bl3p(Exchange, ImplicitAPI):
|
|
237
240
|
return self.parse_ticker(ticker, market)
|
238
241
|
|
239
242
|
def parse_trade(self, trade, market=None):
|
243
|
+
#
|
244
|
+
# fetchTrades
|
245
|
+
#
|
246
|
+
# {
|
247
|
+
# "trade_id": "2518789",
|
248
|
+
# "date": "1694348697745",
|
249
|
+
# "amount_int": "2959153",
|
250
|
+
# "price_int": "2416231440"
|
251
|
+
# }
|
252
|
+
#
|
240
253
|
id = self.safe_string(trade, 'trade_id')
|
241
254
|
timestamp = self.safe_integer(trade, 'date')
|
242
255
|
price = self.safe_string(trade, 'price_int')
|
@@ -271,6 +284,20 @@ class bl3p(Exchange, ImplicitAPI):
|
|
271
284
|
response = await self.publicGetMarketTrades(self.extend({
|
272
285
|
'market': market['id'],
|
273
286
|
}, params))
|
287
|
+
#
|
288
|
+
# {
|
289
|
+
# "result": "success",
|
290
|
+
# "data": {
|
291
|
+
# "trades": [
|
292
|
+
# {
|
293
|
+
# "trade_id": "2518789",
|
294
|
+
# "date": "1694348697745",
|
295
|
+
# "amount_int": "2959153",
|
296
|
+
# "price_int": "2416231440"
|
297
|
+
# },
|
298
|
+
# ]
|
299
|
+
# }
|
300
|
+
# }
|
274
301
|
result = self.parse_trades(response['data']['trades'], market, since, limit)
|
275
302
|
return result
|
276
303
|
|
@@ -329,12 +356,17 @@ class bl3p(Exchange, ImplicitAPI):
|
|
329
356
|
async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
|
330
357
|
"""
|
331
358
|
create a trade order
|
359
|
+
see https://github.com/BitonicNL/bl3p-api/blob/master/examples/nodejs/example.md#21---create-an-order
|
332
360
|
:param str symbol: unified symbol of the market to create an order in
|
333
361
|
:param str type: 'market' or 'limit'
|
334
362
|
:param str side: 'buy' or 'sell'
|
335
363
|
:param float amount: how much of currency you want to trade in units of base currency
|
336
364
|
:param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
337
365
|
:param dict [params]: extra parameters specific to the bl3p api endpoint
|
366
|
+
*
|
367
|
+
* EXCHANGE SPECIFIC PARAMETERS
|
368
|
+
:param int [params.amount_funds]: maximal EUR amount to spend(*1e5)
|
369
|
+
:param str [params.fee_currency]: 'EUR' or 'BTC'
|
338
370
|
:returns dict: an `order structure <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
|
339
371
|
"""
|
340
372
|
market = self.market(symbol)
|
ccxt/async_support/bybit.py
CHANGED
@@ -742,7 +742,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
742
742
|
'110023': InvalidOrder, # This contract only supports position reduction operation, please contact customer service for details
|
743
743
|
'110024': InvalidOrder, # You have an existing position, so position mode cannot be switched
|
744
744
|
'110025': InvalidOrder, # Position mode is not modified
|
745
|
-
'110026':
|
745
|
+
'110026': BadRequest, # Cross/isolated margin mode is not modified
|
746
746
|
'110027': InvalidOrder, # Margin is not modified
|
747
747
|
'110028': InvalidOrder, # Open orders exist, so you cannot change position mode
|
748
748
|
'110029': InvalidOrder, # Hedge mode is not available for self symbol
|
@@ -2338,26 +2338,27 @@ class bybit(Exchange, ImplicitAPI):
|
|
2338
2338
|
if limit is not None:
|
2339
2339
|
request['limit'] = limit # max 1000, default 1000
|
2340
2340
|
request['interval'] = self.safe_string(self.timeframes, timeframe, timeframe)
|
2341
|
-
|
2341
|
+
response = None
|
2342
2342
|
if market['spot']:
|
2343
2343
|
request['category'] = 'spot'
|
2344
|
-
|
2344
|
+
response = await self.publicGetV5MarketKline(self.extend(request, params))
|
2345
2345
|
else:
|
2346
2346
|
price = self.safe_string(params, 'price')
|
2347
2347
|
params = self.omit(params, 'price')
|
2348
|
-
methods = {
|
2349
|
-
'mark': 'publicGetV5MarketMarkPriceKline',
|
2350
|
-
'index': 'publicGetV5MarketIndexPriceKline',
|
2351
|
-
'premiumIndex': 'publicGetV5MarketPremiumIndexPriceKline',
|
2352
|
-
}
|
2353
|
-
method = self.safe_value(methods, price, 'publicGetV5MarketKline')
|
2354
2348
|
if market['linear']:
|
2355
2349
|
request['category'] = 'linear'
|
2356
2350
|
elif market['inverse']:
|
2357
2351
|
request['category'] = 'inverse'
|
2358
2352
|
else:
|
2359
2353
|
raise NotSupported(self.id + ' fetchOHLCV() is not supported for option markets')
|
2360
|
-
|
2354
|
+
if price == 'mark':
|
2355
|
+
response = await self.publicGetV5MarketMarkPriceKline(self.extend(request, params))
|
2356
|
+
elif price == 'index':
|
2357
|
+
response = await self.publicGetV5MarketIndexPriceKline(self.extend(request, params))
|
2358
|
+
elif price == 'premiumIndex':
|
2359
|
+
response = await self.publicGetV5MarketPremiumIndexPriceKline(self.extend(request, params))
|
2360
|
+
else:
|
2361
|
+
response = await self.publicGetV5MarketKline(self.extend(request, params))
|
2361
2362
|
#
|
2362
2363
|
# {
|
2363
2364
|
# "retCode": 0,
|
@@ -3459,6 +3460,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
3459
3460
|
:param boolean [params.isLeverage]: *unified spot only* False then spot trading True then margin trading
|
3460
3461
|
:param str [params.tpslMode]: *contract only* 'full' or 'partial'
|
3461
3462
|
:param str [params.mmp]: *option only* market maker protection
|
3463
|
+
:param int [params.triggerDirection]: *contract only* conditional orders, 1: triggered when market price rises to triggerPrice, 2: triggered when market price falls to triggerPrice
|
3462
3464
|
:returns dict: an `order structure <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
|
3463
3465
|
"""
|
3464
3466
|
await self.load_markets()
|
@@ -3549,7 +3551,6 @@ class bybit(Exchange, ImplicitAPI):
|
|
3549
3551
|
isBuy = side == 'buy'
|
3550
3552
|
ascending = not isBuy if stopLossTriggerPrice else isBuy
|
3551
3553
|
if triggerPrice is not None:
|
3552
|
-
request['triggerDirection'] = 2 if ascending else 1
|
3553
3554
|
request['triggerPrice'] = self.price_to_precision(symbol, triggerPrice)
|
3554
3555
|
elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
|
3555
3556
|
request['triggerDirection'] = 2 if ascending else 1
|
@@ -3558,11 +3559,11 @@ class bybit(Exchange, ImplicitAPI):
|
|
3558
3559
|
request['reduceOnly'] = True
|
3559
3560
|
elif isStopLoss or isTakeProfit:
|
3560
3561
|
if isStopLoss:
|
3561
|
-
|
3562
|
-
request['stopLoss'] = self.price_to_precision(symbol,
|
3562
|
+
slTriggerPrice = self.safe_value_2(stopLoss, 'triggerPrice', 'stopPrice', stopLoss)
|
3563
|
+
request['stopLoss'] = self.price_to_precision(symbol, slTriggerPrice)
|
3563
3564
|
if isTakeProfit:
|
3564
|
-
|
3565
|
-
request['takeProfit'] = self.price_to_precision(symbol,
|
3565
|
+
tpTriggerPrice = self.safe_value_2(takeProfit, 'triggerPrice', 'stopPrice', takeProfit)
|
3566
|
+
request['takeProfit'] = self.price_to_precision(symbol, tpTriggerPrice)
|
3566
3567
|
if market['spot']:
|
3567
3568
|
# only works for spot market
|
3568
3569
|
if triggerPrice is not None:
|
@@ -3656,11 +3657,11 @@ class bybit(Exchange, ImplicitAPI):
|
|
3656
3657
|
request['basePrice'] = Precise.string_sub(preciseStopPrice, delta) if isStopLossTriggerOrder else Precise.string_add(preciseStopPrice, delta)
|
3657
3658
|
elif isStopLoss or isTakeProfit:
|
3658
3659
|
if isStopLoss:
|
3659
|
-
|
3660
|
-
request['stopLoss'] = self.price_to_precision(symbol,
|
3660
|
+
slTriggerPrice = self.safe_value_2(stopLoss, 'triggerPrice', 'stopPrice', stopLoss)
|
3661
|
+
request['stopLoss'] = self.price_to_precision(symbol, slTriggerPrice)
|
3661
3662
|
if isTakeProfit:
|
3662
|
-
|
3663
|
-
request['takeProfit'] = self.price_to_precision(symbol,
|
3663
|
+
tpTriggerPrice = self.safe_value_2(takeProfit, 'triggerPrice', 'stopPrice', takeProfit)
|
3664
|
+
request['takeProfit'] = self.price_to_precision(symbol, tpTriggerPrice)
|
3664
3665
|
else:
|
3665
3666
|
request['orderFilter'] = 'Order'
|
3666
3667
|
clientOrderId = self.safe_string(params, 'clientOrderId')
|
@@ -3670,8 +3671,11 @@ class bybit(Exchange, ImplicitAPI):
|
|
3670
3671
|
# mandatory field for options
|
3671
3672
|
request['orderLinkId'] = self.uuid16()
|
3672
3673
|
params = self.omit(params, ['stopPrice', 'timeInForce', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'clientOrderId'])
|
3673
|
-
|
3674
|
-
|
3674
|
+
response = None
|
3675
|
+
if market['option']:
|
3676
|
+
response = await self.privatePostOptionUsdcOpenapiPrivateV1PlaceOrder(self.extend(request, params))
|
3677
|
+
else:
|
3678
|
+
response = await self.privatePostPerpetualUsdcOpenapiPrivateV1PlaceOrder(self.extend(request, params))
|
3675
3679
|
#
|
3676
3680
|
# {
|
3677
3681
|
# "retCode":0,
|
@@ -3711,11 +3715,10 @@ class bybit(Exchange, ImplicitAPI):
|
|
3711
3715
|
request['orderQty'] = self.amount_to_precision(symbol, amount)
|
3712
3716
|
if price is not None:
|
3713
3717
|
request['orderPrice'] = self.price_to_precision(symbol, price)
|
3714
|
-
|
3718
|
+
response = None
|
3715
3719
|
if market['option']:
|
3716
|
-
|
3720
|
+
response = await self.privatePostOptionUsdcOpenapiPrivateV1ReplaceOrder(self.extend(request, params))
|
3717
3721
|
else:
|
3718
|
-
method = 'privatePostPerpetualUsdcOpenapiPrivateV1ReplaceOrder'
|
3719
3722
|
isStop = self.safe_value(params, 'stop', False)
|
3720
3723
|
triggerPrice = self.safe_value_2(params, 'stopPrice', 'triggerPrice')
|
3721
3724
|
stopLossPrice = self.safe_value(params, 'stopLossPrice')
|
@@ -3732,7 +3735,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
3732
3735
|
if takeProfitPrice is not None:
|
3733
3736
|
request['takeProfit'] = self.price_to_precision(symbol, takeProfitPrice)
|
3734
3737
|
params = self.omit(params, ['stop', 'stopPrice', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice'])
|
3735
|
-
|
3738
|
+
response = await self.privatePostPerpetualUsdcOpenapiPrivateV1ReplaceOrder(self.extend(request, params))
|
3736
3739
|
#
|
3737
3740
|
# {
|
3738
3741
|
# "retCode": 0,
|
@@ -3812,11 +3815,11 @@ class bybit(Exchange, ImplicitAPI):
|
|
3812
3815
|
request['triggerPrice'] = self.price_to_precision(symbol, triggerPrice)
|
3813
3816
|
if isStopLoss or isTakeProfit:
|
3814
3817
|
if isStopLoss:
|
3815
|
-
|
3816
|
-
request['stopLoss'] = self.price_to_precision(symbol,
|
3818
|
+
slTriggerPrice = self.safe_value_2(stopLoss, 'triggerPrice', 'stopPrice', stopLoss)
|
3819
|
+
request['stopLoss'] = self.price_to_precision(symbol, slTriggerPrice)
|
3817
3820
|
if isTakeProfit:
|
3818
|
-
|
3819
|
-
request['takeProfit'] = self.price_to_precision(symbol,
|
3821
|
+
tpTriggerPrice = self.safe_value_2(takeProfit, 'triggerPrice', 'stopPrice', takeProfit)
|
3822
|
+
request['takeProfit'] = self.price_to_precision(symbol, tpTriggerPrice)
|
3820
3823
|
clientOrderId = self.safe_string(params, 'clientOrderId')
|
3821
3824
|
if clientOrderId is not None:
|
3822
3825
|
request['orderLinkId'] = clientOrderId
|
@@ -3851,15 +3854,14 @@ class bybit(Exchange, ImplicitAPI):
|
|
3851
3854
|
}
|
3852
3855
|
isStop = self.safe_value(params, 'stop', False)
|
3853
3856
|
params = self.omit(params, ['stop'])
|
3854
|
-
method = None
|
3855
3857
|
if id is not None: # The user can also use argument params["order_link_id"]
|
3856
3858
|
request['orderId'] = id
|
3859
|
+
response = None
|
3857
3860
|
if market['option']:
|
3858
|
-
|
3861
|
+
response = await self.privatePostOptionUsdcOpenapiPrivateV1CancelOrder(self.extend(request, params))
|
3859
3862
|
else:
|
3860
|
-
method = 'privatePostPerpetualUsdcOpenapiPrivateV1CancelOrder'
|
3861
3863
|
request['orderFilter'] = 'StopOrder' if isStop else 'Order'
|
3862
|
-
|
3864
|
+
response = await self.privatePostPerpetualUsdcOpenapiPrivateV1CancelOrder(self.extend(request, params))
|
3863
3865
|
#
|
3864
3866
|
# {
|
3865
3867
|
# "retCode": 0,
|
@@ -4937,13 +4939,16 @@ class bybit(Exchange, ImplicitAPI):
|
|
4937
4939
|
else:
|
4938
4940
|
if since is not None:
|
4939
4941
|
request['start_date'] = self.yyyymmdd(since)
|
4940
|
-
method = 'privateGetV5AccountTransactionLog' if (enableUnified[1]) else 'privateGetV2PrivateWalletFundRecords'
|
4941
4942
|
if code is not None:
|
4942
4943
|
currency = self.currency(code)
|
4943
4944
|
request[currencyKey] = currency['id']
|
4944
4945
|
if limit is not None:
|
4945
4946
|
request['limit'] = limit
|
4946
|
-
response =
|
4947
|
+
response = None
|
4948
|
+
if enableUnified[1]:
|
4949
|
+
response = await self.privateGetV5AccountTransactionLog(self.extend(request, params))
|
4950
|
+
else:
|
4951
|
+
response = await self.privateGetV2PrivateWalletFundRecords(self.extend(request, params))
|
4947
4952
|
#
|
4948
4953
|
# {
|
4949
4954
|
# "ret_code": 0,
|
@@ -5624,18 +5629,85 @@ class bybit(Exchange, ImplicitAPI):
|
|
5624
5629
|
})
|
5625
5630
|
|
5626
5631
|
async def set_margin_mode(self, marginMode, symbol: Optional[str] = None, params={}):
|
5632
|
+
"""
|
5633
|
+
set margin mode(account) or trade mode(symbol)
|
5634
|
+
see https://bybit-exchange.github.io/docs/v5/account/set-margin-mode
|
5635
|
+
see https://bybit-exchange.github.io/docs/v5/position/cross-isolate
|
5636
|
+
:param str marginMode: account mode must be either [isolated, cross, portfolio], trade mode must be either [isolated, cross]
|
5637
|
+
:param str symbol: unified market symbol of the market the position is held in, default is None
|
5638
|
+
:param dict [params]: extra parameters specific to the bybit api endpoint
|
5639
|
+
:param str [params.leverage]: the rate of leverage, is required if setting trade mode(symbol)
|
5640
|
+
:returns dict: response from the exchange
|
5641
|
+
"""
|
5627
5642
|
await self.load_markets()
|
5628
5643
|
enableUnifiedMargin, enableUnifiedAccount = await self.is_unified_enabled()
|
5629
5644
|
isUnifiedAccount = (enableUnifiedMargin or enableUnifiedAccount)
|
5630
|
-
|
5631
|
-
|
5632
|
-
|
5633
|
-
|
5634
|
-
|
5635
|
-
|
5636
|
-
|
5637
|
-
|
5638
|
-
|
5645
|
+
market = None
|
5646
|
+
response = None
|
5647
|
+
if isUnifiedAccount:
|
5648
|
+
if marginMode == 'isolated':
|
5649
|
+
marginMode = 'ISOLATED_MARGIN'
|
5650
|
+
elif marginMode == 'cross':
|
5651
|
+
marginMode = 'REGULAR_MARGIN'
|
5652
|
+
elif marginMode == 'portfolio':
|
5653
|
+
marginMode = 'PORTFOLIO_MARGIN'
|
5654
|
+
else:
|
5655
|
+
raise NotSupported(self.id + ' setMarginMode() marginMode must be either [isolated, cross, portfolio]')
|
5656
|
+
request = {
|
5657
|
+
'setMarginMode': marginMode,
|
5658
|
+
}
|
5659
|
+
response = await self.privatePostV5AccountSetMarginMode(self.extend(request, params))
|
5660
|
+
else:
|
5661
|
+
if symbol is None:
|
5662
|
+
raise ArgumentsRequired(self.id + ' setMarginMode() requires a symbol parameter for non unified account')
|
5663
|
+
market = self.market(symbol)
|
5664
|
+
isUsdcSettled = market['settle'] == 'USDC'
|
5665
|
+
if isUsdcSettled:
|
5666
|
+
if marginMode == 'cross':
|
5667
|
+
marginMode = 'REGULAR_MARGIN'
|
5668
|
+
elif marginMode == 'portfolio':
|
5669
|
+
marginMode = 'PORTFOLIO_MARGIN'
|
5670
|
+
else:
|
5671
|
+
raise NotSupported(self.id + ' setMarginMode() for usdc market marginMode must be either [cross, portfolio]')
|
5672
|
+
request = {
|
5673
|
+
'setMarginMode': marginMode,
|
5674
|
+
}
|
5675
|
+
response = await self.privatePostV5AccountSetMarginMode(self.extend(request, params))
|
5676
|
+
else:
|
5677
|
+
type = None
|
5678
|
+
type, params = self.get_bybit_type('setPositionMode', market, params)
|
5679
|
+
tradeMode = None
|
5680
|
+
if marginMode == 'cross':
|
5681
|
+
tradeMode = 0
|
5682
|
+
elif marginMode == 'isolated':
|
5683
|
+
tradeMode = 1
|
5684
|
+
else:
|
5685
|
+
raise NotSupported(self.id + ' setMarginMode() with symbol marginMode must be either [isolated, cross]')
|
5686
|
+
sellLeverage = None
|
5687
|
+
buyLeverage = None
|
5688
|
+
leverage = self.safe_string(params, 'leverage')
|
5689
|
+
if leverage is None:
|
5690
|
+
sellLeverage = self.safe_string_2(params, 'sell_leverage', 'sellLeverage')
|
5691
|
+
buyLeverage = self.safe_string_2(params, 'buy_leverage', 'buyLeverage')
|
5692
|
+
if sellLeverage is None and buyLeverage is None:
|
5693
|
+
raise ArgumentsRequired(self.id + ' setMarginMode() requires a leverage parameter or sell_leverage and buy_leverage parameters')
|
5694
|
+
if buyLeverage is None:
|
5695
|
+
buyLeverage = sellLeverage
|
5696
|
+
if sellLeverage is None:
|
5697
|
+
sellLeverage = buyLeverage
|
5698
|
+
params = self.omit(params, ['buy_leverage', 'sell_leverage', 'sellLeverage', 'buyLeverage'])
|
5699
|
+
else:
|
5700
|
+
sellLeverage = leverage
|
5701
|
+
buyLeverage = leverage
|
5702
|
+
params = self.omit(params, 'leverage')
|
5703
|
+
request = {
|
5704
|
+
'category': type,
|
5705
|
+
'symbol': market['id'],
|
5706
|
+
'tradeMode': tradeMode,
|
5707
|
+
'buyLeverage': buyLeverage,
|
5708
|
+
'sellLeverage': sellLeverage,
|
5709
|
+
}
|
5710
|
+
response = await self.privatePostV5PositionSwitchIsolated(self.extend(request, params))
|
5639
5711
|
return response
|
5640
5712
|
|
5641
5713
|
async def set_leverage(self, leverage, symbol: Optional[str] = None, params={}):
|
@@ -5665,21 +5737,21 @@ class bybit(Exchange, ImplicitAPI):
|
|
5665
5737
|
'buyLeverage': leverage,
|
5666
5738
|
'sellLeverage': leverage,
|
5667
5739
|
}
|
5668
|
-
|
5740
|
+
response = None
|
5669
5741
|
if isUsdcSettled and not isUnifiedAccount:
|
5670
5742
|
request['leverage'] = leverage
|
5671
|
-
|
5743
|
+
response = await self.privatePostPerpetualUsdcOpenapiPrivateV1PositionLeverageSave(self.extend(request, params))
|
5672
5744
|
else:
|
5673
5745
|
request['buyLeverage'] = leverage
|
5674
5746
|
request['sellLeverage'] = leverage
|
5675
|
-
method = 'privatePostV5PositionSetLeverage'
|
5676
5747
|
if market['linear']:
|
5677
5748
|
request['category'] = 'linear'
|
5678
5749
|
elif market['inverse']:
|
5679
5750
|
request['category'] = 'inverse'
|
5680
5751
|
else:
|
5681
5752
|
raise NotSupported(self.id + ' setLeverage() only support linear and inverse market')
|
5682
|
-
|
5753
|
+
response = await self.privatePostV5PositionSetLeverage(self.extend(request, params))
|
5754
|
+
return response
|
5683
5755
|
|
5684
5756
|
async def set_position_mode(self, hedged, symbol: Optional[str] = None, params={}):
|
5685
5757
|
"""
|
@@ -799,6 +799,17 @@ class coinbasepro(Exchange, ImplicitAPI):
|
|
799
799
|
if limit is not None:
|
800
800
|
request['limit'] = limit # default 100
|
801
801
|
response = await self.publicGetProductsIdTrades(self.extend(request, params))
|
802
|
+
#
|
803
|
+
# [
|
804
|
+
# {
|
805
|
+
# "trade_id": "15035219",
|
806
|
+
# "side": "sell",
|
807
|
+
# "size": "0.27426731",
|
808
|
+
# "price": "25820.42000000",
|
809
|
+
# "time": "2023-09-10T13:47:41.447577Z"
|
810
|
+
# },
|
811
|
+
# ]
|
812
|
+
#
|
802
813
|
return self.parse_trades(response, market, since, limit)
|
803
814
|
|
804
815
|
async def fetch_trading_fees(self, params={}):
|
@@ -1054,7 +1054,7 @@ class currencycom(Exchange, ImplicitAPI):
|
|
1054
1054
|
# 'limit': 500, # default 500, max 1000
|
1055
1055
|
}
|
1056
1056
|
if limit is not None:
|
1057
|
-
request['limit'] = limit # default 500, max 1000
|
1057
|
+
request['limit'] = min(limit, 1000) # default 500, max 1000
|
1058
1058
|
if since is not None:
|
1059
1059
|
request['startTime'] = since
|
1060
1060
|
response = await self.publicGetV2AggTrades(self.extend(request, params))
|
ccxt/async_support/gemini.py
CHANGED
@@ -238,6 +238,7 @@ class gemini(Exchange, ImplicitAPI):
|
|
238
238
|
'InsufficientFunds': InsufficientFunds, # The order was rejected because of insufficient funds
|
239
239
|
'InvalidJson': BadRequest, # The JSON provided is invalid
|
240
240
|
'InvalidNonce': InvalidNonce, # The nonce was not greater than the previously used nonce, or was not present
|
241
|
+
'InvalidApiKey': AuthenticationError, # Invalid API key
|
241
242
|
'InvalidOrderType': InvalidOrder, # An unknown order type was provided
|
242
243
|
'InvalidPrice': InvalidOrder, # For new orders, the price was invalid
|
243
244
|
'InvalidQuantity': InvalidOrder, # A negative or otherwise invalid quantity was specified
|
ccxt/async_support/huobi.py
CHANGED
@@ -2446,7 +2446,7 @@ class huobi(Exchange, ImplicitAPI):
|
|
2446
2446
|
fieldName = 'contract_code'
|
2447
2447
|
request[fieldName] = market['id']
|
2448
2448
|
if limit is not None:
|
2449
|
-
request['size'] = limit # max 2000
|
2449
|
+
request['size'] = min(limit, 2000) # max 2000
|
2450
2450
|
response = await getattr(self, method)(self.extend(request, params))
|
2451
2451
|
#
|
2452
2452
|
# {
|
ccxt/async_support/huobijp.py
CHANGED
@@ -850,7 +850,7 @@ class huobijp(Exchange, ImplicitAPI):
|
|
850
850
|
'symbol': market['id'],
|
851
851
|
}
|
852
852
|
if limit is not None:
|
853
|
-
request['size'] = limit
|
853
|
+
request['size'] = min(limit, 2000)
|
854
854
|
response = await self.marketGetHistoryTrade(self.extend(request, params))
|
855
855
|
#
|
856
856
|
# {
|
ccxt/async_support/idex.py
CHANGED
@@ -504,7 +504,7 @@ class idex(Exchange, ImplicitAPI):
|
|
504
504
|
if since is not None:
|
505
505
|
request['start'] = since
|
506
506
|
if limit is not None:
|
507
|
-
request['limit'] = limit
|
507
|
+
request['limit'] = min(limit, 1000)
|
508
508
|
# [
|
509
509
|
# {
|
510
510
|
# fillId: 'b5467d00-b13e-3fa9-8216-dd66735550fc',
|