wiz-trader 0.25.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 CHANGED
@@ -3,6 +3,6 @@
3
3
  from .quotes import QuotesClient
4
4
  from .apis import WizzerClient
5
5
 
6
- __version__ = "0.25.0"
6
+ __version__ = "0.26.0"
7
7
 
8
- __all__ = ["QuotesClient", "WizzerClient"]
8
+ __all__ = ["QuotesClient", "WizzerClient"]
@@ -3,4 +3,4 @@
3
3
 
4
4
  from .client import WizzerClient
5
5
 
6
- __all__ = ["WizzerClient"]
6
+ __all__ = ["WizzerClient"]
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
@@ -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.state == State.OPEN:
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.state == State.OPEN:
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.25.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
 
@@ -403,6 +403,73 @@ for component in components[:5]:
403
403
  print(f"{component['tradingSymbol']} - {component.get('weightage', 'N/A')}%")
404
404
  ```
405
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
+
406
473
  #### Get Historical OHLCV Data
407
474
  ## Overview
408
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=0pjCUUIWdupdbX9Rk7OcwJlW287LB1OvtkOFJES4m00,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.25.0.dist-info/METADATA,sha256=SaChOGUc2nsJ7rno-ENsd5-VYI1XrKOSHHJOLfAJhM0,87770
7
- wiz_trader-0.25.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
- wiz_trader-0.25.0.dist-info/top_level.txt,sha256=lnYS_g8LlA6ryKYnvY8xIQ6K2K-xzOsd-99AWgnW6VY,11
9
- wiz_trader-0.25.0.dist-info/RECORD,,