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.
@@ -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