quantplay 2.0.52__tar.gz → 2.0.54__tar.gz

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.
Files changed (66) hide show
  1. {quantplay-2.0.52 → quantplay-2.0.54}/PKG-INFO +26 -1
  2. quantplay-2.0.54/quantplay/broker/broker_factory.py +475 -0
  3. quantplay-2.0.54/quantplay/broker/kotak.py +370 -0
  4. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay.egg-info/PKG-INFO +26 -1
  5. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay.egg-info/SOURCES.txt +1 -0
  6. {quantplay-2.0.52 → quantplay-2.0.54}/setup.py +1 -1
  7. quantplay-2.0.52/quantplay/broker/broker_factory.py +0 -260
  8. {quantplay-2.0.52 → quantplay-2.0.54}/README.md +0 -0
  9. {quantplay-2.0.52 → quantplay-2.0.54}/pyproject.toml +0 -0
  10. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/__init__.py +0 -0
  11. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/__init__.py +0 -0
  12. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/aliceblue.py +0 -0
  13. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/angelone.py +0 -0
  14. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/auto_login/__init__.py +0 -0
  15. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/auto_login/aliceblue.py +0 -0
  16. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/dhan.py +0 -0
  17. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/finvasia_utils/__init__.py +0 -0
  18. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/finvasia_utils/fa_noren.py +0 -0
  19. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/five_paisa.py +0 -0
  20. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/flattrade.py +0 -0
  21. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/ft_utils/__init__.py +0 -0
  22. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/ft_utils/flattrade_utils.py +0 -0
  23. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/ft_utils/ft_noren.py +0 -0
  24. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/generics/__init__.py +0 -0
  25. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/generics/broker.py +0 -0
  26. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/iifl_xts.py +0 -0
  27. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/kite_utils.py +0 -0
  28. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/motilal.py +0 -0
  29. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/noren.py +0 -0
  30. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/shoonya.py +0 -0
  31. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/uplink/__init__.py +0 -0
  32. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/uplink/uplink_utils.py +0 -0
  33. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/upstox.py +0 -0
  34. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/xts.py +0 -0
  35. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/xts_utils/Connect.py +0 -0
  36. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/xts_utils/Exception.py +0 -0
  37. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/xts_utils/InteractiveSocketClient.py +0 -0
  38. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/xts_utils/__init__.py +0 -0
  39. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/broker/zerodha.py +0 -0
  40. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/exception/__init__.py +0 -0
  41. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/exception/exceptions.py +0 -0
  42. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/model/__init__.py +0 -0
  43. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/model/broker.py +0 -0
  44. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/model/generics.py +0 -0
  45. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/model/instrument_data.py +0 -0
  46. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/model/order_event.py +0 -0
  47. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/py.typed +0 -0
  48. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/utils/__init__.py +0 -0
  49. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/utils/caching.py +0 -0
  50. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/utils/constant.py +0 -0
  51. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/utils/exchange.py +0 -0
  52. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/utils/number_utils.py +0 -0
  53. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/utils/pickle_utils.py +0 -0
  54. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/utils/selenium_utils.py +0 -0
  55. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/wrapper/__init__.py +0 -0
  56. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/wrapper/aws/__init__.py +0 -0
  57. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay/wrapper/aws/s3.py +0 -0
  58. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay.egg-info/dependency_links.txt +0 -0
  59. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay.egg-info/requires.txt +0 -0
  60. {quantplay-2.0.52 → quantplay-2.0.54}/quantplay.egg-info/top_level.txt +0 -0
  61. {quantplay-2.0.52 → quantplay-2.0.54}/setup.cfg +0 -0
  62. {quantplay-2.0.52 → quantplay-2.0.54}/tests/__init__.py +0 -0
  63. {quantplay-2.0.52 → quantplay-2.0.54}/tests/conftest.py +0 -0
  64. {quantplay-2.0.52 → quantplay-2.0.54}/tests/wrapper/__init__.py +0 -0
  65. {quantplay-2.0.52 → quantplay-2.0.54}/tests/wrapper/aws/__init__.py +0 -0
  66. {quantplay-2.0.52 → quantplay-2.0.54}/tests/wrapper/aws/s3_test.py +0 -0
@@ -1,11 +1,36 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantplay
3
- Version: 2.0.52
3
+ Version: 2.0.54
4
4
  Summary: This python package will be stored in AWS CodeArtifact
5
5
  Home-page:
6
6
  Author:
7
7
  Author-email:
8
8
  License: MIT
9
+ Requires-Dist: setuptools
10
+ Requires-Dist: path
11
+ Requires-Dist: pyotp
12
+ Requires-Dist: retrying
13
+ Requires-Dist: boto3
14
+ Requires-Dist: numpy
15
+ Requires-Dist: websocket-client
16
+ Requires-Dist: smartapi-python
17
+ Requires-Dist: logzero
18
+ Requires-Dist: selenium
19
+ Requires-Dist: requests
20
+ Requires-Dist: pandas
21
+ Requires-Dist: pyarrow
22
+ Requires-Dist: polars
23
+ Requires-Dist: kiteconnect
24
+ Requires-Dist: pya3
25
+ Requires-Dist: py5paisa
26
+ Requires-Dist: upstox-python-sdk
27
+ Requires-Dist: undetected-chromedriver
28
+ Requires-Dist: cachetools
29
+ Requires-Dist: py_vollib
30
+ Requires-Dist: python-engineio
31
+ Requires-Dist: python-socketio
32
+ Requires-Dist: six
33
+ Requires-Dist: dhanhq
9
34
 
10
35
  # Quantplay Alpha playground
11
36
 
@@ -0,0 +1,475 @@
1
+ import codecs
2
+ import os
3
+ import pickle
4
+ import traceback
5
+ from dataclasses import dataclass
6
+ from typing import Any, Dict
7
+
8
+ from quantplay.broker.aliceblue import Aliceblue
9
+ from quantplay.broker.angelone import AngelOne
10
+ from quantplay.broker.dhan import Dhan
11
+ from quantplay.broker.five_paisa import FivePaisa
12
+ from quantplay.broker.flattrade import FlatTrade
13
+ from quantplay.broker.iifl_xts import IIFL as IIFL_XTS
14
+ from quantplay.broker.kotak import Kotak
15
+ from quantplay.broker.motilal import Motilal
16
+ from quantplay.broker.shoonya import FinvAsia
17
+ from quantplay.broker.upstox import Upstox
18
+ from quantplay.broker.zerodha import Zerodha
19
+ from quantplay.exception.exceptions import InvalidArgumentException
20
+ from quantplay.utils.caching import InstrumentCache
21
+ from quantplay.utils.pickle_utils import PickleUtils
22
+
23
+
24
+ BrokerType = (
25
+ Aliceblue
26
+ | AngelOne
27
+ | FlatTrade
28
+ | Motilal
29
+ | FinvAsia
30
+ | Upstox
31
+ | Zerodha
32
+ | IIFL_XTS
33
+ | FivePaisa
34
+ | Kotak
35
+ | Dhan
36
+ )
37
+
38
+ instrument_cache = InstrumentCache()
39
+
40
+
41
+ @dataclass
42
+ class Broker:
43
+ ZERODHA = "Zerodha"
44
+ UPSTOX = "Upstox"
45
+ ALICEBLUE = "Aliceblue"
46
+ FIVEPAISA_OPENAPI = "5Paisa_OpenAPI"
47
+ FINVASIA = "Finvasia"
48
+ FLATTRADE = "Flattrade"
49
+ IIFL_XTS = "IIFL_XTS"
50
+ MOTILAL = "Motilal"
51
+ ANGELONE = "Angelone"
52
+ KOTAK = "Kotak"
53
+ DHAN = "Dhan"
54
+
55
+
56
+ broker_instruments_map = {
57
+ Broker.ZERODHA: "zerodha_instruments",
58
+ Broker.FINVASIA: "shoonya_instruments",
59
+ Broker.FLATTRADE: "shoonya_instruments",
60
+ Broker.IIFL_XTS: "xts_instruments",
61
+ Broker.MOTILAL: "motilal_instruments",
62
+ Broker.ANGELONE: "angelone_instruments",
63
+ Broker.ALICEBLUE: "aliceblue_instruments",
64
+ Broker.UPSTOX: "upstox_instruments",
65
+ Broker.FIVEPAISA_OPENAPI: "5paisa_instruments",
66
+ Broker.KOTAK: "upstox_instruments",
67
+ }
68
+
69
+ broker_required_args = {
70
+ Broker.ZERODHA: set(["user_id", "zerodha_wrapper"]),
71
+ Broker.FINVASIA: set(["user_id", "user_token"]),
72
+ Broker.FLATTRADE: set(["user_id", "user_token"]),
73
+ Broker.IIFL_XTS: set(["user_id", "wrapper", "md_wrapper"]),
74
+ Broker.MOTILAL: set(["user_id", "headers"]),
75
+ Broker.ALICEBLUE: set(["user_id", "client"]),
76
+ Broker.UPSTOX: set(["user_id", "access_token"]),
77
+ Broker.DHAN: set(["user_id", "access_token"]),
78
+ Broker.FIVEPAISA_OPENAPI: set(["user_id", "client"]),
79
+ Broker.KOTAK: set(["user_id", "configuration"]),
80
+ Broker.ANGELONE: set(
81
+ [
82
+ "user_id",
83
+ "api_key",
84
+ "access_token",
85
+ "refresh_token",
86
+ "feed_token",
87
+ ]
88
+ ),
89
+ }
90
+
91
+ broker_generate_args = {
92
+ Broker.ZERODHA: set(["user_id", "api_key", "api_secret", "password", "totp"]),
93
+ Broker.FINVASIA: set(["user_id", "user_token"]),
94
+ Broker.FLATTRADE: set(["user_id", "user_token"]),
95
+ Broker.IIFL_XTS: set(["user_id", "wrapper", "md_wrapper"]),
96
+ Broker.MOTILAL: set(["user_id", "password", "api_key", "two_fa", "totp"]),
97
+ Broker.ALICEBLUE: set(["user_id", "api_key"]),
98
+ Broker.DHAN: set(["user_id", "access_token"]),
99
+ Broker.FIVEPAISA_OPENAPI: set(["user_id", "client"]),
100
+ Broker.ANGELONE: set(["user_id", "api_key", "mpin", "totp"]),
101
+ Broker.KOTAK: set(
102
+ ["consumer_key", "consumer_secret", "mobilenumber", "password", "mpin"]
103
+ ),
104
+ Broker.UPSTOX: set(
105
+ [
106
+ "user_id",
107
+ "api_key",
108
+ "api_secret",
109
+ "totp",
110
+ "mobile_number",
111
+ "account_pin",
112
+ "redirect_url",
113
+ ]
114
+ ),
115
+ }
116
+
117
+
118
+ class BrokerFactory:
119
+ def __init__(self):
120
+ self.client_broker_data: Dict[str, BrokerType] = {}
121
+
122
+ def get_broker_key(self, username: str, broker_name: str) -> str:
123
+ return f"{username}:{broker_name}"
124
+
125
+ def validate_broker_args(
126
+ self, broker_info: Dict[str, Any], is_generator_args: bool = False
127
+ ):
128
+ broker = broker_info["broker"]
129
+ broker_data = broker_info["broker_data"]
130
+
131
+ compare_map = broker_generate_args if is_generator_args else broker_required_args
132
+
133
+ if broker not in compare_map.keys():
134
+ raise InvalidArgumentException(f"Unsupported Broker: '{broker}'")
135
+
136
+ if not compare_map[broker].issubset(broker_data.keys()):
137
+ raise InvalidArgumentException(
138
+ f"Missing Arguments for {broker_info['username']}:{broker_info['nickname']} in broker '{broker}' -> {compare_map[broker].difference(broker_info.keys())}"
139
+ )
140
+
141
+ def generate_token(self, broker_info: Dict[str, Any]):
142
+ broker_client: BrokerType | None = None
143
+
144
+ broker_data = broker_info["broker_data"]
145
+ broker = broker_info["broker"]
146
+
147
+ broker_client: BrokerType | None = None
148
+ self.validate_broker_args(broker_info, is_generator_args=True)
149
+
150
+ if broker == Broker.MOTILAL:
151
+ broker_client = Motilal(
152
+ user_id=broker_data["user_id"],
153
+ password=broker_data["password"],
154
+ api_key=broker_data["api_key"],
155
+ two_fa=broker_data["two_fa"],
156
+ totp=broker_data["totp"],
157
+ load_instrument=False,
158
+ )
159
+ broker_data["headers"] = broker_client.headers
160
+
161
+ elif broker == Broker.DHAN:
162
+ broker_client = Dhan(
163
+ user_id=broker_data["user_id"],
164
+ access_token=broker_data["access_token"],
165
+ load_instrument=False,
166
+ )
167
+
168
+ elif broker == Broker.KOTAK:
169
+ broker_client = Kotak(
170
+ consumer_key=broker_data["consumer_key"],
171
+ consumer_secret=broker_data["consumer_secret"],
172
+ mobilenumber=broker_data["mobilenumber"],
173
+ password=broker_data["password"],
174
+ mpin=broker_data["mpin"],
175
+ load_instrument=False,
176
+ )
177
+
178
+ broker_data["configuration"] = broker_client.configuration
179
+
180
+ elif broker == Broker.ZERODHA:
181
+ broker_client = Zerodha(
182
+ user_id=broker_data["user_id"],
183
+ api_key=broker_data["api_key"],
184
+ api_secret=broker_data["api_secret"],
185
+ password=broker_data["password"],
186
+ totp=broker_data["totp"],
187
+ load_instrument=False,
188
+ )
189
+
190
+ broker_data["zerodha_wrapper"] = codecs.encode(
191
+ pickle.dumps(broker_client.wrapper), "base64"
192
+ ).decode()
193
+
194
+ elif broker == Broker.ANGELONE:
195
+ broker_client = AngelOne(
196
+ api_key=broker_data["api_key"],
197
+ user_id=broker_data["user_id"],
198
+ mpin=broker_data["mpin"],
199
+ totp=broker_data["totp"],
200
+ load_instrument=False,
201
+ )
202
+
203
+ broker_data["refresh_token"] = broker_client.wrapper.refresh_token # type: ignore
204
+ broker_data["access_token"] = broker_client.wrapper.access_token # type: ignore
205
+ broker_data["feed_token"] = broker_client.wrapper.feed_token # type: ignore
206
+
207
+ elif broker == Broker.ALICEBLUE:
208
+ broker_client = Aliceblue(
209
+ user_id=broker_data["user_id"],
210
+ api_key=broker_data["api_key"],
211
+ load_instrument=False,
212
+ )
213
+
214
+ broker_data["client"] = codecs.encode(
215
+ pickle.dumps(broker_client.alice), "base64"
216
+ ).decode()
217
+
218
+ elif broker == Broker.UPSTOX:
219
+ broker_client = Upstox(
220
+ user_id=broker_data["user_id"],
221
+ api_key=broker_data["api_key"],
222
+ api_secret=broker_data["api_secret"],
223
+ totp=broker_data["totp"],
224
+ mobile_number=broker_data["mobile_number"],
225
+ account_pin=broker_data["account_pin"],
226
+ redirect_url=broker_data["redirect_url"],
227
+ load_instrument=False,
228
+ )
229
+
230
+ broker_data["access_token"] = broker_client.configuration.access_token
231
+
232
+ elif broker == Broker.FINVASIA:
233
+ broker_client = FinvAsia(
234
+ api_secret=broker_data["api_secret"],
235
+ imei=broker_data["imei"],
236
+ password=broker_data["password"],
237
+ totp_key=broker_data["totp_key"],
238
+ user_id=broker_data["user_id"],
239
+ vendor_code=broker_data["vendor_code"],
240
+ load_instrument=False,
241
+ )
242
+
243
+ broker_client.api.close_websocket()
244
+ broker_data["user_token"] = broker_client.user_token
245
+
246
+ elif broker == Broker.FLATTRADE:
247
+ broker_client = FlatTrade(
248
+ user_id=broker_data["user_id"],
249
+ api_secret=broker_data["api_secret"],
250
+ password=broker_data["password"],
251
+ totp_key=broker_data["totp_key"],
252
+ api_key=broker_data["api_key"],
253
+ load_instrument=False,
254
+ )
255
+
256
+ broker_client.api.close_websocket()
257
+ broker_data["user_token"] = broker_client.user_token
258
+
259
+ elif broker == Broker.FIVEPAISA_OPENAPI:
260
+ broker_client = FivePaisa(
261
+ app_source=broker_data["app_source"],
262
+ app_user_id=broker_data["app_user_id"],
263
+ app_password=broker_data["app_password"],
264
+ user_key=broker_data["user_key"],
265
+ encryption_key=broker_data["encryption_key"],
266
+ client_id=broker_data["client_id"],
267
+ totp_key=broker_data["totp_key"],
268
+ pin=broker_data["pin"],
269
+ load_instrument=False,
270
+ )
271
+
272
+ broker_data["client"] = broker_client.get_client()
273
+ broker_data["user_id"] = broker_client.user_id
274
+
275
+ elif broker == Broker.IIFL_XTS:
276
+ broker_client = IIFL_XTS(
277
+ api_secret=broker_data["api_secret"],
278
+ api_key=broker_data["api_key"],
279
+ md_api_key=broker_data["md_api_key"],
280
+ md_api_secret=broker_data["md_api_secret"],
281
+ client_id=broker_data["user_id"],
282
+ load_instrument=False,
283
+ )
284
+ broker_data["user_id"] = broker_client.ClientID
285
+
286
+ broker_data["wrapper"] = codecs.encode(
287
+ pickle.dumps(broker_client.wrapper), "base64"
288
+ ).decode()
289
+
290
+ broker_data["md_wrapper"] = codecs.encode(
291
+ pickle.dumps(broker_client.md_wrapper), "base64"
292
+ ).decode()
293
+
294
+ else:
295
+ raise InvalidArgumentException(f"Broker '{broker}' not supported")
296
+
297
+ return (
298
+ broker_client,
299
+ broker_data,
300
+ )
301
+
302
+ def store_broker_client(
303
+ self, broker_info: Dict[str, Any], load_instrument: bool = True
304
+ ) -> BrokerType | None:
305
+ username = broker_info["username"]
306
+ nickname = broker_info["nickname"]
307
+
308
+ broker_key = self.get_broker_key(username, nickname)
309
+
310
+ broker_data = broker_info["broker_data"]
311
+ broker = broker_info["broker"]
312
+
313
+ broker_client: BrokerType | None = None
314
+
315
+ if broker == Broker.MOTILAL:
316
+ broker_client = Motilal(
317
+ headers=broker_data["headers"],
318
+ load_instrument=load_instrument,
319
+ )
320
+
321
+ if broker == Broker.DHAN:
322
+ broker_client = Dhan(
323
+ user_id=broker_data["user_id"],
324
+ access_token=broker_data["access_token"],
325
+ load_instrument=load_instrument,
326
+ )
327
+
328
+ if broker == Broker.KOTAK:
329
+ broker_client = Kotak(
330
+ configuration=broker_data["configuration"],
331
+ load_instrument=load_instrument,
332
+ )
333
+ elif broker == Broker.ZERODHA:
334
+ broker_client = Zerodha(
335
+ wrapper=broker_data["zerodha_wrapper"],
336
+ load_instrument=load_instrument,
337
+ )
338
+
339
+ elif broker == Broker.ANGELONE:
340
+ broker_client = AngelOne(
341
+ user_id=broker_data["user_id"],
342
+ api_key=broker_data["api_key"],
343
+ access_token=broker_data["access_token"],
344
+ refresh_token=broker_data["refresh_token"],
345
+ feed_token=broker_data["feed_token"],
346
+ load_instrument=load_instrument,
347
+ )
348
+
349
+ elif broker == Broker.ALICEBLUE:
350
+ broker_client = Aliceblue(
351
+ client=broker_data["client"],
352
+ load_instrument=load_instrument,
353
+ )
354
+
355
+ elif broker == Broker.UPSTOX:
356
+ broker_client = Upstox(
357
+ access_token=broker_data["access_token"],
358
+ user_id=broker_data["user_id"],
359
+ load_instrument=load_instrument,
360
+ )
361
+
362
+ elif broker == Broker.FINVASIA:
363
+ broker_client = FinvAsia(
364
+ user_id=broker_data["user_id"],
365
+ user_token=broker_data["user_token"],
366
+ load_instrument=load_instrument,
367
+ )
368
+
369
+ elif broker == Broker.FLATTRADE:
370
+ broker_client = FlatTrade(
371
+ user_id=broker_data["user_id"],
372
+ user_token=broker_data["user_token"],
373
+ load_instrument=load_instrument,
374
+ )
375
+
376
+ elif broker == Broker.FIVEPAISA_OPENAPI:
377
+ broker_client = FivePaisa(
378
+ client=broker_data["client"],
379
+ load_instrument=load_instrument,
380
+ )
381
+
382
+ elif broker == Broker.IIFL_XTS:
383
+ broker_client = IIFL_XTS(
384
+ wrapper=broker_data["wrapper"],
385
+ md_wrapper=broker_data["md_wrapper"],
386
+ client_id=broker_data["user_id"],
387
+ load_instrument=load_instrument,
388
+ )
389
+
390
+ else:
391
+ raise InvalidArgumentException(f"Broker '{broker}' not supported")
392
+
393
+ if not load_instrument:
394
+ broker_client = self.set_broker_instruments(
395
+ broker_name=broker, broker=broker_client
396
+ )
397
+
398
+ broker_client.username = broker_info["username"]
399
+ broker_client.nickname = broker_info["nickname"]
400
+ broker_client.broker_name = broker_info["broker"]
401
+ broker_client.user_id = broker_data["user_id"]
402
+
403
+ self.client_broker_data[broker_key] = broker_client
404
+
405
+ return broker_client
406
+
407
+ def get_broker_client(self, broker_info: Dict[str, Any]) -> BrokerType:
408
+ username = broker_info["username"]
409
+ nickname = broker_info["nickname"]
410
+
411
+ broker_key = self.get_broker_key(username, nickname)
412
+
413
+ if broker_key in self.client_broker_data:
414
+ return self.client_broker_data[broker_key]
415
+
416
+ self.validate_broker_args(broker_info)
417
+ broker_client = self.store_broker_client(broker_info, load_instrument=False)
418
+
419
+ if broker_client is not None:
420
+ return broker_client
421
+ else:
422
+ raise InvalidArgumentException("Invalid broker API configuration")
423
+
424
+ def set_broker_instruments(self, broker_name: str, broker: BrokerType) -> BrokerType:
425
+ symbol_data_key = f"{broker_name}_instruments"
426
+ quantplay_symbol_key = f"{broker_name}_qplay_symbols"
427
+ broker_symbol_key = f"{broker_name}_broker_symbols"
428
+
429
+ symbol_data = instrument_cache.get(symbol_data_key)
430
+ quantplay_symbol_map = instrument_cache.get(quantplay_symbol_key)
431
+ broker_symbol_map = instrument_cache.get(broker_symbol_key)
432
+
433
+ if symbol_data is not None:
434
+ broker.symbol_data = symbol_data
435
+
436
+ if broker_name != "Zerodha":
437
+ if quantplay_symbol_map is not None and broker_symbol_map is not None:
438
+ broker.quantplay_symbol_map = quantplay_symbol_map
439
+ broker.broker_symbol_map = broker_symbol_map
440
+
441
+ else:
442
+ broker.initialize_broker_symbol_map()
443
+ instrument_cache.set(
444
+ quantplay_symbol_key, broker.quantplay_symbol_map
445
+ )
446
+ instrument_cache.set(broker_symbol_key, broker.broker_symbol_map)
447
+
448
+ return broker
449
+
450
+ try:
451
+ symbol_data = PickleUtils.load_data(broker_instruments_map[broker_name])
452
+ broker.symbol_data = symbol_data
453
+
454
+ if broker_name != "Zerodha":
455
+ broker.initialize_broker_symbol_map()
456
+ instrument_cache.set(quantplay_symbol_key, broker.quantplay_symbol_map)
457
+
458
+ instrument_cache.set(symbol_data_key, symbol_data)
459
+
460
+ except Exception:
461
+ traceback.print_exc()
462
+
463
+ if broker_name != "Zerodha":
464
+ broker.load_instrument(broker_instruments_map[broker_name])
465
+ else:
466
+ broker.initialize_symbol_data()
467
+
468
+ return broker
469
+
470
+ def clear_instrument_cache(self, broker: str) -> None:
471
+ symbol_data_key = f"{broker}_instruments"
472
+ instrument_cache.delete(symbol_data_key)
473
+
474
+ file_name = broker_instruments_map[broker]
475
+ os.system(f"rm /tmp/{file_name}*")