HedgeTech 0.0.0__py3-none-any.whl → 0.1.0__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.
- HedgeTech/Auth/__AuthAsyncClient.py +150 -0
- HedgeTech/Auth/__AuthSyncClient.py +153 -0
- HedgeTech/Auth/__init__.py +2 -0
- HedgeTech/DataEngine/__init__.py +4 -0
- HedgeTech/DataEngine/__tse_ifb/__AsyncClient.py +1588 -0
- HedgeTech/DataEngine/__tse_ifb/__SyncClient.py +1542 -0
- HedgeTech/DataEngine/__tse_ifb/__init__.py +2 -0
- HedgeTech/DataEngine/__tse_ifb/__io_types/__init__.py +39 -0
- HedgeTech/DataEngine/__tse_ifb/__io_types/__requests.py +47 -0
- HedgeTech/DataEngine/__tse_ifb/__io_types/__response.py +1921 -0
- {hedgetech-0.0.0.dist-info → hedgetech-0.1.0.dist-info}/METADATA +170 -8
- hedgetech-0.1.0.dist-info/RECORD +16 -0
- HedgeTech/__init__.py +0 -0
- hedgetech-0.0.0.dist-info/RECORD +0 -7
- {hedgetech-0.0.0.dist-info → hedgetech-0.1.0.dist-info}/WHEEL +0 -0
- {hedgetech-0.0.0.dist-info → hedgetech-0.1.0.dist-info}/licenses/LICENSE +0 -0
- {hedgetech-0.0.0.dist-info → hedgetech-0.1.0.dist-info}/licenses/NOTICE +0 -0
- {hedgetech-0.0.0.dist-info → hedgetech-0.1.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,1588 @@
|
|
|
1
|
+
# ========================================|======================================== #
|
|
2
|
+
# Imports #
|
|
3
|
+
# ========================================|======================================== #
|
|
4
|
+
|
|
5
|
+
from asyncio import Event
|
|
6
|
+
from websockets.asyncio.client import connect
|
|
7
|
+
from json import loads
|
|
8
|
+
from HedgeTech.Auth import AuthAsyncClient
|
|
9
|
+
from typing import (
|
|
10
|
+
Literal,
|
|
11
|
+
List,
|
|
12
|
+
Union,
|
|
13
|
+
AsyncGenerator,
|
|
14
|
+
)
|
|
15
|
+
from .__io_types import (
|
|
16
|
+
Instruments,
|
|
17
|
+
OverviewResponse,
|
|
18
|
+
BestLimitResponse,
|
|
19
|
+
OrderBookResponse,
|
|
20
|
+
AggregateResponse,
|
|
21
|
+
Institutional_vs_IndividualItemResponse,
|
|
22
|
+
ContractInfoResponse,
|
|
23
|
+
FundInfoResponse,
|
|
24
|
+
OHLCVLast1mResponse,
|
|
25
|
+
|
|
26
|
+
OHLCVResponse,
|
|
27
|
+
CorporateActionResponse,
|
|
28
|
+
|
|
29
|
+
BestLimit_WS_symbolIsin,
|
|
30
|
+
BestLimit_WS_symbolName,
|
|
31
|
+
OrderBook_WS_symbolIsin,
|
|
32
|
+
OrderBook_WS_symbolName,
|
|
33
|
+
Aggregate_WS_symbolIsin,
|
|
34
|
+
Aggregate_WS_symbolName,
|
|
35
|
+
institutional_vs_individual_WS_symbolIsin,
|
|
36
|
+
institutional_vs_individual_WS_symbolName,
|
|
37
|
+
ContractInfo_WS_symbolIsin,
|
|
38
|
+
ContractInfo_WS_symbolName,
|
|
39
|
+
FundInfo_WS_symbolIsin,
|
|
40
|
+
FundInfo_WS_symbolName,
|
|
41
|
+
OHLCV_WS_symbolIsin,
|
|
42
|
+
OHLCV_WS_symbolName,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# ========================================|======================================== #
|
|
46
|
+
# Class Definitions #
|
|
47
|
+
# ========================================|======================================== #
|
|
48
|
+
|
|
49
|
+
class DataEngine_TseIfb_AsyncClient:
|
|
50
|
+
|
|
51
|
+
"""
|
|
52
|
+
Asynchronous client for interacting with the TSE-IFB (Iranian Securities Exchange) Data Engine API.
|
|
53
|
+
|
|
54
|
+
This class provides high-level asynchronous methods to retrieve live and historical market data,
|
|
55
|
+
order book information, best-limit quotes, OHLCV data, fund info, corporate actions, and other
|
|
56
|
+
trading-related data. It leverages an authenticated `AuthAsyncClient` for authorized access.
|
|
57
|
+
|
|
58
|
+
All methods return TypedDict objects defined in the module, providing structured data
|
|
59
|
+
including:
|
|
60
|
+
- Instruments, SecuritiesAndFunds, StockOptions, StockFutures, TreasuryBonds
|
|
61
|
+
- BestLimit, OrderBook, Aggregate, Institutional_vs_Individual
|
|
62
|
+
- ContractInfo, FundInfo, OHLCV (live and historical)
|
|
63
|
+
- CorporateActions
|
|
64
|
+
|
|
65
|
+
Attributes:
|
|
66
|
+
__AuthAsyncClient (AuthAsyncClient): An instance of `AuthAsyncClient` used to perform
|
|
67
|
+
authorized HTTP requests and WebSocket connections.
|
|
68
|
+
|
|
69
|
+
Examples:
|
|
70
|
+
>>> auth_client = await AuthAsyncClient.login(
|
|
71
|
+
... UserName_or_Email="user@example.com",
|
|
72
|
+
... Password="secure_password"
|
|
73
|
+
... )
|
|
74
|
+
>>> data_client = DataEngine_TseIfb_AsyncClient(AuthAsyncClient=auth_client)
|
|
75
|
+
>>> instruments = await data_client.instruments_static_info_by_name(["فملی", "خودرو"])
|
|
76
|
+
>>> print(instruments["Data"]["فملی"]["symbolName"])
|
|
77
|
+
>>> async for update in data_client.websocket_by_name(
|
|
78
|
+
... channels=["best-limit", "order-book"],
|
|
79
|
+
... symbol_names=["فملی"]
|
|
80
|
+
... ):
|
|
81
|
+
... print(update)
|
|
82
|
+
|
|
83
|
+
Notes:
|
|
84
|
+
- All network requests are asynchronous and should be awaited.
|
|
85
|
+
- WebSocket methods yield streaming updates and should be used with `async for`.
|
|
86
|
+
- Exceptions (ValueError) are raised when the API returns an error or request fails.
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
def __init__(
|
|
90
|
+
self,
|
|
91
|
+
AuthAsyncClient : AuthAsyncClient,
|
|
92
|
+
):
|
|
93
|
+
"""
|
|
94
|
+
Initialize the DataEngine_TseIfb_AsyncClient with an authenticated async client.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
AuthAsyncClient (AuthAsyncClient): An instance of `AuthAsyncClient` used for
|
|
98
|
+
making authorized asynchronous requests to the TSE-IFB data engine.
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
self.__AuthAsyncClient = AuthAsyncClient
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
105
|
+
|
|
106
|
+
async def search_instruments(
|
|
107
|
+
self,
|
|
108
|
+
market : Literal[
|
|
109
|
+
"SecuritiesAndFunds",
|
|
110
|
+
"TreasuryBonds",
|
|
111
|
+
"StockOptions",
|
|
112
|
+
"StockFutures",
|
|
113
|
+
],
|
|
114
|
+
Search_char : str,
|
|
115
|
+
)-> Instruments :
|
|
116
|
+
|
|
117
|
+
"""
|
|
118
|
+
Search for instruments in a specific market by name, title, or partial text.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
market (Literal["SecuritiesAndFunds", "TreasuryBonds", "StockOptions", "StockFutures"]):
|
|
122
|
+
Determines which market group to search in.
|
|
123
|
+
Each market corresponds to a specific instrument class category.
|
|
124
|
+
|
|
125
|
+
Search_char (str):
|
|
126
|
+
Text to search for. Can be part of the symbol name, title,
|
|
127
|
+
or any searchable field related to the instrument.
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
Instruments:
|
|
131
|
+
A dictionary containing:
|
|
132
|
+
- Data: A list of matched instruments. Each item is one of:
|
|
133
|
+
* SecuritiesAndFunds
|
|
134
|
+
* TreasuryBonds
|
|
135
|
+
* StockOptions
|
|
136
|
+
* StockFutures
|
|
137
|
+
* None (when no match exists)
|
|
138
|
+
- Status: Status information returned by the API.
|
|
139
|
+
|
|
140
|
+
Raises:
|
|
141
|
+
ValueError:
|
|
142
|
+
Raised when API response is not successful or contains an error message
|
|
143
|
+
in the field ``detail``.
|
|
144
|
+
|
|
145
|
+
Example:
|
|
146
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
147
|
+
>>> result = await client.search_instruments(
|
|
148
|
+
... market="SecuritiesAndFunds",
|
|
149
|
+
... Search_char="فولاد"
|
|
150
|
+
... )
|
|
151
|
+
>>> print(result["Data"][0]["symbolName"])
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
155
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/static/data/instruments/search',
|
|
156
|
+
params={
|
|
157
|
+
'market' : market,
|
|
158
|
+
'Search_char' : Search_char
|
|
159
|
+
}
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
if data.is_success :
|
|
163
|
+
|
|
164
|
+
return data.json()
|
|
165
|
+
|
|
166
|
+
else :
|
|
167
|
+
|
|
168
|
+
raise ValueError(data.json().get('detail'))
|
|
169
|
+
|
|
170
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
171
|
+
|
|
172
|
+
async def instruments_static_info_by_name(self,symbol_names : List[str])-> Instruments:
|
|
173
|
+
"""
|
|
174
|
+
Retrieve static instrument information based on a list of symbol names.
|
|
175
|
+
|
|
176
|
+
This endpoint returns complete static metadata for each provided symbol name,
|
|
177
|
+
including instrument type, commissions, trading permissions, price limits,
|
|
178
|
+
and additional attributes depending on the instrument class.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
symbol_names (List[str]):
|
|
182
|
+
A list of instrument symbol names to query.
|
|
183
|
+
Each item must be an exact symbol name as recognized by TSE/IFB.
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
Instruments:
|
|
187
|
+
A dictionary containing:
|
|
188
|
+
- Data: A mapping of symbol_name → Instrument info.
|
|
189
|
+
Instrument info is one of:
|
|
190
|
+
* SecuritiesAndFunds
|
|
191
|
+
* TreasuryBonds
|
|
192
|
+
* StockOptions
|
|
193
|
+
* StockFutures
|
|
194
|
+
* None (if symbol not found)
|
|
195
|
+
- Status: General API status information.
|
|
196
|
+
|
|
197
|
+
Raises:
|
|
198
|
+
ValueError:
|
|
199
|
+
Raised if the API request fails or returns an error message inside ``detail``.
|
|
200
|
+
|
|
201
|
+
Example:
|
|
202
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
203
|
+
>>> result = await client.instruments_static_info_by_name(
|
|
204
|
+
... ["فملی", "خودرو"]
|
|
205
|
+
... )
|
|
206
|
+
>>> print(result["Data"]["فملی"]["symbolIsin"])
|
|
207
|
+
"""
|
|
208
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
209
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/static/data/instruments/symbol/name',
|
|
210
|
+
params=[('symbol_names', name) for name in symbol_names]
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
if data.is_success :
|
|
214
|
+
|
|
215
|
+
return data.json()
|
|
216
|
+
|
|
217
|
+
else :
|
|
218
|
+
|
|
219
|
+
raise ValueError(data.json().get('detail'))
|
|
220
|
+
|
|
221
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
222
|
+
|
|
223
|
+
async def instruments_static_info_by_isin(self,symbol_isins : List[str])-> Instruments:
|
|
224
|
+
|
|
225
|
+
"""
|
|
226
|
+
Get static information for multiple instruments using their ISIN codes.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
symbol_isins (List[str]):
|
|
230
|
+
A list of instrument ISIN codes. Each ISIN must be a valid symbol
|
|
231
|
+
registered in TSE/IFB. The request supports multiple ISIN values.
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
Instruments:
|
|
235
|
+
A dictionary containing:
|
|
236
|
+
- Data: A list of instruments matching the provided ISINs.
|
|
237
|
+
Each item can be SecuritiesAndFunds, TreasuryBonds,
|
|
238
|
+
StockOptions, StockFutures, or None if not found.
|
|
239
|
+
- Status: Status information returned by the API.
|
|
240
|
+
|
|
241
|
+
Raises:
|
|
242
|
+
ValueError:
|
|
243
|
+
Raised when the API response indicates failure or contains an
|
|
244
|
+
error message in the response payload.
|
|
245
|
+
|
|
246
|
+
Example:
|
|
247
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
248
|
+
>>> result = await client.instruments_static_info_by_isin([
|
|
249
|
+
... "IRO1XYZ12345",
|
|
250
|
+
... "IRO1ABC98765"
|
|
251
|
+
... ])
|
|
252
|
+
>>> print(result["Data"][0]["symbolName"])
|
|
253
|
+
|
|
254
|
+
"""
|
|
255
|
+
|
|
256
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
257
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/static/data/instruments/symbol/isin',
|
|
258
|
+
params=[('symbol_isins', isin) for isin in symbol_isins]
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
if data.is_success :
|
|
262
|
+
|
|
263
|
+
return data.json()
|
|
264
|
+
|
|
265
|
+
else :
|
|
266
|
+
|
|
267
|
+
raise ValueError(data.json().get('detail'))
|
|
268
|
+
|
|
269
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
270
|
+
|
|
271
|
+
async def live_overview_by_name(self,symbol_names : List[str])-> OverviewResponse:
|
|
272
|
+
"""
|
|
273
|
+
Retrieve the **live aggregated market overview** for a list of symbol names.
|
|
274
|
+
|
|
275
|
+
This endpoint provides a full real-time snapshot for each symbol, combining multiple
|
|
276
|
+
live data sources—best limits, aggregate prices, institutional vs individual flow,
|
|
277
|
+
fund information, and contract details—into a unified structure for each instrument.
|
|
278
|
+
|
|
279
|
+
Args:
|
|
280
|
+
symbol_names (List[str]):
|
|
281
|
+
A list of symbol names whose live overview data should be fetched.
|
|
282
|
+
Each name must match the exact trading symbol (e.g., "فملی", "خودرو").
|
|
283
|
+
|
|
284
|
+
Returns:
|
|
285
|
+
OverviewResponse:
|
|
286
|
+
A dictionary structured as:
|
|
287
|
+
- **Data**: Mapping of symbol_name → overview object.
|
|
288
|
+
Each overview object is one of:
|
|
289
|
+
* OverviewSecuritiesAndFunds
|
|
290
|
+
* OverviewTreasuryBonds
|
|
291
|
+
* OverviewStockOptions
|
|
292
|
+
* OverviewStockFuturess
|
|
293
|
+
* None (if symbol not found)
|
|
294
|
+
|
|
295
|
+
Each overview entry includes:
|
|
296
|
+
- BestLimit: Real-time order-book best limits
|
|
297
|
+
- Aggregate: Live OHLC/volume summary
|
|
298
|
+
- institutional_vs_individual: Buy/sell breakdown
|
|
299
|
+
- FundInfo: NAV + fund statistics
|
|
300
|
+
- ContractInfo: Margin & open interest (if applicable)
|
|
301
|
+
|
|
302
|
+
- **Status**: Standard API status and metadata.
|
|
303
|
+
|
|
304
|
+
Raises:
|
|
305
|
+
ValueError:
|
|
306
|
+
If the request fails or if an error is returned by the API in the `detail` field.
|
|
307
|
+
|
|
308
|
+
Example:
|
|
309
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
310
|
+
>>> overview = await client.live_overview_by_name(["فملی", "شستا"])
|
|
311
|
+
>>> print(overview["Data"]["فملی"]["Aggregate"]["closing_price"])
|
|
312
|
+
"""
|
|
313
|
+
|
|
314
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
315
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/live/data/instruments/overview/symbol/name',
|
|
316
|
+
params=[('symbol_names', name) for name in symbol_names]
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
if data.is_success :
|
|
320
|
+
|
|
321
|
+
return data.json()
|
|
322
|
+
|
|
323
|
+
else :
|
|
324
|
+
|
|
325
|
+
raise ValueError(data.json().get('detail'))
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
async def live_overview_by_isin(self,symbol_isins : List[str])-> OverviewResponse:
|
|
332
|
+
"""
|
|
333
|
+
Retrieve the **live aggregated market overview** for instruments using their ISIN codes.
|
|
334
|
+
|
|
335
|
+
This endpoint provides a comprehensive real-time snapshot for each requested instrument,
|
|
336
|
+
combining multiple live data streams—best limits, aggregate OHLCV, institutional vs
|
|
337
|
+
individual flow, fund information, and contract details—into one unified response object.
|
|
338
|
+
|
|
339
|
+
Args:
|
|
340
|
+
symbol_isins (List[str]):
|
|
341
|
+
A list of instrument ISIN codes (e.g., "IRO1XYZ12345").
|
|
342
|
+
Each ISIN must reference a valid tradable instrument in the TSE/IFB markets.
|
|
343
|
+
|
|
344
|
+
Returns:
|
|
345
|
+
OverviewResponse:
|
|
346
|
+
A dictionary containing:
|
|
347
|
+
- **Data**: Mapping of ISIN → overview object.
|
|
348
|
+
Each overview object is one of:
|
|
349
|
+
* OverviewSecuritiesAndFunds
|
|
350
|
+
* OverviewTreasuryBonds
|
|
351
|
+
* OverviewStockOptions
|
|
352
|
+
* OverviewStockFuturess
|
|
353
|
+
* None (if the ISIN is not found)
|
|
354
|
+
|
|
355
|
+
Each overview contains:
|
|
356
|
+
- BestLimit: Current best bid/ask levels
|
|
357
|
+
- Aggregate: Latest intraday market summary
|
|
358
|
+
- institutional_vs_individual: Buy/sell breakdown
|
|
359
|
+
- FundInfo: NAV and fund-related metrics (if applicable)
|
|
360
|
+
- ContractInfo: Margins & open interest (if applicable)
|
|
361
|
+
|
|
362
|
+
- **Status**: API status information and metadata.
|
|
363
|
+
|
|
364
|
+
Raises:
|
|
365
|
+
ValueError:
|
|
366
|
+
Raised when the API returns a failure response or an error description
|
|
367
|
+
in the `detail` field of the payload.
|
|
368
|
+
|
|
369
|
+
Example:
|
|
370
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
371
|
+
>>> result = await client.live_overview_by_isin([
|
|
372
|
+
... "IRO1XYZ12345",
|
|
373
|
+
... "IRO1ABC98765"
|
|
374
|
+
... ])
|
|
375
|
+
>>> print(result["Data"]["IRO1XYZ12345"]["BestLimit"])
|
|
376
|
+
"""
|
|
377
|
+
|
|
378
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
379
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/live/data/instruments/overview/symbol/isin',
|
|
380
|
+
params=[('symbol_isins', isin) for isin in symbol_isins]
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
if data.is_success :
|
|
384
|
+
|
|
385
|
+
return data.json()
|
|
386
|
+
|
|
387
|
+
else :
|
|
388
|
+
|
|
389
|
+
raise ValueError(data.json().get('detail'))
|
|
390
|
+
|
|
391
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
392
|
+
|
|
393
|
+
async def live_best_limit_by_name(self,symbol_names : List[str])-> BestLimitResponse:
|
|
394
|
+
"""
|
|
395
|
+
Retrieve **real-time best-limit (best bid/ask)** data for a list of instruments using their symbol names.
|
|
396
|
+
|
|
397
|
+
This endpoint returns the top-of-the-book order data, including:
|
|
398
|
+
- Best bid price, quantity, and order count
|
|
399
|
+
- Best ask price, quantity, and order count
|
|
400
|
+
|
|
401
|
+
Args:
|
|
402
|
+
symbol_names (List[str]):
|
|
403
|
+
A list of trading symbol names (e.g., ["فملی", "خودرو"]).
|
|
404
|
+
Each name must exactly match the market symbol.
|
|
405
|
+
|
|
406
|
+
Returns:
|
|
407
|
+
BestLimitResponse:
|
|
408
|
+
An object containing:
|
|
409
|
+
- **Data**:
|
|
410
|
+
Mapping of symbol_name → BestLimitItem
|
|
411
|
+
Each BestLimitItem includes:
|
|
412
|
+
* buy_order_count
|
|
413
|
+
* buy_quantity
|
|
414
|
+
* buy_price
|
|
415
|
+
* sell_order_count
|
|
416
|
+
* sell_quantity
|
|
417
|
+
* sell_price
|
|
418
|
+
- **Status**: Standard API status object.
|
|
419
|
+
|
|
420
|
+
Raises:
|
|
421
|
+
ValueError:
|
|
422
|
+
If the request fails or if the API returns an error message in the `detail` field.
|
|
423
|
+
|
|
424
|
+
Example:
|
|
425
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
426
|
+
>>> bl = await client.live_best_limit_by_name(["فملی"])
|
|
427
|
+
>>> print(bl["Data"]["فملی"]["buy_price"])
|
|
428
|
+
"""
|
|
429
|
+
|
|
430
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
431
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/live/data/instruments/best-limit/symbol/name',
|
|
432
|
+
params=[('symbol_names', name) for name in symbol_names]
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
if data.is_success :
|
|
436
|
+
|
|
437
|
+
return data.json()
|
|
438
|
+
|
|
439
|
+
else :
|
|
440
|
+
|
|
441
|
+
raise ValueError(data.json().get('detail'))
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
async def live_best_limit_by_isin(self,symbol_isins : List[str])-> BestLimitResponse:
|
|
448
|
+
"""
|
|
449
|
+
Retrieve **real-time best-limit (best bid/ask)** data for a list of instruments using their ISIN codes.
|
|
450
|
+
|
|
451
|
+
This endpoint returns the top-of-book order metrics for each ISIN instrument.
|
|
452
|
+
|
|
453
|
+
Args:
|
|
454
|
+
symbol_isins (List[str]):
|
|
455
|
+
A list of instrument ISIN codes (e.g., ["IRO1XYZ12345"]).
|
|
456
|
+
|
|
457
|
+
Returns:
|
|
458
|
+
BestLimitResponse:
|
|
459
|
+
An object containing:
|
|
460
|
+
- **Data**:
|
|
461
|
+
Mapping of symbol_isin → BestLimitItem
|
|
462
|
+
Each BestLimitItem includes:
|
|
463
|
+
* buy_order_count
|
|
464
|
+
* buy_quantity
|
|
465
|
+
* buy_price
|
|
466
|
+
* sell_order_count
|
|
467
|
+
* sell_quantity
|
|
468
|
+
* sell_price
|
|
469
|
+
- **Status**: API status metadata.
|
|
470
|
+
|
|
471
|
+
Raises:
|
|
472
|
+
ValueError:
|
|
473
|
+
If the request fails or the server returns an error in the `detail` field.
|
|
474
|
+
|
|
475
|
+
Example:
|
|
476
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
477
|
+
>>> bl = await client.live_best_limit_by_isin(["IRO1XYZ12345"])
|
|
478
|
+
>>> print(bl["Data"]["IRO1XYZ12345"]["sell_quantity"])
|
|
479
|
+
"""
|
|
480
|
+
|
|
481
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
482
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/live/data/instruments/best-limit/symbol/isin',
|
|
483
|
+
params=[('symbol_isins', isin) for isin in symbol_isins]
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
if data.is_success :
|
|
487
|
+
|
|
488
|
+
return data.json()
|
|
489
|
+
|
|
490
|
+
else :
|
|
491
|
+
|
|
492
|
+
raise ValueError(data.json().get('detail'))
|
|
493
|
+
|
|
494
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
495
|
+
|
|
496
|
+
async def live_order_book_by_name(self,symbol_names : List[str])-> OrderBookResponse :
|
|
497
|
+
"""
|
|
498
|
+
Fetch live order book data for instruments by symbol names.
|
|
499
|
+
|
|
500
|
+
Args:
|
|
501
|
+
symbol_names (List[str]): List of instrument symbol names (e.g., ["فملی", "شپنا"]).
|
|
502
|
+
|
|
503
|
+
Returns:
|
|
504
|
+
OrderBookResponse: TypedDict with structure:
|
|
505
|
+
{
|
|
506
|
+
"Data": {
|
|
507
|
+
"<symbol_name>": {
|
|
508
|
+
"Buy": List[OrderItem],
|
|
509
|
+
"Sell": List[OrderItem]
|
|
510
|
+
},
|
|
511
|
+
...
|
|
512
|
+
},
|
|
513
|
+
"Status": Status
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
Each OrderItem contains:
|
|
517
|
+
- price (float)
|
|
518
|
+
- quantity (int)
|
|
519
|
+
- count (int)
|
|
520
|
+
|
|
521
|
+
Status is a standard API status object.
|
|
522
|
+
|
|
523
|
+
Raises:
|
|
524
|
+
ValueError: If the HTTP request fails or the API returns an error.
|
|
525
|
+
|
|
526
|
+
Example:
|
|
527
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
528
|
+
>>> ob = await client.live_order_book_by_name(["فملی"])
|
|
529
|
+
>>> print(ob["Data"]["فملی"]["Buy"][0]["price"])
|
|
530
|
+
"""
|
|
531
|
+
|
|
532
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
533
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/live/data/instruments/order-book/symbol/name',
|
|
534
|
+
params=[('symbol_names', name) for name in symbol_names]
|
|
535
|
+
)
|
|
536
|
+
|
|
537
|
+
if data.is_success :
|
|
538
|
+
|
|
539
|
+
return data.json()
|
|
540
|
+
|
|
541
|
+
else :
|
|
542
|
+
|
|
543
|
+
raise ValueError(data.json().get('detail'))
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
async def live_order_book_by_isin(self,symbol_isins : List[str])-> OrderBookResponse:
|
|
550
|
+
|
|
551
|
+
"""
|
|
552
|
+
Fetch live order book data for instruments by ISIN codes.
|
|
553
|
+
|
|
554
|
+
Args:
|
|
555
|
+
symbol_isins (List[str]): List of instrument ISIN codes (for example, ["IRO1FOLD0001", "IRO1PASN0001"]).
|
|
556
|
+
|
|
557
|
+
Returns:
|
|
558
|
+
OrderBookResponse: TypedDict with structure:
|
|
559
|
+
{
|
|
560
|
+
"Data": {
|
|
561
|
+
"<ISIN>": {
|
|
562
|
+
"Buy": List[OrderItem],
|
|
563
|
+
"Sell": List[OrderItem]
|
|
564
|
+
},
|
|
565
|
+
...
|
|
566
|
+
},
|
|
567
|
+
"Status": Status
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
Each OrderItem contains:
|
|
571
|
+
- price (float)
|
|
572
|
+
- quantity (int)
|
|
573
|
+
- count (int)
|
|
574
|
+
|
|
575
|
+
Status is a standard API status object.
|
|
576
|
+
|
|
577
|
+
Raises:
|
|
578
|
+
ValueError: If the HTTP request fails or the API returns an error.
|
|
579
|
+
|
|
580
|
+
Example:
|
|
581
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
582
|
+
>>> ob = await client.live_order_book_by_isin(["IRO1FOLD0001"])
|
|
583
|
+
>>> print(ob["Data"]["IRO1FOLD0001"]["Buy"][0]["price"])
|
|
584
|
+
"""
|
|
585
|
+
|
|
586
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
587
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/live/data/instruments/order-book/symbol/isin',
|
|
588
|
+
params=[('symbol_isins', isin) for isin in symbol_isins]
|
|
589
|
+
)
|
|
590
|
+
|
|
591
|
+
if data.is_success :
|
|
592
|
+
|
|
593
|
+
return data.json()
|
|
594
|
+
|
|
595
|
+
else :
|
|
596
|
+
|
|
597
|
+
raise ValueError(data.json().get('detail'))
|
|
598
|
+
|
|
599
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
600
|
+
|
|
601
|
+
async def live_aggregate_by_name(self,symbol_names : List[str])-> AggregateResponse:
|
|
602
|
+
|
|
603
|
+
"""
|
|
604
|
+
Fetch live aggregate (OHLCV) data for instruments by symbol names.
|
|
605
|
+
|
|
606
|
+
Args:
|
|
607
|
+
symbol_names (List[str]): List of instrument symbol names (for example, ["فملی", "شپنا"]).
|
|
608
|
+
|
|
609
|
+
Returns:
|
|
610
|
+
AggregateResponse: TypedDict with structure:
|
|
611
|
+
{
|
|
612
|
+
"Data": {
|
|
613
|
+
"<symbol_name>": {
|
|
614
|
+
"date": str,
|
|
615
|
+
"time": str,
|
|
616
|
+
"trade_count": int,
|
|
617
|
+
"total_volume": int,
|
|
618
|
+
"total_value": int,
|
|
619
|
+
"closing_price": float,
|
|
620
|
+
"last_price": float,
|
|
621
|
+
"low_price": float,
|
|
622
|
+
"high_price": float,
|
|
623
|
+
"open_price": float,
|
|
624
|
+
"previous_close": float
|
|
625
|
+
},
|
|
626
|
+
...
|
|
627
|
+
},
|
|
628
|
+
"Status": Status
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
Raises:
|
|
632
|
+
ValueError: If the HTTP request fails or API returns an error.
|
|
633
|
+
|
|
634
|
+
Example:
|
|
635
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
636
|
+
>>> agg = await client.live_aggregate_by_name(["فملی"])
|
|
637
|
+
>>> print(agg["Data"]["فملی"]["closing_price"])
|
|
638
|
+
"""
|
|
639
|
+
|
|
640
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
641
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/live/data/instruments/aggregate/symbol/name',
|
|
642
|
+
params=[('symbol_names', name) for name in symbol_names]
|
|
643
|
+
)
|
|
644
|
+
|
|
645
|
+
if data.is_success :
|
|
646
|
+
|
|
647
|
+
return data.json()
|
|
648
|
+
|
|
649
|
+
else :
|
|
650
|
+
|
|
651
|
+
raise ValueError(data.json().get('detail'))
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
async def live_aggregate_by_isin(self,symbol_isins : List[str])-> AggregateResponse :
|
|
658
|
+
|
|
659
|
+
"""
|
|
660
|
+
Fetch live aggregate (OHLCV) data for instruments by ISIN codes.
|
|
661
|
+
|
|
662
|
+
Args:
|
|
663
|
+
symbol_isins (List[str]): List of instrument ISIN codes (for example, ["IRO1FOLD0001", "IRO1PASN0001"]).
|
|
664
|
+
|
|
665
|
+
Returns:
|
|
666
|
+
AggregateResponse: TypedDict with structure:
|
|
667
|
+
{
|
|
668
|
+
"Data": {
|
|
669
|
+
"<ISIN>": {
|
|
670
|
+
"date": str,
|
|
671
|
+
"time": str,
|
|
672
|
+
"trade_count": int,
|
|
673
|
+
"total_volume": int,
|
|
674
|
+
"total_value": int,
|
|
675
|
+
"closing_price": float,
|
|
676
|
+
"last_price": float,
|
|
677
|
+
"low_price": float,
|
|
678
|
+
"high_price": float,
|
|
679
|
+
"open_price": float,
|
|
680
|
+
"previous_close": float
|
|
681
|
+
},
|
|
682
|
+
...
|
|
683
|
+
},
|
|
684
|
+
"Status": Status
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
Raises:
|
|
688
|
+
ValueError: If the HTTP request fails or API returns an error.
|
|
689
|
+
|
|
690
|
+
Example:
|
|
691
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
692
|
+
>>> agg = await client.live_aggregate_by_isin(["IRO1FOLD0001"])
|
|
693
|
+
>>> print(agg["Data"]["IRO1FOLD0001"]["closing_price"])
|
|
694
|
+
"""
|
|
695
|
+
|
|
696
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
697
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/live/data/instruments/aggregate/symbol/isin',
|
|
698
|
+
params=[('symbol_isins', isin) for isin in symbol_isins]
|
|
699
|
+
)
|
|
700
|
+
|
|
701
|
+
if data.is_success :
|
|
702
|
+
|
|
703
|
+
return data.json()
|
|
704
|
+
|
|
705
|
+
else :
|
|
706
|
+
|
|
707
|
+
raise ValueError(data.json().get('detail'))
|
|
708
|
+
|
|
709
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
710
|
+
|
|
711
|
+
async def live_institutional_vs_individual_by_name(self,symbol_names : List[str])-> Institutional_vs_IndividualItemResponse:
|
|
712
|
+
|
|
713
|
+
"""
|
|
714
|
+
Fetch real-time buy/sell statistics for institutional vs individual investors by symbol names.
|
|
715
|
+
|
|
716
|
+
Args:
|
|
717
|
+
symbol_names (List[str]): List of instrument symbol names (for example, ["فملی", "شپنا"]).
|
|
718
|
+
|
|
719
|
+
Returns:
|
|
720
|
+
Institutional_vs_IndividualItemResponse: TypedDict with structure:
|
|
721
|
+
{
|
|
722
|
+
"Data": {
|
|
723
|
+
"<symbol_name>": {
|
|
724
|
+
"buy_count_individual": int,
|
|
725
|
+
"buy_volume_individual": int,
|
|
726
|
+
"buy_count_institution": int,
|
|
727
|
+
"buy_volume_institution": int,
|
|
728
|
+
"sell_count_individual": int,
|
|
729
|
+
"sell_volume_individual": int,
|
|
730
|
+
"sell_count_institution": int,
|
|
731
|
+
"sell_volume_institution": int
|
|
732
|
+
},
|
|
733
|
+
...
|
|
734
|
+
},
|
|
735
|
+
"Status": Status
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
Raises:
|
|
739
|
+
ValueError: If the HTTP request fails or the API returns an error.
|
|
740
|
+
|
|
741
|
+
Example:
|
|
742
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
743
|
+
>>> stats = await client.live_institutional_vs_individual_by_name(["فملی"])
|
|
744
|
+
>>> print(stats["Data"]["فملی"]["buy_volume_institution"])
|
|
745
|
+
"""
|
|
746
|
+
|
|
747
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
748
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/live/data/instruments/institutional-vs-individual/symbol/name',
|
|
749
|
+
params=[('symbol_names', name) for name in symbol_names]
|
|
750
|
+
)
|
|
751
|
+
|
|
752
|
+
if data.is_success :
|
|
753
|
+
|
|
754
|
+
return data.json()
|
|
755
|
+
|
|
756
|
+
else :
|
|
757
|
+
|
|
758
|
+
raise ValueError(data.json().get('detail'))
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
762
|
+
|
|
763
|
+
|
|
764
|
+
async def live_institutional_vs_individual_by_isin(self,symbol_isins : List[str])-> Institutional_vs_IndividualItemResponse :
|
|
765
|
+
"""
|
|
766
|
+
Fetch real-time buy/sell statistics for institutional vs individual investors by ISIN codes.
|
|
767
|
+
|
|
768
|
+
Args:
|
|
769
|
+
symbol_isins (List[str]): List of instrument ISIN codes (for example, ["IRO1FOLD0001", "IRO1PASN0001"]).
|
|
770
|
+
|
|
771
|
+
Returns:
|
|
772
|
+
Institutional_vs_IndividualItemResponse: TypedDict with structure:
|
|
773
|
+
{
|
|
774
|
+
"Data": {
|
|
775
|
+
"<ISIN>": {
|
|
776
|
+
"buy_count_individual": int,
|
|
777
|
+
"buy_volume_individual": int,
|
|
778
|
+
"buy_count_institution": int,
|
|
779
|
+
"buy_volume_institution": int,
|
|
780
|
+
"sell_count_individual": int,
|
|
781
|
+
"sell_volume_individual": int,
|
|
782
|
+
"sell_count_institution": int,
|
|
783
|
+
"sell_volume_institution": int
|
|
784
|
+
},
|
|
785
|
+
...
|
|
786
|
+
},
|
|
787
|
+
"Status": Status
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
Raises:
|
|
791
|
+
ValueError: If the HTTP request fails or the API returns an error.
|
|
792
|
+
|
|
793
|
+
Example:
|
|
794
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
795
|
+
>>> stats = await client.live_institutional_vs_individual_by_isin(["IRO1FOLD0001"])
|
|
796
|
+
>>> print(stats["Data"]["IRO1FOLD0001"]["buy_volume_institution"])
|
|
797
|
+
"""
|
|
798
|
+
|
|
799
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
800
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/live/data/instruments/institutional-vs-individual/symbol/isin',
|
|
801
|
+
params=[('symbol_isins', isin) for isin in symbol_isins]
|
|
802
|
+
)
|
|
803
|
+
|
|
804
|
+
if data.is_success :
|
|
805
|
+
|
|
806
|
+
return data.json()
|
|
807
|
+
|
|
808
|
+
else :
|
|
809
|
+
|
|
810
|
+
raise ValueError(data.json().get('detail'))
|
|
811
|
+
|
|
812
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
813
|
+
|
|
814
|
+
async def live_contract_info_by_name(self,symbol_names : List[str])-> ContractInfoResponse :
|
|
815
|
+
|
|
816
|
+
"""
|
|
817
|
+
Fetch real-time contract information (margins and open interest) for instruments by symbol names.
|
|
818
|
+
|
|
819
|
+
Args:
|
|
820
|
+
symbol_names (List[str]): List of instrument symbol names (for example, ["فملی", "شپنا"]).
|
|
821
|
+
|
|
822
|
+
Returns:
|
|
823
|
+
ContractInfoResponse: TypedDict with structure:
|
|
824
|
+
{
|
|
825
|
+
"Data": {
|
|
826
|
+
"<symbol_name>": {
|
|
827
|
+
"open_interest": int,
|
|
828
|
+
"initial_margin": int,
|
|
829
|
+
"required_margin": int
|
|
830
|
+
},
|
|
831
|
+
...
|
|
832
|
+
},
|
|
833
|
+
"Status": Status
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
Raises:
|
|
837
|
+
ValueError: If the HTTP request fails or the API returns an error.
|
|
838
|
+
|
|
839
|
+
Example:
|
|
840
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
841
|
+
>>> ci = await client.live_contract_info_by_name(["فملی"])
|
|
842
|
+
>>> print(ci["Data"]["فملی"]["required_margin"])
|
|
843
|
+
"""
|
|
844
|
+
|
|
845
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
846
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/live/data/instruments/contract-info/symbol/name',
|
|
847
|
+
params=[('symbol_names', name) for name in symbol_names]
|
|
848
|
+
)
|
|
849
|
+
|
|
850
|
+
if data.is_success :
|
|
851
|
+
|
|
852
|
+
return data.json()
|
|
853
|
+
|
|
854
|
+
else :
|
|
855
|
+
|
|
856
|
+
raise ValueError(data.json().get('detail'))
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
860
|
+
|
|
861
|
+
|
|
862
|
+
async def live_contract_info_by_isin(self,symbol_isins : List[str])-> ContractInfoResponse :
|
|
863
|
+
"""
|
|
864
|
+
Fetch real-time contract information (margins and open interest) for instruments by ISIN codes.
|
|
865
|
+
|
|
866
|
+
Args:
|
|
867
|
+
symbol_isins (List[str]): List of instrument ISIN codes (for example, ["IRO1FOLD0001", "IRO1PASN0001"]).
|
|
868
|
+
|
|
869
|
+
Returns:
|
|
870
|
+
ContractInfoResponse: TypedDict with structure:
|
|
871
|
+
{
|
|
872
|
+
"Data": {
|
|
873
|
+
"<ISIN>": {
|
|
874
|
+
"open_interest": int,
|
|
875
|
+
"initial_margin": int,
|
|
876
|
+
"required_margin": int
|
|
877
|
+
},
|
|
878
|
+
...
|
|
879
|
+
},
|
|
880
|
+
"Status": Status
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
Raises:
|
|
884
|
+
ValueError: If the HTTP request fails or the API returns an error.
|
|
885
|
+
|
|
886
|
+
Example:
|
|
887
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
888
|
+
>>> ci = await client.live_contract_info_by_isin(["IRO1FOLD0001"])
|
|
889
|
+
>>> print(ci["Data"]["IRO1FOLD0001"]["required_margin"])
|
|
890
|
+
"""
|
|
891
|
+
|
|
892
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
893
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/live/data/instruments/contract-info/symbol/isin',
|
|
894
|
+
params=[('symbol_isins', isin) for isin in symbol_isins]
|
|
895
|
+
)
|
|
896
|
+
|
|
897
|
+
if data.is_success :
|
|
898
|
+
|
|
899
|
+
return data.json()
|
|
900
|
+
|
|
901
|
+
else :
|
|
902
|
+
|
|
903
|
+
raise ValueError(data.json().get('detail'))
|
|
904
|
+
|
|
905
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
906
|
+
|
|
907
|
+
async def live_fund_info_by_name(self,symbol_names : List[str])-> FundInfoResponse:
|
|
908
|
+
"""
|
|
909
|
+
Fetch real-time fund information for a list of instruments by symbol names.
|
|
910
|
+
|
|
911
|
+
Args:
|
|
912
|
+
symbol_names (List[str]): List of instrument symbol names (for example, ["صندوق_مثالی1", "صندوق_مثالی2"]).
|
|
913
|
+
|
|
914
|
+
Returns:
|
|
915
|
+
FundInfoResponse: TypedDict with structure:
|
|
916
|
+
{
|
|
917
|
+
"Data": {
|
|
918
|
+
"<symbol_name>": {
|
|
919
|
+
"nav": float,
|
|
920
|
+
"units": int,
|
|
921
|
+
"marketCap": int,
|
|
922
|
+
"as_of": datetime
|
|
923
|
+
},
|
|
924
|
+
...
|
|
925
|
+
},
|
|
926
|
+
"Status": Status
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
Raises:
|
|
930
|
+
ValueError: If the HTTP request fails or the API returns an error.
|
|
931
|
+
|
|
932
|
+
Example:
|
|
933
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
934
|
+
>>> fund_info = await client.live_fund_info_by_name(["صندوق_مثالی1"])
|
|
935
|
+
>>> print(fund_info["Data"]["صندوق_مثالی1"]["nav"])
|
|
936
|
+
"""
|
|
937
|
+
|
|
938
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
939
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/live/data/instruments/fund-info/symbol/name',
|
|
940
|
+
params=[('symbol_names', name) for name in symbol_names]
|
|
941
|
+
)
|
|
942
|
+
|
|
943
|
+
if data.is_success :
|
|
944
|
+
|
|
945
|
+
return data.json()
|
|
946
|
+
|
|
947
|
+
else :
|
|
948
|
+
|
|
949
|
+
raise ValueError(data.json().get('detail'))
|
|
950
|
+
|
|
951
|
+
|
|
952
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
async def live_fund_info_by_isin(self,symbol_isins : List[str])-> FundInfoResponse :
|
|
956
|
+
"""
|
|
957
|
+
Fetch real-time fund information for a list of instruments by ISIN codes.
|
|
958
|
+
|
|
959
|
+
Args:
|
|
960
|
+
symbol_isins (List[str]): List of instrument ISIN codes (for example, ["IRO1FUND0001", "IRO1FUND0002"]).
|
|
961
|
+
|
|
962
|
+
Returns:
|
|
963
|
+
FundInfoResponse: TypedDict with structure:
|
|
964
|
+
{
|
|
965
|
+
"Data": {
|
|
966
|
+
"<ISIN>": {
|
|
967
|
+
"nav": float,
|
|
968
|
+
"units": int,
|
|
969
|
+
"marketCap": int,
|
|
970
|
+
"as_of": datetime
|
|
971
|
+
},
|
|
972
|
+
...
|
|
973
|
+
},
|
|
974
|
+
"Status": Status
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
Raises:
|
|
978
|
+
ValueError: If the HTTP request fails or the API returns an error.
|
|
979
|
+
|
|
980
|
+
Example:
|
|
981
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
982
|
+
>>> fund_info = await client.live_fund_info_by_isin(["IRO1FUND0001"])
|
|
983
|
+
>>> print(fund_info["Data"]["IRO1FUND0001"]["nav"])
|
|
984
|
+
"""
|
|
985
|
+
|
|
986
|
+
|
|
987
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
988
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/live/data/instruments/fund-info/symbol/isin',
|
|
989
|
+
params=[('symbol_isins', isin) for isin in symbol_isins]
|
|
990
|
+
)
|
|
991
|
+
|
|
992
|
+
if data.is_success :
|
|
993
|
+
|
|
994
|
+
return data.json()
|
|
995
|
+
|
|
996
|
+
else :
|
|
997
|
+
|
|
998
|
+
raise ValueError(data.json().get('detail'))
|
|
999
|
+
|
|
1000
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
1001
|
+
|
|
1002
|
+
async def live_ohlcv_last1m_by_name(self,symbol_names : List[str])-> OHLCVLast1mResponse :
|
|
1003
|
+
|
|
1004
|
+
"""
|
|
1005
|
+
Retrieve the last 1-minute OHLCV (Open, High, Low, Close, Volume) data for a list of instruments by symbol names.
|
|
1006
|
+
|
|
1007
|
+
Args:
|
|
1008
|
+
symbol_names (List[str]): List of trading symbol names (for example, ["فملی", "خودرو"]).
|
|
1009
|
+
|
|
1010
|
+
Returns:
|
|
1011
|
+
OHLCVLast1mResponse: TypedDict with structure:
|
|
1012
|
+
{
|
|
1013
|
+
"Data": {
|
|
1014
|
+
"<symbol_name>": {
|
|
1015
|
+
"open": float,
|
|
1016
|
+
"high": float,
|
|
1017
|
+
"low": float,
|
|
1018
|
+
"close": float,
|
|
1019
|
+
"volume": int
|
|
1020
|
+
},
|
|
1021
|
+
...
|
|
1022
|
+
},
|
|
1023
|
+
"Status": Status
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
Raises:
|
|
1027
|
+
ValueError: If the HTTP request fails or the API returns an error.
|
|
1028
|
+
|
|
1029
|
+
Example:
|
|
1030
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
1031
|
+
>>> ohlcv = await client.live_ohlcv_last1m_by_name(["فملی"])
|
|
1032
|
+
>>> print(ohlcv["Data"]["فملی"]["close"])
|
|
1033
|
+
"""
|
|
1034
|
+
|
|
1035
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
1036
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/live/data/instruments/ohlcv-last-1m/symbol/name',
|
|
1037
|
+
params=[('symbol_names', name) for name in symbol_names]
|
|
1038
|
+
)
|
|
1039
|
+
|
|
1040
|
+
if data.is_success :
|
|
1041
|
+
|
|
1042
|
+
return data.json()
|
|
1043
|
+
|
|
1044
|
+
else :
|
|
1045
|
+
|
|
1046
|
+
raise ValueError(data.json().get('detail'))
|
|
1047
|
+
|
|
1048
|
+
|
|
1049
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
1050
|
+
|
|
1051
|
+
|
|
1052
|
+
async def live_ohlcv_last1m_by_isin(self,symbol_isins : List[str])-> OHLCVLast1mResponse:
|
|
1053
|
+
|
|
1054
|
+
"""
|
|
1055
|
+
Retrieve the last 1-minute OHLCV (Open, High, Low, Close, Volume) data for a list of instruments by ISIN codes.
|
|
1056
|
+
|
|
1057
|
+
Args:
|
|
1058
|
+
symbol_isins (List[str]): List of instrument ISIN codes (for example, ["IRO1FOLD0001", "IRO1PASN0001"]).
|
|
1059
|
+
|
|
1060
|
+
Returns:
|
|
1061
|
+
OHLCVLast1mResponse: TypedDict with structure:
|
|
1062
|
+
{
|
|
1063
|
+
"Data": {
|
|
1064
|
+
"<ISIN>": {
|
|
1065
|
+
"open": float,
|
|
1066
|
+
"high": float,
|
|
1067
|
+
"low": float,
|
|
1068
|
+
"close": float,
|
|
1069
|
+
"volume": int
|
|
1070
|
+
},
|
|
1071
|
+
...
|
|
1072
|
+
},
|
|
1073
|
+
"Status": Status
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
Raises:
|
|
1077
|
+
ValueError: If the HTTP request fails or the API returns an error.
|
|
1078
|
+
|
|
1079
|
+
Example:
|
|
1080
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
1081
|
+
>>> ohlcv = await client.live_ohlcv_last1m_by_isin(["IRO1FOLD0001"])
|
|
1082
|
+
>>> print(ohlcv["Data"]["IRO1FOLD0001"]["close"])
|
|
1083
|
+
"""
|
|
1084
|
+
|
|
1085
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
1086
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/live/data/instruments/ohlcv-last-1m/symbol/isin',
|
|
1087
|
+
params=[('symbol_isins', isin) for isin in symbol_isins]
|
|
1088
|
+
)
|
|
1089
|
+
|
|
1090
|
+
if data.is_success :
|
|
1091
|
+
|
|
1092
|
+
return data.json()
|
|
1093
|
+
|
|
1094
|
+
else :
|
|
1095
|
+
|
|
1096
|
+
raise ValueError(data.json().get('detail'))
|
|
1097
|
+
|
|
1098
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
1099
|
+
|
|
1100
|
+
async def historical_ohlcv_by_name(
|
|
1101
|
+
self,
|
|
1102
|
+
*,
|
|
1103
|
+
symbol_name : str,
|
|
1104
|
+
start_timestamp : int,
|
|
1105
|
+
end_timestamp : int,
|
|
1106
|
+
AdjustedPrice : bool,
|
|
1107
|
+
Resolution : Literal["1m","5m","15m","30m","1h","D","W","M",]
|
|
1108
|
+
)-> OHLCVResponse:
|
|
1109
|
+
|
|
1110
|
+
"""
|
|
1111
|
+
Fetch historical OHLCV (Open, High, Low, Close, Volume) data for a given instrument by symbol name.
|
|
1112
|
+
|
|
1113
|
+
Args:
|
|
1114
|
+
symbol_name (str): Trading symbol name (e.g., "فملی").
|
|
1115
|
+
start_timestamp (int): Unix timestamp for the start of the requested period.
|
|
1116
|
+
end_timestamp (int): Unix timestamp for the end of the requested period.
|
|
1117
|
+
AdjustedPrice (bool): Whether to return adjusted prices (True) or raw prices (False).
|
|
1118
|
+
Resolution (Literal): Data resolution. Options:
|
|
1119
|
+
- "1m", "5m", "15m", "30m", "1h" for intraday
|
|
1120
|
+
- "D" for daily
|
|
1121
|
+
- "W" for weekly
|
|
1122
|
+
- "M" for monthly
|
|
1123
|
+
|
|
1124
|
+
Returns:
|
|
1125
|
+
OHLCVResponse: TypedDict with structure:
|
|
1126
|
+
{
|
|
1127
|
+
"Data": {
|
|
1128
|
+
"Date_timestamp": List[int],
|
|
1129
|
+
"Open": List[float|int],
|
|
1130
|
+
"High": List[float|int],
|
|
1131
|
+
"Low": List[float|int],
|
|
1132
|
+
"Close": List[float|int],
|
|
1133
|
+
"Volume": List[int],
|
|
1134
|
+
"symbolName": str,
|
|
1135
|
+
"symbolIsin": str
|
|
1136
|
+
},
|
|
1137
|
+
"Status": Status
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
Raises:
|
|
1141
|
+
ValueError: If the HTTP request fails or the API returns an error.
|
|
1142
|
+
|
|
1143
|
+
Example:
|
|
1144
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
1145
|
+
>>> ohlcv = await client.historical_ohlcv_by_name(
|
|
1146
|
+
... symbol_name="فملی",
|
|
1147
|
+
... start_timestamp=1690000000,
|
|
1148
|
+
... end_timestamp=1690100000,
|
|
1149
|
+
... AdjustedPrice=True,
|
|
1150
|
+
... Resolution="1h"
|
|
1151
|
+
... )
|
|
1152
|
+
>>> print(ohlcv["Data"]["Close"])
|
|
1153
|
+
"""
|
|
1154
|
+
|
|
1155
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
1156
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/historical/data/instruments/ohlcv/symbol/name',
|
|
1157
|
+
params={
|
|
1158
|
+
'symbolName' : symbol_name,
|
|
1159
|
+
'start_timestamp' : start_timestamp,
|
|
1160
|
+
'end_timestamp' : end_timestamp,
|
|
1161
|
+
'AdjustedPrice' : AdjustedPrice,
|
|
1162
|
+
'Resolution' : Resolution,
|
|
1163
|
+
}
|
|
1164
|
+
)
|
|
1165
|
+
|
|
1166
|
+
if data.is_success :
|
|
1167
|
+
|
|
1168
|
+
return data.json()
|
|
1169
|
+
|
|
1170
|
+
else :
|
|
1171
|
+
|
|
1172
|
+
raise ValueError(data.json().get('detail'))
|
|
1173
|
+
|
|
1174
|
+
|
|
1175
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
1176
|
+
|
|
1177
|
+
|
|
1178
|
+
async def historical_ohlcv_by_isin(
|
|
1179
|
+
self,
|
|
1180
|
+
*,
|
|
1181
|
+
symbol_isin : str,
|
|
1182
|
+
start_timestamp : int,
|
|
1183
|
+
end_timestamp : int,
|
|
1184
|
+
AdjustedPrice : bool,
|
|
1185
|
+
Resolution : Literal["1m","5m","15m","30m","1h","D","W","M",]
|
|
1186
|
+
)-> OHLCVResponse:
|
|
1187
|
+
|
|
1188
|
+
"""
|
|
1189
|
+
Fetch historical OHLCV (Open, High, Low, Close, Volume) data for a given instrument by ISIN code.
|
|
1190
|
+
|
|
1191
|
+
Args:
|
|
1192
|
+
symbol_isin (str): Instrument ISIN code (e.g., "IRO1FOLD0001").
|
|
1193
|
+
start_timestamp (int): Unix timestamp for the start of the requested period.
|
|
1194
|
+
end_timestamp (int): Unix timestamp for the end of the requested period.
|
|
1195
|
+
AdjustedPrice (bool): Whether to return adjusted prices (True) or raw prices (False).
|
|
1196
|
+
Resolution (Literal): Data resolution. Options:
|
|
1197
|
+
- "1m", "5m", "15m", "30m", "1h" for intraday
|
|
1198
|
+
- "D" for daily
|
|
1199
|
+
- "W" for weekly
|
|
1200
|
+
- "M" for monthly
|
|
1201
|
+
|
|
1202
|
+
Returns:
|
|
1203
|
+
OHLCVResponse: TypedDict with structure:
|
|
1204
|
+
{
|
|
1205
|
+
"Data": {
|
|
1206
|
+
"Date_timestamp": List[int],
|
|
1207
|
+
"Open": List[float|int],
|
|
1208
|
+
"High": List[float|int],
|
|
1209
|
+
"Low": List[float|int],
|
|
1210
|
+
"Close": List[float|int],
|
|
1211
|
+
"Volume": List[int],
|
|
1212
|
+
"symbolName": str,
|
|
1213
|
+
"symbolIsin": str
|
|
1214
|
+
},
|
|
1215
|
+
"Status": Status
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
Raises:
|
|
1219
|
+
ValueError: If the HTTP request fails or the API returns an error.
|
|
1220
|
+
|
|
1221
|
+
Example:
|
|
1222
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
1223
|
+
>>> ohlcv = await client.historical_ohlcv_by_isin(
|
|
1224
|
+
... symbol_isin="IRO1FOLD0001",
|
|
1225
|
+
... start_timestamp=1690000000,
|
|
1226
|
+
... end_timestamp=1690100000,
|
|
1227
|
+
... AdjustedPrice=True,
|
|
1228
|
+
... Resolution="1h"
|
|
1229
|
+
... )
|
|
1230
|
+
>>> print(ohlcv["Data"]["Close"])
|
|
1231
|
+
"""
|
|
1232
|
+
|
|
1233
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
1234
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/historical/data/instruments/ohlcv/symbol/isin',
|
|
1235
|
+
params={
|
|
1236
|
+
'isin' : symbol_isin,
|
|
1237
|
+
'start_timestamp' : start_timestamp,
|
|
1238
|
+
'end_timestamp' : end_timestamp,
|
|
1239
|
+
'AdjustedPrice' : AdjustedPrice,
|
|
1240
|
+
'Resolution' : Resolution,
|
|
1241
|
+
}
|
|
1242
|
+
)
|
|
1243
|
+
|
|
1244
|
+
if data.is_success :
|
|
1245
|
+
|
|
1246
|
+
return data.json()
|
|
1247
|
+
|
|
1248
|
+
else :
|
|
1249
|
+
|
|
1250
|
+
raise ValueError(data.json().get('detail'))
|
|
1251
|
+
|
|
1252
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
1253
|
+
|
|
1254
|
+
async def historical_corporateactions_by_name(
|
|
1255
|
+
self,
|
|
1256
|
+
*,
|
|
1257
|
+
symbol_name : str,
|
|
1258
|
+
start_timestamp : int,
|
|
1259
|
+
end_timestamp : int,
|
|
1260
|
+
)-> CorporateActionResponse :
|
|
1261
|
+
|
|
1262
|
+
"""
|
|
1263
|
+
Fetch historical corporate actions (dividends and capital increases) for a given instrument by symbol name.
|
|
1264
|
+
|
|
1265
|
+
Args:
|
|
1266
|
+
symbol_name (str): Trading symbol name (e.g., "فملی").
|
|
1267
|
+
start_timestamp (int): Unix timestamp marking the start of the requested period.
|
|
1268
|
+
end_timestamp (int): Unix timestamp marking the end of the requested period.
|
|
1269
|
+
|
|
1270
|
+
Returns:
|
|
1271
|
+
CorporateActionResponse: TypedDict with structure:
|
|
1272
|
+
{
|
|
1273
|
+
"Data": List[Union[DividendAction, CapitalIncreaseAction, None]],
|
|
1274
|
+
"Status": Status
|
|
1275
|
+
}
|
|
1276
|
+
Each item in Data includes fields such as:
|
|
1277
|
+
- Date_timestamp: int
|
|
1278
|
+
- corporateAction: str
|
|
1279
|
+
- symbolName: str
|
|
1280
|
+
- symbolIsin: str
|
|
1281
|
+
- سود_تقسیم_شده (optional for DividendAction)
|
|
1282
|
+
- سرمایه_قبلی, سرمایه_جدید, درصد_افزایش (optional for CapitalIncreaseAction)
|
|
1283
|
+
- تاریخ: str
|
|
1284
|
+
|
|
1285
|
+
Raises:
|
|
1286
|
+
ValueError: If the HTTP request fails or the API returns an error.
|
|
1287
|
+
|
|
1288
|
+
Example:
|
|
1289
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
1290
|
+
>>> actions = await client.historical_corporateactions_by_name(
|
|
1291
|
+
... symbol_name="فملی",
|
|
1292
|
+
... start_timestamp=1690000000,
|
|
1293
|
+
... end_timestamp=1690100000
|
|
1294
|
+
... )
|
|
1295
|
+
>>> print(actions["Data"][0]["corporateAction"])
|
|
1296
|
+
"""
|
|
1297
|
+
|
|
1298
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
1299
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/historical/data/instruments/corporateactions/symbol/name',
|
|
1300
|
+
params={
|
|
1301
|
+
'symbolName' : symbol_name,
|
|
1302
|
+
'start_timestamp' : start_timestamp,
|
|
1303
|
+
'end_timestamp' : end_timestamp,
|
|
1304
|
+
}
|
|
1305
|
+
)
|
|
1306
|
+
|
|
1307
|
+
if data.is_success :
|
|
1308
|
+
|
|
1309
|
+
return data.json()
|
|
1310
|
+
|
|
1311
|
+
else :
|
|
1312
|
+
|
|
1313
|
+
raise ValueError(data.json().get('detail'))
|
|
1314
|
+
|
|
1315
|
+
|
|
1316
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
async def historical_corporateactions_by_isin(
|
|
1320
|
+
self,
|
|
1321
|
+
*,
|
|
1322
|
+
symbol_isin : str,
|
|
1323
|
+
start_timestamp : int,
|
|
1324
|
+
end_timestamp : int,
|
|
1325
|
+
)-> CorporateActionResponse:
|
|
1326
|
+
|
|
1327
|
+
"""
|
|
1328
|
+
Fetch historical corporate actions (dividends and capital increases) for a given instrument by ISIN code.
|
|
1329
|
+
|
|
1330
|
+
Args:
|
|
1331
|
+
symbol_isin (str): Instrument ISIN code (e.g., "IRO1FOLD0001").
|
|
1332
|
+
start_timestamp (int): Unix timestamp marking the start of the requested period.
|
|
1333
|
+
end_timestamp (int): Unix timestamp marking the end of the requested period.
|
|
1334
|
+
|
|
1335
|
+
Returns:
|
|
1336
|
+
CorporateActionResponse: TypedDict with structure:
|
|
1337
|
+
{
|
|
1338
|
+
"Data": List[Union[DividendAction, CapitalIncreaseAction, None]],
|
|
1339
|
+
"Status": Status
|
|
1340
|
+
}
|
|
1341
|
+
Each item in Data includes fields such as:
|
|
1342
|
+
- Date_timestamp: int
|
|
1343
|
+
- corporateAction: str
|
|
1344
|
+
- symbolName: str
|
|
1345
|
+
- symbolIsin: str
|
|
1346
|
+
- سود_تقسیم_شده (optional for DividendAction)
|
|
1347
|
+
- سرمایه_قبلی, سرمایه_جدید, درصد_افزایش (optional for CapitalIncreaseAction)
|
|
1348
|
+
- تاریخ: str
|
|
1349
|
+
|
|
1350
|
+
Raises:
|
|
1351
|
+
ValueError: If the HTTP request fails or the API returns an error.
|
|
1352
|
+
|
|
1353
|
+
Example:
|
|
1354
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
1355
|
+
>>> actions = await client.historical_corporateactions_by_isin(
|
|
1356
|
+
... symbol_isin="IRO1FOLD0001",
|
|
1357
|
+
... start_timestamp=1690000000,
|
|
1358
|
+
... end_timestamp=1690100000
|
|
1359
|
+
... )
|
|
1360
|
+
>>> print(actions["Data"][0]["corporateAction"])
|
|
1361
|
+
"""
|
|
1362
|
+
|
|
1363
|
+
data = await self.__AuthAsyncClient.httpx_Client.get(
|
|
1364
|
+
url='https://core.hedgetech.ir/data-engine/tse-ifb/historical/data/instruments/corporateactions/symbol/isin',
|
|
1365
|
+
params={
|
|
1366
|
+
'isin' : symbol_isin,
|
|
1367
|
+
'start_timestamp' : start_timestamp,
|
|
1368
|
+
'end_timestamp' : end_timestamp,
|
|
1369
|
+
}
|
|
1370
|
+
)
|
|
1371
|
+
|
|
1372
|
+
if data.is_success :
|
|
1373
|
+
|
|
1374
|
+
return data.json()
|
|
1375
|
+
|
|
1376
|
+
else :
|
|
1377
|
+
|
|
1378
|
+
raise ValueError(data.json().get('detail'))
|
|
1379
|
+
|
|
1380
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
1381
|
+
|
|
1382
|
+
async def websocket_by_name(
|
|
1383
|
+
self,
|
|
1384
|
+
channels: List[
|
|
1385
|
+
Literal[
|
|
1386
|
+
'best-limit',
|
|
1387
|
+
'order-book',
|
|
1388
|
+
'ohlcv-last-1m',
|
|
1389
|
+
'aggregate',
|
|
1390
|
+
'institutional-vs-individual',
|
|
1391
|
+
'contract-info',
|
|
1392
|
+
'fund-info',
|
|
1393
|
+
]
|
|
1394
|
+
],
|
|
1395
|
+
symbol_names: List[str],
|
|
1396
|
+
event: Event | None = None,
|
|
1397
|
+
)-> AsyncGenerator[
|
|
1398
|
+
Union[
|
|
1399
|
+
BestLimit_WS_symbolName,
|
|
1400
|
+
OrderBook_WS_symbolName,
|
|
1401
|
+
Aggregate_WS_symbolName,
|
|
1402
|
+
institutional_vs_individual_WS_symbolName,
|
|
1403
|
+
ContractInfo_WS_symbolName,
|
|
1404
|
+
FundInfo_WS_symbolName,
|
|
1405
|
+
OHLCV_WS_symbolName,
|
|
1406
|
+
],
|
|
1407
|
+
None
|
|
1408
|
+
]:
|
|
1409
|
+
|
|
1410
|
+
"""
|
|
1411
|
+
Subscribe to **real-time WebSocket updates** for a list of instruments by symbol name.
|
|
1412
|
+
|
|
1413
|
+
This function allows you to receive continuous updates for multiple market channels such as
|
|
1414
|
+
best-limit, order book, last 1-minute OHLCV, aggregate data, institutional vs individual trades,
|
|
1415
|
+
contract information, and fund information.
|
|
1416
|
+
|
|
1417
|
+
Args:
|
|
1418
|
+
channels (List[str]):
|
|
1419
|
+
List of channels to subscribe to. Possible values:
|
|
1420
|
+
- 'best-limit'
|
|
1421
|
+
- 'order-book'
|
|
1422
|
+
- 'ohlcv-last-1m'
|
|
1423
|
+
- 'aggregate'
|
|
1424
|
+
- 'institutional-vs-individual'
|
|
1425
|
+
- 'contract-info'
|
|
1426
|
+
- 'fund-info'
|
|
1427
|
+
symbol_names (List[str]):
|
|
1428
|
+
List of trading symbol names to receive updates for (e.g., ["فملی", "خودرو"]).
|
|
1429
|
+
event (Event | None, optional):
|
|
1430
|
+
Optional asyncio.Event to control the WebSocket loop.
|
|
1431
|
+
If provided, the loop will continue while `event.is_set()` is True.
|
|
1432
|
+
Defaults to a new set Event.
|
|
1433
|
+
|
|
1434
|
+
Returns:
|
|
1435
|
+
AsyncGenerator:
|
|
1436
|
+
Yields TypedDict objects depending on the channel subscribed:
|
|
1437
|
+
- **BestLimit_WS_symbolName** for 'best-limit'
|
|
1438
|
+
- **OrderBook_WS_symbolName** for 'order-book'
|
|
1439
|
+
- **OHLCV_WS_symbolName** for 'ohlcv-last-1m'
|
|
1440
|
+
- **Aggregate_WS_symbolName** for 'aggregate'
|
|
1441
|
+
- **institutional_vs_individual_WS_symbolName** for 'institutional-vs-individual'
|
|
1442
|
+
- **ContractInfo_WS_symbolName** for 'contract-info'
|
|
1443
|
+
- **FundInfo_WS_symbolName** for 'fund-info'
|
|
1444
|
+
|
|
1445
|
+
Each yielded object contains:
|
|
1446
|
+
- `channel`: str — name of the channel
|
|
1447
|
+
- `symbolName`: str — instrument symbol
|
|
1448
|
+
- `timestamp`: str — server timestamp
|
|
1449
|
+
- `data`: Dict[...] — channel-specific real-time data.
|
|
1450
|
+
|
|
1451
|
+
Raises:
|
|
1452
|
+
WebSocketException or ValueError:
|
|
1453
|
+
If the WebSocket connection fails or an exception occurs while receiving data.
|
|
1454
|
+
|
|
1455
|
+
Example:
|
|
1456
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
1457
|
+
>>> async for update in client.websocket_by_name(
|
|
1458
|
+
... channels=["best-limit", "order-book"],
|
|
1459
|
+
... symbol_names=["فملی"]
|
|
1460
|
+
... ):
|
|
1461
|
+
... print(update["data"])
|
|
1462
|
+
"""
|
|
1463
|
+
|
|
1464
|
+
if event is None :
|
|
1465
|
+
event = Event()
|
|
1466
|
+
event.set()
|
|
1467
|
+
|
|
1468
|
+
async with connect(
|
|
1469
|
+
uri=(
|
|
1470
|
+
f"wss://core.hedgetech.ir/data-engine/tse-ifb/live/data/websocket/symbol/name?"
|
|
1471
|
+
+ "&".join(f"channels={c}" for c in channels)
|
|
1472
|
+
+ "&" + "&".join(f"symbol_names={s}" for s in symbol_names)
|
|
1473
|
+
),
|
|
1474
|
+
additional_headers=self.__AuthAsyncClient.token
|
|
1475
|
+
) as ws:
|
|
1476
|
+
|
|
1477
|
+
while event.is_set():
|
|
1478
|
+
|
|
1479
|
+
try:
|
|
1480
|
+
yield loads(await ws.recv())
|
|
1481
|
+
except :
|
|
1482
|
+
await ws.close()
|
|
1483
|
+
break
|
|
1484
|
+
|
|
1485
|
+
# +--------------------------------------------------------------------------------------+ #
|
|
1486
|
+
|
|
1487
|
+
async def websocket_by_isin(
|
|
1488
|
+
self,
|
|
1489
|
+
channels: List[
|
|
1490
|
+
Literal[
|
|
1491
|
+
'best-limit',
|
|
1492
|
+
'order-book',
|
|
1493
|
+
'ohlcv-last-1m',
|
|
1494
|
+
'aggregate',
|
|
1495
|
+
'institutional-vs-individual',
|
|
1496
|
+
'contract-info',
|
|
1497
|
+
'fund-info',
|
|
1498
|
+
]
|
|
1499
|
+
],
|
|
1500
|
+
symbol_isins: List[str],
|
|
1501
|
+
event: Event | None = None,
|
|
1502
|
+
)-> AsyncGenerator[
|
|
1503
|
+
Union[
|
|
1504
|
+
BestLimit_WS_symbolIsin,
|
|
1505
|
+
OrderBook_WS_symbolIsin,
|
|
1506
|
+
Aggregate_WS_symbolIsin,
|
|
1507
|
+
institutional_vs_individual_WS_symbolIsin,
|
|
1508
|
+
ContractInfo_WS_symbolIsin,
|
|
1509
|
+
FundInfo_WS_symbolIsin,
|
|
1510
|
+
OHLCV_WS_symbolIsin,
|
|
1511
|
+
],
|
|
1512
|
+
None
|
|
1513
|
+
]:
|
|
1514
|
+
|
|
1515
|
+
"""
|
|
1516
|
+
Subscribe to **real-time WebSocket updates** for a list of instruments using their ISIN codes.
|
|
1517
|
+
|
|
1518
|
+
This function streams live updates for multiple market channels such as best-limit, order book,
|
|
1519
|
+
last 1-minute OHLCV, aggregate data, institutional vs individual trades, contract information,
|
|
1520
|
+
and fund information.
|
|
1521
|
+
|
|
1522
|
+
Args:
|
|
1523
|
+
channels (List[str]):
|
|
1524
|
+
List of channels to subscribe to. Possible values:
|
|
1525
|
+
- 'best-limit'
|
|
1526
|
+
- 'order-book'
|
|
1527
|
+
- 'ohlcv-last-1m'
|
|
1528
|
+
- 'aggregate'
|
|
1529
|
+
- 'institutional-vs-individual'
|
|
1530
|
+
- 'contract-info'
|
|
1531
|
+
- 'fund-info'
|
|
1532
|
+
symbol_isins (List[str]):
|
|
1533
|
+
List of instrument ISIN codes to receive updates for (e.g., ["IR1234567890", "IR0987654321"]).
|
|
1534
|
+
event (Event | None, optional):
|
|
1535
|
+
Optional asyncio.Event to control the WebSocket loop.
|
|
1536
|
+
If provided, the loop continues while `event.is_set()` is True.
|
|
1537
|
+
Defaults to a new set Event.
|
|
1538
|
+
|
|
1539
|
+
Returns:
|
|
1540
|
+
AsyncGenerator:
|
|
1541
|
+
Yields TypedDict objects depending on the channel subscribed:
|
|
1542
|
+
- **BestLimit_WS_symbolIsin** for 'best-limit'
|
|
1543
|
+
- **OrderBook_WS_symbolIsin** for 'order-book'
|
|
1544
|
+
- **OHLCV_WS_symbolIsin** for 'ohlcv-last-1m'
|
|
1545
|
+
- **Aggregate_WS_symbolIsin** for 'aggregate'
|
|
1546
|
+
- **institutional_vs_individual_WS_symbolIsin** for 'institutional-vs-individual'
|
|
1547
|
+
- **ContractInfo_WS_symbolIsin** for 'contract-info'
|
|
1548
|
+
- **FundInfo_WS_symbolIsin** for 'fund-info'
|
|
1549
|
+
|
|
1550
|
+
Each yielded object contains:
|
|
1551
|
+
- `channel`: str — channel name
|
|
1552
|
+
- `symbolIsin`: str — instrument ISIN
|
|
1553
|
+
- `timestamp`: str — server timestamp
|
|
1554
|
+
- `data`: Dict[...] — channel-specific real-time data.
|
|
1555
|
+
|
|
1556
|
+
Raises:
|
|
1557
|
+
WebSocketException or ValueError:
|
|
1558
|
+
If the WebSocket connection fails or an exception occurs during data reception.
|
|
1559
|
+
|
|
1560
|
+
Example:
|
|
1561
|
+
>>> client = DataEngine_TseIfb_AsyncClient(auth_client)
|
|
1562
|
+
>>> async for update in client.websocket_by_isin(
|
|
1563
|
+
... channels=["best-limit", "order-book"],
|
|
1564
|
+
... symbol_isins=["IR1234567890"]
|
|
1565
|
+
... ):
|
|
1566
|
+
... print(update["data"])
|
|
1567
|
+
"""
|
|
1568
|
+
|
|
1569
|
+
if event is None :
|
|
1570
|
+
event = Event()
|
|
1571
|
+
event.set()
|
|
1572
|
+
|
|
1573
|
+
async with connect(
|
|
1574
|
+
uri=(
|
|
1575
|
+
f"wss://core.hedgetech.ir/data-engine/tse-ifb/live/data/websocket/symbol/isin?"
|
|
1576
|
+
+ "&".join(f"channels={c}" for c in channels)
|
|
1577
|
+
+ "&" + "&".join(f"symbol_isins={s}" for s in symbol_isins)
|
|
1578
|
+
),
|
|
1579
|
+
additional_headers=self.__AuthAsyncClient.token
|
|
1580
|
+
) as ws:
|
|
1581
|
+
|
|
1582
|
+
while event.is_set():
|
|
1583
|
+
|
|
1584
|
+
try:
|
|
1585
|
+
yield loads(await ws.recv())
|
|
1586
|
+
except :
|
|
1587
|
+
await ws.close()
|
|
1588
|
+
break
|