quantplay 1.2.41__tar.gz → 1.2.46__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 (102) hide show
  1. {quantplay-1.2.41 → quantplay-1.2.46}/PKG-INFO +1 -1
  2. quantplay-1.2.46/quantplay/broker/iifl_xts.py +16 -0
  3. quantplay-1.2.46/quantplay/broker/symphony.py +16 -0
  4. quantplay-1.2.46/quantplay/broker/xts.py +263 -0
  5. quantplay-1.2.46/quantplay/broker/xts_utils/Connect.py +877 -0
  6. quantplay-1.2.46/quantplay/broker/xts_utils/Exception.py +81 -0
  7. quantplay-1.2.46/quantplay/broker/xts_utils/InteractiveSocketClient.py +142 -0
  8. quantplay-1.2.46/quantplay/broker/xts_utils/MarketDataSocketClient.py +197 -0
  9. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/broker/zerodha.py +9 -2
  10. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/data_modify_script.py +2 -2
  11. quantplay-1.2.46/quantplay/date_fix.py +56 -0
  12. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/reporting/visuals.py +1 -1
  13. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/utils/data_utils.py +3 -0
  14. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay.egg-info/PKG-INFO +1 -1
  15. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay.egg-info/SOURCES.txt +8 -0
  16. {quantplay-1.2.41 → quantplay-1.2.46}/setup.py +1 -1
  17. quantplay-1.2.46/test/strategy/__init__.py +0 -0
  18. quantplay-1.2.41/quantplay/broker/symphony.py +0 -101
  19. {quantplay-1.2.41 → quantplay-1.2.46}/README.md +0 -0
  20. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/__init__.py +0 -0
  21. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/backtest/__init__.py +0 -0
  22. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/backtest/backtest_trades.py +0 -0
  23. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/broker/__init__.py +0 -0
  24. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/broker/angelone.py +0 -0
  25. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/broker/broker_client.py +0 -0
  26. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/broker/client.py +0 -0
  27. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/broker/finvasia_utils/__init__.py +0 -0
  28. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/broker/finvasia_utils/shoonya.py +0 -0
  29. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/broker/generics/__init__.py +0 -0
  30. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/broker/generics/broker.py +0 -0
  31. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/broker/kite_utils.py +0 -0
  32. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/broker/motilal.py +0 -0
  33. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/broker/shoonya.py +0 -0
  34. {quantplay-1.2.41/quantplay/brokerage → quantplay-1.2.46/quantplay/broker/xts_utils}/__init__.py +0 -0
  35. {quantplay-1.2.41/quantplay/brokerage/angelone → quantplay-1.2.46/quantplay/brokerage}/__init__.py +0 -0
  36. {quantplay-1.2.41/quantplay/brokerage/generics → quantplay-1.2.46/quantplay/brokerage/angelone}/__init__.py +0 -0
  37. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/brokerage/angelone/angel_broker.py +0 -0
  38. {quantplay-1.2.41/quantplay/brokerage/zerodha → quantplay-1.2.46/quantplay/brokerage/generics}/__init__.py +0 -0
  39. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/brokerage/generics/broker.py +0 -0
  40. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/brokerage/zerodha/ZBroker.py +0 -0
  41. {quantplay-1.2.41/quantplay/config → quantplay-1.2.46/quantplay/brokerage/zerodha}/__init__.py +0 -0
  42. {quantplay-1.2.41/quantplay/exception → quantplay-1.2.46/quantplay/config}/__init__.py +0 -0
  43. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/config/qplay_config.py +0 -0
  44. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/create_sample_data.py +0 -0
  45. {quantplay-1.2.41/quantplay/executor → quantplay-1.2.46/quantplay/exception}/__init__.py +0 -0
  46. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/exception/exceptions.py +0 -0
  47. {quantplay-1.2.41/quantplay/indicators → quantplay-1.2.46/quantplay/executor}/__init__.py +0 -0
  48. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/executor/strategy_executor.py +0 -0
  49. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/indicators/Indicator.py +0 -0
  50. {quantplay-1.2.41/quantplay/model → quantplay-1.2.46/quantplay/indicators}/__init__.py +0 -0
  51. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/indicators/atr.py +0 -0
  52. {quantplay-1.2.41/quantplay/model/exchange → quantplay-1.2.46/quantplay/model}/__init__.py +0 -0
  53. {quantplay-1.2.41/quantplay/model/strategy → quantplay-1.2.46/quantplay/model/exchange}/__init__.py +0 -0
  54. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/model/exchange/instrument.py +0 -0
  55. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/model/exchange/order.py +0 -0
  56. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/model/exchange/tick.py +0 -0
  57. {quantplay-1.2.41/quantplay/oms → quantplay-1.2.46/quantplay/model/strategy}/__init__.py +0 -0
  58. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/model/strategy/strategy_response.py +0 -0
  59. {quantplay-1.2.41/quantplay/order_execution → quantplay-1.2.46/quantplay/oms}/__init__.py +0 -0
  60. {quantplay-1.2.41/quantplay/reporting → quantplay-1.2.46/quantplay/order_execution}/__init__.py +0 -0
  61. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/order_execution/execution_algorithm.py +0 -0
  62. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/order_execution/mean_price.py +0 -0
  63. {quantplay-1.2.41/quantplay/services → quantplay-1.2.46/quantplay/reporting}/__init__.py +0 -0
  64. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/reporting/strategy_report.py +0 -0
  65. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/service.py +0 -0
  66. {quantplay-1.2.41/quantplay/strategies → quantplay-1.2.46/quantplay/services}/__init__.py +0 -0
  67. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/services/market.py +0 -0
  68. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/services/tradelens.py +0 -0
  69. {quantplay-1.2.41/quantplay/strategies/equities → quantplay-1.2.46/quantplay/strategies}/__init__.py +0 -0
  70. {quantplay-1.2.41/quantplay/strategies/equities/intraday → quantplay-1.2.46/quantplay/strategies/equities}/__init__.py +0 -0
  71. {quantplay-1.2.41/quantplay/strategies/equities/overnight → quantplay-1.2.46/quantplay/strategies/equities/intraday}/__init__.py +0 -0
  72. {quantplay-1.2.41/quantplay/strategies/futures → quantplay-1.2.46/quantplay/strategies/equities/overnight}/__init__.py +0 -0
  73. {quantplay-1.2.41/quantplay/strategies/futures/overnight → quantplay-1.2.46/quantplay/strategies/futures}/__init__.py +0 -0
  74. {quantplay-1.2.41/quantplay/strategies/options → quantplay-1.2.46/quantplay/strategies/futures/overnight}/__init__.py +0 -0
  75. {quantplay-1.2.41/quantplay/strategies/options/intraday → quantplay-1.2.46/quantplay/strategies/options}/__init__.py +0 -0
  76. {quantplay-1.2.41/quantplay/strategy → quantplay-1.2.46/quantplay/strategies/options/intraday}/__init__.py +0 -0
  77. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/strategies/options/intraday/ladder.py +0 -0
  78. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/strategies/options/intraday/musk.py +0 -0
  79. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/strategies/options/intraday/short_straddle.py +0 -0
  80. {quantplay-1.2.41/quantplay/utils → quantplay-1.2.46/quantplay/strategy}/__init__.py +0 -0
  81. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/strategy/base.py +0 -0
  82. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/strategy_run.py +0 -0
  83. {quantplay-1.2.41/test → quantplay-1.2.46/quantplay/utils}/__init__.py +0 -0
  84. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/utils/config_util.py +0 -0
  85. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/utils/constant.py +0 -0
  86. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/utils/exchange.py +0 -0
  87. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/utils/number_utils.py +0 -0
  88. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/utils/pickle_utils.py +0 -0
  89. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/utils/selenium_utils.py +0 -0
  90. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay/utils/transaction_utils.py +0 -0
  91. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay.egg-info/dependency_links.txt +0 -0
  92. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay.egg-info/requires.txt +0 -0
  93. {quantplay-1.2.41 → quantplay-1.2.46}/quantplay.egg-info/top_level.txt +0 -0
  94. {quantplay-1.2.41 → quantplay-1.2.46}/setup.cfg +0 -0
  95. {quantplay-1.2.41/test/broker → quantplay-1.2.46/test}/__init__.py +0 -0
  96. {quantplay-1.2.41/test/executor → quantplay-1.2.46/test/broker}/__init__.py +0 -0
  97. {quantplay-1.2.41 → quantplay-1.2.46}/test/broker/finvasia.py +0 -0
  98. {quantplay-1.2.41/test/strategy → quantplay-1.2.46/test/executor}/__init__.py +0 -0
  99. {quantplay-1.2.41 → quantplay-1.2.46}/test/executor/strategy_executor.py +0 -0
  100. {quantplay-1.2.41 → quantplay-1.2.46}/test/strategy/base.py +0 -0
  101. {quantplay-1.2.41 → quantplay-1.2.46}/test/strategy/sample_strategy.py +0 -0
  102. {quantplay-1.2.41 → quantplay-1.2.46}/test/test_motilal.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantplay
3
- Version: 1.2.41
3
+ Version: 1.2.46
4
4
  Summary: This python package will be stored in AWS CodeArtifact
5
5
  Home-page:
6
6
  Author:
@@ -0,0 +1,16 @@
1
+ from quantplay.broker.xts import XTS
2
+ from quantplay.utils.constant import timeit
3
+
4
+
5
+ class IIFL(XTS):
6
+ xts_interactive = "https://ttblaze.iifl.com"
7
+ xts_market = "https://ttblaze.iifl.com/apimarketdata"
8
+
9
+ @timeit(MetricName="Symphony:__init__")
10
+ def __init__(self, api_secret=None, api_key=None):
11
+ super().__init__(
12
+ api_secret=api_secret,
13
+ api_key=api_key,
14
+ root_interactive=self.xts_interactive,
15
+ root_market=self.xts_market,
16
+ )
@@ -0,0 +1,16 @@
1
+ from quantplay.broker.xts import XTS
2
+ from quantplay.utils.constant import timeit
3
+
4
+
5
+ class Symphony(XTS):
6
+ xts_interactive = "https://developers.symphonyfintech.in"
7
+ xts_market = "https://developers.symphonyfintech.in"
8
+
9
+ @timeit(MetricName="Symphony:__init__")
10
+ def __init__(self, api_secret=None, api_key=None):
11
+ super().__init__(
12
+ api_secret=api_secret,
13
+ api_key=api_key,
14
+ root_interactive=self.xts_interactive,
15
+ root_market=self.xts_market,
16
+ )
@@ -0,0 +1,263 @@
1
+ import traceback
2
+ import json
3
+
4
+ from quantplay.broker.generics.broker import Broker
5
+ from quantplay.utils.constant import Constants, timeit
6
+ from quantplay.broker.xts_utils.Connect import XTSConnect
7
+
8
+
9
+ class XTS(Broker):
10
+ source = "WebAPI"
11
+
12
+ @timeit(MetricName="XTS:__init__")
13
+ def __init__(
14
+ self,
15
+ api_secret,
16
+ api_key,
17
+ root_interactive,
18
+ root_market,
19
+ ):
20
+ super(XTS, self).__init__()
21
+
22
+ try:
23
+ self.wrapper = XTSConnect(
24
+ apiKey=api_key,
25
+ secretKey=api_secret,
26
+ source=self.source,
27
+ root_interactive=root_interactive,
28
+ root_market=root_market,
29
+ )
30
+ self.login()
31
+
32
+ except Exception as e:
33
+ print(traceback.print_exc())
34
+ raise e
35
+
36
+ def login(self):
37
+ response_interact = self.wrapper.interactive_login()
38
+ self.wrapper.marketdata_login()
39
+
40
+ self.ClientID = response_interact["result"]["clientCodes"][0]
41
+
42
+ def account_summary(self):
43
+ # TODO: Edit For Dealers
44
+
45
+ api_response = self.wrapper.get_balance(self.ClientID)
46
+
47
+ if not api_response:
48
+ raise Exception(
49
+ "[XTS_ERROR]: Balance API available for retail API users only, dealers can watch the same on dealer terminal"
50
+ )
51
+
52
+ api_response = api_response["result"]["BalanceList"][0]["limitObject"]
53
+
54
+ response = {
55
+ # TODO: Get PNL
56
+ "pnl": 0,
57
+ "margin_used": api_response["RMSSubLimits"]["marginUtilized"],
58
+ "margin_available": api_response["RMSSubLimits"]["netMarginAvailable"],
59
+ }
60
+
61
+ return response
62
+
63
+ def profile(self):
64
+ api_response = self.wrapper.get_profile(self.ClientID)["result"]
65
+
66
+ response = {
67
+ "user_id": api_response["ClientId"],
68
+ "full_name": api_response["ClientName"],
69
+ "segments": api_response["ClientExchangeDetailsList"],
70
+ }
71
+
72
+ return response
73
+
74
+ def orders(self):
75
+ # TODO: Transform into Quantplay
76
+ api_response = self.wrapper.get_order_book(self.ClientID)["result"]
77
+
78
+ return api_response
79
+
80
+ def positions(self):
81
+ # TODO: Transform into Quantplay
82
+ api_response = self.wrapper.get_position_daywise(self.ClientID)["result"]
83
+
84
+ return api_response
85
+
86
+ def get_symbol(self, exchange, symbol):
87
+ # TODO: Add Futures and Options
88
+
89
+ if exchange == 1:
90
+ response = self.wrapper.get_equity_symbol(
91
+ exchangeSegment=exchange, series="EQ", symbol=symbol
92
+ )
93
+
94
+ if response["type"] == "error":
95
+ raise Exception("[XTS_ERROR]: " + response["description"])
96
+
97
+ return response["result"][0]["ExchangeInstrumentID"]
98
+
99
+ elif exchange == 2:
100
+ # TODO: Ask
101
+ response = self.wrapper.get_option_symbol(
102
+ exchangeSegment=exchange, series="FUTIDX", symbol=symbol
103
+ )
104
+
105
+ if response["type"] == "error":
106
+ raise Exception("[XTS_ERROR]: " + response["description"])
107
+
108
+ return response["result"][0]["ExchangeInstrumentID"]
109
+
110
+ else:
111
+ raise Exception("UNSUPORTED_EXCHANGE: Exchange not in ['NSE', 'NFO']")
112
+
113
+ def get_exchange_code(self, exchange):
114
+ exchange_code_map = {
115
+ "NSE": 1,
116
+ "NFO": 2,
117
+ "NSECD": 3,
118
+ "BSECM": 11,
119
+ "BSEFO": 12,
120
+ }
121
+
122
+ if exchange not in exchange_code_map:
123
+ raise KeyError(
124
+ "INVALID_EXCHANGE: Exchange not in ['NSE', 'NFO', 'NSECD', 'BSECM', 'BSEFO']"
125
+ )
126
+
127
+ return exchange_code_map[exchange]
128
+
129
+ def get_exchange_name(self, exchange):
130
+ exchange_code_map = {
131
+ "NSE": "NSECM",
132
+ "NFO": "NSEFO",
133
+ "NSECD": "NSECD",
134
+ "BSECM": "BSECM",
135
+ "BSEFO": "BSEFO",
136
+ }
137
+
138
+ if exchange not in exchange_code_map:
139
+ raise KeyError(
140
+ "INVALID_EXCHANGE: Exchange not in ['NSE', 'NFO', 'NSECD', 'BSECM', 'BSEFO']"
141
+ )
142
+
143
+ return exchange_code_map[exchange]
144
+
145
+ def get_ltp(self, exchange=None, tradingsymbol=None):
146
+ exchange = self.get_exchange(exchange)
147
+ tradingsymbol = self.get_symbol(exchange, tradingsymbol)
148
+
149
+ api_response = self.wrapper.get_quote(
150
+ Instruments=[
151
+ {"exchangeSegment": exchange, "exchangeInstrumentID": tradingsymbol}
152
+ ],
153
+ xtsMessageCode=1512,
154
+ publishFormat="JSON",
155
+ )["result"]
156
+
157
+ ltp_json = api_response["listQuotes"][0]
158
+
159
+ ltp = json.loads(ltp_json)["LastTradedPrice"]
160
+
161
+ return ltp
162
+
163
+ def place_order(
164
+ self,
165
+ tradingsymbol=None,
166
+ exchange=None,
167
+ quantity=None,
168
+ order_type=None,
169
+ transaction_type=None,
170
+ tag=None,
171
+ product=None,
172
+ price=None,
173
+ trigger_price=0,
174
+ ):
175
+ exchange_code = self.get_exchange_code(exchange)
176
+ exchange_name = self.get_exchange_name(exchange)
177
+
178
+ tradingsymbol = self.get_symbol(exchange_code, tradingsymbol)
179
+
180
+ api_response = self.wrapper.place_order(
181
+ exchangeSegment=exchange_name,
182
+ exchangeInstrumentID=tradingsymbol,
183
+ orderType=order_type,
184
+ disclosedQuantity=0,
185
+ orderQuantity=quantity,
186
+ limitPrice=price,
187
+ timeInForce="DAY",
188
+ stopPrice=trigger_price,
189
+ orderSide=transaction_type,
190
+ productType=product,
191
+ orderUniqueIdentifier=tag,
192
+ clientID=self.ClientID,
193
+ )["result"]
194
+
195
+ return api_response["AppOrderID"]
196
+
197
+ def cancel_order(self, unique_order_id):
198
+ orders = self.orders()
199
+
200
+ tag = list(filter(lambda x: x["AppOrderID"] == int(unique_order_id), orders))[
201
+ 0
202
+ ]["OrderUniqueIdentifier"]
203
+
204
+ api_response = self.wrapper.cancel_order(
205
+ appOrderID=unique_order_id,
206
+ clientID=self.ClientID,
207
+ orderUniqueIdentifier=tag,
208
+ )
209
+
210
+ if api_response["type"] == "error":
211
+ raise Exception("[XTS_ERROR]: " + api_response["description"])
212
+
213
+ return api_response["result"]["AppOrderID"]
214
+
215
+ def modify_order(
216
+ self,
217
+ order_id,
218
+ price=None,
219
+ trigger_price=None,
220
+ order_type=None,
221
+ transaction_type=None,
222
+ tag=None,
223
+ product=None,
224
+ ):
225
+ orders = self.orders()
226
+ order_data = list(filter(lambda x: x["AppOrderID"] == int(order_id), orders))[0]
227
+
228
+ price = price or order_data["OrderPrice"]
229
+ trigger_price = trigger_price or order_data["OrderStopPrice"]
230
+ order_type = order_type or order_data["OrderType"]
231
+ transaction_type = transaction_type or order_data["OrderSide"]
232
+ tag = tag or order_data["OrderUniqueIdentifier"]
233
+ product = product or order_data["ProductType"]
234
+
235
+ quantity = order_data["OrderQuantity"]
236
+ time_in_force = "DAY"
237
+ disclosed_quantity = 0
238
+
239
+ api_response = self.wrapper.modify_order(
240
+ appOrderID=order_id,
241
+ modifiedTimeInForce=time_in_force,
242
+ modifiedDisclosedQuantity=disclosed_quantity,
243
+ modifiedLimitPrice=price,
244
+ modifiedOrderQuantity=quantity,
245
+ modifiedOrderType=order_type,
246
+ modifiedProductType=product,
247
+ modifiedStopPrice=trigger_price,
248
+ orderUniqueIdentifier=tag,
249
+ clientID=self.ClientID,
250
+ )
251
+
252
+ if api_response["type"] == "error":
253
+ raise Exception("[XTS_ERROR]: " + api_response["description"])
254
+
255
+ return api_response["result"]["AppOrderID"]
256
+
257
+ def modify_price(self, order_id, price, trigger_price=None, order_type=None):
258
+ return self.modify_order(
259
+ order_id=order_id,
260
+ price=price,
261
+ trigger_price=trigger_price,
262
+ order_type=order_type,
263
+ )