quantplay 2.0.92__tar.gz → 2.0.94__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.92 → quantplay-2.0.94}/PKG-INFO +1 -26
  2. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/dhan.py +13 -16
  3. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/motilal.py +31 -16
  4. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/noren.py +16 -0
  5. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/xts.py +43 -99
  6. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/xts_utils/Connect.py +408 -266
  7. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/wrapper/aws/s3.py +1 -6
  8. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay.egg-info/PKG-INFO +1 -26
  9. {quantplay-2.0.92 → quantplay-2.0.94}/setup.py +1 -1
  10. {quantplay-2.0.92 → quantplay-2.0.94}/README.md +0 -0
  11. {quantplay-2.0.92 → quantplay-2.0.94}/pyproject.toml +0 -0
  12. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/__init__.py +0 -0
  13. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/__init__.py +0 -0
  14. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/aliceblue.py +0 -0
  15. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/angelone.py +0 -0
  16. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/auto_login/__init__.py +0 -0
  17. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/auto_login/aliceblue.py +0 -0
  18. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/broker_factory.py +0 -0
  19. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/finvasia_utils/__init__.py +0 -0
  20. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/finvasia_utils/fa_noren.py +0 -0
  21. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/five_paisa.py +0 -0
  22. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/flattrade.py +0 -0
  23. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/ft_utils/__init__.py +0 -0
  24. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/ft_utils/flattrade_utils.py +0 -0
  25. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/ft_utils/ft_noren.py +0 -0
  26. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/generics/__init__.py +0 -0
  27. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/generics/broker.py +0 -0
  28. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/iifl_xts.py +0 -0
  29. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/kite_utils.py +0 -0
  30. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/kotak.py +0 -0
  31. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/shoonya.py +0 -0
  32. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/uplink/__init__.py +0 -0
  33. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/uplink/uplink_utils.py +0 -0
  34. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/upstox.py +0 -0
  35. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/xts_utils/Exception.py +0 -0
  36. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/xts_utils/InteractiveSocketClient.py +0 -0
  37. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/xts_utils/__init__.py +0 -0
  38. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/broker/zerodha.py +1 -1
  39. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/exception/__init__.py +0 -0
  40. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/exception/exceptions.py +0 -0
  41. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/model/__init__.py +0 -0
  42. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/model/broker.py +0 -0
  43. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/model/generics.py +0 -0
  44. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/model/instrument_data.py +0 -0
  45. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/model/order_event.py +0 -0
  46. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/py.typed +0 -0
  47. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/utils/__init__.py +0 -0
  48. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/utils/caching.py +0 -0
  49. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/utils/constant.py +0 -0
  50. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/utils/exchange.py +0 -0
  51. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/utils/number_utils.py +0 -0
  52. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/utils/pickle_utils.py +0 -0
  53. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/utils/selenium_utils.py +0 -0
  54. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/wrapper/__init__.py +0 -0
  55. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay/wrapper/aws/__init__.py +0 -0
  56. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay.egg-info/SOURCES.txt +0 -0
  57. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay.egg-info/dependency_links.txt +0 -0
  58. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay.egg-info/requires.txt +0 -0
  59. {quantplay-2.0.92 → quantplay-2.0.94}/quantplay.egg-info/top_level.txt +0 -0
  60. {quantplay-2.0.92 → quantplay-2.0.94}/setup.cfg +0 -0
  61. {quantplay-2.0.92 → quantplay-2.0.94}/tests/__init__.py +0 -0
  62. {quantplay-2.0.92 → quantplay-2.0.94}/tests/conftest.py +0 -0
  63. {quantplay-2.0.92 → quantplay-2.0.94}/tests/wrapper/__init__.py +0 -0
  64. {quantplay-2.0.92 → quantplay-2.0.94}/tests/wrapper/aws/__init__.py +0 -0
  65. {quantplay-2.0.92 → quantplay-2.0.94}/tests/wrapper/aws/s3_test.py +0 -0
@@ -1,36 +1,11 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantplay
3
- Version: 2.0.92
3
+ Version: 2.0.94
4
4
  Summary: This python package will be stored in AWS CodeArtifact
5
5
  Home-page:
6
6
  Author:
7
7
  Author-email:
8
8
  License: MIT
9
- Requires-Dist: setuptools
10
- Requires-Dist: path
11
- Requires-Dist: pyotp
12
- Requires-Dist: retrying
13
- Requires-Dist: boto3
14
- Requires-Dist: numpy
15
- Requires-Dist: websocket-client
16
- Requires-Dist: smartapi-python
17
- Requires-Dist: logzero
18
- Requires-Dist: selenium
19
- Requires-Dist: requests
20
- Requires-Dist: pandas
21
- Requires-Dist: pyarrow
22
- Requires-Dist: polars
23
- Requires-Dist: kiteconnect
24
- Requires-Dist: pya3
25
- Requires-Dist: py5paisa
26
- Requires-Dist: upstox-python-sdk
27
- Requires-Dist: undetected-chromedriver
28
- Requires-Dist: cachetools
29
- Requires-Dist: py_vollib
30
- Requires-Dist: python-engineio
31
- Requires-Dist: python-socketio
32
- Requires-Dist: six
33
- Requires-Dist: dhanhq
34
9
 
35
10
  # Quantplay Alpha playground
36
11
 
@@ -102,14 +102,6 @@ class Dhan(Broker):
102
102
  self.dhan.DAY,
103
103
  )
104
104
 
105
- response = self.wrapper.modify_order( # type: ignore
106
- order_id=order_id,
107
- variety=order["variety"],
108
- price=order["price"],
109
- trigger_price=order["trigger_price"],
110
- order_type=order["order_type"],
111
- )
112
- return response # type:ignore
113
105
  except Exception as e:
114
106
  exception_message = (
115
107
  "OrderModificationFailed for {} failed with exception {}".format(
@@ -159,8 +151,7 @@ class Dhan(Broker):
159
151
  return dhanhq.CNC
160
152
  elif product == "MIS":
161
153
  return dhanhq.INTRA
162
-
163
- raise InvalidArgumentException(f"Product {product} not supported for trading")
154
+ return product
164
155
 
165
156
  def get_symbol(self, symbol: str, exchange: ExchangeType | None = None):
166
157
  if symbol not in self.quantplay_symbol_map:
@@ -182,19 +173,25 @@ class Dhan(Broker):
182
173
  trigger_price: float | None = None,
183
174
  ) -> str | None:
184
175
  try:
185
- Constants.logger.info(
186
- f"[PLACING_ORDER] {tradingsymbol} {exchange} {quantity} {tag}"
187
- )
188
176
  tradingsymbol = self.get_symbol(tradingsymbol)
189
177
  security_id = self.symbol_data[f"{exchange}:{tradingsymbol}"]["token"]
178
+ exchange_segment = self.get_exchange_segment(exchange)
179
+ dhan_order_type = self.get_order_type(order_type)
180
+ product_type = self.get_product(product)
181
+ Constants.logger.info(
182
+ f"[DHAN_PLACING_ORDER] {security_id} {exchange} {transaction_type} {quantity} {dhan_order_type} {product_type} {price} {trigger_price}"
183
+ )
184
+ if trigger_price is None:
185
+ trigger_price = 0
190
186
  order_id: str = self.dhan.place_order( # type:ignore
191
187
  security_id=security_id, # hdfcbank
192
- exchange_segment=self.get_exchange_segment(exchange),
188
+ exchange_segment=exchange_segment,
193
189
  transaction_type=transaction_type,
194
190
  quantity=quantity,
195
- order_type=self.get_order_type(order_type),
196
- product_type=self.get_product(product),
191
+ order_type=dhan_order_type,
192
+ product_type=product_type,
197
193
  price=price,
194
+ trigger_price=trigger_price, # type:ignore
198
195
  )
199
196
 
200
197
  return order_id # type:ignore
@@ -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(),
@@ -250,6 +250,11 @@ class Noren(Broker):
250
250
  f"[PLACE_ORDER_FAILED] {exception_message}"
251
251
  )
252
252
 
253
+ @retry(
254
+ wait_exponential_multiplier=3000,
255
+ wait_exponential_max=10000,
256
+ stop_max_attempt_number=3,
257
+ )
253
258
  def ltp(self, exchange: ExchangeType, tradingsymbol: str):
254
259
  tradingsymbol = self.get_symbol(tradingsymbol, exchange)
255
260
 
@@ -375,6 +380,11 @@ class Noren(Broker):
375
380
 
376
381
  return response
377
382
 
383
+ @retry(
384
+ wait_exponential_multiplier=3000,
385
+ wait_exponential_max=10000,
386
+ stop_max_attempt_number=3,
387
+ )
378
388
  def holdings(self):
379
389
  holdings = self.invoke_noren_api(self.api.get_holdings)
380
390
  if holdings is None or len(holdings) == 0:
@@ -685,6 +695,12 @@ class Noren(Broker):
685
695
  traceback.print_exc()
686
696
  raise RetryableException("Failed to Receive Data from broker. Retrying Again")
687
697
 
698
+ @retry(
699
+ wait_exponential_multiplier=1000,
700
+ wait_exponential_max=10000,
701
+ stop_max_attempt_number=3,
702
+ retry_on_exception=retry_exception,
703
+ )
688
704
  def margins(self) -> MarginsResponse:
689
705
  api_margins = self.invoke_noren_api(self.api.get_limits)
690
706
 
@@ -12,12 +12,6 @@ from retrying import retry # type: ignore
12
12
 
13
13
  from quantplay.broker.generics.broker import Broker
14
14
  from quantplay.broker.xts_utils.Connect import XTSConnect
15
- from quantplay.broker.xts_utils.Exception import (
16
- XTSDataException,
17
- XTSGeneralException,
18
- XTSNetworkException,
19
- XTSTokenException,
20
- )
21
15
  from quantplay.broker.xts_utils.InteractiveSocketClient import OrderSocket_io
22
16
  from quantplay.exception.exceptions import (
23
17
  BrokerException,
@@ -82,11 +76,8 @@ class XTS(Broker):
82
76
  self.load_instrument()
83
77
 
84
78
  def set_wrapper(self, serialized_wrapper: str, serialized_md_wrapper: str):
85
- self.wrapper: XTSConnect = pickle.loads(
86
- codecs.decode(serialized_wrapper.encode(), "base64")
87
- )
88
-
89
- self.md_wrapper: XTSConnect = pickle.loads(
79
+ self.wrapper = pickle.loads(codecs.decode(serialized_wrapper.encode(), "base64"))
80
+ self.md_wrapper = pickle.loads(
90
81
  codecs.decode(serialized_md_wrapper.encode(), "base64")
91
82
  )
92
83
 
@@ -110,34 +101,29 @@ class XTS(Broker):
110
101
 
111
102
  ins_type = instrument["instrument_type"]
112
103
  name = instrument["name"]
113
-
114
104
  if ins_type in ["CE", "PE"]:
115
105
  expiry = datetime.strftime(
116
106
  datetime.strptime(str(instrument["expiry"]), "%Y-%m-%d"),
117
107
  "%d%b%Y",
118
108
  ).upper()
119
109
  strike = str(instrument["strike"]).rstrip("0")
120
-
121
110
  if strike[-1] == ".":
122
111
  strike = strike[:-1]
123
-
124
112
  instrument["broker_symbol"] = f"{name} {expiry} {ins_type} {strike}"
125
-
126
113
  elif ins_type == "FUT":
127
114
  expiry = datetime.strftime(
128
115
  datetime.strptime(str(instrument["expiry"]), "%Y-%m-%d"),
129
116
  "%d%b%Y",
130
117
  ).upper()
131
118
  instrument["broker_symbol"] = f"{name} {expiry}"
132
-
133
119
  else:
134
120
  instrument["broker_symbol"] = tradingsymbol
135
121
 
122
+ # TODO: Types
136
123
  self.symbol_data[f"{exchange}:{tradingsymbol}"] = instrument # type: ignore
137
124
 
138
125
  PickleUtils.save_data(self.symbol_data, "xts_instruments")
139
126
  Constants.logger.info("[LOADING_INSTRUMENTS] loading data from server")
140
-
141
127
  self.initialize_broker_symbol_map()
142
128
 
143
129
  def login(self, api_key: str, api_secret: str, md_api_key: str, md_api_secret: str):
@@ -147,53 +133,48 @@ class XTS(Broker):
147
133
  secretKey=api_secret,
148
134
  root=self.root_url,
149
135
  )
150
- xt_core_response = self.invoke_xts_api(self.wrapper.interactive_login)
151
-
136
+ xt_core_response = self.wrapper.interactive_login()
152
137
  self.md_wrapper = XTSConnect(
153
138
  apiKey=md_api_key,
154
139
  secretKey=md_api_secret,
155
140
  root=self.root_url,
156
141
  )
157
- md_response = self.invoke_xts_api(self.md_wrapper.marketdata_login)
158
-
142
+ md_response = self.md_wrapper.marketdata_login()
159
143
  if "type" not in xt_core_response or xt_core_response["type"] != "success":
160
144
  print(f"api login response {xt_core_response}")
161
145
  raise TokenException("Api key credentials are incorrect")
162
-
163
146
  if "type" not in md_response or md_response["type"] != "success":
164
147
  print(f"market data login response {md_response}")
165
148
  raise TokenException("Market data api credentials are invalid")
166
-
167
149
  self.ClientID = xt_core_response["result"]["userID"]
168
-
169
150
  except TokenException:
170
151
  raise
171
-
172
152
  except Exception:
173
153
  raise InvalidArgumentException("Invalid api key/secret")
174
154
 
175
155
  def handle_exception(self, response: Dict[str, Any]):
176
156
  if "data" in response and "description" in response["data"]:
177
157
  data = response["data"]
178
-
179
158
  if "max limit" in data["description"].lower():
180
159
  user_id = self.profile()["user_id"]
181
160
  print("Rate limit problem")
182
161
  raise RetryableException(f"{user_id}: Request limit exceeded")
183
-
184
162
  if (
185
163
  "description" in response
186
164
  and "Authorization not found" in response["description"]
187
165
  ):
188
166
  raise TokenException(response["description"])
189
-
190
167
  if "type" in response and response["type"] == "error":
191
168
  raise Exception(f"[XTS_Error]: {response['description']}")
192
169
 
170
+ @retry(
171
+ wait_exponential_multiplier=3000,
172
+ wait_exponential_max=10000,
173
+ stop_max_attempt_number=3,
174
+ retry_on_exception=retry_exception,
175
+ )
193
176
  def margins(self) -> MarginsResponse:
194
- api_response = self.invoke_xts_api(
195
- self.wrapper.get_balance, clientID=self.ClientID
196
- )
177
+ api_response = self.wrapper.get_balance(clientID=self.ClientID)
197
178
  self.handle_exception(api_response)
198
179
 
199
180
  if not api_response:
@@ -213,10 +194,14 @@ class XTS(Broker):
213
194
  "cash": 0,
214
195
  }
215
196
 
197
+ @retry(
198
+ wait_exponential_multiplier=3000,
199
+ wait_exponential_max=10000,
200
+ stop_max_attempt_number=3,
201
+ retry_on_exception=retry_exception,
202
+ )
216
203
  def profile(self) -> UserBrokerProfileResponse:
217
- api_response = self.invoke_xts_api(
218
- self.wrapper.get_profile, clientID=self.ClientID
219
- )
204
+ api_response = self.wrapper.get_profile(self.ClientID)
220
205
  self.handle_exception(api_response)
221
206
  api_response = api_response["result"]
222
207
 
@@ -228,10 +213,14 @@ class XTS(Broker):
228
213
 
229
214
  return response
230
215
 
216
+ @retry(
217
+ wait_exponential_multiplier=3000,
218
+ wait_exponential_max=10000,
219
+ stop_max_attempt_number=3,
220
+ retry_on_exception=retry_exception,
221
+ )
231
222
  def orders(self, tag: str | None = None, add_ltp: bool = True) -> pl.DataFrame:
232
- api_response = self.invoke_xts_api(
233
- self.wrapper.get_order_book, clientID=self.ClientID
234
- )
223
+ api_response = self.wrapper.get_order_book(self.ClientID)
235
224
  self.handle_exception(api_response)
236
225
 
237
226
  api_response = api_response["result"]
@@ -356,13 +345,22 @@ class XTS(Broker):
356
345
 
357
346
  return orders_df[list(self.orders_schema.keys())].cast(self.orders_schema)
358
347
 
348
+ @retry(
349
+ wait_exponential_multiplier=3000,
350
+ wait_exponential_max=10000,
351
+ stop_max_attempt_number=3,
352
+ )
359
353
  def holdings(self):
360
354
  return pl.DataFrame(schema=self.holidings_schema)
361
355
 
356
+ @retry(
357
+ wait_exponential_multiplier=3000,
358
+ wait_exponential_max=10000,
359
+ stop_max_attempt_number=3,
360
+ retry_on_exception=retry_exception,
361
+ )
362
362
  def positions(self, drop_cnc: bool = True) -> pl.DataFrame:
363
- api_response = self.invoke_xts_api(
364
- self.wrapper.get_position_daywise, clientID=self.ClientID
365
- )
363
+ api_response = self.wrapper.get_position_daywise(self.ClientID)
366
364
  self.handle_exception(api_response)
367
365
 
368
366
  api_response = api_response["result"]["positionList"]
@@ -480,9 +478,7 @@ class XTS(Broker):
480
478
  }
481
479
  for x in symbols
482
480
  ]
483
-
484
- api_response = self.invoke_xts_api(
485
- self.md_wrapper.get_quote,
481
+ api_response = self.md_wrapper.get_quote(
486
482
  Instruments=instruments,
487
483
  xtsMessageCode=1512,
488
484
  publishFormat="JSON",
@@ -490,7 +486,6 @@ class XTS(Broker):
490
486
 
491
487
  if "type" in api_response and api_response["type"] == "error":
492
488
  raise TokenException(api_response["description"])
493
-
494
489
  api_response = api_response["result"]
495
490
 
496
491
  ltp_json = api_response["listQuotes"]
@@ -546,8 +541,7 @@ class XTS(Broker):
546
541
  "", # TODO
547
542
  )
548
543
 
549
- api_response = self.invoke_xts_api(
550
- self.md_wrapper.get_quote,
544
+ api_response = self.md_wrapper.get_quote(
551
545
  Instruments=[
552
546
  {
553
547
  "exchangeSegment": exchange_code,
@@ -567,7 +561,6 @@ class XTS(Broker):
567
561
 
568
562
  try:
569
563
  ltp_json = api_response["listQuotes"][0]
570
-
571
564
  except IndexError as e:
572
565
  print(api_response, e)
573
566
  raise BrokerException("Broker Provided Invalid Response")
@@ -600,8 +593,7 @@ class XTS(Broker):
600
593
  if tag is None:
601
594
  tag = ""
602
595
 
603
- api_response = self.invoke_xts_api(
604
- self.wrapper.place_order,
596
+ api_response = self.wrapper.place_order(
605
597
  exchangeSegment=exchange_name,
606
598
  exchangeInstrumentID=exchange_token,
607
599
  orderType=xts_order_type,
@@ -634,8 +626,7 @@ class XTS(Broker):
634
626
 
635
627
  tag = order_data["tag"]
636
628
 
637
- api_response = self.invoke_xts_api(
638
- self.wrapper.cancel_order,
629
+ api_response = self.wrapper.cancel_order(
639
630
  appOrderID=int(order_id),
640
631
  clientID=order_data["user_id"],
641
632
  orderUniqueIdentifier=tag,
@@ -687,8 +678,7 @@ class XTS(Broker):
687
678
  time_in_force = "DAY"
688
679
  disclosed_quantity = 0
689
680
 
690
- api_response = self.invoke_xts_api(
691
- self.wrapper.modify_order,
681
+ api_response = self.wrapper.modify_order(
692
682
  appOrderID=int(order_id),
693
683
  modifiedTimeInForce=time_in_force,
694
684
  modifiedDisclosedQuantity=disclosed_quantity,
@@ -816,49 +806,3 @@ class XTS(Broker):
816
806
  except Exception as e:
817
807
  print(e)
818
808
  Constants.logger.error("[ORDER_UPDATE_PROCESSING_FAILED] {}".format(e))
819
-
820
- @retry(
821
- wait_exponential_multiplier=3000,
822
- wait_exponential_max=10000,
823
- stop_max_attempt_number=3,
824
- retry_on_exception=retry_exception,
825
- )
826
- def invoke_xts_api(self, fn: Any, *args: Any, **kwargs: Any) -> Dict[str, Any]:
827
- try:
828
- response = fn(*args, **kwargs)
829
-
830
- if "data" in response and "description" in response["data"]:
831
- data = response["data"]
832
-
833
- if "max limit" in data["description"].lower():
834
- user_id = self.profile()["user_id"]
835
- print("Rate limit problem")
836
- raise RetryableException(f"{user_id}: Request limit exceeded")
837
-
838
- if (
839
- "description" in response
840
- and "Authorization not found" in response["description"]
841
- ):
842
- raise TokenException(response["description"])
843
-
844
- if "type" in response and response["type"] == "error":
845
- raise Exception(f"[XTS_Error]: {response['description']}")
846
-
847
- return response
848
-
849
- except XTSTokenException as e:
850
- raise TokenException(str(e))
851
-
852
- except (TokenException, RetryableException):
853
- raise
854
-
855
- except (
856
- XTSGeneralException,
857
- XTSDataException,
858
- XTSNetworkException,
859
- ) as e:
860
- raise BrokerException(str(e))
861
-
862
- except Exception:
863
- traceback.print_exc()
864
- raise