quantplay 2.0.86__tar.gz → 2.0.91__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 (65) hide show
  1. {quantplay-2.0.86 → quantplay-2.0.91}/PKG-INFO +1 -1
  2. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/aliceblue.py +3 -1
  3. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/angelone.py +13 -4
  4. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/dhan.py +1 -0
  5. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/finvasia_utils/fa_noren.py +3 -0
  6. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/five_paisa.py +1 -0
  7. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/ft_utils/ft_noren.py +5 -0
  8. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/kotak.py +1 -0
  9. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/motilal.py +32 -16
  10. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/noren.py +2 -1
  11. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/upstox.py +1 -0
  12. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/xts.py +2 -0
  13. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/zerodha.py +10 -0
  14. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/model/broker.py +1 -0
  15. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay.egg-info/PKG-INFO +1 -1
  16. {quantplay-2.0.86 → quantplay-2.0.91}/setup.py +1 -1
  17. {quantplay-2.0.86 → quantplay-2.0.91}/README.md +0 -0
  18. {quantplay-2.0.86 → quantplay-2.0.91}/pyproject.toml +0 -0
  19. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/__init__.py +0 -0
  20. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/__init__.py +0 -0
  21. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/auto_login/__init__.py +0 -0
  22. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/auto_login/aliceblue.py +0 -0
  23. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/broker_factory.py +0 -0
  24. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/finvasia_utils/__init__.py +0 -0
  25. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/flattrade.py +0 -0
  26. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/ft_utils/__init__.py +0 -0
  27. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/ft_utils/flattrade_utils.py +0 -0
  28. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/generics/__init__.py +0 -0
  29. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/generics/broker.py +0 -0
  30. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/iifl_xts.py +0 -0
  31. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/kite_utils.py +0 -0
  32. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/shoonya.py +0 -0
  33. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/uplink/__init__.py +0 -0
  34. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/uplink/uplink_utils.py +0 -0
  35. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/xts_utils/Connect.py +0 -0
  36. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/xts_utils/Exception.py +0 -0
  37. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/xts_utils/InteractiveSocketClient.py +0 -0
  38. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/broker/xts_utils/__init__.py +0 -0
  39. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/exception/__init__.py +0 -0
  40. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/exception/exceptions.py +0 -0
  41. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/model/__init__.py +0 -0
  42. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/model/generics.py +0 -0
  43. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/model/instrument_data.py +0 -0
  44. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/model/order_event.py +0 -0
  45. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/py.typed +0 -0
  46. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/utils/__init__.py +0 -0
  47. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/utils/caching.py +0 -0
  48. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/utils/constant.py +0 -0
  49. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/utils/exchange.py +0 -0
  50. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/utils/number_utils.py +0 -0
  51. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/utils/pickle_utils.py +0 -0
  52. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/utils/selenium_utils.py +0 -0
  53. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/wrapper/__init__.py +0 -0
  54. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/wrapper/aws/__init__.py +0 -0
  55. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay/wrapper/aws/s3.py +0 -0
  56. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay.egg-info/SOURCES.txt +0 -0
  57. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay.egg-info/dependency_links.txt +0 -0
  58. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay.egg-info/requires.txt +0 -0
  59. {quantplay-2.0.86 → quantplay-2.0.91}/quantplay.egg-info/top_level.txt +0 -0
  60. {quantplay-2.0.86 → quantplay-2.0.91}/setup.cfg +0 -0
  61. {quantplay-2.0.86 → quantplay-2.0.91}/tests/__init__.py +0 -0
  62. {quantplay-2.0.86 → quantplay-2.0.91}/tests/conftest.py +0 -0
  63. {quantplay-2.0.86 → quantplay-2.0.91}/tests/wrapper/__init__.py +0 -0
  64. {quantplay-2.0.86 → quantplay-2.0.91}/tests/wrapper/aws/__init__.py +0 -0
  65. {quantplay-2.0.86 → quantplay-2.0.91}/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.86
3
+ Version: 2.0.91
4
4
  Summary: This python package will be stored in AWS CodeArtifact
5
5
  Home-page:
6
6
  Author:
@@ -328,7 +328,7 @@ class Aliceblue(Broker):
328
328
  "order_id": order_id,
329
329
  "price": price,
330
330
  }
331
- if trigger_price is not None:
331
+ if order_type is not None:
332
332
  data["order_type"] = order_type
333
333
 
334
334
  if trigger_price is not None and trigger_price > 0:
@@ -607,6 +607,7 @@ class Aliceblue(Broker):
607
607
  "margin_used": 0.0,
608
608
  "total_balance": 0.0,
609
609
  "margin_available": 0.0,
610
+ "cash": 0,
610
611
  }
611
612
 
612
613
  margins = [a for a in margins if a["segment"] == "ALL"][0]
@@ -615,6 +616,7 @@ class Aliceblue(Broker):
615
616
  "margin_used": float(margins["debits"]),
616
617
  "total_balance": float(margins["credits"]),
617
618
  "margin_available": float(margins["net"]),
619
+ "cash": 0,
618
620
  }
619
621
 
620
622
  def invoke_aliceblue_api(self, fn: Any, *args: Any, **kwargs: Any) -> Any:
@@ -532,15 +532,24 @@ class AngelOne(Broker):
532
532
  if "errorcode" in api_margins and api_margins["errorcode"] == "AB1004":
533
533
  raise TokenException("Angelone server not not responding")
534
534
 
535
- return {"margin_used": 0.0, "margin_available": 0.0, "total_balance": 0.0}
535
+ return {
536
+ "margin_used": 0.0,
537
+ "margin_available": 0.0,
538
+ "total_balance": 0.0,
539
+ "cash": 0,
540
+ }
536
541
 
537
542
  api_margins = api_margins["data"]
538
543
 
539
544
  try:
545
+ margin_used = float(api_margins["utiliseddebits"])
546
+ margin_available = float(api_margins["net"])
547
+
540
548
  margins: MarginsResponse = {
541
- "margin_used": float(api_margins["net"]),
542
- "margin_available": float(api_margins["net"]),
543
- "total_balance": float(api_margins["net"]),
549
+ "margin_used": margin_used,
550
+ "margin_available": margin_available,
551
+ "cash": float(api_margins["availablecash"]),
552
+ "total_balance": margin_used + margin_available,
544
553
  }
545
554
 
546
555
  return margins
@@ -435,6 +435,7 @@ class Dhan(Broker):
435
435
  "margin_available": margin_available,
436
436
  "margin_used": margin_used,
437
437
  "total_balance": margin_used + margin_available,
438
+ "cash": 0,
438
439
  }
439
440
 
440
441
  def profile(self) -> UserBrokerProfileResponse:
@@ -13,6 +13,7 @@ import requests
13
13
  import websocket
14
14
 
15
15
  from quantplay.model.generics import ExchangeType, NorenTypes
16
+ from quantplay.exception import TokenException
16
17
 
17
18
  logger = logging.getLogger(__name__)
18
19
 
@@ -294,6 +295,8 @@ class FA_NorenApi:
294
295
 
295
296
  self.__username = userid
296
297
  self.__accountid = userid
298
+ if "stat" in resDict and resDict["stat"].lower() == "not_ok":
299
+ raise TokenException(resDict["emsg"])
297
300
  self.__susertoken = resDict["susertoken"]
298
301
 
299
302
  return resDict
@@ -544,6 +544,7 @@ class FivePaisa(Broker):
544
544
  "margin_used": margins["MarginUtilized"],
545
545
  "margin_available": margins["NetAvailableMargin"],
546
546
  "total_balance": margins["NetAvailableMargin"] + margins["MarginUtilized"],
547
+ "cash": 0,
547
548
  }
548
549
 
549
550
  def cancel_order(self, order_id: str, variety: str | None = None) -> None:
@@ -12,6 +12,7 @@ from typing import Any, Callable, Dict, List, Literal, TypedDict
12
12
  import requests
13
13
  import websocket
14
14
 
15
+ from quantplay.exception.exceptions import TokenException
15
16
  from quantplay.model.generics import ExchangeType, NorenTypes
16
17
 
17
18
  logger = logging.getLogger(__name__)
@@ -291,6 +292,10 @@ class FT_NorenApi:
291
292
 
292
293
  self.__username = userid
293
294
  self.__accountid = userid
295
+
296
+ if "stat" in resDict and resDict["stat"].lower() == "not_ok":
297
+ raise TokenException(resDict["emsg"])
298
+
294
299
  self.__susertoken = resDict["susertoken"]
295
300
 
296
301
  return resDict
@@ -192,6 +192,7 @@ class Kotak(Broker):
192
192
  "margin_used": limits_resp["MarginUsed"],
193
193
  "margin_available": limits_resp["Net"],
194
194
  "total_balance": limits_resp["MarginUsed"] + limits_resp["Net"],
195
+ "cash": 0,
195
196
  }
196
197
 
197
198
  # **
@@ -285,38 +285,53 @@ class Motilal(Broker):
285
285
  Constants.logger.info(f"[GET_LTP_RESPONSE] response {response}")
286
286
  return response["data"]["ltp"] / 100.0
287
287
 
288
- def modify_price(
289
- self,
290
- order_id: str,
291
- price: float,
292
- trigger_price: float | None = None,
293
- order_type: OrderTypeType | None = None,
294
- ):
288
+ def add_existing_order_details(self, order_to_modify: Dict[str, str]):
289
+ order_id = order_to_modify["order_id"]
295
290
  orders = self.orders()
296
291
  orders = orders.filter(pl.col("order_id") == order_id)
297
292
 
298
293
  if len(orders) != 1:
299
- Constants.logger.error(
300
- "[ORDER_NOT_FOUND] invalid modify request for {}".format(order_id)
294
+ raise InvalidArgumentException(
295
+ f"Invalid modify request, order_id {order_id} not found"
301
296
  )
302
- return
303
297
 
304
298
  order = orders.to_dicts()[0]
305
299
  order["last_modified_time"] = str(order["last_modified_time"])
306
300
 
307
- order["price"] = price
308
- if trigger_price is not None:
309
- order["trigger_price"] = trigger_price
301
+ if "price" in order_to_modify:
302
+ order["price"] = order_to_modify["price"]
303
+ if (
304
+ "trigger_price" in order_to_modify
305
+ and order_to_modify["trigger_price"] is not None # type:ignore
306
+ ):
307
+ order["trigger_price"] = order_to_modify["trigger_price"]
310
308
 
311
- if order["order_type"] == "SL":
309
+ if "order_type" in order_to_modify and order_to_modify["order_type"] == "SL":
312
310
  order["order_type"] = "STOPLOSS"
313
311
 
314
- print(order)
315
- self.modify_order(order) # type: ignore
312
+ return order
313
+
314
+ def modify_price(
315
+ self,
316
+ order_id: str,
317
+ price: float,
318
+ trigger_price: float | None = None,
319
+ order_type: OrderTypeType | None = None,
320
+ ):
321
+ order_to_modify = {
322
+ "order_id": order_id,
323
+ "price": price,
324
+ "trigger_price": trigger_price,
325
+ "order_type": order_type,
326
+ }
327
+
328
+ self.modify_order(order_to_modify) # type: ignore
316
329
 
317
330
  # TODO
318
331
  def modify_order(self, order: Any) -> str:
319
332
  order = copy.deepcopy(order) # type:ignore
333
+ order = self.add_existing_order_details(order)
334
+
320
335
  data = {
321
336
  "uniqueorderid": order["order_id"],
322
337
  "newordertype": order["order_type"].upper(),
@@ -396,6 +411,7 @@ class Motilal(Broker):
396
411
  "margin_available": margin_available,
397
412
  "margin_used": margin_used,
398
413
  "total_balance": margin_used + margin_available,
414
+ "cash": 0,
399
415
  }
400
416
 
401
417
  def place_order(
@@ -739,6 +739,7 @@ class Noren(Broker):
739
739
  margins: MarginsResponse = {
740
740
  "margin_used": api_margins["margin_used"],
741
741
  "margin_available": margin_available,
742
+ "cash": cash,
742
743
  "total_balance": float(cash) + float(holdings_val),
743
744
  }
744
745
 
@@ -748,4 +749,4 @@ class Noren(Broker):
748
749
  logger.error(f"[NOREN_MARGIN_ERROR] {e}")
749
750
  RetryableException("[NOREN] Failed to fetch account margin")
750
751
 
751
- return {"margin_available": 0, "margin_used": 0, "total_balance": 0}
752
+ return {"margin_available": 0, "margin_used": 0, "total_balance": 0, "cash": 0}
@@ -585,6 +585,7 @@ class Upstox(Broker):
585
585
  "margin_used": margin_used,
586
586
  "margin_available": margin_available,
587
587
  "total_balance": margin_used + margin_available,
588
+ "cash": 0,
588
589
  }
589
590
 
590
591
  def stream_order_data(self):
@@ -182,6 +182,7 @@ class XTS(Broker):
182
182
  "margin_used": 0,
183
183
  "margin_available": 0,
184
184
  "total_balance": 0,
185
+ "cash": 0,
185
186
  }
186
187
  api_response = api_response["result"]["BalanceList"][0]["limitObject"]
187
188
  margin_used = api_response["RMSSubLimits"]["marginUtilized"]
@@ -190,6 +191,7 @@ class XTS(Broker):
190
191
  "margin_used": margin_used,
191
192
  "margin_available": margin_available,
192
193
  "total_balance": margin_used + margin_available,
194
+ "cash": 0,
193
195
  }
194
196
 
195
197
  @retry(
@@ -381,7 +381,16 @@ class Zerodha(Broker):
381
381
  [self.get_token(x) for x in holdings_df["instrument_token"].to_list()],
382
382
  )
383
383
  )
384
+ if "collateral_quantity" in holdings_df.columns:
385
+ holdings_df = holdings_df.with_columns(
386
+ pl.col("collateral_quantity").alias("pledged_quantity")
387
+ )
388
+ else:
389
+ holdings_df = holdings_df.with_columns(pl.lit(0).alias("pledged_quantity"))
384
390
 
391
+ holdings_df = holdings_df.with_columns(
392
+ (pl.col("pledged_quantity") + pl.col("quantity")).alias("quantity")
393
+ )
385
394
  holdings_df = holdings_df.with_columns(
386
395
  (pl.col("quantity") * pl.col("price")).alias("value"),
387
396
  pl.lit(0).alias("pledged_quantity"),
@@ -531,6 +540,7 @@ class Zerodha(Broker):
531
540
  "margin_used": margin_used,
532
541
  "margin_available": margin_available,
533
542
  "total_balance": margin_used + margin_available,
543
+ "cash": float(margins["equity"]["available"]["cash"]),
534
544
  }
535
545
  return response
536
546
 
@@ -36,3 +36,4 @@ class MarginsResponse(TypedDict):
36
36
  total_balance: float
37
37
  margin_available: float
38
38
  margin_used: float
39
+ cash: float
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantplay
3
- Version: 2.0.86
3
+ Version: 2.0.91
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.86",
24
+ version="2.0.91",
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
File without changes