ccxt 4.1.89__py2.py3-none-any.whl → 4.1.90__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.

Files changed (49) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/async_support/__init__.py +1 -1
  3. ccxt/async_support/base/exchange.py +3 -3
  4. ccxt/async_support/binance.py +1 -1
  5. ccxt/async_support/bitforex.py +2 -0
  6. ccxt/async_support/bitget.py +9 -4
  7. ccxt/async_support/bitmex.py +2 -0
  8. ccxt/async_support/blockchaincom.py +0 -37
  9. ccxt/async_support/bybit.py +23 -14
  10. ccxt/async_support/coinlist.py +2 -0
  11. ccxt/async_support/coinsph.py +2 -0
  12. ccxt/async_support/cryptocom.py +2 -0
  13. ccxt/async_support/gate.py +258 -11
  14. ccxt/async_support/htx.py +223 -207
  15. ccxt/async_support/kuna.py +2 -0
  16. ccxt/async_support/mexc.py +2 -0
  17. ccxt/async_support/okcoin.py +3 -1
  18. ccxt/async_support/phemex.py +48 -1
  19. ccxt/async_support/poloniex.py +23 -2
  20. ccxt/async_support/tokocrypto.py +2 -0
  21. ccxt/async_support/wazirx.py +2 -0
  22. ccxt/async_support/whitebit.py +2 -0
  23. ccxt/base/exchange.py +3 -3
  24. ccxt/binance.py +1 -1
  25. ccxt/bitforex.py +2 -0
  26. ccxt/bitget.py +9 -4
  27. ccxt/bitmex.py +2 -0
  28. ccxt/blockchaincom.py +0 -37
  29. ccxt/bybit.py +23 -14
  30. ccxt/coinlist.py +2 -0
  31. ccxt/coinsph.py +2 -0
  32. ccxt/cryptocom.py +2 -0
  33. ccxt/gate.py +258 -11
  34. ccxt/htx.py +223 -207
  35. ccxt/kuna.py +2 -0
  36. ccxt/mexc.py +2 -0
  37. ccxt/okcoin.py +3 -1
  38. ccxt/phemex.py +48 -1
  39. ccxt/poloniex.py +23 -2
  40. ccxt/pro/__init__.py +1 -1
  41. ccxt/pro/binance.py +6 -6
  42. ccxt/pro/poloniex.py +15 -11
  43. ccxt/tokocrypto.py +2 -0
  44. ccxt/wazirx.py +2 -0
  45. ccxt/whitebit.py +2 -0
  46. {ccxt-4.1.89.dist-info → ccxt-4.1.90.dist-info}/METADATA +4 -4
  47. {ccxt-4.1.89.dist-info → ccxt-4.1.90.dist-info}/RECORD +49 -49
  48. {ccxt-4.1.89.dist-info → ccxt-4.1.90.dist-info}/WHEEL +0 -0
  49. {ccxt-4.1.89.dist-info → ccxt-4.1.90.dist-info}/top_level.txt +0 -0
ccxt/__init__.py CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  # ----------------------------------------------------------------------------
24
24
 
25
- __version__ = '4.1.89'
25
+ __version__ = '4.1.90'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.1.89'
7
+ __version__ = '4.1.90'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.1.89'
5
+ __version__ = '4.1.90'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -930,7 +930,7 @@ class Exchange(BaseExchange):
930
930
  :param dict [params]: extra parameters specific to the exchange API endpoint
931
931
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
932
932
  """
933
- if self.options['createMarketOrderWithCost'] or (self.options['createMarketBuyOrderWithCost'] and self.options['createMarketSellOrderWithCost']):
933
+ if self.has['createMarketOrderWithCost'] or (self.has['createMarketBuyOrderWithCost'] and self.has['createMarketSellOrderWithCost']):
934
934
  return await self.create_order(symbol, 'market', side, cost, 1, params)
935
935
  raise NotSupported(self.id + ' createMarketOrderWithCost() is not supported yet')
936
936
 
@@ -942,7 +942,7 @@ class Exchange(BaseExchange):
942
942
  :param dict [params]: extra parameters specific to the exchange API endpoint
943
943
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
944
944
  """
945
- if self.options['createMarketBuyOrderRequiresPrice'] or self.options['createMarketBuyOrderWithCost']:
945
+ if self.options['createMarketBuyOrderRequiresPrice'] or self.has['createMarketBuyOrderWithCost']:
946
946
  return await self.create_order(symbol, 'market', 'buy', cost, 1, params)
947
947
  raise NotSupported(self.id + ' createMarketBuyOrderWithCost() is not supported yet')
948
948
 
@@ -61,7 +61,7 @@ class binance(Exchange, ImplicitAPI):
61
61
  'cancelOrder': True,
62
62
  'cancelOrders': True, # contract only
63
63
  'closeAllPositions': False,
64
- 'closePosition': False,
64
+ 'closePosition': False, # exchange specific closePosition parameter for binance createOrder is not synonymous with how CCXT uses closePositions
65
65
  'createDepositAddress': False,
66
66
  'createOrder': True,
67
67
  'createOrders': True,
@@ -84,6 +84,8 @@ class bitforex(Exchange, ImplicitAPI):
84
84
  'fetchWithdrawal': False,
85
85
  'fetchWithdrawals': False,
86
86
  'reduceMargin': False,
87
+ 'repayCrossMargin': False,
88
+ 'repayIsolatedMargin': False,
87
89
  'setLeverage': False,
88
90
  'setMargin': False,
89
91
  'setMarginMode': False,
@@ -3719,17 +3719,22 @@ class bitget(Exchange, ImplicitAPI):
3719
3719
  if feeCostString is not None:
3720
3720
  # swap
3721
3721
  fee = {
3722
- 'cost': feeCostString,
3722
+ 'cost': self.parse_number(Precise.string_abs(feeCostString)),
3723
3723
  'currency': market['settle'],
3724
3724
  }
3725
3725
  feeDetail = self.safe_value(order, 'feeDetail')
3726
3726
  if feeDetail is not None:
3727
3727
  parsedFeeDetail = json.loads(feeDetail)
3728
3728
  feeValues = list(parsedFeeDetail.values())
3729
- first = self.safe_value(feeValues, 0)
3729
+ feeObject = None
3730
+ for i in range(0, len(feeValues)):
3731
+ feeValue = feeValues[i]
3732
+ if self.safe_value(feeValue, 'feeCoinCode') is not None:
3733
+ feeObject = feeValue
3734
+ break
3730
3735
  fee = {
3731
- 'cost': self.safe_string(first, 'totalFee'),
3732
- 'currency': self.safe_currency_code(self.safe_string(first, 'feeCoinCode')),
3736
+ 'cost': self.parse_number(Precise.string_abs(self.safe_string(feeObject, 'totalFee'))),
3737
+ 'currency': self.safe_currency_code(self.safe_string(feeObject, 'feeCoinCode')),
3733
3738
  }
3734
3739
  postOnly = None
3735
3740
  timeInForce = self.safe_string_upper(order, 'force')
@@ -50,6 +50,8 @@ class bitmex(Exchange, ImplicitAPI):
50
50
  'cancelAllOrders': True,
51
51
  'cancelOrder': True,
52
52
  'cancelOrders': True,
53
+ 'closeAllPositions': False,
54
+ 'closePosition': True,
53
55
  'createOrder': True,
54
56
  'createReduceOnlyOrder': True,
55
57
  'editOrder': True,
@@ -857,43 +857,6 @@ class blockchaincom(Exchange, ImplicitAPI):
857
857
  'fee': fee,
858
858
  }
859
859
 
860
- async def fetch_withdrawal_whitelist(self, params={}):
861
- """
862
- fetch the list of withdrawal addresses on the whitelist
863
- :param dict [params]: extra parameters specific to the exchange API endpoint
864
- :returns dict: dictionary with keys beneficiaryId, name, currency
865
- """
866
- await self.load_markets()
867
- response = await self.privateGetWhitelist()
868
- result = []
869
- for i in range(0, len(response)):
870
- entry = response[i]
871
- result.append({
872
- 'beneficiaryId': self.safe_string(entry, 'whitelistId'),
873
- 'name': self.safe_string(entry, 'name'),
874
- 'currency': self.safe_string(entry, 'currency'),
875
- 'info': entry,
876
- })
877
- return result
878
-
879
- async def fetch_withdrawal_whitelist_by_currency(self, code: str, params={}):
880
- await self.load_markets()
881
- currency = self.currency(code)
882
- request = {
883
- 'currency': currency['id'],
884
- }
885
- response = await self.privateGetWhitelistCurrency(self.extend(request, params))
886
- result = []
887
- for i in range(0, len(response)):
888
- entry = response[i]
889
- result.append({
890
- 'beneficiaryId': self.safe_string(entry, 'whitelistId'),
891
- 'name': self.safe_string(entry, 'name'),
892
- 'currency': self.safe_string(entry, 'currency'),
893
- 'info': entry,
894
- })
895
- return result
896
-
897
860
  async def withdraw(self, code: str, amount, address, tag=None, params={}):
898
861
  """
899
862
  make a withdrawal
@@ -960,6 +960,7 @@ class bybit(Exchange, ImplicitAPI):
960
960
  },
961
961
  'precisionMode': TICK_SIZE,
962
962
  'options': {
963
+ 'fetchMarkets': ['spot', 'linear', 'inverse', 'option'],
963
964
  'enableUnifiedMargin': None,
964
965
  'enableUnifiedAccount': None,
965
966
  'createMarketBuyOrderRequiresPrice': True,
@@ -1426,21 +1427,29 @@ class bybit(Exchange, ImplicitAPI):
1426
1427
  """
1427
1428
  if self.options['adjustForTimeDifference']:
1428
1429
  await self.load_time_difference()
1429
- promisesUnresolved = [
1430
- self.fetch_spot_markets(params),
1431
- self.fetch_future_markets({'category': 'linear'}),
1432
- self.fetch_future_markets({'category': 'inverse'}),
1433
- self.fetch_option_markets({'baseCoin': 'BTC'}),
1434
- self.fetch_option_markets({'baseCoin': 'ETH'}),
1435
- self.fetch_option_markets({'baseCoin': 'SOL'}),
1436
- ]
1430
+ promisesUnresolved = []
1431
+ fetchMarkets = self.safe_value(self.options, 'fetchMarkets', ['spot', 'linear', 'inverse'])
1432
+ for i in range(0, len(fetchMarkets)):
1433
+ marketType = fetchMarkets[i]
1434
+ if marketType == 'spot':
1435
+ promisesUnresolved.append(self.fetch_spot_markets(params))
1436
+ elif marketType == 'linear':
1437
+ promisesUnresolved.append(self.fetch_future_markets({'category': 'linear'}))
1438
+ elif marketType == 'inverse':
1439
+ promisesUnresolved.append(self.fetch_future_markets({'category': 'inverse'}))
1440
+ elif marketType == 'option':
1441
+ promisesUnresolved.append(self.fetch_option_markets({'baseCoin': 'BTC'}))
1442
+ promisesUnresolved.append(self.fetch_option_markets({'baseCoin': 'ETH'}))
1443
+ promisesUnresolved.append(self.fetch_option_markets({'baseCoin': 'SOL'}))
1444
+ else:
1445
+ raise ExchangeError(self.id + ' fetchMarkets() self.options fetchMarkets "' + marketType + '" is not a supported market type')
1437
1446
  promises = await asyncio.gather(*promisesUnresolved)
1438
- spotMarkets = promises[0]
1439
- linearMarkets = promises[1]
1440
- inverseMarkets = promises[2]
1441
- btcOptionMarkets = promises[3]
1442
- ethOptionMarkets = promises[4]
1443
- solOptionMarkets = promises[5]
1447
+ spotMarkets = self.safe_value(promises, 0, [])
1448
+ linearMarkets = self.safe_value(promises, 1, [])
1449
+ inverseMarkets = self.safe_value(promises, 2, [])
1450
+ btcOptionMarkets = self.safe_value(promises, 3, [])
1451
+ ethOptionMarkets = self.safe_value(promises, 4, [])
1452
+ solOptionMarkets = self.safe_value(promises, 5, [])
1444
1453
  futureMarkets = self.array_concat(linearMarkets, inverseMarkets)
1445
1454
  optionMarkets = self.array_concat(btcOptionMarkets, ethOptionMarkets)
1446
1455
  optionMarkets = self.array_concat(optionMarkets, solOptionMarkets)
@@ -122,6 +122,8 @@ class coinlist(Exchange, ImplicitAPI):
122
122
  'fetchWithdrawals': False,
123
123
  'fetchWithdrawalWhitelist': False,
124
124
  'reduceMargin': False,
125
+ 'repayCrossMargin': False,
126
+ 'repayIsolatedMargin': False,
125
127
  'setLeverage': False,
126
128
  'setMargin': False,
127
129
  'setMarginMode': False,
@@ -127,6 +127,8 @@ class coinsph(Exchange, ImplicitAPI):
127
127
  'fetchWithdrawals': True,
128
128
  'fetchWithdrawalWhitelist': False,
129
129
  'reduceMargin': False,
130
+ 'repayCrossMargin': False,
131
+ 'repayIsolatedMargin': False,
130
132
  'setLeverage': False,
131
133
  'setMargin': False,
132
134
  'setMarginMode': False,
@@ -111,6 +111,8 @@ class cryptocom(Exchange, ImplicitAPI):
111
111
  'fetchVolatilityHistory': False,
112
112
  'fetchWithdrawals': True,
113
113
  'reduceMargin': False,
114
+ 'repayCrossMargin': False,
115
+ 'repayIsolatedMargin': False,
114
116
  'setLeverage': False,
115
117
  'setMarginMode': False,
116
118
  'setPositionMode': False,
@@ -95,9 +95,14 @@ class gate(Exchange, ImplicitAPI):
95
95
  'future': True,
96
96
  'option': True,
97
97
  'addMargin': True,
98
+ 'borrowCrossMargin': True,
99
+ 'borrowIsolatedMargin': True,
98
100
  'cancelAllOrders': True,
99
101
  'cancelOrder': True,
102
+ 'createMarketBuyOrderWithCost': True,
100
103
  'createMarketOrder': True,
104
+ 'createMarketOrderWithCost': False,
105
+ 'createMarketSellOrderWithCost': False,
101
106
  'createOrder': True,
102
107
  'createOrders': True,
103
108
  'createPostOnlyOrder': True,
@@ -159,6 +164,8 @@ class gate(Exchange, ImplicitAPI):
159
164
  'fetchVolatilityHistory': False,
160
165
  'fetchWithdrawals': True,
161
166
  'reduceMargin': True,
167
+ 'repayCrossMargin': True,
168
+ 'repayIsolatedMargin': True,
162
169
  'setLeverage': True,
163
170
  'setMarginMode': False,
164
171
  'setPositionMode': True,
@@ -3553,6 +3560,7 @@ class gate(Exchange, ImplicitAPI):
3553
3560
  :param bool [params.close]: *contract only* Set to close the position, with size set to 0
3554
3561
  :param bool [params.auto_size]: *contract only* Set side to close dual-mode position, close_long closes the long side, while close_short the short one, size also needs to be set to 0
3555
3562
  :param int [params.price_type]: *contract only* 0 latest deal price, 1 mark price, 2 index price
3563
+ :param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
3556
3564
  :returns dict|None: `An order structure <https://docs.ccxt.com/#/?id=order-structure>`
3557
3565
  """
3558
3566
  await self.load_markets()
@@ -3725,9 +3733,13 @@ class gate(Exchange, ImplicitAPI):
3725
3733
  if contract:
3726
3734
  price = 0
3727
3735
  if contract:
3728
- amountToPrecision = self.amount_to_precision(symbol, amount)
3729
- signedAmount = Precise.string_neg(amountToPrecision) if (side == 'sell') else amountToPrecision
3730
- amount = int(signedAmount)
3736
+ isClose = self.safe_value(params, 'close')
3737
+ if isClose:
3738
+ amount = 0
3739
+ else:
3740
+ amountToPrecision = self.amount_to_precision(symbol, amount)
3741
+ signedAmount = Precise.string_neg(amountToPrecision) if (side == 'sell') else amountToPrecision
3742
+ amount = int(signedAmount)
3731
3743
  request = None
3732
3744
  nonTriggerOrder = not isStopOrder and (trigger is None)
3733
3745
  if nonTriggerOrder:
@@ -3768,20 +3780,25 @@ class gate(Exchange, ImplicitAPI):
3768
3780
  # 'auto_borrow': False, # used in margin or cross margin trading to allow automatic loan of insufficient amount if balance is not enough
3769
3781
  # 'auto_repay': False, # automatic repayment for automatic borrow loan generated by cross margin order, diabled by default
3770
3782
  }
3771
- createMarketBuyOrderRequiresPrice = self.safe_value(self.options, 'createMarketBuyOrderRequiresPrice', True)
3772
3783
  if isMarketOrder and (side == 'buy'):
3773
- if createMarketBuyOrderRequiresPrice:
3784
+ quoteAmount = None
3785
+ createMarketBuyOrderRequiresPrice = True
3786
+ createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
3787
+ cost = self.safe_number(params, 'cost')
3788
+ params = self.omit(params, 'cost')
3789
+ if cost is not None:
3790
+ quoteAmount = self.cost_to_precision(symbol, cost)
3791
+ elif createMarketBuyOrderRequiresPrice:
3774
3792
  if price is None:
3775
- raise InvalidOrder(self.id + ' createOrder() requires price argument for market buy orders on spot markets to calculate the total amount to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option to False and pass in the cost to spend into the amount parameter')
3793
+ 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(quote quantity) in the amount argument')
3776
3794
  else:
3777
3795
  amountString = self.number_to_string(amount)
3778
3796
  priceString = self.number_to_string(price)
3779
- cost = self.parse_number(Precise.string_mul(amountString, priceString))
3780
- request['amount'] = self.cost_to_precision(symbol, cost)
3797
+ costRequest = Precise.string_mul(amountString, priceString)
3798
+ quoteAmount = self.cost_to_precision(symbol, costRequest)
3781
3799
  else:
3782
- cost = self.safe_number(params, 'cost', amount)
3783
- params = self.omit(params, 'cost')
3784
- request['amount'] = self.cost_to_precision(symbol, cost)
3800
+ quoteAmount = self.cost_to_precision(symbol, amount)
3801
+ request['amount'] = quoteAmount
3785
3802
  else:
3786
3803
  request['amount'] = self.amount_to_precision(symbol, amount)
3787
3804
  if isLimitOrder:
@@ -3886,6 +3903,22 @@ class gate(Exchange, ImplicitAPI):
3886
3903
  }
3887
3904
  return self.extend(request, params)
3888
3905
 
3906
+ async def create_market_buy_order_with_cost(self, symbol: str, cost, params={}):
3907
+ """
3908
+ create a market buy order by providing the symbol and cost
3909
+ :see: https://www.gate.io/docs/developers/apiv4/en/#create-an-order
3910
+ :param str symbol: unified symbol of the market to create an order in
3911
+ :param float cost: how much you want to trade in units of the quote currency
3912
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3913
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
3914
+ """
3915
+ await self.load_markets()
3916
+ market = self.market(symbol)
3917
+ if not market['spot']:
3918
+ raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
3919
+ params['createMarketBuyOrderRequiresPrice'] = False
3920
+ return await self.create_order(symbol, 'market', 'buy', cost, None, params)
3921
+
3889
3922
  async def edit_order(self, id: str, symbol, type, side, amount=None, price=None, params={}):
3890
3923
  """
3891
3924
  edit a trade order, gate currently only supports the modification of the price or amount fields
@@ -5341,6 +5374,201 @@ class gate(Exchange, ImplicitAPI):
5341
5374
  floor = cap
5342
5375
  return tiers
5343
5376
 
5377
+ async def repay_isolated_margin(self, symbol: str, code: str, amount, params={}):
5378
+ """
5379
+ repay borrowed margin and interest
5380
+ :see: https://www.gate.io/docs/apiv4/en/#repay-a-loan
5381
+ :param str symbol: unified market symbol
5382
+ :param str code: unified currency code of the currency to repay
5383
+ :param float amount: the amount to repay
5384
+ :param dict [params]: extra parameters specific to the exchange API endpoint
5385
+ :param str [params.mode]: 'all' or 'partial' payment mode, extra parameter required for isolated margin
5386
+ :param str [params.id]: '34267567' loan id, extra parameter required for isolated margin
5387
+ :returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
5388
+ """
5389
+ await self.load_markets()
5390
+ currency = self.currency(code)
5391
+ request = {
5392
+ 'currency': currency['id'].upper(),
5393
+ 'amount': self.currency_to_precision(code, amount),
5394
+ }
5395
+ market = self.market(symbol)
5396
+ request['currency_pair'] = market['id']
5397
+ request['type'] = 'repay'
5398
+ response = await self.privateMarginPostUniLoans(self.extend(request, params))
5399
+ #
5400
+ # empty response
5401
+ #
5402
+ return self.parse_margin_loan(response, currency)
5403
+
5404
+ async def repay_cross_margin(self, code: str, amount, params={}):
5405
+ """
5406
+ repay cross margin borrowed margin and interest
5407
+ :see: https://www.gate.io/docs/developers/apiv4/en/#cross-margin-repayments
5408
+ :param str code: unified currency code of the currency to repay
5409
+ :param float amount: the amount to repay
5410
+ :param str symbol: unified market symbol, required for isolated margin
5411
+ :param dict [params]: extra parameters specific to the exchange API endpoint
5412
+ :param str [params.mode]: 'all' or 'partial' payment mode, extra parameter required for isolated margin
5413
+ :param str [params.id]: '34267567' loan id, extra parameter required for isolated margin
5414
+ :returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
5415
+ """
5416
+ await self.load_markets()
5417
+ currency = self.currency(code)
5418
+ request = {
5419
+ 'currency': currency['id'].upper(),
5420
+ 'amount': self.currency_to_precision(code, amount),
5421
+ }
5422
+ response = await self.privateMarginPostCrossRepayments(self.extend(request, params))
5423
+ #
5424
+ # [
5425
+ # {
5426
+ # "id": "17",
5427
+ # "create_time": 1620381696159,
5428
+ # "update_time": 1620381696159,
5429
+ # "currency": "EOS",
5430
+ # "amount": "110.553635",
5431
+ # "text": "web",
5432
+ # "status": 2,
5433
+ # "repaid": "110.506649705159",
5434
+ # "repaid_interest": "0.046985294841",
5435
+ # "unpaid_interest": "0.0000074393366667"
5436
+ # }
5437
+ # ]
5438
+ #
5439
+ response = self.safe_value(response, 0)
5440
+ return self.parse_margin_loan(response, currency)
5441
+
5442
+ async def borrow_isolated_margin(self, symbol: str, code: str, amount, params={}):
5443
+ """
5444
+ create a loan to borrow margin
5445
+ :see: https://www.gate.io/docs/developers/apiv4/en/#marginuni
5446
+ :param str code: unified currency code of the currency to borrow
5447
+ :param float amount: the amount to borrow
5448
+ :param str symbol: unified market symbol, required for isolated margin
5449
+ :param dict [params]: extra parameters specific to the exchange API endpoint
5450
+ :param str [params.rate]: '0.0002' or '0.002' extra parameter required for isolated margin
5451
+ :returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
5452
+ """
5453
+ await self.load_markets()
5454
+ currency = self.currency(code)
5455
+ request = {
5456
+ 'currency': currency['id'].upper(),
5457
+ 'amount': self.currency_to_precision(code, amount),
5458
+ }
5459
+ response = None
5460
+ market = self.market(symbol)
5461
+ request['currency_pair'] = market['id']
5462
+ request['type'] = 'borrow'
5463
+ response = await self.privateMarginPostUniLoans(self.extend(request, params))
5464
+ #
5465
+ # {
5466
+ # "id": "34267567",
5467
+ # "create_time": "1656394778",
5468
+ # "expire_time": "1657258778",
5469
+ # "status": "loaned",
5470
+ # "side": "borrow",
5471
+ # "currency": "USDT",
5472
+ # "rate": "0.0002",
5473
+ # "amount": "100",
5474
+ # "days": 10,
5475
+ # "auto_renew": False,
5476
+ # "currency_pair": "LTC_USDT",
5477
+ # "left": "0",
5478
+ # "repaid": "0",
5479
+ # "paid_interest": "0",
5480
+ # "unpaid_interest": "0.003333333333"
5481
+ # }
5482
+ #
5483
+ return self.parse_margin_loan(response, currency)
5484
+
5485
+ async def borrow_cross_margin(self, code: str, amount, params={}):
5486
+ """
5487
+ create a loan to borrow margin
5488
+ :see: https://www.gate.io/docs/apiv4/en/#create-a-cross-margin-borrow-loan
5489
+ :param str code: unified currency code of the currency to borrow
5490
+ :param float amount: the amount to borrow
5491
+ :param str symbol: unified market symbol, required for isolated margin
5492
+ :param dict [params]: extra parameters specific to the exchange API endpoint
5493
+ :param str [params.rate]: '0.0002' or '0.002' extra parameter required for isolated margin
5494
+ :returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
5495
+ """
5496
+ await self.load_markets()
5497
+ currency = self.currency(code)
5498
+ request = {
5499
+ 'currency': currency['id'].upper(),
5500
+ 'amount': self.currency_to_precision(code, amount),
5501
+ }
5502
+ response = await self.privateMarginPostCrossLoans(self.extend(request, params))
5503
+ #
5504
+ # {
5505
+ # "id": "17",
5506
+ # "create_time": 1620381696159,
5507
+ # "update_time": 1620381696159,
5508
+ # "currency": "EOS",
5509
+ # "amount": "110.553635",
5510
+ # "text": "web",
5511
+ # "status": 2,
5512
+ # "repaid": "110.506649705159",
5513
+ # "repaid_interest": "0.046985294841",
5514
+ # "unpaid_interest": "0.0000074393366667"
5515
+ # }
5516
+ #
5517
+ return self.parse_margin_loan(response, currency)
5518
+
5519
+ def parse_margin_loan(self, info, currency: Currency = None):
5520
+ #
5521
+ # Cross
5522
+ #
5523
+ # {
5524
+ # "id": "17",
5525
+ # "create_time": 1620381696159,
5526
+ # "update_time": 1620381696159,
5527
+ # "currency": "EOS",
5528
+ # "amount": "110.553635",
5529
+ # "text": "web",
5530
+ # "status": 2,
5531
+ # "repaid": "110.506649705159",
5532
+ # "repaid_interest": "0.046985294841",
5533
+ # "unpaid_interest": "0.0000074393366667"
5534
+ # }
5535
+ #
5536
+ # Isolated
5537
+ #
5538
+ # {
5539
+ # "id": "34267567",
5540
+ # "create_time": "1656394778",
5541
+ # "expire_time": "1657258778",
5542
+ # "status": "loaned",
5543
+ # "side": "borrow",
5544
+ # "currency": "USDT",
5545
+ # "rate": "0.0002",
5546
+ # "amount": "100",
5547
+ # "days": 10,
5548
+ # "auto_renew": False,
5549
+ # "currency_pair": "LTC_USDT",
5550
+ # "left": "0",
5551
+ # "repaid": "0",
5552
+ # "paid_interest": "0",
5553
+ # "unpaid_interest": "0.003333333333"
5554
+ # }
5555
+ #
5556
+ marginMode = self.safe_string_2(self.options, 'defaultMarginMode', 'marginMode', 'cross')
5557
+ timestamp = self.safe_integer(info, 'create_time')
5558
+ if marginMode == 'isolated':
5559
+ timestamp = self.safe_timestamp(info, 'create_time')
5560
+ currencyId = self.safe_string(info, 'currency')
5561
+ marketId = self.safe_string(info, 'currency_pair')
5562
+ return {
5563
+ 'id': self.safe_integer(info, 'id'),
5564
+ 'currency': self.safe_currency_code(currencyId, currency),
5565
+ 'amount': self.safe_number(info, 'amount'),
5566
+ 'symbol': self.safe_symbol(marketId, None, '_', 'margin'),
5567
+ 'timestamp': timestamp,
5568
+ 'datetime': self.iso8601(timestamp),
5569
+ 'info': info,
5570
+ }
5571
+
5344
5572
  def sign(self, path, api=[], method='GET', params={}, headers=None, body=None):
5345
5573
  authentication = api[0] # public, private
5346
5574
  type = api[1] # spot, margin, future, delivery
@@ -6266,6 +6494,25 @@ class gate(Exchange, ImplicitAPI):
6266
6494
  'info': greeks,
6267
6495
  }
6268
6496
 
6497
+ async def close_position(self, symbol: str, side: OrderSide = None, params={}) -> Order:
6498
+ """
6499
+ closes open positions for a market
6500
+ :see: https://www.gate.io/docs/developers/apiv4/en/#create-a-futures-order
6501
+ :see: https://www.gate.io/docs/developers/apiv4/en/#create-a-futures-order-2
6502
+ :see: https://www.gate.io/docs/developers/apiv4/en/#create-an-options-order
6503
+ :param str symbol: Unified CCXT market symbol
6504
+ :param str side: 'buy' or 'sell'
6505
+ :param dict [params]: extra parameters specific to the okx api endpoint
6506
+ :returns [dict]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
6507
+ """
6508
+ request = {
6509
+ 'close': True,
6510
+ }
6511
+ params = self.extend(request, params)
6512
+ if side is None:
6513
+ side = '' # side is not used but needs to be present, otherwise crashes in php
6514
+ return await self.create_order(symbol, 'market', side, 0, None, params)
6515
+
6269
6516
  def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
6270
6517
  if response is None:
6271
6518
  return None