quantplay 2.0.34__tar.gz → 2.0.36__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 (62) hide show
  1. {quantplay-2.0.34 → quantplay-2.0.36}/PKG-INFO +1 -1
  2. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/aliceblue.py +2 -4
  3. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/angelone.py +4 -6
  4. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/five_paisa.py +3 -3
  5. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/generics/broker.py +4 -3
  6. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/uplink/uplink_utils.py +0 -1
  7. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/upstox.py +8 -8
  8. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/xts.py +6 -3
  9. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/xts_utils/Connect.py +35 -24
  10. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/xts_utils/InteractiveSocketClient.py +39 -39
  11. quantplay-2.0.36/quantplay/model/xts.py +7 -0
  12. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/utils/pickle_utils.py +3 -3
  13. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/wrapper/aws/s3.py +3 -3
  14. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay.egg-info/PKG-INFO +1 -1
  15. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay.egg-info/SOURCES.txt +1 -0
  16. {quantplay-2.0.34 → quantplay-2.0.36}/setup.py +1 -1
  17. {quantplay-2.0.34 → quantplay-2.0.36}/README.md +0 -0
  18. {quantplay-2.0.34 → quantplay-2.0.36}/pyproject.toml +0 -0
  19. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/__init__.py +0 -0
  20. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/__init__.py +0 -0
  21. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/auto_login/__init__.py +0 -0
  22. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/auto_login/aliceblue.py +0 -0
  23. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/finvasia_utils/__init__.py +0 -0
  24. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/finvasia_utils/fa_noren.py +0 -0
  25. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/flattrade.py +0 -0
  26. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/ft_utils/__init__.py +0 -0
  27. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/ft_utils/flattrade_utils.py +0 -0
  28. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/ft_utils/ft_noren.py +0 -0
  29. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/generics/__init__.py +0 -0
  30. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/iifl_xts.py +0 -0
  31. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/kite_utils.py +0 -0
  32. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/motilal.py +0 -0
  33. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/noren.py +0 -0
  34. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/shoonya.py +0 -0
  35. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/uplink/__init__.py +0 -0
  36. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/xts_utils/Exception.py +0 -0
  37. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/xts_utils/__init__.py +0 -0
  38. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/broker/zerodha.py +0 -0
  39. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/exception/__init__.py +0 -0
  40. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/exception/exceptions.py +0 -0
  41. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/model/__init__.py +0 -0
  42. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/model/broker.py +0 -0
  43. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/model/generics.py +0 -0
  44. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/model/instrument_data.py +0 -0
  45. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/model/order_event.py +0 -0
  46. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/py.typed +0 -0
  47. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/utils/__init__.py +0 -0
  48. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/utils/constant.py +0 -0
  49. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/utils/exchange.py +0 -0
  50. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/utils/number_utils.py +0 -0
  51. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/utils/selenium_utils.py +0 -0
  52. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/wrapper/__init__.py +0 -0
  53. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay/wrapper/aws/__init__.py +0 -0
  54. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay.egg-info/dependency_links.txt +0 -0
  55. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay.egg-info/requires.txt +0 -0
  56. {quantplay-2.0.34 → quantplay-2.0.36}/quantplay.egg-info/top_level.txt +0 -0
  57. {quantplay-2.0.34 → quantplay-2.0.36}/setup.cfg +0 -0
  58. {quantplay-2.0.34 → quantplay-2.0.36}/tests/__init__.py +0 -0
  59. {quantplay-2.0.34 → quantplay-2.0.36}/tests/conftest.py +0 -0
  60. {quantplay-2.0.34 → quantplay-2.0.36}/tests/wrapper/__init__.py +0 -0
  61. {quantplay-2.0.34 → quantplay-2.0.36}/tests/wrapper/aws/__init__.py +0 -0
  62. {quantplay-2.0.34 → quantplay-2.0.36}/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.34
3
+ Version: 2.0.36
4
4
  Summary: This python package will be stored in AWS CodeArtifact
5
5
  Home-page:
6
6
  Author:
@@ -134,7 +134,7 @@ class Aliceblue(Broker):
134
134
  return TransactionType.Sell
135
135
 
136
136
  raise InvalidArgumentException(
137
- "transaction type {} not supported for trading".format(transaction_type)
137
+ f"transaction type {transaction_type} not supported for trading"
138
138
  )
139
139
 
140
140
  def get_order_type(self, order_type):
@@ -170,9 +170,7 @@ class Aliceblue(Broker):
170
170
  ]:
171
171
  return product
172
172
 
173
- raise InvalidArgumentException(
174
- "Product {} not supported for trading".format(product)
175
- )
173
+ raise InvalidArgumentException(f"Product {product} not supported for trading")
176
174
 
177
175
  def place_order(
178
176
  self,
@@ -5,7 +5,7 @@ import json
5
5
  import pickle
6
6
  from queue import Queue
7
7
  import traceback
8
- from typing import Callable, Dict
8
+ from typing import Any, Callable, Dict
9
9
 
10
10
  from SmartApi.smartExceptions import DataException
11
11
  import polars as pl
@@ -157,9 +157,7 @@ class AngelOne(Broker):
157
157
  elif product in ["BO", "MARGIN", "INTRADAY", "CARRYFORWARD", "DELIVERY"]:
158
158
  return product
159
159
 
160
- raise InvalidArgumentException(
161
- "Product {} not supported for trading".format(product)
162
- )
160
+ raise InvalidArgumentException(f"Product {product} not supported for trading")
163
161
 
164
162
  def ltp(self, exchange, tradingsymbol: str) -> float:
165
163
  if tradingsymbol in MarketConstants.INDEX_SYMBOL_TO_DERIVATIVE_SYMBOL_MAP:
@@ -224,7 +222,7 @@ class AngelOne(Broker):
224
222
  "ordertag": tag,
225
223
  }
226
224
 
227
- Constants.logger.info("[PLACING_ORDER] {}".format(json.dumps(order)))
225
+ Constants.logger.info(f"[PLACING_ORDER] {json.dumps(order)}")
228
226
  return self.invoke_angelone_api(self.wrapper.placeOrder, orderparams=order)
229
227
 
230
228
  except (TimeoutError, ConnectTimeout):
@@ -563,7 +561,7 @@ class AngelOne(Broker):
563
561
  stop_max_attempt_number=3,
564
562
  retry_on_exception=retry_exception,
565
563
  )
566
- def invoke_angelone_api(self, fn: Callable, *args, **kwargs) -> Dict:
564
+ def invoke_angelone_api(self, fn: Callable, *args, **kwargs) -> Any:
567
565
  try:
568
566
  response = fn(*args, **kwargs)
569
567
  if "errorCode" in response and response["errorCode"] == "AG8001":
@@ -1,3 +1,4 @@
1
+ from ast import alias
1
2
  import codecs
2
3
  import pickle
3
4
  import traceback
@@ -5,7 +6,7 @@ from typing import Dict
5
6
 
6
7
  import polars as pl
7
8
  import pyotp
8
- from py5paisa import FivePaisaClient
9
+ from py5paisa import FivePaisaClient # type: ignore
9
10
  from retrying import retry # type: ignore
10
11
 
11
12
  from quantplay.broker.generics.broker import Broker
@@ -147,9 +148,8 @@ class FivePaisa(Broker):
147
148
  return self.client.fetch_market_feed_scrip(req_list_)["Data"][0]["LastRate"] # type: ignore
148
149
 
149
150
  def add_exchange(self, data: pl.DataFrame):
150
- data["exchange"] = None
151
-
152
151
  return data.with_columns(
152
+ pl.lit(None).alias("exchange"),
153
153
  pl.when((pl.col("Exch").eq("N")) & (pl.col("ExchType").eq("D")))
154
154
  .then(pl.lit("NFO"))
155
155
  .alias("exchange"),
@@ -147,7 +147,7 @@ class Broker:
147
147
  if not input:
148
148
  raise InvalidArgumentException(message)
149
149
 
150
- def symbol_attribute(self, exchange: ExchangeType, symbol, value):
150
+ def symbol_attribute(self, exchange: ExchangeType, symbol: str, value):
151
151
  try:
152
152
  return_value = self.symbol_data[f"{exchange}:{symbol}"][value]
153
153
  return return_value
@@ -307,6 +307,7 @@ class Broker:
307
307
  file_name = url.split(".txt")[0].split("/")[-1]
308
308
  os.system("cp /tmp/{}.txt /tmp/{}.csv".format(file_name, file_name))
309
309
  time.sleep(2)
310
+
310
311
  return pd.read_csv("/tmp/{}.csv".format(file_name))
311
312
 
312
313
  def initialize_expiry_fields(self):
@@ -1166,13 +1167,13 @@ class Broker:
1166
1167
  if modification_count[order_id] > max_modification_count:
1167
1168
  order["order_type"] = "MARKET"
1168
1169
  order["price"] = 0
1169
- Constants.logger.info("Placing MARKET order [{}]".format(order))
1170
+ Constants.logger.info(f"Placing MARKET order [{order}]")
1170
1171
  self.modify_order(order) # type: ignore
1171
1172
 
1172
1173
  elif modification_count[order_id] > 20:
1173
1174
  self.cancel_order(order_id)
1174
1175
  Constants.logger.error(
1175
- "Max Modification Limit Exceeded : [{}]".format(order_id)
1176
+ f"Max Modification Limit Exceeded : [{order_id}]"
1176
1177
  )
1177
1178
 
1178
1179
  def log_event(
@@ -71,7 +71,6 @@ class UplinkUtils:
71
71
 
72
72
  time.sleep(2)
73
73
  url = f"{UplinkUtils.auth_url}dialog?response_type=code&client_id={api_key}&redirect_uri={redirect_url}"
74
- print("Upstox Url {}".format(url))
75
74
 
76
75
  driver.get(url)
77
76
  time.sleep(1)
@@ -142,8 +142,8 @@ class Upstox(Broker):
142
142
  f"{self.get_exchange(symbol_info['exchange'])}:{tradingsymbol}"
143
143
  ].last_price
144
144
  except ApiException as e:
145
- Constants.logger.error("Exception when calling MarketQuoteApi->ltp: %s\n" % e)
146
145
  self.handle_exception(e)
146
+ Constants.logger.error("Exception when calling MarketQuoteApi->ltp: %s\n" % e)
147
147
  return ltp
148
148
 
149
149
  @retry(
@@ -172,6 +172,7 @@ class Upstox(Broker):
172
172
  api_response = api_instance.modify_order(body, self.api_version)
173
173
  return api_response.status # type:ignore
174
174
  except ApiException as e:
175
+ self.handle_exception(e)
175
176
  Constants.logger.error(
176
177
  "Exception when calling OrderApi->modify_order: %s\n" % e
177
178
  )
@@ -181,10 +182,9 @@ class Upstox(Broker):
181
182
  order_to_modify["order_id"], order_to_modify["price"]
182
183
  )
183
184
  )
184
- self.handle_exception(e)
185
185
  return order_to_modify["order_id"]
186
186
 
187
- def cancel_order(self, order_id: str, variety=None) -> None:
187
+ def cancel_order(self, order_id: str, variety: str | None = None) -> None:
188
188
  api_instance = upstox_client.OrderApi(self.api_client)
189
189
 
190
190
  try:
@@ -289,8 +289,8 @@ class Upstox(Broker):
289
289
  self.email = response["email"]
290
290
  self.enabled_exchanges = response["exchanges"]
291
291
  except ApiException as e:
292
- Constants.logger.info("error when calling UserApi->get_profile: %s\n" % e)
293
292
  self.handle_exception(e)
293
+ Constants.logger.info("error when calling UserApi->get_profile: %s\n" % e)
294
294
 
295
295
  self.user_id = response["user_id"]
296
296
  return response
@@ -305,10 +305,10 @@ class Upstox(Broker):
305
305
  holdings = [holding.to_dict() for holding in api_response.data] # type:ignore
306
306
  holdings_df = pl.DataFrame(holdings)
307
307
  except ApiException as e:
308
+ self.handle_exception(e)
308
309
  Constants.logger.error(
309
310
  "Exception when calling PortfolioApi->get_holdings: %s\n" % e
310
311
  )
311
- self.handle_exception(e)
312
312
 
313
313
  if len(holdings_df) == 0:
314
314
  return pl.DataFrame(schema=self.holidings_schema)
@@ -359,10 +359,10 @@ class Upstox(Broker):
359
359
  ]
360
360
  positions_df = pl.DataFrame(positions)
361
361
  except ApiException as e:
362
+ self.handle_exception(e)
362
363
  Constants.logger.error(
363
364
  "Exception when calling PortfolioApi->get_positions: %s\n" % e
364
365
  )
365
- self.handle_exception(e)
366
366
 
367
367
  if len(positions_df) == 0:
368
368
  return pl.DataFrame(schema=self.positions_schema)
@@ -451,10 +451,10 @@ class Upstox(Broker):
451
451
  orders = [order.to_dict() for order in api_response.data] # type:ignore
452
452
  orders_df = pl.DataFrame(orders)
453
453
  except ApiException as e:
454
+ self.handle_exception(e)
454
455
  Constants.logger.error(
455
456
  "Exception when calling OrderApi->get_order_book: %s\n" % e
456
457
  )
457
- self.handle_exception(e)
458
458
 
459
459
  if len(orders_df) == 0:
460
460
  return pl.DataFrame(schema=self.orders_schema)
@@ -570,10 +570,10 @@ class Upstox(Broker):
570
570
  api_response.data["equity"].available_margin # type:ignore
571
571
  )
572
572
  except ApiException as e:
573
+ self.handle_exception(e)
573
574
  Constants.logger.error(
574
575
  "Exception when calling UserApi->get_user_fund_margin: %s\n" % e
575
576
  )
576
- self.handle_exception(e)
577
577
 
578
578
  margins = {
579
579
  "margin_used": margin_used,
@@ -52,7 +52,7 @@ class XTS(Broker):
52
52
  self.root_url = root_url
53
53
 
54
54
  try:
55
- if wrapper:
55
+ if wrapper and ClientID:
56
56
  self.set_wrapper(wrapper, md_wrapper)
57
57
  self.ClientID = ClientID
58
58
  self.wrapper.root = root_url
@@ -164,7 +164,7 @@ class XTS(Broker):
164
164
  ):
165
165
  raise TokenException(response["description"])
166
166
  if "type" in response and response["type"] == "error":
167
- raise Exception("[XTS_Error]: " + response["description"])
167
+ raise Exception(f"[XTS_Error]: {response["description"]}")
168
168
 
169
169
  @retry(
170
170
  wait_exponential_multiplier=3000,
@@ -668,7 +668,7 @@ class XTS(Broker):
668
668
  disclosed_quantity = 0
669
669
 
670
670
  api_response = self.wrapper.modify_order(
671
- appOrderID=order_id,
671
+ appOrderID=int(order_id),
672
672
  modifiedTimeInForce=time_in_force,
673
673
  modifiedDisclosedQuantity=disclosed_quantity,
674
674
  modifiedLimitPrice=price,
@@ -698,6 +698,9 @@ class XTS(Broker):
698
698
  )
699
699
 
700
700
  def stream_order_updates(self):
701
+ if self.wrapper.token is None:
702
+ raise InvalidArgumentException("XTS Token Missing")
703
+
701
704
  socket = OrderSocket_io(
702
705
  userID=self.ClientID,
703
706
  token=self.wrapper.token,
@@ -9,7 +9,7 @@ import json
9
9
  import logging
10
10
  import os
11
11
  import traceback
12
- from typing import Any, Dict, Literal
12
+ from typing import Any, Dict, List, Literal
13
13
 
14
14
  import requests
15
15
  import urllib3
@@ -20,6 +20,7 @@ from six.moves.urllib.parse import urljoin # type:ignore
20
20
  from quantplay.broker.xts_utils import Exception as ex
21
21
  from quantplay.broker.xts_utils.Exception import XTSDataException
22
22
  from quantplay.exception.exceptions import BrokerException
23
+ from quantplay.model.xts import ExchangeSegmentType
23
24
 
24
25
  log = logging.getLogger(__name__)
25
26
 
@@ -346,15 +347,15 @@ class XTSConnect(XTSCommon):
346
347
 
347
348
  def modify_order(
348
349
  self,
349
- appOrderID,
350
+ appOrderID: int,
350
351
  modifiedProductType,
351
352
  modifiedOrderType,
352
- modifiedOrderQuantity,
353
- modifiedDisclosedQuantity,
354
- modifiedLimitPrice,
355
- modifiedStopPrice,
353
+ modifiedOrderQuantity: int,
354
+ modifiedDisclosedQuantity: int,
355
+ modifiedLimitPrice: float,
356
+ modifiedStopPrice: float,
356
357
  modifiedTimeInForce,
357
- orderUniqueIdentifier,
358
+ orderUniqueIdentifier: str,
358
359
  clientID: str | None = None,
359
360
  ):
360
361
  """The facility to modify your open orders by allowing you to change limit order to market or vice versa,
@@ -468,7 +469,7 @@ class XTSConnect(XTSCommon):
468
469
  raise BrokerException("convert_position Failed for XTS")
469
470
 
470
471
  def cancel_order(
471
- self, appOrderID, orderUniqueIdentifier, clientID: str | None = None
472
+ self, appOrderID: int, orderUniqueIdentifier: str, clientID: str | None = None
472
473
  ):
473
474
  """This API can be called to cancel any open order of the user by providing correct appOrderID matching with
474
475
  the chosen open order to cancel."""
@@ -485,7 +486,7 @@ class XTSConnect(XTSCommon):
485
486
  traceback.print_exc()
486
487
  raise BrokerException("cancel_order Failed for XTS")
487
488
 
488
- def cancelall_order(self, exchangeSegment, exchangeInstrumentID):
489
+ def cancelall_order(self, exchangeSegment: ExchangeSegmentType, exchangeInstrumentID):
489
490
  """This API can be called to cancel all open order of the user by providing exchange segment and exchange instrument ID"""
490
491
  try:
491
492
  params: Dict[str, Any] = {
@@ -506,10 +507,10 @@ class XTSConnect(XTSCommon):
506
507
  exchangeInstrumentID,
507
508
  orderSide,
508
509
  orderType,
509
- orderQuantity,
510
- disclosedQuantity,
511
- limitPrice,
512
- stopPrice,
510
+ orderQuantity: int,
511
+ disclosedQuantity: int,
512
+ limitPrice: float,
513
+ stopPrice: float,
513
514
  orderUniqueIdentifier,
514
515
  clientID: str | None = None,
515
516
  ):
@@ -537,7 +538,7 @@ class XTSConnect(XTSCommon):
537
538
  traceback.print_exc()
538
539
  raise BrokerException("place_cover_order Failed for XTS")
539
540
 
540
- def exit_cover_order(self, appOrderID, clientID: str | None = None):
541
+ def exit_cover_order(self, appOrderID: int, clientID: str | None = None):
541
542
  """Exit Cover API is a functionality to enable user to easily exit an open stoploss order by converting it
542
543
  into Exit order."""
543
544
  try:
@@ -583,7 +584,7 @@ class XTSConnect(XTSCommon):
583
584
  traceback.print_exc()
584
585
  raise BrokerException("squareoff_position Failed for XTS")
585
586
 
586
- def get_order_history(self, appOrderID, clientID: str | None = None):
587
+ def get_order_history(self, appOrderID: int, clientID: str | None = None):
587
588
  """Order history will provide particular order trail chain. This indicate the particular order & its state
588
589
  changes. i.e.Pending New to New, New to PartiallyFilled, PartiallyFilled, PartiallyFilled & PartiallyFilled
589
590
  to Filled etc"""
@@ -677,7 +678,7 @@ class XTSConnect(XTSCommon):
677
678
  traceback.print_exc()
678
679
  raise BrokerException("send_unsubscription Failed for XTS")
679
680
 
680
- def get_master(self, exchangeSegmentList):
681
+ def get_master(self, exchangeSegmentList: List[ExchangeSegmentType]):
681
682
  try:
682
683
  params: Dict[str, Any] = {"exchangeSegmentList": exchangeSegmentList}
683
684
  response = self._post("market.instruments.master", json.dumps(params))
@@ -688,7 +689,7 @@ class XTSConnect(XTSCommon):
688
689
 
689
690
  def get_ohlc(
690
691
  self,
691
- exchangeSegment,
692
+ exchangeSegment: ExchangeSegmentType,
692
693
  exchangeInstrumentID,
693
694
  startTime,
694
695
  endTime,
@@ -708,7 +709,7 @@ class XTSConnect(XTSCommon):
708
709
  traceback.print_exc()
709
710
  raise BrokerException("get_ohlc Failed for XTS")
710
711
 
711
- def get_series(self, exchangeSegment):
712
+ def get_series(self, exchangeSegment: ExchangeSegmentType):
712
713
  try:
713
714
  params: Dict[str, Any] = {"exchangeSegment": exchangeSegment}
714
715
  response = self._get("market.instruments.instrument.series", params)
@@ -717,7 +718,7 @@ class XTSConnect(XTSCommon):
717
718
  traceback.print_exc()
718
719
  raise BrokerException("get_series Failed for XTS")
719
720
 
720
- def get_equity_symbol(self, exchangeSegment, series, symbol):
721
+ def get_equity_symbol(self, exchangeSegment: ExchangeSegmentType, series, symbol):
721
722
  try:
722
723
  params: Dict[str, Any] = {
723
724
  "exchangeSegment": exchangeSegment,
@@ -730,7 +731,7 @@ class XTSConnect(XTSCommon):
730
731
  traceback.print_exc()
731
732
  raise BrokerException("get_equity_symbol Failed for XTS")
732
733
 
733
- def get_expiry_date(self, exchangeSegment, series, symbol):
734
+ def get_expiry_date(self, exchangeSegment: ExchangeSegmentType, series, symbol):
734
735
  try:
735
736
  params: Dict[str, Any] = {
736
737
  "exchangeSegment": exchangeSegment,
@@ -743,7 +744,9 @@ class XTSConnect(XTSCommon):
743
744
  traceback.print_exc()
744
745
  raise BrokerException("get_expiry_date Failed for XTS")
745
746
 
746
- def get_future_symbol(self, exchangeSegment, series, symbol, expiryDate):
747
+ def get_future_symbol(
748
+ self, exchangeSegment: ExchangeSegmentType, series, symbol, expiryDate
749
+ ):
747
750
  try:
748
751
  params: Dict[str, Any] = {
749
752
  "exchangeSegment": exchangeSegment,
@@ -758,7 +761,13 @@ class XTSConnect(XTSCommon):
758
761
  raise BrokerException("get_future_symbol Failed for XTS")
759
762
 
760
763
  def get_option_symbol(
761
- self, exchangeSegment, series, symbol, expiryDate, optionType, strikePrice
764
+ self,
765
+ exchangeSegment: ExchangeSegmentType,
766
+ series,
767
+ symbol,
768
+ expiryDate,
769
+ optionType,
770
+ strikePrice,
762
771
  ):
763
772
  try:
764
773
  params: Dict[str, Any] = {
@@ -775,7 +784,9 @@ class XTSConnect(XTSCommon):
775
784
  traceback.print_exc()
776
785
  raise BrokerException("get_option_symbol Failed for XTS")
777
786
 
778
- def get_option_type(self, exchangeSegment, series, symbol, expiryDate):
787
+ def get_option_type(
788
+ self, exchangeSegment: ExchangeSegmentType, series, symbol, expiryDate
789
+ ):
779
790
  try:
780
791
  params: Dict[str, Any] = {
781
792
  "exchangeSegment": exchangeSegment,
@@ -789,7 +800,7 @@ class XTSConnect(XTSCommon):
789
800
  traceback.print_exc()
790
801
  raise BrokerException("get_option_type Failed for XTS")
791
802
 
792
- def get_index_list(self, exchangeSegment):
803
+ def get_index_list(self, exchangeSegment: ExchangeSegmentType):
793
804
  try:
794
805
  params: Dict[str, Any] = {"exchangeSegment": exchangeSegment}
795
806
  response = self._get("market.instruments.indexlist", params)
@@ -1,5 +1,5 @@
1
- from typing import Literal
2
- import socketio
1
+ from typing import Any, Dict, List, Literal
2
+ import socketio # type: ignore
3
3
 
4
4
 
5
5
  class OrderSocket_io(socketio.Client):
@@ -38,18 +38,18 @@ class OrderSocket_io(socketio.Client):
38
38
 
39
39
  def __init__(
40
40
  self,
41
- token,
42
- userID,
43
- root_url,
44
- reconnection=True,
45
- reconnection_attempts=0,
46
- reconnection_delay=1,
47
- reconnection_delay_max=50000,
48
- randomization_factor=0.5,
49
- logger=False,
50
- binary=False,
51
- json=None,
52
- **kwargs,
41
+ token: str,
42
+ userID: str,
43
+ root_url: str,
44
+ reconnection: bool = True,
45
+ reconnection_attempts: int = 0,
46
+ reconnection_delay: float = 1,
47
+ reconnection_delay_max: float = 50000,
48
+ randomization_factor: float = 0.5,
49
+ logger: bool = False,
50
+ binary: bool = False,
51
+ json: Any | None = None,
52
+ **kwargs: Any,
53
53
  ):
54
54
  self.sid = socketio.Client(logger=False, engineio_logger=False)
55
55
  self.eventlistener = self.sid
@@ -65,24 +65,24 @@ class OrderSocket_io(socketio.Client):
65
65
  port + self.token + "&userID=" + self.userID + "&apiType=INTERACTIVE"
66
66
  )
67
67
 
68
- def setup_event_listners(self, on_order):
69
- self.sid.on("order", on_order)
68
+ def setup_event_listners(self, on_order: Any):
69
+ self.sid.on("order", on_order) # type: ignore
70
70
 
71
71
  # self.sid.on("connect", self.on_connect)
72
- self.sid.on("message", self.on_message)
72
+ self.sid.on("message", self.on_message) # type: ignore
73
73
  # self.sid.on("joined", self.on_joined)
74
- self.sid.on("error", self.on_error)
75
- self.sid.on("trade", self.on_trade)
76
- self.sid.on("position", self.on_position)
77
- self.sid.on("tradeConversion", self.on_tradeconversion)
78
- self.sid.on("logout", self.on_messagelogout)
74
+ self.sid.on("error", self.on_error) # type: ignore
75
+ self.sid.on("trade", self.on_trade) # type: ignore
76
+ self.sid.on("position", self.on_position) # type: ignore
77
+ self.sid.on("tradeConversion", self.on_tradeconversion) # type: ignore
78
+ self.sid.on("logout", self.on_messagelogout) # type: ignore
79
79
  # self.sid.on("disconnect", self.on_disconnect)
80
80
 
81
81
  def connect( # type: ignore
82
82
  self,
83
- headers={},
83
+ headers: Dict[str, str] = {},
84
84
  transports: Literal["polling", "websocket"] = "websocket",
85
- namespaces=None,
85
+ namespaces: List[str] | None = None,
86
86
  socketio_path: str = "/interactive/socket.io",
87
87
  verify: bool = False,
88
88
  ):
@@ -108,7 +108,7 @@ class OrderSocket_io(socketio.Client):
108
108
  url = self.connection_url
109
109
 
110
110
  """Connected to the socket."""
111
- self.sid.connect(url, headers, transports, namespaces, socketio_path)
111
+ self.sid.connect(url, headers, transports, namespaces, socketio_path) # type: ignore
112
112
  self.sid.wait()
113
113
  """Disconnect from the socket."""
114
114
  # self.sid.disconnect()
@@ -121,33 +121,33 @@ class OrderSocket_io(socketio.Client):
121
121
  """On message from socket"""
122
122
  print("I received a message!")
123
123
 
124
- def on_joined(self, data):
124
+ def on_joined(self, data: Any):
125
125
  """On socket joined"""
126
- print("Interactive socket joined successfully!" + data)
126
+ print(f"Interactive socket joined successfully!{data}")
127
127
 
128
- def on_error(self, data):
128
+ def on_error(self, data: Any):
129
129
  """On receiving error from socket"""
130
- print("Interactive socket error!" + data)
130
+ print(f"Interactive socket error!{data}")
131
131
 
132
- def on_order(self, data):
132
+ def on_order(self, data: Any):
133
133
  """On receiving order placed data from socket"""
134
- print("Order placed!" + data)
134
+ print(f"Order placed!{data}")
135
135
 
136
- def on_trade(self, data):
136
+ def on_trade(self, data: Any):
137
137
  """On receiving trade data from socket"""
138
- print("Trade Received!" + data)
138
+ print(f"Trade Received!{data}")
139
139
 
140
- def on_position(self, data):
140
+ def on_position(self, data: Any):
141
141
  """On receiving position data from socket"""
142
- print("Position Retrieved!" + data)
142
+ print(f"Position Retrieved!{data}")
143
143
 
144
- def on_tradeconversion(self, data):
144
+ def on_tradeconversion(self, data: Any):
145
145
  """On receiving trade conversion data from socket"""
146
- print("Trade Conversion Received!" + data)
146
+ print(f"Trade Conversion Received!{data}")
147
147
 
148
- def on_messagelogout(self, data):
148
+ def on_messagelogout(self, data: Any):
149
149
  """On receiving user logout message"""
150
- print("User logged out!" + data)
150
+ print(f"User logged out!{data}")
151
151
 
152
152
  def on_disconnect(self):
153
153
  """On receiving disconnection from socket"""
@@ -0,0 +1,7 @@
1
+ from typing import Literal
2
+
3
+
4
+ ExchangeSegmentType = Literal[1, 2, 3, 11, 12]
5
+ XTSMessageCodeType = Literal[1501, 1502, 1505, 1507, 1510, 1512, 1105]
6
+ PublishFormatType = Literal["JSON", "Binary"]
7
+ ExchangeType = Literal["NSECM", "NSEFO", "NSECD", "BSECM", "BSEFO"]
@@ -8,12 +8,12 @@ from quantplay.model.instrument_data import InstrumentDataType
8
8
  class PickleUtils:
9
9
  @staticmethod
10
10
  def save_data(data: Any, file_name: str):
11
- with open("/tmp/{}.pickle".format(file_name), "wb") as handle:
11
+ with open(f"/tmp/{file_name}.pickle", "wb") as handle:
12
12
  pickle.dump(data, handle, protocol=pickle.HIGHEST_PROTOCOL)
13
13
 
14
14
  @staticmethod
15
15
  def load_data(file_name: str):
16
- with open("/tmp/{}.pickle".format(file_name), "rb") as disk_data:
16
+ with open(f"/tmp/{file_name}.pickle", "rb") as disk_data:
17
17
  unserialized_data = pickle.load(disk_data)
18
18
 
19
19
  return unserialized_data
@@ -44,7 +44,7 @@ class InstrumentData:
44
44
 
45
45
  try:
46
46
  self.lock.acquire()
47
- with open("/tmp/{}.pickle".format(file_name), "rb") as disk_data:
47
+ with open(f"/tmp/{file_name}.pickle", "rb") as disk_data:
48
48
  unserialized_data = pickle.load(disk_data)
49
49
  self.instrument_data[file_name] = unserialized_data
50
50
  self.lock.release()
@@ -37,15 +37,15 @@ class S3Utils:
37
37
  lock.release()
38
38
 
39
39
  except Exception:
40
- print("Data not found for {}".format(key))
40
+ print(f"Data not found for {key}")
41
41
 
42
- print("fetching bucket from s3 {} key {}".format(bucket, key))
42
+ print(f"fetching bucket from s3 {bucket} key {key}")
43
43
 
44
44
  client = boto3.client("s3") # type: ignore
45
45
  raw_stream = client.get_object(Bucket=bucket, Key=key)
46
46
  content = raw_stream["Body"].read().decode("utf-8")
47
47
 
48
- print("Saving data at {}".format("/tmp/" + key))
48
+ print(f"Saving data at /tmp/{key}")
49
49
  full_folder_path = full_path[0 : full_path.rfind("/")]
50
50
  if not os.path.exists(full_folder_path):
51
51
  os.makedirs(full_folder_path)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantplay
3
- Version: 2.0.34
3
+ Version: 2.0.36
4
4
  Summary: This python package will be stored in AWS CodeArtifact
5
5
  Home-page:
6
6
  Author:
@@ -43,6 +43,7 @@ quantplay/model/broker.py
43
43
  quantplay/model/generics.py
44
44
  quantplay/model/instrument_data.py
45
45
  quantplay/model/order_event.py
46
+ quantplay/model/xts.py
46
47
  quantplay/utils/__init__.py
47
48
  quantplay/utils/constant.py
48
49
  quantplay/utils/exchange.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.34",
24
+ version="2.0.36",
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