wiz-trader 0.24.0__py3-none-any.whl → 0.26.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 +2 -2
- wiz_trader/apis/__init__.py +1 -1
- wiz_trader/apis/client.py +87 -2
- wiz_trader/quotes/client.py +2 -3
- {wiz_trader-0.24.0.dist-info → wiz_trader-0.26.0.dist-info}/METADATA +86 -4
- wiz_trader-0.26.0.dist-info/RECORD +9 -0
- wiz_trader-0.24.0.dist-info/RECORD +0 -9
- {wiz_trader-0.24.0.dist-info → wiz_trader-0.26.0.dist-info}/WHEEL +0 -0
- {wiz_trader-0.24.0.dist-info → wiz_trader-0.26.0.dist-info}/top_level.txt +0 -0
wiz_trader/__init__.py
CHANGED
wiz_trader/apis/__init__.py
CHANGED
wiz_trader/apis/client.py
CHANGED
@@ -197,7 +197,14 @@ class WizzerClient:
|
|
197
197
|
"instrument.metrics": "/instruments/metrics",
|
198
198
|
"instrument.option_chain": "/instruments/options/chain",
|
199
199
|
"instrument.expiry_list": "/instruments/options/chain/expirylist",
|
200
|
-
"instrument.future_list": "/instruments/futures/list"
|
200
|
+
"instrument.future_list": "/instruments/futures/list",
|
201
|
+
|
202
|
+
# Classification API endpoints
|
203
|
+
"classification.types": "/datahub/classifications/types",
|
204
|
+
"classification.values": "/datahub/classifications/{type}",
|
205
|
+
"indices.filter": "/datahub/indices/filter",
|
206
|
+
"instruments.filter": "/datahub/instruments/filter",
|
207
|
+
"instruments.filter_with_index": "/datahub/indices/{id}/instruments"
|
201
208
|
}
|
202
209
|
|
203
210
|
def __init__(
|
@@ -1598,6 +1605,84 @@ class WizzerClient:
|
|
1598
1605
|
logger.debug("Fetching futures list for: %s", identifier)
|
1599
1606
|
return self._make_request("POST", endpoint, json=data)
|
1600
1607
|
|
1608
|
+
|
1609
|
+
def get_classification_types(self) -> list:
|
1610
|
+
"""
|
1611
|
+
Retrieve all available classification types.
|
1612
|
+
|
1613
|
+
Returns:
|
1614
|
+
list: A list of classification types.
|
1615
|
+
"""
|
1616
|
+
endpoint = self._routes["classification.types"]
|
1617
|
+
logger.debug("Fetching classification types.")
|
1618
|
+
return self._make_request("GET", endpoint)
|
1619
|
+
|
1620
|
+
def get_classifications(self, classification_type: str) -> list:
|
1621
|
+
"""
|
1622
|
+
Retrieve all values for a specific classification type.
|
1623
|
+
|
1624
|
+
Args:
|
1625
|
+
classification_type (str): The type of classification to retrieve values for.
|
1626
|
+
|
1627
|
+
Returns:
|
1628
|
+
list: A list of classification values.
|
1629
|
+
"""
|
1630
|
+
endpoint = self._routes["classification.values"].format(type=classification_type)
|
1631
|
+
logger.debug(f"Fetching classification values for type: {classification_type}")
|
1632
|
+
return self._make_request("GET", endpoint)
|
1633
|
+
|
1634
|
+
def filter_indices(self, filters: Dict[str, List[str]], match_all: bool = True) -> list:
|
1635
|
+
"""
|
1636
|
+
Filter indices based on multiple classification criteria.
|
1637
|
+
|
1638
|
+
Args:
|
1639
|
+
filters (Dict[str, List[str]]): A dictionary of filters where keys are classification
|
1640
|
+
types and values are lists of classification values.
|
1641
|
+
match_all (bool): If True, performs an AND logic search. If False, performs an OR logic search.
|
1642
|
+
|
1643
|
+
Returns:
|
1644
|
+
list: A list of indices that match the filter criteria.
|
1645
|
+
"""
|
1646
|
+
endpoint = self._routes["indices.filter"]
|
1647
|
+
data = {
|
1648
|
+
"filters": filters,
|
1649
|
+
"matchAll": match_all
|
1650
|
+
}
|
1651
|
+
logger.debug(f"Filtering indices with filters: {filters} and match_all: {match_all}")
|
1652
|
+
return self._make_request("POST", endpoint, json=data)
|
1653
|
+
|
1654
|
+
def filter_instruments(
|
1655
|
+
self,
|
1656
|
+
filters: Optional[Dict[str, List[str]]] = None,
|
1657
|
+
match_all: bool = True,
|
1658
|
+
index_identifier: Optional[str] = None
|
1659
|
+
) -> list:
|
1660
|
+
"""
|
1661
|
+
Filter instruments based on classification criteria, with an option to filter within an index.
|
1662
|
+
|
1663
|
+
Args:
|
1664
|
+
filters (Optional[Dict[str, List[str]]]): A dictionary of filters where keys are classification
|
1665
|
+
types and values are lists of classification values. Can be None.
|
1666
|
+
match_all (bool): If True, performs an AND logic search. If False, performs an OR logic search.
|
1667
|
+
index_identifier (Optional[str]): If provided, filters instruments within a specific index.
|
1668
|
+
|
1669
|
+
Returns:
|
1670
|
+
list: A list of instruments that match the filter criteria.
|
1671
|
+
"""
|
1672
|
+
data = {
|
1673
|
+
"filters": filters or {},
|
1674
|
+
"matchAll": match_all
|
1675
|
+
}
|
1676
|
+
|
1677
|
+
if index_identifier:
|
1678
|
+
endpoint = self._routes["instruments.filter_with_index"].format(id=index_identifier)
|
1679
|
+
logger.debug(f"Filtering instruments for index: {index_identifier} with filters: {filters} and match_all: {match_all}")
|
1680
|
+
else:
|
1681
|
+
endpoint = self._routes["instruments.filter"]
|
1682
|
+
logger.debug(f"Filtering instruments with filters: {filters} and match_all: {match_all}")
|
1683
|
+
|
1684
|
+
return self._make_request("POST", endpoint, json=data)
|
1685
|
+
|
1601
1686
|
def _make_request(
|
1602
1687
|
self,
|
1603
1688
|
method: str,
|
@@ -1640,4 +1725,4 @@ class WizzerClient:
|
|
1640
1725
|
logger.error("API request failed: %s", e, exc_info=True)
|
1641
1726
|
if hasattr(e.response, 'text'):
|
1642
1727
|
logger.error("Response content: %s", e.response.text)
|
1643
|
-
raise
|
1728
|
+
raise
|
wiz_trader/quotes/client.py
CHANGED
@@ -7,7 +7,6 @@ from typing import Callable, List, Optional, Any, Iterator
|
|
7
7
|
|
8
8
|
import websockets
|
9
9
|
from websockets.exceptions import ConnectionClosed
|
10
|
-
from websockets.protocol import State
|
11
10
|
|
12
11
|
# Setup module‐level logger with a default handler if none exists.
|
13
12
|
logger = logging.getLogger(__name__)
|
@@ -163,7 +162,7 @@ class QuotesClient:
|
|
163
162
|
# -- Async core methods (for internal use) --
|
164
163
|
|
165
164
|
async def _subscribe_async(self, instruments: List[str]) -> None:
|
166
|
-
if self.ws and self.ws.
|
165
|
+
if self.ws and self.ws.open:
|
167
166
|
new = set(instruments) - self.subscribed_instruments
|
168
167
|
if new:
|
169
168
|
self.subscribed_instruments |= new
|
@@ -178,7 +177,7 @@ class QuotesClient:
|
|
178
177
|
self.subscribed_instruments |= set(instruments)
|
179
178
|
|
180
179
|
async def _unsubscribe_async(self, instruments: List[str]) -> None:
|
181
|
-
if self.ws and self.ws.
|
180
|
+
if self.ws and self.ws.open:
|
182
181
|
to_remove = set(instruments) & self.subscribed_instruments
|
183
182
|
if to_remove:
|
184
183
|
self.subscribed_instruments -= to_remove
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: wiz_trader
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.26.0
|
4
4
|
Summary: A Python SDK for connecting to the Wizzer.
|
5
5
|
Home-page: https://bitbucket.org/wizzer-tech/quotes_sdk.git
|
6
6
|
Author: Pawan Wagh
|
@@ -59,7 +59,7 @@ Dynamic: requires-python
|
|
59
59
|
WizTrader is a Python SDK for connecting to the Wizzer trading platform. It provides two main client classes:
|
60
60
|
|
61
61
|
- **QuotesClient**: For real-time market data streaming via WebSockets
|
62
|
-
- **WizzerClient**: For REST API access to trading, order management, and market data
|
62
|
+
- **WizzerClient**: For REST API access to trading, order management, and market data, including data pipelines and classification APIs.
|
63
63
|
|
64
64
|
This documentation covers all the ways to use the SDK, with examples for each endpoint and common use cases.
|
65
65
|
|
@@ -227,12 +227,22 @@ def on_connect(ws):
|
|
227
227
|
|
228
228
|
### Unsubscribing from Instruments
|
229
229
|
|
230
|
-
|
230
|
+
Use the `unsubscribe` method to stop receiving real-time data for specific instruments. This helps manage bandwidth and reduces unnecessary data processing.
|
231
231
|
|
232
232
|
```python
|
233
|
+
# Unsubscribe from specific instruments
|
233
234
|
ws.unsubscribe(["NSE:SBIN:3045", "NSE:ICICIBANK:4963"])
|
235
|
+
|
236
|
+
# You can also unsubscribe from a single instrument
|
237
|
+
ws.unsubscribe(["NSE:RELIANCE:2885"])
|
234
238
|
```
|
235
239
|
|
240
|
+
**Key Features:**
|
241
|
+
- Immediately stops tick data for the specified instruments
|
242
|
+
- Reduces network bandwidth and processing overhead
|
243
|
+
- Can be called multiple times for different instrument sets
|
244
|
+
- No callback fired for unsubscribed instruments
|
245
|
+
|
236
246
|
### Complete Examples
|
237
247
|
|
238
248
|
#### Blocking Example
|
@@ -301,8 +311,13 @@ asyncio.run(main())
|
|
301
311
|
ts = tick timestamp
|
302
312
|
lastTradedTs = timestamp of the last executed trade in this instrument
|
303
313
|
|
314
|
+
**New Fields Added:**
|
315
|
+
- `oi`: Current open interest (for futures and options)
|
316
|
+
- `oiDayHigh`: Day's highest open interest value
|
317
|
+
- `oiDayLow`: Day's lowest open interest value
|
318
|
+
|
304
319
|
```
|
305
|
-
{'identifier': 'NSE:RELIANCE:2885', 'tradingSymbol': 'RELIANCE', 'exchange': 'NSE', 'segment': 'NSECM', 'exchangeToken': 2885, 'bids': [{'volume': 1722, 'price': 1295.5, 'orders': 43}, {'volume': 0, 'price': 0, 'orders': 0}, {'volume': 0, 'price': 0, 'orders': 0}, {'volume': 0, 'price': 0, 'orders': 0}, {'volume': 0, 'price': 0, 'orders': 0}], 'offers': [{'volume': 0, 'price': 0, 'orders': 0}, {'volume': 0, 'price': 0, 'orders': 0}, {'volume': 0, 'price': 0, 'orders': 0}, {'volume': 0, 'price': 0, 'orders': 0}, {'volume': 0, 'price': 0, 'orders': 0}], 'ltp': 1295.5, 'lastTradedQty': 10, 'buyQty': 1722, 'sellQty': 0, 'volume': 10429964, 'avgPrice': 1291.46, 'netChange': 0, 'ohlc': {'open': 1270, 'high': 1300.9, 'low': 1267, 'close': 1295.5}, 'lastTradedTs': '2025-04-21T10:29:33Z', 'ts': '2025-04-21T10:29:46Z'}
|
320
|
+
{'identifier': 'NSE:RELIANCE:2885', 'tradingSymbol': 'RELIANCE', 'exchange': 'NSE', 'segment': 'NSECM', 'exchangeToken': 2885, 'bids': [{'volume': 1722, 'price': 1295.5, 'orders': 43}, {'volume': 0, 'price': 0, 'orders': 0}, {'volume': 0, 'price': 0, 'orders': 0}, {'volume': 0, 'price': 0, 'orders': 0}, {'volume': 0, 'price': 0, 'orders': 0}], 'offers': [{'volume': 0, 'price': 0, 'orders': 0}, {'volume': 0, 'price': 0, 'orders': 0}, {'volume': 0, 'price': 0, 'orders': 0}, {'volume': 0, 'price': 0, 'orders': 0}, {'volume': 0, 'price': 0, 'orders': 0}], 'ltp': 1295.5, 'lastTradedQty': 10, 'buyQty': 1722, 'sellQty': 0, 'volume': 10429964, 'avgPrice': 1291.46, 'netChange': 0, 'ohlc': {'open': 1270, 'high': 1300.9, 'low': 1267, 'close': 1295.5}, 'oi': 1234567, 'oiDayHigh': 1250000, 'oiDayLow': 1200000, 'lastTradedTs': '2025-04-21T10:29:33Z', 'ts': '2025-04-21T10:29:46Z'}
|
306
321
|
```
|
307
322
|
|
308
323
|
## Wizzer Client
|
@@ -388,6 +403,73 @@ for component in components[:5]:
|
|
388
403
|
print(f"{component['tradingSymbol']} - {component.get('weightage', 'N/A')}%")
|
389
404
|
```
|
390
405
|
|
406
|
+
#### List Classification Types
|
407
|
+
|
408
|
+
Retrieve all available classification types.
|
409
|
+
|
410
|
+
```python
|
411
|
+
classification_types = client.get_classification_types()
|
412
|
+
# Response: ['basicIndustry', 'industry', 'macroEconomicSector', 'sector']
|
413
|
+
```
|
414
|
+
|
415
|
+
#### List Classification Values
|
416
|
+
|
417
|
+
Retrieve all values for a specific classification type.
|
418
|
+
|
419
|
+
```python
|
420
|
+
basic_industry_values = client.get_classifications("basicIndustry")
|
421
|
+
# Response: ['Aerospace & Defense', 'Agricultural Food & other Products', ...]
|
422
|
+
```
|
423
|
+
|
424
|
+
#### Filter Indices by Classifications
|
425
|
+
|
426
|
+
Filter indices based on multiple classification criteria. The `match_all` parameter controls the filter logic:
|
427
|
+
- `True`: AND logic (all filters must match)
|
428
|
+
- `False`: OR logic (any filter can match)
|
429
|
+
|
430
|
+
```python
|
431
|
+
# Example: Find indices in the 'Commodities' macro-economic sector OR 'Aerospace & Defense' industry
|
432
|
+
filters = {
|
433
|
+
"macroEconomicSector": ["Commodities"],
|
434
|
+
"industry": ["Aerospace & Defense"]
|
435
|
+
}
|
436
|
+
or_logic_indices = client.filter_indices(filters=filters, match_all=False)
|
437
|
+
|
438
|
+
# Example: Find indices that are in BOTH 'Housing Finance Company' and 'Financial Services'
|
439
|
+
filters = {
|
440
|
+
"basicIndustry": ["Housing Finance Company"],
|
441
|
+
"sector": ["Financial Services"]
|
442
|
+
}
|
443
|
+
and_logic_indices = client.filter_indices(filters=filters, match_all=True)
|
444
|
+
```
|
445
|
+
|
446
|
+
#### Filter Instruments by Classifications
|
447
|
+
|
448
|
+
Filter instruments based on classification criteria.
|
449
|
+
|
450
|
+
```python
|
451
|
+
# Example: Find instruments in the 'Technology' sector
|
452
|
+
filters = {"sector": ["Technology"]}
|
453
|
+
tech_instruments = client.filter_instruments(filters=filters, match_all=True)
|
454
|
+
```
|
455
|
+
|
456
|
+
#### Filter Instruments by Classifications and Index
|
457
|
+
|
458
|
+
Filter instruments that belong to both specific classifications and a given index.
|
459
|
+
|
460
|
+
```python
|
461
|
+
# Example: Find 'Financial Services' instruments within the 'NIFTY NEXT 50' index
|
462
|
+
filters = {
|
463
|
+
"basicIndustry": ["Housing Finance Company"],
|
464
|
+
"sector": ["Financial Services"]
|
465
|
+
}
|
466
|
+
filtered_instruments = client.filter_instruments(
|
467
|
+
index_identifier="NSE:NIFTY NEXT 50:26054",
|
468
|
+
filters=filters,
|
469
|
+
match_all=False
|
470
|
+
)
|
471
|
+
```
|
472
|
+
|
391
473
|
#### Get Historical OHLCV Data
|
392
474
|
## Overview
|
393
475
|
|
@@ -0,0 +1,9 @@
|
|
1
|
+
wiz_trader/__init__.py,sha256=J8tpFwWCVMnCGEwHmeOLFzA3KvKEF3lNyScNCjZPhZ8,183
|
2
|
+
wiz_trader/apis/__init__.py,sha256=6sUr1nzmplNdld0zryMrQSt0jHT2GhOiFYgKKVHzk8U,133
|
3
|
+
wiz_trader/apis/client.py,sha256=VEotcYfPkjmpp2seJtTWyEdppa6q9NecX89iWxnFQf0,63154
|
4
|
+
wiz_trader/quotes/__init__.py,sha256=RF9g9CNP6bVWlmCh_ad8krm3-EWOIuVfLp0-H9fAeEM,108
|
5
|
+
wiz_trader/quotes/client.py,sha256=EkRxCudEq0J6ReP5nBgDzrL1XbtgWhrzpZT27xXBMBU,10891
|
6
|
+
wiz_trader-0.26.0.dist-info/METADATA,sha256=zlzua-zw8mkNRa5SwnWQLZ-SyIYSPlowcJzTKwKFhIM,89856
|
7
|
+
wiz_trader-0.26.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
8
|
+
wiz_trader-0.26.0.dist-info/top_level.txt,sha256=lnYS_g8LlA6ryKYnvY8xIQ6K2K-xzOsd-99AWgnW6VY,11
|
9
|
+
wiz_trader-0.26.0.dist-info/RECORD,,
|
@@ -1,9 +0,0 @@
|
|
1
|
-
wiz_trader/__init__.py,sha256=hL8zImLBBtwxnrKrTpTqcsIzg5cxFMWDOfTkfKNwo9o,182
|
2
|
-
wiz_trader/apis/__init__.py,sha256=ItWKMOl4omiW0g2f-M7WRW3v-dss_ULd9vYnFyIIT9o,132
|
3
|
-
wiz_trader/apis/client.py,sha256=GY1aAaV4ia1tnFnB2qaNqnv-qeUvkVlvw9xOKN54qIs,59786
|
4
|
-
wiz_trader/quotes/__init__.py,sha256=RF9g9CNP6bVWlmCh_ad8krm3-EWOIuVfLp0-H9fAeEM,108
|
5
|
-
wiz_trader/quotes/client.py,sha256=oPDOKqc9EChID_V0_O7ziCdcDnyM_jC7uuKfkc1GwmI,10959
|
6
|
-
wiz_trader-0.24.0.dist-info/METADATA,sha256=38v7XP4SiKWiNDaIAex2cHkv7afK8ExKzs5pv-MKFzM,87046
|
7
|
-
wiz_trader-0.24.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
8
|
-
wiz_trader-0.24.0.dist-info/top_level.txt,sha256=lnYS_g8LlA6ryKYnvY8xIQ6K2K-xzOsd-99AWgnW6VY,11
|
9
|
-
wiz_trader-0.24.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|