quantplay 2.0.164__tar.gz → 2.0.166__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.
- {quantplay-2.0.164 → quantplay-2.0.166}/PKG-INFO +1 -1
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/broker_factory.py +2 -1
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/kotak.py +40 -40
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/noren.py +6 -3
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/shoonya.py +1 -1
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay.egg-info/PKG-INFO +1 -1
- {quantplay-2.0.164 → quantplay-2.0.166}/setup.py +1 -1
- {quantplay-2.0.164 → quantplay-2.0.166}/README.md +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/pyproject.toml +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/aliceblue.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/angelone.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/auto_login/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/auto_login/aliceblue.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/breeze/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/breeze/breeze_utils.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/dhan.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/finvasia_utils/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/finvasia_utils/fa_noren.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/five_paisa.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/flattrade.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/ft_utils/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/ft_utils/flattrade_utils.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/ft_utils/ft_noren.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/generics/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/generics/broker.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/icici_direct.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/iifl_xts.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/jainam_xts.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/kite_utils.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/motilal.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/uplink/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/uplink/uplink_utils.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/upstox.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/xts.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/xts_utils/Connect.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/xts_utils/Exception.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/xts_utils/InteractiveSocketClient.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/xts_utils/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/zerodha.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/exception/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/exception/exceptions.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/model/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/model/broker.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/model/broker_response.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/model/generics.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/model/instrument_data.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/model/order_event.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/py.typed +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/utils/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/utils/caching.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/utils/constant.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/utils/exchange.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/utils/number_utils.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/utils/pickle_utils.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/utils/selenium_utils.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/wrapper/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/wrapper/aws/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay/wrapper/aws/s3.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay.egg-info/SOURCES.txt +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay.egg-info/dependency_links.txt +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay.egg-info/requires.txt +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/quantplay.egg-info/top_level.txt +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/setup.cfg +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/tests/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/tests/conftest.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/tests/wrapper/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/tests/wrapper/aws/__init__.py +0 -0
- {quantplay-2.0.164 → quantplay-2.0.166}/tests/wrapper/aws/s3_test.py +0 -0
|
@@ -188,7 +188,7 @@ class BrokerFactory:
|
|
|
188
188
|
consumer_secret=broker_data["consumer_secret"],
|
|
189
189
|
mobilenumber=broker_data["mobilenumber"],
|
|
190
190
|
password=broker_data["password"],
|
|
191
|
-
|
|
191
|
+
otp=broker_data.get("otp"),
|
|
192
192
|
load_instrument=False,
|
|
193
193
|
)
|
|
194
194
|
|
|
@@ -387,6 +387,7 @@ class BrokerFactory:
|
|
|
387
387
|
elif broker == Broker.KOTAK:
|
|
388
388
|
broker_client = Kotak(
|
|
389
389
|
configuration=broker_data["configuration"],
|
|
390
|
+
otp=broker_data.get("otp"),
|
|
390
391
|
load_instrument=load_instrument,
|
|
391
392
|
)
|
|
392
393
|
elif broker == Broker.ZERODHA:
|
|
@@ -7,6 +7,7 @@ from urllib.parse import urlencode
|
|
|
7
7
|
import polars as pl
|
|
8
8
|
import requests
|
|
9
9
|
import urllib
|
|
10
|
+
import jwt
|
|
10
11
|
|
|
11
12
|
from quantplay.broker.generics.broker import Broker
|
|
12
13
|
from quantplay.model.broker import (
|
|
@@ -44,13 +45,13 @@ class Kotak(Broker):
|
|
|
44
45
|
consumer_secret: str | None = None,
|
|
45
46
|
mobilenumber: str | None = None,
|
|
46
47
|
password: str | None = None,
|
|
47
|
-
|
|
48
|
+
otp: str | None = None,
|
|
48
49
|
configuration: dict[str, str] | None = None,
|
|
49
50
|
load_instrument: bool = True,
|
|
50
|
-
):
|
|
51
|
+
) -> None:
|
|
51
52
|
super().__init__()
|
|
52
53
|
|
|
53
|
-
self.configuration: dict[str, str] = {
|
|
54
|
+
self.configuration: dict[str, str | None] = {
|
|
54
55
|
"fin_key": "X6Nk8cQhUgGmJ2vBdWw4sfzrz4L5En",
|
|
55
56
|
}
|
|
56
57
|
|
|
@@ -60,14 +61,17 @@ class Kotak(Broker):
|
|
|
60
61
|
"bearer_token": configuration["bearer_token"],
|
|
61
62
|
"view_token": configuration["view_token"],
|
|
62
63
|
"sid": configuration["sid"],
|
|
63
|
-
"edit_token": configuration
|
|
64
|
-
"edit_sid": configuration
|
|
65
|
-
"edit_rid": configuration
|
|
66
|
-
"serverId": configuration
|
|
64
|
+
"edit_token": configuration.get("edit_token"),
|
|
65
|
+
"edit_sid": configuration.get("edit_sid"),
|
|
66
|
+
"edit_rid": configuration.get("edit_rid"),
|
|
67
|
+
"serverId": configuration.get("serverId"),
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
elif consumer_key and consumer_secret and mobilenumber and password
|
|
70
|
-
self.login(consumer_key, consumer_secret, mobilenumber, password
|
|
70
|
+
elif consumer_key and consumer_secret and mobilenumber and password:
|
|
71
|
+
self.login(consumer_key, consumer_secret, mobilenumber, password)
|
|
72
|
+
|
|
73
|
+
if otp:
|
|
74
|
+
self.verify_2fa(otp)
|
|
71
75
|
|
|
72
76
|
if load_instrument:
|
|
73
77
|
self.load_instrument()
|
|
@@ -96,8 +100,7 @@ class Kotak(Broker):
|
|
|
96
100
|
consumer_secret: str,
|
|
97
101
|
mobilenumber: str,
|
|
98
102
|
password: str,
|
|
99
|
-
|
|
100
|
-
):
|
|
103
|
+
) -> None:
|
|
101
104
|
base64_string = str(consumer_key) + ":" + str(consumer_secret)
|
|
102
105
|
base64_token = base64_string.encode("ascii")
|
|
103
106
|
|
|
@@ -132,7 +135,29 @@ class Kotak(Broker):
|
|
|
132
135
|
self.configuration["view_token"] = view_token.get("data").get("token")
|
|
133
136
|
self.configuration["sid"] = view_token.get("data").get("sid")
|
|
134
137
|
|
|
135
|
-
|
|
138
|
+
decode_jwt = jwt.decode( # type: ignore
|
|
139
|
+
self.configuration["view_token"], options={"verify_signature": False}
|
|
140
|
+
)
|
|
141
|
+
userid = decode_jwt.get("sub")
|
|
142
|
+
self.kotakUserId = userid
|
|
143
|
+
|
|
144
|
+
generate_otp_resp = requests.post(
|
|
145
|
+
url=f"{PROD_BASE_URL}login/1.0/login/otp/generate",
|
|
146
|
+
headers={"Authorization": "Bearer " + self.configuration["bearer_token"]},
|
|
147
|
+
data=json.dumps({"userId": userid, "sendEmail": True, "isWhitelisted": True}),
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
_generate_otp = json.loads(generate_otp_resp.text)
|
|
151
|
+
|
|
152
|
+
def verify_2fa(self, otp: str) -> None:
|
|
153
|
+
if (
|
|
154
|
+
self.configuration["bearer_token"] is None
|
|
155
|
+
or self.configuration["sid"] is None
|
|
156
|
+
or self.configuration["view_token"] is None
|
|
157
|
+
):
|
|
158
|
+
raise InvalidArgumentException("Missing Params")
|
|
159
|
+
|
|
160
|
+
login_resp = requests.post(
|
|
136
161
|
url=f"{PROD_BASE_URL}login/1.0/login/v2/validate",
|
|
137
162
|
headers={
|
|
138
163
|
"Authorization": "Bearer " + self.configuration["bearer_token"],
|
|
@@ -140,14 +165,9 @@ class Kotak(Broker):
|
|
|
140
165
|
"Auth": self.configuration["view_token"],
|
|
141
166
|
"Content-Type": "application/json",
|
|
142
167
|
},
|
|
143
|
-
data=json.dumps({"
|
|
168
|
+
data=json.dumps({"userId": self.kotakUserId, "otp": otp}),
|
|
144
169
|
)
|
|
145
170
|
|
|
146
|
-
login_resp = requests.post(
|
|
147
|
-
url=f"{PROD_BASE_URL}login/1.0/login/v2/validate",
|
|
148
|
-
headers={"Authorization": "Bearer " + self.configuration["bearer_token"]},
|
|
149
|
-
data=json.dumps({"mobileNumber": mobilenumber, "mpin": mpin}),
|
|
150
|
-
)
|
|
151
171
|
edit_token_resp = json.loads(login_resp.text)
|
|
152
172
|
|
|
153
173
|
if "error" not in edit_token_resp:
|
|
@@ -157,27 +177,7 @@ class Kotak(Broker):
|
|
|
157
177
|
self.configuration["serverId"] = edit_token_resp.get("data").get("hsServerId")
|
|
158
178
|
self.user_id = edit_token_resp.get("data").get("ucc")
|
|
159
179
|
|
|
160
|
-
|
|
161
|
-
# self.configuration["view_token"], options={"verify_signature": False}
|
|
162
|
-
# )
|
|
163
|
-
# userid = decode_jwt.get("sub")
|
|
164
|
-
# self.kotakUserId = userid
|
|
165
|
-
|
|
166
|
-
# generate_otp_resp = requests.post(
|
|
167
|
-
# url=f"{PROD_BASE_URL}login/1.0/login/otp/generate",
|
|
168
|
-
# headers={"Authorization": "Bearer " + self.configuration["bearer_token"]},
|
|
169
|
-
# data=json.dumps({"userId": userid, "sendEmail": True, "isWhitelisted": True}),
|
|
170
|
-
# )
|
|
171
|
-
|
|
172
|
-
# generate_otp = json.loads(generate_otp_resp.text)
|
|
173
|
-
|
|
174
|
-
def get_base64_token(self, consumer_key: str, consumer_secret: str):
|
|
175
|
-
"""The Base64 Token Generation.
|
|
176
|
-
This function will generate the Base64 Token this will be used to generate the Bearer Token.
|
|
177
|
-
Return the Token in a String Format
|
|
178
|
-
"""
|
|
179
|
-
|
|
180
|
-
def order_history(self, order_id: str):
|
|
180
|
+
def order_history(self, order_id: str) -> pl.DataFrame:
|
|
181
181
|
body = {"nOrdNo": order_id}
|
|
182
182
|
order_history = self.request("order_history", body=body)["data"] # type:ignore
|
|
183
183
|
return pl.DataFrame(order_history)
|
|
@@ -591,7 +591,7 @@ class Kotak(Broker):
|
|
|
591
591
|
url = f"{PROD_BASE_URL}{url}"
|
|
592
592
|
|
|
593
593
|
request_headers = {
|
|
594
|
-
"Authorization":
|
|
594
|
+
"Authorization": f'Bearer {self.configuration["bearer_token"]}',
|
|
595
595
|
"Sid": self.configuration["edit_sid"],
|
|
596
596
|
"Auth": self.configuration["edit_token"],
|
|
597
597
|
"neo-fin-key": self.configuration["fin_key"],
|
|
@@ -45,7 +45,7 @@ class Noren(Broker):
|
|
|
45
45
|
self,
|
|
46
46
|
load_instrument: bool = True,
|
|
47
47
|
order_updates: Queue[OrderUpdateEvent] | None = None,
|
|
48
|
-
):
|
|
48
|
+
) -> None:
|
|
49
49
|
super().__init__()
|
|
50
50
|
|
|
51
51
|
self.order_updates = order_updates
|
|
@@ -253,7 +253,7 @@ class Noren(Broker):
|
|
|
253
253
|
f"[PLACE_ORDER_FAILED] {exception_message}"
|
|
254
254
|
)
|
|
255
255
|
|
|
256
|
-
def ltp(self, exchange: ExchangeType, tradingsymbol: str):
|
|
256
|
+
def ltp(self, exchange: ExchangeType, tradingsymbol: str) -> float:
|
|
257
257
|
tradingsymbol = self.get_symbol(tradingsymbol, exchange)
|
|
258
258
|
|
|
259
259
|
try:
|
|
@@ -288,7 +288,7 @@ class Noren(Broker):
|
|
|
288
288
|
"lower_circuit": float(data["lc"]),
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
-
def order_history(self, order_id: str):
|
|
291
|
+
def order_history(self, order_id: str) -> dict[str, str | Any]:
|
|
292
292
|
order_history = self.api.single_order_history(order_id)
|
|
293
293
|
|
|
294
294
|
if order_history is None:
|
|
@@ -406,10 +406,12 @@ class Noren(Broker):
|
|
|
406
406
|
)
|
|
407
407
|
.alias("price")
|
|
408
408
|
)
|
|
409
|
+
print(holdings_df)
|
|
409
410
|
|
|
410
411
|
holdings_df = holdings_df.with_columns(
|
|
411
412
|
pl.col("tradingsymbol").str.replace("-EQ", "").alias("tradingsymbol")
|
|
412
413
|
)
|
|
414
|
+
print(holdings_df)
|
|
413
415
|
|
|
414
416
|
holdings_df = holdings_df.with_columns(
|
|
415
417
|
(pl.col("quantity") * pl.col("price")).alias("value"),
|
|
@@ -418,6 +420,7 @@ class Noren(Broker):
|
|
|
418
420
|
(pl.col("quantity") * pl.col("price")).alias("current_value"),
|
|
419
421
|
((pl.col("price") / pl.col("average_price") - 1) * 100).alias("pct_change"),
|
|
420
422
|
)
|
|
423
|
+
print(holdings_df)
|
|
421
424
|
|
|
422
425
|
return holdings_df[list(self.holidings_schema.keys())].cast(self.holidings_schema)
|
|
423
426
|
|
|
@@ -25,7 +25,7 @@ class FinvAsia(Noren):
|
|
|
25
25
|
vendor_code: str | None = None,
|
|
26
26
|
user_token: str | None = None,
|
|
27
27
|
load_instrument: bool = True,
|
|
28
|
-
):
|
|
28
|
+
) -> None:
|
|
29
29
|
super().__init__(order_updates=order_updates, load_instrument=load_instrument)
|
|
30
30
|
self.api = FA_NorenApi(
|
|
31
31
|
"https://api.shoonya.com/NorenWClientTP/",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{quantplay-2.0.164 → quantplay-2.0.166}/quantplay/broker/xts_utils/InteractiveSocketClient.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|