quantplay 2.0.24__tar.gz → 2.0.26__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 (71) hide show
  1. {quantplay-2.0.24 → quantplay-2.0.26}/PKG-INFO +1 -1
  2. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/aliceblue.py +2 -2
  3. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/angelone.py +2 -2
  4. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/five_paisa.py +1 -1
  5. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/generics/broker.py +16 -9
  6. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/motilal.py +35 -40
  7. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/noren.py +10 -5
  8. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/upstox.py +3 -4
  9. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/xts.py +1 -1
  10. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/zerodha.py +6 -3
  11. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay.egg-info/PKG-INFO +1 -1
  12. {quantplay-2.0.24 → quantplay-2.0.26}/setup.py +1 -1
  13. {quantplay-2.0.24 → quantplay-2.0.26}/README.md +0 -0
  14. {quantplay-2.0.24 → quantplay-2.0.26}/pyproject.toml +0 -0
  15. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/__init__.py +0 -0
  16. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/__init__.py +0 -0
  17. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/auto_login/__init__.py +0 -0
  18. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/auto_login/aliceblue.py +0 -0
  19. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/finvasia_utils/__init__.py +0 -0
  20. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/finvasia_utils/fa_noren.py +0 -0
  21. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/flattrade.py +0 -0
  22. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/ft_utils/__init__.py +0 -0
  23. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/ft_utils/flattrade_utils.py +0 -0
  24. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/ft_utils/ft_noren.py +0 -0
  25. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/generics/__init__.py +0 -0
  26. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/iifl_xts.py +0 -0
  27. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/kite_utils.py +0 -0
  28. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/shoonya.py +0 -0
  29. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/uplink/__init__.py +0 -0
  30. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/uplink/uplink_utils.py +0 -0
  31. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/xts_utils/Connect.py +0 -0
  32. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/xts_utils/Exception.py +0 -0
  33. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/xts_utils/InteractiveSocketClient.py +0 -0
  34. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/broker/xts_utils/__init__.py +0 -0
  35. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/exception/__init__.py +0 -0
  36. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/exception/exceptions.py +0 -0
  37. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/model/__init__.py +0 -0
  38. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/model/broker.py +0 -0
  39. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/model/generics.py +0 -0
  40. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/model/order_event.py +0 -0
  41. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/py.typed +0 -0
  42. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/strategies/__init__.py +0 -0
  43. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/strategies/equities/__init__.py +0 -0
  44. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/strategies/equities/intraday/__init__.py +0 -0
  45. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/strategies/equities/overnight/__init__.py +0 -0
  46. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/strategies/futures/__init__.py +0 -0
  47. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/strategies/futures/overnight/__init__.py +0 -0
  48. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/strategies/options/__init__.py +0 -0
  49. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/strategies/options/intraday/__init__.py +0 -0
  50. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/strategies/options/intraday/ladder.py +0 -0
  51. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/strategies/options/intraday/musk.py +0 -0
  52. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/strategies/options/intraday/short_straddle.py +0 -0
  53. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/utils/__init__.py +0 -0
  54. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/utils/constant.py +0 -0
  55. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/utils/exchange.py +0 -0
  56. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/utils/number_utils.py +0 -0
  57. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/utils/pickle_utils.py +0 -0
  58. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/utils/selenium_utils.py +0 -0
  59. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/wrapper/__init__.py +0 -0
  60. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/wrapper/aws/__init__.py +0 -0
  61. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay/wrapper/aws/s3.py +0 -0
  62. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay.egg-info/SOURCES.txt +0 -0
  63. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay.egg-info/dependency_links.txt +0 -0
  64. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay.egg-info/requires.txt +0 -0
  65. {quantplay-2.0.24 → quantplay-2.0.26}/quantplay.egg-info/top_level.txt +0 -0
  66. {quantplay-2.0.24 → quantplay-2.0.26}/setup.cfg +0 -0
  67. {quantplay-2.0.24 → quantplay-2.0.26}/tests/__init__.py +0 -0
  68. {quantplay-2.0.24 → quantplay-2.0.26}/tests/conftest.py +0 -0
  69. {quantplay-2.0.24 → quantplay-2.0.26}/tests/wrapper/__init__.py +0 -0
  70. {quantplay-2.0.24 → quantplay-2.0.26}/tests/wrapper/aws/__init__.py +0 -0
  71. {quantplay-2.0.24 → quantplay-2.0.26}/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.24
3
+ Version: 2.0.26
4
4
  Summary: This python package will be stored in AWS CodeArtifact
5
5
  Home-page:
6
6
  Author:
@@ -213,7 +213,7 @@ class Aliceblue(Broker):
213
213
  exception_message = f"Order placement failed [{str(e)}]"
214
214
  raise QuantplayOrderPlacementException(exception_message)
215
215
 
216
- def get_ltp(self, exchange, tradingsymbol: str):
216
+ def ltp(self, exchange, tradingsymbol: str):
217
217
  inst = self.alice.get_instrument_by_symbol(exchange, tradingsymbol)
218
218
  info = self.invoke_aliceblue_api(self.alice.get_scrip_info, instrument=inst)
219
219
 
@@ -327,7 +327,7 @@ class Aliceblue(Broker):
327
327
  holdings_df = holdings_df.with_columns(
328
328
  pl.struct(["exchange", "tradingsymbol"])
329
329
  .map_elements(
330
- lambda x: int(self.get_ltp(x["exchange"], x["tradingsymbol"])),
330
+ lambda x: int(self.ltp(x["exchange"], x["tradingsymbol"])),
331
331
  return_dtype=pl.Float64,
332
332
  )
333
333
  .alias("price")
@@ -167,7 +167,7 @@ class AngelOne(Broker):
167
167
  wait_exponential_max=10000,
168
168
  stop_max_attempt_number=3,
169
169
  )
170
- def get_ltp(self, exchange, tradingsymbol: str) -> float:
170
+ def ltp(self, exchange, tradingsymbol: str) -> float:
171
171
  if tradingsymbol in MarketConstants.INDEX_SYMBOL_TO_DERIVATIVE_SYMBOL_MAP:
172
172
  tradingsymbol = MarketConstants.INDEX_SYMBOL_TO_DERIVATIVE_SYMBOL_MAP[
173
173
  tradingsymbol
@@ -573,7 +573,7 @@ class AngelOne(Broker):
573
573
  if "errorcode" in api_margins and api_margins["errorcode"] == "AB1004":
574
574
  raise TokenException("Angelone server not not responding")
575
575
 
576
- return {"margin_used": 0, "margin_available": 0, "total_balance": 0}
576
+ return {"margin_used": 0.0, "margin_available": 0.0, "total_balance": 0.0}
577
577
 
578
578
  api_margins = api_margins["data"]
579
579
 
@@ -134,7 +134,7 @@ class FivePaisa(Broker):
134
134
  stop_max_attempt_number=3,
135
135
  retry_on_exception=retry_exception,
136
136
  )
137
- def get_ltp(self, exchange, tradingsymbol: str) -> float:
137
+ def ltp(self, exchange, tradingsymbol: str) -> float:
138
138
  tradingsymbol = self.get_symbol(tradingsymbol, exchange)
139
139
  exchange_name = self.get_exchange(exchange)
140
140
  exchange_type = self.get_exchange_type(exchange)
@@ -456,7 +456,7 @@ class Broker:
456
456
 
457
457
  def live_data(self, exchange, tradingsymbol):
458
458
  return {
459
- "ltp": self.get_ltp(exchange, tradingsymbol),
459
+ "ltp": self.ltp(exchange, tradingsymbol),
460
460
  "upper_circuit": None,
461
461
  "lower_circuit": None,
462
462
  }
@@ -606,7 +606,7 @@ class Broker:
606
606
  exchange = stoploss_order["exchange"]
607
607
  tradingsymbol = stoploss_order["tradingsymbol"]
608
608
 
609
- ltp = self.get_ltp(exchange, tradingsymbol)
609
+ ltp = self.ltp(exchange, tradingsymbol)
610
610
  stoploss_order["order_type"] = "LIMIT"
611
611
  stoploss_order["price"] = self.round_to_tick(ltp)
612
612
  stoploss_order["trigger_price"] = None
@@ -713,7 +713,7 @@ class Broker:
713
713
  positions = positions.with_columns(
714
714
  pl.struct(["exchange", "tradingsymbol"])
715
715
  .map_elements(
716
- lambda x: int(self.get_ltp(x["exchange"], x["tradingsymbol"])),
716
+ lambda x: int(self.ltp(x["exchange"], x["tradingsymbol"])),
717
717
  return_dtype=pl.Float64,
718
718
  )
719
719
  .alias("price")
@@ -895,7 +895,7 @@ class Broker:
895
895
  elif "SENSEX" in symbol and exchange == "BFO":
896
896
  return self.underlying_config("SENSEX")["max_lots"]
897
897
  elif exchange == "NSE":
898
- max_qty = int(500000 / self.get_ltp(exchange, symbol))
898
+ max_qty = int(500000 / self.ltp(exchange, symbol))
899
899
  if max_qty == 0:
900
900
  return 1
901
901
  return max_qty
@@ -995,9 +995,7 @@ class Broker:
995
995
  all_symbols = list(orders.exchange_symbol.unique())
996
996
  symbol_ltp = {}
997
997
  for exchange_symbol in all_symbols:
998
- ltp = self.get_ltp(
999
- exchange_symbol.split(":")[0], exchange_symbol.split(":")[1]
1000
- )
998
+ ltp = self.ltp(exchange_symbol.split(":")[0], exchange_symbol.split(":")[1])
1001
999
  symbol_ltp[exchange_symbol] = ltp
1002
1000
  orders.loc[:, "ltp"] = orders["exchange_symbol"].map(symbol_ltp)
1003
1001
 
@@ -1130,7 +1128,7 @@ class Broker:
1130
1128
  else:
1131
1129
  modification_count[order_id] += 1
1132
1130
 
1133
- ltp = self.get_ltp(order["exchange"], order["tradingsymbol"])
1131
+ ltp = self.ltp(order["exchange"], order["tradingsymbol"])
1134
1132
 
1135
1133
  market_protection = 0.02
1136
1134
  if modification_count[order_id] > 5:
@@ -1237,7 +1235,7 @@ class Broker:
1237
1235
  """
1238
1236
  raise NotImplementedError
1239
1237
 
1240
- def get_ltp(self, exchange: ExchangeType, tradingsymbol: str) -> float:
1238
+ def ltp(self, exchange: ExchangeType, tradingsymbol: str) -> float:
1241
1239
  """_summary_
1242
1240
 
1243
1241
  Args:
@@ -1284,3 +1282,12 @@ class Broker:
1284
1282
  UserBrokerProfile: contains exchange user_id full_name and email
1285
1283
  """
1286
1284
  raise NotImplementedError
1285
+
1286
+ def margins(self) -> Dict[str, float]:
1287
+ """Returns User Margin Summary
1288
+
1289
+ Raises:
1290
+ NotImplementedError: if Function Not Implemented by Sub class
1291
+
1292
+ """
1293
+ raise NotImplementedError
@@ -19,6 +19,7 @@ import binascii
19
19
  from quantplay.utils.pickle_utils import InstrumentData
20
20
  from quantplay.exception.exceptions import (
21
21
  QuantplayOrderPlacementException,
22
+ TokenException,
22
23
  retry_exception,
23
24
  RetryableException,
24
25
  )
@@ -133,8 +134,7 @@ class Motilal(Broker):
133
134
  else:
134
135
  raise Exception("Missing Arguments")
135
136
 
136
- profile = self.profile()
137
- self.user_id = profile["user_id"]
137
+ self.user_id = self.headers["vendorinfo"]
138
138
  except binascii.Error:
139
139
  raise InvalidArgumentException("Invalid TOTP key provided")
140
140
  except InvalidArgumentException:
@@ -268,7 +268,7 @@ class Motilal(Broker):
268
268
  wait_exponential_max=10000,
269
269
  stop_max_attempt_number=3,
270
270
  )
271
- def get_ltp(self, exchange, tradingsymbol: str) -> float:
271
+ def ltp(self, exchange, tradingsymbol: str) -> float:
272
272
  tradingsymbol = self.get_symbol(tradingsymbol)
273
273
  token = self.symbol_data["{}:{}".format(exchange, tradingsymbol)]["token"]
274
274
  exchange = self.get_exchange(exchange)
@@ -383,36 +383,15 @@ class Motilal(Broker):
383
383
  )
384
384
  Constants.logger.error(exception_message)
385
385
 
386
- def get_profile(self):
387
- response = requests.post(
388
- self.get_profile_url,
389
- headers=self.headers,
390
- data=json.dumps({"Clientcode": self.headers["vendorinfo"]}),
391
- ).json()
392
- if response["status"] == "ERROR":
393
- raise Exception(response["message"])
394
-
395
- return response["data"]
396
-
397
- @retry(
398
- wait_exponential_multiplier=3000,
399
- wait_exponential_max=10000,
400
- stop_max_attempt_number=3,
401
- )
402
386
  def margins(self):
403
- response = requests.post(
404
- self.margin_summary_url,
405
- headers=self.headers,
406
- data=json.dumps({"Clientcode": self.headers["vendorinfo"]}),
407
- ).json()
408
- if response["status"] == "ERROR":
409
- raise Exception(response["message"])
387
+ response = self.__post_request(self.margin_summary_url, {})
410
388
  margin_summary = response["data"]
411
389
 
412
- margins = {"margin_used": 0, "margin_available": 0}
390
+ margins = {"margin_used": 0.0, "margin_available": 0.0}
413
391
  for margin_particular in margin_summary:
414
392
  if margin_particular["srno"] in [103]:
415
393
  margins["margin_available"] += margin_particular["amount"]
394
+
416
395
  if margin_particular["srno"] in [301, 321, 340, 360]:
417
396
  margins["margin_used"] += margin_particular["amount"]
418
397
 
@@ -554,14 +533,35 @@ class Motilal(Broker):
554
533
 
555
534
  return response
556
535
 
557
- def profile(self) -> UserBrokerProfileResponse:
536
+ @retry(
537
+ wait_exponential_multiplier=3000,
538
+ wait_exponential_max=10000,
539
+ stop_max_attempt_number=3,
540
+ retry_on_exception=retry_exception,
541
+ )
542
+ def __post_request(self, url, data):
558
543
  api_response = requests.post(
559
- self.get_profile_url,
544
+ url,
560
545
  headers=self.headers,
561
546
  data=json.dumps({"Clientcode": self.headers["vendorinfo"]}),
562
547
  ).json()
563
- if api_response["status"] == "ERROR":
564
- raise Exception(api_response["message"])
548
+
549
+ if api_response["status"] == "ERROR" and api_response["errorcode"] in [
550
+ "MO8001",
551
+ "MO8002",
552
+ "MO8003",
553
+ "MO8050",
554
+ "MO8051",
555
+ "MO8052",
556
+ ]:
557
+ raise TokenException("Motilal token expired")
558
+ elif api_response["status"] == "ERROR":
559
+ raise RetryableException(api_response["message"])
560
+
561
+ return api_response
562
+
563
+ def profile(self) -> UserBrokerProfileResponse:
564
+ api_response = self.__post_request(self.get_profile_url, {})
565
565
 
566
566
  api_response = api_response["data"]
567
567
  response: UserBrokerProfileResponse = {
@@ -578,7 +578,7 @@ class Motilal(Broker):
578
578
  stop_max_attempt_number=3,
579
579
  )
580
580
  def holdings(self):
581
- response = (requests.post(self.holdings_url, headers=self.headers)).json()
581
+ response = self.__post_request(self.holdings_url, {})
582
582
  if response["status"] == "ERROR":
583
583
  Constants.logger.info(
584
584
  "Error while fetching order book [{}]".format(response["message"])
@@ -605,7 +605,7 @@ class Motilal(Broker):
605
605
  holdings_df = holdings_df.with_columns(
606
606
  pl.struct(["exchange", "tradingsymbol"])
607
607
  .map_elements(
608
- lambda x: int(self.get_ltp(x["exchange"], x["tradingsymbol"])),
608
+ lambda x: int(self.ltp(x["exchange"], x["tradingsymbol"])),
609
609
  return_dtype=pl.Float64,
610
610
  )
611
611
  .alias("price")
@@ -624,13 +624,8 @@ class Motilal(Broker):
624
624
 
625
625
  return holdings_df[list(self.holidings_schema.keys())].cast(self.holidings_schema)
626
626
 
627
- @retry(
628
- wait_exponential_multiplier=3000,
629
- wait_exponential_max=10000,
630
- stop_max_attempt_number=3,
631
- )
632
627
  def positions(self, drop_cnc: bool = True) -> pl.DataFrame:
633
- response = (requests.post(self.positions_url, headers=self.headers)).json()
628
+ response = self.__post_request(self.positions_url, {})
634
629
  if response["status"] == "ERROR":
635
630
  Constants.logger.info(
636
631
  "Error while fetching positions [{}]".format(response["message"])
@@ -699,7 +694,7 @@ class Motilal(Broker):
699
694
  )
700
695
 
701
696
  def orders(self, tag: str | None = None, add_ltp: bool = True) -> pl.DataFrame:
702
- response = (requests.post(self.order_book_url, headers=self.headers)).json()
697
+ response = self.__post_request(self.order_book_url, {})
703
698
  if response["status"] == "ERROR":
704
699
  Constants.logger.info(
705
700
  "Error while fetching order book [{}]".format(response["message"])
@@ -75,6 +75,8 @@ class Noren(Broker):
75
75
  def get_symbol(self, symbol: str, exchange: ExchangeType | None = None):
76
76
  if symbol not in self.quantplay_symbol_map:
77
77
  return symbol
78
+ if exchange == "NSE" and "-EQ" not in symbol:
79
+ return f"{symbol}-EQ"
78
80
 
79
81
  return self.quantplay_symbol_map[symbol]
80
82
 
@@ -246,8 +248,8 @@ class Noren(Broker):
246
248
  wait_exponential_max=10000,
247
249
  stop_max_attempt_number=3,
248
250
  )
249
- def get_ltp(self, exchange, tradingsymbol):
250
- tradingsymbol = self.get_symbol(tradingsymbol)
251
+ def ltp(self, exchange, tradingsymbol):
252
+ tradingsymbol = self.get_symbol(tradingsymbol, exchange)
251
253
 
252
254
  token = self.symbol_data["{}:{}".format(exchange, tradingsymbol)]["token"]
253
255
  quote = self.api.get_quotes(exchange, str(token))
@@ -387,7 +389,7 @@ class Noren(Broker):
387
389
  holdings_df = holdings_df.with_columns(
388
390
  pl.struct(["exchange", "tradingsymbol"])
389
391
  .map_elements(
390
- lambda x: int(self.get_ltp(x["exchange"], x["tradingsymbol"])),
392
+ lambda x: int(self.ltp(x["exchange"], x["tradingsymbol"])),
391
393
  return_dtype=pl.Float64,
392
394
  )
393
395
  .alias("price")
@@ -510,7 +512,6 @@ class Noren(Broker):
510
512
  "qty": "quantity",
511
513
  "prc": "price",
512
514
  "prctyp": "order_type",
513
- "fillshares": "filled_quantity",
514
515
  "norentm": "order_timestamp",
515
516
  }
516
517
  )
@@ -527,8 +528,12 @@ class Noren(Broker):
527
528
 
528
529
  orders_df = orders_df.with_columns(pl.lit(None).alias("variety"))
529
530
 
530
- if "filled_quantity" not in orders_df.columns:
531
+ if "fillshares" not in orders_df.columns:
531
532
  orders_df = orders_df.with_columns(pl.lit(0).alias("filled_quantity"))
533
+ else:
534
+ orders_df = orders_df.with_columns(
535
+ pl.col("fillshares").cast(pl.Int64).alias("filled_quantity")
536
+ )
532
537
  if "rorgqty" not in orders_df.columns:
533
538
  orders_df = orders_df.with_columns(pl.lit(0).alias("pending_quantity"))
534
539
  else:
@@ -126,7 +126,7 @@ class Upstox(Broker):
126
126
  stop_max_attempt_number=3,
127
127
  retry_on_exception=retry_exception,
128
128
  )
129
- def get_ltp(self, exchange: ExchangeType, tradingsymbol: str) -> float:
129
+ def ltp(self, exchange: ExchangeType, tradingsymbol: str) -> float:
130
130
  api_instance = upstox_client.MarketQuoteApi(self.api_client)
131
131
 
132
132
  ltp = 0
@@ -315,7 +315,7 @@ class Upstox(Broker):
315
315
  holdings_df = holdings_df.with_columns(
316
316
  pl.struct(["exchange", "tradingsymbol"])
317
317
  .map_elements(
318
- lambda x: int(self.get_ltp(x["exchange"], x["tradingsymbol"])),
318
+ lambda x: int(self.ltp(x["exchange"], x["tradingsymbol"])),
319
319
  return_dtype=pl.Float64,
320
320
  )
321
321
  .alias("price")
@@ -354,8 +354,7 @@ class Upstox(Broker):
354
354
  # Get Positions
355
355
  api_response = api_instance.get_positions(self.api_version)
356
356
  positions = [
357
- position.to_dict()
358
- for position in api_response.data # type:ignore
357
+ position.to_dict() for position in api_response.data # type:ignore
359
358
  ]
360
359
  positions_df = pl.DataFrame(positions)
361
360
  except ApiException as e:
@@ -538,7 +538,7 @@ class XTS(Broker):
538
538
 
539
539
  return exchange_code_map[exchange]
540
540
 
541
- def get_ltp(self, exchange=None, tradingsymbol=None) -> float:
541
+ def ltp(self, exchange=None, tradingsymbol=None) -> float:
542
542
  exchange_code = self.get_exchange_code(exchange)
543
543
  exchange_token = self.symbol_data[f"{exchange}:{tradingsymbol}"]["exchange_token"]
544
544
 
@@ -132,8 +132,9 @@ class Zerodha(Broker):
132
132
  wait_exponential_multiplier=3000,
133
133
  wait_exponential_max=10000,
134
134
  stop_max_attempt_number=3,
135
+ retry_on_exception=retry_exception,
135
136
  )
136
- def get_ltp(self, exchange: ExchangeType, tradingsymbol: str) -> float:
137
+ def ltp(self, exchange: ExchangeType, tradingsymbol: str) -> float:
137
138
  try:
138
139
  key = "{}:".format(exchange) + tradingsymbol
139
140
  response = self.wrapper.ltp([key])
@@ -149,11 +150,13 @@ class Zerodha(Broker):
149
150
  )
150
151
 
151
152
  return api_response[key]["last_price"]
153
+ except TokenException:
154
+ raise QuantplayTokenException("Zerodha token expired")
152
155
  except Exception as e:
153
156
  exception_message = "GetLtp call failed for [{}] with error [{}]".format(
154
157
  tradingsymbol, str(e)
155
158
  )
156
- raise InvalidArgumentException(exception_message)
159
+ raise RetryableException(exception_message)
157
160
 
158
161
  @retry(
159
162
  wait_exponential_multiplier=3000,
@@ -211,7 +214,7 @@ class Zerodha(Broker):
211
214
  exchange = order["exchange"]
212
215
  tradingsymbol = order["tradingsymbol"]
213
216
 
214
- return self.get_ltp(exchange, tradingsymbol)
217
+ return self.ltp(exchange, tradingsymbol)
215
218
 
216
219
  @retry(
217
220
  wait_exponential_multiplier=3000,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantplay
3
- Version: 2.0.24
3
+ Version: 2.0.26
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.24",
24
+ version="2.0.26",
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