ccxt 4.2.21__py2.py3-none-any.whl → 4.2.22__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.
Potentially problematic release.
This version of ccxt might be problematic. Click here for more details.
- ccxt/__init__.py +1 -1
- ccxt/abstract/binance.py +3 -0
- ccxt/abstract/binancecoinm.py +3 -0
- ccxt/abstract/binanceus.py +16 -12
- ccxt/abstract/binanceusdm.py +3 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/bigone.py +1 -0
- ccxt/async_support/binance.py +14 -3
- ccxt/async_support/bitget.py +11 -1
- ccxt/async_support/bitrue.py +1 -0
- ccxt/async_support/bybit.py +49 -10
- ccxt/async_support/coinbasepro.py +1 -0
- ccxt/async_support/coinex.py +34 -12
- ccxt/async_support/deribit.py +145 -0
- ccxt/async_support/okcoin.py +3 -0
- ccxt/async_support/phemex.py +5 -2
- ccxt/async_support/poloniex.py +1 -0
- ccxt/async_support/woo.py +1 -1
- ccxt/base/exchange.py +1 -1
- ccxt/bigone.py +1 -0
- ccxt/binance.py +14 -3
- ccxt/bitget.py +11 -1
- ccxt/bitrue.py +1 -0
- ccxt/bybit.py +49 -10
- ccxt/coinbasepro.py +1 -0
- ccxt/coinex.py +34 -12
- ccxt/deribit.py +145 -0
- ccxt/okcoin.py +3 -0
- ccxt/phemex.py +5 -2
- ccxt/poloniex.py +1 -0
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bequant.py +7 -1
- ccxt/pro/binance.py +7 -4
- ccxt/pro/binancecoinm.py +7 -1
- ccxt/pro/binanceus.py +7 -1
- ccxt/pro/bitcoincom.py +7 -1
- ccxt/pro/bitget.py +1 -1
- ccxt/pro/bitrue.py +5 -1
- ccxt/pro/okx.py +10 -2
- ccxt/test/test_async.py +14 -1
- ccxt/test/test_sync.py +14 -1
- ccxt/woo.py +1 -1
- {ccxt-4.2.21.dist-info → ccxt-4.2.22.dist-info}/METADATA +4 -4
- {ccxt-4.2.21.dist-info → ccxt-4.2.22.dist-info}/RECORD +47 -47
- {ccxt-4.2.21.dist-info → ccxt-4.2.22.dist-info}/WHEEL +0 -0
- {ccxt-4.2.21.dist-info → ccxt-4.2.22.dist-info}/top_level.txt +0 -0
ccxt/async_support/deribit.py
CHANGED
@@ -415,6 +415,151 @@ class deribit(Exchange, ImplicitAPI):
|
|
415
415
|
},
|
416
416
|
})
|
417
417
|
|
418
|
+
def convert_expire_date(self, date):
|
419
|
+
# parse YYMMDD to timestamp
|
420
|
+
year = date[0:2]
|
421
|
+
month = date[2:4]
|
422
|
+
day = date[4:6]
|
423
|
+
reconstructedDate = '20' + year + '-' + month + '-' + day + 'T00:00:00Z'
|
424
|
+
return reconstructedDate
|
425
|
+
|
426
|
+
def convert_market_id_expire_date(self, date):
|
427
|
+
# parse 19JAN24 to 240119
|
428
|
+
monthMappping = {
|
429
|
+
'JAN': '01',
|
430
|
+
'FEB': '02',
|
431
|
+
'MAR': '03',
|
432
|
+
'APR': '04',
|
433
|
+
'MAY': '05',
|
434
|
+
'JUN': '06',
|
435
|
+
'JUL': '07',
|
436
|
+
'AUG': '08',
|
437
|
+
'SEP': '09',
|
438
|
+
'OCT': '10',
|
439
|
+
'NOV': '11',
|
440
|
+
'DEC': '12',
|
441
|
+
}
|
442
|
+
year = date[0:2]
|
443
|
+
monthName = date[2:5]
|
444
|
+
month = self.safe_string(monthMappping, monthName)
|
445
|
+
day = date[5:7]
|
446
|
+
reconstructedDate = day + month + year
|
447
|
+
return reconstructedDate
|
448
|
+
|
449
|
+
def convert_expire_date_to_market_id_date(self, date):
|
450
|
+
# parse 240119 to 19JAN24
|
451
|
+
year = date[0:2]
|
452
|
+
monthRaw = date[2:4]
|
453
|
+
month = None
|
454
|
+
day = date[4:6]
|
455
|
+
if monthRaw == '01':
|
456
|
+
month = 'JAN'
|
457
|
+
elif monthRaw == '02':
|
458
|
+
month = 'FEB'
|
459
|
+
elif monthRaw == '03':
|
460
|
+
month = 'MAR'
|
461
|
+
elif monthRaw == '04':
|
462
|
+
month = 'APR'
|
463
|
+
elif monthRaw == '05':
|
464
|
+
month = 'MAY'
|
465
|
+
elif monthRaw == '06':
|
466
|
+
month = 'JUN'
|
467
|
+
elif monthRaw == '07':
|
468
|
+
month = 'JUL'
|
469
|
+
elif monthRaw == '08':
|
470
|
+
month = 'AUG'
|
471
|
+
elif monthRaw == '09':
|
472
|
+
month = 'SEP'
|
473
|
+
elif monthRaw == '10':
|
474
|
+
month = 'OCT'
|
475
|
+
elif monthRaw == '11':
|
476
|
+
month = 'NOV'
|
477
|
+
elif monthRaw == '12':
|
478
|
+
month = 'DEC'
|
479
|
+
reconstructedDate = day + month + year
|
480
|
+
return reconstructedDate
|
481
|
+
|
482
|
+
def create_expired_option_market(self, symbol):
|
483
|
+
# support expired option contracts
|
484
|
+
quote = 'USD'
|
485
|
+
settle = None
|
486
|
+
optionParts = symbol.split('-')
|
487
|
+
symbolBase = symbol.split('/')
|
488
|
+
base = None
|
489
|
+
expiry = None
|
490
|
+
if symbol.find('/') > -1:
|
491
|
+
base = self.safe_string(symbolBase, 0)
|
492
|
+
expiry = self.safe_string(optionParts, 1)
|
493
|
+
if symbol.find('USDC') > -1:
|
494
|
+
base = base + '_USDC'
|
495
|
+
else:
|
496
|
+
base = self.safe_string(optionParts, 0)
|
497
|
+
expiry = self.convert_market_id_expire_date(self.safe_string(optionParts, 1))
|
498
|
+
if symbol.find('USDC') > -1:
|
499
|
+
quote = 'USDC'
|
500
|
+
settle = 'USDC'
|
501
|
+
else:
|
502
|
+
settle = base
|
503
|
+
splitBase = base
|
504
|
+
if base.find('_') > -1:
|
505
|
+
splitSymbol = base.split('_')
|
506
|
+
splitBase = self.safe_string(splitSymbol, 0)
|
507
|
+
strike = self.safe_string(optionParts, 2)
|
508
|
+
optionType = self.safe_string(optionParts, 3)
|
509
|
+
datetime = self.convert_expire_date(expiry)
|
510
|
+
timestamp = self.parse8601(datetime)
|
511
|
+
return {
|
512
|
+
'id': base + '-' + self.convert_expire_date_to_market_id_date(expiry) + '-' + strike + '-' + optionType,
|
513
|
+
'symbol': splitBase + '/' + quote + ':' + settle + '-' + expiry + '-' + strike + '-' + optionType,
|
514
|
+
'base': base,
|
515
|
+
'quote': quote,
|
516
|
+
'settle': settle,
|
517
|
+
'baseId': base,
|
518
|
+
'quoteId': quote,
|
519
|
+
'settleId': settle,
|
520
|
+
'active': False,
|
521
|
+
'type': 'option',
|
522
|
+
'linear': None,
|
523
|
+
'inverse': None,
|
524
|
+
'spot': False,
|
525
|
+
'swap': False,
|
526
|
+
'future': False,
|
527
|
+
'option': True,
|
528
|
+
'margin': False,
|
529
|
+
'contract': True,
|
530
|
+
'contractSize': None,
|
531
|
+
'expiry': timestamp,
|
532
|
+
'expiryDatetime': datetime,
|
533
|
+
'optionType': 'call' if (optionType == 'C') else 'put',
|
534
|
+
'strike': self.parse_number(strike),
|
535
|
+
'precision': {
|
536
|
+
'amount': None,
|
537
|
+
'price': None,
|
538
|
+
},
|
539
|
+
'limits': {
|
540
|
+
'amount': {
|
541
|
+
'min': None,
|
542
|
+
'max': None,
|
543
|
+
},
|
544
|
+
'price': {
|
545
|
+
'min': None,
|
546
|
+
'max': None,
|
547
|
+
},
|
548
|
+
'cost': {
|
549
|
+
'min': None,
|
550
|
+
'max': None,
|
551
|
+
},
|
552
|
+
},
|
553
|
+
'info': None,
|
554
|
+
}
|
555
|
+
|
556
|
+
def safe_market(self, marketId=None, market=None, delimiter=None, marketType=None):
|
557
|
+
isOption = (marketId is not None) and ((marketId.endswith('-C')) or (marketId.endswith('-P')))
|
558
|
+
if isOption and not (marketId in self.markets_by_id):
|
559
|
+
# handle expired option contracts
|
560
|
+
return self.create_expired_option_market(marketId)
|
561
|
+
return super(deribit, self).safe_market(marketId, market, delimiter, marketType)
|
562
|
+
|
418
563
|
async def fetch_time(self, params={}):
|
419
564
|
"""
|
420
565
|
fetches the current integer timestamp in milliseconds from the exchange server
|
ccxt/async_support/okcoin.py
CHANGED
@@ -67,6 +67,9 @@ class okcoin(Exchange, ImplicitAPI):
|
|
67
67
|
'fetchCurrencies': True, # see below
|
68
68
|
'fetchDepositAddress': True,
|
69
69
|
'fetchDeposits': True,
|
70
|
+
'fetchFundingHistory': False,
|
71
|
+
'fetchFundingRate': False,
|
72
|
+
'fetchFundingRateHistory': False,
|
70
73
|
'fetchLedger': True,
|
71
74
|
'fetchMarkets': True,
|
72
75
|
'fetchMyTrades': True,
|
ccxt/async_support/phemex.py
CHANGED
@@ -1850,23 +1850,26 @@ class phemex(Exchange, ImplicitAPI):
|
|
1850
1850
|
async def fetch_balance(self, params={}) -> Balances:
|
1851
1851
|
"""
|
1852
1852
|
query for balance and get the amount of funds available for trading or funds locked in orders
|
1853
|
+
:see: https://phemex-docs.github.io/#query-wallets
|
1853
1854
|
:see: https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query-account-positions
|
1855
|
+
:see: https://phemex-docs.github.io/#query-trading-account-and-positions
|
1854
1856
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1855
1857
|
:param str [params.type]: spot or swap
|
1858
|
+
:param str [params.code]: *swap only* currency code of the balance to query(USD, USDT, etc), default is USDT
|
1856
1859
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
1857
1860
|
"""
|
1858
1861
|
await self.load_markets()
|
1859
1862
|
type = None
|
1860
1863
|
type, params = self.handle_market_type_and_params('fetchBalance', None, params)
|
1861
1864
|
code = self.safe_string(params, 'code')
|
1862
|
-
params = self.omit(params, ['
|
1865
|
+
params = self.omit(params, ['code'])
|
1863
1866
|
response = None
|
1864
1867
|
request = {}
|
1865
1868
|
if (type != 'spot') and (type != 'swap'):
|
1866
1869
|
raise BadRequest(self.id + ' does not support ' + type + ' markets, only spot and swap')
|
1867
1870
|
if type == 'swap':
|
1868
1871
|
settle = None
|
1869
|
-
settle, params = self.handle_option_and_params(params, 'fetchBalance', 'settle')
|
1872
|
+
settle, params = self.handle_option_and_params(params, 'fetchBalance', 'settle', 'USDT')
|
1870
1873
|
if code is not None or settle is not None:
|
1871
1874
|
coin = None
|
1872
1875
|
if code is not None:
|
ccxt/async_support/poloniex.py
CHANGED
@@ -60,6 +60,7 @@ class poloniex(Exchange, ImplicitAPI):
|
|
60
60
|
'fetchDepositsWithdrawals': True,
|
61
61
|
'fetchDepositWithdrawFee': 'emulated',
|
62
62
|
'fetchDepositWithdrawFees': True,
|
63
|
+
'fetchFundingRate': False,
|
63
64
|
'fetchMarginMode': False,
|
64
65
|
'fetchMarkets': True,
|
65
66
|
'fetchMyTrades': True,
|
ccxt/async_support/woo.py
CHANGED
@@ -66,7 +66,7 @@ class woo(Exchange, ImplicitAPI):
|
|
66
66
|
'fetchClosedOrder': False,
|
67
67
|
'fetchClosedOrders': False,
|
68
68
|
'fetchCurrencies': True,
|
69
|
-
'fetchDepositAddress':
|
69
|
+
'fetchDepositAddress': True,
|
70
70
|
'fetchDeposits': True,
|
71
71
|
'fetchDepositsWithdrawals': True,
|
72
72
|
'fetchFundingHistory': True,
|
ccxt/base/exchange.py
CHANGED
ccxt/bigone.py
CHANGED
ccxt/binance.py
CHANGED
@@ -329,6 +329,7 @@ class binance(Exchange, ImplicitAPI):
|
|
329
329
|
'convert/exchangeInfo': 50,
|
330
330
|
'convert/assetInfo': 10,
|
331
331
|
'convert/orderStatus': 0.6667,
|
332
|
+
'convert/limit/queryOpenOrders': 20.001, # Weight(UID): 3000 => cost = 0.006667 * 3000 = 20.001
|
332
333
|
'account/status': 0.1,
|
333
334
|
'account/apiTradingStatus': 0.1,
|
334
335
|
'account/apiRestrictions/ipRestriction': 0.1,
|
@@ -600,6 +601,8 @@ class binance(Exchange, ImplicitAPI):
|
|
600
601
|
'loan/vip/repay': 40.002,
|
601
602
|
'convert/getQuote': 1.3334, # Weight(UID): 200 => cost = 0.006667 * 200 = 1.3334
|
602
603
|
'convert/acceptQuote': 3.3335, # Weight(UID): 500 => cost = 0.006667 * 500 = 3.3335
|
604
|
+
'convert/limit/placeOrder': 3.3335, # Weight(UID): 500 => cost = 0.006667 * 500 = 3.3335
|
605
|
+
'convert/limit/cancelOrder': 1.3334, # Weight(UID): 200 => cost = 0.006667 * 200 = 1.3334
|
603
606
|
'portfolio/auto-collection': 150, # Weight(IP): 1500 => cost = 0.1 * 1500 = 150
|
604
607
|
'portfolio/asset-collection': 6, # Weight(IP): 60 => cost = 0.1 * 60 = 6
|
605
608
|
'portfolio/bnb-transfer': 150, # Weight(IP): 1500 => cost = 0.1 * 1500 = 150
|
@@ -7369,12 +7372,20 @@ class binance(Exchange, ImplicitAPI):
|
|
7369
7372
|
|
7370
7373
|
def fetch_positions(self, symbols: Strings = None, params={}):
|
7371
7374
|
"""
|
7375
|
+
:see: https://binance-docs.github.io/apidocs/futures/en/#position-information-v2-user_data
|
7376
|
+
:see: https://binance-docs.github.io/apidocs/delivery/en/#position-information-user_data
|
7377
|
+
:see: https://binance-docs.github.io/apidocs/futures/en/#account-information-v2-user_data
|
7378
|
+
:see: https://binance-docs.github.io/apidocs/delivery/en/#account-information-user_data
|
7379
|
+
:see: https://binance-docs.github.io/apidocs/voptions/en/#option-position-information-user_data
|
7372
7380
|
fetch all open positions
|
7373
|
-
:param str[]
|
7381
|
+
:param str[] [symbols]: list of unified market symbols
|
7374
7382
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7383
|
+
:param str [method]: method name to call, "positionRisk", "account" or "option", default is "positionRisk"
|
7375
7384
|
:returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
|
7376
7385
|
"""
|
7377
|
-
|
7386
|
+
defaultValue = self.safe_string(self.options, 'fetchPositions', 'positionRisk')
|
7387
|
+
defaultMethod = None
|
7388
|
+
defaultMethod, params = self.handle_option_and_params(params, 'fetchPositions', 'method', defaultValue)
|
7378
7389
|
if defaultMethod == 'positionRisk':
|
7379
7390
|
return self.fetch_positions_risk(symbols, params)
|
7380
7391
|
elif defaultMethod == 'account':
|
@@ -7382,7 +7393,7 @@ class binance(Exchange, ImplicitAPI):
|
|
7382
7393
|
elif defaultMethod == 'option':
|
7383
7394
|
return self.fetch_option_positions(symbols, params)
|
7384
7395
|
else:
|
7385
|
-
raise NotSupported(self.id + '.options["fetchPositions"] = "' + defaultMethod + '" is invalid, please choose between "account", "positionRisk" and "option"')
|
7396
|
+
raise NotSupported(self.id + '.options["fetchPositions"]/params["method"] = "' + defaultMethod + '" is invalid, please choose between "account", "positionRisk" and "option"')
|
7386
7397
|
|
7387
7398
|
def fetch_account_positions(self, symbols: Strings = None, params={}):
|
7388
7399
|
"""
|
ccxt/bitget.py
CHANGED
@@ -58,15 +58,21 @@ class bitget(Exchange, ImplicitAPI):
|
|
58
58
|
'cancelOrders': True,
|
59
59
|
'closeAllPositions': True,
|
60
60
|
'closePosition': True,
|
61
|
+
'createDepositAddress': False,
|
61
62
|
'createMarketBuyOrderWithCost': True,
|
62
63
|
'createMarketOrderWithCost': False,
|
63
64
|
'createMarketSellOrderWithCost': False,
|
64
65
|
'createOrder': True,
|
65
66
|
'createOrders': True,
|
66
67
|
'createOrderWithTakeProfitAndStopLoss': True,
|
68
|
+
'createPostOnlyOrder': True,
|
67
69
|
'createReduceOnlyOrder': False,
|
70
|
+
'createStopLimitOrder': True,
|
68
71
|
'createStopLossOrder': True,
|
72
|
+
'createStopMarketOrder': True,
|
73
|
+
'createStopOrder': True,
|
69
74
|
'createTakeProfitOrder': True,
|
75
|
+
'createTrailingAmountOrder': False,
|
70
76
|
'createTrailingPercentOrder': True,
|
71
77
|
'createTriggerOrder': True,
|
72
78
|
'editOrder': True,
|
@@ -84,6 +90,7 @@ class bitget(Exchange, ImplicitAPI):
|
|
84
90
|
'fetchDepositAddress': True,
|
85
91
|
'fetchDepositAddresses': False,
|
86
92
|
'fetchDeposits': True,
|
93
|
+
'fetchDepositsWithdrawals': False,
|
87
94
|
'fetchDepositWithdrawFee': 'emulated',
|
88
95
|
'fetchDepositWithdrawFees': True,
|
89
96
|
'fetchFundingHistory': True,
|
@@ -97,7 +104,7 @@ class bitget(Exchange, ImplicitAPI):
|
|
97
104
|
'fetchLeverage': True,
|
98
105
|
'fetchLeverageTiers': False,
|
99
106
|
'fetchLiquidations': False,
|
100
|
-
'fetchMarginMode':
|
107
|
+
'fetchMarginMode': False,
|
101
108
|
'fetchMarketLeverageTiers': True,
|
102
109
|
'fetchMarkets': True,
|
103
110
|
'fetchMarkOHLCV': True,
|
@@ -122,8 +129,10 @@ class bitget(Exchange, ImplicitAPI):
|
|
122
129
|
'fetchTrades': True,
|
123
130
|
'fetchTradingFee': True,
|
124
131
|
'fetchTradingFees': True,
|
132
|
+
'fetchTransactions': False,
|
125
133
|
'fetchTransfer': False,
|
126
134
|
'fetchTransfers': True,
|
135
|
+
'fetchWithdrawAddresses': False,
|
127
136
|
'fetchWithdrawal': False,
|
128
137
|
'fetchWithdrawals': True,
|
129
138
|
'reduceMargin': True,
|
@@ -132,6 +141,7 @@ class bitget(Exchange, ImplicitAPI):
|
|
132
141
|
'setLeverage': True,
|
133
142
|
'setMarginMode': True,
|
134
143
|
'setPositionMode': True,
|
144
|
+
'signIn': False,
|
135
145
|
'transfer': True,
|
136
146
|
'withdraw': True,
|
137
147
|
},
|
ccxt/bitrue.py
CHANGED
@@ -72,6 +72,7 @@ class bitrue(Exchange, ImplicitAPI):
|
|
72
72
|
'fetchDepositsWithdrawals': False,
|
73
73
|
'fetchDepositWithdrawFee': 'emulated',
|
74
74
|
'fetchDepositWithdrawFees': True,
|
75
|
+
'fetchFundingRate': False,
|
75
76
|
'fetchIsolatedBorrowRate': False,
|
76
77
|
'fetchIsolatedBorrowRates': False,
|
77
78
|
'fetchMarginMode': False,
|
ccxt/bybit.py
CHANGED
@@ -52,7 +52,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
52
52
|
'closeAllPositions': False,
|
53
53
|
'closePosition': False,
|
54
54
|
'createMarketBuyOrderWithCost': True,
|
55
|
-
'createMarketSellOrderWithCost':
|
55
|
+
'createMarketSellOrderWithCost': True,
|
56
56
|
'createOrder': True,
|
57
57
|
'createOrders': True,
|
58
58
|
'createOrderWithTakeProfitAndStopLoss': True,
|
@@ -972,7 +972,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
972
972
|
'fetchMarkets': ['spot', 'linear', 'inverse', 'option'],
|
973
973
|
'enableUnifiedMargin': None,
|
974
974
|
'enableUnifiedAccount': None,
|
975
|
-
'createMarketBuyOrderRequiresPrice': True,
|
975
|
+
'createMarketBuyOrderRequiresPrice': True, # only True for classic accounts
|
976
976
|
'createUnifiedMarginAccount': False,
|
977
977
|
'defaultType': 'swap', # 'swap', 'future', 'option', 'spot'
|
978
978
|
'defaultSubType': 'linear', # 'linear', 'inverse'
|
@@ -3301,8 +3301,26 @@ class bybit(Exchange, ImplicitAPI):
|
|
3301
3301
|
market = self.market(symbol)
|
3302
3302
|
if not market['spot']:
|
3303
3303
|
raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
|
3304
|
-
|
3305
|
-
|
3304
|
+
return self.create_order(symbol, 'market', 'buy', cost, 1, params)
|
3305
|
+
|
3306
|
+
def create_market_sell_order_with_cost(self, symbol: str, cost, params={}):
|
3307
|
+
"""
|
3308
|
+
:see: https://bybit-exchange.github.io/docs/v5/order/create-order
|
3309
|
+
create a market sell order by providing the symbol and cost
|
3310
|
+
:param str symbol: unified symbol of the market to create an order in
|
3311
|
+
:param float cost: how much you want to trade in units of the quote currency
|
3312
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3313
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
3314
|
+
"""
|
3315
|
+
self.load_markets()
|
3316
|
+
types = self.is_unified_enabled()
|
3317
|
+
enableUnifiedAccount = types[1]
|
3318
|
+
if not enableUnifiedAccount:
|
3319
|
+
raise NotSupported(self.id + ' createMarketSellOrderWithCost() supports UTA accounts only')
|
3320
|
+
market = self.market(symbol)
|
3321
|
+
if not market['spot']:
|
3322
|
+
raise NotSupported(self.id + ' createMarketSellOrderWithCost() supports spot orders only')
|
3323
|
+
return self.create_order(symbol, 'market', 'sell', cost, 1, params)
|
3306
3324
|
|
3307
3325
|
def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
|
3308
3326
|
"""
|
@@ -3343,7 +3361,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
3343
3361
|
return self.create_usdc_order(symbol, type, side, amount, price, params)
|
3344
3362
|
trailingAmount = self.safe_string_2(params, 'trailingAmount', 'trailingStop')
|
3345
3363
|
isTrailingAmountOrder = trailingAmount is not None
|
3346
|
-
orderRequest = self.create_order_request(symbol, type, side, amount, price, params)
|
3364
|
+
orderRequest = self.create_order_request(symbol, type, side, amount, price, params, enableUnifiedAccount)
|
3347
3365
|
response = None
|
3348
3366
|
if isTrailingAmountOrder:
|
3349
3367
|
response = self.privatePostV5PositionTradingStop(orderRequest)
|
@@ -3364,7 +3382,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
3364
3382
|
order = self.safe_value(response, 'result', {})
|
3365
3383
|
return self.parse_order(order, market)
|
3366
3384
|
|
3367
|
-
def create_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
|
3385
|
+
def create_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}, isUTA=True):
|
3368
3386
|
market = self.market(symbol)
|
3369
3387
|
symbol = market['symbol']
|
3370
3388
|
lowerCaseType = type.lower()
|
@@ -3403,12 +3421,31 @@ class bybit(Exchange, ImplicitAPI):
|
|
3403
3421
|
request['category'] = 'inverse'
|
3404
3422
|
elif market['option']:
|
3405
3423
|
request['category'] = 'option'
|
3406
|
-
|
3424
|
+
cost = self.safe_string(params, 'cost')
|
3425
|
+
params = self.omit(params, 'cost')
|
3426
|
+
# if the cost is inferable, let's keep the old logic and ignore marketUnit, to minimize the impact of the changes
|
3427
|
+
isMarketBuyAndCostInferable = (lowerCaseType == 'market') and (side == 'buy') and ((price is not None) or (cost is not None))
|
3428
|
+
if market['spot'] and (type == 'market') and isUTA and not isMarketBuyAndCostInferable:
|
3429
|
+
# UTA account can specify the cost of the order on both sides
|
3430
|
+
if (cost is not None) or (price is not None):
|
3431
|
+
request['marketUnit'] = 'quoteCoin'
|
3432
|
+
orderCost = None
|
3433
|
+
if cost is not None:
|
3434
|
+
orderCost = cost
|
3435
|
+
else:
|
3436
|
+
amountString = self.number_to_string(amount)
|
3437
|
+
priceString = self.number_to_string(price)
|
3438
|
+
quoteAmount = Precise.string_mul(amountString, priceString)
|
3439
|
+
orderCost = quoteAmount
|
3440
|
+
request['qty'] = self.cost_to_precision(symbol, orderCost)
|
3441
|
+
else:
|
3442
|
+
request['marketUnit'] = 'baseCoin'
|
3443
|
+
request['qty'] = self.amount_to_precision(symbol, amount)
|
3444
|
+
elif market['spot'] and (type == 'market') and (side == 'buy'):
|
3445
|
+
# classic accounts
|
3407
3446
|
# for market buy it requires the amount of quote currency to spend
|
3408
3447
|
createMarketBuyOrderRequiresPrice = True
|
3409
3448
|
createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
|
3410
|
-
cost = self.safe_number(params, 'cost')
|
3411
|
-
params = self.omit(params, 'cost')
|
3412
3449
|
if createMarketBuyOrderRequiresPrice:
|
3413
3450
|
if (price is None) and (cost is None):
|
3414
3451
|
raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend in the amount argument')
|
@@ -3504,6 +3541,8 @@ class bybit(Exchange, ImplicitAPI):
|
|
3504
3541
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
3505
3542
|
"""
|
3506
3543
|
self.load_markets()
|
3544
|
+
accounts = self.is_unified_enabled()
|
3545
|
+
isUta = accounts[1]
|
3507
3546
|
ordersRequests = []
|
3508
3547
|
orderSymbols = []
|
3509
3548
|
for i in range(0, len(orders)):
|
@@ -3515,7 +3554,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
3515
3554
|
amount = self.safe_value(rawOrder, 'amount')
|
3516
3555
|
price = self.safe_value(rawOrder, 'price')
|
3517
3556
|
orderParams = self.safe_value(rawOrder, 'params', {})
|
3518
|
-
orderRequest = self.create_order_request(marketId, type, side, amount, price, orderParams)
|
3557
|
+
orderRequest = self.create_order_request(marketId, type, side, amount, price, orderParams, isUta)
|
3519
3558
|
ordersRequests.append(orderRequest)
|
3520
3559
|
symbols = self.market_symbols(orderSymbols, None, False, True, True)
|
3521
3560
|
market = self.market(symbols[0])
|
ccxt/coinbasepro.py
CHANGED
@@ -53,6 +53,7 @@ class coinbasepro(Exchange, ImplicitAPI):
|
|
53
53
|
'fetchDepositAddress': False, # the exchange does not have self method, only createDepositAddress, see https://github.com/ccxt/ccxt/pull/7405
|
54
54
|
'fetchDeposits': True,
|
55
55
|
'fetchDepositsWithdrawals': True,
|
56
|
+
'fetchFundingRate': False,
|
56
57
|
'fetchLedger': True,
|
57
58
|
'fetchMarginMode': False,
|
58
59
|
'fetchMarkets': True,
|
ccxt/coinex.py
CHANGED
@@ -1530,8 +1530,9 @@ class coinex(Exchange, ImplicitAPI):
|
|
1530
1530
|
"""
|
1531
1531
|
marketType = None
|
1532
1532
|
marketType, params = self.handle_market_type_and_params('fetchBalance', None, params)
|
1533
|
-
|
1534
|
-
|
1533
|
+
marginMode = None
|
1534
|
+
marginMode, params = self.handle_margin_mode_and_params('fetchBalance', params)
|
1535
|
+
marketType = 'margin' if (marginMode is not None) else marketType
|
1535
1536
|
params = self.omit(params, 'margin')
|
1536
1537
|
if marketType == 'margin':
|
1537
1538
|
return self.fetch_margin_balance(params)
|
@@ -2005,8 +2006,9 @@ class coinex(Exchange, ImplicitAPI):
|
|
2005
2006
|
if timeInForceRaw is not None:
|
2006
2007
|
request['option'] = timeInForceRaw # exchange takes 'IOC' and 'FOK'
|
2007
2008
|
accountId = self.safe_integer(params, 'account_id')
|
2008
|
-
|
2009
|
-
|
2009
|
+
marginMode = None
|
2010
|
+
marginMode, params = self.handle_margin_mode_and_params('createOrder', params)
|
2011
|
+
if marginMode is not None:
|
2010
2012
|
if accountId is None:
|
2011
2013
|
raise BadRequest(self.id + ' createOrder() requires an account_id parameter for margin orders')
|
2012
2014
|
request['account_id'] = accountId
|
@@ -2473,9 +2475,10 @@ class coinex(Exchange, ImplicitAPI):
|
|
2473
2475
|
'market': market['id'],
|
2474
2476
|
}
|
2475
2477
|
accountId = self.safe_integer(params, 'account_id')
|
2476
|
-
|
2478
|
+
marginMode = None
|
2479
|
+
marginMode, params = self.handle_margin_mode_and_params('cancelOrder', params)
|
2477
2480
|
clientOrderId = self.safe_string_2(params, 'client_id', 'clientOrderId')
|
2478
|
-
if
|
2481
|
+
if marginMode is not None:
|
2479
2482
|
if accountId is None:
|
2480
2483
|
raise BadRequest(self.id + ' cancelOrder() requires an account_id parameter for margin orders')
|
2481
2484
|
request['account_id'] = accountId
|
@@ -2814,8 +2817,9 @@ class coinex(Exchange, ImplicitAPI):
|
|
2814
2817
|
request['market'] = market['id']
|
2815
2818
|
marketType, query = self.handle_market_type_and_params('fetchOrdersByStatus', market, params)
|
2816
2819
|
accountId = self.safe_integer(params, 'account_id')
|
2817
|
-
|
2818
|
-
|
2820
|
+
marginMode = None
|
2821
|
+
marginMode, params = self.handle_margin_mode_and_params('fetchOrdersByStatus', params)
|
2822
|
+
if marginMode is not None:
|
2819
2823
|
if accountId is None:
|
2820
2824
|
raise BadRequest(self.id + ' fetchOpenOrders() and fetchClosedOrders() require an account_id parameter for margin orders')
|
2821
2825
|
request['account_id'] = accountId
|
@@ -3179,8 +3183,9 @@ class coinex(Exchange, ImplicitAPI):
|
|
3179
3183
|
raise ArgumentsRequired(self.id + ' fetchMyTrades() requires a symbol argument for non-spot markets')
|
3180
3184
|
swap = (type == 'swap')
|
3181
3185
|
accountId = self.safe_integer(params, 'account_id')
|
3182
|
-
|
3183
|
-
|
3186
|
+
marginMode = None
|
3187
|
+
marginMode, params = self.handle_margin_mode_and_params('fetchMyTrades', params)
|
3188
|
+
if marginMode is not None:
|
3184
3189
|
if accountId is None:
|
3185
3190
|
raise BadRequest(self.id + ' fetchMyTrades() requires an account_id parameter for margin trades')
|
3186
3191
|
request['account_id'] = accountId
|
@@ -4418,9 +4423,10 @@ class coinex(Exchange, ImplicitAPI):
|
|
4418
4423
|
else:
|
4419
4424
|
request['limit'] = 100
|
4420
4425
|
params = self.omit(params, 'page')
|
4421
|
-
|
4426
|
+
marginMode = None
|
4427
|
+
marginMode, params = self.handle_margin_mode_and_params('fetchTransfers', params)
|
4422
4428
|
response = None
|
4423
|
-
if
|
4429
|
+
if marginMode is not None:
|
4424
4430
|
response = self.privateGetMarginTransferHistory(self.extend(request, params))
|
4425
4431
|
else:
|
4426
4432
|
response = self.privateGetContractTransferHistory(self.extend(request, params))
|
@@ -4967,6 +4973,22 @@ class coinex(Exchange, ImplicitAPI):
|
|
4967
4973
|
depositWithdrawFees[code] = self.assign_default_deposit_withdraw_fees(depositWithdrawFees[code], currency)
|
4968
4974
|
return depositWithdrawFees
|
4969
4975
|
|
4976
|
+
def handle_margin_mode_and_params(self, methodName, params={}, defaultValue=None):
|
4977
|
+
"""
|
4978
|
+
* @ignore
|
4979
|
+
marginMode specified by params["marginMode"], self.options["marginMode"], self.options["defaultMarginMode"], params["margin"] = True or self.options["defaultType"] = 'margin'
|
4980
|
+
:param dict params: extra parameters specific to the exchange api endpoint
|
4981
|
+
:returns Array: the marginMode in lowercase
|
4982
|
+
"""
|
4983
|
+
defaultType = self.safe_string(self.options, 'defaultType')
|
4984
|
+
isMargin = self.safe_value(params, 'margin', False)
|
4985
|
+
marginMode = None
|
4986
|
+
marginMode, params = super(coinex, self).handle_margin_mode_and_params(methodName, params, defaultValue)
|
4987
|
+
if marginMode is None:
|
4988
|
+
if (defaultType == 'margin') or (isMargin is True):
|
4989
|
+
marginMode = 'isolated'
|
4990
|
+
return [marginMode, params]
|
4991
|
+
|
4970
4992
|
def nonce(self):
|
4971
4993
|
return self.milliseconds()
|
4972
4994
|
|