wiz-trader 0.9.0__py3-none-any.whl → 0.11.0__py3-none-any.whl
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.
- wiz_trader/__init__.py +1 -1
- wiz_trader/apis/client.py +176 -44
- wiz_trader/quotes/client.py +231 -222
- wiz_trader-0.11.0.dist-info/METADATA +1722 -0
- wiz_trader-0.11.0.dist-info/RECORD +9 -0
- {wiz_trader-0.9.0.dist-info → wiz_trader-0.11.0.dist-info}/WHEEL +1 -1
- wiz_trader-0.9.0.dist-info/METADATA +0 -165
- wiz_trader-0.9.0.dist-info/RECORD +0 -9
- {wiz_trader-0.9.0.dist-info → wiz_trader-0.11.0.dist-info}/top_level.txt +0 -0
wiz_trader/__init__.py
CHANGED
wiz_trader/apis/client.py
CHANGED
@@ -23,7 +23,77 @@ class WizzerClient:
|
|
23
23
|
log_level (str): Logging level. Options: "error", "info", "debug".
|
24
24
|
strategy_id (str): Default strategy ID to use if not provided in methods.
|
25
25
|
"""
|
26
|
+
|
27
|
+
# Constants
|
28
|
+
# Transaction types
|
29
|
+
TRANSACTION_TYPE_BUY = "BUY"
|
30
|
+
TRANSACTION_TYPE_SELL = "SELL"
|
31
|
+
|
32
|
+
# Product types
|
33
|
+
PRODUCT_CNC = "CNC" # Cash and Carry
|
34
|
+
PRODUCT_MIS = "MIS" # Margin Intraday Square-off
|
35
|
+
PRODUCT_NRML = "NRML" # Normal / Overnight Futures and Options
|
36
|
+
|
37
|
+
# Order types
|
38
|
+
ORDER_TYPE_MARKET = "MARKET"
|
39
|
+
ORDER_TYPE_LIMIT = "LIMIT"
|
40
|
+
ORDER_TYPE_SL = "SL" # Stop Loss
|
41
|
+
ORDER_TYPE_SLM = "SL-M" # Stop Loss Market
|
42
|
+
|
43
|
+
# Validity types
|
44
|
+
VALIDITY_DAY = "DAY"
|
45
|
+
VALIDITY_IOC = "IOC" # Immediate or Cancel
|
46
|
+
VALIDITY_GTT = "GTT" # Good Till Triggered
|
47
|
+
|
48
|
+
# Variety types
|
49
|
+
VARIETY_REGULAR = "REGULAR"
|
50
|
+
VARIETY_AMO = "AMO" # After Market Order
|
51
|
+
VARIETY_BO = "BO" # Bracket Order
|
52
|
+
VARIETY_CO = "CO" # Cover Order
|
53
|
+
|
54
|
+
# Exchanges
|
55
|
+
EXCHANGE_NSE = "NSE" # National Stock Exchange
|
56
|
+
EXCHANGE_BSE = "BSE" # Bombay Stock Exchange
|
57
|
+
EXCHANGE_WZR = "WZR" # Wizzer Exchange (for baskets)
|
58
|
+
|
59
|
+
# Segments
|
60
|
+
SEGMENT_NSE_CM = "NSECM" # NSE Cash Market
|
61
|
+
SEGMENT_BSE_CM = "BSECM" # BSE Cash Market
|
62
|
+
SEGMENT_NSE_FO = "NSEFO" # NSE Futures and Options
|
63
|
+
SEGMENT_WZREQ = "WZREQ" # Wizzer Basket Segment
|
26
64
|
|
65
|
+
# URIs to various API endpoints
|
66
|
+
_routes = {
|
67
|
+
# Order related endpoints
|
68
|
+
"order.place": "/orders",
|
69
|
+
"order.modify": "/orders/{order_id}",
|
70
|
+
"order.cancel": "/orders/{order_id}",
|
71
|
+
"order.info": "/orders/{order_id}",
|
72
|
+
|
73
|
+
# Basket order endpoints
|
74
|
+
"basket.order.place": "/orders/basket",
|
75
|
+
"basket.order.exit": "/orders/basket/exit",
|
76
|
+
"basket.order.modify": "/orders/basket/{order_id}",
|
77
|
+
|
78
|
+
# Portfolio and position management
|
79
|
+
"portfolio.positions": "/portfolios/positions",
|
80
|
+
"portfolio.positions.exit.all": "/portfolios/positions/exit/all",
|
81
|
+
"portfolio.positions.exit.strategy": "/portfolios/positions/exit/strategies/{strategy_id}",
|
82
|
+
"portfolio.holdings": "/portfolios/holdings",
|
83
|
+
|
84
|
+
# Basket management
|
85
|
+
"basket.create": "/baskets",
|
86
|
+
"basket.list": "/baskets",
|
87
|
+
"basket.info": "/baskets/{basket_id}",
|
88
|
+
"basket.instruments": "/baskets/{basket_id}/instruments",
|
89
|
+
"basket.rebalance": "/baskets/rebalance",
|
90
|
+
|
91
|
+
# Data hub endpoints
|
92
|
+
"datahub.indices": "/datahub/indices",
|
93
|
+
"datahub.index.components": "/datahub/index/components",
|
94
|
+
"datahub.historical.ohlcv": "/datahub/historical/ohlcv",
|
95
|
+
}
|
96
|
+
|
27
97
|
def __init__(
|
28
98
|
self,
|
29
99
|
base_url: Optional[str] = None,
|
@@ -90,7 +160,6 @@ class WizzerClient:
|
|
90
160
|
Returns:
|
91
161
|
List[Dict[str, Any]]: List of index information.
|
92
162
|
"""
|
93
|
-
endpoint = "/datahub/indices"
|
94
163
|
params = {}
|
95
164
|
|
96
165
|
if trading_symbol:
|
@@ -99,7 +168,7 @@ class WizzerClient:
|
|
99
168
|
params["exchange"] = exchange
|
100
169
|
|
101
170
|
logger.debug("Fetching indices with params: %s", params)
|
102
|
-
response = self._make_request("GET",
|
171
|
+
response = self._make_request("GET", self._routes["datahub.indices"], params=params)
|
103
172
|
return response
|
104
173
|
|
105
174
|
def get_index_components(self, trading_symbol: str, exchange: str) -> List[Dict[str, Any]]:
|
@@ -113,14 +182,13 @@ class WizzerClient:
|
|
113
182
|
Returns:
|
114
183
|
List[Dict[str, Any]]: List of component stocks in the index.
|
115
184
|
"""
|
116
|
-
endpoint = "/datahub/index/components"
|
117
185
|
params = {
|
118
186
|
"tradingSymbol": trading_symbol,
|
119
187
|
"exchange": exchange
|
120
188
|
}
|
121
189
|
|
122
190
|
logger.debug("Fetching index components with params: %s", params)
|
123
|
-
response = self._make_request("GET",
|
191
|
+
response = self._make_request("GET", self._routes["datahub.index.components"], params=params)
|
124
192
|
return response
|
125
193
|
|
126
194
|
def get_historical_ohlcv(
|
@@ -144,7 +212,6 @@ class WizzerClient:
|
|
144
212
|
Returns:
|
145
213
|
List[Dict[str, Any]]: Historical data for requested instruments.
|
146
214
|
"""
|
147
|
-
endpoint = "/datahub/historical/ohlcv"
|
148
215
|
data = {
|
149
216
|
"instruments": instruments,
|
150
217
|
"startDate": start_date,
|
@@ -154,7 +221,7 @@ class WizzerClient:
|
|
154
221
|
}
|
155
222
|
|
156
223
|
logger.debug("Fetching historical OHLCV with data: %s", data)
|
157
|
-
response = self._make_request("POST",
|
224
|
+
response = self._make_request("POST", self._routes["datahub.historical.ohlcv"], json=data)
|
158
225
|
return response
|
159
226
|
|
160
227
|
# ===== ORDER MANAGEMENT METHODS =====
|
@@ -165,13 +232,13 @@ class WizzerClient:
|
|
165
232
|
trading_symbol: str,
|
166
233
|
transaction_type: str,
|
167
234
|
quantity: int,
|
168
|
-
order_type: str =
|
169
|
-
product: str =
|
235
|
+
order_type: str = None,
|
236
|
+
product: str = None,
|
170
237
|
price: float = 0,
|
171
238
|
trigger_price: float = 0,
|
172
239
|
disclosed_qty: int = 0,
|
173
|
-
validity: str =
|
174
|
-
variety: str =
|
240
|
+
validity: str = None,
|
241
|
+
variety: str = None,
|
175
242
|
stoploss: float = 0,
|
176
243
|
target: float = 0,
|
177
244
|
segment: Optional[str] = None,
|
@@ -187,13 +254,13 @@ class WizzerClient:
|
|
187
254
|
trading_symbol (str): Symbol of the instrument.
|
188
255
|
transaction_type (str): "BUY" or "SELL".
|
189
256
|
quantity (int): Number of shares to trade.
|
190
|
-
order_type (str, optional): Order type (e.g., "MARKET", "LIMIT"). Defaults to
|
191
|
-
product (str, optional): Product code (e.g., "CNC" for delivery). Defaults to
|
257
|
+
order_type (str, optional): Order type (e.g., "MARKET", "LIMIT"). Defaults to MARKET.
|
258
|
+
product (str, optional): Product code (e.g., "CNC" for delivery). Defaults to CNC.
|
192
259
|
price (float, optional): Price for limit orders. Defaults to 0.
|
193
260
|
trigger_price (float, optional): Trigger price for stop orders. Defaults to 0.
|
194
261
|
disclosed_qty (int, optional): Disclosed quantity. Defaults to 0.
|
195
|
-
validity (str, optional): Order validity (e.g., "DAY", "IOC"). Defaults to
|
196
|
-
variety (str, optional): Order variety. Defaults to
|
262
|
+
validity (str, optional): Order validity (e.g., "DAY", "IOC"). Defaults to DAY.
|
263
|
+
variety (str, optional): Order variety. Defaults to REGULAR.
|
197
264
|
stoploss (float, optional): Stop loss price. Defaults to 0.
|
198
265
|
target (float, optional): Target price. Defaults to 0.
|
199
266
|
segment (Optional[str], optional): Market segment. If None, determined from exchange.
|
@@ -204,11 +271,27 @@ class WizzerClient:
|
|
204
271
|
Returns:
|
205
272
|
Dict[str, Any]: Order response containing orderId.
|
206
273
|
"""
|
207
|
-
endpoint = "
|
274
|
+
endpoint = self._routes["order.place"]
|
275
|
+
|
276
|
+
# Set default values from constants if not provided
|
277
|
+
if order_type is None:
|
278
|
+
order_type = self.ORDER_TYPE_MARKET
|
279
|
+
if product is None:
|
280
|
+
product = self.PRODUCT_CNC
|
281
|
+
if validity is None:
|
282
|
+
validity = self.VALIDITY_DAY
|
283
|
+
if variety is None:
|
284
|
+
variety = self.VARIETY_REGULAR
|
208
285
|
|
209
286
|
# Determine segment if not provided
|
210
287
|
if not segment:
|
211
288
|
segment = f"{exchange}CM"
|
289
|
+
# If exchange is NSE, use the NSE_CM constant
|
290
|
+
if exchange == self.EXCHANGE_NSE:
|
291
|
+
segment = self.SEGMENT_NSE_CM
|
292
|
+
# If exchange is BSE, use the BSE_CM constant
|
293
|
+
elif exchange == self.EXCHANGE_BSE:
|
294
|
+
segment = self.SEGMENT_BSE_CM
|
212
295
|
|
213
296
|
# Get strategy information
|
214
297
|
strategy_info = self._get_strategy(strategy)
|
@@ -236,7 +319,7 @@ class WizzerClient:
|
|
236
319
|
data["exchangeToken"] = exchange_token
|
237
320
|
|
238
321
|
logger.debug("Placing order: %s", data)
|
239
|
-
return self._make_request("POST",
|
322
|
+
return self._make_request("POST", self._routes["order.place"], json=data)
|
240
323
|
|
241
324
|
def modify_order(
|
242
325
|
self,
|
@@ -253,7 +336,7 @@ class WizzerClient:
|
|
253
336
|
Returns:
|
254
337
|
Dict[str, Any]: Order response containing orderId.
|
255
338
|
"""
|
256
|
-
endpoint =
|
339
|
+
endpoint = self._routes["order.modify"].format(order_id=order_id)
|
257
340
|
|
258
341
|
logger.debug("Modifying order %s with params: %s", order_id, params)
|
259
342
|
return self._make_request("PATCH", endpoint, json=params)
|
@@ -268,7 +351,7 @@ class WizzerClient:
|
|
268
351
|
Returns:
|
269
352
|
Dict[str, Any]: Response with the cancelled order ID.
|
270
353
|
"""
|
271
|
-
endpoint =
|
354
|
+
endpoint = self._routes["order.cancel"].format(order_id=order_id)
|
272
355
|
|
273
356
|
logger.debug("Cancelling order: %s", order_id)
|
274
357
|
return self._make_request("DELETE", endpoint)
|
@@ -283,7 +366,7 @@ class WizzerClient:
|
|
283
366
|
Returns:
|
284
367
|
Dict[str, Any]: Order details.
|
285
368
|
"""
|
286
|
-
endpoint =
|
369
|
+
endpoint = self._routes["order.info"].format(order_id=order_id)
|
287
370
|
|
288
371
|
logger.debug("Fetching order: %s", order_id)
|
289
372
|
return self._make_request("GET", endpoint)
|
@@ -299,7 +382,7 @@ class WizzerClient:
|
|
299
382
|
Returns:
|
300
383
|
List[Dict[str, Any]]: List of positions matching the filter criteria.
|
301
384
|
"""
|
302
|
-
endpoint = "
|
385
|
+
endpoint = self._routes["portfolio.positions"]
|
303
386
|
params = {}
|
304
387
|
|
305
388
|
if position_status:
|
@@ -338,7 +421,7 @@ class WizzerClient:
|
|
338
421
|
Returns:
|
339
422
|
List[Dict[str, Any]]: List of holdings.
|
340
423
|
"""
|
341
|
-
endpoint = "
|
424
|
+
endpoint = self._routes["portfolio.holdings"]
|
342
425
|
params = {"portfolios": portfolios}
|
343
426
|
|
344
427
|
logger.debug("Fetching holdings for portfolio: %s", portfolios)
|
@@ -368,7 +451,7 @@ class WizzerClient:
|
|
368
451
|
Returns:
|
369
452
|
Dict[str, Any]: Basket information.
|
370
453
|
"""
|
371
|
-
endpoint = "
|
454
|
+
endpoint = self._routes["basket.create"]
|
372
455
|
|
373
456
|
# Set defaults
|
374
457
|
if capital is None:
|
@@ -392,7 +475,7 @@ class WizzerClient:
|
|
392
475
|
Returns:
|
393
476
|
List[Dict[str, Any]]: List of baskets.
|
394
477
|
"""
|
395
|
-
endpoint = "
|
478
|
+
endpoint = self._routes["basket.list"]
|
396
479
|
|
397
480
|
logger.debug("Fetching baskets")
|
398
481
|
return self._make_request("GET", endpoint)
|
@@ -407,7 +490,7 @@ class WizzerClient:
|
|
407
490
|
Returns:
|
408
491
|
Dict[str, Any]: Basket information.
|
409
492
|
"""
|
410
|
-
endpoint =
|
493
|
+
endpoint = self._routes["basket.info"].format(basket_id=basket_id)
|
411
494
|
|
412
495
|
logger.debug("Fetching basket: %s", basket_id)
|
413
496
|
return self._make_request("GET", endpoint)
|
@@ -422,7 +505,7 @@ class WizzerClient:
|
|
422
505
|
Returns:
|
423
506
|
List[Dict[str, Any]]: List of instruments in the basket.
|
424
507
|
"""
|
425
|
-
endpoint =
|
508
|
+
endpoint = self._routes["basket.instruments"].format(basket_id=basket_id)
|
426
509
|
|
427
510
|
logger.debug("Fetching instruments for basket: %s", basket_id)
|
428
511
|
return self._make_request("GET", endpoint)
|
@@ -433,15 +516,15 @@ class WizzerClient:
|
|
433
516
|
transaction_type: str,
|
434
517
|
quantity: float,
|
435
518
|
price: float = 0,
|
436
|
-
order_type: str =
|
437
|
-
product: str =
|
438
|
-
validity: str =
|
519
|
+
order_type: str = None,
|
520
|
+
product: str = None,
|
521
|
+
validity: str = None,
|
439
522
|
exchange_token: Optional[int] = None,
|
440
523
|
trigger_price: float = 0,
|
441
524
|
stoploss: float = 0,
|
442
525
|
target: float = 0,
|
443
526
|
broker: str = "wizzer",
|
444
|
-
variety: str =
|
527
|
+
variety: str = None,
|
445
528
|
strategy: Optional[Dict[str, str]] = None,
|
446
529
|
disclosed_qty: int = 0,
|
447
530
|
sl_applied_level: Optional[str] = None
|
@@ -454,15 +537,15 @@ class WizzerClient:
|
|
454
537
|
transaction_type (str): "BUY" or "SELL".
|
455
538
|
quantity (float): Quantity/units of the basket.
|
456
539
|
price (float, optional): Price for limit orders. Defaults to 0.
|
457
|
-
order_type (str, optional): Order type. Defaults to
|
458
|
-
product (str, optional): Product code. Defaults to
|
459
|
-
validity (str, optional): Order validity. Defaults to
|
540
|
+
order_type (str, optional): Order type. Defaults to MARKET.
|
541
|
+
product (str, optional): Product code. Defaults to CNC.
|
542
|
+
validity (str, optional): Order validity. Defaults to DAY.
|
460
543
|
exchange_token (Optional[int], optional): Exchange token for the basket.
|
461
544
|
trigger_price (float, optional): Trigger price. Defaults to 0.
|
462
545
|
stoploss (float, optional): Stop loss price. Defaults to 0.
|
463
546
|
target (float, optional): Target price. Defaults to 0.
|
464
547
|
broker (str, optional): Broker code. Defaults to "wizzer".
|
465
|
-
variety (str, optional): Order variety. Defaults to
|
548
|
+
variety (str, optional): Order variety. Defaults to REGULAR.
|
466
549
|
strategy (Optional[Dict[str, str]], optional): Strategy information. If None, uses default.
|
467
550
|
disclosed_qty (int, optional): Disclosed quantity. Defaults to 0.
|
468
551
|
sl_applied_level (Optional[str], optional): Stop loss applied level (e.g., "basket").
|
@@ -470,14 +553,24 @@ class WizzerClient:
|
|
470
553
|
Returns:
|
471
554
|
Dict[str, Any]: Order response containing orderId.
|
472
555
|
"""
|
473
|
-
endpoint = "
|
556
|
+
endpoint = self._routes["order.basket"]
|
557
|
+
|
558
|
+
# Set default values from constants if not provided
|
559
|
+
if order_type is None:
|
560
|
+
order_type = self.ORDER_TYPE_MARKET
|
561
|
+
if product is None:
|
562
|
+
product = self.PRODUCT_CNC
|
563
|
+
if validity is None:
|
564
|
+
validity = self.VALIDITY_DAY
|
565
|
+
if variety is None:
|
566
|
+
variety = self.VARIETY_REGULAR
|
474
567
|
|
475
568
|
# Get strategy information
|
476
569
|
strategy_info = self._get_strategy(strategy)
|
477
570
|
|
478
571
|
data = {
|
479
572
|
"tradingSymbol": trading_symbol,
|
480
|
-
"exchange":
|
573
|
+
"exchange": self.EXCHANGE_WZR,
|
481
574
|
"transactionType": transaction_type,
|
482
575
|
"qty": quantity,
|
483
576
|
"price": price,
|
@@ -490,7 +583,7 @@ class WizzerClient:
|
|
490
583
|
"broker": broker,
|
491
584
|
"variety": variety,
|
492
585
|
"strategy": strategy_info,
|
493
|
-
"segment":
|
586
|
+
"segment": self.SEGMENT_WZREQ,
|
494
587
|
"disclosedQty": disclosed_qty
|
495
588
|
}
|
496
589
|
|
@@ -528,7 +621,7 @@ class WizzerClient:
|
|
528
621
|
Returns:
|
529
622
|
Dict[str, Any]: Order response containing orderId.
|
530
623
|
"""
|
531
|
-
endpoint = "
|
624
|
+
endpoint = self._routes["order.basket_exit"]
|
532
625
|
|
533
626
|
# Build base data
|
534
627
|
data = {
|
@@ -546,17 +639,17 @@ class WizzerClient:
|
|
546
639
|
|
547
640
|
# Set defaults if not in kwargs
|
548
641
|
defaults = {
|
549
|
-
"orderType":
|
550
|
-
"product":
|
551
|
-
"validity":
|
642
|
+
"orderType": self.ORDER_TYPE_MARKET,
|
643
|
+
"product": self.PRODUCT_CNC,
|
644
|
+
"validity": self.VALIDITY_DAY,
|
552
645
|
"disclosedQty": 0,
|
553
646
|
"price": 0,
|
554
|
-
"variety":
|
647
|
+
"variety": self.VARIETY_REGULAR,
|
555
648
|
"stoploss": 0,
|
556
649
|
"broker": "wizzer",
|
557
650
|
"triggerPrice": 0,
|
558
651
|
"target": 0,
|
559
|
-
"segment":
|
652
|
+
"segment": self.SEGMENT_WZREQ
|
560
653
|
}
|
561
654
|
|
562
655
|
for key, value in defaults.items():
|
@@ -581,7 +674,7 @@ class WizzerClient:
|
|
581
674
|
Returns:
|
582
675
|
Dict[str, Any]: Order response containing orderId.
|
583
676
|
"""
|
584
|
-
endpoint =
|
677
|
+
endpoint = self._routes["order.basket_modify"].format(order_id=order_id)
|
585
678
|
|
586
679
|
logger.debug("Modifying basket order %s with params: %s", order_id, params)
|
587
680
|
return self._make_request("PATCH", endpoint, json=params)
|
@@ -601,7 +694,7 @@ class WizzerClient:
|
|
601
694
|
Returns:
|
602
695
|
Dict[str, Any]: Rebalance response.
|
603
696
|
"""
|
604
|
-
endpoint = "
|
697
|
+
endpoint = self._routes["basket.rebalance"]
|
605
698
|
|
606
699
|
data = {
|
607
700
|
"tradingSymbol": trading_symbol,
|
@@ -610,6 +703,45 @@ class WizzerClient:
|
|
610
703
|
|
611
704
|
logger.debug("Rebalancing basket %s with instruments: %s", trading_symbol, instruments)
|
612
705
|
return self._make_request("POST", endpoint, json=data)
|
706
|
+
|
707
|
+
def exit_all_positions(self) -> Dict[str, Any]:
|
708
|
+
"""
|
709
|
+
Exit all positions across all strategies.
|
710
|
+
|
711
|
+
This method sends a request to close all open positions for the user.
|
712
|
+
|
713
|
+
Returns:
|
714
|
+
Dict[str, Any]: Response with summary of success and failure counts.
|
715
|
+
"""
|
716
|
+
endpoint = self._routes["portfolio.positions_exit_all"]
|
717
|
+
|
718
|
+
logger.debug("Exiting all positions")
|
719
|
+
return self._make_request("POST", endpoint)
|
720
|
+
|
721
|
+
def exit_strategy_positions(self, strategy_id: Optional[str] = None) -> Dict[str, Any]:
|
722
|
+
"""
|
723
|
+
Exit all positions for a specific strategy.
|
724
|
+
|
725
|
+
Args:
|
726
|
+
strategy_id (Optional[str]): ID of the strategy to exit positions for.
|
727
|
+
If None, uses the default strategy ID.
|
728
|
+
|
729
|
+
Returns:
|
730
|
+
Dict[str, Any]: Response with summary of success and failure counts.
|
731
|
+
|
732
|
+
Raises:
|
733
|
+
ValueError: If no strategy_id is provided and no default is set.
|
734
|
+
"""
|
735
|
+
# Get strategy ID (either from parameter or default)
|
736
|
+
if not strategy_id:
|
737
|
+
if not self.strategy_id:
|
738
|
+
raise ValueError("Strategy ID must be provided either as a parameter or set in .env (WZ__STRATEGY_ID)")
|
739
|
+
strategy_id = self.strategy_id
|
740
|
+
|
741
|
+
endpoint = self._routes["portfolio.positions_exit_strategies"].format(strategy_id=strategy_id)
|
742
|
+
|
743
|
+
logger.debug("Exiting all positions for strategy: %s", strategy_id)
|
744
|
+
return self._make_request("POST", endpoint)
|
613
745
|
|
614
746
|
def _make_request(
|
615
747
|
self,
|