quantplay 2.0.181__tar.gz → 2.0.183__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 (81) hide show
  1. {quantplay-2.0.181 → quantplay-2.0.183}/PKG-INFO +1 -1
  2. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/kotak.py +2 -2
  3. quantplay-2.0.183/quantplay/broker/kotak_utils/kotak_ws.py +93 -0
  4. quantplay-2.0.183/quantplay/broker/kotak_utils/kotak_ws_lib.py +142 -0
  5. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay.egg-info/PKG-INFO +1 -1
  6. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay.egg-info/SOURCES.txt +3 -0
  7. {quantplay-2.0.181 → quantplay-2.0.183}/setup.py +1 -1
  8. quantplay-2.0.183/tests/wrapper/aws/__init__.py +0 -0
  9. {quantplay-2.0.181 → quantplay-2.0.183}/README.md +0 -0
  10. {quantplay-2.0.181 → quantplay-2.0.183}/pyproject.toml +0 -0
  11. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/__init__.py +0 -0
  12. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/__init__.py +0 -0
  13. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/aliceblue.py +0 -0
  14. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/angelone.py +0 -0
  15. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/auto_login/__init__.py +0 -0
  16. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/auto_login/aliceblue.py +0 -0
  17. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/breeze/__init__.py +0 -0
  18. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/breeze/breeze_utils.py +0 -0
  19. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/broker_factory.py +0 -0
  20. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/dhan.py +0 -0
  21. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/finvasia_utils/__init__.py +0 -0
  22. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/finvasia_utils/fa_noren.py +0 -0
  23. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/five_paisa.py +0 -0
  24. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/flattrade.py +0 -0
  25. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/ft_utils/__init__.py +0 -0
  26. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/ft_utils/flattrade_utils.py +0 -0
  27. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/ft_utils/ft_noren.py +0 -0
  28. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/generics/__init__.py +0 -0
  29. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/generics/broker.py +0 -0
  30. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/icici_direct.py +0 -0
  31. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/iifl_xts.py +0 -0
  32. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/jainam_xts.py +0 -0
  33. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/kite_utils.py +0 -0
  34. {quantplay-2.0.181/quantplay/broker/uplink → quantplay-2.0.183/quantplay/broker/kotak_utils}/__init__.py +0 -0
  35. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/motilal.py +0 -0
  36. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/noren.py +0 -0
  37. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/shoonya.py +0 -0
  38. {quantplay-2.0.181/quantplay/broker/xts_utils → quantplay-2.0.183/quantplay/broker/uplink}/__init__.py +0 -0
  39. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/uplink/uplink_utils.py +0 -0
  40. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/upstox.py +0 -0
  41. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/xts.py +0 -0
  42. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/xts_utils/Connect.py +0 -0
  43. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/xts_utils/Exception.py +0 -0
  44. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/xts_utils/InteractiveSocketClient.py +0 -0
  45. {quantplay-2.0.181/quantplay/core → quantplay-2.0.183/quantplay/broker/xts_utils}/__init__.py +0 -0
  46. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/broker/zerodha.py +0 -0
  47. {quantplay-2.0.181/quantplay/indicator → quantplay-2.0.183/quantplay/core}/__init__.py +0 -0
  48. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/core/strategy.py +0 -0
  49. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/exception/__init__.py +0 -0
  50. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/exception/exceptions.py +0 -0
  51. {quantplay-2.0.181/quantplay/model → quantplay-2.0.183/quantplay/indicator}/__init__.py +0 -0
  52. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/indicator/iv.py +0 -0
  53. {quantplay-2.0.181/quantplay/strategy → quantplay-2.0.183/quantplay/model}/__init__.py +0 -0
  54. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/model/broker.py +0 -0
  55. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/model/broker_response.py +0 -0
  56. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/model/generics.py +0 -0
  57. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/model/instrument_data.py +0 -0
  58. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/model/order_event.py +0 -0
  59. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/py.typed +0 -0
  60. {quantplay-2.0.181/quantplay/wrapper → quantplay-2.0.183/quantplay/strategy}/__init__.py +0 -0
  61. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/strategy/iv_spike.py +0 -0
  62. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/strategy/obuy.py +0 -0
  63. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/utils/__init__.py +0 -0
  64. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/utils/caching.py +0 -0
  65. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/utils/constant.py +0 -0
  66. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/utils/exchange.py +0 -0
  67. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/utils/number_utils.py +0 -0
  68. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/utils/pickle_utils.py +0 -0
  69. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/utils/selenium_utils.py +0 -0
  70. {quantplay-2.0.181/quantplay/wrapper/aws → quantplay-2.0.183/quantplay/wrapper}/__init__.py +0 -0
  71. {quantplay-2.0.181/tests → quantplay-2.0.183/quantplay/wrapper/aws}/__init__.py +0 -0
  72. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/wrapper/aws/s3.py +0 -0
  73. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay/wrapper/redis.py +0 -0
  74. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay.egg-info/dependency_links.txt +0 -0
  75. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay.egg-info/requires.txt +0 -0
  76. {quantplay-2.0.181 → quantplay-2.0.183}/quantplay.egg-info/top_level.txt +0 -0
  77. {quantplay-2.0.181 → quantplay-2.0.183}/setup.cfg +0 -0
  78. {quantplay-2.0.181/tests/wrapper → quantplay-2.0.183/tests}/__init__.py +0 -0
  79. {quantplay-2.0.181 → quantplay-2.0.183}/tests/conftest.py +0 -0
  80. {quantplay-2.0.181/tests/wrapper/aws → quantplay-2.0.183/tests/wrapper}/__init__.py +0 -0
  81. {quantplay-2.0.181 → quantplay-2.0.183}/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.181
3
+ Version: 2.0.183
4
4
  Summary: This python package will be stored in AWS CodeArtifact
5
5
  Home-page:
6
6
  Author:
@@ -587,12 +587,12 @@ class Kotak(Broker):
587
587
  return order_type_map.get(order_type, order_type) # type:ignore
588
588
 
589
589
  def get_quantplay_order_status(self, status: str) -> OrderStatusType:
590
- if status in ["put order req received", "validation pending", "open pending"]:
590
+ if status in ["put order req received", "validation pending", "open pending", "modify pending", "modify validation pending"]:
591
591
  return "OPEN"
592
592
  if status == "cancel pending":
593
593
  return "CANCELLED"
594
594
  status = status.upper()
595
- if status not in ["OPEN", "TRIGGER_PENDING", "CANCELLED", "REJECTED"]:
595
+ if status not in ["OPEN", "TRIGGER PENDING", "CANCELLED", "REJECTED", "COMPLETE"]:
596
596
  Constants.logger.error(f"{status} not supported for Kotak")
597
597
  return "INVALID STATUS" # type:ignore
598
598
  return status # type:ignore
@@ -0,0 +1,93 @@
1
+ from collections.abc import Callable
2
+ import json
3
+ import threading
4
+ import time
5
+ from typing import Any
6
+
7
+ from quantplay.broker.kotak_utils.kotak_ws_lib import HSIWebSocket
8
+
9
+
10
+ ORDER_FEED_URL = "wss://clhsi.kotaksecurities.com/realtime?sId={server_id}"
11
+
12
+
13
+ class NeoWebSocket:
14
+ def __init__(self, sid: str | None, token: str | None, server_id: str | None):
15
+ self.hsiWebsocket = None
16
+ self.is_hsi_open = 0
17
+ self.sid = sid
18
+ self.access_token = token
19
+ self.server_id = server_id
20
+ self.on_message: Callable[[Any], None] | None = None
21
+ self.on_error: Callable[[Any], None] | None = None
22
+ self.on_close: Callable[[], None] | None = None
23
+ self.on_open: Callable[[], None] | None = None
24
+ self.hsi_thread = None
25
+
26
+ def on_hsi_open(self):
27
+ server = "WEB"
28
+ json_d = {
29
+ "type": "CONNECTION",
30
+ "Authorization": self.access_token,
31
+ "Sid": self.sid,
32
+ "source": server,
33
+ }
34
+ json_d = json.dumps(json_d)
35
+
36
+ if self.hsiWebsocket:
37
+ self.hsiWebsocket.send(json_d)
38
+
39
+ if self.on_open:
40
+ self.on_open()
41
+
42
+ def on_hsi_close(self):
43
+ if self.is_hsi_open == 1:
44
+ self.is_hsi_open = 0
45
+ if self.on_close:
46
+ self.on_close()
47
+
48
+ def on_hsi_error(self, error: Any):
49
+ if self.is_hsi_open == 1:
50
+ self.is_hsi_open = 0
51
+
52
+ if self.on_error:
53
+ self.on_error(error)
54
+ else:
55
+ print("Error Occurred in Websocket! Error Message ", error)
56
+
57
+ def on_hsi_message(self, message: Any):
58
+ if message:
59
+ if isinstance(message, str):
60
+ req = json.loads(message)
61
+ if req["type"] == "cn":
62
+ self.is_hsi_open = 1
63
+ threading.Thread(target=self.start_hsi_ping_thread).start()
64
+
65
+ if self.on_message:
66
+ self.on_message({"type": "order_feed", "data": message})
67
+
68
+ def start_hsi_ping_thread(self):
69
+ while self.hsiWebsocket and self.is_hsi_open:
70
+ time.sleep(30)
71
+ payload = {"type": "HB"}
72
+ self.hsiWebsocket.send(json.dumps(payload))
73
+
74
+ def start_hsi_websocket(self):
75
+ url = ORDER_FEED_URL.format(server_id=self.server_id)
76
+ self.hsiWebsocket = HSIWebSocket()
77
+ self.hsiWebsocket.open_connection(
78
+ url=url,
79
+ onopen=self.on_hsi_open,
80
+ onmessage=self.on_hsi_message,
81
+ onclose=self.on_hsi_close,
82
+ onerror=self.on_hsi_error,
83
+ )
84
+
85
+ def start_hsi_websocket_thread(self):
86
+ self.hsi_thread = threading.Thread(target=self.start_hsi_websocket)
87
+ self.hsi_thread.start()
88
+
89
+ def get_order_feed(self):
90
+ if self.hsiWebsocket is None or self.is_hsi_open == 0:
91
+ self.start_hsi_websocket_thread()
92
+ else:
93
+ print("you had already subscribed for order feed")
@@ -0,0 +1,142 @@
1
+ from collections.abc import Callable
2
+ import json
3
+ import ssl
4
+ from typing import Any
5
+
6
+ import websocket
7
+
8
+
9
+ class StartHSIServer:
10
+ def __init__(
11
+ self,
12
+ url: str,
13
+ onopen: Callable[[], None],
14
+ onmessage: Callable[[Any], None],
15
+ onerror: Callable[[Any], None],
16
+ onclose: Callable[[], None],
17
+ ):
18
+ self.openState = None
19
+ self.readyState = None
20
+ self.url = url
21
+ self.onopen = onopen
22
+ self.onmessage = onmessage
23
+ self.onerror = onerror
24
+ self.onclose = onclose
25
+ # self.token, self.sid = token, sid
26
+ global hsiWs
27
+ try:
28
+ # websocket.enableTrace(True)
29
+ hsiWs = websocket.WebSocketApp(
30
+ self.url,
31
+ on_open=self.on_open,
32
+ on_message=self.on_message,
33
+ on_error=self.on_error,
34
+ on_close=self.on_close,
35
+ )
36
+ hsiWs.run_forever( # type: ignore
37
+ ping_interval=5, reconnect=5, sslopt={"cert_reqs": ssl.CERT_NONE}
38
+ )
39
+ except Exception:
40
+ print("WebSocket not supported!")
41
+
42
+ def on_message(self, ws: websocket.WebSocket, message: Any):
43
+ # print("Received message:", message)
44
+ self.onmessage(message)
45
+
46
+ def on_error(self, ws: websocket.WebSocket, error: Any):
47
+ print("Error:", error)
48
+ self.onerror(error)
49
+
50
+ def on_close(self, ws: websocket.WebSocket, close_status_code: Any, close_msg: Any):
51
+ # print("Connection closed")
52
+ self.openState = 0
53
+ self.readyState = 0
54
+ if hsiWs:
55
+ hsiWs.close() # type: ignore
56
+ self.onclose()
57
+
58
+ def on_open(self, ws: websocket.WebSocket):
59
+ # print("Connection established HSWebSocket")
60
+ self.openState = 1
61
+ self.readyState = 1
62
+ self.onopen()
63
+
64
+
65
+ class HSIWebSocket:
66
+ def __init__(self):
67
+ # self.hsiWs = None
68
+ self.hsiSocket = None
69
+ self.reqData = None
70
+ self.openState = 0
71
+ self.readyState = 0
72
+ self.url = None
73
+ self.onopen = None
74
+ self.onmessage = None
75
+ self.onclose = None
76
+ self.onerror = None
77
+ # self.token, self.sid = token, sid
78
+
79
+ def open_connection(
80
+ self,
81
+ url: str,
82
+ onopen: Callable[[], None],
83
+ onmessage: Callable[[Any], None],
84
+ onerror: Callable[[Any], None],
85
+ onclose: Callable[[], None],
86
+ ):
87
+ self.url = url
88
+ self.onopen = onopen
89
+ self.onmessage = onmessage
90
+ self.onclose = onclose
91
+ self.onerror = onerror
92
+ StartHSIServer(self.url, self.onopen, self.onmessage, self.onerror, self.onclose)
93
+
94
+ def send(self, d: Any):
95
+ reqJson = json.loads(d)
96
+ req = None
97
+ if reqJson["type"] == "CONNECTION":
98
+ if "Authorization" in reqJson and "Sid" in reqJson and "source" in reqJson:
99
+ req = {
100
+ "type": "cn",
101
+ "Authorization": reqJson["Authorization"],
102
+ "Sid": reqJson["Sid"],
103
+ "src": reqJson["source"],
104
+ }
105
+ self.reqData = req
106
+ else:
107
+ if "x-access-token" in reqJson and "src" in reqJson:
108
+ req = {
109
+ "type": "cn",
110
+ "x-access-token": reqJson["x-access-token"],
111
+ "source": reqJson["source"],
112
+ }
113
+ self.reqData = req
114
+ else:
115
+ print("Invalid connection mode !")
116
+
117
+ elif reqJson["type"] == "HB":
118
+ # self.reqData=reqJson
119
+ req = {"type": "hb"}
120
+ self.reqData = req
121
+
122
+ else:
123
+ if reqJson["type"] == "FORCE_CONNECTION":
124
+ self.reqData = self.reqData["type"] = "fcn" # type: ignore
125
+ req = self.reqData
126
+ else:
127
+ print("Invalid Request !")
128
+
129
+ if hsiWs and req:
130
+ js_obj = json.dumps(req)
131
+ hsiWs.send(js_obj)
132
+ else:
133
+ print(
134
+ "Unable to send request! Reason: Connection faulty or request not valid!"
135
+ )
136
+
137
+ def close(self):
138
+ self.openState = 0
139
+ self.readyState = 0
140
+
141
+ if hsiWs:
142
+ hsiWs.close() # type: ignore
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantplay
3
- Version: 2.0.181
3
+ Version: 2.0.183
4
4
  Summary: This python package will be stored in AWS CodeArtifact
5
5
  Home-page:
6
6
  Author:
@@ -37,6 +37,9 @@ quantplay/broker/ft_utils/flattrade_utils.py
37
37
  quantplay/broker/ft_utils/ft_noren.py
38
38
  quantplay/broker/generics/__init__.py
39
39
  quantplay/broker/generics/broker.py
40
+ quantplay/broker/kotak_utils/__init__.py
41
+ quantplay/broker/kotak_utils/kotak_ws.py
42
+ quantplay/broker/kotak_utils/kotak_ws_lib.py
40
43
  quantplay/broker/uplink/__init__.py
41
44
  quantplay/broker/uplink/uplink_utils.py
42
45
  quantplay/broker/xts_utils/Connect.py
@@ -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.181",
24
+ version="2.0.183",
25
25
  setup_requires=["pytest-runner"],
26
26
  install_requires=requirements,
27
27
  tests_require=[],
File without changes
File without changes
File without changes
File without changes