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