ccxt-ir 4.9.14__py2.py3-none-any.whl → 4.9.16__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ccxt/__init__.py CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  # ----------------------------------------------------------------------------
24
24
 
25
- __version__ = '4.9.14'
25
+ __version__ = '4.9.16'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
@@ -210,6 +210,7 @@ from ccxt.ramzinex import ramzinex # noqa: F4
210
210
  from ccxt.sarmayex import sarmayex # noqa: F401
211
211
  from ccxt.sarrafex import sarrafex # noqa: F401
212
212
  from ccxt.tabdeal import tabdeal # noqa: F401
213
+ from ccxt.tehran_exchange import tehran_exchange # noqa: F401
213
214
  from ccxt.tetherland import tetherland # noqa: F401
214
215
  from ccxt.timex import timex # noqa: F401
215
216
  from ccxt.tokocrypto import tokocrypto # noqa: F401
@@ -356,6 +357,7 @@ exchanges = [
356
357
  'sarmayex',
357
358
  'sarrafex',
358
359
  'tabdeal',
360
+ 'tehran_exchange',
359
361
  'tetherland',
360
362
  'timex',
361
363
  'tokocrypto',
ccxt/abantether.py CHANGED
@@ -185,8 +185,8 @@ class abantether(Exchange, ImplicitAPI):
185
185
  'baseId': baseId,
186
186
  'quoteId': quoteId,
187
187
  'settleId': None,
188
- 'type': 'spot',
189
- 'spot': True,
188
+ 'type': 'otc',
189
+ 'spot': False,
190
190
  'margin': False,
191
191
  'swap': False,
192
192
  'future': False,
@@ -0,0 +1,6 @@
1
+ from ccxt.base.types import Entry
2
+
3
+
4
+ class ImplicitAPI:
5
+ public_get_otc_v1_market_pair = publicGetOtcV1MarketPair = Entry('otc/v1/market/pair', 'public', 'GET', {'cost': 1})
6
+ public_get_otc_v1_market_order_pair_price = publicGetOtcV1MarketOrderPairPrice = Entry('otc/v1/market/order/pair/price', 'public', 'GET', {'cost': 1})
ccxt/abstract/toobit.py CHANGED
@@ -4,3 +4,4 @@ from ccxt.base.types import Entry
4
4
  class ImplicitAPI:
5
5
  public_get_quote_v1_ticker_24hr = publicGetQuoteV1Ticker24hr = Entry('quote/v1/ticker/24hr', 'public', 'GET', {'cost': 1})
6
6
  public_get_quote_v1_klines = publicGetQuoteV1Klines = Entry('quote/v1/klines', 'public', 'GET', {'cost': 1})
7
+ public_get_api_v1_exchangeinfo = publicGetApiV1ExchangeInfo = Entry('/api/v1/exchangeInfo', 'public', 'GET', {'cost': 1})
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.9.14'
7
+ __version__ = '4.9.16'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -190,6 +190,7 @@ from ccxt.async_support.ramzinex import ramzinex
190
190
  from ccxt.async_support.sarmayex import sarmayex # noqa: F401
191
191
  from ccxt.async_support.sarrafex import sarrafex # noqa: F401
192
192
  from ccxt.async_support.tabdeal import tabdeal # noqa: F401
193
+ from ccxt.async_support.tehran_exchange import tehran_exchange # noqa: F401
193
194
  from ccxt.async_support.tetherland import tetherland # noqa: F401
194
195
  from ccxt.async_support.timex import timex # noqa: F401
195
196
  from ccxt.async_support.tokocrypto import tokocrypto # noqa: F401
@@ -336,6 +337,7 @@ exchanges = [
336
337
  'sarmayex',
337
338
  'sarrafex',
338
339
  'tabdeal',
340
+ 'tehran_exchange',
339
341
  'tetherland',
340
342
  'timex',
341
343
  'tokocrypto',
@@ -185,8 +185,8 @@ class abantether(Exchange, ImplicitAPI):
185
185
  'baseId': baseId,
186
186
  'quoteId': quoteId,
187
187
  'settleId': None,
188
- 'type': 'spot',
189
- 'spot': True,
188
+ 'type': 'otc',
189
+ 'spot': False,
190
190
  'margin': False,
191
191
  'swap': False,
192
192
  'future': False,
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.9.14'
5
+ __version__ = '4.9.16'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -282,5 +282,8 @@ class hamtapay(Exchange, ImplicitAPI):
282
282
 
283
283
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
284
284
  url = self.urls['api']['public'] + '/' + path
285
- headers = {'Content-Type': 'application/json'}
285
+ headers = {
286
+ 'Content-Type': 'application/json',
287
+ 'Origin': 'https://hamtapay.net',
288
+ }
286
289
  return {'url': url, 'method': method, 'body': body, 'headers': headers}
@@ -22,7 +22,7 @@ class sarmayex(Exchange, ImplicitAPI):
22
22
  'pro': False,
23
23
  'has': {
24
24
  'CORS': None,
25
- 'spot': True,
25
+ 'spot': False,
26
26
  'margin': False,
27
27
  'swap': False,
28
28
  'future': False,
@@ -78,6 +78,7 @@ class sarmayex(Exchange, ImplicitAPI):
78
78
  'fetchTradingFee': False,
79
79
  'fetchTradingFees': False,
80
80
  'fetchWithdrawals': False,
81
+ 'otc': True,
81
82
  'setLeverage': False,
82
83
  'setMarginMode': False,
83
84
  'transfer': False,
@@ -193,8 +194,8 @@ class sarmayex(Exchange, ImplicitAPI):
193
194
  'baseId': baseId,
194
195
  'quoteId': quoteId,
195
196
  'settleId': None,
196
- 'type': 'spot',
197
- 'spot': True,
197
+ 'type': 'otc',
198
+ 'spot': False,
198
199
  'margin': False,
199
200
  'swap': False,
200
201
  'future': False,
@@ -0,0 +1,317 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+
6
+ from ccxt.async_support.base.exchange import Exchange
7
+ from ccxt.abstract.tehran_exchange import ImplicitAPI
8
+ from ccxt.base.types import Any, Market, Strings, Ticker, Tickers
9
+ from typing import List
10
+
11
+
12
+ class tehran_exchange(Exchange, ImplicitAPI):
13
+
14
+ def describe(self) -> Any:
15
+ return self.deep_extend(super(tehran_exchange, self).describe(), {
16
+ 'id': 'tehran_exchange',
17
+ 'name': 'Tehran Exchange',
18
+ 'countries': ['IR'],
19
+ 'rateLimit': 1000,
20
+ 'version': '1',
21
+ 'certified': False,
22
+ 'pro': False,
23
+ 'has': {
24
+ 'CORS': None,
25
+ 'spot': True,
26
+ 'margin': False,
27
+ 'swap': False,
28
+ 'future': False,
29
+ 'option': False,
30
+ 'addMargin': False,
31
+ 'cancelAllOrders': False,
32
+ 'cancelOrder': False,
33
+ 'cancelOrders': False,
34
+ 'createDepositAddress': False,
35
+ 'createOrder': False,
36
+ 'createStopLimitOrder': False,
37
+ 'createStopMarketOrder': False,
38
+ 'createStopOrder': False,
39
+ 'editOrder': False,
40
+ 'fetchBalance': False,
41
+ 'fetchBorrowInterest': False,
42
+ 'fetchBorrowRateHistories': False,
43
+ 'fetchBorrowRateHistory': False,
44
+ 'fetchClosedOrders': False,
45
+ 'fetchCrossBorrowRate': False,
46
+ 'fetchCrossBorrowRates': False,
47
+ 'fetchCurrencies': False,
48
+ 'fetchDepositAddress': False,
49
+ 'fetchDeposits': False,
50
+ 'fetchFundingHistory': False,
51
+ 'fetchFundingRate': False,
52
+ 'fetchFundingRateHistory': False,
53
+ 'fetchFundingRates': False,
54
+ 'fetchIndexOHLCV': False,
55
+ 'fetchIsolatedBorrowRate': False,
56
+ 'fetchIsolatedBorrowRates': False,
57
+ 'fetchL2OrderBook': False,
58
+ 'fetchLedger': False,
59
+ 'fetchLedgerEntry': False,
60
+ 'fetchLeverageTiers': False,
61
+ 'fetchMarkets': True,
62
+ 'fetchMarkOHLCV': False,
63
+ 'fetchMyTrades': False,
64
+ 'fetchOHLCV': False,
65
+ 'fetchOpenInterestHistory': False,
66
+ 'fetchOpenOrders': False,
67
+ 'fetchOrder': False,
68
+ 'fetchOrderBook': False,
69
+ 'fetchOrders': False,
70
+ 'fetchOrderTrades': 'emulated',
71
+ 'fetchPositions': False,
72
+ 'fetchPremiumIndexOHLCV': False,
73
+ 'fetchTicker': True,
74
+ 'fetchTickers': True,
75
+ 'fetchTime': False,
76
+ 'fetchTrades': False,
77
+ 'fetchTradingFee': False,
78
+ 'fetchTradingFees': False,
79
+ 'fetchWithdrawals': False,
80
+ 'setLeverage': False,
81
+ 'setMarginMode': False,
82
+ 'transfer': False,
83
+ 'withdraw': False,
84
+ },
85
+ 'comment': 'This comment is optional',
86
+ 'urls': {
87
+ 'logo': 'https://cdn.arz.digital/cr-odin/img/exchanges/tehran_exchange/64x64.png',
88
+ 'api': {
89
+ 'public': 'https://otc-api.tehran.exchange',
90
+ },
91
+ 'www': 'https://tehran.exchange',
92
+ 'doc': [
93
+ 'https://tehran.exchange',
94
+ ],
95
+ },
96
+ 'api': {
97
+ 'public': {
98
+ 'get': {
99
+ 'otc/v1/market/pair': 1,
100
+ 'otc/v1/market/order/pair/price': 1,
101
+ },
102
+ },
103
+ },
104
+ 'fees': {
105
+ 'trading': {
106
+ 'tierBased': False,
107
+ 'percentage': True,
108
+ 'maker': self.parse_number('0.0025'),
109
+ 'taker': self.parse_number('0.0025'),
110
+ },
111
+ },
112
+ })
113
+
114
+ async def fetch_markets(self, params={}) -> List[Market]:
115
+ """
116
+ retrieves data on all markets for tehran_exchange
117
+ https://otc-api.tehran.exchange/otc/v1/market/pair
118
+ :param dict [params]: extra parameters specific to the exchange API endpoint
119
+ :returns dict[]: an array of objects representing market data
120
+ """
121
+ response = await self.publicGetOtcV1MarketPair(params)
122
+ data = self.safe_dict(response, 'data', {})
123
+ pairs = self.safe_list(data, 'pairs', [])
124
+ result = []
125
+ for i in range(0, len(pairs)):
126
+ market = self.parse_market(pairs[i])
127
+ result.append(market)
128
+ return result
129
+
130
+ def parse_market(self, market) -> Market:
131
+ # {
132
+ # "id": 6054,
133
+ # "pair": "HBAR_USDT",
134
+ # "status": "TRADABLE",
135
+ # "tradable": True,
136
+ # "fiatOrder": False,
137
+ # "quoteName": "Tether",
138
+ # "baseName": "Hedera",
139
+ # "quoteNameFa": "تتر",
140
+ # "baseNameFa": "هدرا هش گراف ",
141
+ # "quoteImageUrl": "https://s3-dev.tehranex.com/asset/coin_icon/64/usdt.png",
142
+ # "baseImageUrl": "https://s3-dev.tehranex.com/asset/coin_icon/64/hbar.png",
143
+ # "quoteSymbol": "USDT",
144
+ # "baseSymbol": "HBAR",
145
+ # "amountPrecision": 2,
146
+ # "feePercentage": 0.25,
147
+ # "providerFeePercentage": 0.05,
148
+ # "maxQuoteAmount": 600000,
149
+ # "minBaseAmount": 0.01,
150
+ # "minQuoteAmount": 1,
151
+ # "pricePrecision": 5,
152
+ # "baseVirtualCurrencyId": 989,
153
+ # "quoteVirtualCurrencyId": 1
154
+ # }
155
+ id = self.safe_string(market, 'pair')
156
+ baseId = self.safe_string(market, 'baseSymbol')
157
+ quoteId = self.safe_string(market, 'quoteSymbol')
158
+ base = self.safe_currency_code(baseId)
159
+ quote = self.safe_currency_code(quoteId)
160
+ status = self.safe_string(market, 'status')
161
+ tradable = self.safe_bool(market, 'tradable', False)
162
+ active = (status == 'TRADABLE') and tradable
163
+ amountPrecision = self.safe_integer(market, 'amountPrecision')
164
+ pricePrecision = self.safe_integer(market, 'pricePrecision')
165
+ minBaseAmount = self.safe_string(market, 'minBaseAmount')
166
+ minQuoteAmount = self.safe_string(market, 'minQuoteAmount')
167
+ maxQuoteAmount = self.safe_string(market, 'maxQuoteAmount')
168
+ return {
169
+ 'id': id,
170
+ 'symbol': base + '/' + quote,
171
+ 'base': base,
172
+ 'quote': quote,
173
+ 'settle': None,
174
+ 'baseId': baseId,
175
+ 'quoteId': quoteId,
176
+ 'settleId': None,
177
+ 'type': 'spot',
178
+ 'spot': True,
179
+ 'margin': False,
180
+ 'swap': False,
181
+ 'future': False,
182
+ 'option': False,
183
+ 'active': active,
184
+ 'contract': False,
185
+ 'linear': None,
186
+ 'inverse': None,
187
+ 'contractSize': None,
188
+ 'expiry': None,
189
+ 'expiryDatetime': None,
190
+ 'strike': None,
191
+ 'optionType': None,
192
+ 'precision': {
193
+ 'amount': amountPrecision,
194
+ 'price': pricePrecision,
195
+ },
196
+ 'limits': {
197
+ 'leverage': {
198
+ 'min': None,
199
+ 'max': None,
200
+ },
201
+ 'amount': {
202
+ 'min': self.parse_number(minBaseAmount),
203
+ 'max': None,
204
+ },
205
+ 'price': {
206
+ 'min': None,
207
+ 'max': None,
208
+ },
209
+ 'cost': {
210
+ 'min': self.parse_number(minQuoteAmount),
211
+ 'max': self.parse_number(maxQuoteAmount),
212
+ },
213
+ },
214
+ 'created': None,
215
+ 'info': market,
216
+ }
217
+
218
+ async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
219
+ """
220
+ fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
221
+ https://otc-api.tehran.exchange/otc/v1/market/pair
222
+ https://otc-api.tehran.exchange/otc/v1/market/order/pair/price
223
+ :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
224
+ :param dict [params]: extra parameters specific to the exchange API endpoint
225
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
226
+ """
227
+ await self.load_markets()
228
+ if symbols is not None:
229
+ symbols = self.market_symbols(symbols)
230
+ response = await self.publicGetOtcV1MarketPair(params)
231
+ data = self.safe_dict(response, 'data', {})
232
+ pairs = self.safe_list(data, 'pairs', [])
233
+ # filter symbols from pairs
234
+ filteredPairs = []
235
+ for i in range(0, len(pairs)):
236
+ pair = pairs[i]
237
+ pairId = self.safe_string(pair, 'pair')
238
+ symbol = self.safe_symbol(pairId)
239
+ if symbols.includes(symbol):
240
+ filteredPairs.append(pair)
241
+ result = {}
242
+ for i in range(0, len(filteredPairs)):
243
+ pairData = filteredPairs[i]
244
+ pairId = self.safe_string(pairData, 'pair')
245
+ # Fetch BUY price
246
+ request = {
247
+ 'pair': pairId,
248
+ 'side': 'BUY',
249
+ 'basedOn': 'BASE',
250
+ 'amount': 1,
251
+ }
252
+ priceResponse = await self.publicGetOtcV1MarketOrderPairPrice(request)
253
+ priceData = self.safe_dict(priceResponse, 'data', {})
254
+ price = self.safe_float(priceData, 'price', 0)
255
+ pairData['price'] = price
256
+ ticker = self.parse_ticker(pairData)
257
+ symbol = ticker['symbol']
258
+ result[symbol] = ticker
259
+ return self.filter_by_array_tickers(result, 'symbol', symbols)
260
+
261
+ async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
262
+ """
263
+ fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
264
+ https://otc-api.tehran.exchange/otc/v1/market/pair
265
+ :param str symbol: unified symbol of the market to fetch the ticker for
266
+ :param dict [params]: extra parameters specific to the exchange API endpoint
267
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
268
+ """
269
+ ticker = await self.fetch_tickers([symbol])
270
+ return ticker[self.safe_symbol(symbol)]
271
+
272
+ def parse_ticker(self, ticker, market: Market = None) -> Ticker:
273
+ # {
274
+ # "id": 6054,
275
+ # "pair": "HBAR_USDT",
276
+ # "status": "TRADABLE",
277
+ # "tradable": True,
278
+ # "baseSymbol": "HBAR",
279
+ # "quoteSymbol": "USDT",
280
+ # ...
281
+ # "price": 12345,
282
+ # }
283
+ marketType = 'spot'
284
+ baseSymbol = self.safe_string(ticker, 'baseSymbol')
285
+ quoteSymbol = self.safe_string(ticker, 'quoteSymbol')
286
+ marketId = baseSymbol + '/' + quoteSymbol
287
+ symbol = self.safe_symbol(marketId, market, None, marketType)
288
+ price = self.safe_float(ticker, 'price')
289
+ return self.safe_ticker({
290
+ 'symbol': symbol,
291
+ 'timestamp': None,
292
+ 'datetime': None,
293
+ 'high': None,
294
+ 'low': None,
295
+ 'bid': price,
296
+ 'bidVolume': None,
297
+ 'ask': price,
298
+ 'askVolume': None,
299
+ 'open': None,
300
+ 'close': price,
301
+ 'last': price,
302
+ 'previousClose': None,
303
+ 'change': None,
304
+ 'percentage': None,
305
+ 'average': None,
306
+ 'baseVolume': None,
307
+ 'quoteVolume': None,
308
+ 'info': ticker,
309
+ }, market)
310
+
311
+ def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
312
+ query = self.omit(params, self.extract_params(path))
313
+ url = self.urls['api']['public'] + '/' + path
314
+ if query:
315
+ url += '?' + self.urlencode(query)
316
+ headers = {'Content-Type': 'application/json'}
317
+ return {'url': url, 'method': method, 'body': body, 'headers': headers}
@@ -113,6 +113,7 @@ class toobit(Exchange, ImplicitAPI):
113
113
  'get': {
114
114
  'quote/v1/ticker/24hr': 1,
115
115
  'quote/v1/klines': 1,
116
+ '/api/v1/exchangeInfo': 1,
116
117
  },
117
118
  },
118
119
  },
@@ -129,48 +130,98 @@ class toobit(Exchange, ImplicitAPI):
129
130
  async def fetch_markets(self, params={}) -> List[Market]:
130
131
  """
131
132
  retrieves data on all markets for toobit
132
- https://apidocs.toobit.io/#tickers
133
+ https://api.toobit.com/api/v1/exchangeInfo
133
134
  :param dict [params]: extra parameters specific to the exchange API endpoint
134
135
  :returns dict[]: an array of objects representing market data
135
136
  """
136
- response = await self.publicGetQuoteV1Ticker24hr()
137
+ response = await self.publicGetApiV1ExchangeInfo()
138
+ symbols = self.safe_value(response, 'symbols', [])
137
139
  result = []
138
- for i in range(0, len(response)):
139
- volume = self.safe_float(response[i], 'v')
140
- symbol = self.safe_value(response[i], 's')
141
- if volume == 0 or symbol == 'TESTA1S3TESTX8Z9':
140
+ for i in range(0, len(symbols)):
141
+ symbolData = symbols[i]
142
+ status = self.safe_value(symbolData, 'status')
143
+ symbol = self.safe_value(symbolData, 'symbol')
144
+ if status != 'TRADING' or symbol == 'TESTA1S3TESTX8Z9':
142
145
  continue
143
- market = self.parse_market(response[i])
146
+ market = self.parse_market(symbolData)
144
147
  result.append(market)
145
148
  return result
146
149
 
147
150
  def parse_market(self, market) -> Market:
148
151
  # {
149
- # t: 1757164008834,
150
- # s: "BTCUSDT",
151
- # c: "110895.06",
152
- # h: "113310.01",
153
- # l: "110219.01",
154
- # o: "112951.99",
155
- # v: "3893.406649",
156
- # qv: "433374169.27969515",
157
- # pc: "-2056.93",
158
- # pcp: "-0.0182"
159
- # }
160
- symbol = self.safe_value(market, 's')
161
- baseId = symbol
162
- quoteId = None
163
- if symbol.endswith('USDT'):
164
- baseId = symbol[0:-4]
165
- quoteId = 'USDT'
166
- elif symbol.endswith('USDC'):
167
- baseId = symbol[0:-4]
168
- quoteId = 'USDC'
152
+ # "filters": [
153
+ # {
154
+ # "minPrice": "0.01",
155
+ # "maxPrice": "10000000.00000000",
156
+ # "tickSize": "0.01",
157
+ # "filterType": "PRICE_FILTER"
158
+ # },
159
+ # {
160
+ # "minQty": "0.0001",
161
+ # "maxQty": "4000",
162
+ # "stepSize": "0.0001",
163
+ # "filterType": "LOT_SIZE"
164
+ # },
165
+ # {
166
+ # "minNotional": "5",
167
+ # "filterType": "MIN_NOTIONAL"
168
+ # }
169
+ # ],
170
+ # "exchangeId": "301",
171
+ # "symbol": "ETHUSDT",
172
+ # "symbolName": "ETHUSDT",
173
+ # "status": "TRADING",
174
+ # "baseAsset": "ETH",
175
+ # "baseAssetName": "ETH",
176
+ # "baseAssetPrecision": "0.0001",
177
+ # "quoteAsset": "USDT",
178
+ # "quoteAssetName": "USDT",
179
+ # "quotePrecision": "0.01",
180
+ # "icebergAllowed": False,
181
+ # "isAggregate": False,
182
+ # "allowMargin": True
183
+ # }
184
+ symbol = self.safe_value(market, 'symbol')
185
+ baseAsset = self.safe_value(market, 'baseAsset')
186
+ quoteAsset = self.safe_value(market, 'quoteAsset')
187
+ baseAssetPrecision = self.safe_value(market, 'baseAssetPrecision')
188
+ quotePrecision = self.safe_value(market, 'quotePrecision')
189
+ allowMargin = self.safe_value(market, 'allowMargin', False)
190
+ filters = self.safe_value(market, 'filters', [])
191
+ # Parse filters to extract limits and precision
192
+ minPrice = None
193
+ maxPrice = None
194
+ tickSize = None
195
+ minQty = None
196
+ maxQty = None
197
+ stepSize = None
198
+ minNotional = None
199
+ minAmount = None
200
+ maxAmount = None
201
+ for i in range(0, len(filters)):
202
+ filter = filters[i]
203
+ filterType = self.safe_value(filter, 'filterType')
204
+ if filterType == 'PRICE_FILTER':
205
+ minPrice = self.safe_number(filter, 'minPrice')
206
+ maxPrice = self.safe_number(filter, 'maxPrice')
207
+ tickSize = self.safe_number(filter, 'tickSize')
208
+ elif filterType == 'LOT_SIZE':
209
+ minQty = self.safe_number(filter, 'minQty')
210
+ maxQty = self.safe_number(filter, 'maxQty')
211
+ stepSize = self.safe_number(filter, 'stepSize')
212
+ elif filterType == 'MIN_NOTIONAL':
213
+ minNotional = self.safe_number(filter, 'minNotional')
214
+ elif filterType == 'TRADE_AMOUNT':
215
+ minAmount = self.safe_number(filter, 'minAmount')
216
+ maxAmount = self.safe_number(filter, 'maxAmount')
169
217
  id = symbol
170
- base = self.safe_currency_code(baseId)
171
- quote = self.safe_currency_code(quoteId)
172
- baseId = baseId.lower()
173
- quoteId = quoteId.lower()
218
+ base = self.safe_currency_code(baseAsset)
219
+ quote = self.safe_currency_code(quoteAsset)
220
+ baseId = baseAsset.lower()
221
+ quoteId = quoteAsset.lower()
222
+ # Calculate precision from step sizes and precision strings
223
+ amountPrecision = str(self.precision_from_string(stepSize)) if stepSize else self.precision_from_string(baseAssetPrecision)
224
+ pricePrecision = str(self.precision_from_string(tickSize)) if tickSize else self.precision_from_string(quotePrecision)
174
225
  return {
175
226
  'id': id,
176
227
  'symbol': base + '/' + quote,
@@ -182,7 +233,7 @@ class toobit(Exchange, ImplicitAPI):
182
233
  'settleId': None,
183
234
  'type': 'spot',
184
235
  'spot': True,
185
- 'margin': False,
236
+ 'margin': allowMargin,
186
237
  'swap': False,
187
238
  'future': False,
188
239
  'option': False,
@@ -196,8 +247,8 @@ class toobit(Exchange, ImplicitAPI):
196
247
  'strike': None,
197
248
  'optionType': None,
198
249
  'precision': {
199
- 'amount': None,
200
- 'price': None,
250
+ 'amount': amountPrecision,
251
+ 'price': pricePrecision,
201
252
  },
202
253
  'limits': {
203
254
  'leverage': {
@@ -205,16 +256,16 @@ class toobit(Exchange, ImplicitAPI):
205
256
  'max': None,
206
257
  },
207
258
  'amount': {
208
- 'min': None,
209
- 'max': None,
259
+ 'min': minQty,
260
+ 'max': maxQty,
210
261
  },
211
262
  'price': {
212
- 'min': None,
213
- 'max': None,
263
+ 'min': minPrice,
264
+ 'max': maxPrice,
214
265
  },
215
266
  'cost': {
216
- 'min': None,
217
- 'max': None,
267
+ 'min': minNotional or minAmount,
268
+ 'max': maxAmount,
218
269
  },
219
270
  },
220
271
  'created': None,
@@ -224,7 +275,7 @@ class toobit(Exchange, ImplicitAPI):
224
275
  async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
225
276
  """
226
277
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
227
- https://apidocs.toobit.io/#tickers
278
+ https://toobit-docs.github.io/apidocs/spot/v1/en/#tickers
228
279
  :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
229
280
  :param dict [params]: extra parameters specific to the exchange API endpoint
230
281
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -246,7 +297,7 @@ class toobit(Exchange, ImplicitAPI):
246
297
  async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
247
298
  """
248
299
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
249
- https://apidocs.toobit.io/#ticker
300
+ https://toobit-docs.github.io/apidocs/spot/v1/en/#ticker
250
301
  :param str symbol: unified symbol of the market to fetch the ticker for
251
302
  :param dict [params]: extra parameters specific to the exchange API endpoint
252
303
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -315,7 +366,7 @@ class toobit(Exchange, ImplicitAPI):
315
366
  async def fetch_ohlcv(self, symbol: str, timeframe='1h', since: Int = None, limit: Int = None, params={}) -> List[list]:
316
367
  """
317
368
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
318
- https://apidocs.toobit.io/#chart
369
+ https://toobit-docs.github.io/apidocs/spot/v1/en/#chart
319
370
  :param str symbol: unified symbol of the market to fetch OHLCV data for
320
371
  :param str timeframe: the length of time each candle represents
321
372
  :param int [since]: timestamp in ms of the earliest candle to fetch