ccxt-ir 4.9.14__py2.py3-none-any.whl → 4.9.15__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.15'
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',
@@ -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})
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.9.14'
7
+ __version__ = '4.9.15'
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',
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.9.14'
5
+ __version__ = '4.9.15'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -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}
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.9.14'
7
+ __version__ = '4.9.15'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.9.14'
7
+ __version__ = '4.9.15'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
@@ -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.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
+ 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 = 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
+ 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
+ self.load_markets()
228
+ if symbols is not None:
229
+ symbols = self.market_symbols(symbols)
230
+ response = 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 = 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
+ 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 = 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}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ccxt-ir
3
- Version: 4.9.14
3
+ Version: 4.9.15
4
4
  Summary: A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges
5
5
  Home-page: https://ccxt.com
6
6
  Author: Igor Kroitor
@@ -62,7 +62,7 @@ Dynamic: summary
62
62
 
63
63
  # CCXT – CryptoCurrency eXchange Trading Library
64
64
 
65
- [![NPM Downloads](https://img.shields.io/npm/dy/ccxt.svg)](https://www.npmjs.com/package/ccxt) [![npm](https://img.shields.io/npm/v/ccxt.svg)](https://npmjs.com/package/ccxt) [![PyPI](https://img.shields.io/pypi/v/ccxt.svg)](https://pypi.python.org/pypi/ccxt) [![NuGet version](https://img.shields.io/nuget/v/ccxt)](https://www.nuget.org/packages/ccxt) [![GoDoc](https://pkg.go.dev/badge/github.com/ccxt/ccxt/go/v4?utm_source=godoc)](https://godoc.org/github.com/ccxt/ccxt/go/v4) [![Discord](https://img.shields.io/discord/690203284119617602?logo=discord&logoColor=white)](https://discord.gg/ccxt) [![Supported Exchanges](https://img.shields.io/badge/exchanges-144-blue.svg)](https://github.com/ccxt/ccxt/wiki/Exchange-Markets) [![Follow CCXT at x.com](https://img.shields.io/twitter/follow/ccxt_official.svg?style=social&label=CCXT)](https://x.com/ccxt_official)
65
+ [![NPM Downloads](https://img.shields.io/npm/dy/ccxt.svg)](https://www.npmjs.com/package/ccxt) [![npm](https://img.shields.io/npm/v/ccxt.svg)](https://npmjs.com/package/ccxt) [![PyPI](https://img.shields.io/pypi/v/ccxt.svg)](https://pypi.python.org/pypi/ccxt) [![NuGet version](https://img.shields.io/nuget/v/ccxt)](https://www.nuget.org/packages/ccxt) [![GoDoc](https://pkg.go.dev/badge/github.com/ccxt/ccxt/go/v4?utm_source=godoc)](https://godoc.org/github.com/ccxt/ccxt/go/v4) [![Discord](https://img.shields.io/discord/690203284119617602?logo=discord&logoColor=white)](https://discord.gg/ccxt) [![Supported Exchanges](https://img.shields.io/badge/exchanges-145-blue.svg)](https://github.com/ccxt/ccxt/wiki/Exchange-Markets) [![Follow CCXT at x.com](https://img.shields.io/twitter/follow/ccxt_official.svg?style=social&label=CCXT)](https://x.com/ccxt_official)
66
66
 
67
67
  A `JavaScript` / `Python` / `PHP` / `C#` / `Go` library for cryptocurrency trading and e-commerce with support for many bitcoin/ether/altcoin exchange markets and merchant APIs.
68
68
 
@@ -304,13 +304,13 @@ console.log(version, Object.keys(exchanges));
304
304
 
305
305
  All-in-one browser bundle (dependencies included), served from a CDN of your choice:
306
306
 
307
- - jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.9.14/dist/ccxt.browser.min.js
308
- - unpkg: https://unpkg.com/ccxt@4.9.14/dist/ccxt.browser.min.js
307
+ - jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.9.15/dist/ccxt.browser.min.js
308
+ - unpkg: https://unpkg.com/ccxt@4.9.15/dist/ccxt.browser.min.js
309
309
 
310
310
  CDNs are not updated in real-time and may have delays. Defaulting to the most recent version without specifying the version number is not recommended. Please, keep in mind that we are not responsible for the correct operation of those CDN servers.
311
311
 
312
312
  ```HTML
313
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.9.14/dist/ccxt.browser.min.js"></script>
313
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.9.15/dist/ccxt.browser.min.js"></script>
314
314
  console.log (ccxt.exchanges) // print all available exchanges
315
315
  ```
316
316
 
@@ -1,4 +1,4 @@
1
- ccxt/__init__.py,sha256=2_6cf7ENK3ZNeeM6t18WaZxBiyTJ9X2urdGL6MQZNog,20091
1
+ ccxt/__init__.py,sha256=bGpuCwRBhSalnqhpahecE6Xb-D0AFfd1mt1IvQwnxoM,20197
2
2
  ccxt/abantether.py,sha256=Ds5AIDyJtOwcsKHY6LBXJsFL2tR7d_5k64HHzpaBeGI,12879
3
3
  ccxt/afratether.py,sha256=5PX0U1GQ3ylOQuQ8Mm9yIsF5J3aqfTZcp6iV87I8E_0,12245
4
4
  ccxt/alpaca.py,sha256=oO0YJHxo5_1iYyGVRMbxfGyPahqzuMlE7LZ3TMYgPGo,80694
@@ -125,6 +125,7 @@ ccxt/ramzinex.py,sha256=Si0Nuhfy7fo7t3Gi9y7uVFSt_FM5nS3Uo2j2vf6gxEw,19486
125
125
  ccxt/sarmayex.py,sha256=jTbQOwdZYlxgHKDoFRoKTngtm1asFaEihnUx7n1Q2pw,13404
126
126
  ccxt/sarrafex.py,sha256=D1fo5tCmowlDb8CtsCoHrVkmf_WjhYp-6q-pcVkDFBg,19125
127
127
  ccxt/tabdeal.py,sha256=OWR4aV5Ek3cgIk3zjXy1l04hdbLxJZxd-3icm6prAvA,14358
128
+ ccxt/tehran_exchange.py,sha256=02LkTk0aJYTv-vMKgl9CCn9dzhIEUNEiKBv-XQyYQlI,12514
128
129
  ccxt/tetherland.py,sha256=lqV2-p2c3bBj98wx8uOuig1HIvfC3YPnjY68EVFeMuA,13915
129
130
  ccxt/timex.py,sha256=MiLB4GyIpEOHweaQuzIrBJyuevw3jsVvitsaK7iQ6RE,76698
130
131
  ccxt/tokocrypto.py,sha256=-q95F-FvV-dgatuZzfJNnojtNxuyyyzmTpHLyOpu8Vw,126328
@@ -270,6 +271,7 @@ ccxt/abstract/ramzinex.py,sha256=P_sb56EyRGXHKpAlrpmrFDVw6I3uv_p5PysEoqsoTbQ,584
270
271
  ccxt/abstract/sarmayex.py,sha256=bbyChQifNASMQnFiwpEu1rlXJNDBkdE2jqjRWvWEBYA,194
271
272
  ccxt/abstract/sarrafex.py,sha256=3z9KKrA1jybHLOAjxLm7tGA7Uiga6p9-yulkU6k-PMs,538
272
273
  ccxt/abstract/tabdeal.py,sha256=9wPBn90yiZrWpS9lWHAbE-mvOj4rdn_0ImYwPaRN5js,418
274
+ ccxt/abstract/tehran_exchange.py,sha256=J189abh3OO9j86o6Rd3iXuwwCOP4LJ2CJjnrSN1mpNw,331
273
275
  ccxt/abstract/tetherland.py,sha256=oeq5VUYhHg8h9IaD7bDQlTCgZfHY80WAYnO-F-esl18,174
274
276
  ccxt/abstract/timex.py,sha256=9b0CDsyjm8XrYZmhUMB1dTHUmyE9YrsZTCZrz1UTt6E,5875
275
277
  ccxt/abstract/tokocrypto.py,sha256=OF5UW4ch_Lf3-avOPgd4AD4CVrOUDUfUpSMCmxhNHlk,4094
@@ -288,7 +290,7 @@ ccxt/abstract/xt.py,sha256=n3eX1cItL_J0j8prOViV-C_tRwIFv_GO8JTvZZw8jv8,27837
288
290
  ccxt/abstract/yobit.py,sha256=8ycfCO8ORFly9hc0Aa47sZyX4_ZKPXS9h9yJzI-uQ7Q,1339
289
291
  ccxt/abstract/zaif.py,sha256=m15WHdl3gYy0GOXNZ8NEH8eE7sVh8c0T_ITNuU8vXeU,3935
290
292
  ccxt/abstract/zonda.py,sha256=X-hCW0SdX3YKZWixDyW-O2211M58Rno8kKJ6quY7rw4,7183
291
- ccxt/async_support/__init__.py,sha256=3aI6c7frbh6E9p1304C-7vuuK1kFKsJTsC-PYssOqHc,20254
293
+ ccxt/async_support/__init__.py,sha256=t500HQFFT5ozK5mP4LciIrQX3XcQ9oFu7hOR47Cysh4,20370
292
294
  ccxt/async_support/abantether.py,sha256=588gCktw-6cxm6nyp4_KvlCJb9_TphurxpxsK2MVlKs,12935
293
295
  ccxt/async_support/afratether.py,sha256=fhVGoxrIbXXser4tIsCBgfVIivLnq7hpZBvzR84WgBs,12313
294
296
  ccxt/async_support/alpaca.py,sha256=oFpSnAjX-faRgTN4d5rwHa08WRaCkwiAbHGZ7JBe6Ww,81140
@@ -415,6 +417,7 @@ ccxt/async_support/ramzinex.py,sha256=Abs2Uj31vh4KnAXxuRsTcj2Bjrs0MExZ4dC4PCTuX4
415
417
  ccxt/async_support/sarmayex.py,sha256=WqQjSTKi9EAoaOilJEEA0BMtqoEKOzk9XoAijdD1i-E,13460
416
418
  ccxt/async_support/sarrafex.py,sha256=ZJBxRfWZ0vMgBPeneEyxlNVxXHLzeGICwxT3lAVhH-M,19223
417
419
  ccxt/async_support/tabdeal.py,sha256=_kDTQeB8pQSZKYOiBc0IoZBuIsOkwvhhhTNN8m4A0G8,14450
420
+ ccxt/async_support/tehran_exchange.py,sha256=-z8FCrUUqJSHjuJ2RUD9U4gKNKIunqzjia9i9ZIn7xU,12576
418
421
  ccxt/async_support/tetherland.py,sha256=qjrg3bVakqBPs-2-u9fr2gPTN--JbXbw5gJ0_jWF6O0,13971
419
422
  ccxt/async_support/timex.py,sha256=SMMswaincdUzCI8waSpCnCEMPG5zEWe6UtcE4KteJaI,77060
420
423
  ccxt/async_support/tokocrypto.py,sha256=noI2aWGN2rH71WDomTl2GeysjsNbuMbLNHKMTNvJYOs,126690
@@ -434,7 +437,7 @@ ccxt/async_support/yobit.py,sha256=FBI7ajvxprTYUqX8zosd7-LntDft8vIEjRTHng5ry8Y,5
434
437
  ccxt/async_support/zaif.py,sha256=mh0PETLMTJV509zhT7jukddg6S7YhvwhCT7zqxC6YLA,31364
435
438
  ccxt/async_support/zonda.py,sha256=7hmHotE5JBd8034d1ZbX3oIeWIpQFrQb8aK-dP3Btx0,85327
436
439
  ccxt/async_support/base/__init__.py,sha256=aVYSsFi--b4InRs9zDN_wtCpj8odosAB726JdUHavrk,67
437
- ccxt/async_support/base/exchange.py,sha256=QBJGiTm8HAAxk6y3KBAHgOYkEagJvoo8EdVwDSPjv_k,121269
440
+ ccxt/async_support/base/exchange.py,sha256=Jj14GCgAB3Nrp3E4bqGRRIur9CTPNw_PLyEM_uKhVfw,121269
438
441
  ccxt/async_support/base/throttler.py,sha256=tvDVcdRUVYi8fZRlEcnqtgzcgB_KMUMRs5Pu8tuU-tU,1847
439
442
  ccxt/async_support/base/ws/__init__.py,sha256=uockzpLuwntKGZbs5EOWFe-Zg-k6Cj7GhNJLc_RX0so,1791
440
443
  ccxt/async_support/base/ws/cache.py,sha256=xf2VOtfUwloxSlIQ39M1RGZHWQzyS9IGhB5NX6cDcAc,8370
@@ -446,10 +449,10 @@ ccxt/async_support/base/ws/order_book_side.py,sha256=GhnGUt78pJ-AYL_Dq9produGjmB
446
449
  ccxt/base/__init__.py,sha256=eTx1OE3HJjspFUQjGm6LBhaQiMKJnXjkdP-JUXknyQ0,1320
447
450
  ccxt/base/decimal_to_precision.py,sha256=3XI30u9YudHbTA438397u5rkdlXa3atxwZEfUus3C4k,6803
448
451
  ccxt/base/errors.py,sha256=OGhWNvNtRlJOzFx-n1x3ZjTnaPpfWH0Vc0xACS-MeDw,5012
449
- ccxt/base/exchange.py,sha256=Fs-CjxfJbx-CC8qxY-i1-4eOiPHjfUScjKajqPUHfs0,334338
452
+ ccxt/base/exchange.py,sha256=fLo_vJtpKkfmf6PI5wxlqZ8sacsWstTl_fvL7V74Ar8,334338
450
453
  ccxt/base/precise.py,sha256=koce64Yrp6vFbGijJtUt-QQ6XhJgeGTCksZ871FPp_A,8886
451
454
  ccxt/base/types.py,sha256=Gvbogh9i7pPH7Z18xesYeDPribqqwq8uKpOv-YODFBs,11505
452
- ccxt/pro/__init__.py,sha256=r54jDyNW-tQiQ8iE65wtG7rQQclE6lG_DBVGusAi730,11464
455
+ ccxt/pro/__init__.py,sha256=qRU34cfGk8pvHQTj5TjDWWSXRvfDUNtTmXPvphVkuQU,11464
453
456
  ccxt/pro/alpaca.py,sha256=REAEZxdv2pY8xjxBGCBca3nPKpIdleVqr-IVpuVmADg,27637
454
457
  ccxt/pro/apex.py,sha256=FLBaLN2FESIh9gqHPVwf0IkkIHpxGHHUcFwgBGBEkrA,42018
455
458
  ccxt/pro/ascendex.py,sha256=P0DnIMIA-BIGxyoEQBLGtjH-whRhkPbhe8gU2s5V238,37526
@@ -772,8 +775,8 @@ ccxt/test/tests_async.py,sha256=D5ZDYYW635E2LFEhJt7HfIjbFVCQl3WSBEFnR-QEQzM,9549
772
775
  ccxt/test/tests_helpers.py,sha256=egM69A2ZFYeVF5hwC1Qt-c5DOeClY5bv4jowmceeFV8,9736
773
776
  ccxt/test/tests_init.py,sha256=qM0-Gb0h0p6CANWTkyYZI7wl-iYOcrPur7aj_OKh7m0,1212
774
777
  ccxt/test/tests_sync.py,sha256=Rr72cGmoKqbUIIEJJAGh2_QhBc4rIZlBxVtGCQVd4BE,94440
775
- ccxt_ir-4.9.14.dist-info/licenses/LICENSE.txt,sha256=EIb9221AhMHV7xF1_55STFdKTFsnJVJYkRpY2Lnvo5w,1068
776
- ccxt_ir-4.9.14.dist-info/METADATA,sha256=6nNZ6y-4lEFUqQRk1Tiq-rX2hVFtBk7d1vLm1f3jZa8,138934
777
- ccxt_ir-4.9.14.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
778
- ccxt_ir-4.9.14.dist-info/top_level.txt,sha256=CkQDuCTDKNcImPV60t36G6MdYfxsAPNiSaEwifVoVMo,5
779
- ccxt_ir-4.9.14.dist-info/RECORD,,
778
+ ccxt_ir-4.9.15.dist-info/licenses/LICENSE.txt,sha256=EIb9221AhMHV7xF1_55STFdKTFsnJVJYkRpY2Lnvo5w,1068
779
+ ccxt_ir-4.9.15.dist-info/METADATA,sha256=nEssrCMpFsmIWJsZZ7Kz3ekD_7Cxe2VdOv5LnkMAsok,138934
780
+ ccxt_ir-4.9.15.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
781
+ ccxt_ir-4.9.15.dist-info/top_level.txt,sha256=CkQDuCTDKNcImPV60t36G6MdYfxsAPNiSaEwifVoVMo,5
782
+ ccxt_ir-4.9.15.dist-info/RECORD,,