quantplay 2.1.65__tar.gz → 2.1.67__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 (86) hide show
  1. {quantplay-2.1.65 → quantplay-2.1.67}/PKG-INFO +1 -1
  2. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/angelone_utils/angeloneWS.py +2 -1
  3. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/broker_factory.py +2 -0
  4. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/kotak.py +141 -21
  5. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/kotak_utils/kotak_ws.py +49 -15
  6. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/kotak_utils/kotak_ws_lib.py +15 -8
  7. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay.egg-info/PKG-INFO +1 -1
  8. {quantplay-2.1.65 → quantplay-2.1.67}/setup.py +1 -1
  9. {quantplay-2.1.65 → quantplay-2.1.67}/README.md +0 -0
  10. {quantplay-2.1.65 → quantplay-2.1.67}/pyproject.toml +0 -0
  11. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/__init__.py +0 -0
  12. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/__init__.py +0 -0
  13. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/aliceblue.py +2 -2
  14. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/angelone.py +1 -1
  15. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/angelone_utils/__init__.py +0 -0
  16. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/auto_login/__init__.py +0 -0
  17. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/auto_login/aliceblue.py +0 -0
  18. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/breeze/__init__.py +0 -0
  19. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/breeze/breeze_utils.py +0 -0
  20. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/dhan.py +0 -0
  21. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/finvasia_utils/__init__.py +0 -0
  22. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/finvasia_utils/fa_noren.py +0 -0
  23. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/five_paisa.py +0 -0
  24. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/flattrade.py +0 -0
  25. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/ft_utils/__init__.py +0 -0
  26. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/ft_utils/flattrade_utils.py +0 -0
  27. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/ft_utils/ft_noren.py +0 -0
  28. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/generics/__init__.py +0 -0
  29. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/generics/broker.py +0 -0
  30. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/icici_direct.py +0 -0
  31. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/iifl_xts.py +0 -0
  32. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/jainam_xts.py +0 -0
  33. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/kite_utils.py +0 -0
  34. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/kotak_utils/__init__.py +0 -0
  35. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/motilal.py +0 -0
  36. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/noren.py +0 -0
  37. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/shoonya.py +0 -0
  38. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/uplink/__init__.py +0 -0
  39. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/uplink/uplink_utils.py +0 -0
  40. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/upstox.py +0 -0
  41. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/xts.py +0 -0
  42. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/xts_utils/Connect.py +0 -0
  43. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/xts_utils/Exception.py +0 -0
  44. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/xts_utils/InteractiveSocketClient.py +0 -0
  45. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/xts_utils/__init__.py +0 -0
  46. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/xts_utils_v2/ConnectV2.py +0 -0
  47. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/xts_utils_v2/InteractiveSocketClientV2.py +0 -0
  48. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/xts_utils_v2/__init__.py +0 -0
  49. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/broker/zerodha.py +0 -0
  50. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/core/__init__.py +0 -0
  51. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/core/strategy.py +0 -0
  52. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/exception/__init__.py +0 -0
  53. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/exception/exceptions.py +0 -0
  54. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/indicator/__init__.py +0 -0
  55. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/indicator/iv.py +0 -0
  56. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/model/__init__.py +0 -0
  57. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/model/broker.py +0 -0
  58. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/model/broker_response.py +0 -0
  59. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/model/generics.py +0 -0
  60. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/model/instrument_data.py +0 -0
  61. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/model/order_event.py +0 -0
  62. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/py.typed +0 -0
  63. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/strategy/__init__.py +0 -0
  64. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/strategy/iv_spike.py +0 -0
  65. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/strategy/obuy.py +0 -0
  66. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/utils/__init__.py +0 -0
  67. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/utils/caching.py +0 -0
  68. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/utils/constant.py +0 -0
  69. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/utils/exchange.py +0 -0
  70. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/utils/number_utils.py +0 -0
  71. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/utils/pickle_utils.py +0 -0
  72. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/utils/selenium_utils.py +0 -0
  73. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/wrapper/__init__.py +0 -0
  74. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/wrapper/aws/__init__.py +0 -0
  75. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/wrapper/aws/s3.py +0 -0
  76. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay/wrapper/redis.py +0 -0
  77. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay.egg-info/SOURCES.txt +0 -0
  78. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay.egg-info/dependency_links.txt +0 -0
  79. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay.egg-info/requires.txt +0 -0
  80. {quantplay-2.1.65 → quantplay-2.1.67}/quantplay.egg-info/top_level.txt +0 -0
  81. {quantplay-2.1.65 → quantplay-2.1.67}/setup.cfg +0 -0
  82. {quantplay-2.1.65 → quantplay-2.1.67}/tests/__init__.py +0 -0
  83. {quantplay-2.1.65 → quantplay-2.1.67}/tests/conftest.py +0 -0
  84. {quantplay-2.1.65 → quantplay-2.1.67}/tests/wrapper/__init__.py +0 -0
  85. {quantplay-2.1.65 → quantplay-2.1.67}/tests/wrapper/aws/__init__.py +0 -0
  86. {quantplay-2.1.65 → quantplay-2.1.67}/tests/wrapper/aws/s3_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: quantplay
3
- Version: 2.1.65
3
+ Version: 2.1.67
4
4
  Summary: This python package will be stored in AWS CodeArtifact
5
5
  Home-page:
6
6
  Author:
@@ -1,7 +1,8 @@
1
1
  import ssl
2
- import websocket
3
2
  import time
4
3
 
4
+ import websocket
5
+
5
6
  from quantplay.utils.constant import Constants
6
7
 
7
8
  logger = Constants.logger
@@ -187,6 +187,8 @@ class BrokerFactory:
187
187
  consumer_secret=broker_data["consumer_secret"],
188
188
  mobilenumber=broker_data["mobilenumber"],
189
189
  password=broker_data["password"],
190
+ totp=broker_data.get("totp"),
191
+ mpin=broker_data.get("mpin"),
190
192
  otp=broker_data.get("otp"),
191
193
  load_instrument=False,
192
194
  )
@@ -7,6 +7,7 @@ from urllib.parse import urlencode
7
7
 
8
8
  import jwt
9
9
  import polars as pl
10
+ import pyotp
10
11
  import requests
11
12
  import shortuuid # type:ignore
12
13
 
@@ -48,6 +49,8 @@ class Kotak(Broker):
48
49
  consumer_secret: str | None = None,
49
50
  mobilenumber: str | None = None,
50
51
  password: str | None = None,
52
+ totp: str | None = None,
53
+ mpin: str | None = None,
51
54
  otp: str | None = None,
52
55
  configuration: dict[str, str] | None = None,
53
56
  load_instrument: bool = True,
@@ -55,28 +58,39 @@ class Kotak(Broker):
55
58
  ) -> None:
56
59
  super().__init__()
57
60
 
58
- self.configuration: dict[str, str | None] = {
59
- "fin_key": "X6Nk8cQhUgGmJ2vBdWw4sfzrz4L5En",
60
- }
61
+ self.configuration: dict[str, str | None] = {}
62
+ self.version: Literal["NEW", "OLD"]
61
63
 
62
64
  if configuration:
63
65
  self.configuration = {
64
- "fin_key": "X6Nk8cQhUgGmJ2vBdWw4sfzrz4L5En",
65
- "bearer_token": configuration.get("bearer_token"),
66
- "view_token": configuration.get("view_token"),
67
- "sid": configuration.get("sid"),
68
- "kotakUserId": configuration.get("kotakUserId"),
69
- "edit_token": configuration.get("edit_token"),
70
- "edit_sid": configuration.get("edit_sid"),
71
- "edit_rid": configuration.get("edit_rid"),
72
- "serverId": configuration.get("serverId"),
66
+ "Authorization": self.configuration.get(
67
+ "Authorization", f"Bearer {configuration.get('bearer_token')}"
68
+ ),
69
+ "Sid": self.configuration.get("Sid", configuration.get("edit_sid")),
70
+ "Auth": self.configuration.get("Auth", configuration.get("edit_token")),
71
+ "serverId": self.configuration.get("serverId"),
72
+ **configuration,
73
73
  }
74
74
 
75
75
  if verify_config:
76
76
  self.margins() # To Verify Configuration
77
77
 
78
78
  elif consumer_key and consumer_secret and mobilenumber and password:
79
- self.login(consumer_key, consumer_secret, mobilenumber, password)
79
+ if totp and mpin:
80
+ self.login_v2(
81
+ consumer_key,
82
+ consumer_secret,
83
+ mobilenumber,
84
+ password,
85
+ user_id,
86
+ totp,
87
+ mpin,
88
+ )
89
+ self.version = "NEW"
90
+
91
+ else:
92
+ self.login(consumer_key, consumer_secret, mobilenumber, password)
93
+ self.version = "OLD"
80
94
 
81
95
  if otp:
82
96
  self.verify_2fa(otp)
@@ -106,6 +120,99 @@ class Kotak(Broker):
106
120
 
107
121
  self.initialize_broker_symbol_map()
108
122
 
123
+ def login_v2(
124
+ self,
125
+ consumer_key: str,
126
+ consumer_secret: str,
127
+ mobilenumber: str,
128
+ password: str,
129
+ user_id: str,
130
+ totp: str,
131
+ mpin: str,
132
+ ) -> None:
133
+ # *** Generate Authorization Token via converting consumer_key and consumer_secret into base64 ***
134
+
135
+ base64_string = str(consumer_key) + ":" + str(consumer_secret)
136
+ base64_token = base64_string.encode("ascii")
137
+
138
+ base64_bytes = base64.b64encode(base64_token)
139
+ final_base64_token = base64_bytes.decode("ascii")
140
+
141
+ # *** Generate Access Token ***
142
+
143
+ session_init = requests.post(
144
+ url=f"{SESSION_PROD_BASE_URL}oauth2/token",
145
+ headers={
146
+ "Authorization": "Basic " + final_base64_token,
147
+ "Content-Type": "application/json",
148
+ },
149
+ data=json.dumps({"grant_type": "client_credentials"}),
150
+ )
151
+
152
+ if not session_init.ok:
153
+ raise InvalidArgumentException(json.loads(session_init.content))
154
+
155
+ json_resp = json.loads(session_init.text)
156
+ self.configuration["Authorization"] = f"Bearer {json_resp.get('access_token')}"
157
+
158
+ # *** Generate View Token ***
159
+
160
+ view_token_resp = requests.post(
161
+ url=f"{PROD_BASE_URL}login/1.0/login/v6/totp/login",
162
+ headers={
163
+ "Authorization": self.configuration["Authorization"],
164
+ "neo-fin-key": "neotradeapi",
165
+ "Content-Type": "application/json",
166
+ },
167
+ data=json.dumps(
168
+ {
169
+ "mobileNumber": mobilenumber,
170
+ "ucc": user_id,
171
+ "totp": pyotp.TOTP(str(totp)).now(),
172
+ }
173
+ ),
174
+ )
175
+ view_token = json.loads(view_token_resp.text)
176
+
177
+ view_token_val = view_token.get("data").get("token")
178
+ sid = view_token.get("data").get("sid")
179
+
180
+ # *** Generate Final Login Token ***
181
+
182
+ generate_otp_resp = requests.post(
183
+ url=f"{PROD_BASE_URL}login/1.0/login/v6/totp/validate",
184
+ headers={
185
+ "accept": "application/json",
186
+ "sid": sid,
187
+ "Auth": view_token_val,
188
+ "neo-fin-key": "neotradeapi",
189
+ "Content-Type": "application/json",
190
+ "Authorization": self.configuration["Authorization"],
191
+ },
192
+ data=json.dumps(
193
+ {
194
+ "mobileNumber": mobilenumber,
195
+ "mpin": mpin,
196
+ }
197
+ ),
198
+ )
199
+
200
+ login_resp = json.loads(generate_otp_resp.text)["data"]
201
+
202
+ if login_resp["status"] != "success":
203
+ raise TokenException("Kotak Failed to Login")
204
+
205
+ self.configuration = {
206
+ "Authorization": self.configuration["Authorization"],
207
+ "Sid": login_resp["sid"],
208
+ "Auth": login_resp["token"],
209
+ "serverId": login_resp["hsServerId"],
210
+ "dataCenter": login_resp["dataCenter"],
211
+ # "ucc": login_resp["ucc"],
212
+ # "kId": login_resp["kId"],
213
+ # "kType": login_resp["kType"],
214
+ }
215
+
109
216
  def login(
110
217
  self,
111
218
  consumer_key: str,
@@ -188,7 +295,16 @@ class Kotak(Broker):
188
295
  self.configuration["edit_sid"] = edit_token_resp.get("data").get("sid")
189
296
  self.configuration["edit_rid"] = edit_token_resp.get("data").get("rid")
190
297
  self.configuration["serverId"] = edit_token_resp.get("data").get("hsServerId")
191
- self.user_id = edit_token_resp.get("data").get("ucc")
298
+ # self.user_id = edit_token_resp.get("data").get("ucc")
299
+
300
+ self.configuration = {
301
+ "Authorization": self.configuration.get(
302
+ "Authorization", f"Bearer {self.configuration['bearer_token']}"
303
+ ),
304
+ "Sid": self.configuration.get("Sid", self.configuration["edit_sid"]),
305
+ "Auth": self.configuration.get("Auth", self.configuration["edit_token"]),
306
+ "serverId": self.configuration["serverId"],
307
+ }
192
308
 
193
309
  def order_history(self, order_id: str) -> pl.DataFrame:
194
310
  body = {"nOrdNo": order_id}
@@ -770,10 +886,10 @@ class Kotak(Broker):
770
886
  url = f"{PROD_BASE_URL}{url}"
771
887
 
772
888
  request_headers = {
773
- "Authorization": f"Bearer {self.configuration['bearer_token']}",
774
- "Sid": self.configuration["edit_sid"],
775
- "Auth": self.configuration["edit_token"],
776
- "neo-fin-key": self.configuration["fin_key"],
889
+ "Authorization": self.configuration["Authorization"],
890
+ "Sid": self.configuration["Sid"],
891
+ "Auth": self.configuration["Auth"],
892
+ "neo-fin-key": "neotradeapi",
777
893
  "Content-Type": content_type,
778
894
  "accept": "application/json",
779
895
  }
@@ -882,11 +998,15 @@ class Kotak(Broker):
882
998
  if self.order_updates:
883
999
  self.order_updates.put(quantplay_order)
884
1000
 
885
- def stream_order_data(self):
1001
+ def stream_order_data(self) -> None:
886
1002
  ws = NeoWebSocket(
887
- sid=self.configuration.get("sid", ""),
888
- token=self.configuration.get("edit_token", ""),
1003
+ sid=self.configuration.get("Sid", self.configuration.get("sid", "")),
1004
+ token=self.configuration.get(
1005
+ "Auth", self.configuration.get("edit_token", "")
1006
+ ),
889
1007
  server_id=self.configuration.get("serverId", ""),
1008
+ data_center=self.configuration.get("dataCenter"),
1009
+ version=self.version,
890
1010
  )
891
1011
  ws.on_message = self.event_handler_order_update
892
1012
  ws.on_error = lambda x: print(f"[KOTAK_WS_ERROR]: {self.user_id} {x}")
@@ -2,29 +2,46 @@ import json
2
2
  import threading
3
3
  import time
4
4
  from collections.abc import Callable
5
- from typing import Any
5
+ from typing import Any, Literal
6
6
 
7
7
  from retrying import retry # type: ignore
8
8
 
9
9
  from quantplay.broker.kotak_utils.kotak_ws_lib import HSIWebSocket
10
10
 
11
- ORDER_FEED_URL = "wss://clhsi.kotaksecurities.com/realtime?sId={server_id}"
11
+ OLD_ORDER_FEED_URL = "wss://clhsi.kotaksecurities.com/realtime?sId={server_id}"
12
+
13
+ ORDER_FEED_URL = "wss://mis.kotaksecurities.com/realtime"
14
+ ORDER_FEED_URL_ADC = "wss://cis.kotaksecurities.com/realtime"
15
+ ORDER_FEED_URL_E21 = "wss://e21.kotaksecurities.com/realtime"
16
+ ORDER_FEED_URL_E22 = "wss://e22.kotaksecurities.com/realtime"
17
+ ORDER_FEED_URL_E41 = "wss://e41.kotaksecurities.com/realtime"
18
+ ORDER_FEED_URL_E43 = "wss://e43.kotaksecurities.com/realtime"
12
19
 
13
20
 
14
21
  class NeoWebSocket:
15
- def __init__(self, sid: str | None, token: str | None, server_id: str | None):
22
+ def __init__(
23
+ self,
24
+ sid: str | None,
25
+ token: str | None,
26
+ server_id: str | None,
27
+ data_center: str | None,
28
+ version: Literal["OLD", "NEW"],
29
+ ) -> None:
16
30
  self.hsiWebsocket = None
17
31
  self.is_hsi_open = 0
18
32
  self.sid = sid
19
33
  self.access_token = token
20
34
  self.server_id = server_id
35
+ self.version: Literal["OLD", "NEW"] = version
36
+ self.data_center = data_center
37
+
21
38
  self.on_message: Callable[[Any], None] | None = None
22
39
  self.on_error: Callable[[Any], None] | None = None
23
40
  self.on_close: Callable[[], None] | None = None
24
41
  self.on_open: Callable[[], None] | None = None
25
42
  self.hsi_thread = None
26
43
 
27
- def on_hsi_open(self):
44
+ def on_hsi_open(self) -> None:
28
45
  server = "WEB"
29
46
  json_d = {
30
47
  "type": "CONNECTION",
@@ -34,7 +51,7 @@ class NeoWebSocket:
34
51
  }
35
52
  json_d = json.dumps(json_d)
36
53
 
37
- print(f"[KOTAK_OPEN_SEND]: {json_d}")
54
+ # print(f"[KOTAK_OPEN_SEND]: {json_d}")
38
55
 
39
56
  if self.hsiWebsocket:
40
57
  self.hsiWebsocket.send(json_d)
@@ -42,7 +59,7 @@ class NeoWebSocket:
42
59
  if self.on_open:
43
60
  self.on_open()
44
61
 
45
- def on_hsi_close(self):
62
+ def on_hsi_close(self) -> None:
46
63
  if self.is_hsi_open == 1:
47
64
  self.is_hsi_open = 0
48
65
  self.reconnect()
@@ -55,10 +72,10 @@ class NeoWebSocket:
55
72
  wait_exponential_max=20000,
56
73
  stop_max_attempt_number=5,
57
74
  )
58
- def reconnect(self):
75
+ def reconnect(self) -> None:
59
76
  self.start_hsi_websocket()
60
77
 
61
- def on_hsi_error(self, error: Any):
78
+ def on_hsi_error(self, error: Any) -> None:
62
79
  if self.is_hsi_open == 1:
63
80
  self.is_hsi_open = 0
64
81
 
@@ -67,7 +84,7 @@ class NeoWebSocket:
67
84
  else:
68
85
  print("Error Occurred in Websocket! Error Message ", error)
69
86
 
70
- def on_hsi_message(self, message: Any):
87
+ def on_hsi_message(self, message: Any) -> None:
71
88
  if message:
72
89
  if isinstance(message, str):
73
90
  req = json.loads(message)
@@ -78,15 +95,32 @@ class NeoWebSocket:
78
95
  if self.on_message:
79
96
  self.on_message({"type": "order_feed", "data": message})
80
97
 
81
- def start_hsi_ping_thread(self):
98
+ def start_hsi_ping_thread(self) -> None:
82
99
  while self.hsiWebsocket and self.is_hsi_open:
83
100
  time.sleep(30)
84
101
  payload = {"type": "HB"}
85
102
  self.hsiWebsocket.send(json.dumps(payload))
86
103
 
87
- def start_hsi_websocket(self):
88
- url = ORDER_FEED_URL.format(server_id=self.server_id)
89
- self.hsiWebsocket = HSIWebSocket()
104
+ def start_hsi_websocket(self) -> None:
105
+ if self.version == "NEW":
106
+ url = ORDER_FEED_URL
107
+
108
+ if self.data_center:
109
+ if self.data_center.lower() == "adc":
110
+ url = ORDER_FEED_URL_ADC
111
+ # elif self.data_center.lower() == "e21":
112
+ # url = ORDER_FEED_URL_E21
113
+ # elif self.data_center.lower() == "e22":
114
+ # url = ORDER_FEED_URL_E22
115
+ # elif self.data_center.lower() == "e41":
116
+ # url = ORDER_FEED_URL_E41
117
+ # elif self.data_center.lower() == "e43":
118
+ # url = ORDER_FEED_URL_E43
119
+
120
+ else:
121
+ url = OLD_ORDER_FEED_URL.format(server_id=self.server_id)
122
+
123
+ self.hsiWebsocket = HSIWebSocket(self.version)
90
124
  self.hsiWebsocket.open_connection(
91
125
  url=url,
92
126
  onopen=self.on_hsi_open,
@@ -95,11 +129,11 @@ class NeoWebSocket:
95
129
  onerror=self.on_hsi_error,
96
130
  )
97
131
 
98
- def start_hsi_websocket_thread(self):
132
+ def start_hsi_websocket_thread(self) -> None:
99
133
  self.hsi_thread = threading.Thread(target=self.start_hsi_websocket)
100
134
  self.hsi_thread.start()
101
135
 
102
- def get_order_feed(self):
136
+ def get_order_feed(self) -> None:
103
137
  if self.hsiWebsocket is None or self.is_hsi_open == 0:
104
138
  self.start_hsi_websocket_thread()
105
139
  else:
@@ -14,7 +14,7 @@ class StartHSIServer:
14
14
  onmessage: Callable[[Any], None],
15
15
  onerror: Callable[[Any], None],
16
16
  onclose: Callable[[], None],
17
- ):
17
+ ) -> None:
18
18
  self.openState = None
19
19
  self.readyState = None
20
20
  self.url = url
@@ -39,15 +39,17 @@ class StartHSIServer:
39
39
  except Exception:
40
40
  print("WebSocket not supported!")
41
41
 
42
- def on_message(self, ws: websocket.WebSocket, message: Any):
42
+ def on_message(self, ws: websocket.WebSocket, message: Any) -> None:
43
43
  # print("Received message:", message)
44
44
  self.onmessage(message)
45
45
 
46
- def on_error(self, ws: websocket.WebSocket, error: Any):
46
+ def on_error(self, ws: websocket.WebSocket, error: Any) -> None:
47
47
  print("Error:", error)
48
48
  self.onerror(error)
49
49
 
50
- def on_close(self, ws: websocket.WebSocket, close_status_code: Any, close_msg: Any):
50
+ def on_close(
51
+ self, ws: websocket.WebSocket, close_status_code: Any, close_msg: Any
52
+ ) -> None:
51
53
  # print("Connection closed")
52
54
  self.openState = 0
53
55
  self.readyState = 0
@@ -55,7 +57,7 @@ class StartHSIServer:
55
57
  hsiWs.close() # type: ignore
56
58
  self.onclose()
57
59
 
58
- def on_open(self, ws: websocket.WebSocket):
60
+ def on_open(self, ws: websocket.WebSocket) -> None:
59
61
  # print("Connection established HSWebSocket")
60
62
  self.openState = 1
61
63
  self.readyState = 1
@@ -63,7 +65,7 @@ class StartHSIServer:
63
65
 
64
66
 
65
67
  class HSIWebSocket:
66
- def __init__(self) -> None:
68
+ def __init__(self, version: str) -> None:
67
69
  # self.hsiWs = None
68
70
  self.hsiSocket = None
69
71
  self.reqData = None
@@ -74,6 +76,7 @@ class HSIWebSocket:
74
76
  self.onmessage = None
75
77
  self.onclose = None
76
78
  self.onerror = None
79
+ self.version = version
77
80
  # self.token, self.sid = token, sid
78
81
 
79
82
  def open_connection(
@@ -91,7 +94,7 @@ class HSIWebSocket:
91
94
  self.onerror = onerror
92
95
  StartHSIServer(self.url, self.onopen, self.onmessage, self.onerror, self.onclose)
93
96
 
94
- def send(self, d: Any) -> None:
97
+ def send(self, d: str) -> None:
95
98
  reqJson = json.loads(d)
96
99
  req = None
97
100
 
@@ -115,7 +118,7 @@ class HSIWebSocket:
115
118
  else:
116
119
  print("Invalid connection mode !")
117
120
 
118
- print(f"[KOTAK_OPEN_SEND]: {self.reqData}")
121
+ # print(f"[KOTAK_OPEN_SEND]: {self.reqData}")
119
122
 
120
123
  elif reqJson["type"] == "HB":
121
124
  # self.reqData=reqJson
@@ -131,6 +134,10 @@ class HSIWebSocket:
131
134
 
132
135
  if hsiWs and req:
133
136
  js_obj = json.dumps(req)
137
+
138
+ if self.version == "NEW":
139
+ js_obj = str(js_obj).replace('"', "").replace(" ", "")
140
+
134
141
  hsiWs.send(js_obj)
135
142
  else:
136
143
  print(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: quantplay
3
- Version: 2.1.65
3
+ Version: 2.1.67
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.1.65",
24
+ version="2.1.67",
25
25
  setup_requires=["pytest-runner"],
26
26
  install_requires=requirements,
27
27
  tests_require=[],
File without changes
File without changes
@@ -9,13 +9,13 @@ from queue import Queue
9
9
  from typing import Any, Literal
10
10
 
11
11
  import polars as pl
12
+ import requests
13
+ import websocket # type: ignore
12
14
  from pya3 import Aliceblue as Alice
13
15
  from pya3 import OrderType as AliceOrderType
14
16
  from pya3 import ProductType as AliceProductType
15
17
  from pya3 import TransactionType as AliceTransactionType
16
- import requests
17
18
  from retrying import retry # type: ignore
18
- import websocket # type: ignore
19
19
 
20
20
  from quantplay.broker.generics.broker import Broker
21
21
  from quantplay.exception.exceptions import (
@@ -9,11 +9,11 @@ from typing import Any
9
9
  import logzero # type: ignore
10
10
  import polars as pl
11
11
  import pyotp
12
+ import websocket # type: ignore
12
13
  from requests.exceptions import ConnectionError, ConnectTimeout
13
14
  from retrying import retry # type: ignore
14
15
  from SmartApi import SmartConnect # type: ignore
15
16
  from SmartApi.smartExceptions import DataException # type: ignore
16
- import websocket # type: ignore
17
17
 
18
18
  from quantplay.broker.angelone_utils.angeloneWS import AngelOneOrderUpdateWS
19
19
  from quantplay.broker.generics.broker import Broker
File without changes
File without changes
File without changes