ccxt 4.4.23__py2.py3-none-any.whl → 4.4.24__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/bybit.py CHANGED
@@ -1026,6 +1026,7 @@ class bybit(Exchange, ImplicitAPI):
1026
1026
  },
1027
1027
  'enableUnifiedMargin': None,
1028
1028
  'enableUnifiedAccount': None,
1029
+ 'unifiedMarginStatus': None,
1029
1030
  'createMarketBuyOrderRequiresPrice': True, # only True for classic accounts
1030
1031
  'createUnifiedMarginAccount': False,
1031
1032
  'defaultType': 'swap', # 'swap', 'future', 'option', 'spot'
@@ -1145,6 +1146,8 @@ class bybit(Exchange, ImplicitAPI):
1145
1146
 
1146
1147
  def is_unified_enabled(self, params={}):
1147
1148
  """
1149
+ :see: https://bybit-exchange.github.io/docs/v5/user/apikey-info#http-request
1150
+ :see: https://bybit-exchange.github.io/docs/v5/account/account-info
1148
1151
  returns [enableUnifiedMargin, enableUnifiedAccount] so the user can check if unified account is enabled
1149
1152
  """
1150
1153
  # The API key of user id must own one of permissions will be allowed to call following API endpoints.
@@ -1158,8 +1161,12 @@ class bybit(Exchange, ImplicitAPI):
1158
1161
  # so we're assuming UTA is enabled
1159
1162
  self.options['enableUnifiedMargin'] = False
1160
1163
  self.options['enableUnifiedAccount'] = True
1164
+ self.options['unifiedMarginStatus'] = 3
1161
1165
  return [self.options['enableUnifiedMargin'], self.options['enableUnifiedAccount']]
1162
- response = self.privateGetV5UserQueryApi(params)
1166
+ rawPromises = [self.privateGetV5UserQueryApi(params), self.privateGetV5AccountInfo(params)]
1167
+ promises = rawPromises
1168
+ response = promises[0]
1169
+ accountInfo = promises[1]
1163
1170
  #
1164
1171
  # {
1165
1172
  # "retCode": 0,
@@ -1199,13 +1206,34 @@ class bybit(Exchange, ImplicitAPI):
1199
1206
  # "retExtInfo": {},
1200
1207
  # "time": 1676891757649
1201
1208
  # }
1209
+ # account info
1210
+ # {
1211
+ # "retCode": 0,
1212
+ # "retMsg": "OK",
1213
+ # "result": {
1214
+ # "marginMode": "REGULAR_MARGIN",
1215
+ # "updatedTime": "1697078946000",
1216
+ # "unifiedMarginStatus": 4,
1217
+ # "dcpStatus": "OFF",
1218
+ # "timeWindow": 10,
1219
+ # "smpGroup": 0,
1220
+ # "isMasterTrader": False,
1221
+ # "spotHedgingStatus": "OFF"
1222
+ # }
1223
+ # }
1202
1224
  #
1203
1225
  result = self.safe_dict(response, 'result', {})
1226
+ accountResult = self.safe_dict(accountInfo, 'result', {})
1204
1227
  self.options['enableUnifiedMargin'] = self.safe_integer(result, 'unified') == 1
1205
1228
  self.options['enableUnifiedAccount'] = self.safe_integer(result, 'uta') == 1
1229
+ self.options['unifiedMarginStatus'] = self.safe_integer(accountResult, 'unifiedMarginStatus', 3) # default to uta.1 if not found
1206
1230
  return [self.options['enableUnifiedMargin'], self.options['enableUnifiedAccount']]
1207
1231
 
1208
1232
  def upgrade_unified_trade_account(self, params={}):
1233
+ """
1234
+ :see: https://bybit-exchange.github.io/docs/v5/account/upgrade-unified-account
1235
+ upgrades the account to unified trade account *warning* self is irreversible
1236
+ """
1209
1237
  return self.privatePostV5AccountUpgradeToUta(params)
1210
1238
 
1211
1239
  def create_expired_option_market(self, symbol: str):
@@ -3018,10 +3046,15 @@ class bybit(Exchange, ImplicitAPI):
3018
3046
  isInverse = (type == 'inverse')
3019
3047
  isFunding = (lowercaseRawType == 'fund') or (lowercaseRawType == 'funding')
3020
3048
  if isUnifiedAccount:
3021
- if isInverse:
3022
- type = 'contract'
3049
+ unifiedMarginStatus = self.safe_integer(self.options, 'unifiedMarginStatus', 3)
3050
+ if unifiedMarginStatus < 5:
3051
+ # it's not uta.20 where inverse are unified
3052
+ if isInverse:
3053
+ type = 'contract'
3054
+ else:
3055
+ type = 'unified'
3023
3056
  else:
3024
- type = 'unified'
3057
+ type = 'unified' # uta.20 where inverse are unified
3025
3058
  else:
3026
3059
  if isLinear or isInverse:
3027
3060
  type = 'contract'
ccxt/coincatch.py CHANGED
@@ -154,7 +154,7 @@ class coincatch(Exchange, ImplicitAPI):
154
154
  '1M': '1M',
155
155
  },
156
156
  'urls': {
157
- 'logo': 'https://private-user-images.githubusercontent.com/43336371/379178446-b99d8af1-3016-4775-ac37-d5016dccb000.jpeg?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mjk2NzMxOTksIm5iZiI6MTcyOTY3Mjg5OSwicGF0aCI6Ii80MzMzNjM3MS8zNzkxNzg0NDYtYjk5ZDhhZjEtMzAxNi00Nzc1LWFjMzctZDUwMTZkY2NiMDAwLmpwZWc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQxMDIzJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MTAyM1QwODQxMzlaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0xMTkzNTAzYjhlYzg5ODU4ZjFhYzgwZTg3MGFmYjk5MWViMjMwNDY5ZGU4NDRlNGU0NmUxYTgxMzM3OTNlZWM4JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.tosowLHE9p_cKbY8dPPduHXFVJQrUZ8qzGBOTCCznvw',
157
+ 'logo': 'https://github.com/user-attachments/assets/3d49065f-f05d-4573-88a2-1b5201ec6ff3',
158
158
  'api': {
159
159
  'public': 'https://api.coincatch.com',
160
160
  'private': 'https://api.coincatch.com',
ccxt/gate.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.gate import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currencies, Currency, DepositAddress, FundingHistory, Greeks, Int, LedgerEntry, Leverage, Leverages, LeverageTier, LeverageTiers, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
9
+ from ccxt.base.types import Balances, Bool, Currencies, Currency, DepositAddress, FundingHistory, Greeks, Int, LedgerEntry, Leverage, Leverages, LeverageTier, LeverageTiers, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -117,6 +117,7 @@ class gate(Exchange, ImplicitAPI):
117
117
  'createTriggerOrder': True,
118
118
  'editOrder': True,
119
119
  'fetchBalance': True,
120
+ 'fetchBorrowInterest': True,
120
121
  'fetchBorrowRateHistories': False,
121
122
  'fetchBorrowRateHistory': False,
122
123
  'fetchClosedOrders': True,
@@ -1522,7 +1523,7 @@ class gate(Exchange, ImplicitAPI):
1522
1523
  request['currency_pair'] = market['id'] # Should always be set for non-stop
1523
1524
  return [request, query]
1524
1525
 
1525
- def multi_order_spot_prepare_request(self, market=None, stop=False, params={}):
1526
+ def multi_order_spot_prepare_request(self, market=None, trigger=False, params={}):
1526
1527
  """
1527
1528
  * @ignore
1528
1529
  Fills request params currency_pair, market and account where applicable for spot order methods like fetchOpenOrders, cancelAllOrders
@@ -1531,12 +1532,12 @@ class gate(Exchange, ImplicitAPI):
1531
1532
  :param dict [params]: request parameters
1532
1533
  :returns: the api request object, and the new params object with non-needed parameters removed
1533
1534
  """
1534
- marginMode, query = self.get_margin_mode(stop, params)
1535
+ marginMode, query = self.get_margin_mode(trigger, params)
1535
1536
  request: dict = {
1536
1537
  'account': marginMode,
1537
1538
  }
1538
1539
  if market is not None:
1539
- if stop:
1540
+ if trigger:
1540
1541
  # gate spot and margin stop orders use the term market instead of currency_pair, and normal instead of spot. Neither parameter is used when fetching/cancelling a single order. They are used for creating a single stop order, but createOrder does not call self method
1541
1542
  request['market'] = market['id']
1542
1543
  else:
@@ -1566,6 +1567,10 @@ class gate(Exchange, ImplicitAPI):
1566
1567
  marginMode = 'normal'
1567
1568
  if marginMode == 'cross_margin':
1568
1569
  raise BadRequest(self.id + ' getMarginMode() does not support stop orders for cross margin')
1570
+ isUnifiedAccount = False
1571
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'getMarginMode', 'unifiedAccount')
1572
+ if isUnifiedAccount:
1573
+ marginMode = 'unified'
1569
1574
  return [marginMode, params]
1570
1575
 
1571
1576
  def get_settlement_currencies(self, type, method):
@@ -3202,10 +3207,12 @@ class gate(Exchange, ImplicitAPI):
3202
3207
  :param int [params.offset]: *contract only* list offset, starting from 0
3203
3208
  :param str [params.last_id]: *contract only* specify list staring point using the id of last record in previous list-query results
3204
3209
  :param int [params.count_total]: *contract only* whether to return total number matched, default to 0(no return)
3205
- :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
3210
+ :param bool [params.unifiedAccount]: set to True for fetching trades in a unified account
3211
+ :param bool [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
3206
3212
  :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
3207
3213
  """
3208
3214
  self.load_markets()
3215
+ self.load_unified_status()
3209
3216
  paginate = False
3210
3217
  paginate, params = self.handle_option_and_params(params, 'fetchMyTrades', 'paginate')
3211
3218
  if paginate:
@@ -3723,9 +3730,11 @@ class gate(Exchange, ImplicitAPI):
3723
3730
  :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
3724
3731
  :param int [params.price_type]: *contract only* 0 latest deal price, 1 mark price, 2 index price
3725
3732
  :param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
3733
+ :param bool [params.unifiedAccount]: set to True for creating an order in the unified account
3726
3734
  :returns dict|None: `An order structure <https://docs.ccxt.com/#/?id=order-structure>`
3727
3735
  """
3728
3736
  self.load_markets()
3737
+ self.load_unified_status()
3729
3738
  market = self.market(symbol)
3730
3739
  trigger = self.safe_value(params, 'trigger')
3731
3740
  triggerPrice = self.safe_value_2(params, 'triggerPrice', 'stopPrice')
@@ -3860,6 +3869,7 @@ class gate(Exchange, ImplicitAPI):
3860
3869
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
3861
3870
  """
3862
3871
  self.load_markets()
3872
+ self.load_unified_status()
3863
3873
  ordersRequests = self.create_orders_request(orders, params)
3864
3874
  firstOrder = orders[0]
3865
3875
  market = self.market(firstOrder['symbol'])
@@ -3947,7 +3957,7 @@ class gate(Exchange, ImplicitAPI):
3947
3957
  # 'text': clientOrderId, # 't-abcdef1234567890',
3948
3958
  'currency_pair': market['id'], # filled in prepareRequest above
3949
3959
  'type': type,
3950
- 'account': marginMode, # 'spot', 'margin', 'cross_margin'
3960
+ 'account': marginMode, # spot, margin, cross_margin, unified
3951
3961
  'side': side,
3952
3962
  # 'time_in_force': 'gtc', # gtc, ioc, poc PendingOrCancelled == postOnly order
3953
3963
  # 'iceberg': 0, # amount to display for the iceberg order, null or 0 for normal orders, set to -1 to hide the order completely
@@ -4088,9 +4098,11 @@ class gate(Exchange, ImplicitAPI):
4088
4098
  :param str symbol: unified symbol of the market to create an order in
4089
4099
  :param float cost: how much you want to trade in units of the quote currency
4090
4100
  :param dict [params]: extra parameters specific to the exchange API endpoint
4101
+ :param bool [params.unifiedAccount]: set to True for creating a unified account order
4091
4102
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4092
4103
  """
4093
4104
  self.load_markets()
4105
+ self.load_unified_status()
4094
4106
  market = self.market(symbol)
4095
4107
  if not market['spot']:
4096
4108
  raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
@@ -4099,8 +4111,13 @@ class gate(Exchange, ImplicitAPI):
4099
4111
 
4100
4112
  def edit_order_request(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
4101
4113
  market = self.market(symbol)
4102
- marketType, query = self.handle_market_type_and_params('editOrder', market, params)
4114
+ marketType = None
4115
+ marketType, params = self.handle_market_type_and_params('editOrder', market, params)
4103
4116
  account = self.convert_type_to_account(marketType)
4117
+ isUnifiedAccount = False
4118
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'editOrder', 'unifiedAccount')
4119
+ if isUnifiedAccount:
4120
+ account = 'unified'
4104
4121
  isLimitOrder = (type == 'limit')
4105
4122
  if account == 'spot':
4106
4123
  if not isLimitOrder:
@@ -4123,7 +4140,7 @@ class gate(Exchange, ImplicitAPI):
4123
4140
  request['price'] = self.price_to_precision(symbol, price)
4124
4141
  if not market['spot']:
4125
4142
  request['settle'] = market['settleId']
4126
- return self.extend(request, query)
4143
+ return self.extend(request, params)
4127
4144
 
4128
4145
  def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
4129
4146
  """
@@ -4137,9 +4154,11 @@ class gate(Exchange, ImplicitAPI):
4137
4154
  :param float amount: how much of the currency you want to trade in units of the base currency
4138
4155
  :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
4139
4156
  :param dict [params]: extra parameters specific to the exchange API endpoint
4157
+ :param bool [params.unifiedAccount]: set to True for editing an order in a unified account
4140
4158
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4141
4159
  """
4142
4160
  self.load_markets()
4161
+ self.load_unified_status()
4143
4162
  market = self.market(symbol)
4144
4163
  extendedRequest = self.edit_order_request(id, symbol, type, side, amount, price, params)
4145
4164
  response = None
@@ -4392,19 +4411,19 @@ class gate(Exchange, ImplicitAPI):
4392
4411
  # Everything below self(above return) is related to fees
4393
4412
  fees = []
4394
4413
  gtFee = self.safe_string(order, 'gt_fee')
4395
- if gtFee:
4414
+ if gtFee is not None:
4396
4415
  fees.append({
4397
4416
  'currency': 'GT',
4398
4417
  'cost': gtFee,
4399
4418
  })
4400
4419
  fee = self.safe_string(order, 'fee')
4401
- if fee:
4420
+ if fee is not None:
4402
4421
  fees.append({
4403
4422
  'currency': self.safe_currency_code(self.safe_string(order, 'fee_currency')),
4404
4423
  'cost': fee,
4405
4424
  })
4406
4425
  rebate = self.safe_string(order, 'rebated_fee')
4407
- if rebate:
4426
+ if rebate is not None:
4408
4427
  fees.append({
4409
4428
  'currency': self.safe_currency_code(self.safe_string(order, 'rebated_fee_currency')),
4410
4429
  'cost': Precise.string_neg(rebate),
@@ -4481,9 +4500,11 @@ class gate(Exchange, ImplicitAPI):
4481
4500
  :param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
4482
4501
  :param str [params.type]: 'spot', 'swap', or 'future', if not provided self.options['defaultMarginMode'] is used
4483
4502
  :param str [params.settle]: 'btc' or 'usdt' - settle currency for perpetual swap and future - market settle currency is used if symbol is not None, default="usdt" for swap and "btc" for future
4503
+ :param bool [params.unifiedAccount]: set to True for fetching a unified account order
4484
4504
  :returns: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4485
4505
  """
4486
4506
  self.load_markets()
4507
+ self.load_unified_status()
4487
4508
  market = None if (symbol is None) else self.market(symbol)
4488
4509
  result = self.handle_market_type_and_params('fetchOrder', market, params)
4489
4510
  type = self.safe_string(result, 0)
@@ -4523,6 +4544,7 @@ class gate(Exchange, ImplicitAPI):
4523
4544
  :param bool [params.stop]: True for fetching stop orders
4524
4545
  :param str [params.type]: spot, margin, swap or future, if not provided self.options['defaultType'] is used
4525
4546
  :param str [params.marginMode]: 'cross' or 'isolated' - marginMode for type='margin', if not provided self.options['defaultMarginMode'] is used
4547
+ :param bool [params.unifiedAccount]: set to True for fetching unified account orders
4526
4548
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4527
4549
  """
4528
4550
  return self.fetch_orders_by_status('open', symbol, since, limit, params)
@@ -4546,9 +4568,11 @@ class gate(Exchange, ImplicitAPI):
4546
4568
  :param str [params.type]: spot, swap or future, if not provided self.options['defaultType'] is used
4547
4569
  :param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
4548
4570
  :param boolean [params.historical]: *swap only* True for using historical endpoint
4571
+ :param bool [params.unifiedAccount]: set to True for fetching unified account orders
4549
4572
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4550
4573
  """
4551
4574
  self.load_markets()
4575
+ self.load_unified_status()
4552
4576
  until = self.safe_integer(params, 'until')
4553
4577
  market = None
4554
4578
  if symbol is not None:
@@ -4578,13 +4602,15 @@ class gate(Exchange, ImplicitAPI):
4578
4602
  if symbol is not None:
4579
4603
  market = self.market(symbol)
4580
4604
  symbol = market['symbol']
4581
- stop = self.safe_bool_2(params, 'stop', 'trigger')
4582
- params = self.omit(params, ['stop', 'trigger'])
4605
+ trigger: Bool = None
4606
+ trigger, params = self.handle_param_bool_2(params, 'trigger', 'stop')
4583
4607
  type: Str = None
4584
4608
  type, params = self.handle_market_type_and_params('fetchOrdersByStatus', market, params)
4585
4609
  spot = (type == 'spot') or (type == 'margin')
4586
4610
  request: dict = {}
4587
- request, params = self.multi_order_spot_prepare_request(market, stop, params) if spot else self.prepare_request(market, type, params)
4611
+ request, params = self.multi_order_spot_prepare_request(market, trigger, params) if spot else self.prepare_request(market, type, params)
4612
+ if spot and trigger:
4613
+ request = self.omit(request, 'account')
4588
4614
  if status == 'closed':
4589
4615
  status = 'finished'
4590
4616
  request['status'] = status
@@ -4604,33 +4630,35 @@ class gate(Exchange, ImplicitAPI):
4604
4630
 
4605
4631
  def fetch_orders_by_status(self, status, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4606
4632
  self.load_markets()
4633
+ self.load_unified_status()
4607
4634
  market = None
4608
4635
  if symbol is not None:
4609
4636
  market = self.market(symbol)
4610
4637
  symbol = market['symbol']
4611
- stop = self.safe_bool_2(params, 'stop', 'trigger')
4612
- params = self.omit(params, ['trigger', 'stop'])
4638
+ # don't omit here, omits done in prepareOrdersByStatusRequest
4639
+ trigger: Bool = self.safe_bool_2(params, 'trigger', 'stop')
4613
4640
  res = self.handle_market_type_and_params('fetchOrdersByStatus', market, params)
4614
4641
  type = self.safe_string(res, 0)
4615
- params['type'] = type
4616
4642
  request, requestParams = self.prepare_orders_by_status_request(status, symbol, since, limit, params)
4617
4643
  spot = (type == 'spot') or (type == 'margin')
4618
- openSpotOrders = spot and (status == 'open') and not stop
4644
+ openStatus = (status == 'open')
4645
+ openSpotOrders = spot and openStatus and not trigger
4619
4646
  response = None
4620
- if type == 'spot' or type == 'margin':
4621
- if openSpotOrders:
4622
- response = self.privateSpotGetOpenOrders(self.extend(request, requestParams))
4623
- elif stop:
4624
- response = self.privateSpotGetPriceOrders(self.extend(request, requestParams))
4647
+ if spot:
4648
+ if not trigger:
4649
+ if openStatus:
4650
+ response = self.privateSpotGetOpenOrders(self.extend(request, requestParams))
4651
+ else:
4652
+ response = self.privateSpotGetOrders(self.extend(request, requestParams))
4625
4653
  else:
4626
- response = self.privateSpotGetOrders(self.extend(request, requestParams))
4654
+ response = self.privateSpotGetPriceOrders(self.extend(request, requestParams))
4627
4655
  elif type == 'swap':
4628
- if stop:
4656
+ if trigger:
4629
4657
  response = self.privateFuturesGetSettlePriceOrders(self.extend(request, requestParams))
4630
4658
  else:
4631
4659
  response = self.privateFuturesGetSettleOrders(self.extend(request, requestParams))
4632
4660
  elif type == 'future':
4633
- if stop:
4661
+ if trigger:
4634
4662
  response = self.privateDeliveryGetSettlePriceOrders(self.extend(request, requestParams))
4635
4663
  else:
4636
4664
  response = self.privateDeliveryGetSettleOrders(self.extend(request, requestParams))
@@ -4804,9 +4832,11 @@ class gate(Exchange, ImplicitAPI):
4804
4832
  :param str symbol: Unified market symbol
4805
4833
  :param dict [params]: Parameters specified by the exchange api
4806
4834
  :param bool [params.stop]: True if the order to be cancelled is a trigger order
4835
+ :param bool [params.unifiedAccount]: set to True for canceling unified account orders
4807
4836
  :returns: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4808
4837
  """
4809
4838
  self.load_markets()
4839
+ self.load_unified_status()
4810
4840
  market = None if (symbol is None) else self.market(symbol)
4811
4841
  stop = self.safe_bool_n(params, ['is_stop_order', 'stop', 'trigger'], False)
4812
4842
  params = self.omit(params, ['is_stop_order', 'stop', 'trigger'])
@@ -4924,9 +4954,11 @@ class gate(Exchange, ImplicitAPI):
4924
4954
  :param str[] ids: order ids
4925
4955
  :param str symbol: unified symbol of the market the order was made in
4926
4956
  :param dict [params]: extra parameters specific to the exchange API endpoint
4957
+ :param bool [params.unifiedAccount]: set to True for canceling unified account orders
4927
4958
  :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4928
4959
  """
4929
4960
  self.load_markets()
4961
+ self.load_unified_status()
4930
4962
  market = None
4931
4963
  if symbol is not None:
4932
4964
  market = self.market(symbol)
@@ -4963,9 +4995,11 @@ class gate(Exchange, ImplicitAPI):
4963
4995
  :param CancellationRequest[] orders: list of order ids with symbol, example [{"id": "a", "symbol": "BTC/USDT"}, {"id": "b", "symbol": "ETH/USDT"}]
4964
4996
  :param dict [params]: extra parameters specific to the exchange API endpoint
4965
4997
  :param str[] [params.clientOrderIds]: client order ids
4998
+ :param bool [params.unifiedAccount]: set to True for canceling unified account orders
4966
4999
  :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4967
5000
  """
4968
5001
  self.load_markets()
5002
+ self.load_unified_status()
4969
5003
  ordersRequests = []
4970
5004
  for i in range(0, len(orders)):
4971
5005
  order = orders[i]
@@ -4999,9 +5033,11 @@ class gate(Exchange, ImplicitAPI):
4999
5033
  :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-matched-3
5000
5034
  :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
5001
5035
  :param dict [params]: extra parameters specific to the exchange API endpoint
5036
+ :param bool [params.unifiedAccount]: set to True for canceling unified account orders
5002
5037
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
5003
5038
  """
5004
5039
  self.load_markets()
5040
+ self.load_unified_status()
5005
5041
  market = None if (symbol is None) else self.market(symbol)
5006
5042
  stop = self.safe_bool_2(params, 'stop', 'trigger')
5007
5043
  params = self.omit(params, ['stop', 'trigger'])
@@ -5748,38 +5784,48 @@ class gate(Exchange, ImplicitAPI):
5748
5784
  """
5749
5785
  repay cross margin borrowed margin and interest
5750
5786
  :see: https://www.gate.io/docs/developers/apiv4/en/#cross-margin-repayments
5787
+ :see: https://www.gate.io/docs/developers/apiv4/en/#borrow-or-repay
5751
5788
  :param str code: unified currency code of the currency to repay
5752
5789
  :param float amount: the amount to repay
5753
5790
  :param str symbol: unified market symbol, required for isolated margin
5754
5791
  :param dict [params]: extra parameters specific to the exchange API endpoint
5755
5792
  :param str [params.mode]: 'all' or 'partial' payment mode, extra parameter required for isolated margin
5756
5793
  :param str [params.id]: '34267567' loan id, extra parameter required for isolated margin
5794
+ :param boolean [params.unifiedAccount]: set to True for repaying in the unified account
5757
5795
  :returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
5758
5796
  """
5759
5797
  self.load_markets()
5798
+ self.load_unified_status()
5760
5799
  currency = self.currency(code)
5761
5800
  request: dict = {
5762
5801
  'currency': currency['id'].upper(), # todo: currencies have network-junctions
5763
5802
  'amount': self.currency_to_precision(code, amount),
5764
5803
  }
5765
- response = self.privateMarginPostCrossRepayments(self.extend(request, params))
5766
- #
5767
- # [
5768
- # {
5769
- # "id": "17",
5770
- # "create_time": 1620381696159,
5771
- # "update_time": 1620381696159,
5772
- # "currency": "EOS",
5773
- # "amount": "110.553635",
5774
- # "text": "web",
5775
- # "status": 2,
5776
- # "repaid": "110.506649705159",
5777
- # "repaid_interest": "0.046985294841",
5778
- # "unpaid_interest": "0.0000074393366667"
5779
- # }
5780
- # ]
5781
- #
5782
- response = self.safe_value(response, 0)
5804
+ isUnifiedAccount = False
5805
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'repayCrossMargin', 'unifiedAccount')
5806
+ response = None
5807
+ if isUnifiedAccount:
5808
+ request['type'] = 'repay'
5809
+ response = self.privateUnifiedPostLoans(self.extend(request, params))
5810
+ else:
5811
+ response = self.privateMarginPostCrossRepayments(self.extend(request, params))
5812
+ response = self.safe_dict(response, 0)
5813
+ #
5814
+ # [
5815
+ # {
5816
+ # "id": "17",
5817
+ # "create_time": 1620381696159,
5818
+ # "update_time": 1620381696159,
5819
+ # "currency": "EOS",
5820
+ # "amount": "110.553635",
5821
+ # "text": "web",
5822
+ # "status": 2,
5823
+ # "repaid": "110.506649705159",
5824
+ # "repaid_interest": "0.046985294841",
5825
+ # "unpaid_interest": "0.0000074393366667"
5826
+ # }
5827
+ # ]
5828
+ #
5783
5829
  return self.parse_margin_loan(response, currency)
5784
5830
 
5785
5831
  def borrow_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
@@ -5829,34 +5875,44 @@ class gate(Exchange, ImplicitAPI):
5829
5875
  """
5830
5876
  create a loan to borrow margin
5831
5877
  :see: https://www.gate.io/docs/apiv4/en/#create-a-cross-margin-borrow-loan
5878
+ :see: https://www.gate.io/docs/developers/apiv4/en/#borrow-or-repay
5832
5879
  :param str code: unified currency code of the currency to borrow
5833
5880
  :param float amount: the amount to borrow
5834
5881
  :param str symbol: unified market symbol, required for isolated margin
5835
5882
  :param dict [params]: extra parameters specific to the exchange API endpoint
5836
5883
  :param str [params.rate]: '0.0002' or '0.002' extra parameter required for isolated margin
5884
+ :param boolean [params.unifiedAccount]: set to True for borrowing in the unified account
5837
5885
  :returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
5838
5886
  """
5839
5887
  self.load_markets()
5888
+ self.load_unified_status()
5840
5889
  currency = self.currency(code)
5841
5890
  request: dict = {
5842
5891
  'currency': currency['id'].upper(), # todo: currencies have network-junctions
5843
5892
  'amount': self.currency_to_precision(code, amount),
5844
5893
  }
5845
- response = self.privateMarginPostCrossLoans(self.extend(request, params))
5846
- #
5847
- # {
5848
- # "id": "17",
5849
- # "create_time": 1620381696159,
5850
- # "update_time": 1620381696159,
5851
- # "currency": "EOS",
5852
- # "amount": "110.553635",
5853
- # "text": "web",
5854
- # "status": 2,
5855
- # "repaid": "110.506649705159",
5856
- # "repaid_interest": "0.046985294841",
5857
- # "unpaid_interest": "0.0000074393366667"
5858
- # }
5859
- #
5894
+ isUnifiedAccount = False
5895
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'borrowCrossMargin', 'unifiedAccount')
5896
+ response = None
5897
+ if isUnifiedAccount:
5898
+ request['type'] = 'borrow'
5899
+ response = self.privateUnifiedPostLoans(self.extend(request, params))
5900
+ else:
5901
+ response = self.privateMarginPostCrossLoans(self.extend(request, params))
5902
+ #
5903
+ # {
5904
+ # "id": "17",
5905
+ # "create_time": 1620381696159,
5906
+ # "update_time": 1620381696159,
5907
+ # "currency": "EOS",
5908
+ # "amount": "110.553635",
5909
+ # "text": "web",
5910
+ # "status": 2,
5911
+ # "repaid": "110.506649705159",
5912
+ # "repaid_interest": "0.046985294841",
5913
+ # "unpaid_interest": "0.0000074393366667"
5914
+ # }
5915
+ #
5860
5916
  return self.parse_margin_loan(response, currency)
5861
5917
 
5862
5918
  def parse_margin_loan(self, info, currency: Currency = None):
@@ -5912,6 +5968,68 @@ class gate(Exchange, ImplicitAPI):
5912
5968
  'info': info,
5913
5969
  }
5914
5970
 
5971
+ def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
5972
+ """
5973
+ fetch the interest owed by the user for borrowing currency for margin trading
5974
+ :see: https://www.gate.io/docs/developers/apiv4/en/#list-interest-records
5975
+ :see: https://www.gate.io/docs/developers/apiv4/en/#interest-records-for-the-cross-margin-account
5976
+ :see: https://www.gate.io/docs/developers/apiv4/en/#list-interest-records-2
5977
+ :param str [code]: unified currency code
5978
+ :param str [symbol]: unified market symbol when fetching interest in isolated markets
5979
+ :param int [since]: the earliest time in ms to fetch borrow interest for
5980
+ :param int [limit]: the maximum number of structures to retrieve
5981
+ :param dict [params]: extra parameters specific to the exchange API endpoint
5982
+ :param boolean [params.unifiedAccount]: set to True for fetching borrow interest in the unified account
5983
+ :returns dict[]: a list of `borrow interest structures <https://docs.ccxt.com/#/?id=borrow-interest-structure>`
5984
+ """
5985
+ self.load_markets()
5986
+ self.load_unified_status()
5987
+ isUnifiedAccount = False
5988
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'fetchBorrowInterest', 'unifiedAccount')
5989
+ request: dict = {}
5990
+ request, params = self.handle_until_option('to', request, params)
5991
+ currency = None
5992
+ if code is not None:
5993
+ currency = self.currency(code)
5994
+ request['currency'] = currency['id']
5995
+ market = None
5996
+ if symbol is not None:
5997
+ market = self.market(symbol)
5998
+ if since is not None:
5999
+ request['from'] = since
6000
+ if limit is not None:
6001
+ request['limit'] = limit
6002
+ response = None
6003
+ marginMode = None
6004
+ marginMode, params = self.handle_margin_mode_and_params('fetchBorrowInterest', params, 'cross')
6005
+ if isUnifiedAccount:
6006
+ response = self.privateUnifiedGetInterestRecords(self.extend(request, params))
6007
+ elif marginMode == 'isolated':
6008
+ if market is not None:
6009
+ request['currency_pair'] = market['id']
6010
+ response = self.privateMarginGetUniInterestRecords(self.extend(request, params))
6011
+ elif marginMode == 'cross':
6012
+ response = self.privateMarginGetCrossInterestRecords(self.extend(request, params))
6013
+ interest = self.parse_borrow_interests(response, market)
6014
+ return self.filter_by_currency_since_limit(interest, code, since, limit)
6015
+
6016
+ def parse_borrow_interest(self, info: dict, market: Market = None):
6017
+ marketId = self.safe_string(info, 'currency_pair')
6018
+ market = self.safe_market(marketId, market)
6019
+ marginMode = 'isolated' if (marketId is not None) else 'cross'
6020
+ timestamp = self.safe_integer(info, 'create_time')
6021
+ return {
6022
+ 'info': info,
6023
+ 'timestamp': timestamp,
6024
+ 'datetime': self.iso8601(timestamp),
6025
+ 'symbol': self.safe_string(market, 'symbol'),
6026
+ 'currency': self.safe_currency_code(self.safe_string(info, 'currency')),
6027
+ 'marginMode': marginMode,
6028
+ 'interest': self.safe_number(info, 'interest'),
6029
+ 'interestRate': self.safe_number(info, 'actual_rate'),
6030
+ 'amountBorrowed': None,
6031
+ }
6032
+
5915
6033
  def sign(self, path, api=[], method='GET', params={}, headers=None, body=None):
5916
6034
  authentication = api[0] # public, private
5917
6035
  type = api[1] # spot, margin, future, delivery
ccxt/hyperliquid.py CHANGED
@@ -2138,7 +2138,7 @@ class hyperliquid(Exchange, ImplicitAPI):
2138
2138
  'notional': self.safe_number(entry, 'positionValue'),
2139
2139
  'leverage': self.safe_number(leverage, 'value'),
2140
2140
  'collateral': self.safe_number(entry, 'marginUsed'),
2141
- 'initialMargin': initialMargin,
2141
+ 'initialMargin': self.parse_number(initialMargin),
2142
2142
  'maintenanceMargin': None,
2143
2143
  'initialMarginPercentage': None,
2144
2144
  'maintenanceMarginPercentage': None,