quantplay 2.0.53__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.53 → quantplay-2.0.54}/PKG-INFO +1 -1
  2. quantplay-2.0.54/quantplay/broker/broker_factory.py +475 -0
  3. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay.egg-info/PKG-INFO +1 -1
  4. {quantplay-2.0.53 → quantplay-2.0.54}/setup.py +1 -1
  5. quantplay-2.0.53/quantplay/broker/broker_factory.py +0 -282
  6. {quantplay-2.0.53 → quantplay-2.0.54}/README.md +0 -0
  7. {quantplay-2.0.53 → quantplay-2.0.54}/pyproject.toml +0 -0
  8. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/__init__.py +0 -0
  9. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/__init__.py +0 -0
  10. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/aliceblue.py +0 -0
  11. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/angelone.py +0 -0
  12. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/auto_login/__init__.py +0 -0
  13. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/auto_login/aliceblue.py +0 -0
  14. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/dhan.py +0 -0
  15. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/finvasia_utils/__init__.py +0 -0
  16. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/finvasia_utils/fa_noren.py +0 -0
  17. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/five_paisa.py +0 -0
  18. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/flattrade.py +0 -0
  19. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/ft_utils/__init__.py +0 -0
  20. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/ft_utils/flattrade_utils.py +0 -0
  21. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/ft_utils/ft_noren.py +0 -0
  22. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/generics/__init__.py +0 -0
  23. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/generics/broker.py +0 -0
  24. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/iifl_xts.py +0 -0
  25. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/kite_utils.py +0 -0
  26. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/kotak.py +0 -0
  27. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/motilal.py +0 -0
  28. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/noren.py +0 -0
  29. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/shoonya.py +0 -0
  30. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/uplink/__init__.py +0 -0
  31. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/uplink/uplink_utils.py +0 -0
  32. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/upstox.py +0 -0
  33. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/xts.py +0 -0
  34. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/xts_utils/Connect.py +0 -0
  35. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/xts_utils/Exception.py +0 -0
  36. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/xts_utils/InteractiveSocketClient.py +0 -0
  37. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/xts_utils/__init__.py +0 -0
  38. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/broker/zerodha.py +0 -0
  39. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/exception/__init__.py +0 -0
  40. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/exception/exceptions.py +0 -0
  41. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/model/__init__.py +0 -0
  42. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/model/broker.py +0 -0
  43. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/model/generics.py +0 -0
  44. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/model/instrument_data.py +0 -0
  45. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/model/order_event.py +0 -0
  46. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/py.typed +0 -0
  47. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/utils/__init__.py +0 -0
  48. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/utils/caching.py +0 -0
  49. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/utils/constant.py +0 -0
  50. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/utils/exchange.py +0 -0
  51. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/utils/number_utils.py +0 -0
  52. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/utils/pickle_utils.py +0 -0
  53. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/utils/selenium_utils.py +0 -0
  54. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/wrapper/__init__.py +0 -0
  55. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/wrapper/aws/__init__.py +0 -0
  56. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay/wrapper/aws/s3.py +0 -0
  57. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay.egg-info/SOURCES.txt +0 -0
  58. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay.egg-info/dependency_links.txt +0 -0
  59. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay.egg-info/requires.txt +0 -0
  60. {quantplay-2.0.53 → quantplay-2.0.54}/quantplay.egg-info/top_level.txt +0 -0
  61. {quantplay-2.0.53 → quantplay-2.0.54}/setup.cfg +0 -0
  62. {quantplay-2.0.53 → quantplay-2.0.54}/tests/__init__.py +0 -0
  63. {quantplay-2.0.53 → quantplay-2.0.54}/tests/conftest.py +0 -0
  64. {quantplay-2.0.53 → quantplay-2.0.54}/tests/wrapper/__init__.py +0 -0
  65. {quantplay-2.0.53 → quantplay-2.0.54}/tests/wrapper/aws/__init__.py +0 -0
  66. {quantplay-2.0.53 → quantplay-2.0.54}/tests/wrapper/aws/s3_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantplay
3
- Version: 2.0.53
3
+ Version: 2.0.54
4
4
  Summary: This python package will be stored in AWS CodeArtifact
5
5
  Home-page:
6
6
  Author:
@@ -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}*")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantplay
3
- Version: 2.0.53
3
+ Version: 2.0.54
4
4
  Summary: This python package will be stored in AWS CodeArtifact
5
5
  Home-page:
6
6
  Author:
@@ -21,7 +21,7 @@ requirements = [
21
21
  setup(
22
22
  name="quantplay",
23
23
  long_description=Path("README.md").read_text(),
24
- version="2.0.53",
24
+ version="2.0.54",
25
25
  setup_requires=["pytest-runner"],
26
26
  install_requires=requirements,
27
27
  tests_require=[],
@@ -1,282 +0,0 @@
1
- import os
2
- import traceback
3
- from dataclasses import dataclass
4
- from typing import Any, Dict
5
-
6
- from quantplay.broker.aliceblue import Aliceblue
7
- from quantplay.broker.angelone import AngelOne
8
- from quantplay.broker.dhan import Dhan
9
- from quantplay.broker.five_paisa import FivePaisa
10
- from quantplay.broker.flattrade import FlatTrade
11
- from quantplay.broker.iifl_xts import IIFL as IIFL_XTS
12
- from quantplay.broker.kotak import Kotak
13
- from quantplay.broker.motilal import Motilal
14
- from quantplay.broker.shoonya import FinvAsia
15
- from quantplay.broker.upstox import Upstox
16
- from quantplay.broker.zerodha import Zerodha
17
- from quantplay.exception.exceptions import InvalidArgumentException
18
- from quantplay.utils.caching import InstrumentCache
19
- from quantplay.utils.pickle_utils import PickleUtils
20
-
21
-
22
- BrokerType = (
23
- Aliceblue
24
- | AngelOne
25
- | FlatTrade
26
- | Motilal
27
- | FinvAsia
28
- | Upstox
29
- | Zerodha
30
- | IIFL_XTS
31
- | FivePaisa
32
- | Kotak
33
- | Dhan
34
- )
35
-
36
- instrument_cache = InstrumentCache()
37
-
38
-
39
- @dataclass
40
- class Broker:
41
- ZERODHA = "Zerodha"
42
- UPSTOX = "Upstox"
43
- ALICEBLUE = "Aliceblue"
44
- FIVEPAISA_OPENAPI = "5Paisa_OpenAPI"
45
- FINVASIA = "Finvasia"
46
- FLATTRADE = "Flattrade"
47
- IIFL_XTS = "IIFL_XTS"
48
- MOTILAL = "Motilal"
49
- ANGELONE = "Angelone"
50
- KOTAK = "Kotak"
51
- DHAN = "Dhan"
52
-
53
-
54
- class BrokerFactory:
55
- broker_instruments_map = {
56
- Broker.ZERODHA: "zerodha_instruments",
57
- Broker.FINVASIA: "shoonya_instruments",
58
- Broker.FLATTRADE: "shoonya_instruments",
59
- Broker.IIFL_XTS: "xts_instruments",
60
- Broker.MOTILAL: "motilal_instruments",
61
- Broker.ANGELONE: "angelone_instruments",
62
- Broker.ALICEBLUE: "aliceblue_instruments",
63
- Broker.UPSTOX: "upstox_instruments",
64
- Broker.FIVEPAISA_OPENAPI: "5paisa_instruments",
65
- Broker.KOTAK: "upstox_instruments",
66
- }
67
- broker_required_args = {
68
- Broker.ZERODHA: set(["user_id", "zerodha_wrapper"]),
69
- Broker.FINVASIA: set(["user_id", "user_token"]),
70
- Broker.FLATTRADE: set(["user_id", "user_token"]),
71
- Broker.IIFL_XTS: set(["user_id", "wrapper", "md_wrapper"]),
72
- Broker.MOTILAL: set(["user_id", "headers"]),
73
- Broker.ALICEBLUE: set(["user_id", "client"]),
74
- Broker.UPSTOX: set(["user_id", "access_token"]),
75
- Broker.DHAN: set(["user_id", "access_token"]),
76
- Broker.FIVEPAISA_OPENAPI: set(["user_id", "client"]),
77
- Broker.ANGELONE: set(
78
- [
79
- "user_id",
80
- "api_key",
81
- "access_token",
82
- "refresh_token",
83
- "feed_token",
84
- ]
85
- ),
86
- Broker.KOTAK: set(["user_id", "configuration"]),
87
- }
88
-
89
- def __init__(self):
90
- self.client_broker_data: Dict[str, BrokerType] = {}
91
-
92
- def get_broker_key(self, username: str, broker_name: str) -> str:
93
- return f"{username}:{broker_name}"
94
-
95
- def validate_broker_args(self, broker_info: Dict[str, Any]):
96
- broker = broker_info["broker"]
97
- broker_data = broker_info["broker_data"]
98
-
99
- if broker not in self.broker_required_args.keys():
100
- raise InvalidArgumentException(f"Unsupported Broker: '{broker}'")
101
-
102
- if not self.broker_required_args[broker].issubset(broker_data.keys()):
103
- raise InvalidArgumentException(
104
- f"Missing Arguments for {broker_info['username']}:{broker_info['nickname']} in broker '{broker}' -> {self.broker_required_args[broker].difference(broker_info.keys())}"
105
- )
106
-
107
- def store_broker_client(
108
- self, broker_info: Dict[str, Any], load_instrument: bool = True
109
- ) -> BrokerType | None:
110
- username = broker_info["username"]
111
- nickname = broker_info["nickname"]
112
-
113
- broker_key = self.get_broker_key(username, nickname)
114
-
115
- broker_data = broker_info["broker_data"]
116
- broker = broker_info["broker"]
117
-
118
- broker_client: BrokerType | None = None
119
-
120
- if broker == Broker.MOTILAL:
121
- broker_client = Motilal(
122
- headers=broker_data["headers"],
123
- load_instrument=load_instrument,
124
- )
125
-
126
- if broker == Broker.DHAN:
127
- broker_client = Dhan(
128
- user_id=broker_data["user_id"],
129
- access_token=broker_data["access_token"],
130
- load_instrument=load_instrument,
131
- )
132
-
133
- if broker == Broker.KOTAK:
134
- broker_client = Kotak(
135
- configuration=broker_data["configuration"],
136
- load_instrument=load_instrument,
137
- )
138
- elif broker == Broker.ZERODHA:
139
- broker_client = Zerodha(
140
- wrapper=broker_data["zerodha_wrapper"],
141
- load_instrument=load_instrument,
142
- )
143
-
144
- elif broker == Broker.ANGELONE:
145
- broker_client = AngelOne(
146
- user_id=broker_data["user_id"],
147
- api_key=broker_data["api_key"],
148
- access_token=broker_data["access_token"],
149
- refresh_token=broker_data["refresh_token"],
150
- feed_token=broker_data["feed_token"],
151
- load_instrument=load_instrument,
152
- )
153
-
154
- elif broker == Broker.ALICEBLUE:
155
- broker_client = Aliceblue(
156
- client=broker_data["client"],
157
- load_instrument=load_instrument,
158
- )
159
-
160
- elif broker == Broker.UPSTOX:
161
- broker_client = Upstox(
162
- access_token=broker_data["access_token"],
163
- user_id=broker_data["user_id"],
164
- load_instrument=load_instrument,
165
- )
166
-
167
- elif broker == Broker.FINVASIA:
168
- broker_client = FinvAsia(
169
- user_id=broker_data["user_id"],
170
- user_token=broker_data["user_token"],
171
- load_instrument=load_instrument,
172
- )
173
-
174
- elif broker == Broker.FLATTRADE:
175
- broker_client = FlatTrade(
176
- user_id=broker_data["user_id"],
177
- user_token=broker_data["user_token"],
178
- load_instrument=load_instrument,
179
- )
180
-
181
- elif broker == Broker.FIVEPAISA_OPENAPI:
182
- broker_client = FivePaisa(
183
- client=broker_data["client"],
184
- load_instrument=load_instrument,
185
- )
186
-
187
- elif broker == Broker.IIFL_XTS:
188
- broker_client = IIFL_XTS(
189
- wrapper=broker_data["wrapper"],
190
- md_wrapper=broker_data["md_wrapper"],
191
- client_id=broker_data["user_id"],
192
- load_instrument=load_instrument,
193
- )
194
-
195
- else:
196
- raise InvalidArgumentException(f"Broker '{broker}' not supported")
197
-
198
- if not load_instrument:
199
- broker_client = self.set_broker_instruments(
200
- broker_name=broker, broker=broker_client
201
- )
202
-
203
- broker_client.username = broker_info["username"]
204
- broker_client.nickname = broker_info["nickname"]
205
- broker_client.broker_name = broker_info["broker"]
206
- broker_client.user_id = broker_data["user_id"]
207
-
208
- self.client_broker_data[broker_key] = broker_client
209
-
210
- return broker_client
211
-
212
- def get_broker_client(self, broker_info: Dict[str, Any]) -> BrokerType:
213
- username = broker_info["username"]
214
- nickname = broker_info["nickname"]
215
-
216
- broker_key = self.get_broker_key(username, nickname)
217
-
218
- if broker_key in self.client_broker_data:
219
- return self.client_broker_data[broker_key]
220
-
221
- self.validate_broker_args(broker_info)
222
- broker_client = self.store_broker_client(broker_info, load_instrument=False)
223
-
224
- if broker_client is not None:
225
- return broker_client
226
- else:
227
- raise InvalidArgumentException("Invalid broker API configuration")
228
-
229
- def set_broker_instruments(self, broker_name: str, broker: BrokerType) -> BrokerType:
230
- symbol_data_key = f"{broker_name}_instruments"
231
- quantplay_symbol_key = f"{broker_name}_qplay_symbols"
232
- broker_symbol_key = f"{broker_name}_broker_symbols"
233
-
234
- symbol_data = instrument_cache.get(symbol_data_key)
235
- quantplay_symbol_map = instrument_cache.get(quantplay_symbol_key)
236
- broker_symbol_map = instrument_cache.get(broker_symbol_key)
237
-
238
- if symbol_data is not None:
239
- broker.symbol_data = symbol_data
240
-
241
- if broker_name != "Zerodha":
242
- if quantplay_symbol_map is not None and broker_symbol_map is not None:
243
- broker.quantplay_symbol_map = quantplay_symbol_map
244
- broker.broker_symbol_map = broker_symbol_map
245
-
246
- else:
247
- broker.initialize_broker_symbol_map()
248
- instrument_cache.set(
249
- quantplay_symbol_key, broker.quantplay_symbol_map
250
- )
251
- instrument_cache.set(broker_symbol_key, broker.broker_symbol_map)
252
-
253
- return broker
254
-
255
- try:
256
- symbol_data = PickleUtils.load_data(
257
- BrokerFactory.broker_instruments_map[broker_name]
258
- )
259
- broker.symbol_data = symbol_data
260
-
261
- if broker_name != "Zerodha":
262
- broker.initialize_broker_symbol_map()
263
- instrument_cache.set(quantplay_symbol_key, broker.quantplay_symbol_map)
264
-
265
- instrument_cache.set(symbol_data_key, symbol_data)
266
-
267
- except Exception:
268
- traceback.print_exc()
269
-
270
- if broker_name != "Zerodha":
271
- broker.load_instrument(BrokerFactory.broker_instruments_map[broker_name])
272
- else:
273
- broker.initialize_symbol_data()
274
-
275
- return broker
276
-
277
- def clear_instrument_cache(self, broker: str) -> None:
278
- symbol_data_key = f"{broker}_instruments"
279
- instrument_cache.delete(symbol_data_key)
280
-
281
- file_name = self.broker_instruments_map[broker]
282
- os.system(f"rm /tmp/{file_name}*")
File without changes
File without changes
File without changes
File without changes
File without changes