ccxt 4.4.74__py2.py3-none-any.whl → 4.4.77__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/bitrue.py CHANGED
@@ -50,20 +50,32 @@ class bitrue(Exchange, ImplicitAPI):
50
50
  'swap': True,
51
51
  'future': False,
52
52
  'option': False,
53
+ 'addMargin': False,
54
+ 'borrowCrossMargin': False,
55
+ 'borrowIsolatedMargin': False,
56
+ 'borrowMargin': False,
53
57
  'cancelAllOrders': True,
54
58
  'cancelOrder': True,
59
+ 'closeAllPositions': False,
60
+ 'closePosition': False,
55
61
  'createMarketBuyOrderWithCost': True,
56
62
  'createMarketOrderWithCost': False,
57
63
  'createMarketSellOrderWithCost': False,
58
64
  'createOrder': True,
65
+ 'createOrderWithTakeProfitAndStopLoss': False,
66
+ 'createOrderWithTakeProfitAndStopLossWs': False,
59
67
  'createReduceOnlyOrder': True,
60
68
  'createStopLimitOrder': True,
61
69
  'createStopMarketOrder': True,
62
70
  'createStopOrder': True,
63
71
  'fetchBalance': True,
64
72
  'fetchBidsAsks': True,
73
+ 'fetchBorrowInterest': False,
74
+ 'fetchBorrowRate': False,
65
75
  'fetchBorrowRateHistories': False,
66
76
  'fetchBorrowRateHistory': False,
77
+ 'fetchBorrowRates': False,
78
+ 'fetchBorrowRatesPerSymbol': False,
67
79
  'fetchClosedOrders': True,
68
80
  'fetchCrossBorrowRate': False,
69
81
  'fetchCrossBorrowRates': False,
@@ -74,20 +86,50 @@ class bitrue(Exchange, ImplicitAPI):
74
86
  'fetchDepositWithdrawFee': 'emulated',
75
87
  'fetchDepositWithdrawFees': True,
76
88
  'fetchFundingHistory': False,
89
+ 'fetchFundingInterval': False,
90
+ 'fetchFundingIntervals': False,
77
91
  'fetchFundingRate': False,
78
92
  'fetchFundingRateHistory': False,
79
93
  'fetchFundingRates': False,
94
+ 'fetchGreeks': False,
95
+ 'fetchIndexOHLCV': False,
80
96
  'fetchIsolatedBorrowRate': False,
81
97
  'fetchIsolatedBorrowRates': False,
98
+ 'fetchIsolatedPositions': False,
99
+ 'fetchLeverage': False,
100
+ 'fetchLeverages': False,
101
+ 'fetchLeverageTiers': False,
102
+ 'fetchLiquidations': False,
103
+ 'fetchLongShortRatio': False,
104
+ 'fetchLongShortRatioHistory': False,
105
+ 'fetchMarginAdjustmentHistory': False,
82
106
  'fetchMarginMode': False,
107
+ 'fetchMarginModes': False,
108
+ 'fetchMarketLeverageTiers': False,
83
109
  'fetchMarkets': True,
110
+ 'fetchMarkOHLCV': False,
111
+ 'fetchMarkPrices': False,
112
+ 'fetchMyLiquidations': False,
113
+ 'fetchMySettlementHistory': False,
84
114
  'fetchMyTrades': True,
85
115
  'fetchOHLCV': True,
116
+ 'fetchOpenInterest': False,
117
+ 'fetchOpenInterestHistory': False,
118
+ 'fetchOpenInterests': False,
86
119
  'fetchOpenOrders': True,
120
+ 'fetchOption': False,
121
+ 'fetchOptionChain': False,
87
122
  'fetchOrder': True,
88
123
  'fetchOrderBook': True,
89
124
  'fetchOrders': False,
125
+ 'fetchPosition': False,
126
+ 'fetchPositionHistory': False,
90
127
  'fetchPositionMode': False,
128
+ 'fetchPositions': False,
129
+ 'fetchPositionsHistory': False,
130
+ 'fetchPositionsRisk': False,
131
+ 'fetchPremiumIndexOHLCV': False,
132
+ 'fetchSettlementHistory': False,
91
133
  'fetchStatus': True,
92
134
  'fetchTicker': True,
93
135
  'fetchTickers': True,
@@ -98,9 +140,15 @@ class bitrue(Exchange, ImplicitAPI):
98
140
  'fetchTransactionFees': False,
99
141
  'fetchTransactions': False,
100
142
  'fetchTransfers': True,
143
+ 'fetchVolatilityHistory': False,
101
144
  'fetchWithdrawals': True,
145
+ 'reduceMargin': False,
146
+ 'repayCrossMargin': False,
147
+ 'repayIsolatedMargin': False,
102
148
  'setLeverage': True,
103
149
  'setMargin': True,
150
+ 'setMarginMode': False,
151
+ 'setPositionMode': False,
104
152
  'transfer': True,
105
153
  'withdraw': True,
106
154
  },
ccxt/coinex.py CHANGED
@@ -762,6 +762,8 @@ class coinex(Exchange, ImplicitAPI):
762
762
  for j in range(0, len(chains)):
763
763
  chain = chains[j]
764
764
  networkId = self.safe_string(chain, 'chain')
765
+ if networkId is None:
766
+ continue
765
767
  precisionString = self.parse_precision(self.safe_string(chain, 'withdrawal_precision'))
766
768
  feeString = self.safe_string(chain, 'withdrawal_fee')
767
769
  minNetworkDepositString = self.safe_string(chain, 'min_deposit_amount')
ccxt/coinlist.py CHANGED
@@ -7,7 +7,7 @@ from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.coinlist import ImplicitAPI
8
8
  import hashlib
9
9
  import math
10
- from ccxt.base.types import Account, Any, Balances, Currencies, Currency, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction, TransferEntry
10
+ from ccxt.base.types import Account, Any, Balances, Currencies, Currency, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFees, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import AuthenticationError
@@ -79,7 +79,7 @@ class coinlist(Exchange, ImplicitAPI):
79
79
  'fetchDepositWithdrawFee': False,
80
80
  'fetchDepositWithdrawFees': False,
81
81
  'fetchFundingHistory': False,
82
- 'fetchFundingRate': False,
82
+ 'fetchFundingRate': True,
83
83
  'fetchFundingRateHistory': False,
84
84
  'fetchFundingRates': False,
85
85
  'fetchIndexOHLCV': False,
@@ -171,6 +171,7 @@ class coinlist(Exchange, ImplicitAPI):
171
171
  'v1/leaderboard': 1,
172
172
  'v1/affiliate/{competition_code}': 1,
173
173
  'v1/competition/{competition_id}': 1,
174
+ 'v1/symbols/{symbol}/funding': 1,
174
175
  },
175
176
  },
176
177
  'private': {
@@ -194,6 +195,7 @@ class coinlist(Exchange, ImplicitAPI):
194
195
  'v1/credits': 1, # not unified
195
196
  'v1/positions': 1,
196
197
  'v1/accounts/{trader_id}/competitions': 1,
198
+ 'v1/closedPositions': 1,
197
199
  },
198
200
  'post': {
199
201
  'v1/keys': 1, # not unified
@@ -212,6 +214,9 @@ class coinlist(Exchange, ImplicitAPI):
212
214
  'v1/orders/{order_id}': 1,
213
215
  'v1/orders/bulk': 1, # not unified
214
216
  },
217
+ 'put': {
218
+ 'v1/accounts/{trader_id}/alias': 1,
219
+ },
215
220
  'delete': {
216
221
  'v1/keys/{key}': 1, # not unified
217
222
  'v1/orders': 1,
@@ -2400,6 +2405,89 @@ class coinlist(Exchange, ImplicitAPI):
2400
2405
  }
2401
2406
  return self.safe_string(types, type, type)
2402
2407
 
2408
+ def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
2409
+ """
2410
+ fetch the current funding rate
2411
+
2412
+ https://trade-docs.coinlist.co/#coinlist-pro-api-Funding-Rates
2413
+
2414
+ :param str symbol: unified market symbol
2415
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2416
+ :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
2417
+ """
2418
+ self.load_markets()
2419
+ market = self.market(symbol)
2420
+ if not market['swap']:
2421
+ raise BadSymbol(self.id + ' fetchFundingRate() supports swap contracts only')
2422
+ request: dict = {
2423
+ 'symbol': market['id'],
2424
+ }
2425
+ response = self.publicGetV1SymbolsSymbolFunding(self.extend(request, params))
2426
+ #
2427
+ # {
2428
+ # "last": {
2429
+ # "funding_rate": "-0.00043841",
2430
+ # "funding_time": "2025-04-15T04:00:00.000Z"
2431
+ # },
2432
+ # "next": {
2433
+ # "funding_rate": "-0.00046952",
2434
+ # "funding_time": "2025-04-15T12:00:00.000Z"
2435
+ # },
2436
+ # "indicative": {
2437
+ # "funding_rate": "-0.00042517",
2438
+ # "funding_time": "2025-04-15T20:00:00.000Z"
2439
+ # },
2440
+ # "timestamp": "2025-04-15T07:01:15.219Z"
2441
+ # }
2442
+ #
2443
+ return self.parse_funding_rate(response, market)
2444
+
2445
+ def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
2446
+ #
2447
+ # {
2448
+ # "last": {
2449
+ # "funding_rate": "-0.00043841",
2450
+ # "funding_time": "2025-04-15T04:00:00.000Z"
2451
+ # },
2452
+ # "next": {
2453
+ # "funding_rate": "-0.00046952",
2454
+ # "funding_time": "2025-04-15T12:00:00.000Z"
2455
+ # },
2456
+ # "indicative": {
2457
+ # "funding_rate": "-0.00042517",
2458
+ # "funding_time": "2025-04-15T20:00:00.000Z"
2459
+ # },
2460
+ # "timestamp": "2025-04-15T07:01:15.219Z"
2461
+ # }
2462
+ #
2463
+ previous = self.safe_dict(contract, 'last', {})
2464
+ current = self.safe_dict(contract, 'next', {})
2465
+ next = self.safe_dict(contract, 'indicative', {})
2466
+ previousDatetime = self.safe_string(previous, 'funding_time')
2467
+ currentDatetime = self.safe_string(current, 'funding_time')
2468
+ nextDatetime = self.safe_string(next, 'funding_time')
2469
+ datetime = self.safe_string(contract, 'timestamp')
2470
+ return {
2471
+ 'info': contract,
2472
+ 'symbol': self.safe_symbol(None, market),
2473
+ 'markPrice': None,
2474
+ 'indexPrice': None,
2475
+ 'interestRate': None,
2476
+ 'estimatedSettlePrice': None,
2477
+ 'timestamp': self.parse8601(datetime),
2478
+ 'datetime': datetime,
2479
+ 'fundingRate': self.safe_number(current, 'funding_rate'),
2480
+ 'fundingTimestamp': self.parse8601(currentDatetime),
2481
+ 'fundingDatetime': currentDatetime,
2482
+ 'nextFundingRate': self.safe_number(next, 'funding_rate'),
2483
+ 'nextFundingTimestamp': self.parse8601(nextDatetime),
2484
+ 'nextFundingDatetime': nextDatetime,
2485
+ 'previousFundingRate': self.safe_number(previous, 'funding_rate'),
2486
+ 'previousFundingTimestamp': self.parse8601(previousDatetime),
2487
+ 'previousFundingDatetime': previousDatetime,
2488
+ 'interval': '8h',
2489
+ }
2490
+
2403
2491
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
2404
2492
  request = self.omit(params, self.extract_params(path))
2405
2493
  endpoint = '/' + self.implode_params(path, params)
ccxt/okx.py CHANGED
@@ -397,6 +397,7 @@ class okx(Exchange, ImplicitAPI):
397
397
  'asset/subaccount/managed-subaccount-bills': 5 / 3,
398
398
  'users/entrust-subaccount-list': 10,
399
399
  'account/subaccount/interest-limits': 4,
400
+ 'users/subaccount/apikey': 10,
400
401
  # grid trading
401
402
  'tradingBot/grid/orders-algo-pending': 1,
402
403
  'tradingBot/grid/orders-algo-history': 1,
@@ -529,6 +530,9 @@ class okx(Exchange, ImplicitAPI):
529
530
  'asset/subaccount/transfer': 10,
530
531
  'users/subaccount/set-transfer-out': 10,
531
532
  'account/subaccount/set-loan-allocation': 4,
533
+ 'users/subaccount/create-subaccount': 10,
534
+ 'users/subaccount/subaccount-apikey': 10,
535
+ 'users/subaccount/delete-apikey': 10,
532
536
  # grid trading
533
537
  'tradingBot/grid/order-algo': 1,
534
538
  'tradingBot/grid/amend-order-algo': 1,
@@ -939,6 +943,11 @@ class okx(Exchange, ImplicitAPI):
939
943
  '59506': ExchangeError, # APIKey does not exist
940
944
  '59507': ExchangeError, # The two accounts involved in a transfer must be two different sub accounts under the same parent account
941
945
  '59508': AccountSuspended, # The sub account of {0} is suspended
946
+ '59515': ExchangeError, # You are currently not on the custody whitelist. Please contact customer service for assistance.
947
+ '59516': ExchangeError, # Please create the Copper custody funding account first.
948
+ '59517': ExchangeError, # Please create the Komainu custody funding account first.
949
+ '59518': ExchangeError, # You can’t create a sub-account using the API; please use the app or web.
950
+ '59519': ExchangeError, # You can’t use self function/feature while it's frozen, due to: {freezereason}
942
951
  '59642': BadRequest, # Lead and copy traders can only use margin-free or single-currency margin account modes
943
952
  '59643': ExchangeError, # Couldn’t switch account modes’re currently copying spot trades
944
953
  # WebSocket error Codes from 60000-63999
@@ -1607,8 +1616,8 @@ class okx(Exchange, ImplicitAPI):
1607
1616
  swap = (type == 'swap')
1608
1617
  option = (type == 'option')
1609
1618
  contract = swap or future or option
1610
- baseId = self.safe_string(market, 'baseCcy')
1611
- quoteId = self.safe_string(market, 'quoteCcy')
1619
+ baseId = self.safe_string(market, 'baseCcy', '') # defaulting to '' because some weird preopen markets have empty baseId
1620
+ quoteId = self.safe_string(market, 'quoteCcy', '')
1612
1621
  settleId = self.safe_string(market, 'settleCcy')
1613
1622
  settle = self.safe_currency_code(settleId)
1614
1623
  underlying = self.safe_string(market, 'uly')
@@ -1623,18 +1632,21 @@ class okx(Exchange, ImplicitAPI):
1623
1632
  strikePrice = None
1624
1633
  optionType = None
1625
1634
  if contract:
1626
- symbol = symbol + ':' + settle
1635
+ if settle is not None:
1636
+ symbol = symbol + ':' + settle
1627
1637
  if future:
1628
1638
  expiry = self.safe_integer(market, 'expTime')
1629
- ymd = self.yymmdd(expiry)
1630
- symbol = symbol + '-' + ymd
1639
+ if expiry is not None:
1640
+ ymd = self.yymmdd(expiry)
1641
+ symbol = symbol + '-' + ymd
1631
1642
  elif option:
1632
1643
  expiry = self.safe_integer(market, 'expTime')
1633
1644
  strikePrice = self.safe_string(market, 'stk')
1634
1645
  optionType = self.safe_string(market, 'optType')
1635
- ymd = self.yymmdd(expiry)
1636
- symbol = symbol + '-' + ymd + '-' + strikePrice + '-' + optionType
1637
- optionType = 'put' if (optionType == 'P') else 'call'
1646
+ if expiry is not None:
1647
+ ymd = self.yymmdd(expiry)
1648
+ symbol = symbol + '-' + ymd + '-' + strikePrice + '-' + optionType
1649
+ optionType = 'put' if (optionType == 'P') else 'call'
1638
1650
  tickSize = self.safe_string(market, 'tickSz')
1639
1651
  fees = self.safe_dict_2(self.fees, type, 'trading', {})
1640
1652
  maxLeverage = self.safe_string(market, 'lever', '1')
@@ -1824,31 +1836,31 @@ class okx(Exchange, ImplicitAPI):
1824
1836
  chainsLength = len(chains)
1825
1837
  for j in range(0, chainsLength):
1826
1838
  chain = chains[j]
1827
- networkId = self.safe_string(chain, 'chain') # USDT-BEP20, USDT-Avalance-C, etc
1828
- if networkId is not None:
1829
- idParts = networkId.split('-')
1830
- parts = self.array_slice(idParts, 1)
1831
- chainPart = '-'.join(parts)
1832
- networkCode = self.network_id_to_code(chainPart, currency['code'])
1833
- networks[networkCode] = {
1834
- 'id': networkId,
1835
- 'network': networkCode,
1836
- 'active': None,
1837
- 'deposit': self.safe_bool(chain, 'canDep'),
1838
- 'withdraw': self.safe_bool(chain, 'canWd'),
1839
- 'fee': self.safe_number(chain, 'fee'),
1840
- 'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'wdTickSz'))),
1841
- 'limits': {
1842
- 'withdraw': {
1843
- 'min': self.safe_number(chain, 'minWd'),
1844
- 'max': self.safe_number(chain, 'maxWd'),
1845
- },
1846
- },
1847
- 'info': chain,
1848
- }
1849
- else:
1850
- # only happens for FIAT currency
1839
+ # allow empty string for rare fiat-currencies, e.g. TRY
1840
+ networkId = self.safe_string(chain, 'chain', '') # USDT-BEP20, USDT-Avalance-C, etc
1841
+ if networkId == '':
1842
+ # only happens for fiat 'TRY' currency
1851
1843
  type = 'fiat'
1844
+ idParts = networkId.split('-')
1845
+ parts = self.array_slice(idParts, 1)
1846
+ chainPart = '-'.join(parts)
1847
+ networkCode = self.network_id_to_code(chainPart, currency['code'])
1848
+ networks[networkCode] = {
1849
+ 'id': networkId,
1850
+ 'network': networkCode,
1851
+ 'active': None,
1852
+ 'deposit': self.safe_bool(chain, 'canDep'),
1853
+ 'withdraw': self.safe_bool(chain, 'canWd'),
1854
+ 'fee': self.safe_number(chain, 'fee'),
1855
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'wdTickSz'))),
1856
+ 'limits': {
1857
+ 'withdraw': {
1858
+ 'min': self.safe_number(chain, 'minWd'),
1859
+ 'max': self.safe_number(chain, 'maxWd'),
1860
+ },
1861
+ },
1862
+ 'info': chain,
1863
+ }
1852
1864
  firstChain = self.safe_dict(chains, 0, {})
1853
1865
  result[code] = self.safe_currency_structure({
1854
1866
  'info': chains,
ccxt/paradex.py CHANGED
@@ -703,14 +703,9 @@ class paradex(Exchange, ImplicitAPI):
703
703
  """
704
704
  self.load_markets()
705
705
  symbols = self.market_symbols(symbols)
706
- request: dict = {}
707
- if symbols is not None:
708
- if isinstance(symbols, list):
709
- request['market'] = self.market_id(symbols[0])
710
- else:
711
- request['market'] = self.market_id(symbols)
712
- else:
713
- request['market'] = 'ALL'
706
+ request: dict = {
707
+ 'market': 'ALL',
708
+ }
714
709
  response = self.publicGetMarketsSummary(self.extend(request, params))
715
710
  #
716
711
  # {
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.74'
7
+ __version__ = '4.4.77'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/pro/hyperliquid.py CHANGED
@@ -614,7 +614,7 @@ class hyperliquid(ccxt.async_support.hyperliquid):
614
614
  'datetime': self.iso8601(timestamp),
615
615
  'symbol': symbol,
616
616
  'id': id,
617
- 'order': None,
617
+ 'order': self.safe_string(trade, 'oid'),
618
618
  'type': None,
619
619
  'side': side,
620
620
  'takerOrMaker': None,
ccxt/test/tests_async.py CHANGED
@@ -1094,6 +1094,26 @@ class testMainClass:
1094
1094
  sum = exchange.sum(sum, results_length)
1095
1095
  return sum
1096
1096
 
1097
+ def check_if_exchange_is_disabled(self, exchange_name, exchange_data):
1098
+ exchange = init_exchange('Exchange', {})
1099
+ is_disabled_py = exchange.safe_bool(exchange_data, 'disabledPy', False)
1100
+ if is_disabled_py and (self.lang == 'PY'):
1101
+ dump('[TEST_WARNING] Exchange ' + exchange_name + ' is disabled in python')
1102
+ return True
1103
+ is_disabled_php = exchange.safe_bool(exchange_data, 'disabledPHP', False)
1104
+ if is_disabled_php and (self.lang == 'PHP'):
1105
+ dump('[TEST_WARNING] Exchange ' + exchange_name + ' is disabled in php')
1106
+ return True
1107
+ is_disabled_c_sharp = exchange.safe_bool(exchange_data, 'disabledCS', False)
1108
+ if is_disabled_c_sharp and (self.lang == 'C#'):
1109
+ dump('[TEST_WARNING] Exchange ' + exchange_name + ' is disabled in c#')
1110
+ return True
1111
+ is_disabled_go = exchange.safe_bool(exchange_data, 'disabledGO', False)
1112
+ if is_disabled_go and (self.lang == 'GO'):
1113
+ dump('[TEST_WARNING] Exchange ' + exchange_name + ' is disabled in go')
1114
+ return True
1115
+ return False
1116
+
1097
1117
  async def run_static_request_tests(self, target_exchange=None, test_name=None):
1098
1118
  await self.run_static_tests('request', target_exchange, test_name)
1099
1119
  return True
@@ -1114,6 +1134,9 @@ class testMainClass:
1114
1134
  for i in range(0, len(exchanges)):
1115
1135
  exchange_name = exchanges[i]
1116
1136
  exchange_data = static_data[exchange_name]
1137
+ disabled = self.check_if_exchange_is_disabled(exchange_name, exchange_data)
1138
+ if disabled:
1139
+ continue
1117
1140
  number_of_tests = self.get_number_of_tests_from_exchange(exchange, exchange_data, test_name)
1118
1141
  sum = exchange.sum(sum, number_of_tests)
1119
1142
  if type == 'request':
ccxt/test/tests_sync.py CHANGED
@@ -1091,6 +1091,26 @@ class testMainClass:
1091
1091
  sum = exchange.sum(sum, results_length)
1092
1092
  return sum
1093
1093
 
1094
+ def check_if_exchange_is_disabled(self, exchange_name, exchange_data):
1095
+ exchange = init_exchange('Exchange', {})
1096
+ is_disabled_py = exchange.safe_bool(exchange_data, 'disabledPy', False)
1097
+ if is_disabled_py and (self.lang == 'PY'):
1098
+ dump('[TEST_WARNING] Exchange ' + exchange_name + ' is disabled in python')
1099
+ return True
1100
+ is_disabled_php = exchange.safe_bool(exchange_data, 'disabledPHP', False)
1101
+ if is_disabled_php and (self.lang == 'PHP'):
1102
+ dump('[TEST_WARNING] Exchange ' + exchange_name + ' is disabled in php')
1103
+ return True
1104
+ is_disabled_c_sharp = exchange.safe_bool(exchange_data, 'disabledCS', False)
1105
+ if is_disabled_c_sharp and (self.lang == 'C#'):
1106
+ dump('[TEST_WARNING] Exchange ' + exchange_name + ' is disabled in c#')
1107
+ return True
1108
+ is_disabled_go = exchange.safe_bool(exchange_data, 'disabledGO', False)
1109
+ if is_disabled_go and (self.lang == 'GO'):
1110
+ dump('[TEST_WARNING] Exchange ' + exchange_name + ' is disabled in go')
1111
+ return True
1112
+ return False
1113
+
1094
1114
  def run_static_request_tests(self, target_exchange=None, test_name=None):
1095
1115
  self.run_static_tests('request', target_exchange, test_name)
1096
1116
  return True
@@ -1111,6 +1131,9 @@ class testMainClass:
1111
1131
  for i in range(0, len(exchanges)):
1112
1132
  exchange_name = exchanges[i]
1113
1133
  exchange_data = static_data[exchange_name]
1134
+ disabled = self.check_if_exchange_is_disabled(exchange_name, exchange_data)
1135
+ if disabled:
1136
+ continue
1114
1137
  number_of_tests = self.get_number_of_tests_from_exchange(exchange, exchange_data, test_name)
1115
1138
  sum = exchange.sum(sum, number_of_tests)
1116
1139
  if type == 'request':
ccxt/upbit.py CHANGED
@@ -28,7 +28,7 @@ class upbit(Exchange, ImplicitAPI):
28
28
  'name': 'Upbit',
29
29
  'countries': ['KR'],
30
30
  'version': 'v1',
31
- 'rateLimit': 1000,
31
+ 'rateLimit': 50,
32
32
  'pro': True,
33
33
  # new metainfo interface
34
34
  'has': {
@@ -83,6 +83,7 @@ class upbit(Exchange, ImplicitAPI):
83
83
  'withdraw': True,
84
84
  },
85
85
  'timeframes': {
86
+ '1s': 'seconds',
86
87
  '1m': 'minutes',
87
88
  '3m': 'minutes',
88
89
  '5m': 'minutes',
@@ -94,6 +95,7 @@ class upbit(Exchange, ImplicitAPI):
94
95
  '1d': 'days',
95
96
  '1w': 'weeks',
96
97
  '1M': 'months',
98
+ '1y': 'years',
97
99
  },
98
100
  'hostname': 'api.upbit.com',
99
101
  'urls': {
@@ -107,54 +109,70 @@ class upbit(Exchange, ImplicitAPI):
107
109
  'fees': 'https://upbit.com/service_center/guide',
108
110
  },
109
111
  'api': {
112
+ # 'endpoint','API Cost'
113
+ # cost = 1000 / (rateLimit * RPS)
110
114
  'public': {
111
- 'get': [
112
- 'market/all',
113
- 'candles/{timeframe}',
114
- 'candles/{timeframe}/{unit}',
115
- 'candles/minutes/{unit}',
116
- 'candles/minutes/1',
117
- 'candles/minutes/3',
118
- 'candles/minutes/5',
119
- 'candles/minutes/10',
120
- 'candles/minutes/15',
121
- 'candles/minutes/30',
122
- 'candles/minutes/60',
123
- 'candles/minutes/240',
124
- 'candles/days',
125
- 'candles/weeks',
126
- 'candles/months',
127
- 'trades/ticks',
128
- 'ticker',
129
- 'orderbook',
130
- ],
115
+ 'get': {
116
+ 'market/all': 2, # RPS: 10
117
+ 'candles/{timeframe}': 2,
118
+ 'candles/{timeframe}/{unit}': 2,
119
+ 'candles/seconds': 2,
120
+ 'candles/minutes/{unit}': 2,
121
+ 'candles/minutes/1': 2,
122
+ 'candles/minutes/3': 2,
123
+ 'candles/minutes/5': 2,
124
+ 'candles/minutes/10': 2,
125
+ 'candles/minutes/15': 2,
126
+ 'candles/minutes/30': 2,
127
+ 'candles/minutes/60': 2,
128
+ 'candles/minutes/240': 2,
129
+ 'candles/days': 2,
130
+ 'candles/weeks': 2,
131
+ 'candles/months': 2,
132
+ 'candles/years': 2,
133
+ 'trades/ticks': 2,
134
+ 'ticker': 2,
135
+ 'ticker/all': 2,
136
+ 'orderbook': 2,
137
+ 'orderbook/supported_levels': 2, # Upbit KR only
138
+ },
131
139
  },
132
140
  'private': {
133
- 'get': [
134
- 'accounts',
135
- 'orders/chance',
136
- 'order',
137
- 'orders',
138
- 'orders/closed',
139
- 'orders/open',
140
- 'orders/uuids',
141
- 'withdraws',
142
- 'withdraw',
143
- 'withdraws/chance',
144
- 'deposits',
145
- 'deposit',
146
- 'deposits/coin_addresses',
147
- 'deposits/coin_address',
148
- ],
149
- 'post': [
150
- 'orders',
151
- 'withdraws/coin',
152
- 'withdraws/krw',
153
- 'deposits/generate_coin_address',
154
- ],
155
- 'delete': [
156
- 'order',
157
- ],
141
+ 'get': {
142
+ 'accounts': 0.67, # RPS: 30
143
+ 'orders/chance': 0.67,
144
+ 'order': 0.67,
145
+ 'orders/closed': 0.67,
146
+ 'orders/open': 0.67,
147
+ 'orders/uuids': 0.67,
148
+ 'withdraws': 0.67,
149
+ 'withdraw': 0.67,
150
+ 'withdraws/chance': 0.67,
151
+ 'withdraws/coin_addresses': 0.67,
152
+ 'deposits': 0.67,
153
+ 'deposits/chance/coin': 0.67,
154
+ 'deposit': 0.67,
155
+ 'deposits/coin_addresses': 0.67,
156
+ 'deposits/coin_address': 0.67,
157
+ 'travel_rule/vasps': 0.67,
158
+ 'status/wallet': 0.67, # Upbit KR only
159
+ 'api_keys': 0.67, # Upbit KR only
160
+ },
161
+ 'post': {
162
+ 'orders': 2.5, # RPS: 8
163
+ 'orders/cancel_and_new': 2.5, # RPS: 8
164
+ 'withdraws/coin': 0.67,
165
+ 'withdraws/krw': 0.67, # Upbit KR only.
166
+ 'deposits/krw': 0.67, # Upbit KR only.
167
+ 'deposits/generate_coin_address': 0.67,
168
+ 'travel_rule/deposit/uuid': 0.67, # RPS: 30, but each deposit can only be queried once every 10 minutes
169
+ 'travel_rule/deposit/txid': 0.67, # RPS: 30, but each deposit can only be queried once every 10 minutes
170
+ },
171
+ 'delete': {
172
+ 'order': 0.67,
173
+ 'orders/open': 40, # RPS: 0.5
174
+ 'orders/uuids': 0.67,
175
+ },
158
176
  },
159
177
  },
160
178
  'fees': {