tradx 0.8.2__py3-none-any.whl → 0.9__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.
- tradx/algoContainer.py +82 -2
- tradx/baseClass/baseAlgo.py +24 -9
- tradx/baseClass/{order.py → interactive/order.py} +6 -0
- tradx/baseClass/{orderEvent.py → interactive/orderEvent.py} +3 -1
- tradx/baseClass/{position.py → interactive/position.py} +8 -1
- tradx/interactiveEngine.py +197 -58
- tradx/marketDataEngine.py +254 -76
- {tradx-0.8.2.dist-info → tradx-0.9.dist-info}/METADATA +1 -1
- tradx-0.9.dist-info/RECORD +33 -0
- tradx-0.8.2.dist-info/RECORD +0 -33
- /tradx/baseClass/{positionEvent.py → interactive/positionEvent.py} +0 -0
- /tradx/baseClass/{tradeConversionEvent.py → interactive/tradeConversionEvent.py} +0 -0
- /tradx/baseClass/{tradeEvent.py → interactive/tradeEvent.py} +0 -0
- /tradx/baseClass/{candleData.py → market/candleData.py} +0 -0
- /tradx/baseClass/{cmInstrument.py → market/cmInstrument.py} +0 -0
- /tradx/baseClass/{futureInstrument.py → market/futureInstrument.py} +0 -0
- /tradx/baseClass/{index.py → market/index.py} +0 -0
- /tradx/baseClass/{instrumentPropertyChangeData.py → market/instrumentPropertyChangeData.py} +0 -0
- /tradx/baseClass/{ltpData.py → market/ltpData.py} +0 -0
- /tradx/baseClass/{ltpPartialData.py → market/ltpPartialData.py} +0 -0
- /tradx/baseClass/{marketDepthData.py → market/marketDepthData.py} +0 -0
- /tradx/baseClass/{marketStatusData.py → market/marketStatusData.py} +0 -0
- /tradx/baseClass/{openInterestData.py → market/openInterestData.py} +0 -0
- /tradx/baseClass/{openInterestPartialData.py → market/openInterestPartialData.py} +0 -0
- /tradx/baseClass/{optionsInstrument.py → market/optionsInstrument.py} +0 -0
- /tradx/baseClass/{touchLineData.py → market/touchLineData.py} +0 -0
- /tradx/baseClass/{touchLinePartialData.py → market/touchLinePartialData.py} +0 -0
- {tradx-0.8.2.dist-info → tradx-0.9.dist-info}/WHEEL +0 -0
tradx/marketDataEngine.py
CHANGED
@@ -1,26 +1,30 @@
|
|
1
|
+
# Importing from xts_api_client
|
1
2
|
from xts_api_client.market_data_socket_client import MarketDataSocketClient
|
2
3
|
from xts_api_client.market_data_socket import MDSocket_io
|
3
4
|
from xts_api_client.xts_connect_async import XTSConnect
|
4
5
|
import xts_api_client.helper.helper as helper
|
5
|
-
|
6
|
+
|
7
|
+
# Importing from self module
|
6
8
|
from tradx.logger.logger import *
|
7
9
|
from tradx.baseClass.baseAlgo import BaseAlgo
|
8
|
-
from tradx.baseClass.candleData import CandleData
|
9
|
-
from tradx.baseClass.marketDepthData import MarketDepthData
|
10
|
-
from tradx.baseClass.marketStatusData import MarketStatusData
|
11
|
-
from tradx.baseClass.openInterestData import OpenInterestData
|
12
|
-
from tradx.baseClass.ltpData import LtpData
|
13
|
-
from tradx.baseClass.touchLineData import TouchLineData
|
14
|
-
from tradx.baseClass.index import Index
|
15
|
-
from tradx.baseClass.optionsInstrument import OptionManager, OptionsInstrument
|
16
|
-
from tradx.baseClass.tradeEvent import TradeEvent
|
10
|
+
from tradx.baseClass.market.candleData import CandleData
|
11
|
+
from tradx.baseClass.market.marketDepthData import MarketDepthData
|
12
|
+
from tradx.baseClass.market.marketStatusData import MarketStatusData
|
13
|
+
from tradx.baseClass.market.openInterestData import OpenInterestData
|
14
|
+
from tradx.baseClass.market.ltpData import LtpData
|
15
|
+
from tradx.baseClass.market.touchLineData import TouchLineData
|
16
|
+
from tradx.baseClass.market.index import Index
|
17
|
+
from tradx.baseClass.market.optionsInstrument import OptionManager, OptionsInstrument
|
18
|
+
from tradx.baseClass.interactive.tradeEvent import TradeEvent
|
17
19
|
from tradx.dualHashMap import DualHashMap
|
18
|
-
from tradx.algoContainer import
|
20
|
+
from tradx.algoContainer import SubcribeContainer
|
21
|
+
|
22
|
+
# Importing other python modules.
|
19
23
|
from datetime import datetime
|
20
24
|
import json
|
21
25
|
import pandas
|
22
26
|
import asyncio
|
23
|
-
|
27
|
+
from typing import Any, List, Dict
|
24
28
|
import pandas as pd
|
25
29
|
import math
|
26
30
|
from decimal import Decimal
|
@@ -149,6 +153,7 @@ class marketDataEngine(MarketDataSocketClient):
|
|
149
153
|
assert source, "Source is required"
|
150
154
|
assert root, "Root is required"
|
151
155
|
self.isConnected: bool = False
|
156
|
+
self.isLive: bool = False
|
152
157
|
self._api_key: str = api_key
|
153
158
|
self._api_password: str = api_password
|
154
159
|
self._source: str = source
|
@@ -156,12 +161,14 @@ class marketDataEngine(MarketDataSocketClient):
|
|
156
161
|
self.exchange_to_exchangeSegments: dict = None
|
157
162
|
self.index_list: List[Index] = []
|
158
163
|
self.F_MASTER_DF: pandas.DataFrame = None
|
159
|
-
self.
|
164
|
+
self.option_manager: OptionManager = None
|
160
165
|
self.CM_MASTER_DF: pandas.DataFrame = None
|
161
|
-
self.subscribe_manager =
|
166
|
+
self.subscribe_manager = SubcribeContainer()
|
162
167
|
self.set_marketDataToken: str = None
|
163
168
|
self.set_userID: str = None
|
169
|
+
self.set_isInvestorClient: str = None
|
164
170
|
self.user_logger = user_logger
|
171
|
+
|
165
172
|
if self.user_logger:
|
166
173
|
self.user_logger.info(
|
167
174
|
"Market Data Engine Object initialized.",
|
@@ -183,6 +190,38 @@ class marketDataEngine(MarketDataSocketClient):
|
|
183
190
|
await self.login()
|
184
191
|
await self.socket.connect()
|
185
192
|
|
193
|
+
async def initializeClient(self, response) -> None:
|
194
|
+
"""
|
195
|
+
Initializes the trading client connection using an explicit login response.
|
196
|
+
|
197
|
+
This method sets up the XTSConnect object and configures it with the provided
|
198
|
+
login response, including the authentication token, user ID, and investor client status.
|
199
|
+
It is intended for cases where the login response has already been obtained externally.
|
200
|
+
|
201
|
+
Args:
|
202
|
+
response (dict): The login response containing keys:
|
203
|
+
- "token": Authentication token for the client.
|
204
|
+
- "userID": User identifier.
|
205
|
+
- "isInvestorClient": Boolean flag indicating investor client status.
|
206
|
+
|
207
|
+
Returns:
|
208
|
+
None
|
209
|
+
|
210
|
+
Side Effects:
|
211
|
+
- Sets `self.xt` as the XTSConnect instance.
|
212
|
+
- Updates `self.isConnected` to True.
|
213
|
+
- Configures common variables in the XTSConnect instance.
|
214
|
+
- Prints a confirmation message of successful initialization.
|
215
|
+
"""
|
216
|
+
self.xt = XTSConnect(
|
217
|
+
self._api_key, self._api_password, self._source, self._root
|
218
|
+
)
|
219
|
+
self.isConnected = True
|
220
|
+
self.xt._set_common_variables(
|
221
|
+
response["token"], response["userID"], response["isInvestorClient"]
|
222
|
+
)
|
223
|
+
print("Initialized trade client.")
|
224
|
+
|
186
225
|
async def on_event_candle_data_full(self, message: str) -> None:
|
187
226
|
"""
|
188
227
|
Handles the full candle data event.
|
@@ -262,7 +301,22 @@ class marketDataEngine(MarketDataSocketClient):
|
|
262
301
|
"Market Data Socket connected successfully!",
|
263
302
|
caller="marketDataEngine.on_connect",
|
264
303
|
)
|
304
|
+
|
265
305
|
async def reconnect(self):
|
306
|
+
"""
|
307
|
+
Asynchronously reconnects the market data socket using previously obtained credentials.
|
308
|
+
|
309
|
+
This method performs the following steps:
|
310
|
+
1. Initializes the MDSocket_io object with the stored market data token, user ID, and root path.
|
311
|
+
2. Logs a successful reconnection if a user logger is available.
|
312
|
+
3. Establishes the socket connection asynchronously.
|
313
|
+
|
314
|
+
Raises:
|
315
|
+
Exception: If any error occurs during socket initialization or connection, it is logged and re-raised.
|
316
|
+
|
317
|
+
Returns:
|
318
|
+
None
|
319
|
+
"""
|
266
320
|
try:
|
267
321
|
# Initialize and connect OrderSocket_io object
|
268
322
|
self.socket = MDSocket_io(
|
@@ -275,10 +329,11 @@ class marketDataEngine(MarketDataSocketClient):
|
|
275
329
|
)
|
276
330
|
|
277
331
|
await self.socket.connect()
|
278
|
-
|
332
|
+
|
279
333
|
except Exception as e:
|
280
334
|
if self.user_logger:
|
281
335
|
self.user_logger.error(e, caller="marketDataEngine.reconnect")
|
336
|
+
|
282
337
|
async def on_disconnect(self) -> None:
|
283
338
|
"""
|
284
339
|
Handles the event when the market data socket gets disconnected.
|
@@ -296,30 +351,27 @@ class marketDataEngine(MarketDataSocketClient):
|
|
296
351
|
)
|
297
352
|
current_time = datetime.now().time()
|
298
353
|
cnt: int = 0
|
299
|
-
if current_time < datetime.strptime("15:
|
300
|
-
while not self.isConnected and
|
301
|
-
print(
|
354
|
+
if current_time < datetime.strptime("15:30", "%H:%M").time():
|
355
|
+
while not self.isConnected and self.isLive:
|
356
|
+
print(
|
357
|
+
"Attempting to reconnect as the time is before 3:30 PM and isConnected is False for market data socket."
|
358
|
+
)
|
302
359
|
if self.user_logger:
|
303
360
|
self.user_logger.info(
|
304
|
-
"Attempting to reconnect as the time is before 3:
|
361
|
+
"Attempting to reconnect as the time is before 3:30 PM and isConnected is False.",
|
305
362
|
caller="marketDataEngine.on_disconnect",
|
306
363
|
)
|
307
364
|
await self.reconnect()
|
308
365
|
await asyncio.sleep(3)
|
309
366
|
cnt += 1
|
310
367
|
if not self.isConnected and self.user_logger:
|
311
|
-
print(
|
368
|
+
print(
|
369
|
+
f"Reconnection attempt {cnt} failed for market data socket. Retrying..."
|
370
|
+
)
|
312
371
|
self.user_logger.warning(
|
313
372
|
f"Reconnection attempt {cnt} failed. Retrying...",
|
314
373
|
caller="marketDataEngine.on_disconnect",
|
315
374
|
)
|
316
|
-
if cnt >= 3:
|
317
|
-
print("Reconnection attempts failed for market data socket. Please check the network connection.",)
|
318
|
-
if self.user_logger:
|
319
|
-
self.user_logger.error(
|
320
|
-
f"Reconnection attempts failed. Please check the network connection.",
|
321
|
-
caller="marketDataEngine.on_disconnect",
|
322
|
-
)
|
323
375
|
|
324
376
|
async def on_message(self, xts_message: Any) -> None:
|
325
377
|
"""
|
@@ -406,9 +458,10 @@ class marketDataEngine(MarketDataSocketClient):
|
|
406
458
|
|
407
459
|
# Perform interactive login
|
408
460
|
response = await self.xt.marketdata_login()
|
461
|
+
|
409
462
|
self.set_marketDataToken = response["result"]["token"]
|
410
463
|
self.set_userID = response["result"]["userID"]
|
411
|
-
|
464
|
+
self.set_isInvestorClient = False
|
412
465
|
# Initialize and connect OrderSocket_io object
|
413
466
|
self.socket = MDSocket_io(
|
414
467
|
self.set_marketDataToken, self.set_userID, self._root, self
|
@@ -459,7 +512,7 @@ class marketDataEngine(MarketDataSocketClient):
|
|
459
512
|
raise (e)
|
460
513
|
|
461
514
|
async def subscribe(
|
462
|
-
self, Instruments: List[Dict], xtsMessageCode: int,
|
515
|
+
self, Instruments: List[Dict], xtsMessageCode: int, uuid: str
|
463
516
|
) -> None:
|
464
517
|
"""
|
465
518
|
Subscribes to market data for the given instruments.
|
@@ -477,8 +530,8 @@ class marketDataEngine(MarketDataSocketClient):
|
|
477
530
|
assert isinstance(Instruments, list), "Instruments must be a list"
|
478
531
|
assert isinstance(xtsMessageCode, int), "xtsMessageCode must be an integer"
|
479
532
|
assert isinstance(
|
480
|
-
|
481
|
-
), "
|
533
|
+
uuid, str
|
534
|
+
), "uuid should be a string representing the strategy UUID"
|
482
535
|
for instrument in Instruments:
|
483
536
|
assert isinstance(instrument, dict), "Each instrument must be a dictionary"
|
484
537
|
assert (
|
@@ -497,34 +550,42 @@ class marketDataEngine(MarketDataSocketClient):
|
|
497
550
|
], "Invalid message code"
|
498
551
|
|
499
552
|
try:
|
553
|
+
listToSubscribe: List = []
|
554
|
+
for item in range(len(Instruments)):
|
555
|
+
if not self.subscribe_manager.ifExists(
|
556
|
+
Instruments[item]["exchangeInstrumentID"], xtsMessageCode
|
557
|
+
):
|
558
|
+
listToSubscribe.append(item)
|
559
|
+
if listToSubscribe:
|
560
|
+
response = await self.xt.send_subscription(
|
561
|
+
Instruments=Instruments, xtsMessageCode=xtsMessageCode
|
562
|
+
)
|
563
|
+
|
564
|
+
if (
|
565
|
+
response["type"] == "error"
|
566
|
+
and response["description"] == "Instrument Already Subscribed !"
|
567
|
+
):
|
568
|
+
if self.user_logger:
|
569
|
+
self.user_logger.error(
|
570
|
+
f"Error in Subscribing Quantities: {Instruments} on request from {uuid} as {response}",
|
571
|
+
caller="marketDataEngine.subscribe",
|
572
|
+
)
|
573
|
+
# Avoid raising this error
|
574
|
+
if response["type"] != "success":
|
575
|
+
if self.user_logger:
|
576
|
+
self.user_logger.error(
|
577
|
+
f"Error in Subscribing Quantities: {Instruments} on request from {uuid} as {response}",
|
578
|
+
caller="marketDataEngine.subscribe",
|
579
|
+
)
|
580
|
+
raise (response)
|
500
581
|
for item in range(len(Instruments)):
|
501
582
|
self.subscribe_manager.subscribe(
|
502
|
-
Instruments[item]["exchangeInstrumentID"],
|
583
|
+
Instruments[item]["exchangeInstrumentID"], xtsMessageCode, uuid
|
503
584
|
)
|
504
585
|
|
505
|
-
response = await self.xt.send_subscription(
|
506
|
-
Instruments=Instruments, xtsMessageCode=xtsMessageCode
|
507
|
-
)
|
508
|
-
if (
|
509
|
-
response["type"] == "error"
|
510
|
-
and response["description"] == "Instrument Already Subscribed !"
|
511
|
-
):
|
512
|
-
if self.user_logger:
|
513
|
-
self.user_logger.error(
|
514
|
-
f"Error in Subscribing Quantities: {Instruments} on request from {algo.name} as {response}",
|
515
|
-
caller="marketDataEngine.subscribe",
|
516
|
-
)
|
517
|
-
# Avoid raising this error
|
518
|
-
if response["type"] != "success":
|
519
|
-
if self.user_logger:
|
520
|
-
self.user_logger.error(
|
521
|
-
f"Error in Subscribing Quantities: {Instruments} on request from {algo.name} as {response}",
|
522
|
-
caller="marketDataEngine.subscribe",
|
523
|
-
)
|
524
|
-
raise (response)
|
525
586
|
if self.user_logger:
|
526
587
|
self.user_logger.info(
|
527
|
-
f"Subscribed Quantities: {Instruments} on request from {
|
588
|
+
f"Subscribed Quantities: {Instruments} on request from {uuid}",
|
528
589
|
caller="marketDataEngine.subscribe",
|
529
590
|
)
|
530
591
|
except Exception as e:
|
@@ -552,7 +613,7 @@ class marketDataEngine(MarketDataSocketClient):
|
|
552
613
|
"UnderlyingIndexName"
|
553
614
|
].str.upper()
|
554
615
|
O_MASTER_DF.to_csv(f"MASTER_O.csv", index=False)
|
555
|
-
self.
|
616
|
+
self.option_manager = OptionManager(O_MASTER_DF)
|
556
617
|
self.F_MASTER_DF.to_csv(f"MASTER_F.csv", index=False)
|
557
618
|
|
558
619
|
if self.user_logger:
|
@@ -583,6 +644,68 @@ class marketDataEngine(MarketDataSocketClient):
|
|
583
644
|
self.user_logger.error(e, caller="marketDataEngine.loadMaster")
|
584
645
|
raise (e)
|
585
646
|
|
647
|
+
async def loadMasterServer(self) -> None:
|
648
|
+
"""
|
649
|
+
Asynchronously fetches and saves master contract data for different market segments.
|
650
|
+
|
651
|
+
This method retrieves the latest Futures & Options (FO) and Cash Market (CM) master files
|
652
|
+
from the server for the relevant exchange segments. The fetched data is saved as plain text
|
653
|
+
files on disk for local reference.
|
654
|
+
|
655
|
+
Steps performed:
|
656
|
+
1. Fetches FO master data for NSE FO and BSE FO segments.
|
657
|
+
2. Fetches CM master data for NSE CM segment.
|
658
|
+
3. Writes the FO master data to "FandO_master.txt".
|
659
|
+
4. Writes the CM master data to "CM_master.txt".
|
660
|
+
5. Logs the completion of each step if a user logger is available.
|
661
|
+
|
662
|
+
Raises:
|
663
|
+
Exception: If there is an error while fetching the master files or writing them to disk.
|
664
|
+
|
665
|
+
Returns:
|
666
|
+
None
|
667
|
+
"""
|
668
|
+
try:
|
669
|
+
# Fetch FO Master
|
670
|
+
exchangesegments = [self.xt.EXCHANGE_NSEFO, self.xt.EXCHANGE_BSEFO]
|
671
|
+
response = await self.xt.get_master(exchangeSegmentList=exchangesegments)
|
672
|
+
FandO_response = response["result"]
|
673
|
+
if self.user_logger:
|
674
|
+
self.user_logger.info(
|
675
|
+
f"Futures and Options Contract file fetched.",
|
676
|
+
caller="marketDataEngine.loadMasterServer",
|
677
|
+
)
|
678
|
+
|
679
|
+
# Fetch CM Master
|
680
|
+
exchangesegments = [self.xt.EXCHANGE_NSECM]
|
681
|
+
response = await self.xt.get_master(exchangeSegmentList=exchangesegments)
|
682
|
+
CM_response = response["result"]
|
683
|
+
|
684
|
+
if self.user_logger:
|
685
|
+
self.user_logger.info(
|
686
|
+
f"Cash Market Contract file fetched.",
|
687
|
+
caller="marketDataEngine.loadMasterServer",
|
688
|
+
)
|
689
|
+
|
690
|
+
# Save files as compressed JSON Lines
|
691
|
+
|
692
|
+
# Save FO Master as simple JSON
|
693
|
+
with open("FandO_master.txt", "w", encoding="utf-8") as f:
|
694
|
+
f.write(FandO_response) # assuming list of strings
|
695
|
+
|
696
|
+
with open("CM_master.txt", "w", encoding="utf-8") as f:
|
697
|
+
f.write(CM_response) # assuming list of strings
|
698
|
+
|
699
|
+
if self.user_logger:
|
700
|
+
self.user_logger.info(
|
701
|
+
"Master files written to disk successfully.",
|
702
|
+
caller="marketDataEngine.loadMasterServer",
|
703
|
+
)
|
704
|
+
|
705
|
+
except Exception as e:
|
706
|
+
self.user_logger.error(str(e), caller="marketDataEngine.loadMasterServer")
|
707
|
+
raise (e)
|
708
|
+
|
586
709
|
async def fetch_ltp(self, Instruments: List[Dict]) -> List[TouchLineData]:
|
587
710
|
"""
|
588
711
|
Fetches the Last Traded Price (LTP) data for a list of instruments.
|
@@ -632,14 +755,14 @@ class marketDataEngine(MarketDataSocketClient):
|
|
632
755
|
return json.loads(response["result"]["listQuotes"][0])
|
633
756
|
|
634
757
|
async def unsubscribe(
|
635
|
-
self, Instruments: List[Dict], xtsMessageCode: int,
|
758
|
+
self, Instruments: List[Dict], xtsMessageCode: int, uuid: str
|
636
759
|
) -> None:
|
637
760
|
"""
|
638
761
|
Unsubscribes from market data for the given instruments.
|
639
762
|
Args:
|
640
763
|
Instruments (List[Dict]): A list of dictionaries, each containing 'exchangeSegment' and 'exchangeInstrumentID'.
|
641
764
|
xtsMessageCode (int): The message code for the unsubscription. Must be one of [1501, 1502, 1505, 1507, 1512, 1105].
|
642
|
-
|
765
|
+
uuid (str): A string representing the strategy UUID.
|
643
766
|
Raises:
|
644
767
|
AssertionError: If any of the input arguments do not meet the required conditions.
|
645
768
|
Exception: If an error occurs during the unsubscription process.
|
@@ -650,8 +773,8 @@ class marketDataEngine(MarketDataSocketClient):
|
|
650
773
|
assert isinstance(Instruments, list), "Instruments must be a list"
|
651
774
|
assert isinstance(xtsMessageCode, int), "xtsMessageCode must be an integer"
|
652
775
|
assert isinstance(
|
653
|
-
|
654
|
-
), "
|
776
|
+
uuid, str
|
777
|
+
), "uuid should be a string representing the strategy UUID"
|
655
778
|
for instrument in Instruments:
|
656
779
|
assert isinstance(instrument, dict), "Each instrument must be a dictionary"
|
657
780
|
assert (
|
@@ -670,23 +793,29 @@ class marketDataEngine(MarketDataSocketClient):
|
|
670
793
|
], "Invalid message code"
|
671
794
|
|
672
795
|
try:
|
796
|
+
listToUnsubscribe: List = []
|
673
797
|
for item in range(len(Instruments)):
|
674
798
|
self.subscribe_manager.unsubscribe(
|
675
|
-
Instruments[item]["exchangeInstrumentID"],
|
799
|
+
Instruments[item]["exchangeInstrumentID"], xtsMessageCode, uuid
|
676
800
|
)
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
if
|
682
|
-
self.
|
683
|
-
|
684
|
-
caller="marketDataEngine.unsubscribe",
|
801
|
+
if not self.subscribe_manager.ifExists(
|
802
|
+
Instruments[item]["exchangeInstrumentID"], xtsMessageCode
|
803
|
+
):
|
804
|
+
listToUnsubscribe.append(item)
|
805
|
+
if listToUnsubscribe:
|
806
|
+
response = await self.xt.send_unsubscription(
|
807
|
+
Instruments=Instruments, xtsMessageCode=xtsMessageCode
|
685
808
|
)
|
686
|
-
|
809
|
+
if response["type"] != "success":
|
810
|
+
if self.user_logger:
|
811
|
+
self.user_logger.error(
|
812
|
+
f"Error in unsubscribing Quantities: {Instruments} on request from {uuid} as {response}",
|
813
|
+
caller="marketDataEngine.unsubscribe",
|
814
|
+
)
|
815
|
+
raise (response)
|
687
816
|
if self.user_logger:
|
688
817
|
self.user_logger.info(
|
689
|
-
f"Unsubscribed Quantities: {Instruments} on request from {
|
818
|
+
f"Unsubscribed Quantities: {Instruments} on request from {uuid}",
|
690
819
|
caller="marketDataEngine.unsubscribe",
|
691
820
|
)
|
692
821
|
|
@@ -703,7 +832,7 @@ class marketDataEngine(MarketDataSocketClient):
|
|
703
832
|
Returns:
|
704
833
|
List[datetime.datetime]: A sorted list of contract expirations.
|
705
834
|
"""
|
706
|
-
return self.
|
835
|
+
return self.option_manager.search_expiry_by_underline(underline)
|
707
836
|
|
708
837
|
async def option_search_all_underline(self) -> List[str]:
|
709
838
|
"""
|
@@ -711,7 +840,7 @@ class marketDataEngine(MarketDataSocketClient):
|
|
711
840
|
Returns:
|
712
841
|
List[str]: A list of all unique underlying index names.
|
713
842
|
"""
|
714
|
-
return self.
|
843
|
+
return self.option_manager.search_all_underline()
|
715
844
|
|
716
845
|
async def option_search_by_underline(
|
717
846
|
self, underline: str
|
@@ -723,7 +852,7 @@ class marketDataEngine(MarketDataSocketClient):
|
|
723
852
|
Returns:
|
724
853
|
List[OptionsInstrument]: A list of options instruments.
|
725
854
|
"""
|
726
|
-
return self.
|
855
|
+
return self.option_manager.search_option_by_underline(underline)
|
727
856
|
|
728
857
|
async def option_search_by_expiry_and_underline(
|
729
858
|
self, underline: str, expiry: datetime
|
@@ -736,9 +865,7 @@ class marketDataEngine(MarketDataSocketClient):
|
|
736
865
|
Returns:
|
737
866
|
List[OptionsInstrument]: A list of options instruments.
|
738
867
|
"""
|
739
|
-
return self.
|
740
|
-
underline, expiry
|
741
|
-
)
|
868
|
+
return self.option_manager.search_option_by_expiry_underline(underline, expiry)
|
742
869
|
|
743
870
|
async def option_search(
|
744
871
|
self,
|
@@ -769,7 +896,7 @@ class marketDataEngine(MarketDataSocketClient):
|
|
769
896
|
Returns:
|
770
897
|
pandas.DataFrame: DataFrame containing the search results.
|
771
898
|
"""
|
772
|
-
return self.
|
899
|
+
return self.option_manager.search_option(
|
773
900
|
ExchangeSegment=ExchangeSegment,
|
774
901
|
ExchangeInstrumentID=ExchangeInstrumentID,
|
775
902
|
InstrumentType=InstrumentType,
|
@@ -925,3 +1052,54 @@ class marketDataEngine(MarketDataSocketClient):
|
|
925
1052
|
}
|
926
1053
|
)
|
927
1054
|
asyncio.ensure_future(baseAlgo.trade_(tradeEvent))
|
1055
|
+
|
1056
|
+
def loadMasterClient(
|
1057
|
+
self,
|
1058
|
+
index_list: None,
|
1059
|
+
exchange_to_exchangeSegments: None,
|
1060
|
+
fo_response: str = None,
|
1061
|
+
cm_response: str = None,
|
1062
|
+
) -> None:
|
1063
|
+
"""
|
1064
|
+
Loads and initializes master data for the client using provided inputs.
|
1065
|
+
|
1066
|
+
This method updates internal mappings and dataframes with master data for
|
1067
|
+
exchanges, indices, Futures & Options (FO), and Cash Market (CM). It can be
|
1068
|
+
called with any subset of the available inputs.
|
1069
|
+
|
1070
|
+
Args:
|
1071
|
+
index_list (list, optional): A list of index dictionaries containing keys
|
1072
|
+
"Name", "ExchangeSegment", and "ExchangeInstrumentID". Used to populate
|
1073
|
+
self.index_list.
|
1074
|
+
exchange_to_exchangeSegments (dict, optional): Mapping of exchange codes to
|
1075
|
+
exchange segment IDs. Updates self.exchange_to_exchangeSegments.
|
1076
|
+
fo_response (str, optional): FO master data as a string. Processes and
|
1077
|
+
initializes the option manager with the data.
|
1078
|
+
cm_response (str, optional): CM master data as a string. Converts and stores
|
1079
|
+
it in self.CM_MASTER_DF.
|
1080
|
+
|
1081
|
+
Returns:
|
1082
|
+
None
|
1083
|
+
"""
|
1084
|
+
if exchange_to_exchangeSegments:
|
1085
|
+
self.exchange_to_exchangeSegments = exchange_to_exchangeSegments
|
1086
|
+
|
1087
|
+
if index_list:
|
1088
|
+
for index in index_list:
|
1089
|
+
self.index_list.append(
|
1090
|
+
Index(
|
1091
|
+
index["Name"],
|
1092
|
+
index["ExchangeSegment"],
|
1093
|
+
index["ExchangeInstrumentID"],
|
1094
|
+
)
|
1095
|
+
)
|
1096
|
+
|
1097
|
+
if fo_response:
|
1098
|
+
_, o_master_df, __ = helper.fo_master_string_to_df(fo_response)
|
1099
|
+
o_master_df["UnderlyingIndexName"] = o_master_df[
|
1100
|
+
"UnderlyingIndexName"
|
1101
|
+
].str.upper()
|
1102
|
+
self.option_manager = OptionManager(o_master_df)
|
1103
|
+
|
1104
|
+
if cm_response:
|
1105
|
+
self.CM_MASTER_DF = cm_master_string_to_df(cm_response)
|
@@ -0,0 +1,33 @@
|
|
1
|
+
tradx/__init__.py,sha256=MlWuula4lJZLPYPi4d5ZE9yoJnYWtgbZ0QsgWdWPwU0,53
|
2
|
+
tradx/algoContainer.py,sha256=L-Pmqh5Ls8r9_edSpayEyC7Vtwv8Uiy1GKUpphnAW4Y,7330
|
3
|
+
tradx/dualHashMap.py,sha256=XsidIc3aMvpVGOvdfV7lOeZaLCWAD5i180BGyAfdYXE,1737
|
4
|
+
tradx/interactiveEngine.py,sha256=xEjev7ttHX2J7UlG5_N55Bjpu99Guqi4gIMqqkE11UI,46572
|
5
|
+
tradx/marketDataEngine.py,sha256=NQ62tc-arnzdFBjojiy8Mx8k2RKd0aU0CRY4mWbE4qk,47350
|
6
|
+
tradx/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
+
tradx/baseClass/baseAlgo.py,sha256=3PCLTyXLnXK66wiRKnwwK15033a2-vSzwL4bitKtCC0,21833
|
8
|
+
tradx/baseClass/interactive/order.py,sha256=yAQ3V0DYJ0KnNUeismmvJlPxbV8bPFGOe_-kYcNh5qE,1834
|
9
|
+
tradx/baseClass/interactive/orderEvent.py,sha256=_RbUYpU2L-6HyG5QJicagHbyNUkZdSwhlRPwdJuEFSI,2979
|
10
|
+
tradx/baseClass/interactive/position.py,sha256=C7DQQmBIK1PtEwjdNZszvt2kkQP_MfiCdjRSXWxNSsg,1688
|
11
|
+
tradx/baseClass/interactive/positionEvent.py,sha256=odOMeBqKUKfJ9Zj7IPcipMyfRTMsQyA-hvTJ_NcqKUk,3484
|
12
|
+
tradx/baseClass/interactive/tradeConversionEvent.py,sha256=WyRBu02EeUFrcYd9zkahAPYoP1rCoTQDB09IzNa3Zno,3246
|
13
|
+
tradx/baseClass/interactive/tradeEvent.py,sha256=djunJW5AzjeMfJZVMlrFprplB7vrYBi-mmaR1TA0MK4,6699
|
14
|
+
tradx/baseClass/market/candleData.py,sha256=tS-iAoRGwK2xVSvrqmNZPYeB63qD53oPPHaUDfJBWkk,2947
|
15
|
+
tradx/baseClass/market/cmInstrument.py,sha256=WpibHdJyVGVs0B8o1COiXr4rNXB8bapzFLyRaIG0w9Q,2408
|
16
|
+
tradx/baseClass/market/futureInstrument.py,sha256=ygsGfzUg337gSwoSaAb8DB31YhLOI-nOv3ApX3z5CWQ,2186
|
17
|
+
tradx/baseClass/market/index.py,sha256=C5kj0WW_R3__5zsYGH1zJlSTfkAy_7vhbOtw1f3Iwew,786
|
18
|
+
tradx/baseClass/market/instrumentPropertyChangeData.py,sha256=DIqLb54eEu8aRzFk8J7crkqTedvBbf5dHQjw6pbcv1o,328
|
19
|
+
tradx/baseClass/market/ltpData.py,sha256=D6NSCgvRd1Fk6vD0EMuaDIyNgBxEPzN9C9RDJbN-uM0,3199
|
20
|
+
tradx/baseClass/market/ltpPartialData.py,sha256=W1Kw3OIiwOzrRAFHdjc42D_LDjNsquPnLsF3v2QsHhk,4289
|
21
|
+
tradx/baseClass/market/marketDepthData.py,sha256=WGKTmrUbXcZgCC8MBy404BDG0si-jO9mDWeXnHjmjiM,5050
|
22
|
+
tradx/baseClass/market/marketStatusData.py,sha256=lZKJlYB_Bfc1Rpv4rQ15ZQTXgH5EkBDOvH6RSqAnu9w,4037
|
23
|
+
tradx/baseClass/market/openInterestData.py,sha256=L-WuxyNwdZAFPoSVhfJPKv8jOy5K0rSB2o5EkWVSv9g,3111
|
24
|
+
tradx/baseClass/market/openInterestPartialData.py,sha256=vpo18P9VCBuCXbxjggg4ahd0uS5WkP14rBvcLwdrTFw,1673
|
25
|
+
tradx/baseClass/market/optionsInstrument.py,sha256=O3zhNf1R1wmtdPCUaDr7mOM7co0Aeg8AHmPvVpabP60,9886
|
26
|
+
tradx/baseClass/market/touchLineData.py,sha256=sVODRdT97Xefnpzzddcza_N5KD6teh2tBhME4dRAE7w,7784
|
27
|
+
tradx/baseClass/market/touchLinePartialData.py,sha256=mdLVrD_4O74NRamTrrlH9ge69xVXv2w_XZXpAQOIMYI,4069
|
28
|
+
tradx/constants/holidays.py,sha256=B4ee4bPFy-gBTKN6-G68Idf1n6HxoRcx72O92zSobcE,1200
|
29
|
+
tradx/logger/logger.py,sha256=DfrjzwYkujTq7arksNTPcQeioXnwT1xgN659blhreog,3232
|
30
|
+
tradx/logger/logger2.py,sha256=ebJ-qqnpnCqvyx1Cz1-kGGULtkH-hfrK6UNfa0bSlH8,2654
|
31
|
+
tradx-0.9.dist-info/METADATA,sha256=w7yHOTtMdzGP5x0n8ybU15MPG16ZRvdkmOaEvoq3YnY,2626
|
32
|
+
tradx-0.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
33
|
+
tradx-0.9.dist-info/RECORD,,
|
tradx-0.8.2.dist-info/RECORD
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
tradx/__init__.py,sha256=MlWuula4lJZLPYPi4d5ZE9yoJnYWtgbZ0QsgWdWPwU0,53
|
2
|
-
tradx/algoContainer.py,sha256=1IkVCIF_gXIby8z3pDdlVeUablh-PZVZ1EawyCB7oUs,3807
|
3
|
-
tradx/dualHashMap.py,sha256=XsidIc3aMvpVGOvdfV7lOeZaLCWAD5i180BGyAfdYXE,1737
|
4
|
-
tradx/interactiveEngine.py,sha256=vKGjIlyngFay4bD-9jvmGB8cGDyqDi2tmZdHmPdDbYs,40860
|
5
|
-
tradx/marketDataEngine.py,sha256=NsMEI4tdyLxpyAP2QiKFkn2mywXxTV9yekEbcTFFk44,39994
|
6
|
-
tradx/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
-
tradx/baseClass/baseAlgo.py,sha256=eUfFNlTB7rwgIt8pbU3qj7SlD5jOCgpnL4jXXFJQqa8,21012
|
8
|
-
tradx/baseClass/candleData.py,sha256=tS-iAoRGwK2xVSvrqmNZPYeB63qD53oPPHaUDfJBWkk,2947
|
9
|
-
tradx/baseClass/cmInstrument.py,sha256=WpibHdJyVGVs0B8o1COiXr4rNXB8bapzFLyRaIG0w9Q,2408
|
10
|
-
tradx/baseClass/futureInstrument.py,sha256=ygsGfzUg337gSwoSaAb8DB31YhLOI-nOv3ApX3z5CWQ,2186
|
11
|
-
tradx/baseClass/index.py,sha256=C5kj0WW_R3__5zsYGH1zJlSTfkAy_7vhbOtw1f3Iwew,786
|
12
|
-
tradx/baseClass/instrumentPropertyChangeData.py,sha256=DIqLb54eEu8aRzFk8J7crkqTedvBbf5dHQjw6pbcv1o,328
|
13
|
-
tradx/baseClass/ltpData.py,sha256=D6NSCgvRd1Fk6vD0EMuaDIyNgBxEPzN9C9RDJbN-uM0,3199
|
14
|
-
tradx/baseClass/ltpPartialData.py,sha256=W1Kw3OIiwOzrRAFHdjc42D_LDjNsquPnLsF3v2QsHhk,4289
|
15
|
-
tradx/baseClass/marketDepthData.py,sha256=WGKTmrUbXcZgCC8MBy404BDG0si-jO9mDWeXnHjmjiM,5050
|
16
|
-
tradx/baseClass/marketStatusData.py,sha256=lZKJlYB_Bfc1Rpv4rQ15ZQTXgH5EkBDOvH6RSqAnu9w,4037
|
17
|
-
tradx/baseClass/openInterestData.py,sha256=L-WuxyNwdZAFPoSVhfJPKv8jOy5K0rSB2o5EkWVSv9g,3111
|
18
|
-
tradx/baseClass/openInterestPartialData.py,sha256=vpo18P9VCBuCXbxjggg4ahd0uS5WkP14rBvcLwdrTFw,1673
|
19
|
-
tradx/baseClass/optionsInstrument.py,sha256=O3zhNf1R1wmtdPCUaDr7mOM7co0Aeg8AHmPvVpabP60,9886
|
20
|
-
tradx/baseClass/order.py,sha256=1o3AtlysNBs4dRwSjCh11AOoJ97QCNra4D9HLv9vMm4,1699
|
21
|
-
tradx/baseClass/orderEvent.py,sha256=P4sJW3NKi53JDo8RwMVVKpCA_dIpkcE1-sm9ikpFYWk,2901
|
22
|
-
tradx/baseClass/position.py,sha256=6fzm_Mr1GKSaRArRgsZItgw74_8omy-MBXRTfO12Pwk,1551
|
23
|
-
tradx/baseClass/positionEvent.py,sha256=odOMeBqKUKfJ9Zj7IPcipMyfRTMsQyA-hvTJ_NcqKUk,3484
|
24
|
-
tradx/baseClass/touchLineData.py,sha256=sVODRdT97Xefnpzzddcza_N5KD6teh2tBhME4dRAE7w,7784
|
25
|
-
tradx/baseClass/touchLinePartialData.py,sha256=mdLVrD_4O74NRamTrrlH9ge69xVXv2w_XZXpAQOIMYI,4069
|
26
|
-
tradx/baseClass/tradeConversionEvent.py,sha256=WyRBu02EeUFrcYd9zkahAPYoP1rCoTQDB09IzNa3Zno,3246
|
27
|
-
tradx/baseClass/tradeEvent.py,sha256=djunJW5AzjeMfJZVMlrFprplB7vrYBi-mmaR1TA0MK4,6699
|
28
|
-
tradx/constants/holidays.py,sha256=B4ee4bPFy-gBTKN6-G68Idf1n6HxoRcx72O92zSobcE,1200
|
29
|
-
tradx/logger/logger.py,sha256=DfrjzwYkujTq7arksNTPcQeioXnwT1xgN659blhreog,3232
|
30
|
-
tradx/logger/logger2.py,sha256=ebJ-qqnpnCqvyx1Cz1-kGGULtkH-hfrK6UNfa0bSlH8,2654
|
31
|
-
tradx-0.8.2.dist-info/METADATA,sha256=DouKh0E8J3UL6V5a--FX5pV6ktMhx1y6ip_CYEdRDLs,2628
|
32
|
-
tradx-0.8.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
33
|
-
tradx-0.8.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|