wiz-trader


Namewiz-trader JSON
Version 0.35.0 PyPI version JSON
download
home_pagehttps://bitbucket.org/wizzer-tech/quotes_sdk.git
SummaryA Python SDK for connecting to the Wizzer.
upload_time2025-07-22 20:31:39
maintainerNone
docs_urlNone
authorPawan Wagh
requires_python>=3.6
licenseMIT
keywords finance trading sdk
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # WizTrader SDK Documentation

## Table of Contents

1. [Introduction](#introduction)
2. [Installation](#installation)
3. [Authentication](#authentication)
4. [Quotes Client](#quotes-client)
    - [Initialization](#quotes-client-initialization)
    - [Connection Methods](#connection-methods)
    - [Callbacks](#callbacks)
    - [Subscribing to Instruments](#subscribing-to-instruments)
    - [Unsubscribing from Instruments](#unsubscribing-from-instruments)
    - [Handling WebSocket Connection](#handling-websocket-connection)
    - [Complete Examples](#quotes-client-examples)
5. [Wizzer Client](#wizzer-client)
    - [Initialization](#wizzer-client-initialization)
    - [Constants](#constants)
    - [Data Hub Methods](#data-hub-methods)
    - [Order Management](#order-management)
    - [Portfolio Management](#portfolio-management)
    - [Basket Management](#basket-management)
    - [Instrument Management](#instrument-management)
    - [Instrument Screener](#instrument-screener)
    - [Complete Examples](#wizzer-client-examples)
6. [Common Use Cases](#common-use-cases)
7. [Error Handling](#error-handling)
8. [Troubleshooting](#troubleshooting)
9. [API Reference](#api-reference)

## Introduction

WizTrader is a Python SDK for connecting to the Wizzer trading platform. It provides two main client classes:

- **QuotesClient**: For real-time market data streaming via WebSockets
- **WizzerClient**: For REST API access to trading, order management, and market data, including data pipelines and classification APIs.

This documentation covers all the ways to use the SDK, with examples for each endpoint and common use cases.

## Installation

You can install the package directly from PyPI:

```bash
pip install wiz_trader
```

To install the development version from GitHub:

```bash
pip install git+https://github.com/wizzer-tech/wiz_trader.git
```

## Authentication

There are two ways to provide authentication credentials to the SDK:

1. **Direct parameter passing** (Recommended for most use cases)
2. **Environment variables** (Recommended for production deployments)

### Direct Parameter Passing

Simply provide the required parameters directly when initializing the clients:

```python
from wiz_trader import QuotesClient, WizzerClient

quotes_client = QuotesClient(
    base_url="wss://websocket-url/quotes",
    token="your-jwt-token",
    log_level="info"
)

wizzer_client = WizzerClient(
    base_url="https://api-url.in",
    token="your-jwt-token",
    strategy_id="str_01hxgwgfxgfrxb48bzchnve7gm",  # Optional
    log_level="info"
)
```

### Environment Variables

Set the following environment variables:

```bash
export WZ__QUOTES_BASE_URL="wss://websocket-url/quotes"
export WZ__API_BASE_URL="https://api-url.in"
export WZ__TOKEN="your-jwt-token"
export WZ__STRATEGY_ID="str_01hxgwgfxgfrxb48bzchnve7gm"  # Optional
```

Then initialize the clients without parameters:

```python
from wiz_trader import QuotesClient, WizzerClient

quotes_client = QuotesClient(log_level="info")
wizzer_client = WizzerClient(log_level="info")
```

You can also use a hybrid approach, providing some parameters directly and letting others fall back to environment variables:

```python
quotes_client = QuotesClient(log_level="debug")  # Only override log level
```

## Quotes Client

The `QuotesClient` enables you to connect to Wizzer's WebSocket server for real‑time market data using **plain synchronous** callbacks—no `async def` required.

### Quotes Client Initialization

You can initialize the `QuotesClient` in several ways:

```python
from wiz_trader import QuotesClient

# Method 1: All parameters provided directly
client = QuotesClient(
    base_url="wss://websocket-url/quotes",
    token="your-jwt-token",
    log_level="info",         # Options: "error", "info", "debug"
    max_message_size=10 * 1024 * 1024,  # Optional: default 10MB
    batch_size=20             # Optional: default 20 instruments per batch
)

# Method 2: Using environment variables
# (Requires WZ__QUOTES_BASE_URL and WZ__TOKEN set)
client = QuotesClient(log_level="info")

# Method 3: Mixed approach
client = QuotesClient(
    base_url="wss://custom-url/quotes",
    log_level="debug"         # token from WZ__TOKEN env var
)
```

### Connection Methods

#### Blocking Connection

Blocks your main thread, similar to Zerodha’s KiteTicker:

```python
client.connect()
```

#### Non‑Blocking Connection

Run alongside your own `asyncio` code:

```python
client.connect_async()
# … do other work …
client.stop()
```

### Callbacks

All callbacks are **plain `def`** functions.  Inside them you can call `subscribe(...)`, which under the hood schedules the actual async work—so you never `await` in your callbacks.

The QuotesClient routes messages based on their `type` field:
- Messages with `type: 'ticks'` are sent to the `on_tick` callback
- Messages with `type: 'greeks'` are sent to the `on_stats` callback
- Messages without a `type` field are sent to `on_tick` for backward compatibility

```python
def on_tick(ws, tick):
    print("Tick:", tick)

def on_stats(ws, stats):
    print("Stats:", stats)
    # Stats/Greek messages contain: {'type': 'greeks', 'identifier': '...', 'rho': 0.1, 'theta': 9.8, ...}

def on_connect(ws):
    print("Connected!")
    # Subscribe with different modes
    ws.subscribe(["NSE:SBIN:3045"], mode="ticks")      # Will receive tick messages
    ws.subscribe(["NSE:NIFTY25JULFUT:53216"], mode="greeks") # Will receive greek messages
    ws.subscribe(["NSE:RELIANCE:2885"], mode="full")   # Will receive both types

def on_close(ws, code, reason):
    print(f"Connection closed [{code}]: {reason}")
    ws.stop()   # to prevent auto‑reconnect

def on_error(ws, error):
    print("Error:", error)

client.on_tick    = on_tick
client.on_stats   = on_stats
client.on_connect = on_connect
client.on_close   = on_close
client.on_error   = on_error
```

### Subscribing to Instruments

Call `ws.subscribe([...])` directly; the SDK will batch large lists and send them over the socket:

```python
def on_connect(ws):
    # subscribe without await
    ws.subscribe([
        "NSE:SBIN:3045",
        "NSE:ICICIBANK:4963",
        "NSE:RELIANCE:2885",
    ])
```

### Unsubscribing from Instruments

Use the `unsubscribe` method to stop receiving real-time data for specific instruments. This helps manage bandwidth and reduces unnecessary data processing.

```python
# Unsubscribe from specific instruments
ws.unsubscribe(["NSE:SBIN:3045", "NSE:ICICIBANK:4963"])

# You can also unsubscribe from a single instrument
ws.unsubscribe(["NSE:RELIANCE:2885"])
```

**Key Features:**
- Immediately stops tick data for the specified instruments
- Reduces network bandwidth and processing overhead
- Can be called multiple times for different instrument sets
- No callback fired for unsubscribed instruments

### Complete Examples

#### Blocking Example

```python
import logging
from wiz_trader import QuotesClient

logging.basicConfig(level=logging.INFO)

client = QuotesClient(
    base_url="wss://websocket-url/quotes",
    token="your-jwt-token"
)

def on_tick(ws, tick):
    logging.debug("Tick: %s", tick)

def on_stats(ws, stats):
    logging.debug("Stats: %s", stats)

def on_connect(ws):
    logging.info("Connected.")
    ws.subscribe(["NSE:SBIN:3045"], mode="ticks")
    ws.subscribe(["NSE:NIFTY24JUN20100CE:20100"], mode="greeks")

def on_close(ws, code, reason):
    logging.warning("Closed: %s", reason)
    ws.stop()

def on_error(ws, error):
    logging.error("Error: %s", error)

client.on_tick    = on_tick
client.on_stats   = on_stats
client.on_connect = on_connect
client.on_close   = on_close
client.on_error   = on_error

try:
    client.connect()
except KeyboardInterrupt:
    client.stop()
```

#### Non‑Blocking Example

```python
import asyncio
import logging
from wiz_trader import QuotesClient

async def main():
    logging.basicConfig(level=logging.INFO)
    client = QuotesClient(
        base_url="wss://websocket-url/quotes",
        token="your-jwt-token"
    )
    client.on_tick    = lambda ws, tick: logging.info(tick)
    client.on_connect = lambda ws: ws.subscribe(["NSE:SBIN:3045"])
    client.connect_async()

    # Your other async work here...
    await asyncio.sleep(60)
    client.stop()

asyncio.run(main())
```

#### Message Data Structures

##### Ticks structure
Messages with `type: 'ticks'` contain market data:
- `ts`: tick timestamp
- `lastTradedTs`: timestamp of the last executed trade in this instrument
- `oi`: Current open interest (for futures and options)
- `oiDayHigh`: Day's highest open interest value  
- `oiDayLow`: Day's lowest open interest value

```json
{
  "type": "ticks",
  "identifier": "NSE:RELIANCE:2885",
  "tradingSymbol": "RELIANCE",
  "exchange": "NSE",
  "segment": "NSECM",
  "exchangeToken": 2885,
  "bids": [{"volume": 1722, "price": 1295.5, "orders": 43}, ...],
  "offers": [{"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"
}
```

##### Greeks structure
Messages with `type: 'greeks'` contain options Greeks data:

```json
{
  "type": "greeks",
  "identifier": "NSE:NIFTY25JULFUT:53216",
  "tradingSymbol": "NIFTY25JULFUT",
  "iv": 0.0,
  "delta": 0.0,
  "gamma": 0.0,
  "theta": 0.0,
  "vega": 0.0,
  "rho": 0.0,
  "ts": "2025-04-21T10:29:46Z"
}
```

## Wizzer Client

The `WizzerClient` provides access to Wizzer's REST APIs for trading, portfolio management, and market data.

### Wizzer Client Initialization

Initialize the client with your authentication details:

```python
from wiz_trader import WizzerClient

# Method 1: All parameters provided directly
client = WizzerClient(
    base_url="https://api-url.in",
    token="your-jwt-token",
    strategy_id="str_01hxgwgfxgfrxb48bzchnve7gm",  # Optional: Default strategy ID
    log_level="info"  # Options: "error", "info", "debug"
)

# Method 2: Using environment variables
# (Requires WZ__API_BASE_URL and WZ__TOKEN to be set)
client = WizzerClient(log_level="info")
```

### Constants

The `WizzerClient` provides constants for various parameter values, making your code more readable and type-safe:

```python
from wiz_trader import WizzerClient

client = WizzerClient(...)

# Use constants for transaction types
client.place_order(
    exchange=client.EXCHANGE_NSE,
    trading_symbol="SBIN",
    transaction_type=client.TRANSACTION_TYPE_BUY,
    quantity=10,
    order_type=client.ORDER_TYPE_MARKET,
    product=client.PRODUCT_CNC
)
```

Available constants:

- Transaction types: `TRANSACTION_TYPE_BUY`, `TRANSACTION_TYPE_SELL`
- Product types: `PRODUCT_CNC`, `PRODUCT_MIS`, `PRODUCT_NRML`
- Order types: `ORDER_TYPE_MARKET`, `ORDER_TYPE_LIMIT`, `ORDER_TYPE_SL`, `ORDER_TYPE_SLM`
- Validity types: `VALIDITY_DAY`, `VALIDITY_IOC`, `VALIDITY_GTT`
- Variety types: `VARIETY_REGULAR`, `VARIETY_AMO`, `VARIETY_BO`, `VARIETY_CO`
- Exchanges: `EXCHANGE_NSE`, `EXCHANGE_BSE`, `EXCHANGE_WZR`
- Segments: `SEGMENT_NSE_CM`, `SEGMENT_BSE_CM`, `SEGMENT_NSE_FO`, `SEGMENT_WZREQ`
- Instrument types: `INSTRUMENT_TYPE_EQ`, `INSTRUMENT_TYPE_EQLC`, `INSTRUMENT_TYPE_EQMCC`, `INSTRUMENT_TYPE_EQSCC`, `INSTRUMENT_TYPE_BASKET`
- - Weightage schemes: `WEIGHTAGE_SCHEME_EQUI_WEIGHTED`, `WEIGHTAGE_SCHEME_QUANTITY_WEIGHTED`, `WEIGHTAGE_SCHEME_PRICE_WEIGHTED`, `WEIGHTAGE_SCHEME_MARKET_CAP_WEIGHTED`, `WEIGHTAGE_SCHEME_FLOAT_ADJUSTED_MARKET_CAP_WEIGHTED`, `WEIGHTAGE_SCHEME_FUNDAMENTAL_WEIGHTED`, `WEIGHTAGE_SCHEME_CUSTOM_WEIGHTED`

### Data Hub Methods

#### Get Indices

Fetch available indices from an exchange:

```python
# Get all indices from NSE
indices = client.get_indices(exchange="NSE")
print(f"Found {len(indices)} indices")

# Get a specific index by trading symbol
nifty_50 = client.get_indices(trading_symbol="NIFTY 50", exchange="NSE")
```

#### Get Index Components

Fetch components (stocks) in a specific index:

```python
# Get components of NIFTY 50
components = client.get_index_components(trading_symbol="NIFTY 50", exchange="NSE")
print(f"Found {len(components)} components in NIFTY 50")
for component in components[:5]:
    print(f"{component['tradingSymbol']} - {component.get('weightage', 'N/A')}%")
```

#### List Classification Types

Retrieve all available classification types.

```python
classification_types = client.get_classification_types()
# Response: ['basicIndustry', 'industry', 'macroEconomicSector', 'sector']
```

#### List Classification Values

Retrieve all values for a specific classification type.

```python
basic_industry_values = client.get_classifications("basicIndustry")
# Response: ['Aerospace & Defense', 'Agricultural Food & other Products', ...]
```

#### Filter Indices by Classifications

Filter indices based on multiple classification criteria. The `match_all` parameter controls the filter logic:
- `True`: AND logic (all filters must match)
- `False`: OR logic (any filter can match)

```python
# Example: Find indices in the 'Commodities' macro-economic sector OR 'Aerospace & Defense' industry
filters = {
    "macroEconomicSector": ["Commodities"],
    "industry": ["Aerospace & Defense"]
}
or_logic_indices = client.filter_indices(filters=filters, match_all=False)

# Example: Find indices that are in BOTH 'Housing Finance Company' and 'Financial Services'
filters = {
    "basicIndustry": ["Housing Finance Company"],
    "sector": ["Financial Services"]
}
and_logic_indices = client.filter_indices(filters=filters, match_all=True)
```

#### Filter Instruments by Classifications

Filter instruments based on classification criteria.

```python
# Example: Find instruments in the 'Technology' sector
filters = {"sector": ["Technology"]}
tech_instruments = client.filter_instruments(filters=filters, match_all=True)
```

#### Filter Instruments by Classifications and Index

Filter instruments that belong to both specific classifications and a given index.

```python
# Example: Find 'Financial Services' instruments within the 'NIFTY NEXT 50' index
filters = {
    "basicIndustry": ["Housing Finance Company"],
    "sector": ["Financial Services"]
}
filtered_instruments = client.filter_instruments(
    index_identifier="NSE:NIFTY NEXT 50:26054",
    filters=filters,
    match_all=False
)
```

#### Filter Instruments by Derivatives

Filter instruments based on whether they have associated futures or options contracts.

```python
# Find all instruments that have options
optionable_stocks = client.filter_instruments_by_derivatives(hasOptions=True)

# Find all instruments that have futures
futures_stocks = client.filter_instruments_by_derivatives(hasFutures=True)

# Find all instruments that have both options and futures
fno_stocks = client.filter_instruments_by_derivatives(hasOptions=True, hasFutures=True)

# Find all instruments that have either options or futures
all_derivative_stocks = client.filter_instruments_by_derivatives()
```

### Instrument Screener

The SDK provides a powerful instrument screener to filter and sort instruments based on a wide range of criteria using a simple and expressive Domain Specific Language (DSL).

> **📋 Comprehensive Screener Documentation**: For detailed information about all available screener fields, practical use cases, and advanced filtering examples, see **[screener.md](screener.md)**.

#### `get_screener_fields()`

This method returns a list of all available filterable fields and their supported operations.

```python
# Get all available screener fields
fields = client.get_screener_fields()
print(json.dumps(fields, indent=2))
```

#### `run_screener(filters, sort=None, limit=None, as_of=None)`

This is the main method for the instrument screener. It accepts a dictionary with a `filters` object to define the screening criteria.

**Arguments:**

*   `filters` (dict, required): An object containing the filter conditions.
*   `sort` (list, optional): A list of objects to define the sort order.
*   `limit` (int, optional): The maximum number of results to return.

#### Filter DSL (Domain Specific Language)

The `filters` object uses a simple DSL to define the screening criteria.

##### Operators

| Operator  | Description              | Example                               |
| :-------- | :----------------------- | :------------------------------------ |
| `$eq`     | Equal to                 | `{ "sector": { "$eq": "Finance" } }`  |
| `$ne`     | Not equal to             | `{ "sector": { "$ne": "Finance" } }`  |
| `$gt`     | Greater than             | `{ "roe": { "$gt": 0.15 } }`          |
| `$gte`    | Greater than or equal to | `{ "roe": { "$gte": 0.15 } }`         |
| `$lt`     | Less than                | `{ "roe": { "$lt": 0.15 } }`          |
| `$lte`    | Less than or equal to    | `{ "roe": { "$lte": 0.15 } }`         |
| `$in`     | In a list of values    | `{ "sector": { "$in": ["Information Technology", "Finance"] } }` |
| `$nin`    | Not in a list of values| `{ "sector": { "$nin": ["Information Technology", "Finance"] } }` |
| `$like`   | Like (case-sensitive)    | `{ "companyName": { "$like": "%Bank%" } }` |
| `$nlike`  | Not like (case-sensitive)| `{ "companyName": { "$nlike": "%Bank%" } }` |
| `$ilike`  | Like (case-insensitive)  | `{ "companyName": { "$ilike": "%bank%" } }` |
| `$between`| Between two values       | `{ "roe": { "$between": [0.10, 0.20] } }` |

##### Logical Operators

*   `$and`: A list of filter conditions that must all be true.
*   `$or`: A list of filter conditions where at least one must be true.

#### Screener Examples

##### Basic Filters

1.  **Find all instruments in the 'Finance' sector.**
    ```python
    client.run_screener(filters={"sector": {"$eq": "Finance"}})
    ```

2.  **Find all instruments on the 'NSE' exchange.**
    ```python
    client.run_screener(filters={"exchange": {"$eq": "NSE"}})
    ```

3.  **Find all instruments with a Return on Equity (ROE) greater than 15%.**
    ```python
    client.run_screener(filters={"roe": {"$gt": 0.15}})
    ```

##### Set and Range Operators

4.  **Find all instruments in the 'Energy' or 'Healthcare' sectors.**
    ```python
    client.run_screener(filters={"sector": {"$in": ["Energy", "Healthcare"]}})
    ```

5.  **Find instruments with a PAT Margin between 5% and 10%.**
    ```python
    client.run_screener(filters={"patMargin": {"$between": [0.05, 0.10]}})
    ```

##### Pattern Matching

6.  **Find all instruments with 'Bank' in their name (case-insensitive).**
    ```python
    client.run_screener(filters={"companyName": {"$ilike": "%bank%"}})
    ```

##### Logical Combinations

7.  **Find instruments in the 'IT' sector with a ROE greater than 20%.**
    ```python
    client.run_screener(
        filters={
            "$and": [
                {"sector": {"$eq": "Information Technology"}},
                {"roe": {"$gt": 0.20}}
            ]
        }
    )
    ```

8.  **Complex Nested Query:** Find instruments in the 'Automobile' sector that have (a ROE > 18% AND a low Debt/Equity) OR have a high Asset Turnover.
    ```python
    client.run_screener(
        filters={
            "$and": [
                {"sector": {"$eq": "Automobile"}},
                {
                    "$or": [
                        {
                            "$and": [
                                {"roe": {"$gt": 0.18}},
                                {"debtEquity": {"$lt": 0.3}}
                            ]
                        },
                        {"assetTurnover": {"$gt": 1.5}}
                    ]
                }
            ]
        }
    )
    ```

##### Sort and Limit

9.  **Find the top 10 companies by highest ROE.**
    ```python
    client.run_screener(
        filters={},
        sort=[{"roe": -1}],
        limit=10
    )
    ```

10. **Find companies in the 'Pharmaceuticals' sector, sort them by the highest PAT margin, and then by the lowest Debt-to-Equity ratio.**
    ```python
    client.run_screener(
        filters={"sector": {"$eq": "Pharmaceuticals"}},
        sort=[
            {"patMargin": -1},
            {"debtEquity": 1}
        ]
    )
    ```

#### Get Historical OHLCV Data
## Overview

The `get_historical_ohlcv` method supports multiple time intervals for historical data retrieval, from 1-minute intraday data to monthly aggregated data.

## Supported Intervals

### Intraday Intervals
- `1m` - 1 minute
- `2m` - 2 minutes  
- `3m` - 3 minutes
- `5m` - 5 minutes
- `10m` - 10 minutes
- `15m` - 15 minutes
- `30m` - 30 minutes
- `45m` - 45 minutes
- `1h` - 1 hour

### Daily/Monthly Intervals
- `1d` - 1 day (default)
- `1M` - 1 month (last trading day of month)

## Date Format Requirements

### For Daily and Monthly Intervals (`1d`, `1M`)
- **Format**: `YYYY-MM-DD`
- **Example**: `"2024-01-15"`

### For Intraday Intervals (all minute/hour intervals)
- **Format**: `YYYY-MM-DD HH:MM:SS`
- **Example**: `"2024-01-15 09:30:00"`

**New Features in Historical Data API:**

- **Open Interest (`oi`)**: Now supported in the `ohlcv` parameter for futures instruments
- **Continuous Data**: The `continuous` parameter (for futures only) provides seamless data across multiple contract months when your date range spans multiple months

## Using Constants

The client provides constants for all intervals:

```python
from wiz_trader import WizzerClient

client = WizzerClient(...)

# Intraday intervals
client.INTERVAL_1_MINUTE     # "1m"
client.INTERVAL_2_MINUTES    # "2m"
client.INTERVAL_3_MINUTES    # "3m"
client.INTERVAL_5_MINUTES    # "5m"
client.INTERVAL_10_MINUTES   # "10m"
client.INTERVAL_15_MINUTES   # "15m"
client.INTERVAL_30_MINUTES   # "30m"
client.INTERVAL_45_MINUTES   # "45m"
client.INTERVAL_1_HOUR       # "1h"

# Daily/Monthly intervals
client.INTERVAL_1_DAY        # "1d"
client.INTERVAL_1_MONTH      # "1M"
```

## Usage Examples

### 1. Get 5-minute intraday data

```python
# Get 5-minute candles for a trading session
intraday_data = client.get_historical_ohlcv(
    instruments=["NSE:SBIN:3045"],
    start_date="2024-01-15 09:15:00",  # Market open
    end_date="2024-01-15 15:30:00",    # Market close
    ohlcv=["open", "high", "low", "close", "volume"],
    interval=client.INTERVAL_5_MINUTES
)

# Response will have date field as: "2024-01-15 09:15:00", "2024-01-15 09:20:00", etc.
```

### 2. Get 1-minute data for scalping

```python
# Get 1-minute data for the first hour of trading
scalping_data = client.get_historical_ohlcv(
    instruments=["NSE:RELIANCE:2885", "NSE:TCS:2953"],
    start_date="2024-01-15 09:15:00",
    end_date="2024-01-15 10:15:00",
    ohlcv=["open", "high", "low", "close", "volume"],
    interval=client.INTERVAL_1_MINUTE
)
```

### 3. Get hourly data for swing trading

```python
# Get hourly data for a week
hourly_data = client.get_historical_ohlcv(
    instruments=["NSE:NIFTY 50:26000"],
    start_date="2024-01-15 09:15:00",
    end_date="2024-01-19 15:30:00",
    ohlcv=["open", "high", "low", "close", "volume"],
    interval=client.INTERVAL_1_HOUR
)
```

### 4. Get daily data (traditional)

```python
# Get daily data for a month
daily_data = client.get_historical_ohlcv(
    instruments=["NSE:SBIN:3045"],
    start_date="2024-01-01",  # Note: No time component
    end_date="2024-01-31",
    ohlcv=["open", "high", "low", "close", "volume"],
    interval=client.INTERVAL_1_DAY
)

# Response will have date field as: "2024-01-01", "2024-01-02", etc.
```

### 5. Get monthly data for long-term analysis

```python
# Get monthly data for a year
monthly_data = client.get_historical_ohlcv(
    instruments=["NSE:SBIN:3045"],
    start_date="2023-01-01",
    end_date="2023-12-31",
    ohlcv=["close", "volume"],
    interval=client.INTERVAL_1_MONTH
)

# Get futures data with open interest
futures_data = client.get_historical_ohlcv(
    instruments=["NSE:SBIN25MAYFUT:57515"],
    start_date="2024-01-01",
    end_date="2024-03-01",
    ohlcv=["open", "high", "low", "close", "volume", "oi"],  # Include open interest
    interval="1d"
)

# Get continuous futures data across multiple contract months
continuous_futures = client.get_historical_ohlcv(
    instruments=["NSE:SBIN25MAYFUT:57515"],
    start_date="2023-01-01",
    end_date="2024-12-31",
    ohlcv=["close", "oi"],
    interval="1d",
    continuous=True  # Get seamless data across contract months
)
```

## Response Structure

The response structure remains the same, but the `date` field format varies:

### For Daily/Monthly Intervals
```json
{
  "instrument": {
    "exchange": "NSE",
    "tradingSymbol": "SBIN",
    "exchangeToken": 3045,
    "identifier": "NSE:SBIN:3045"
  },
  "data": [
    {
      "date": "2024-01-15",  // YYYY-MM-DD format
      "open": 750.0,
      "high": 765.0,
      "low": 745.0,
      "close": 760.0,
      "volume": 1000000
    }
  ]
}
```

### For Intraday Intervals
```json
{
  "instrument": {
    "exchange": "NSE",
    "tradingSymbol": "SBIN",
    "exchangeToken": 3045,
    "identifier": "NSE:SBIN:3045"
  },
  "data": [
    {
      "date": "2024-01-15 09:15:00",  // YYYY-MM-DD HH:MM:SS format
      "open": 750.0,
      "high": 752.0,
      "low": 749.0,
      "close": 751.0,
      "volume": 50000
    }
  ]
}
```

## Advanced Usage Examples

### Multiple Timeframe Analysis

```python
def get_multi_timeframe_data(symbol, date):
    """Get data across multiple timeframes for comprehensive analysis"""
    
    # 1-minute data for entry/exit precision
    minute_data = client.get_historical_ohlcv(
        instruments=[symbol],
        start_date=f"{date} 09:15:00",
        end_date=f"{date} 15:30:00",
        ohlcv=["open", "high", "low", "close", "volume"],
        interval=client.INTERVAL_1_MINUTE
    )
    
    # 5-minute data for short-term trends
    five_min_data = client.get_historical_ohlcv(
        instruments=[symbol],
        start_date=f"{date} 09:15:00",
        end_date=f"{date} 15:30:00",
        ohlcv=["open", "high", "low", "close", "volume"],
        interval=client.INTERVAL_5_MINUTES
    )
    
    # 15-minute data for medium-term trends
    fifteen_min_data = client.get_historical_ohlcv(
        instruments=[symbol],
        start_date=f"{date} 09:15:00",
        end_date=f"{date} 15:30:00",
        ohlcv=["open", "high", "low", "close", "volume"],
        interval=client.INTERVAL_15_MINUTES
    )
    
    # Hourly data for major trend
    hourly_data = client.get_historical_ohlcv(
        instruments=[symbol],
        start_date=f"{date} 09:15:00",
        end_date=f"{date} 15:30:00",
        ohlcv=["open", "high", "low", "close", "volume"],
        interval=client.INTERVAL_1_HOUR
    )
    
    return {
        "1m": minute_data,
        "5m": five_min_data,
        "15m": fifteen_min_data,
        "1h": hourly_data
    }

# Usage
multi_data = get_multi_timeframe_data("NSE:SBIN:3045", "2024-01-15")
```

### Building OHLC Candlestick Data

```python
import pandas as pd
import matplotlib.pyplot as plt
from mplfinance import plot as mpf

def plot_candlestick_chart(symbol, start_date, end_date, interval):
    """Create a candlestick chart from historical data"""
    
    # Get historical data
    data = client.get_historical_ohlcv(
        instruments=[symbol],
        start_date=start_date,
        end_date=end_date,
        ohlcv=["open", "high", "low", "close", "volume"],
        interval=interval
    )
    
    if not data or not data[0].get('data'):
        print("No data available")
        return
    
    # Convert to DataFrame
    df = pd.DataFrame(data[0]['data'])
    df['date'] = pd.to_datetime(df['date'])
    df.set_index('date', inplace=True)
    
    # Rename columns for mplfinance
    df.columns = ['Open', 'High', 'Low', 'Close', 'Volume']
    
    # Create candlestick chart
    mpf.plot(df, type='candle', volume=True, 
             title=f'{symbol} - {interval} Chart',
             style='charles')

# Plot 5-minute chart
plot_candlestick_chart(
    "NSE:SBIN:3045", 
    "2024-01-15 09:15:00", 
    "2024-01-15 15:30:00",
    client.INTERVAL_5_MINUTES
)
```

### Backtesting with Different Intervals

```python
def backtest_strategy_multiple_intervals(symbol, start_date, end_date):
    """Backtest a strategy across different intervals"""
    
    intervals = [
        (client.INTERVAL_5_MINUTES, "5m"),
        (client.INTERVAL_15_MINUTES, "15m"),
        (client.INTERVAL_30_MINUTES, "30m"),
        (client.INTERVAL_1_HOUR, "1h")
    ]
    
    results = {}
    
    for interval_code, interval_name in intervals:
        # For intraday intervals, use datetime format
        data = client.get_historical_ohlcv(
            instruments=[symbol],
            start_date=f"{start_date} 09:15:00",
            end_date=f"{end_date} 15:30:00",
            ohlcv=["open", "high", "low", "close", "volume"],
            interval=interval_code
        )
        
        if data and data[0].get('data'):
            df = pd.DataFrame(data[0]['data'])
            df['date'] = pd.to_datetime(df['date'])
            
            # Simple moving average crossover strategy
            df['sma_10'] = df['close'].rolling(10).mean()
            df['sma_20'] = df['close'].rolling(20).mean()
            
            # Generate signals
            df['signal'] = 0
            df.loc[df['sma_10'] > df['sma_20'], 'signal'] = 1
            df.loc[df['sma_10'] < df['sma_20'], 'signal'] = -1
            
            # Calculate returns
            df['returns'] = df['close'].pct_change()
            df['strategy_returns'] = df['signal'].shift(1) * df['returns']
            
            # Calculate total return
            total_return = (1 + df['strategy_returns']).prod() - 1
            
            results[interval_name] = {
                'total_return': total_return,
                'num_trades': df['signal'].diff().abs().sum() / 2,
                'num_candles': len(df)
            }
    
    return results

# Compare strategy performance across intervals
performance = backtest_strategy_multiple_intervals(
    "NSE:SBIN:3045",
    "2024-01-01",
    "2024-01-31"
)

for interval, metrics in performance.items():
    print(f"{interval}: Return={metrics['total_return']:.2%}, "
          f"Trades={metrics['num_trades']:.0f}, "
          f"Candles={metrics['num_candles']}")
```

## Error Handling

```python
try:
    data = client.get_historical_ohlcv(
        instruments=["NSE:SBIN:3045"],
        start_date="2024-01-15 09:15:00",
        end_date="2024-01-15 15:30:00",
        ohlcv=["open", "high", "low", "close", "volume"],
        interval=client.INTERVAL_5_MINUTES
    )
except ValueError as e:
    print(f"Date format error: {e}")
except Exception as e:
    print(f"API error: {e}")
```

## Best Practices

1. **Use appropriate intervals for your strategy**:
   - Scalping: 1m, 2m, 3m
   - Day trading: 5m, 15m, 30m
   - Swing trading: 1h, 1d
   - Position trading: 1d, 1M

2. **Be mindful of data volume**:
   - 1-minute data generates a lot of candles
   - Use shorter date ranges for minute-level data

3. **Validate date formats**:
   - The client will validate formats automatically
   - Use datetime strings consistently

4. **Consider market hours**:
   - For intraday data, use market hours: 09:15:00 to 15:30:00
   - Weekend dates won't have intraday data

5. **Cache data when possible**:
   - Historical data doesn't change
   - Store frequently used datasets locally

### Order Management

#### Place Regular Order

Place a regular order for a single instrument:

```python
# Simple market order
order_response = client.place_order(
    exchange=client.EXCHANGE_NSE,
    trading_symbol="SBIN",
    transaction_type=client.TRANSACTION_TYPE_BUY,
    quantity=10,
    order_type=client.ORDER_TYPE_MARKET,
    product=client.PRODUCT_CNC
)
print(f"Order placed successfully: {order_response.get('orderId')}")

# Limit order with price
limit_order = client.place_order(
    exchange=client.EXCHANGE_NSE,
    trading_symbol="SBIN",
    transaction_type=client.TRANSACTION_TYPE_BUY,
    quantity=10,
    order_type=client.ORDER_TYPE_LIMIT,
    product=client.PRODUCT_CNC,
    price=650.00
)

# Order with stop loss and target
sl_order = client.place_order(
    exchange=client.EXCHANGE_NSE,
    trading_symbol="SBIN",
    transaction_type=client.TRANSACTION_TYPE_BUY,
    quantity=10,
    product=client.PRODUCT_CNC,
    stoploss=640.00,
    target=670.00
)
```

#### Modify Order

Modify an existing order:

```python
# Modify an order's price
modified_order = client.modify_order(
    order_id="order_01jpeyxtr4fb69fx740my3115c",
    price=655.00
)

# Modify an order's quantity
modified_order = client.modify_order(
    order_id="order_01jpeyxtr4fb69fx740my3115c",
    qty=15
)
```

#### Cancel Order

Cancel an existing order:

```python
# Cancel an order
cancelled_order = client.cancel_order(order_id="order_01jpeyxtr4fb69fx740my3115c")
```

#### Get Order Details

Fetch details of a specific order:

```python
# Get order details
order_details = client.get_order(order_id="order_01jpeyxtr4fb69fx740my3115c")
print(f"Order status: {order_details.get('status')}")
```

### Portfolio Management

#### Get Positions

Fetch your current positions:

```python
# Get all positions
all_positions = client.get_positions()
print(f"Found {len(all_positions)} positions")

# Get only open positions
open_positions = client.get_open_positions()
print(f"Found {len(open_positions)} open positions")

# Get only closed positions
closed_positions = client.get_closed_positions()
print(f"Found {len(closed_positions)} closed positions")
```

#### Get Holdings

Fetch your holdings:

```python
# Get holdings
holdings = client.get_holdings()
print(f"Found {len(holdings)} holdings")

# Get holdings for a specific portfolio
portfolio_holdings = client.get_holdings(portfolios="my_portfolio")
```

#### Exit Positions

Exit all positions or positions for a specific strategy:

```python
# Exit all positions
exit_response = client.exit_all_positions()
print(f"Successfully exited {exit_response.get('success', 0)} positions")

# Exit positions for a specific strategy
strategy_exit = client.exit_strategy_positions(strategy_id="str_01jbxszcjdegz8zt3h95g8c1d9")
```

### Basket Management

#### Create Basket

Create a new basket of instruments:

```python
# Create a basic basket with two stocks
basket_response = client.create_basket(
    name="My Basket",
    instruments=[
        {
            "shares": 10,
            "weightage": 50,
            "instrument": {
                "exchange": "NSE",
                "identifier": "NSE:SBIN:3045",
                "orderIndex": 1,
                "exchangeToken": 3045,
                "tradingSymbol": "SBIN"
            }
        },
        {
            "shares": 15,
            "weightage": 50,
            "instrument": {
                "exchange": "NSE",
                "identifier": "NSE:ICICIBANK:4963",
                "orderIndex": 2,
                "exchangeToken": 4963,
                "tradingSymbol": "ICICIBANK"
            }
        }
    ],
    weightage_scheme="equi_weighted",
    capital={"minValue": 50000, "actualValue": 50000},
    instrument_types=["EQLC"]
)
basket_id = basket_response.get('id')
```

#### Get Baskets

Fetch existing baskets:

```python
# Get all baskets
baskets = client.get_baskets()
print(f"Found {len(baskets)} baskets")

# Get a specific basket by ID
basket = client.get_basket(basket_id="bk_01jpf2d57ae96bez63me7p6g9k")

# Get instruments in a basket
basket_instruments = client.get_basket_instruments(basket_id="bk_01jpf2d57ae96bez63me7p6g9k")
```

#### Place Basket Order

Place an order for an entire basket:

```python
# Place a basket order
basket_order = client.place_basket_order(
    trading_symbol="/MY_BASKET",
    transaction_type=client.TRANSACTION_TYPE_BUY,
    quantity=1,
    price=50000.00,
    product=client.PRODUCT_CNC
)
```

#### Exit Basket Order

Exit a basket position:

```python
# Exit a basket position
exit_order = client.place_basket_exit_order(
    trading_symbol="/MY_BASKET",
    exchange=client.EXCHANGE_WZR,
    transaction_type=client.TRANSACTION_TYPE_SELL,
    quantity=1,
    exchange_token=1741872632
)
```

#### Rebalance Basket

#### Available Weightage Schemes

When creating or rebalancing baskets, you can choose from several weightage schemes:

- **`WEIGHTAGE_SCHEME_EQUI_WEIGHTED`**: Equal weightage for all instruments
- **`WEIGHTAGE_SCHEME_QUANTITY_WEIGHTED`**: Weighted by quantity
- **`WEIGHTAGE_SCHEME_PRICE_WEIGHTED`**: Weighted by price
- **`WEIGHTAGE_SCHEME_MARKET_CAP_WEIGHTED`**: Weighted by market capitalization
- **`WEIGHTAGE_SCHEME_FLOAT_ADJUSTED_MARKET_CAP_WEIGHTED`**: Weighted by float-adjusted market cap
- **`WEIGHTAGE_SCHEME_FUNDAMENTAL_WEIGHTED`**: Weighted by fundamental metrics
- **`WEIGHTAGE_SCHEME_CUSTOM_WEIGHTED`**: Custom weightage scheme

Rebalance a basket with new instruments:

```python
# Rebalance a basket
rebalance_response = client.rebalance_basket(
    trading_symbol="/MY_BASKET",
    instruments=["NSE:SBIN:3045", "NSE:HDFCBANK:1333", "NSE:TCS:2953"]
)

# Full Rebalance with market cap weighting & execution of all orders at market price
client.rebalance_basket(
    trading_symbol="/MY_BASKET",
    instruments=["NSE:SBIN:3045", "NSE:HDFCBANK:1333"],
    execution_policy=client.REBALANCE_FULL,
    order_type=client.ORDER_TYPE_MARKET,
    weightage_scheme=client.WEIGHTAGE_SCHEME_MARKET_CAP_WEIGHTED
)

# Entry-only rebalance with price weighting
client.rebalance_basket(
    trading_symbol="/MY_BASKET",
    instruments=["NSE:SBIN:3045", "NSE:HDFCBANK:1333"],
    execution_policy=client.REBALANCE_ENTRY_ONLY,
    weightage_scheme=client.WEIGHTAGE_SCHEME_EQUI_WEIGHTED
)
```

### Instrument Management
## Instrument Data APIs

### Get Instrument Metrics

Fetch detailed information and metrics for specific instruments:

```python
# Get metrics for a single equity instrument
equity_info = client.get_instrument_metrics(identifiers=["NSE:SBIN:3045"])
print(f"SBIN Last Price: {equity_info[0]['ltp']}")
print(f"SBIN 52-week High: {equity_info[0]['week52High']}")

# Get metrics for multiple instruments of different types
instruments_info = client.get_instrument_metrics(
    identifiers=[
        "NSE:AARTIIND:7",              # Equity
        "NSE:NIFTY26DEC11000CE:61009", # Option
        "NSE:SBIN25MAYFUT:57515"       # Future
    ]
)

# Print detailed information for each instrument
for instrument in instruments_info:
    print(f"{instrument['tradingSymbol']} ({instrument['instrumentType']}):")
    print(f"  LTP: {instrument['ltp']}")
    print(f"  Exchange: {instrument['exchange']}")
    print(f"  Segment: {instrument['segment']}")
    if instrument.get('bhavcopy'):
        print(f"  Volume: {instrument['bhavcopy']['volume']}")
        print(f"  OHLC: {instrument['bhavcopy']['open']}/{instrument['bhavcopy']['high']}/"
              f"{instrument['bhavcopy']['low']}/{instrument['bhavcopy']['close']}")
```

#### Response Structure for Instrument Metrics

The `get_instrument_metrics` method returns a list of dictionaries, each with the following structure:

```python
[
    {
        # Instrument name if available
        "name": "",
        
        # Trading symbol
        "tradingSymbol": "AARTIIND",
        
        # Exchange code
        "exchange": "NSE",
        
        # Bid price if available
        "bid": 0,
        
        # Size of total bids at best bid price
        "bidSize": 0,
        
        # Ask (offer) price
        "ask": 0,
        
        # Size of total asks at best ask price
        "askSize": 0,
        
        # Last traded price
        "ltp": 450.05,
        
        # Trading volume
        "volume": 0,
        
        # Lot size for the instrument
        "lotSize": 1,
        
        # Mid price ((bid+ask)/2)
        "mid": 0,
        
        # Market capitalization (for equities)
        "marketCap": 0,
        
        # Dividend yield percentage (for equities)
        "dividendYield": 0,
        
        # Last dividend date
        "dividendDate": "",
        
        # Daily Open-High-Low-Close values
        "ohlc": {
            "open": 0,
            "high": 0,
            "low": 0,
            "close": 0
        },
        
        # Industry classification (for equities)
        "industry": "",
        
        # Sector classification (for equities)
        "sector": "",
        
        # Relevant indicators for underlying assets (for derivatives)
        "underlyingIndicators": "",
        
        # Net change in price
        "netChange": 0,
        
        # Net change in percentage
        "netChangePercentage": 0,
        
        # Beta value (for equities)
        "beta": 0,
        
        # Liquidity rating
        "liquidityRating": 0,
        
        # Implied volatility metrics (for options)
        "iv": {
            "index": 0,
            "indexRank": 0,
            "percentile": 0,
            "change5Days": 0,
            "change30Days": 0,
            "ivHvChange30Days": 0
        },
        
        # Historical volatility metrics
        "hv": {
            "change30Days": 0,
            "change60Days": 0,
            "change90Days": 0
        },
        
        # Minimum price movement
        "tickSize": 0.05,
        
        # Previous day's trading summary
        "bhavcopy": {
            "open": 458.4,
            "high": 470.9,
            "low": 440.75,
            "close": 448.55,
            "volume": 3544523,
            "turnover": 1632822505.15,
            "totalTrades": 59999
        },
        
        # Exchange token identifier
        "exchangeToken": 7,
        
        # Market segment
        "segment": "NSECM",
        
        # Whether the instrument is actively traded
        "isTraded": false,
        
        # Complete instrument identifier
        "identifier": "NSE:AARTIIND:7",
        
        # Instrument type code
        "instrumentType": "EQLC",
        
        # Option type (for options) - CE or PE
        "optionType": "",
        
        # Expiry date (for derivatives)
        "expiry": "",
        
        # International Securities Identification Number
        "isin": "INE769A01020",
        
        # Margin requirement percentage
        "margin": 19.43,
        
        # 52-week high price
        "week52High": 765.5,
        
        # 52-week low price
        "week52Low": 344.2,
        
        # Maximum allowed trade volume
        "maxTradeVolume": 2147483647,
        
        # Price band limits
        "priceBand": {
            "high": 493.4,
            "low": 403.7,
            "creditRating": {
                "lower": 403.7,
                "higher": 493.4
            }
        }
    },
    # Additional instruments...
]
```

Note that certain fields may have zero or empty values if the data is not available from the exchange or if it's not applicable to that instrument type.

### Options Chain

#### Get Option Expiry List

Fetch available expiry dates for an instrument's options:

```python
# For a stock
expiry_list = client.get_option_expiry_list("NSE:SBIN:3045")

# For an index
nifty_expiry = client.get_option_expiry_list("NSE:NIFTY 50:26000")

# Print all available expiry dates
for expiry in expiry_list.get('expiryList', []):
    print(f"{expiry['date']} - {expiry['contract']} " +
          f"(Futures: {'Yes' if expiry['isFuturesExpiry'] else 'No'}, " +
          f"Options: {'Yes' if expiry['isOptionsExpiry'] else 'No'})")
```

#### Response Structure

The response is a JSON object with the following structure:

```json
{
  "exchange": "NSE",                // Exchange of the instrument
  "tradingSymbol": "SBIN",          // Trading symbol
  "exchangeToken": 3045,            // Exchange token
  "identifier": "NSE:SBIN:3045",    // Full identifier
  "expiryList": [                   // Array of expiry objects
    {
      "date": "2025-05-29",         // Expiry date in YYYY-MM-DD format
      "contract": "near_month",     // Contract type (see below)
      "isFuturesExpiry": true,      // Whether futures expire on this date
      "isOptionsExpiry": true       // Whether options expire on this date
    },
    // More expiry objects...
  ]
}
```

For index options like NIFTY, the response will typically include more expiry dates, including weekly options and longer-dated quarterly options.

The `expiryList` array contains objects with the following fields:
- `date`: The expiry date in YYYY-MM-DD format
- `contract`: The type of contract (e.g., "near_month", "current_weekly")
- `isFuturesExpiry`: Boolean indicating if futures expire on this date
- `isOptionsExpiry`: Boolean indicating if options expire on this date

#### Contract Types

Each expiry date is categorized with a `contract` field that indicates the type of expiry. The possible contract types are:

1. **Weekly Expiries (Thursdays/Wednesdays)**
   - `current_weekly`: The first non-expiry Thursday of the current week

2. **Monthly Expiries (last Wed/Thu of month)**
   - `near_month`: Last Wed/Thu of this month (current month)
   - `mid_month`: Last Wed/Thu of next month
   - `far_month`: Last Wed/Thu of month after next

3. **Weekly Ordinals Within Current Month**
   - `first_weekly`: 1st non-expiry Thursday of current month
   - `second_weekly`: 2nd non-expiry Thursday
   - `third_weekly`: 3rd non-expiry Thursday
   - `fourth_weekly`: 4th non-expiry Thursday
   - `fifth_weekly`: 5th non-expiry Thursday (rare)

4. **Weekly Ordinals in Mid-Month Slot (next month's week-trade dates)**
   - `first_weekly_mid_month`: 1st Thursday of next month
   - `second_weekly_mid_month`: 2nd Thursday of next month
   - `third_weekly_mid_month`: 3rd Thursday of next month
   - `fourth_weekly_mid_month`: 4th Thursday of next month
   - `fifth_weekly_mid_month`: 5th Thursday of next month (rare)

5. **Weekly Ordinals in Far-Month Slot (month-after-next)**
   - `first_weekly_far_month`: 1st Thursday of month after next
   - `second_weekly_far_month`: 2nd Thursday of month after next
   - `third_weekly_far_month`: 3rd Thursday of month after next
   - `fourth_weekly_far_month`: 4th Thursday of month after next
   - `fifth_weekly_far_month`: 5th Thursday of month after next (rare)

6. **Quarterly Expiries (last-Thu of Mar/Jun/Sep/Dec)**
   - `first_quarter`: Last Thu of March (Q1)
   - `second_quarter`: Last Thu of June (Q2)
   - `third_quarter`: Last Thu of September (Q3)
   - `fourth_quarter`: Last Thu of December (Q4)

7. **Half-Yearly Expiries**
   - `first_half_yearly`: Last Thu of June (H1)
   - `second_half_yearly`: Last Thu of December (H2)

8. **Year-Plus-N Quarterly/Half-Yearly (N = years ahead)**
   - For quarterly options in future years:
     - `first_quarter_1`: Q1 (March) of next year
     - `second_quarter_1`: Q2 (June) of next year
     - `third_quarter_1`: Q3 (September) of next year
     - `fourth_quarter_1`: Q4 (December) of next year
   - For half-yearly options in future years:
     - `first_half_yearly_1`: H1 (June) of next year
     - `second_half_yearly_1`: H2 (December) of next year
   - This pattern continues with `_2`, `_3`, and `_4` suffixes for up to 4 years ahead

9. **Special Case**
   - `none`: No matching expiry category

### Get Options Chain

The Options Chain API provides detailed information about available option contracts for a specified instrument, including strike prices, premiums, and option Greeks.

#### Constants

The SDK provides constants for option types, moneyness, and expiry preferences to make your code more readable and type-safe:

**Option Types:**
```python
client.OPTION_TYPE_CE  # Call option
client.OPTION_TYPE_PE  # Put option
```

**Moneyness Types:**
```python
client.MONEYNESS_ATM  # At-the-money
client.MONEYNESS_ITM  # In-the-money
client.MONEYNESS_OTM  # Out-of-the-money
```

**Expiry Preferences:**
```python
# Common expiry preferences
client.EXPIRY_CURRENT_WEEKLY  # Current week's expiry
client.EXPIRY_NEAR_MONTH      # Current month's expiry
client.EXPIRY_MID_MONTH       # Next month's expiry
client.EXPIRY_FAR_MONTH       # Month after next expiry

# Many more constants available for weekly, monthly, 
# quarterly, and yearly expiries
```

#### Get Option Chain

Fetch the option chain for a specific instrument using either an exact expiry date or a expiry preference:

```python
# Get ATM call options for SBIN with specific expiry date
options = client.get_option_chain(
    identifier="NSE:SBIN:3045",
    expiry_date="2025-05-30",
    option_type=[client.OPTION_TYPE_CE],  # Call options
    moneyness=[client.MONEYNESS_ATM]      # At-the-money
)
print(f"Found {len(options['strikes'])} strikes")
print(f"Current underlying price: {options['underlyingPrice']}")

# Get both call and put options with expiry preference
all_options = client.get_option_chain(
    identifier="NSE:NIFTY 50:26000",
    expiry_preference=client.EXPIRY_CURRENT_WEEKLY,  # Current week's expiry
    option_type=[client.OPTION_TYPE_CE, client.OPTION_TYPE_PE],  # Both calls and puts
    moneyness=[client.MONEYNESS_ATM, client.MONEYNESS_ITM, client.MONEYNESS_OTM]  # All moneyness types
)

# Print option chain details
print(f"Resolved expiry: {all_options['resolvedExpiry']}")
print(f"Underlying price: {all_options['underlyingPrice']}")
print(f"Future price: {all_options['futurePrice']}")

# Process options data
for strike in all_options['strikes']:
    print(f"{strike['tradingSymbol']} ({strike['moneyness']}): {strike['ltp']}")
```

#### Response Structure

The `get_option_chain` method returns a dictionary with the following structure:

```python
{
    # The actual expiry date that was resolved (may differ slightly from requested date)
    "resolvedExpiry": "2025-05-29", 
    
    # Current price of the underlying stock/index
    "underlyingPrice": 792.1,
    
    # Price of the corresponding futures contract (if applicable)
    "futurePrice": 793.35,
    
    # Array of available strike prices matching the query criteria
    "strikes": [
        {
            # The strike price of the option
            "strikePrice": 790,
            
            # Option type: "CE" (Call) or "PE" (Put)
            "optionType": "CE",
            
            # Exchange token for the option contract
            "exchangeToken": 136169,
            
            # Exchange where the option is traded
            "exchange": "NSE",
            
            # Trading symbol for the option contract
            "tradingSymbol": "SBIN25MAY790CE",
            
            # Moneyness classification: "ATM", "ITM", or "OTM"
            "moneyness": "ATM",
            
            # Expiry date of the option contract
            "expiry": "2025-05-29",
            
            # Last traded price of the option
            "ltp": 15.1,
            
            # Option Greeks and metrics (if available)
            "metrics": {
                # Option premium
                "premium": 0,
                
                # Open interest
                "oi": 0,
                
                # Implied volatility
                "iv": 0,
                
                # Delta - rate of change of option price with respect to underlying
                "delta": 0,
                
                # Gamma - rate of change of delta with respect to underlying
                "gamma": 0,
                
                # Theta - rate of change of option price with respect to time
                "theta": 0,
                
                # Vega - rate of change of option price with respect to volatility
                "vega": 0,
                
                # Rho - rate of change of option price with respect to interest rate
                "rho": 0
            }
        },
        # Additional strikes...
    ]
}
```

#### Advanced Examples

##### Finding a Straddle/Strangle

```python
def find_straddle_strangle(identifier, expiry):
    """Find and analyze straddle/strangle opportunities."""
    # Get the option chain
    option_chain = client.get_option_chain(
        identifier=identifier,
        expiry_date=expiry,
        option_type=[client.OPTION_TYPE_CE, client.OPTION_TYPE_PE],
        moneyness=[client.MONEYNESS_ATM]
    )
    
    # Find ATM call and put
    calls = [s for s in option_chain["strikes"] if s["optionType"] == "CE"]
    puts = [s for s in option_chain["strikes"] if s["optionType"] == "PE"]
    
    if not calls or not puts:
        print("Couldn't find both call and put options")
        return
    
    # For a straddle, we want the same strike price
    atm_strike = calls[0]["strikePrice"]
    atm_call = calls[0]
    atm_put = next((p for p in puts if p["strikePrice"] == atm_strike), None)
    
    if atm_call and atm_put:
        call_premium = atm_call["ltp"]
        put_premium = atm_put["ltp"]
        total_premium = call_premium + put_premium
        
        print(f"ATM Straddle Analysis for {identifier} (Expiry: {expiry})")
        print(f"Underlying Price: {option_chain['underlyingPrice']}")
        print(f"ATM Strike: {atm_strike}")
        print(f"Call Premium: {call_premium}")
        print(f"Put Premium: {put_premium}")
        print(f"Total Premium: {total_premium}")
        print(f"Breakeven Upper: {atm_strike + total_premium}")
        print(f"Breakeven Lower: {atm_strike - total_premium}")
        
        # Calculate the percentage move needed for breakeven
        pct_move = (total_premium / option_chain['underlyingPrice']) * 100
        print(f"Required % Move for Breakeven: {pct_move:.2f}%")
    
    # For a strangle, we want OTM call and put
    otm_options = client.get_option_chain(
        identifier=identifier,
        expiry_date=expiry,
        option_type=[client.OPTION_TYPE_CE, client.OPTION_TYPE_PE],
        moneyness=[client.MONEYNESS_OTM]
    )
    
    otm_calls = sorted([s for s in otm_options["strikes"] if s["optionType"] == "CE"], 
                       key=lambda x: x["strikePrice"])
    otm_puts = sorted([s for s in otm_options["strikes"] if s["optionType"] == "PE"], 
                      key=lambda x: x["strikePrice"], reverse=True)
    
    if otm_calls and otm_puts:
        otm_call = otm_calls[0]  # First OTM call
        otm_put = otm_puts[0]    # First OTM put
        
        call_premium = otm_call["ltp"]
        put_premium = otm_put["ltp"]
        total_premium = call_premium + put_premium
        
        print(f"\nOTM Strangle Analysis for {identifier} (Expiry: {expiry})")
        print(f"Call Strike: {otm_call['strikePrice']} (Premium: {call_premium})")
        print(f"Put Strike: {otm_put['strikePrice']} (Premium: {put_premium})")
        print(f"Total Premium: {total_premium}")
        print(f"Breakeven Upper: {otm_call['strikePrice'] + total_premium}")
        print(f"Breakeven Lower: {otm_put['strikePrice'] - total_premium}")
    
    return option_chain

# Example usage
find_straddle_strangle("NSE:SBIN:3045", "2025-05-30")
```

##### Option Chain Visualization

```python
def visualize_option_chain(identifier, expiry):
    """Create a visualization of the option chain."""
    import matplotlib.pyplot as plt
    import numpy as np
    
    # Get the option chain
    option_chain = client.get_option_chain(
        identifier=identifier,
        expiry_date=expiry,
        option_type=[client.OPTION_TYPE_CE, client.OPTION_TYPE_PE],
        moneyness=[client.MONEYNESS_ATM, client.MONEYNESS_ITM, client.MONEYNESS_OTM]
    )
    
    # Extract data
    underlying_price = option_chain["underlyingPrice"]
    
    # Separate calls and puts
    calls = sorted([s for s in option_chain["strikes"] if s["optionType"] == "CE"], 
                  key=lambda x: x["strikePrice"])
    puts = sorted([s for s in option_chain["strikes"] if s["optionType"] == "PE"], 
                 key=lambda x: x["strikePrice"])
    
    # Extract strike prices and premiums
    call_strikes = [c["strikePrice"] for c in calls]
    call_premiums = [c["ltp"] for c in calls]
    
    put_strikes = [p["strikePrice"] for p in puts]
    put_premiums = [p["ltp"] for p in puts]
    
    # Create figure and axis
    fig, ax = plt.subplots(figsize=(12, 8))
    
    # Plot calls and puts
    ax.plot(call_strikes, call_premiums, 'b-', marker='o', label='Calls')
    ax.plot(put_strikes, put_premiums, 'r-', marker='o', label='Puts')
    
    # Add vertical line for current price
    ax.axvline(x=underlying_price, color='g', linestyle='--', 
               label=f'Current Price ({underlying_price})')
    
    # Add labels and title
    ax.set_xlabel('Strike Price')
    ax.set_ylabel('Premium')
    ax.set_title(f'Option Chain for {identifier} (Expiry: {expiry})')
    ax.legend()
    ax.grid(True)
    
    plt.tight_layout()
    plt.show()
    
    return option_chain

# Example usage
visualize_option_chain("NSE:NIFTY 50:26000", "2025-05-30")
```

#### Get Futures List

Fetch available futures contracts for an instrument:

```python
# Get futures for an equity stock
sbin_futures = client.get_futures_list("NSE:SBIN:3045")
print(f"Found {len(sbin_futures)} futures contracts for SBIN")
for future in sbin_futures:
    print(f"{future['tradingSymbol']} - Expiry: {future['expiry']} ({future['contract']})")

# Get futures for an index
nifty_futures = client.get_futures_list("NSE:NIFTY 50:26000")
print(f"Found {len(nifty_futures)} futures contracts for NIFTY 50")
for future in nifty_futures:
    print(f"{future['tradingSymbol']} - Expiry: {future['expiry']} ({future['contract']})")
```

#### Response Structure for Futures List

The `get_futures_list` method returns a list of dictionaries, each representing a futures contract:

```python
[
    {
        # Exchange where the future is traded
        "exchange": "NSE",
        
        # Trading symbol of the futures contract
        "tradingSymbol": "SBIN25MAYFUT",
        
        # Exchange token for the futures contract
        "exchangeToken": 57515,
        
        # Complete identifier for the futures contract
        "identifier": "NSE:SBIN25MAYFUT:57515",
        
        # Expiry date in YYYY-MM-DD format
        "expiry": "2025-05-29",
        
        # Contract type (near_month, mid_month, far_month)
        "contract": "near_month"
    },
    # Additional futures contracts...
]
```

The `contract` field indicates the type of futures contract:
- **`near_month`**: Current month's futures contract
- **`mid_month`**: Next month's futures contract  
- **`far_month`**: Month after next futures contract

### Wizzer Client Examples

#### Market Data and Analysis Example

```python
from wiz_trader import WizzerClient
import pandas as pd
import matplotlib.pyplot as plt

# Initialize client
client = WizzerClient(
    base_url="https://api-url.in",
    token="your-jwt-token"
)

def analyze_index_performance(index_symbol, exchange, start_date, end_date):
    # Get index components
    components = client.get_index_components(
        trading_symbol=index_symbol,
        exchange=exchange
    )
    print(f"Found {len(components)} components in {index_symbol}")
    
    # Get the identifiers for the top 5 weighted components
    top_components = sorted(components, key=lambda x: x.get('weightage', 0), reverse=True)[:5]
    instrument_ids = [comp['identifier'] for comp in top_components]
    
    # Fetch historical data
    historical_data = client.get_historical_ohlcv(
        instruments=instrument_ids,
        start_date=start_date,
        end_date=end_date,
        ohlcv=["close"],
        interval="1d"
    )
    
    # Process and plot the data
    for instrument_data in historical_data:
        symbol = instrument_data['instrument'].split(':')[1]
        df = pd.DataFrame(instrument_data['data'])
        df['date'] = pd.to_datetime(df['date'])
        df.set_index('date', inplace=True)
        
        # Calculate percentage change from first day
        first_close = df['close'].iloc[0]
        df['pct_change'] = ((df['close'] - first_close) / first_close) * 100
        
        plt.plot(df.index, df['pct_change'], label=symbol)
    
    plt.title(f"Performance of Top {index_symbol} Components")
    plt.xlabel("Date")
    plt.ylabel("% Change")
    plt.legend()
    plt.grid(True)
    plt.show()

# Analyze NIFTY 50 performance for Jan 2024
analyze_index_performance(
    index_symbol="NIFTY 50",
    exchange="NSE",
    start_date="2024-01-01",
    end_date="2024-01-31"
)
```

#### Algorithmic Trading Example

```python
from wiz_trader import QuotesClient, WizzerClient
import time
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class SimpleMovingAverageCrossover:
    def __init__(self, symbol, exchange, token, fast_period=5, slow_period=20):
        # Trading parameters
        self.symbol = symbol
        self.exchange = exchange
        self.token = token
        self.instrument_id = f"{exchange}:{symbol}:{token}"
        self.fast_period = fast_period
        self.slow_period = slow_period
        
        # State variables
        self.prices = []
        self.position = None
        self.order_id = None
        
        # Clients
        self.quotes_client = QuotesClient(
            base_url="wss://websocket-url/quotes",
            token="your-jwt-token"
        )
        self.wizzer_client = WizzerClient(
            base_url="https://api-url.in",
            token="your-jwt-token"
        )
        
        # Set up quotes client callbacks
        self.quotes_client.on_tick = self.on_tick
        self.quotes_client.on_connect = self.on_connect
        self.quotes_client.on_error = lambda ws, error: logger.error(f"Error: {error}")
    
    def on_connect(self, ws):
        logger.info(f"Connected to quotes server")
        ws.subscribe([self.instrument_id])
    
    def on_tick(self, ws, tick):
        if "ltp" in tick:
            price = tick["ltp"]
            self.prices.append(price)
            
            # Keep only the required number of prices
            if len(self.prices) > self.slow_period:
                self.prices.pop(0)
            
            # Once we have enough data, check for signals
            if len(self.prices) >= self.slow_period:
                self.check_for_signals()
    
    def check_for_signals(self):
        # Calculate moving averages
        fast_ma = sum(self.prices[-self.fast_period:]) / self.fast_period
        slow_ma = sum(self.prices) / self.slow_period
        
        current_price = self.prices[-1]
        
        logger.info(f"Price: {current_price}, Fast MA: {fast_ma:.2f}, Slow MA: {slow_ma:.2f}")
        
        # Generate signals
        if fast_ma > slow_ma and self.position != "long":
            # Buy signal
            logger.info("BUY SIGNAL")
            self.enter_position("long", current_price)
        
        elif fast_ma < slow_ma and self.position == "long":
            # Sell signal
            logger.info("SELL SIGNAL")
            self.exit_position(current_price)
    
    def enter_position(self, position_type, price):
        if position_type == "long":
            # Place a buy order
            try:
                order_response = self.wizzer_client.place_order(
                    exchange=self.exchange,
                    trading_symbol=self.symbol,
                    transaction_type=self.wizzer_client.TRANSACTION_TYPE_BUY,
                    quantity=10,  # Fixed quantity for simplicity
                    order_type=self.wizzer_client.ORDER_TYPE_MARKET,
                    product=self.wizzer_client.PRODUCT_CNC
                )
                self.order_id = order_response.get("orderId")
                self.position = "long"
                logger.info(f"Entered LONG position at {price}, Order ID: {self.order_id}")
            except Exception as e:
                logger.error(f"Error entering position: {e}")
    
    def exit_position(self, price):
        if self.position == "long":
            # Place a sell order
            try:
                order_response = self.wizzer_client.place_order(
                    exchange=self.exchange,
                    trading_symbol=self.symbol,
                    transaction_type=self.wizzer_client.TRANSACTION_TYPE_SELL,
                    quantity=10,  # Fixed quantity for simplicity
                    order_type=self.wizzer_client.ORDER_TYPE_MARKET,
                    product=self.wizzer_client.PRODUCT_CNC
                )
                logger.info(f"Exited LONG position at {price}, Order ID: {order_response.get('orderId')}")
                self.position = None
                self.order_id = None
            except Exception as e:
                logger.error(f"Error exiting position: {e}")
    
    def run(self):
        try:
            logger.info("Starting the strategy...")
            self.quotes_client.connect()
        except KeyboardInterrupt:
            logger.info("Strategy interrupted by user")
            if self.position:
                logger.info("Closing position before exit")
                self.exit_position(self.prices[-1] if self.prices else 0)
            self.quotes_client.stop()

# Run the strategy
strategy = SimpleMovingAverageCrossover(
    symbol="SBIN",
    exchange="NSE",
    token=3045,
    fast_period=5,
    slow_period=20
)
strategy.run()
```

#### Basket Management Example

```python
from wiz_trader import WizzerClient
import json

# Initialize client
client = WizzerClient(
    base_url="https://api-url.in",
    token="your-jwt-token"
)

def create_and_trade_basket():
    # Create a sector-based basket
    banking_basket = client.create_basket(
        name="Banking Basket",
        instruments=[
            {
                "shares": 20,
                "weightage": 25,
                "instrument": {
                    "exchange": "NSE",
                    "identifier": "NSE:SBIN:3045",
                    "orderIndex": 1,
                    "exchangeToken": 3045,
                    "tradingSymbol": "SBIN"
                }
            },
            {
                "shares": 15,
                "weightage": 25,
                "instrument": {
                    "exchange": "NSE",
                    "identifier": "NSE:ICICIBANK:4963",
                    "orderIndex": 2,
                    "exchangeToken": 4963,
                    "tradingSymbol": "ICICIBANK"
                }
            },
            {
                "shares": 15,
                "weightage": 25,
                "instrument": {
                    "exchange": "NSE",
                    "identifier": "NSE:HDFCBANK:1333",
                    "orderIndex": 3,
                    "exchangeToken": 1333,
                    "tradingSymbol": "HDFCBANK"
                }
            },
            {
                "shares": 30,
                "weightage": 25,
                "instrument": {
                    "exchange": "NSE",
                    "identifier": "NSE:BANKBARODA:2263",
                    "orderIndex": 4,
                    "exchangeToken": 2263,
                    "tradingSymbol": "BANKBARODA"
                }
            }
        ],
        weightage_scheme="equi_weighted",
        capital={"minValue": 100000, "actualValue": 100000},
        instrument_types=["EQLC"]
    )
    
    basket_id = banking_basket.get('id')
    basket_symbol = banking_basket.get('tradingSymbol')
    exchange_token = banking_basket.get('basketInstrument', {}).get('exchangeToken')
    
    print(f"Created basket: {basket_symbol} (ID: {basket_id})")
    
    # Place a buy order for the basket
    try:
        order_response = client.place_basket_order(
            trading_symbol=basket_symbol,
            transaction_type=client.TRANSACTION_TYPE_BUY,
            quantity=1,  # Buy one unit of the basket
            price=100000.00,
            product=client.PRODUCT_CNC
        )
        print(f"Placed basket buy order: {order_response.get('orderId')}")
        
        # After some time, exit the basket
        # (This would normally be based on some strategy or time delay)
        exit_response = client.place_basket_exit_order(
            trading_symbol=basket_symbol,
            exchange=client.EXCHANGE_WZR,
            transaction_type=client.TRANSACTION_TYPE_SELL,
            quantity=1,
            exchange_token=exchange_token
        )
        print(f"Placed basket exit order: {exit_response.get('orderId')}")
        
    except Exception as e:
        print(f"Error during basket trading: {e}")

# Rebalance the basket (e.g., to adjust weightages or change stocks)
    try:
        rebalance_response = client.rebalance_basket(
            trading_symbol=basket_symbol,
            instruments=[
                "NSE:SBIN:3045",
                "NSE:HDFCBANK:1333",
                "NSE:ICICIBANK:4963",
                "NSE:AXISBANK:5900"  # Replacing BANKBARODA with AXISBANK
            ]
        )
        print(f"Rebalanced basket successfully")
    except Exception as e:
        print(f"Error during basket rebalancing: {e}")

# Run the basket trading example
create_and_trade_basket()
```

## Common Use Cases

### Backtesting with Historical Data

```python
from wiz_trader import WizzerClient
import pandas as pd
import numpy as np
from datetime import datetime

# Initialize client
client = WizzerClient(
    base_url="https://api-url.in",
    token="your-jwt-token"
)

def backtest_simple_strategy(symbol, exchange, token, start_date, end_date, 
                             fast_period=10, slow_period=30):
    # Get historical data
    instrument_id = f"{exchange}:{symbol}:{token}"
    data = client.get_historical_ohlcv(
        instruments=[instrument_id],
        start_date=start_date,
        end_date=end_date,
        ohlcv=["open", "high", "low", "close", "volume"],
        interval="1d"
    )
    
    if not data or not data[0].get('data'):
        print("No data available for the specified period")
        return
    
    # Convert to DataFrame
    df = pd.DataFrame(data[0]['data'])
    df['date'] = pd.to_datetime(df['date'])
    df.set_index('date', inplace=True)
    
    # Calculate moving averages
    df['fast_ma'] = df['close'].rolling(window=fast_period).mean()
    df['slow_ma'] = df['close'].rolling(window=slow_period).mean()
    
    # Generate signals
    df['signal'] = 0
    df.loc[df['fast_ma'] > df['slow_ma'], 'signal'] = 1  # Buy signal
    df.loc[df['fast_ma'] < df['slow_ma'], 'signal'] = -1  # Sell signal
    
    # Calculate returns
    df['returns'] = df['close'].pct_change()
    df['strategy_returns'] = df['signal'].shift(1) * df['returns']
    
    # Calculate cumulative returns
    df['cumulative_returns'] = (1 + df['returns']).cumprod() - 1
    df['strategy_cumulative_returns'] = (1 + df['strategy_returns']).cumprod() - 1
    
    # Calculate statistics
    total_days = len(df)
    winning_days = len(df[df['strategy_returns'] > 0])
    win_rate = winning_days / total_days if total_days > 0 else 0
    
    strategy_return = df['strategy_cumulative_returns'].iloc[-1]
    buy_hold_return = df['cumulative_returns'].iloc[-1]
    
    print(f"Backtest Results for {symbol} ({start_date} to {end_date}):")
    print(f"Strategy Return: {strategy_return:.2%}")
    print(f"Buy & Hold Return: {buy_hold_return:.2%}")
    print(f"Win Rate: {win_rate:.2%}")
    print(f"Total Trades: {df['signal'].diff().abs().sum() / 2:.0f}")
    
    return df

# Run a backtest
result_df = backtest_simple_strategy(
    symbol="SBIN",
    exchange="NSE",
    token=3045,
    start_date="2023-01-01",
    end_date="2023-12-31",
    fast_period=10,
    slow_period=30
)

# Plot the results 
import matplotlib.pyplot as plt

plt.figure(figsize=(12, 8))

# Plot prices and moving averages
plt.subplot(2, 1, 1)
plt.plot(result_df.index, result_df['close'], label='Close Price')
plt.plot(result_df.index, result_df['fast_ma'], label=f'Fast MA ({10} days)')
plt.plot(result_df.index, result_df['slow_ma'], label=f'Slow MA ({30} days)')
plt.title('Price and Moving Averages')
plt.legend()
plt.grid(True)

# Plot cumulative returns
plt.subplot(2, 1, 2)
plt.plot(result_df.index, result_df['cumulative_returns'], label='Buy & Hold')
plt.plot(result_df.index, result_df['strategy_cumulative_returns'], label='Strategy')
plt.title('Cumulative Returns')
plt.legend()
plt.grid(True)

plt.tight_layout()
plt.show()
```

### Real-time Portfolio Monitoring

```python
from wiz_trader import QuotesClient, WizzerClient
import pandas as pd
import time
from datetime import datetime

# Initialize clients
quotes_client = QuotesClient(
    base_url="wss://websocket-url/quotes",
    token="your-jwt-token",
    log_level="info"
)

wizzer_client = WizzerClient(
    base_url="https://api-url.in",
    token="your-jwt-token",
    log_level="info"
)

class PortfolioMonitor:
    def __init__(self):
        self.portfolio = {}
        self.last_update_time = None
        self.update_interval = 60  # seconds
        
    def on_tick(self, ws, tick):
        """Process incoming market data"""
        if 'instrument' in tick and 'ltp' in tick:
            instrument = tick['instrument']
            ltp = tick['ltp']
            
            if instrument in self.portfolio:
                # Update the current price
                self.portfolio[instrument]['current_price'] = ltp
                
                # Calculate P&L
                avg_price = self.portfolio[instrument]['avg_price']
                qty = self.portfolio[instrument]['qty']
                
                if qty > 0:  # Long position
                    pnl = (ltp - avg_price) * qty
                    pnl_percent = ((ltp / avg_price) - 1) * 100
                else:  # Short position
                    pnl = (avg_price - ltp) * abs(qty)
                    pnl_percent = ((avg_price / ltp) - 1) * 100
                
                self.portfolio[instrument]['pnl'] = pnl
                self.portfolio[instrument]['pnl_percent'] = pnl_percent
                
                # Display portfolio if update interval has passed
                current_time = time.time()
                if (self.last_update_time is None or 
                    current_time - self.last_update_time > self.update_interval):
                    self.display_portfolio()
                    self.last_update_time = current_time
    
    def on_connect(self, ws):
        """Handle connection to quotes server"""
        print(f"Connected to quotes server at {datetime.now()}")
        # Fetch holdings and subscribe to them
        self.fetch_holdings()
    
    def fetch_holdings(self):
        """Fetch holdings from the API and update portfolio"""
        try:
            holdings = wizzer_client.get_holdings()
            
            # Extract holding information and update portfolio
            instruments_to_subscribe = []
            for holding in holdings:
                if holding.get('qty', 0) > 0:
                    instrument = holding.get('identifier', '')
                    if instrument:
                        self.portfolio[instrument] = {
                            'symbol': holding.get('tradingSymbol', ''),
                            'exchange': holding.get('exchange', ''),
                            'qty': holding.get('qty', 0),
                            'avg_price': holding.get('avgPrice', 0),
                            'invested_value': holding.get('investedValue', 0),
                            'current_price': 0,
                            'pnl': 0,
                            'pnl_percent': 0
                        }
                        instruments_to_subscribe.append(instrument)
            
            # Subscribe to these instruments for real-time updates
            if instruments_to_subscribe:
                quotes_client.subscribe(instruments_to_subscribe)
                print(f"Subscribed to {len(instruments_to_subscribe)} instruments")
            else:
                print("No holdings found to monitor")
        
        except Exception as e:
            print(f"Error fetching holdings: {e}")
    
    def display_portfolio(self):
        """Display the current portfolio status"""
        if not self.portfolio:
            print("Portfolio is empty")
            return
        
        print("\n" + "="*80)
        print(f"Portfolio Status as of {datetime.now()}")
        print("="*80)
        
        # Create a pandas DataFrame for nicer display
        df = pd.DataFrame.from_dict(self.portfolio, orient='index')
        df['pnl'] = df['pnl'].round(2)
        df['pnl_percent'] = df['pnl_percent'].round(2)
        
        # Sort by P&L
        df = df.sort_values('pnl', ascending=False)
        
        print(df[['symbol', 'qty', 'avg_price', 'current_price', 'pnl', 'pnl_percent']])
        
        # Calculate total values
        total_invested = df['invested_value'].sum()
        total_current = (df['current_price'] * df['qty']).sum()
        total_pnl = df['pnl'].sum()
        total_pnl_percent = ((total_current / total_invested) - 1) * 100 if total_invested > 0 else 0
        
        print("-"*80)
        print(f"Total Invested: ₹{total_invested:.2f}")
        print(f"Total Current Value: ₹{total_current:.2f}")
        print(f"Total P&L: ₹{total_pnl:.2f} ({total_pnl_percent:.2f}%)")
        print("="*80 + "\n")

# Create and run the portfolio monitor
monitor = PortfolioMonitor()

# Set up callbacks
quotes_client.on_tick = monitor.on_tick
quotes_client.on_connect = monitor.on_connect
quotes_client.on_error = lambda ws, error: print(f"Error: {error}")

# Start monitoring (blocking call)
try:
    quotes_client.connect()
except KeyboardInterrupt:
    print("\nPortfolio monitoring stopped by user")
    quotes_client.stop()
```

### Multi-Strategy Trading

```python
from wiz_trader import QuotesClient, WizzerClient
import pandas as pd
import threading
import time
from datetime import datetime
import numpy as np

# Initialize API clients
quotes_client = QuotesClient(
    base_url="wss://websocket-url/quotes",
    token="your-jwt-token",
    log_level="info"
)

wizzer_client = WizzerClient(
    base_url="https://api-url.in",
    token="your-jwt-token",
    log_level="info"
)

class TradingStrategy:
    """Base class for trading strategies"""
    def __init__(self, name, symbols):
        self.name = name
        self.symbols = symbols
        self.active = False
        self.positions = {}
        self.prices = {}
        
    def on_tick(self, tick):
        """Process tick data - should be implemented by subclasses"""
        pass
    
    def start(self):
        """Start the strategy"""
        self.active = True
        print(f"Strategy {self.name} started at {datetime.now()}")
    
    def stop(self):
        """Stop the strategy"""
        self.active = False
        print(f"Strategy {self.name} stopped at {datetime.now()}")
        
        # Close any open positions
        self.close_all_positions()
    
    def close_all_positions(self):
        """Close all open positions"""
        for symbol, position in list(self.positions.items()):
            if position != 0:
                try:
                    self.execute_order(
                        symbol=symbol.split(':')[1],
                        exchange=symbol.split(':')[0],
                        transaction_type="SELL" if position > 0 else "BUY",
                        quantity=abs(position)
                    )
                    print(f"Closed position for {symbol}: {position} units")
                    self.positions[symbol] = 0
                except Exception as e:
                    print(f"Error closing position for {symbol}: {e}")
    
    def execute_order(self, symbol, exchange, transaction_type, quantity):
        """Execute an order through the API"""
        try:
            response = wizzer_client.place_order(
                exchange=exchange,
                trading_symbol=symbol,
                transaction_type=transaction_type,
                quantity=quantity,
                order_type=wizzer_client.ORDER_TYPE_MARKET,
                product=wizzer_client.PRODUCT_CNC
            )
            print(f"Order executed: {exchange}:{symbol} {transaction_type} {quantity} units")
            return response.get('orderId')
        except Exception as e:
            print(f"Order execution error: {e}")
            return None

class MovingAverageCrossover(TradingStrategy):
    """Moving Average Crossover Strategy"""
    def __init__(self, name, symbols, fast_period=10, slow_period=30):
        super().__init__(name, symbols)
        self.fast_period = fast_period
        self.slow_period = slow_period
        self.price_history = {s: [] for s in symbols}
    
    def on_tick(self, tick):
        if not self.active:
            return
            
        instrument = tick.get('instrument')
        ltp = tick.get('ltp')
        
        if instrument in self.symbols and ltp is not None:
            # Store the current price
            self.prices[instrument] = ltp
            
            # Add to price history
            self.price_history[instrument].append(ltp)
            
            # Keep only enough prices for the slow MA
            if len(self.price_history[instrument]) > self.slow_period:
                self.price_history[instrument].pop(0)
            
            # Check for trading signals if we have enough data
            if len(self.price_history[instrument]) >= self.slow_period:
                self.check_signals(instrument)
    
    def check_signals(self, instrument):
        prices = self.price_history[instrument]
        
        # Calculate moving averages
        fast_ma = sum(prices[-self.fast_period:]) / self.fast_period
        slow_ma = sum(prices) / self.slow_period
        
        # Get current position and price
        current_position = self.positions.get(instrument, 0)
        current_price = self.prices[instrument]
        
        # Generate signals
        if fast_ma > slow_ma and current_position <= 0:
            # Buy signal
            quantity = 10  # Fixed quantity for simplicity
            
            # Close any short position first
            if current_position < 0:
                self.execute_order(
                    symbol=instrument.split(':')[1],
                    exchange=instrument.split(':')[0],
                    transaction_type="BUY",
                    quantity=abs(current_position)
                )
                self.positions[instrument] = 0
            
            # Enter long position
            self.execute_order(
                symbol=instrument.split(':')[1],
                exchange=instrument.split(':')[0],
                transaction_type="BUY",
                quantity=quantity
            )
            self.positions[instrument] = quantity
            
            print(f"{self.name}: BUY {quantity} units of {instrument} at {current_price}")
            
        elif fast_ma < slow_ma and current_position >= 0:
            # Sell signal
            
            # Close any long position
            if current_position > 0:
                self.execute_order(
                    symbol=instrument.split(':')[1],
                    exchange=instrument.split(':')[0],
                    transaction_type="SELL",
                    quantity=current_position
                )
                self.positions[instrument] = 0
                
                print(f"{self.name}: SELL {current_position} units of {instrument} at {current_price}")
            
            # Option: Enter short position (if allowed)
            # quantity = 10  # Fixed quantity for simplicity
            # self.execute_order(
            #     symbol=instrument.split(':')[1],
            #     exchange=instrument.split(':')[0],
            #     transaction_type="SELL",
            #     quantity=quantity
            # )
            # self.positions[instrument] = -quantity
            # print(f"{self.name}: SHORT {quantity} units of {instrument} at {current_price}")

class BollingerBands(TradingStrategy):
    """Bollinger Bands Strategy"""
    def __init__(self, name, symbols, period=20, std_dev=2):
        super().__init__(name, symbols)
        self.period = period
        self.std_dev = std_dev
        self.price_history = {s: [] for s in symbols}
    
    def on_tick(self, tick):
        if not self.active:
            return
            
        instrument = tick.get('instrument')
        ltp = tick.get('ltp')
        
        if instrument in self.symbols and ltp is not None:
            # Store the current price
            self.prices[instrument] = ltp
            
            # Add to price history
            self.price_history[instrument].append(ltp)
            
            # Keep only enough prices for the calculation
            if len(self.price_history[instrument]) > self.period:
                self.price_history[instrument].pop(0)
            
            # Check for trading signals if we have enough data
            if len(self.price_history[instrument]) >= self.period:
                self.check_signals(instrument)
    
    def check_signals(self, instrument):
        prices = self.price_history[instrument]
        
        # Calculate Bollinger Bands
        sma = sum(prices) / len(prices)
        std = np.std(prices)
        upper_band = sma + (std * self.std_dev)
        lower_band = sma - (std * self.std_dev)
        
        # Get current position and price
        current_position = self.positions.get(instrument, 0)
        current_price = self.prices[instrument]
        
        # Generate signals
        if current_price < lower_band and current_position <= 0:
            # Buy signal (price below lower band)
            quantity = 10  # Fixed quantity for simplicity
            
            # Close any short position first
            if current_position < 0:
                self.execute_order(
                    symbol=instrument.split(':')[1],
                    exchange=instrument.split(':')[0],
                    transaction_type="BUY",
                    quantity=abs(current_position)
                )
                self.positions[instrument] = 0
            
            # Enter long position
            self.execute_order(
                symbol=instrument.split(':')[1],
                exchange=instrument.split(':')[0],
                transaction_type="BUY",
                quantity=quantity
            )
            self.positions[instrument] = quantity
            
            print(f"{self.name}: BUY {quantity} units of {instrument} at {current_price} (below lower band {lower_band:.2f})")
            
        elif current_price > upper_band and current_position >= 0:
            # Sell signal (price above upper band)
            
            # Close any long position
            if current_position > 0:
                self.execute_order(
                    symbol=instrument.split(':')[1],
                    exchange=instrument.split(':')[0],
                    transaction_type="SELL",
                    quantity=current_position
                )
                self.positions[instrument] = 0
                
                print(f"{self.name}: SELL {current_position} units of {instrument} at {current_price} (above upper band {upper_band:.2f})")

class MultiStrategyManager:
    """Manages multiple trading strategies"""
    def __init__(self, quotes_client):
        self.quotes_client = quotes_client
        self.strategies = {}
        
    def add_strategy(self, strategy):
        """Add a strategy to the manager"""
        self.strategies[strategy.name] = strategy
        
        # Subscribe to all strategy symbols
        for symbol in strategy.symbols:
            if not symbol.startswith('NSE:') and not symbol.startswith('BSE:'):
                print(f"Warning: Symbol {symbol} does not include exchange prefix")
        
    def on_tick(self, ws, tick):
        """Process ticks and distribute to strategies"""
        for strategy in self.strategies.values():
            strategy.on_tick(tick)
    
    def on_connect(self, ws):
        """Handle connection to quotes server"""
        print(f"Connected to quotes server at {datetime.now()}")
        
        # Collect all symbols from all strategies
        all_symbols = set()
        for strategy in self.strategies.values():
            all_symbols.update(strategy.symbols)
        
        # Subscribe to all symbols
        if all_symbols:
            ws.subscribe(list(all_symbols))
            print(f"Subscribed to {len(all_symbols)} symbols")
    
    def start_all(self):
        """Start all strategies"""
        for strategy in self.strategies.values():
            strategy.start()
    
    def stop_all(self):
        """Stop all strategies"""
        for strategy in self.strategies.values():
            strategy.stop()
    
    def start_strategy(self, name):
        """Start a specific strategy"""
        if name in self.strategies:
            self.strategies[name].start()
        else:
            print(f"Strategy {name} not found")
    
    def stop_strategy(self, name):
        """Stop a specific strategy"""
        if name in self.strategies:
            self.strategies[name].stop()
        else:
            print(f"Strategy {name} not found")
    
    def run(self):
        """Run the strategy manager"""
        # Set up callbacks
        self.quotes_client.on_tick = self.on_tick
        self.quotes_client.on_connect = self.on_connect
        self.quotes_client.on_error = lambda ws, error: print(f"Error: {error}")
        
        # Start all strategies
        self.start_all()
        
        # Start the quotes client (blocking call)
        try:
            self.quotes_client.connect()
        except KeyboardInterrupt:
            print("\nMulti-strategy manager stopped by user")
            self.stop_all()
            self.quotes_client.stop()

# Create strategies
ma_strategy = MovingAverageCrossover(
    name="MA Crossover",
    symbols=["NSE:SBIN:3045", "NSE:ICICIBANK:4963"],
    fast_period=10,
    slow_period=30
)

bb_strategy = BollingerBands(
    name="Bollinger Bands",
    symbols=["NSE:RELIANCE:2885", "NSE:TCS:2953"],
    period=20,
    std_dev=2
)

# Create and run the multi-strategy manager
manager = MultiStrategyManager(quotes_client)
manager.add_strategy(ma_strategy)
manager.add_strategy(bb_strategy)
manager.run()
```

## Error Handling

The SDK provides several mechanisms for handling errors:

### Exception Handling

All API calls can throw exceptions, which should be caught and handled:

```python
try:
    order_response = client.place_order(
        exchange=client.EXCHANGE_NSE,
        trading_symbol="SBIN",
        transaction_type=client.TRANSACTION_TYPE_BUY,
        quantity=10,
        order_type=client.ORDER_TYPE_MARKET,
        product=client.PRODUCT_CNC
    )
    print(f"Order placed successfully: {order_response.get('orderId')}")
except Exception as e:
    print(f"Error placing order: {e}")
```

### Callback Error Handling

For the WebSocket client, errors are also sent via the `on_error` callback:

```python
def on_error(ws, error):
    """Handle WebSocket errors"""
    print(f"WebSocket error: {error}")
    
    # You could implement reconnection logic or alerting here
    if isinstance(error, ConnectionRefusedError):
        print("Connection refused. Check server status.")
    elif isinstance(error, TimeoutError):
        print("Connection timed out. Check network.")

quotes_client.on_error = on_error
```

### Logging

Both clients support different log levels:

```python
client = WizzerClient(
    base_url="https://api-url.in",
    token="your-jwt-token",
    log_level="debug"  # Options: "error", "info", "debug"
)
```

The logs can help diagnose issues during development and production.

## Troubleshooting

### Common Issues

#### Authentication Issues

If you're facing authentication errors:

1. Check that your token is valid and not expired
2. Ensure you're using the correct base_url for production or development
3. Verify environment variables if you're using them

Example of token validation:
```python
def is_token_valid(token):
    """Basic validation of JWT token format"""
    parts = token.split('.')
    if len(parts) != 3:
        return False
    
    # Check if the token is expired
    import base64
    import json
    import time
    
    try:
        # Decode the payload
        payload = parts[1]
        # Add padding if needed
        payload += '=' * (4 - len(payload) % 4) if len(payload) % 4 != 0 else ''
        decoded = base64.b64decode(payload)
        data = json.loads(decoded)
        
        # Check expiration
        if 'exp' in data:
            return data['exp'] > time.time()
        return True
    except Exception:
        return False

# Check if token is valid
if not is_token_valid(token):
    print("Token is invalid or expired. Please get a new token.")
```

#### WebSocket Connection Issues

If you're having trouble connecting to the WebSocket server:

1. Check network connectivity and firewall settings
2. Verify the WebSocket URL is correct
3. Check if the server supports SSL/TLS if using 'wss://' protocol
4. Try with a smaller `max_message_size` to rule out size limitations

#### Order Placement Failures

If orders are not being placed successfully:

1. Check the error message from the API response
2. Verify that you're using the correct exchange, symbol, and token
3. Ensure you have sufficient funds/holdings for the trade
4. Check that market hours are active for the segment you're trading

## API Reference

For a complete list of all available methods and parameters, refer to the class docstrings within the SDK.

```python
# Example of getting detailed help on a method
help(WizzerClient.place_order)
```

### Environment Variables

All supported environment variables:

- `WZ__QUOTES_BASE_URL`: WebSocket URL for the quotes server
- `WZ__API_BASE_URL`: Base URL for the Wizzer's REST API
- `WZ__TOKEN`: JWT token for authentication
- `WZ__STRATEGY_ID`: Default strategy ID to use if not provided in methods

### Full Method List

#### QuotesClient
- `__init__(base_url, token, log_level, max_message_size, batch_size)`
- `connect()` - Connect in blocking mode
- `connect_async()` - Connect in non-blocking mode
- `stop()` - Stop the WebSocket connection
- `subscribe(instruments)` - Subscribe to instruments
- `unsubscribe(instruments)` - Unsubscribe from instruments

#### WizzerClient
- `__init__(base_url, token, strategy_id, log_level)`
- `get_indices(trading_symbol, exchange)`
- `get_index_components(trading_symbol, exchange)`
- `get_historical_ohlcv(instruments, start_date, end_date, ohlcv, interval)`
- `place_order(exchange, trading_symbol, transaction_type, quantity, ...)`
- `modify_order(order_id, **params)`
- `cancel_order(order_id)`
- `get_order(order_id)`
- `get_positions(position_status)`
- `get_open_positions()`
- `get_closed_positions()`
- `get_holdings(portfolios)`
- `create_basket(name, instruments, weightage_scheme, capital, instrument_types)`
- `get_baskets()`
- `get_basket(basket_id)`
- `get_basket_instruments(basket_id)`
- `place_basket_order(trading_symbol, transaction_type, quantity, ...)`
- `place_basket_exit_order(trading_symbol, exchange, transaction_type, quantity, exchange_token, **kwargs)`
- `modify_basket_order(order_id, **params)`
- `rebalance_basket(trading_symbol, instruments)`
- `exit_all_positions()`
- `exit_strategy_positions(strategy_id)`

# Indian Industry Classification Table

| MacroSector | Sector | Industry | BasicIndustries |
|-------------|---------|----------|-----------------|
| Commodities | Chemicals | Chemicals & Petrochemicals | Commodity Chemicals |
|  |  |  | Specialty Chemicals |
|  |  |  | Carbon Black |
|  |  |  | Dyes And Pigments |
|  |  |  | Explosives |
|  |  |  | Petrochemicals |
|  |  |  | Printing Inks |
|  |  |  | Trading - Chemicals |
|  |  |  | Industrial Gases |
|  |  | Fertilizers & Agrochemicals | Fertilizers |
|  |  |  | Pesticides & Agrochemicals |
|  | Construction Materials | Cement & Cement Products | Cement & Cement Products |
|  |  | Other Construction Materials | Other Construction Materials |
|  | Metals & Mining | Ferrous Metals | Ferro & Silica Manganese |
|  |  |  | Pig Iron |
|  |  |  | Sponge Iron |
|  |  |  | Iron & Steel |
|  |  | Non - Ferrous Metals | Aluminium |
|  |  |  | Copper |
|  |  |  | Zinc |
|  |  |  | Precious Metals |
|  |  | Diversified Metals | Diversified Metals |
|  |  | Minerals & Mining | Industrial Minerals |
|  |  | Metals & Minerals Trading | Trading - Metals |
|  |  |  | Trading - Minerals |
|  | Forest Materials | Paper, Forest & Jute Products | Paper & Paper Products |
|  |  |  | Forest Products |
|  |  |  | Jute & Jute Products |
| Consumer Discretionary | Automobile and Auto Components | Automobiles | Passenger Cars & Utility Vehicles |
|  |  |  | 2/3 Wheelers |
|  |  |  | Auto Dealer |
|  |  | Auto Components | Auto Components & Equipments |
|  |  |  | Tyres & Rubber Products |
|  |  |  | Trading - Auto Components |
|  | Consumer Durables | Consumer Durables | Cycles |
|  |  |  | Consumer Electronics |
|  |  |  | Furniture, Home Furnishing |
|  |  |  | Ceramics |
|  |  |  | Granites & Marbles |
|  |  |  | Gems, Jewellery And Watches |
|  |  |  | Glass - Consumer |
|  |  |  | Household Appliances |
|  |  |  | Houseware |
|  |  |  | Leather And Leather Products |
|  |  |  | Leisure Products |
|  |  |  | Plastic Products - Consumer |
|  |  |  | Plywood Boards/Laminates |
|  |  |  | Sanitary Ware |
|  |  |  | Paints |
|  |  |  | Diversified consumer products |
|  |  |  | Footwear |
|  | Textiles | Textiles & Apparels | Garments & Apparels |
|  |  |  | Other Textile Products |
|  |  |  | Trading - Textile Products |
|  | Media,Entertainment & Publication | Media | Advertising & Media Agencies |
|  |  |  | Electronic Media |
|  |  |  | Web based media and service |
|  |  |  | Print Media |
|  |  | Entertainment | Film Production,Distribution & Exhibition |
|  |  |  | Digital Entertainment |
|  |  |  | Media & Entertainment |
|  |  |  | TV Broadcasting & Software Production |
|  |  | Printing & Publication | Printing & Publication |
|  | Realty | Realty | Residential,Commercial Projects |
|  |  |  | Real Estate related services |
|  |  |  | Real Estate Investment Trusts(REITs) |
|  | Consumer Services | Leisure Services | Hotels & Resorts |
|  |  |  | Restaurants |
|  |  |  | Amusement Parks/Other Recreation |
|  |  |  | Wellness |
|  |  |  | Tour, Travel Related Services |
|  |  | Other Consumer Services | Education |
|  |  |  | E-Learning |
|  |  |  | Food Storage Facilities |
|  |  |  | Other Consumer Services |
|  |  | Retailing | Speciality Retail  |
|  |  |  | Pharmacy Retail |
|  |  |  | Diversified Retail |
|  |  |  | E-Retail/ ECommerce |
|  |  |  | Internet & Catalogue Retail |
|  |  |  | Distributors |
| Energy | Oil, Gas & Consumable Fuels | Gas | Gas Transmission/Marketing |
|  |  |  | LPG/CNG/PNG/LNG Supplier |
|  |  |  | Trading - Gas |
|  |  | Oil | Oil Exploration & Production |
|  |  |  | Offshore Support Solution Drilling |
|  |  |  | Oil Storage & Transportation |
|  |  |  | Oil Equipment & Services |
|  |  | Petroleum Products | Refineries & Marketing |
|  |  |  | Lubricants |
|  |  | Consumable Fuels | Coal |
|  |  |  | Trading - Coal |
| Fast Moving Consumer Goods | Fast Moving Consumer Goods | Agricultural Food & other Products | Edible Oil |
|  |  |  | Sugar |
|  |  |  | Tea & Coffee |
|  |  |  | Other Agricultural Products |
|  |  |  | Other Beverages |
|  |  | Beverages | Breweries & Distilleries |
|  |  | Cigarettes & Tobacco Products | Cigarettes & Tobacco Products |
|  |  | Food Products | Animal Feed |
|  |  |  | Dairy Products |
|  |  |  | Other Food Products |
|  |  |  | Packaged Foods |
|  |  |  | Seafood |
|  |  |  | Meat Products including Poultry |
|  |  | Personal Products | Personal Care |
|  |  | Household Products | Household Products |
|  |  |  | Stationary |
|  |  | Diversified FMCG | Diversified FMCG |
| Financial Services | Financial Services | Finance | Financial Institution |
|  |  |  | Housing Finance Company |
|  |  |  | Investment Company |
|  |  |  | Non Banking Financial Company (NBFC) |
|  |  |  | Other Financial Services |
|  |  |  | Holding Company |
|  |  |  | Microfinance Institutions |
|  |  |  | Securitisation |
|  |  | Banks | Public Sector Bank |
|  |  |  | Private Sector Bank |
|  |  |  | Other Bank |
|  |  | Capital Markets | Asset Management Company |
|  |  |  | Depositories,Clearing Houses and Other Intermediaries |
|  |  |  | Financial Products Distributor |
|  |  |  | Ratings |
|  |  |  | Exchange and Data Platform |
|  |  |  | Stockbroking & Allied |
|  |  |  | Other Capital Market related Services |
|  |  | Insurance | General Insurance |
|  |  |  | Life Insurance |
|  |  |  | Other Insurance Companies |
|  |  |  | Insurance Distributors |
|  |  | Financial Technology (Fintech) | Financial Technology (Fintech) |
| Healthcare | Healthcare | Pharmaceuticals & Biotechnology | Pharmaceuticals |
|  |  |  | Biotechnology |
|  |  | Healthcare Equipment & Supplies | Medical Equipment & Supplies |
|  |  | Healthcare Services | Hospital |
|  |  |  | Healthcare Service Provider |
|  |  |  | Healthcare Research, Analytics & Technology |
| Industrials | Construction | Construction | Civil Construction |
|  | Capital Goods | Aerospace & Defense | Aerospace & Defense |
|  |  | Agricultural,Commercial & Construction Vehicles | Tractors |
|  |  |  | Commercial Vehicles |
|  |  |  | Construction Vehicles |
|  |  |  | Dealers-Commercial Vehicles, Tractors, Construction Vehicles |
|  |  | Electrical Equipment | Heavy Electrical Equipment |
|  |  |  | Other Electrical Equipment |
|  |  | Industrial Manufacturing | Railway Wagons |
|  |  |  | Ship Building & Allied Services |
|  |  |  | Industrial Products |
|  |  | Industrial Products | Cables - Electricals |
|  |  |  | Castings & Forgings |
|  |  |  | Packaging |
|  |  |  | Plastic Products - Industrial |
|  |  |  | Rubber |
|  |  |  | Other Industrial Products |
|  |  |  | Glass - Industrial |
|  |  |  | Aluminium, Copper & Zinc Products |
|  |  |  | Iron & Steel Products |
|  |  |  | Abrasives & Bearings |
|  |  |  | Compressors,Pumps & Diesel Engines |
|  |  |  | Electrodes & Refractories |
| Information Technology | Information Technology | IT - Software | Computers - Software & Consulting |
|  |  |  | Software Products |
|  |  | IT - Services | IT Enabled Services |
|  |  | IT - Hardware | Computers Hardware & Equipments |
| Services | Services | Engineering Services | Dredging |
|  |  | Transport Services | Airline |
|  |  |  | Logistics Solution Provider |
|  |  |  | Railways |
|  |  |  | Road Transport |
|  |  |  | Shipping |
|  |  |  | Transport Related Services |
|  |  | Transport Infrastructure | Airport & Airport services |
|  |  |  | Port & Port services |
|  |  |  | Road Assets-Toll, Annuity, HybridAnnuity |
|  |  | Commercial Services & Supplies | Trading & Distributors |
|  |  |  | Consulting Services |
|  |  |  | Data Processing Services |
|  |  |  | Diversified Commercial Services |
|  |  |  | Business Process Outsourcing (BPO)/ Knowledge Process Outsourcing (KPO) |
|  |  | Public Services | Urban Local Bodies |
|  |  |  | Development Authority |
| Telecommunication | Telecommunication | Telecom - Services | Telecom - Cellular & Fixed line services |
|  |  |  | Telecom - Infrastructure |
|  |  |  | Other Telecom Services |
|  |  | Telecom - Equipment & Accessories | Telecom - Equipment & Accessories |
| Utilities | Power | Power | Power Generation |
|  |  |  | Integrated Power Utilities |
|  |  |  | Power Trading |
|  |  |  | Power - Transmission |
|  |  |  | Power Distribution |
|  | Utilities | Other Utilities | Water Supply & Management |
|  |  |  | Waste Management |
|  |  |  | Emergency Services |
|  |  |  | Multi Utilities |
|  |  |  | Other Utilities |
| Diversified | Diversified | Diversified | Diversified |


## Available Screener Fields

The screener supports filtering instruments using various financial, technical, and fundamental data points. Use `client.get_screener_fields()` to get the complete list of available fields with their metadata.

### Instrument Properties

| Field | Description | Data Type | Supported Operations |
|--- |--- |--- |--- |
| `exchange` | Stock exchange where the instrument is traded | String | `$eq`, `$ne`, `$in`, `$nin`, `$like`, `$nlike`, `$ilike` |
| `tradingSymbol` | Trading symbol of the instrument | String | `$eq`, `$ne`, `$in`, `$nin`, `$like`, `$nlike`, `$ilike` |
| `macroEconomicSector` | Macro economic sector classification | String | `$eq`, `$ne`, `$in`, `$nin`, `$like`, `$nlike`, `$ilike` |
| `sector` | Sector classification | String | `$eq`, `$ne`, `$in`, `$nin`, `$like`, `$nlike`, `$ilike` |
| `industry` | Industry classification | String | `$eq`, `$ne`, `$in`, `$nin`, `$like`, `$nlike`, `$ilike` |
| `basicIndustry` | Basic industry classification | String | `$eq`, `$ne`, `$in`, `$nin`, `$like`, `$nlike`, `$ilike` |
| `indices` | List of indices the instrument belongs to | Array(String) | `$in`, `$nin` |
| `issuedSize` | Total issued shares (listed shares count) | UInt64 | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `marketCap` | Market capitalization (issuedSize × latest closing price) | Float64 | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `logMarketCap` | Logarithm of Market Capitalization | Nullable(Float64) | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Financial Data

| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `reportDate` | Date of the financial report | Date | - | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `latestReportDate_daily` | Date of the latest financial report (daily derived) | Date | - | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `companyName` | Company name | String | - | `$eq`, `$ne`, `$like`, `$nlike`, `$ilike` |
| `period` | Financial reporting period (Q1, Q2, Q3, Q4, FY) | String | - | `$eq`, `$ne`, `$in`, `$nin` |
| `filingDate` | Date when the report was filed | Date | - | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `natureOfReport` | Type of financial report (Annual, Quarterly, etc.) | String | - | `$eq`, `$ne`, `$in`, `$nin` |
| `auditedUnaudited` | Audited or Unaudited status of the financial report | String | - | `$eq`, `$ne`, `$in`, `$nin` |

## Banking-Specific Metrics

### Interest Income & Expense
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `interestEarnedQuarterly` | Interest Earned - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `interestEarnedAnnual` | Interest Earned - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `interestExpenseQuarterly` | Interest Expense - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `interestExpenseAnnual` | Interest Expense - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### NPA & Asset Quality
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `grossNpaRatioQuarterly` | Gross NPA Ratio - quarterly | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `grossNpaRatioAnnual` | Gross NPA Ratio - annual | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `netNpaRatioQuarterly` | Net NPA Ratio - quarterly | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `netNpaRatioAnnual` | Net NPA Ratio - annual | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `gnpaPct` | Gross Non-Performing Assets Percentage | Float | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Capital Adequacy
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `cet1RatioQuarterly` | CET1 Capital Ratio - quarterly | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `cet1RatioAnnual` | CET1 Capital Ratio - annual | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `tier1CapitalRatioQuarterly` | Tier 1 Capital Ratio - quarterly | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `tier1CapitalRatioAnnual` | Tier 1 Capital Ratio - annual | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `totalCapitalRatioQuarterly` | Total Capital Ratio - quarterly | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `totalCapitalRatioAnnual` | Total Capital Ratio - annual | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Banking Assets & Liabilities
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `advancesQuarterly` | Advances - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `advancesAnnual` | Advances - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `depositsQuarterly` | Deposits - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `depositsAnnual` | Deposits - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `investmentsQuarterly` | Investments - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `investmentsAnnual` | Investments - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `cashBankBalanceQuarterly` | Cash and Bank Balance - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `cashBankBalanceAnnual` | Cash and Bank Balance - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

## Balance Sheet Items

### Fixed Assets
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `ppeQuarterly` | Property, Plant & Equipment - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `ppeAnnual` | Property, Plant & Equipment - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `goodwillQuarterly` | Goodwill - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `goodwillAnnual` | Goodwill - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `intangibleAssetsQuarterly` | Intangible Assets - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `intangibleAssetsAnnual` | Intangible Assets - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `cwipQuarterly` | Capital Work in Progress - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `cwipAnnual` | Capital Work in Progress - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `intangiblesUnderDevQuarterly` | Intangibles Under Development - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `intangiblesUnderDevAnnual` | Intangibles Under Development - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `investmentPropertyQuarterly` | Investment Property - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `investmentPropertyAnnual` | Investment Property - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Current Assets
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `inventoriesQuarterly` | Inventories - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `inventoriesAnnual` | Inventories - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `tradeReceivablesQuarterly` | Trade Receivables - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `tradeReceivablesAnnual` | Trade Receivables - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `otherReceivablesQuarterly` | Other Receivables - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `otherReceivablesAnnual` | Other Receivables - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `cashEquivalentsQuarterly` | Cash and Cash Equivalents - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `cashEquivalentsAnnual` | Cash and Cash Equivalents - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Total Assets & Equity
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `totalAssetsQuarterly` | Total Assets - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `totalAssetsAnnual` | Total Assets - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `totalEquityQuarterly` | Total Equity - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `totalEquityAnnual` | Total Equity - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `equityShareCapitalQuarterly` | Equity Share Capital - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `equityShareCapitalAnnual` | Equity Share Capital - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `totalLiabilitiesQuarterly` | Total Liabilities - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `totalLiabilitiesAnnual` | Total Liabilities - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

## Income Statement Items

### Revenue & Income
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `revenueOperationsQuarterly` | Revenue from Operations - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `revenueOperationsAnnual` | Revenue from Operations - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `otherIncomeQuarterly` | Other Income - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `otherIncomeAnnual` | Other Income - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `totalIncomeQuarterly` | Total Income - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `totalIncomeAnnual` | Total Income - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `dividendIncomeQuarterly` | Dividend Income - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `dividendIncomeAnnual` | Dividend Income - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Expenses
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `materialCostQuarterly` | Material Cost - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `materialCostAnnual` | Material Cost - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `employeeExpenseQuarterly` | Employee Expenses - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `employeeExpenseAnnual` | Employee Expenses - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `financeCostsQuarterly` | Finance Costs - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `financeCostsAnnual` | Finance Costs - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `depreciationAmortisationQuarterly` | Depreciation & Amortisation - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `depreciationAmortisationAnnual` | Depreciation & Amortisation - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `otherExpensesQuarterly` | Other Expenses - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `otherExpensesAnnual` | Other Expenses - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `totalExpensesQuarterly` | Total Expenses - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `totalExpensesAnnual` | Total Expenses - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Profit & Loss
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `profitBeforeTaxQuarterly` | Profit Before Tax - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `profitBeforeTaxAnnual` | Profit Before Tax - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `currentTaxQuarterly` | Current Tax - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `currentTaxAnnual` | Current Tax - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `deferredTaxQuarterly` | Deferred Tax - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `deferredTaxAnnual` | Deferred Tax - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `taxExpenseQuarterly` | Tax Expense - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `taxExpenseAnnual` | Tax Expense - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `netProfitQuarterly` | Net Profit - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `netProfitAnnual` | Net Profit - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `ebitda` | Earnings Before Interest, Taxes, Depreciation, and Amortization | Nullable(Float64) | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

## Cash Flow Statement

### Operating Activities
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `operatingCashFlowQuarterly` | Operating Cash Flow - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `operatingCashFlowAnnual` | Operating Cash Flow - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `netOperatingCashQuarterly` | Net Operating Cash - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `netOperatingCashAnnual` | Net Operating Cash - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Investing Activities
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `investingCashFlowQuarterly` | Investing Cash Flow - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `investingCashFlowAnnual` | Investing Cash Flow - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `netInvestingCashQuarterly` | Net Investing Cash - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `netInvestingCashAnnual` | Net Investing Cash - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `ppePurchasesQuarterly` | PPE Purchases - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `ppePurchasesAnnual` | PPE Purchases - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `ppeSaleProceedsQuarterly` | PPE Sale Proceeds - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `ppeSaleProceedsAnnual` | PPE Sale Proceeds - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `purchaseInvestmentsQuarterly` | Purchase of Investments - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `purchaseInvestmentsAnnual` | Purchase of Investments - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `saleInvestmentsQuarterly` | Sale of Investments - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `saleInvestmentsAnnual` | Sale of Investments - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Financing Activities
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `financingCashFlowQuarterly` | Financing Cash Flow - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `financingCashFlowAnnual` | Financing Cash Flow - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `netFinancingCashQuarterly` | Net Financing Cash - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `netFinancingCashAnnual` | Net Financing Cash - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `borrowingProceedsQuarterly` | Borrowing Proceeds - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `borrowingProceedsAnnual` | Borrowing Proceeds - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `borrowingRepaymentsQuarterly` | Borrowing Repayments - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `borrowingRepaymentsAnnual` | Borrowing Repayments - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `dividendsPaidQuarterly` | Dividends Paid - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `dividendsPaidAnnual` | Dividends Paid - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `shareIssueProceedsQuarterly` | Share Issue Proceeds - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `shareIssueProceedsAnnual` | Share Issue Proceeds - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `shareBuybackQuarterly` | Share Buyback - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `shareBuybackAnnual` | Share Buyback - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Net Cash Changes
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `netCashChangeQuarterly` | Net Cash Change - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `netCashChangeAnnual` | Net Cash Change - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `cashCashflowStmtQuarterly` | Cash from Cashflow Statement - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `cashCashflowStmtAnnual` | Cash from Cashflow Statement - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `freeCashFlow` | Free Cash Flow | Nullable(Float64) | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `netCash` | Net Cash Position | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

## NBFC-Specific Metrics

### Revenue & Income
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `feesCommissionIncomeQuarterly` | Fees & Commission Income - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `feesCommissionIncomeAnnual` | Fees & Commission Income - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `fairValueGainsQuarterly` | Fair Value Gains - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `fairValueGainsAnnual` | Fair Value Gains - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `rentalIncomeQuarterly` | Rental Income - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `rentalIncomeAnnual` | Rental Income - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Expenses
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `feesCommissionExpenseQuarterly` | Fees & Commission Expense - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `feesCommissionExpenseAnnual` | Fees & Commission Expense - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `fairValueLossesQuarterly` | Fair Value Losses - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `fairValueLossesAnnual` | Fair Value Losses - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `impairmentFinancialInstrumentsQuarterly` | Impairment of Financial Instruments - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `impairmentFinancialInstrumentsAnnual` | Impairment of Financial Instruments - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### NBFC Assets
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `loansQuarterly` | Loans - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `loansAnnual` | Loans - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `otherFinancialAssetsQuarterly` | Other Financial Assets - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `otherFinancialAssetsAnnual` | Other Financial Assets - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

## Insurance-Specific Metrics

### Premium Income
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `grossPremiumIncomeQuarterly` | Gross Premium Income - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `grossPremiumIncomeAnnual` | Gross Premium Income - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `netPremiumIncomeQuarterly` | Net Premium Income - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `netPremiumIncomeAnnual` | Net Premium Income - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Insurance Ratios
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `solvencyRatioQuarterly` | Solvency Ratio - quarterly | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `solvencyRatioAnnual` | Solvency Ratio - annual | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `expensesOfManagementRatioQuarterly` | Expenses of Management Ratio - quarterly | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `expensesOfManagementRatioAnnual` | Expenses of Management Ratio - annual | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

## Financial Ratios

### Valuation Ratios
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `peRatio` | Price-to-Earnings Ratio | Nullable(Float32) | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `pbRatio` | Price-to-Book Ratio | Nullable(Float32) | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `evEbitda` | Enterprise Value to EBITDA Ratio | Nullable(Float32) | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `fcfYield` | Free Cash Flow Yield | Nullable(Float32) | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Leverage Ratios
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `debtEquityRatioQuarterly` | Debt to Equity Ratio - quarterly | Float64 | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `debtEquityRatioAnnual` | Debt to Equity Ratio - annual | Float64 | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `debtEquity` | Debt to Equity Ratio | Float | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `debtServiceRatioQuarterly` | Debt Service Ratio - quarterly | Float64 | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `debtServiceRatioAnnual` | Debt Service Ratio - annual | Float64 | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `interestCoverageRatioQuarterly` | Interest Coverage Ratio - quarterly | Float64 | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `interestCoverageRatioAnnual` | Interest Coverage Ratio - annual | Float64 | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `interestCov` | Interest Coverage Ratio | Float | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Profitability Ratios
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `basicEpsQuarterly` | Basic EPS - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `basicEpsAnnual` | Basic EPS - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `dilutedEpsQuarterly` | Diluted EPS - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `dilutedEpsAnnual` | Diluted EPS - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `roe` | Return on Equity | Float | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `roa` | Return on Assets | Nullable(Float32) | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `patMargin` | Profit After Tax Margin | Float | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `grossMargin` | Gross Profit Margin | Nullable(Float32) | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `operatingMargin` | Operating Profit Margin | Nullable(Float32) | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `ebitMargin` | Earnings Before Interest and Taxes Margin | Nullable(Float32) | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Efficiency Ratios
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `assetTurnover` | Asset Turnover Ratio | Float | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `currentRatio` | Current Ratio | Float | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `ocfPat` | Operating Cash Flow to PAT Ratio | Float | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `ocfNetProfit` | Operating Cash Flow to Net Profit Ratio | Nullable(Float32) | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

## Technical Indicators

| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `fiftyDayMA` | 50-Day Moving Average | Nullable(Float32) | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `hundredDayMA` | 100-Day Moving Average | Nullable(Float32) | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `twoHundredDayMA` | 200-Day Moving Average | Nullable(Float32) | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `rsi` | Relative Strength Index | Nullable(Float32) | index | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `macd` | Moving Average Convergence Divergence | Nullable(Float32) | index | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `macdSignal` | MACD Signal Line | Nullable(Float32) | index | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `bollingerUpper` | Bollinger Band Upper | Nullable(Float32) | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `bollingerLower` | Bollinger Band Lower | Nullable(Float32) | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `atr` | Average True Range | Nullable(Float32) | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `volumeRatio` | Volume Ratio | Nullable(Float32) | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `thirtyDayVolatility` | 30-Day Volatility | Nullable(Float32) | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `sixMMaxDrawdown` | Six Month Maximum Drawdown | Nullable(Float32) | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

## Segment Analysis

### Segment Financial Data
| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `segmentRevenueQuarterly` | Segment Revenue - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `segmentRevenueAnnual` | Segment Revenue - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `segmentProfitBeforeTaxQuarterly` | Segment Profit Before Tax - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `segmentProfitBeforeTaxAnnual` | Segment Profit Before Tax - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `segmentAssetsQuarterly` | Segment Assets - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `segmentAssetsAnnual` | Segment Assets - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `segmentLiabilitiesQuarterly` | Segment Liabilities - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `segmentLiabilitiesAnnual` | Segment Liabilities - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Historical Market Data

| Field | Description | Data Type | Unit | Supported Operations |
|--- |--- |--- |--- |--- |
| `hmdOpen` | Opening price of the trading session | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `hmdHigh` | Highest price during the trading session | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `hmdLow` | Lowest price during the trading session | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `hmdClose` | Closing price of the trading session | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `hmdLtp` | Last Traded Price | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `hmdPrevClose` | Previous day closing price | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `hmdVolume` | Trading volume (number of shares traded) | UInt64 | shares | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `hmdTurnover` | Trading turnover (total value of shares traded) | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `hmdTotalTrades` | Total number of trades executed | UInt64 | count | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `hmdPriceBandLower` | Lower price band limit | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `hmdPriceBandUpper` | Upper price band limit | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |
| `hmdDate` | Trading date | Date | - | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |

### Supported Operations

- **Comparison**: `$eq` (equal), `$ne` (not equal), `$gt` (greater than), `$gte` (greater than or equal), `$lt` (less than), `$lte` (less than or equal)
- **Range**: `$between` (between two values)
- **Array**: `$in` (in array), `$nin` (not in array)
- **Pattern**: `$like` (case-sensitive pattern), `$nlike` (case-sensitive not pattern), `$ilike` (case-insensitive pattern)
- **Logical**: `$and` (all conditions must be true), `$or` (at least one condition must be true)

### Example Usage

```python
# Get all available screener fields
fields = client.get_screener_fields()
print(json.dumps(fields, indent=2))

# Screen for high ROE companies in Finance sector
results = client.run_screener(
    filters={
        "$and": [
            {"sector": {"$eq": "Finance"}},
            {"roe": {"$gt": 0.15}}
        ]
    },
    sort=[{"roe": -1}],
    limit=10
)
```

## KV Store Integration

The WizzerClient includes comprehensive Key-Value (KV) store functionality for persistent data management. This feature allows you to store configuration data, state information, user preferences, and other persistent data associated with your trading strategies.

### Supported Data Types

The KV store supports all JSON-serializable data types:

- **STRING**: Text values (`"production"`, `"user123"`)
- **NUMBER**: Integer and float values (`42`, `150.25`)
- **BOOLEAN**: True/false values (`True`, `False`)
- **ARRAY**: Lists of values (`["AAPL", "GOOGL", "MSFT"]`)
- **OBJECT**: Dictionaries/objects (`{"positions": 30, "cash": 50000}`)

### Available Constants

```python
client.KV_TYPE_STRING   # "string"
client.KV_TYPE_NUMBER   # "number" 
client.KV_TYPE_BOOLEAN  # "boolean"
client.KV_TYPE_ARRAY    # "array"
client.KV_TYPE_OBJECT   # "object"
```

### Core CRUD Operations

#### Create Key-Value Pair

```python
# Store different data types
client.create_kv("environment", "production")
client.create_kv("trade_count", 42)
client.create_kv("is_active", True)
client.create_kv("symbols", ["AAPL", "GOOGL", "MSFT"])

# Store complex configuration with TTL (expires in 1 hour)
config = {
    "risk_level": "medium",
    "max_positions": 10,
    "stop_loss_pct": 0.05,
    "take_profit_pct": 0.15
}
client.create_kv("strategy_config", config, ttl=3600)
```

#### Retrieve Key-Value Pair

```python
# Get a single KV pair
data = client.get_kv("strategy_config")
print(data["value"])          # The stored object
print(data["type"])           # "object"
print(data["ttl"])            # Remaining time to live (if set)

# Access nested values
risk_level = data["value"]["risk_level"]  # "medium"
```

#### Update Key-Value Pair (Complete Replacement)

```python
# Complete replacement of existing key
new_config = {"risk_level": "high", "max_positions": 5}
client.update_kv("strategy_config", new_config, ttl=1800)
```

#### Patch Key-Value Pair (Partial Update)

```python
# For objects - merges with existing data
client.patch_kv("strategy_config", {"last_updated": "2024-01-15"})

# For non-objects - replaces entirely  
client.patch_kv("trade_count", 50)

# Update only TTL
client.patch_kv("strategy_config", ttl=7200)
```

#### Delete Key-Value Pair

```python
response = client.delete_kv("old_config")
if response["success"]:
    print("Key deleted successfully")
```

### List Operations

#### Get All KV Pairs (with values)

```python
# Get first page (20 items)
kvs = client.get_all_kvs(page_no=1)

# Get all pages automatically
all_kvs = client.get_all_kvs(paginate=True)

for kv in all_kvs:
    print(f"Key: {kv['key']}")
    print(f"Type: {kv['type']}")
    print(f"Value: {kv['value']}")
```

#### Get Keys Only (memory efficient)

```python
# Get all keys without values (faster for large datasets)
keys = client.get_kv_keys(paginate=True)

for key_info in keys:
    print(f"Key: {key_info['key']}, Type: {key_info['type']}")
    if 'ttl' in key_info:
        print(f"  TTL: {key_info['ttl']} seconds remaining")
```

### Advanced Usage Examples

#### Strategy Configuration Management

```python
# Store strategy parameters
params = {
    "moving_average_period": 20,
    "rsi_oversold": 30,
    "rsi_overbought": 70,
    "position_size": 0.02
}
client.create_kv("strategy_params", params)

# Update specific parameters using patch (merges with existing)
client.patch_kv("strategy_params", {"moving_average_period": 50})
```

#### State Persistence

```python
# Save current portfolio state
portfolio_state = {
    "cash_balance": 50000,
    "open_positions": 5,
    "daily_pnl": 1250.75,
    "last_updated": "2024-01-15T15:30:00Z"
}
client.create_kv("portfolio_state", portfolio_state, ttl=3600)

# Update state periodically
client.patch_kv("portfolio_state", {
    "daily_pnl": 1500.25,
    "last_updated": "2024-01-15T16:00:00Z"
})
```

#### Feature Flags

```python
# Enable/disable features dynamically
features = {
    "advanced_charts": True,
    "paper_trading": True,
    "options_trading": False,
    "algo_trading": True
}
client.create_kv("feature_flags", features)

# Toggle a feature
client.patch_kv("feature_flags", {"options_trading": True})
```

#### Data Caching with TTL

```python
# Cache market data with short TTL (5 minutes)
market_status = {
    "nse_open": True,
    "bse_open": True,
    "last_checked": "2024-01-15T09:15:00Z"
}
client.create_kv("market_status", market_status, ttl=300)
```

### Object Merge Behavior

For OBJECT type data, the `patch_kv` method performs intelligent merging:

```python
# Initial object
client.create_kv("user_prefs", {
    "theme": "dark",
    "notifications": True,
    "language": "en"
})

# Patch merges new fields with existing ones
client.patch_kv("user_prefs", {
    "notifications": False,  # Updates existing field
    "timezone": "UTC"        # Adds new field
})

# Result: {"theme": "dark", "notifications": False, "language": "en", "timezone": "UTC"}
```

### Delete All KV Pairs

The `delete_all_kv` method allows you to remove all key-value pairs for a strategy at once:

```python
# Delete all KV pairs for the current strategy
response = client.delete_all_kv()
print(f"Deleted {response['deleted']} key-value pairs")

# Example response:
# {
#     "success": True,
#     "deleted": 15,
#     "message": "Successfully deleted 15 key-value pairs"
# }

# Common usage - reset strategy state before reinitialization
def reset_strategy_state():
    """Reset all persistent state for the strategy."""
    # Clear all existing KV pairs
    result = client.delete_all_kv()
    print(f"Cleared {result['deleted']} KV pairs")
    
    # Reinitialize with default configuration
    client.create_kv("config", {
        "mode": "production",
        "risk_percentage": 0.02,
        "max_positions": 10
    })
    client.create_kv("state", {
        "initialized": True,
        "start_time": datetime.now().isoformat()
    })
    print("Strategy state reset successfully")

# Use with caution - this operation cannot be undone!
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://bitbucket.org/wizzer-tech/quotes_sdk.git",
    "name": "wiz-trader",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": null,
    "keywords": "finance, trading, sdk",
    "author": "Pawan Wagh",
    "author_email": "Pawan Wagh <pawan@wizzer.in>",
    "download_url": "https://files.pythonhosted.org/packages/26/84/9fc21ff1d93bbc3dda0ebfc458d2b46f7e1ad7f2262c47269e77286da57e/wiz_trader-0.35.0.tar.gz",
    "platform": null,
    "description": "# WizTrader SDK Documentation\n\n## Table of Contents\n\n1. [Introduction](#introduction)\n2. [Installation](#installation)\n3. [Authentication](#authentication)\n4. [Quotes Client](#quotes-client)\n    - [Initialization](#quotes-client-initialization)\n    - [Connection Methods](#connection-methods)\n    - [Callbacks](#callbacks)\n    - [Subscribing to Instruments](#subscribing-to-instruments)\n    - [Unsubscribing from Instruments](#unsubscribing-from-instruments)\n    - [Handling WebSocket Connection](#handling-websocket-connection)\n    - [Complete Examples](#quotes-client-examples)\n5. [Wizzer Client](#wizzer-client)\n    - [Initialization](#wizzer-client-initialization)\n    - [Constants](#constants)\n    - [Data Hub Methods](#data-hub-methods)\n    - [Order Management](#order-management)\n    - [Portfolio Management](#portfolio-management)\n    - [Basket Management](#basket-management)\n    - [Instrument Management](#instrument-management)\n    - [Instrument Screener](#instrument-screener)\n    - [Complete Examples](#wizzer-client-examples)\n6. [Common Use Cases](#common-use-cases)\n7. [Error Handling](#error-handling)\n8. [Troubleshooting](#troubleshooting)\n9. [API Reference](#api-reference)\n\n## Introduction\n\nWizTrader is a Python SDK for connecting to the Wizzer trading platform. It provides two main client classes:\n\n- **QuotesClient**: For real-time market data streaming via WebSockets\n- **WizzerClient**: For REST API access to trading, order management, and market data, including data pipelines and classification APIs.\n\nThis documentation covers all the ways to use the SDK, with examples for each endpoint and common use cases.\n\n## Installation\n\nYou can install the package directly from PyPI:\n\n```bash\npip install wiz_trader\n```\n\nTo install the development version from GitHub:\n\n```bash\npip install git+https://github.com/wizzer-tech/wiz_trader.git\n```\n\n## Authentication\n\nThere are two ways to provide authentication credentials to the SDK:\n\n1. **Direct parameter passing** (Recommended for most use cases)\n2. **Environment variables** (Recommended for production deployments)\n\n### Direct Parameter Passing\n\nSimply provide the required parameters directly when initializing the clients:\n\n```python\nfrom wiz_trader import QuotesClient, WizzerClient\n\nquotes_client = QuotesClient(\n    base_url=\"wss://websocket-url/quotes\",\n    token=\"your-jwt-token\",\n    log_level=\"info\"\n)\n\nwizzer_client = WizzerClient(\n    base_url=\"https://api-url.in\",\n    token=\"your-jwt-token\",\n    strategy_id=\"str_01hxgwgfxgfrxb48bzchnve7gm\",  # Optional\n    log_level=\"info\"\n)\n```\n\n### Environment Variables\n\nSet the following environment variables:\n\n```bash\nexport WZ__QUOTES_BASE_URL=\"wss://websocket-url/quotes\"\nexport WZ__API_BASE_URL=\"https://api-url.in\"\nexport WZ__TOKEN=\"your-jwt-token\"\nexport WZ__STRATEGY_ID=\"str_01hxgwgfxgfrxb48bzchnve7gm\"  # Optional\n```\n\nThen initialize the clients without parameters:\n\n```python\nfrom wiz_trader import QuotesClient, WizzerClient\n\nquotes_client = QuotesClient(log_level=\"info\")\nwizzer_client = WizzerClient(log_level=\"info\")\n```\n\nYou can also use a hybrid approach, providing some parameters directly and letting others fall back to environment variables:\n\n```python\nquotes_client = QuotesClient(log_level=\"debug\")  # Only override log level\n```\n\n## Quotes Client\n\nThe `QuotesClient` enables you to connect to Wizzer's WebSocket server for real\u2011time market data using **plain synchronous** callbacks\u2014no `async def` required.\n\n### Quotes Client Initialization\n\nYou can initialize the `QuotesClient` in several ways:\n\n```python\nfrom wiz_trader import QuotesClient\n\n# Method 1: All parameters provided directly\nclient = QuotesClient(\n    base_url=\"wss://websocket-url/quotes\",\n    token=\"your-jwt-token\",\n    log_level=\"info\",         # Options: \"error\", \"info\", \"debug\"\n    max_message_size=10 * 1024 * 1024,  # Optional: default 10MB\n    batch_size=20             # Optional: default 20 instruments per batch\n)\n\n# Method 2: Using environment variables\n# (Requires WZ__QUOTES_BASE_URL and WZ__TOKEN set)\nclient = QuotesClient(log_level=\"info\")\n\n# Method 3: Mixed approach\nclient = QuotesClient(\n    base_url=\"wss://custom-url/quotes\",\n    log_level=\"debug\"         # token from WZ__TOKEN env var\n)\n```\n\n### Connection Methods\n\n#### Blocking Connection\n\nBlocks your main thread, similar to Zerodha\u2019s KiteTicker:\n\n```python\nclient.connect()\n```\n\n#### Non\u2011Blocking Connection\n\nRun alongside your own `asyncio` code:\n\n```python\nclient.connect_async()\n# \u2026 do other work \u2026\nclient.stop()\n```\n\n### Callbacks\n\nAll callbacks are **plain `def`** functions.  Inside them you can call `subscribe(...)`, which under the hood schedules the actual async work\u2014so you never `await` in your callbacks.\n\nThe QuotesClient routes messages based on their `type` field:\n- Messages with `type: 'ticks'` are sent to the `on_tick` callback\n- Messages with `type: 'greeks'` are sent to the `on_stats` callback\n- Messages without a `type` field are sent to `on_tick` for backward compatibility\n\n```python\ndef on_tick(ws, tick):\n    print(\"Tick:\", tick)\n\ndef on_stats(ws, stats):\n    print(\"Stats:\", stats)\n    # Stats/Greek messages contain: {'type': 'greeks', 'identifier': '...', 'rho': 0.1, 'theta': 9.8, ...}\n\ndef on_connect(ws):\n    print(\"Connected!\")\n    # Subscribe with different modes\n    ws.subscribe([\"NSE:SBIN:3045\"], mode=\"ticks\")      # Will receive tick messages\n    ws.subscribe([\"NSE:NIFTY25JULFUT:53216\"], mode=\"greeks\") # Will receive greek messages\n    ws.subscribe([\"NSE:RELIANCE:2885\"], mode=\"full\")   # Will receive both types\n\ndef on_close(ws, code, reason):\n    print(f\"Connection closed [{code}]: {reason}\")\n    ws.stop()   # to prevent auto\u2011reconnect\n\ndef on_error(ws, error):\n    print(\"Error:\", error)\n\nclient.on_tick    = on_tick\nclient.on_stats   = on_stats\nclient.on_connect = on_connect\nclient.on_close   = on_close\nclient.on_error   = on_error\n```\n\n### Subscribing to Instruments\n\nCall `ws.subscribe([...])` directly; the SDK will batch large lists and send them over the socket:\n\n```python\ndef on_connect(ws):\n    # subscribe without await\n    ws.subscribe([\n        \"NSE:SBIN:3045\",\n        \"NSE:ICICIBANK:4963\",\n        \"NSE:RELIANCE:2885\",\n    ])\n```\n\n### Unsubscribing from Instruments\n\nUse the `unsubscribe` method to stop receiving real-time data for specific instruments. This helps manage bandwidth and reduces unnecessary data processing.\n\n```python\n# Unsubscribe from specific instruments\nws.unsubscribe([\"NSE:SBIN:3045\", \"NSE:ICICIBANK:4963\"])\n\n# You can also unsubscribe from a single instrument\nws.unsubscribe([\"NSE:RELIANCE:2885\"])\n```\n\n**Key Features:**\n- Immediately stops tick data for the specified instruments\n- Reduces network bandwidth and processing overhead\n- Can be called multiple times for different instrument sets\n- No callback fired for unsubscribed instruments\n\n### Complete Examples\n\n#### Blocking Example\n\n```python\nimport logging\nfrom wiz_trader import QuotesClient\n\nlogging.basicConfig(level=logging.INFO)\n\nclient = QuotesClient(\n    base_url=\"wss://websocket-url/quotes\",\n    token=\"your-jwt-token\"\n)\n\ndef on_tick(ws, tick):\n    logging.debug(\"Tick: %s\", tick)\n\ndef on_stats(ws, stats):\n    logging.debug(\"Stats: %s\", stats)\n\ndef on_connect(ws):\n    logging.info(\"Connected.\")\n    ws.subscribe([\"NSE:SBIN:3045\"], mode=\"ticks\")\n    ws.subscribe([\"NSE:NIFTY24JUN20100CE:20100\"], mode=\"greeks\")\n\ndef on_close(ws, code, reason):\n    logging.warning(\"Closed: %s\", reason)\n    ws.stop()\n\ndef on_error(ws, error):\n    logging.error(\"Error: %s\", error)\n\nclient.on_tick    = on_tick\nclient.on_stats   = on_stats\nclient.on_connect = on_connect\nclient.on_close   = on_close\nclient.on_error   = on_error\n\ntry:\n    client.connect()\nexcept KeyboardInterrupt:\n    client.stop()\n```\n\n#### Non\u2011Blocking Example\n\n```python\nimport asyncio\nimport logging\nfrom wiz_trader import QuotesClient\n\nasync def main():\n    logging.basicConfig(level=logging.INFO)\n    client = QuotesClient(\n        base_url=\"wss://websocket-url/quotes\",\n        token=\"your-jwt-token\"\n    )\n    client.on_tick    = lambda ws, tick: logging.info(tick)\n    client.on_connect = lambda ws: ws.subscribe([\"NSE:SBIN:3045\"])\n    client.connect_async()\n\n    # Your other async work here...\n    await asyncio.sleep(60)\n    client.stop()\n\nasyncio.run(main())\n```\n\n#### Message Data Structures\n\n##### Ticks structure\nMessages with `type: 'ticks'` contain market data:\n- `ts`: tick timestamp\n- `lastTradedTs`: timestamp of the last executed trade in this instrument\n- `oi`: Current open interest (for futures and options)\n- `oiDayHigh`: Day's highest open interest value  \n- `oiDayLow`: Day's lowest open interest value\n\n```json\n{\n  \"type\": \"ticks\",\n  \"identifier\": \"NSE:RELIANCE:2885\",\n  \"tradingSymbol\": \"RELIANCE\",\n  \"exchange\": \"NSE\",\n  \"segment\": \"NSECM\",\n  \"exchangeToken\": 2885,\n  \"bids\": [{\"volume\": 1722, \"price\": 1295.5, \"orders\": 43}, ...],\n  \"offers\": [{\"volume\": 0, \"price\": 0, \"orders\": 0}, ...],\n  \"ltp\": 1295.5,\n  \"lastTradedQty\": 10,\n  \"buyQty\": 1722,\n  \"sellQty\": 0,\n  \"volume\": 10429964,\n  \"avgPrice\": 1291.46,\n  \"netChange\": 0,\n  \"ohlc\": {\"open\": 1270, \"high\": 1300.9, \"low\": 1267, \"close\": 1295.5},\n  \"oi\": 1234567,\n  \"oiDayHigh\": 1250000,\n  \"oiDayLow\": 1200000,\n  \"lastTradedTs\": \"2025-04-21T10:29:33Z\",\n  \"ts\": \"2025-04-21T10:29:46Z\"\n}\n```\n\n##### Greeks structure\nMessages with `type: 'greeks'` contain options Greeks data:\n\n```json\n{\n  \"type\": \"greeks\",\n  \"identifier\": \"NSE:NIFTY25JULFUT:53216\",\n  \"tradingSymbol\": \"NIFTY25JULFUT\",\n  \"iv\": 0.0,\n  \"delta\": 0.0,\n  \"gamma\": 0.0,\n  \"theta\": 0.0,\n  \"vega\": 0.0,\n  \"rho\": 0.0,\n  \"ts\": \"2025-04-21T10:29:46Z\"\n}\n```\n\n## Wizzer Client\n\nThe `WizzerClient` provides access to Wizzer's REST APIs for trading, portfolio management, and market data.\n\n### Wizzer Client Initialization\n\nInitialize the client with your authentication details:\n\n```python\nfrom wiz_trader import WizzerClient\n\n# Method 1: All parameters provided directly\nclient = WizzerClient(\n    base_url=\"https://api-url.in\",\n    token=\"your-jwt-token\",\n    strategy_id=\"str_01hxgwgfxgfrxb48bzchnve7gm\",  # Optional: Default strategy ID\n    log_level=\"info\"  # Options: \"error\", \"info\", \"debug\"\n)\n\n# Method 2: Using environment variables\n# (Requires WZ__API_BASE_URL and WZ__TOKEN to be set)\nclient = WizzerClient(log_level=\"info\")\n```\n\n### Constants\n\nThe `WizzerClient` provides constants for various parameter values, making your code more readable and type-safe:\n\n```python\nfrom wiz_trader import WizzerClient\n\nclient = WizzerClient(...)\n\n# Use constants for transaction types\nclient.place_order(\n    exchange=client.EXCHANGE_NSE,\n    trading_symbol=\"SBIN\",\n    transaction_type=client.TRANSACTION_TYPE_BUY,\n    quantity=10,\n    order_type=client.ORDER_TYPE_MARKET,\n    product=client.PRODUCT_CNC\n)\n```\n\nAvailable constants:\n\n- Transaction types: `TRANSACTION_TYPE_BUY`, `TRANSACTION_TYPE_SELL`\n- Product types: `PRODUCT_CNC`, `PRODUCT_MIS`, `PRODUCT_NRML`\n- Order types: `ORDER_TYPE_MARKET`, `ORDER_TYPE_LIMIT`, `ORDER_TYPE_SL`, `ORDER_TYPE_SLM`\n- Validity types: `VALIDITY_DAY`, `VALIDITY_IOC`, `VALIDITY_GTT`\n- Variety types: `VARIETY_REGULAR`, `VARIETY_AMO`, `VARIETY_BO`, `VARIETY_CO`\n- Exchanges: `EXCHANGE_NSE`, `EXCHANGE_BSE`, `EXCHANGE_WZR`\n- Segments: `SEGMENT_NSE_CM`, `SEGMENT_BSE_CM`, `SEGMENT_NSE_FO`, `SEGMENT_WZREQ`\n- Instrument types: `INSTRUMENT_TYPE_EQ`, `INSTRUMENT_TYPE_EQLC`, `INSTRUMENT_TYPE_EQMCC`, `INSTRUMENT_TYPE_EQSCC`, `INSTRUMENT_TYPE_BASKET`\n- - Weightage schemes: `WEIGHTAGE_SCHEME_EQUI_WEIGHTED`, `WEIGHTAGE_SCHEME_QUANTITY_WEIGHTED`, `WEIGHTAGE_SCHEME_PRICE_WEIGHTED`, `WEIGHTAGE_SCHEME_MARKET_CAP_WEIGHTED`, `WEIGHTAGE_SCHEME_FLOAT_ADJUSTED_MARKET_CAP_WEIGHTED`, `WEIGHTAGE_SCHEME_FUNDAMENTAL_WEIGHTED`, `WEIGHTAGE_SCHEME_CUSTOM_WEIGHTED`\n\n### Data Hub Methods\n\n#### Get Indices\n\nFetch available indices from an exchange:\n\n```python\n# Get all indices from NSE\nindices = client.get_indices(exchange=\"NSE\")\nprint(f\"Found {len(indices)} indices\")\n\n# Get a specific index by trading symbol\nnifty_50 = client.get_indices(trading_symbol=\"NIFTY 50\", exchange=\"NSE\")\n```\n\n#### Get Index Components\n\nFetch components (stocks) in a specific index:\n\n```python\n# Get components of NIFTY 50\ncomponents = client.get_index_components(trading_symbol=\"NIFTY 50\", exchange=\"NSE\")\nprint(f\"Found {len(components)} components in NIFTY 50\")\nfor component in components[:5]:\n    print(f\"{component['tradingSymbol']} - {component.get('weightage', 'N/A')}%\")\n```\n\n#### List Classification Types\n\nRetrieve all available classification types.\n\n```python\nclassification_types = client.get_classification_types()\n# Response: ['basicIndustry', 'industry', 'macroEconomicSector', 'sector']\n```\n\n#### List Classification Values\n\nRetrieve all values for a specific classification type.\n\n```python\nbasic_industry_values = client.get_classifications(\"basicIndustry\")\n# Response: ['Aerospace & Defense', 'Agricultural Food & other Products', ...]\n```\n\n#### Filter Indices by Classifications\n\nFilter indices based on multiple classification criteria. The `match_all` parameter controls the filter logic:\n- `True`: AND logic (all filters must match)\n- `False`: OR logic (any filter can match)\n\n```python\n# Example: Find indices in the 'Commodities' macro-economic sector OR 'Aerospace & Defense' industry\nfilters = {\n    \"macroEconomicSector\": [\"Commodities\"],\n    \"industry\": [\"Aerospace & Defense\"]\n}\nor_logic_indices = client.filter_indices(filters=filters, match_all=False)\n\n# Example: Find indices that are in BOTH 'Housing Finance Company' and 'Financial Services'\nfilters = {\n    \"basicIndustry\": [\"Housing Finance Company\"],\n    \"sector\": [\"Financial Services\"]\n}\nand_logic_indices = client.filter_indices(filters=filters, match_all=True)\n```\n\n#### Filter Instruments by Classifications\n\nFilter instruments based on classification criteria.\n\n```python\n# Example: Find instruments in the 'Technology' sector\nfilters = {\"sector\": [\"Technology\"]}\ntech_instruments = client.filter_instruments(filters=filters, match_all=True)\n```\n\n#### Filter Instruments by Classifications and Index\n\nFilter instruments that belong to both specific classifications and a given index.\n\n```python\n# Example: Find 'Financial Services' instruments within the 'NIFTY NEXT 50' index\nfilters = {\n    \"basicIndustry\": [\"Housing Finance Company\"],\n    \"sector\": [\"Financial Services\"]\n}\nfiltered_instruments = client.filter_instruments(\n    index_identifier=\"NSE:NIFTY NEXT 50:26054\",\n    filters=filters,\n    match_all=False\n)\n```\n\n#### Filter Instruments by Derivatives\n\nFilter instruments based on whether they have associated futures or options contracts.\n\n```python\n# Find all instruments that have options\noptionable_stocks = client.filter_instruments_by_derivatives(hasOptions=True)\n\n# Find all instruments that have futures\nfutures_stocks = client.filter_instruments_by_derivatives(hasFutures=True)\n\n# Find all instruments that have both options and futures\nfno_stocks = client.filter_instruments_by_derivatives(hasOptions=True, hasFutures=True)\n\n# Find all instruments that have either options or futures\nall_derivative_stocks = client.filter_instruments_by_derivatives()\n```\n\n### Instrument Screener\n\nThe SDK provides a powerful instrument screener to filter and sort instruments based on a wide range of criteria using a simple and expressive Domain Specific Language (DSL).\n\n> **\ud83d\udccb Comprehensive Screener Documentation**: For detailed information about all available screener fields, practical use cases, and advanced filtering examples, see **[screener.md](screener.md)**.\n\n#### `get_screener_fields()`\n\nThis method returns a list of all available filterable fields and their supported operations.\n\n```python\n# Get all available screener fields\nfields = client.get_screener_fields()\nprint(json.dumps(fields, indent=2))\n```\n\n#### `run_screener(filters, sort=None, limit=None, as_of=None)`\n\nThis is the main method for the instrument screener. It accepts a dictionary with a `filters` object to define the screening criteria.\n\n**Arguments:**\n\n*   `filters` (dict, required): An object containing the filter conditions.\n*   `sort` (list, optional): A list of objects to define the sort order.\n*   `limit` (int, optional): The maximum number of results to return.\n\n#### Filter DSL (Domain Specific Language)\n\nThe `filters` object uses a simple DSL to define the screening criteria.\n\n##### Operators\n\n| Operator  | Description              | Example                               |\n| :-------- | :----------------------- | :------------------------------------ |\n| `$eq`     | Equal to                 | `{ \"sector\": { \"$eq\": \"Finance\" } }`  |\n| `$ne`     | Not equal to             | `{ \"sector\": { \"$ne\": \"Finance\" } }`  |\n| `$gt`     | Greater than             | `{ \"roe\": { \"$gt\": 0.15 } }`          |\n| `$gte`    | Greater than or equal to | `{ \"roe\": { \"$gte\": 0.15 } }`         |\n| `$lt`     | Less than                | `{ \"roe\": { \"$lt\": 0.15 } }`          |\n| `$lte`    | Less than or equal to    | `{ \"roe\": { \"$lte\": 0.15 } }`         |\n| `$in`     | In a list of values    | `{ \"sector\": { \"$in\": [\"Information Technology\", \"Finance\"] } }` |\n| `$nin`    | Not in a list of values| `{ \"sector\": { \"$nin\": [\"Information Technology\", \"Finance\"] } }` |\n| `$like`   | Like (case-sensitive)    | `{ \"companyName\": { \"$like\": \"%Bank%\" } }` |\n| `$nlike`  | Not like (case-sensitive)| `{ \"companyName\": { \"$nlike\": \"%Bank%\" } }` |\n| `$ilike`  | Like (case-insensitive)  | `{ \"companyName\": { \"$ilike\": \"%bank%\" } }` |\n| `$between`| Between two values       | `{ \"roe\": { \"$between\": [0.10, 0.20] } }` |\n\n##### Logical Operators\n\n*   `$and`: A list of filter conditions that must all be true.\n*   `$or`: A list of filter conditions where at least one must be true.\n\n#### Screener Examples\n\n##### Basic Filters\n\n1.  **Find all instruments in the 'Finance' sector.**\n    ```python\n    client.run_screener(filters={\"sector\": {\"$eq\": \"Finance\"}})\n    ```\n\n2.  **Find all instruments on the 'NSE' exchange.**\n    ```python\n    client.run_screener(filters={\"exchange\": {\"$eq\": \"NSE\"}})\n    ```\n\n3.  **Find all instruments with a Return on Equity (ROE) greater than 15%.**\n    ```python\n    client.run_screener(filters={\"roe\": {\"$gt\": 0.15}})\n    ```\n\n##### Set and Range Operators\n\n4.  **Find all instruments in the 'Energy' or 'Healthcare' sectors.**\n    ```python\n    client.run_screener(filters={\"sector\": {\"$in\": [\"Energy\", \"Healthcare\"]}})\n    ```\n\n5.  **Find instruments with a PAT Margin between 5% and 10%.**\n    ```python\n    client.run_screener(filters={\"patMargin\": {\"$between\": [0.05, 0.10]}})\n    ```\n\n##### Pattern Matching\n\n6.  **Find all instruments with 'Bank' in their name (case-insensitive).**\n    ```python\n    client.run_screener(filters={\"companyName\": {\"$ilike\": \"%bank%\"}})\n    ```\n\n##### Logical Combinations\n\n7.  **Find instruments in the 'IT' sector with a ROE greater than 20%.**\n    ```python\n    client.run_screener(\n        filters={\n            \"$and\": [\n                {\"sector\": {\"$eq\": \"Information Technology\"}},\n                {\"roe\": {\"$gt\": 0.20}}\n            ]\n        }\n    )\n    ```\n\n8.  **Complex Nested Query:** Find instruments in the 'Automobile' sector that have (a ROE > 18% AND a low Debt/Equity) OR have a high Asset Turnover.\n    ```python\n    client.run_screener(\n        filters={\n            \"$and\": [\n                {\"sector\": {\"$eq\": \"Automobile\"}},\n                {\n                    \"$or\": [\n                        {\n                            \"$and\": [\n                                {\"roe\": {\"$gt\": 0.18}},\n                                {\"debtEquity\": {\"$lt\": 0.3}}\n                            ]\n                        },\n                        {\"assetTurnover\": {\"$gt\": 1.5}}\n                    ]\n                }\n            ]\n        }\n    )\n    ```\n\n##### Sort and Limit\n\n9.  **Find the top 10 companies by highest ROE.**\n    ```python\n    client.run_screener(\n        filters={},\n        sort=[{\"roe\": -1}],\n        limit=10\n    )\n    ```\n\n10. **Find companies in the 'Pharmaceuticals' sector, sort them by the highest PAT margin, and then by the lowest Debt-to-Equity ratio.**\n    ```python\n    client.run_screener(\n        filters={\"sector\": {\"$eq\": \"Pharmaceuticals\"}},\n        sort=[\n            {\"patMargin\": -1},\n            {\"debtEquity\": 1}\n        ]\n    )\n    ```\n\n#### Get Historical OHLCV Data\n## Overview\n\nThe `get_historical_ohlcv` method supports multiple time intervals for historical data retrieval, from 1-minute intraday data to monthly aggregated data.\n\n## Supported Intervals\n\n### Intraday Intervals\n- `1m` - 1 minute\n- `2m` - 2 minutes  \n- `3m` - 3 minutes\n- `5m` - 5 minutes\n- `10m` - 10 minutes\n- `15m` - 15 minutes\n- `30m` - 30 minutes\n- `45m` - 45 minutes\n- `1h` - 1 hour\n\n### Daily/Monthly Intervals\n- `1d` - 1 day (default)\n- `1M` - 1 month (last trading day of month)\n\n## Date Format Requirements\n\n### For Daily and Monthly Intervals (`1d`, `1M`)\n- **Format**: `YYYY-MM-DD`\n- **Example**: `\"2024-01-15\"`\n\n### For Intraday Intervals (all minute/hour intervals)\n- **Format**: `YYYY-MM-DD HH:MM:SS`\n- **Example**: `\"2024-01-15 09:30:00\"`\n\n**New Features in Historical Data API:**\n\n- **Open Interest (`oi`)**: Now supported in the `ohlcv` parameter for futures instruments\n- **Continuous Data**: The `continuous` parameter (for futures only) provides seamless data across multiple contract months when your date range spans multiple months\n\n## Using Constants\n\nThe client provides constants for all intervals:\n\n```python\nfrom wiz_trader import WizzerClient\n\nclient = WizzerClient(...)\n\n# Intraday intervals\nclient.INTERVAL_1_MINUTE     # \"1m\"\nclient.INTERVAL_2_MINUTES    # \"2m\"\nclient.INTERVAL_3_MINUTES    # \"3m\"\nclient.INTERVAL_5_MINUTES    # \"5m\"\nclient.INTERVAL_10_MINUTES   # \"10m\"\nclient.INTERVAL_15_MINUTES   # \"15m\"\nclient.INTERVAL_30_MINUTES   # \"30m\"\nclient.INTERVAL_45_MINUTES   # \"45m\"\nclient.INTERVAL_1_HOUR       # \"1h\"\n\n# Daily/Monthly intervals\nclient.INTERVAL_1_DAY        # \"1d\"\nclient.INTERVAL_1_MONTH      # \"1M\"\n```\n\n## Usage Examples\n\n### 1. Get 5-minute intraday data\n\n```python\n# Get 5-minute candles for a trading session\nintraday_data = client.get_historical_ohlcv(\n    instruments=[\"NSE:SBIN:3045\"],\n    start_date=\"2024-01-15 09:15:00\",  # Market open\n    end_date=\"2024-01-15 15:30:00\",    # Market close\n    ohlcv=[\"open\", \"high\", \"low\", \"close\", \"volume\"],\n    interval=client.INTERVAL_5_MINUTES\n)\n\n# Response will have date field as: \"2024-01-15 09:15:00\", \"2024-01-15 09:20:00\", etc.\n```\n\n### 2. Get 1-minute data for scalping\n\n```python\n# Get 1-minute data for the first hour of trading\nscalping_data = client.get_historical_ohlcv(\n    instruments=[\"NSE:RELIANCE:2885\", \"NSE:TCS:2953\"],\n    start_date=\"2024-01-15 09:15:00\",\n    end_date=\"2024-01-15 10:15:00\",\n    ohlcv=[\"open\", \"high\", \"low\", \"close\", \"volume\"],\n    interval=client.INTERVAL_1_MINUTE\n)\n```\n\n### 3. Get hourly data for swing trading\n\n```python\n# Get hourly data for a week\nhourly_data = client.get_historical_ohlcv(\n    instruments=[\"NSE:NIFTY 50:26000\"],\n    start_date=\"2024-01-15 09:15:00\",\n    end_date=\"2024-01-19 15:30:00\",\n    ohlcv=[\"open\", \"high\", \"low\", \"close\", \"volume\"],\n    interval=client.INTERVAL_1_HOUR\n)\n```\n\n### 4. Get daily data (traditional)\n\n```python\n# Get daily data for a month\ndaily_data = client.get_historical_ohlcv(\n    instruments=[\"NSE:SBIN:3045\"],\n    start_date=\"2024-01-01\",  # Note: No time component\n    end_date=\"2024-01-31\",\n    ohlcv=[\"open\", \"high\", \"low\", \"close\", \"volume\"],\n    interval=client.INTERVAL_1_DAY\n)\n\n# Response will have date field as: \"2024-01-01\", \"2024-01-02\", etc.\n```\n\n### 5. Get monthly data for long-term analysis\n\n```python\n# Get monthly data for a year\nmonthly_data = client.get_historical_ohlcv(\n    instruments=[\"NSE:SBIN:3045\"],\n    start_date=\"2023-01-01\",\n    end_date=\"2023-12-31\",\n    ohlcv=[\"close\", \"volume\"],\n    interval=client.INTERVAL_1_MONTH\n)\n\n# Get futures data with open interest\nfutures_data = client.get_historical_ohlcv(\n    instruments=[\"NSE:SBIN25MAYFUT:57515\"],\n    start_date=\"2024-01-01\",\n    end_date=\"2024-03-01\",\n    ohlcv=[\"open\", \"high\", \"low\", \"close\", \"volume\", \"oi\"],  # Include open interest\n    interval=\"1d\"\n)\n\n# Get continuous futures data across multiple contract months\ncontinuous_futures = client.get_historical_ohlcv(\n    instruments=[\"NSE:SBIN25MAYFUT:57515\"],\n    start_date=\"2023-01-01\",\n    end_date=\"2024-12-31\",\n    ohlcv=[\"close\", \"oi\"],\n    interval=\"1d\",\n    continuous=True  # Get seamless data across contract months\n)\n```\n\n## Response Structure\n\nThe response structure remains the same, but the `date` field format varies:\n\n### For Daily/Monthly Intervals\n```json\n{\n  \"instrument\": {\n    \"exchange\": \"NSE\",\n    \"tradingSymbol\": \"SBIN\",\n    \"exchangeToken\": 3045,\n    \"identifier\": \"NSE:SBIN:3045\"\n  },\n  \"data\": [\n    {\n      \"date\": \"2024-01-15\",  // YYYY-MM-DD format\n      \"open\": 750.0,\n      \"high\": 765.0,\n      \"low\": 745.0,\n      \"close\": 760.0,\n      \"volume\": 1000000\n    }\n  ]\n}\n```\n\n### For Intraday Intervals\n```json\n{\n  \"instrument\": {\n    \"exchange\": \"NSE\",\n    \"tradingSymbol\": \"SBIN\",\n    \"exchangeToken\": 3045,\n    \"identifier\": \"NSE:SBIN:3045\"\n  },\n  \"data\": [\n    {\n      \"date\": \"2024-01-15 09:15:00\",  // YYYY-MM-DD HH:MM:SS format\n      \"open\": 750.0,\n      \"high\": 752.0,\n      \"low\": 749.0,\n      \"close\": 751.0,\n      \"volume\": 50000\n    }\n  ]\n}\n```\n\n## Advanced Usage Examples\n\n### Multiple Timeframe Analysis\n\n```python\ndef get_multi_timeframe_data(symbol, date):\n    \"\"\"Get data across multiple timeframes for comprehensive analysis\"\"\"\n    \n    # 1-minute data for entry/exit precision\n    minute_data = client.get_historical_ohlcv(\n        instruments=[symbol],\n        start_date=f\"{date} 09:15:00\",\n        end_date=f\"{date} 15:30:00\",\n        ohlcv=[\"open\", \"high\", \"low\", \"close\", \"volume\"],\n        interval=client.INTERVAL_1_MINUTE\n    )\n    \n    # 5-minute data for short-term trends\n    five_min_data = client.get_historical_ohlcv(\n        instruments=[symbol],\n        start_date=f\"{date} 09:15:00\",\n        end_date=f\"{date} 15:30:00\",\n        ohlcv=[\"open\", \"high\", \"low\", \"close\", \"volume\"],\n        interval=client.INTERVAL_5_MINUTES\n    )\n    \n    # 15-minute data for medium-term trends\n    fifteen_min_data = client.get_historical_ohlcv(\n        instruments=[symbol],\n        start_date=f\"{date} 09:15:00\",\n        end_date=f\"{date} 15:30:00\",\n        ohlcv=[\"open\", \"high\", \"low\", \"close\", \"volume\"],\n        interval=client.INTERVAL_15_MINUTES\n    )\n    \n    # Hourly data for major trend\n    hourly_data = client.get_historical_ohlcv(\n        instruments=[symbol],\n        start_date=f\"{date} 09:15:00\",\n        end_date=f\"{date} 15:30:00\",\n        ohlcv=[\"open\", \"high\", \"low\", \"close\", \"volume\"],\n        interval=client.INTERVAL_1_HOUR\n    )\n    \n    return {\n        \"1m\": minute_data,\n        \"5m\": five_min_data,\n        \"15m\": fifteen_min_data,\n        \"1h\": hourly_data\n    }\n\n# Usage\nmulti_data = get_multi_timeframe_data(\"NSE:SBIN:3045\", \"2024-01-15\")\n```\n\n### Building OHLC Candlestick Data\n\n```python\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom mplfinance import plot as mpf\n\ndef plot_candlestick_chart(symbol, start_date, end_date, interval):\n    \"\"\"Create a candlestick chart from historical data\"\"\"\n    \n    # Get historical data\n    data = client.get_historical_ohlcv(\n        instruments=[symbol],\n        start_date=start_date,\n        end_date=end_date,\n        ohlcv=[\"open\", \"high\", \"low\", \"close\", \"volume\"],\n        interval=interval\n    )\n    \n    if not data or not data[0].get('data'):\n        print(\"No data available\")\n        return\n    \n    # Convert to DataFrame\n    df = pd.DataFrame(data[0]['data'])\n    df['date'] = pd.to_datetime(df['date'])\n    df.set_index('date', inplace=True)\n    \n    # Rename columns for mplfinance\n    df.columns = ['Open', 'High', 'Low', 'Close', 'Volume']\n    \n    # Create candlestick chart\n    mpf.plot(df, type='candle', volume=True, \n             title=f'{symbol} - {interval} Chart',\n             style='charles')\n\n# Plot 5-minute chart\nplot_candlestick_chart(\n    \"NSE:SBIN:3045\", \n    \"2024-01-15 09:15:00\", \n    \"2024-01-15 15:30:00\",\n    client.INTERVAL_5_MINUTES\n)\n```\n\n### Backtesting with Different Intervals\n\n```python\ndef backtest_strategy_multiple_intervals(symbol, start_date, end_date):\n    \"\"\"Backtest a strategy across different intervals\"\"\"\n    \n    intervals = [\n        (client.INTERVAL_5_MINUTES, \"5m\"),\n        (client.INTERVAL_15_MINUTES, \"15m\"),\n        (client.INTERVAL_30_MINUTES, \"30m\"),\n        (client.INTERVAL_1_HOUR, \"1h\")\n    ]\n    \n    results = {}\n    \n    for interval_code, interval_name in intervals:\n        # For intraday intervals, use datetime format\n        data = client.get_historical_ohlcv(\n            instruments=[symbol],\n            start_date=f\"{start_date} 09:15:00\",\n            end_date=f\"{end_date} 15:30:00\",\n            ohlcv=[\"open\", \"high\", \"low\", \"close\", \"volume\"],\n            interval=interval_code\n        )\n        \n        if data and data[0].get('data'):\n            df = pd.DataFrame(data[0]['data'])\n            df['date'] = pd.to_datetime(df['date'])\n            \n            # Simple moving average crossover strategy\n            df['sma_10'] = df['close'].rolling(10).mean()\n            df['sma_20'] = df['close'].rolling(20).mean()\n            \n            # Generate signals\n            df['signal'] = 0\n            df.loc[df['sma_10'] > df['sma_20'], 'signal'] = 1\n            df.loc[df['sma_10'] < df['sma_20'], 'signal'] = -1\n            \n            # Calculate returns\n            df['returns'] = df['close'].pct_change()\n            df['strategy_returns'] = df['signal'].shift(1) * df['returns']\n            \n            # Calculate total return\n            total_return = (1 + df['strategy_returns']).prod() - 1\n            \n            results[interval_name] = {\n                'total_return': total_return,\n                'num_trades': df['signal'].diff().abs().sum() / 2,\n                'num_candles': len(df)\n            }\n    \n    return results\n\n# Compare strategy performance across intervals\nperformance = backtest_strategy_multiple_intervals(\n    \"NSE:SBIN:3045\",\n    \"2024-01-01\",\n    \"2024-01-31\"\n)\n\nfor interval, metrics in performance.items():\n    print(f\"{interval}: Return={metrics['total_return']:.2%}, \"\n          f\"Trades={metrics['num_trades']:.0f}, \"\n          f\"Candles={metrics['num_candles']}\")\n```\n\n## Error Handling\n\n```python\ntry:\n    data = client.get_historical_ohlcv(\n        instruments=[\"NSE:SBIN:3045\"],\n        start_date=\"2024-01-15 09:15:00\",\n        end_date=\"2024-01-15 15:30:00\",\n        ohlcv=[\"open\", \"high\", \"low\", \"close\", \"volume\"],\n        interval=client.INTERVAL_5_MINUTES\n    )\nexcept ValueError as e:\n    print(f\"Date format error: {e}\")\nexcept Exception as e:\n    print(f\"API error: {e}\")\n```\n\n## Best Practices\n\n1. **Use appropriate intervals for your strategy**:\n   - Scalping: 1m, 2m, 3m\n   - Day trading: 5m, 15m, 30m\n   - Swing trading: 1h, 1d\n   - Position trading: 1d, 1M\n\n2. **Be mindful of data volume**:\n   - 1-minute data generates a lot of candles\n   - Use shorter date ranges for minute-level data\n\n3. **Validate date formats**:\n   - The client will validate formats automatically\n   - Use datetime strings consistently\n\n4. **Consider market hours**:\n   - For intraday data, use market hours: 09:15:00 to 15:30:00\n   - Weekend dates won't have intraday data\n\n5. **Cache data when possible**:\n   - Historical data doesn't change\n   - Store frequently used datasets locally\n\n### Order Management\n\n#### Place Regular Order\n\nPlace a regular order for a single instrument:\n\n```python\n# Simple market order\norder_response = client.place_order(\n    exchange=client.EXCHANGE_NSE,\n    trading_symbol=\"SBIN\",\n    transaction_type=client.TRANSACTION_TYPE_BUY,\n    quantity=10,\n    order_type=client.ORDER_TYPE_MARKET,\n    product=client.PRODUCT_CNC\n)\nprint(f\"Order placed successfully: {order_response.get('orderId')}\")\n\n# Limit order with price\nlimit_order = client.place_order(\n    exchange=client.EXCHANGE_NSE,\n    trading_symbol=\"SBIN\",\n    transaction_type=client.TRANSACTION_TYPE_BUY,\n    quantity=10,\n    order_type=client.ORDER_TYPE_LIMIT,\n    product=client.PRODUCT_CNC,\n    price=650.00\n)\n\n# Order with stop loss and target\nsl_order = client.place_order(\n    exchange=client.EXCHANGE_NSE,\n    trading_symbol=\"SBIN\",\n    transaction_type=client.TRANSACTION_TYPE_BUY,\n    quantity=10,\n    product=client.PRODUCT_CNC,\n    stoploss=640.00,\n    target=670.00\n)\n```\n\n#### Modify Order\n\nModify an existing order:\n\n```python\n# Modify an order's price\nmodified_order = client.modify_order(\n    order_id=\"order_01jpeyxtr4fb69fx740my3115c\",\n    price=655.00\n)\n\n# Modify an order's quantity\nmodified_order = client.modify_order(\n    order_id=\"order_01jpeyxtr4fb69fx740my3115c\",\n    qty=15\n)\n```\n\n#### Cancel Order\n\nCancel an existing order:\n\n```python\n# Cancel an order\ncancelled_order = client.cancel_order(order_id=\"order_01jpeyxtr4fb69fx740my3115c\")\n```\n\n#### Get Order Details\n\nFetch details of a specific order:\n\n```python\n# Get order details\norder_details = client.get_order(order_id=\"order_01jpeyxtr4fb69fx740my3115c\")\nprint(f\"Order status: {order_details.get('status')}\")\n```\n\n### Portfolio Management\n\n#### Get Positions\n\nFetch your current positions:\n\n```python\n# Get all positions\nall_positions = client.get_positions()\nprint(f\"Found {len(all_positions)} positions\")\n\n# Get only open positions\nopen_positions = client.get_open_positions()\nprint(f\"Found {len(open_positions)} open positions\")\n\n# Get only closed positions\nclosed_positions = client.get_closed_positions()\nprint(f\"Found {len(closed_positions)} closed positions\")\n```\n\n#### Get Holdings\n\nFetch your holdings:\n\n```python\n# Get holdings\nholdings = client.get_holdings()\nprint(f\"Found {len(holdings)} holdings\")\n\n# Get holdings for a specific portfolio\nportfolio_holdings = client.get_holdings(portfolios=\"my_portfolio\")\n```\n\n#### Exit Positions\n\nExit all positions or positions for a specific strategy:\n\n```python\n# Exit all positions\nexit_response = client.exit_all_positions()\nprint(f\"Successfully exited {exit_response.get('success', 0)} positions\")\n\n# Exit positions for a specific strategy\nstrategy_exit = client.exit_strategy_positions(strategy_id=\"str_01jbxszcjdegz8zt3h95g8c1d9\")\n```\n\n### Basket Management\n\n#### Create Basket\n\nCreate a new basket of instruments:\n\n```python\n# Create a basic basket with two stocks\nbasket_response = client.create_basket(\n    name=\"My Basket\",\n    instruments=[\n        {\n            \"shares\": 10,\n            \"weightage\": 50,\n            \"instrument\": {\n                \"exchange\": \"NSE\",\n                \"identifier\": \"NSE:SBIN:3045\",\n                \"orderIndex\": 1,\n                \"exchangeToken\": 3045,\n                \"tradingSymbol\": \"SBIN\"\n            }\n        },\n        {\n            \"shares\": 15,\n            \"weightage\": 50,\n            \"instrument\": {\n                \"exchange\": \"NSE\",\n                \"identifier\": \"NSE:ICICIBANK:4963\",\n                \"orderIndex\": 2,\n                \"exchangeToken\": 4963,\n                \"tradingSymbol\": \"ICICIBANK\"\n            }\n        }\n    ],\n    weightage_scheme=\"equi_weighted\",\n    capital={\"minValue\": 50000, \"actualValue\": 50000},\n    instrument_types=[\"EQLC\"]\n)\nbasket_id = basket_response.get('id')\n```\n\n#### Get Baskets\n\nFetch existing baskets:\n\n```python\n# Get all baskets\nbaskets = client.get_baskets()\nprint(f\"Found {len(baskets)} baskets\")\n\n# Get a specific basket by ID\nbasket = client.get_basket(basket_id=\"bk_01jpf2d57ae96bez63me7p6g9k\")\n\n# Get instruments in a basket\nbasket_instruments = client.get_basket_instruments(basket_id=\"bk_01jpf2d57ae96bez63me7p6g9k\")\n```\n\n#### Place Basket Order\n\nPlace an order for an entire basket:\n\n```python\n# Place a basket order\nbasket_order = client.place_basket_order(\n    trading_symbol=\"/MY_BASKET\",\n    transaction_type=client.TRANSACTION_TYPE_BUY,\n    quantity=1,\n    price=50000.00,\n    product=client.PRODUCT_CNC\n)\n```\n\n#### Exit Basket Order\n\nExit a basket position:\n\n```python\n# Exit a basket position\nexit_order = client.place_basket_exit_order(\n    trading_symbol=\"/MY_BASKET\",\n    exchange=client.EXCHANGE_WZR,\n    transaction_type=client.TRANSACTION_TYPE_SELL,\n    quantity=1,\n    exchange_token=1741872632\n)\n```\n\n#### Rebalance Basket\n\n#### Available Weightage Schemes\n\nWhen creating or rebalancing baskets, you can choose from several weightage schemes:\n\n- **`WEIGHTAGE_SCHEME_EQUI_WEIGHTED`**: Equal weightage for all instruments\n- **`WEIGHTAGE_SCHEME_QUANTITY_WEIGHTED`**: Weighted by quantity\n- **`WEIGHTAGE_SCHEME_PRICE_WEIGHTED`**: Weighted by price\n- **`WEIGHTAGE_SCHEME_MARKET_CAP_WEIGHTED`**: Weighted by market capitalization\n- **`WEIGHTAGE_SCHEME_FLOAT_ADJUSTED_MARKET_CAP_WEIGHTED`**: Weighted by float-adjusted market cap\n- **`WEIGHTAGE_SCHEME_FUNDAMENTAL_WEIGHTED`**: Weighted by fundamental metrics\n- **`WEIGHTAGE_SCHEME_CUSTOM_WEIGHTED`**: Custom weightage scheme\n\nRebalance a basket with new instruments:\n\n```python\n# Rebalance a basket\nrebalance_response = client.rebalance_basket(\n    trading_symbol=\"/MY_BASKET\",\n    instruments=[\"NSE:SBIN:3045\", \"NSE:HDFCBANK:1333\", \"NSE:TCS:2953\"]\n)\n\n# Full Rebalance with market cap weighting & execution of all orders at market price\nclient.rebalance_basket(\n    trading_symbol=\"/MY_BASKET\",\n    instruments=[\"NSE:SBIN:3045\", \"NSE:HDFCBANK:1333\"],\n    execution_policy=client.REBALANCE_FULL,\n    order_type=client.ORDER_TYPE_MARKET,\n    weightage_scheme=client.WEIGHTAGE_SCHEME_MARKET_CAP_WEIGHTED\n)\n\n# Entry-only rebalance with price weighting\nclient.rebalance_basket(\n    trading_symbol=\"/MY_BASKET\",\n    instruments=[\"NSE:SBIN:3045\", \"NSE:HDFCBANK:1333\"],\n    execution_policy=client.REBALANCE_ENTRY_ONLY,\n    weightage_scheme=client.WEIGHTAGE_SCHEME_EQUI_WEIGHTED\n)\n```\n\n### Instrument Management\n## Instrument Data APIs\n\n### Get Instrument Metrics\n\nFetch detailed information and metrics for specific instruments:\n\n```python\n# Get metrics for a single equity instrument\nequity_info = client.get_instrument_metrics(identifiers=[\"NSE:SBIN:3045\"])\nprint(f\"SBIN Last Price: {equity_info[0]['ltp']}\")\nprint(f\"SBIN 52-week High: {equity_info[0]['week52High']}\")\n\n# Get metrics for multiple instruments of different types\ninstruments_info = client.get_instrument_metrics(\n    identifiers=[\n        \"NSE:AARTIIND:7\",              # Equity\n        \"NSE:NIFTY26DEC11000CE:61009\", # Option\n        \"NSE:SBIN25MAYFUT:57515\"       # Future\n    ]\n)\n\n# Print detailed information for each instrument\nfor instrument in instruments_info:\n    print(f\"{instrument['tradingSymbol']} ({instrument['instrumentType']}):\")\n    print(f\"  LTP: {instrument['ltp']}\")\n    print(f\"  Exchange: {instrument['exchange']}\")\n    print(f\"  Segment: {instrument['segment']}\")\n    if instrument.get('bhavcopy'):\n        print(f\"  Volume: {instrument['bhavcopy']['volume']}\")\n        print(f\"  OHLC: {instrument['bhavcopy']['open']}/{instrument['bhavcopy']['high']}/\"\n              f\"{instrument['bhavcopy']['low']}/{instrument['bhavcopy']['close']}\")\n```\n\n#### Response Structure for Instrument Metrics\n\nThe `get_instrument_metrics` method returns a list of dictionaries, each with the following structure:\n\n```python\n[\n    {\n        # Instrument name if available\n        \"name\": \"\",\n        \n        # Trading symbol\n        \"tradingSymbol\": \"AARTIIND\",\n        \n        # Exchange code\n        \"exchange\": \"NSE\",\n        \n        # Bid price if available\n        \"bid\": 0,\n        \n        # Size of total bids at best bid price\n        \"bidSize\": 0,\n        \n        # Ask (offer) price\n        \"ask\": 0,\n        \n        # Size of total asks at best ask price\n        \"askSize\": 0,\n        \n        # Last traded price\n        \"ltp\": 450.05,\n        \n        # Trading volume\n        \"volume\": 0,\n        \n        # Lot size for the instrument\n        \"lotSize\": 1,\n        \n        # Mid price ((bid+ask)/2)\n        \"mid\": 0,\n        \n        # Market capitalization (for equities)\n        \"marketCap\": 0,\n        \n        # Dividend yield percentage (for equities)\n        \"dividendYield\": 0,\n        \n        # Last dividend date\n        \"dividendDate\": \"\",\n        \n        # Daily Open-High-Low-Close values\n        \"ohlc\": {\n            \"open\": 0,\n            \"high\": 0,\n            \"low\": 0,\n            \"close\": 0\n        },\n        \n        # Industry classification (for equities)\n        \"industry\": \"\",\n        \n        # Sector classification (for equities)\n        \"sector\": \"\",\n        \n        # Relevant indicators for underlying assets (for derivatives)\n        \"underlyingIndicators\": \"\",\n        \n        # Net change in price\n        \"netChange\": 0,\n        \n        # Net change in percentage\n        \"netChangePercentage\": 0,\n        \n        # Beta value (for equities)\n        \"beta\": 0,\n        \n        # Liquidity rating\n        \"liquidityRating\": 0,\n        \n        # Implied volatility metrics (for options)\n        \"iv\": {\n            \"index\": 0,\n            \"indexRank\": 0,\n            \"percentile\": 0,\n            \"change5Days\": 0,\n            \"change30Days\": 0,\n            \"ivHvChange30Days\": 0\n        },\n        \n        # Historical volatility metrics\n        \"hv\": {\n            \"change30Days\": 0,\n            \"change60Days\": 0,\n            \"change90Days\": 0\n        },\n        \n        # Minimum price movement\n        \"tickSize\": 0.05,\n        \n        # Previous day's trading summary\n        \"bhavcopy\": {\n            \"open\": 458.4,\n            \"high\": 470.9,\n            \"low\": 440.75,\n            \"close\": 448.55,\n            \"volume\": 3544523,\n            \"turnover\": 1632822505.15,\n            \"totalTrades\": 59999\n        },\n        \n        # Exchange token identifier\n        \"exchangeToken\": 7,\n        \n        # Market segment\n        \"segment\": \"NSECM\",\n        \n        # Whether the instrument is actively traded\n        \"isTraded\": false,\n        \n        # Complete instrument identifier\n        \"identifier\": \"NSE:AARTIIND:7\",\n        \n        # Instrument type code\n        \"instrumentType\": \"EQLC\",\n        \n        # Option type (for options) - CE or PE\n        \"optionType\": \"\",\n        \n        # Expiry date (for derivatives)\n        \"expiry\": \"\",\n        \n        # International Securities Identification Number\n        \"isin\": \"INE769A01020\",\n        \n        # Margin requirement percentage\n        \"margin\": 19.43,\n        \n        # 52-week high price\n        \"week52High\": 765.5,\n        \n        # 52-week low price\n        \"week52Low\": 344.2,\n        \n        # Maximum allowed trade volume\n        \"maxTradeVolume\": 2147483647,\n        \n        # Price band limits\n        \"priceBand\": {\n            \"high\": 493.4,\n            \"low\": 403.7,\n            \"creditRating\": {\n                \"lower\": 403.7,\n                \"higher\": 493.4\n            }\n        }\n    },\n    # Additional instruments...\n]\n```\n\nNote that certain fields may have zero or empty values if the data is not available from the exchange or if it's not applicable to that instrument type.\n\n### Options Chain\n\n#### Get Option Expiry List\n\nFetch available expiry dates for an instrument's options:\n\n```python\n# For a stock\nexpiry_list = client.get_option_expiry_list(\"NSE:SBIN:3045\")\n\n# For an index\nnifty_expiry = client.get_option_expiry_list(\"NSE:NIFTY 50:26000\")\n\n# Print all available expiry dates\nfor expiry in expiry_list.get('expiryList', []):\n    print(f\"{expiry['date']} - {expiry['contract']} \" +\n          f\"(Futures: {'Yes' if expiry['isFuturesExpiry'] else 'No'}, \" +\n          f\"Options: {'Yes' if expiry['isOptionsExpiry'] else 'No'})\")\n```\n\n#### Response Structure\n\nThe response is a JSON object with the following structure:\n\n```json\n{\n  \"exchange\": \"NSE\",                // Exchange of the instrument\n  \"tradingSymbol\": \"SBIN\",          // Trading symbol\n  \"exchangeToken\": 3045,            // Exchange token\n  \"identifier\": \"NSE:SBIN:3045\",    // Full identifier\n  \"expiryList\": [                   // Array of expiry objects\n    {\n      \"date\": \"2025-05-29\",         // Expiry date in YYYY-MM-DD format\n      \"contract\": \"near_month\",     // Contract type (see below)\n      \"isFuturesExpiry\": true,      // Whether futures expire on this date\n      \"isOptionsExpiry\": true       // Whether options expire on this date\n    },\n    // More expiry objects...\n  ]\n}\n```\n\nFor index options like NIFTY, the response will typically include more expiry dates, including weekly options and longer-dated quarterly options.\n\nThe `expiryList` array contains objects with the following fields:\n- `date`: The expiry date in YYYY-MM-DD format\n- `contract`: The type of contract (e.g., \"near_month\", \"current_weekly\")\n- `isFuturesExpiry`: Boolean indicating if futures expire on this date\n- `isOptionsExpiry`: Boolean indicating if options expire on this date\n\n#### Contract Types\n\nEach expiry date is categorized with a `contract` field that indicates the type of expiry. The possible contract types are:\n\n1. **Weekly Expiries (Thursdays/Wednesdays)**\n   - `current_weekly`: The first non-expiry Thursday of the current week\n\n2. **Monthly Expiries (last Wed/Thu of month)**\n   - `near_month`: Last Wed/Thu of this month (current month)\n   - `mid_month`: Last Wed/Thu of next month\n   - `far_month`: Last Wed/Thu of month after next\n\n3. **Weekly Ordinals Within Current Month**\n   - `first_weekly`: 1st non-expiry Thursday of current month\n   - `second_weekly`: 2nd non-expiry Thursday\n   - `third_weekly`: 3rd non-expiry Thursday\n   - `fourth_weekly`: 4th non-expiry Thursday\n   - `fifth_weekly`: 5th non-expiry Thursday (rare)\n\n4. **Weekly Ordinals in Mid-Month Slot (next month's week-trade dates)**\n   - `first_weekly_mid_month`: 1st Thursday of next month\n   - `second_weekly_mid_month`: 2nd Thursday of next month\n   - `third_weekly_mid_month`: 3rd Thursday of next month\n   - `fourth_weekly_mid_month`: 4th Thursday of next month\n   - `fifth_weekly_mid_month`: 5th Thursday of next month (rare)\n\n5. **Weekly Ordinals in Far-Month Slot (month-after-next)**\n   - `first_weekly_far_month`: 1st Thursday of month after next\n   - `second_weekly_far_month`: 2nd Thursday of month after next\n   - `third_weekly_far_month`: 3rd Thursday of month after next\n   - `fourth_weekly_far_month`: 4th Thursday of month after next\n   - `fifth_weekly_far_month`: 5th Thursday of month after next (rare)\n\n6. **Quarterly Expiries (last-Thu of Mar/Jun/Sep/Dec)**\n   - `first_quarter`: Last Thu of March (Q1)\n   - `second_quarter`: Last Thu of June (Q2)\n   - `third_quarter`: Last Thu of September (Q3)\n   - `fourth_quarter`: Last Thu of December (Q4)\n\n7. **Half-Yearly Expiries**\n   - `first_half_yearly`: Last Thu of June (H1)\n   - `second_half_yearly`: Last Thu of December (H2)\n\n8. **Year-Plus-N Quarterly/Half-Yearly (N = years ahead)**\n   - For quarterly options in future years:\n     - `first_quarter_1`: Q1 (March) of next year\n     - `second_quarter_1`: Q2 (June) of next year\n     - `third_quarter_1`: Q3 (September) of next year\n     - `fourth_quarter_1`: Q4 (December) of next year\n   - For half-yearly options in future years:\n     - `first_half_yearly_1`: H1 (June) of next year\n     - `second_half_yearly_1`: H2 (December) of next year\n   - This pattern continues with `_2`, `_3`, and `_4` suffixes for up to 4 years ahead\n\n9. **Special Case**\n   - `none`: No matching expiry category\n\n### Get Options Chain\n\nThe Options Chain API provides detailed information about available option contracts for a specified instrument, including strike prices, premiums, and option Greeks.\n\n#### Constants\n\nThe SDK provides constants for option types, moneyness, and expiry preferences to make your code more readable and type-safe:\n\n**Option Types:**\n```python\nclient.OPTION_TYPE_CE  # Call option\nclient.OPTION_TYPE_PE  # Put option\n```\n\n**Moneyness Types:**\n```python\nclient.MONEYNESS_ATM  # At-the-money\nclient.MONEYNESS_ITM  # In-the-money\nclient.MONEYNESS_OTM  # Out-of-the-money\n```\n\n**Expiry Preferences:**\n```python\n# Common expiry preferences\nclient.EXPIRY_CURRENT_WEEKLY  # Current week's expiry\nclient.EXPIRY_NEAR_MONTH      # Current month's expiry\nclient.EXPIRY_MID_MONTH       # Next month's expiry\nclient.EXPIRY_FAR_MONTH       # Month after next expiry\n\n# Many more constants available for weekly, monthly, \n# quarterly, and yearly expiries\n```\n\n#### Get Option Chain\n\nFetch the option chain for a specific instrument using either an exact expiry date or a expiry preference:\n\n```python\n# Get ATM call options for SBIN with specific expiry date\noptions = client.get_option_chain(\n    identifier=\"NSE:SBIN:3045\",\n    expiry_date=\"2025-05-30\",\n    option_type=[client.OPTION_TYPE_CE],  # Call options\n    moneyness=[client.MONEYNESS_ATM]      # At-the-money\n)\nprint(f\"Found {len(options['strikes'])} strikes\")\nprint(f\"Current underlying price: {options['underlyingPrice']}\")\n\n# Get both call and put options with expiry preference\nall_options = client.get_option_chain(\n    identifier=\"NSE:NIFTY 50:26000\",\n    expiry_preference=client.EXPIRY_CURRENT_WEEKLY,  # Current week's expiry\n    option_type=[client.OPTION_TYPE_CE, client.OPTION_TYPE_PE],  # Both calls and puts\n    moneyness=[client.MONEYNESS_ATM, client.MONEYNESS_ITM, client.MONEYNESS_OTM]  # All moneyness types\n)\n\n# Print option chain details\nprint(f\"Resolved expiry: {all_options['resolvedExpiry']}\")\nprint(f\"Underlying price: {all_options['underlyingPrice']}\")\nprint(f\"Future price: {all_options['futurePrice']}\")\n\n# Process options data\nfor strike in all_options['strikes']:\n    print(f\"{strike['tradingSymbol']} ({strike['moneyness']}): {strike['ltp']}\")\n```\n\n#### Response Structure\n\nThe `get_option_chain` method returns a dictionary with the following structure:\n\n```python\n{\n    # The actual expiry date that was resolved (may differ slightly from requested date)\n    \"resolvedExpiry\": \"2025-05-29\", \n    \n    # Current price of the underlying stock/index\n    \"underlyingPrice\": 792.1,\n    \n    # Price of the corresponding futures contract (if applicable)\n    \"futurePrice\": 793.35,\n    \n    # Array of available strike prices matching the query criteria\n    \"strikes\": [\n        {\n            # The strike price of the option\n            \"strikePrice\": 790,\n            \n            # Option type: \"CE\" (Call) or \"PE\" (Put)\n            \"optionType\": \"CE\",\n            \n            # Exchange token for the option contract\n            \"exchangeToken\": 136169,\n            \n            # Exchange where the option is traded\n            \"exchange\": \"NSE\",\n            \n            # Trading symbol for the option contract\n            \"tradingSymbol\": \"SBIN25MAY790CE\",\n            \n            # Moneyness classification: \"ATM\", \"ITM\", or \"OTM\"\n            \"moneyness\": \"ATM\",\n            \n            # Expiry date of the option contract\n            \"expiry\": \"2025-05-29\",\n            \n            # Last traded price of the option\n            \"ltp\": 15.1,\n            \n            # Option Greeks and metrics (if available)\n            \"metrics\": {\n                # Option premium\n                \"premium\": 0,\n                \n                # Open interest\n                \"oi\": 0,\n                \n                # Implied volatility\n                \"iv\": 0,\n                \n                # Delta - rate of change of option price with respect to underlying\n                \"delta\": 0,\n                \n                # Gamma - rate of change of delta with respect to underlying\n                \"gamma\": 0,\n                \n                # Theta - rate of change of option price with respect to time\n                \"theta\": 0,\n                \n                # Vega - rate of change of option price with respect to volatility\n                \"vega\": 0,\n                \n                # Rho - rate of change of option price with respect to interest rate\n                \"rho\": 0\n            }\n        },\n        # Additional strikes...\n    ]\n}\n```\n\n#### Advanced Examples\n\n##### Finding a Straddle/Strangle\n\n```python\ndef find_straddle_strangle(identifier, expiry):\n    \"\"\"Find and analyze straddle/strangle opportunities.\"\"\"\n    # Get the option chain\n    option_chain = client.get_option_chain(\n        identifier=identifier,\n        expiry_date=expiry,\n        option_type=[client.OPTION_TYPE_CE, client.OPTION_TYPE_PE],\n        moneyness=[client.MONEYNESS_ATM]\n    )\n    \n    # Find ATM call and put\n    calls = [s for s in option_chain[\"strikes\"] if s[\"optionType\"] == \"CE\"]\n    puts = [s for s in option_chain[\"strikes\"] if s[\"optionType\"] == \"PE\"]\n    \n    if not calls or not puts:\n        print(\"Couldn't find both call and put options\")\n        return\n    \n    # For a straddle, we want the same strike price\n    atm_strike = calls[0][\"strikePrice\"]\n    atm_call = calls[0]\n    atm_put = next((p for p in puts if p[\"strikePrice\"] == atm_strike), None)\n    \n    if atm_call and atm_put:\n        call_premium = atm_call[\"ltp\"]\n        put_premium = atm_put[\"ltp\"]\n        total_premium = call_premium + put_premium\n        \n        print(f\"ATM Straddle Analysis for {identifier} (Expiry: {expiry})\")\n        print(f\"Underlying Price: {option_chain['underlyingPrice']}\")\n        print(f\"ATM Strike: {atm_strike}\")\n        print(f\"Call Premium: {call_premium}\")\n        print(f\"Put Premium: {put_premium}\")\n        print(f\"Total Premium: {total_premium}\")\n        print(f\"Breakeven Upper: {atm_strike + total_premium}\")\n        print(f\"Breakeven Lower: {atm_strike - total_premium}\")\n        \n        # Calculate the percentage move needed for breakeven\n        pct_move = (total_premium / option_chain['underlyingPrice']) * 100\n        print(f\"Required % Move for Breakeven: {pct_move:.2f}%\")\n    \n    # For a strangle, we want OTM call and put\n    otm_options = client.get_option_chain(\n        identifier=identifier,\n        expiry_date=expiry,\n        option_type=[client.OPTION_TYPE_CE, client.OPTION_TYPE_PE],\n        moneyness=[client.MONEYNESS_OTM]\n    )\n    \n    otm_calls = sorted([s for s in otm_options[\"strikes\"] if s[\"optionType\"] == \"CE\"], \n                       key=lambda x: x[\"strikePrice\"])\n    otm_puts = sorted([s for s in otm_options[\"strikes\"] if s[\"optionType\"] == \"PE\"], \n                      key=lambda x: x[\"strikePrice\"], reverse=True)\n    \n    if otm_calls and otm_puts:\n        otm_call = otm_calls[0]  # First OTM call\n        otm_put = otm_puts[0]    # First OTM put\n        \n        call_premium = otm_call[\"ltp\"]\n        put_premium = otm_put[\"ltp\"]\n        total_premium = call_premium + put_premium\n        \n        print(f\"\\nOTM Strangle Analysis for {identifier} (Expiry: {expiry})\")\n        print(f\"Call Strike: {otm_call['strikePrice']} (Premium: {call_premium})\")\n        print(f\"Put Strike: {otm_put['strikePrice']} (Premium: {put_premium})\")\n        print(f\"Total Premium: {total_premium}\")\n        print(f\"Breakeven Upper: {otm_call['strikePrice'] + total_premium}\")\n        print(f\"Breakeven Lower: {otm_put['strikePrice'] - total_premium}\")\n    \n    return option_chain\n\n# Example usage\nfind_straddle_strangle(\"NSE:SBIN:3045\", \"2025-05-30\")\n```\n\n##### Option Chain Visualization\n\n```python\ndef visualize_option_chain(identifier, expiry):\n    \"\"\"Create a visualization of the option chain.\"\"\"\n    import matplotlib.pyplot as plt\n    import numpy as np\n    \n    # Get the option chain\n    option_chain = client.get_option_chain(\n        identifier=identifier,\n        expiry_date=expiry,\n        option_type=[client.OPTION_TYPE_CE, client.OPTION_TYPE_PE],\n        moneyness=[client.MONEYNESS_ATM, client.MONEYNESS_ITM, client.MONEYNESS_OTM]\n    )\n    \n    # Extract data\n    underlying_price = option_chain[\"underlyingPrice\"]\n    \n    # Separate calls and puts\n    calls = sorted([s for s in option_chain[\"strikes\"] if s[\"optionType\"] == \"CE\"], \n                  key=lambda x: x[\"strikePrice\"])\n    puts = sorted([s for s in option_chain[\"strikes\"] if s[\"optionType\"] == \"PE\"], \n                 key=lambda x: x[\"strikePrice\"])\n    \n    # Extract strike prices and premiums\n    call_strikes = [c[\"strikePrice\"] for c in calls]\n    call_premiums = [c[\"ltp\"] for c in calls]\n    \n    put_strikes = [p[\"strikePrice\"] for p in puts]\n    put_premiums = [p[\"ltp\"] for p in puts]\n    \n    # Create figure and axis\n    fig, ax = plt.subplots(figsize=(12, 8))\n    \n    # Plot calls and puts\n    ax.plot(call_strikes, call_premiums, 'b-', marker='o', label='Calls')\n    ax.plot(put_strikes, put_premiums, 'r-', marker='o', label='Puts')\n    \n    # Add vertical line for current price\n    ax.axvline(x=underlying_price, color='g', linestyle='--', \n               label=f'Current Price ({underlying_price})')\n    \n    # Add labels and title\n    ax.set_xlabel('Strike Price')\n    ax.set_ylabel('Premium')\n    ax.set_title(f'Option Chain for {identifier} (Expiry: {expiry})')\n    ax.legend()\n    ax.grid(True)\n    \n    plt.tight_layout()\n    plt.show()\n    \n    return option_chain\n\n# Example usage\nvisualize_option_chain(\"NSE:NIFTY 50:26000\", \"2025-05-30\")\n```\n\n#### Get Futures List\n\nFetch available futures contracts for an instrument:\n\n```python\n# Get futures for an equity stock\nsbin_futures = client.get_futures_list(\"NSE:SBIN:3045\")\nprint(f\"Found {len(sbin_futures)} futures contracts for SBIN\")\nfor future in sbin_futures:\n    print(f\"{future['tradingSymbol']} - Expiry: {future['expiry']} ({future['contract']})\")\n\n# Get futures for an index\nnifty_futures = client.get_futures_list(\"NSE:NIFTY 50:26000\")\nprint(f\"Found {len(nifty_futures)} futures contracts for NIFTY 50\")\nfor future in nifty_futures:\n    print(f\"{future['tradingSymbol']} - Expiry: {future['expiry']} ({future['contract']})\")\n```\n\n#### Response Structure for Futures List\n\nThe `get_futures_list` method returns a list of dictionaries, each representing a futures contract:\n\n```python\n[\n    {\n        # Exchange where the future is traded\n        \"exchange\": \"NSE\",\n        \n        # Trading symbol of the futures contract\n        \"tradingSymbol\": \"SBIN25MAYFUT\",\n        \n        # Exchange token for the futures contract\n        \"exchangeToken\": 57515,\n        \n        # Complete identifier for the futures contract\n        \"identifier\": \"NSE:SBIN25MAYFUT:57515\",\n        \n        # Expiry date in YYYY-MM-DD format\n        \"expiry\": \"2025-05-29\",\n        \n        # Contract type (near_month, mid_month, far_month)\n        \"contract\": \"near_month\"\n    },\n    # Additional futures contracts...\n]\n```\n\nThe `contract` field indicates the type of futures contract:\n- **`near_month`**: Current month's futures contract\n- **`mid_month`**: Next month's futures contract  \n- **`far_month`**: Month after next futures contract\n\n### Wizzer Client Examples\n\n#### Market Data and Analysis Example\n\n```python\nfrom wiz_trader import WizzerClient\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\n# Initialize client\nclient = WizzerClient(\n    base_url=\"https://api-url.in\",\n    token=\"your-jwt-token\"\n)\n\ndef analyze_index_performance(index_symbol, exchange, start_date, end_date):\n    # Get index components\n    components = client.get_index_components(\n        trading_symbol=index_symbol,\n        exchange=exchange\n    )\n    print(f\"Found {len(components)} components in {index_symbol}\")\n    \n    # Get the identifiers for the top 5 weighted components\n    top_components = sorted(components, key=lambda x: x.get('weightage', 0), reverse=True)[:5]\n    instrument_ids = [comp['identifier'] for comp in top_components]\n    \n    # Fetch historical data\n    historical_data = client.get_historical_ohlcv(\n        instruments=instrument_ids,\n        start_date=start_date,\n        end_date=end_date,\n        ohlcv=[\"close\"],\n        interval=\"1d\"\n    )\n    \n    # Process and plot the data\n    for instrument_data in historical_data:\n        symbol = instrument_data['instrument'].split(':')[1]\n        df = pd.DataFrame(instrument_data['data'])\n        df['date'] = pd.to_datetime(df['date'])\n        df.set_index('date', inplace=True)\n        \n        # Calculate percentage change from first day\n        first_close = df['close'].iloc[0]\n        df['pct_change'] = ((df['close'] - first_close) / first_close) * 100\n        \n        plt.plot(df.index, df['pct_change'], label=symbol)\n    \n    plt.title(f\"Performance of Top {index_symbol} Components\")\n    plt.xlabel(\"Date\")\n    plt.ylabel(\"% Change\")\n    plt.legend()\n    plt.grid(True)\n    plt.show()\n\n# Analyze NIFTY 50 performance for Jan 2024\nanalyze_index_performance(\n    index_symbol=\"NIFTY 50\",\n    exchange=\"NSE\",\n    start_date=\"2024-01-01\",\n    end_date=\"2024-01-31\"\n)\n```\n\n#### Algorithmic Trading Example\n\n```python\nfrom wiz_trader import QuotesClient, WizzerClient\nimport time\nimport logging\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\nclass SimpleMovingAverageCrossover:\n    def __init__(self, symbol, exchange, token, fast_period=5, slow_period=20):\n        # Trading parameters\n        self.symbol = symbol\n        self.exchange = exchange\n        self.token = token\n        self.instrument_id = f\"{exchange}:{symbol}:{token}\"\n        self.fast_period = fast_period\n        self.slow_period = slow_period\n        \n        # State variables\n        self.prices = []\n        self.position = None\n        self.order_id = None\n        \n        # Clients\n        self.quotes_client = QuotesClient(\n            base_url=\"wss://websocket-url/quotes\",\n            token=\"your-jwt-token\"\n        )\n        self.wizzer_client = WizzerClient(\n            base_url=\"https://api-url.in\",\n            token=\"your-jwt-token\"\n        )\n        \n        # Set up quotes client callbacks\n        self.quotes_client.on_tick = self.on_tick\n        self.quotes_client.on_connect = self.on_connect\n        self.quotes_client.on_error = lambda ws, error: logger.error(f\"Error: {error}\")\n    \n    def on_connect(self, ws):\n        logger.info(f\"Connected to quotes server\")\n        ws.subscribe([self.instrument_id])\n    \n    def on_tick(self, ws, tick):\n        if \"ltp\" in tick:\n            price = tick[\"ltp\"]\n            self.prices.append(price)\n            \n            # Keep only the required number of prices\n            if len(self.prices) > self.slow_period:\n                self.prices.pop(0)\n            \n            # Once we have enough data, check for signals\n            if len(self.prices) >= self.slow_period:\n                self.check_for_signals()\n    \n    def check_for_signals(self):\n        # Calculate moving averages\n        fast_ma = sum(self.prices[-self.fast_period:]) / self.fast_period\n        slow_ma = sum(self.prices) / self.slow_period\n        \n        current_price = self.prices[-1]\n        \n        logger.info(f\"Price: {current_price}, Fast MA: {fast_ma:.2f}, Slow MA: {slow_ma:.2f}\")\n        \n        # Generate signals\n        if fast_ma > slow_ma and self.position != \"long\":\n            # Buy signal\n            logger.info(\"BUY SIGNAL\")\n            self.enter_position(\"long\", current_price)\n        \n        elif fast_ma < slow_ma and self.position == \"long\":\n            # Sell signal\n            logger.info(\"SELL SIGNAL\")\n            self.exit_position(current_price)\n    \n    def enter_position(self, position_type, price):\n        if position_type == \"long\":\n            # Place a buy order\n            try:\n                order_response = self.wizzer_client.place_order(\n                    exchange=self.exchange,\n                    trading_symbol=self.symbol,\n                    transaction_type=self.wizzer_client.TRANSACTION_TYPE_BUY,\n                    quantity=10,  # Fixed quantity for simplicity\n                    order_type=self.wizzer_client.ORDER_TYPE_MARKET,\n                    product=self.wizzer_client.PRODUCT_CNC\n                )\n                self.order_id = order_response.get(\"orderId\")\n                self.position = \"long\"\n                logger.info(f\"Entered LONG position at {price}, Order ID: {self.order_id}\")\n            except Exception as e:\n                logger.error(f\"Error entering position: {e}\")\n    \n    def exit_position(self, price):\n        if self.position == \"long\":\n            # Place a sell order\n            try:\n                order_response = self.wizzer_client.place_order(\n                    exchange=self.exchange,\n                    trading_symbol=self.symbol,\n                    transaction_type=self.wizzer_client.TRANSACTION_TYPE_SELL,\n                    quantity=10,  # Fixed quantity for simplicity\n                    order_type=self.wizzer_client.ORDER_TYPE_MARKET,\n                    product=self.wizzer_client.PRODUCT_CNC\n                )\n                logger.info(f\"Exited LONG position at {price}, Order ID: {order_response.get('orderId')}\")\n                self.position = None\n                self.order_id = None\n            except Exception as e:\n                logger.error(f\"Error exiting position: {e}\")\n    \n    def run(self):\n        try:\n            logger.info(\"Starting the strategy...\")\n            self.quotes_client.connect()\n        except KeyboardInterrupt:\n            logger.info(\"Strategy interrupted by user\")\n            if self.position:\n                logger.info(\"Closing position before exit\")\n                self.exit_position(self.prices[-1] if self.prices else 0)\n            self.quotes_client.stop()\n\n# Run the strategy\nstrategy = SimpleMovingAverageCrossover(\n    symbol=\"SBIN\",\n    exchange=\"NSE\",\n    token=3045,\n    fast_period=5,\n    slow_period=20\n)\nstrategy.run()\n```\n\n#### Basket Management Example\n\n```python\nfrom wiz_trader import WizzerClient\nimport json\n\n# Initialize client\nclient = WizzerClient(\n    base_url=\"https://api-url.in\",\n    token=\"your-jwt-token\"\n)\n\ndef create_and_trade_basket():\n    # Create a sector-based basket\n    banking_basket = client.create_basket(\n        name=\"Banking Basket\",\n        instruments=[\n            {\n                \"shares\": 20,\n                \"weightage\": 25,\n                \"instrument\": {\n                    \"exchange\": \"NSE\",\n                    \"identifier\": \"NSE:SBIN:3045\",\n                    \"orderIndex\": 1,\n                    \"exchangeToken\": 3045,\n                    \"tradingSymbol\": \"SBIN\"\n                }\n            },\n            {\n                \"shares\": 15,\n                \"weightage\": 25,\n                \"instrument\": {\n                    \"exchange\": \"NSE\",\n                    \"identifier\": \"NSE:ICICIBANK:4963\",\n                    \"orderIndex\": 2,\n                    \"exchangeToken\": 4963,\n                    \"tradingSymbol\": \"ICICIBANK\"\n                }\n            },\n            {\n                \"shares\": 15,\n                \"weightage\": 25,\n                \"instrument\": {\n                    \"exchange\": \"NSE\",\n                    \"identifier\": \"NSE:HDFCBANK:1333\",\n                    \"orderIndex\": 3,\n                    \"exchangeToken\": 1333,\n                    \"tradingSymbol\": \"HDFCBANK\"\n                }\n            },\n            {\n                \"shares\": 30,\n                \"weightage\": 25,\n                \"instrument\": {\n                    \"exchange\": \"NSE\",\n                    \"identifier\": \"NSE:BANKBARODA:2263\",\n                    \"orderIndex\": 4,\n                    \"exchangeToken\": 2263,\n                    \"tradingSymbol\": \"BANKBARODA\"\n                }\n            }\n        ],\n        weightage_scheme=\"equi_weighted\",\n        capital={\"minValue\": 100000, \"actualValue\": 100000},\n        instrument_types=[\"EQLC\"]\n    )\n    \n    basket_id = banking_basket.get('id')\n    basket_symbol = banking_basket.get('tradingSymbol')\n    exchange_token = banking_basket.get('basketInstrument', {}).get('exchangeToken')\n    \n    print(f\"Created basket: {basket_symbol} (ID: {basket_id})\")\n    \n    # Place a buy order for the basket\n    try:\n        order_response = client.place_basket_order(\n            trading_symbol=basket_symbol,\n            transaction_type=client.TRANSACTION_TYPE_BUY,\n            quantity=1,  # Buy one unit of the basket\n            price=100000.00,\n            product=client.PRODUCT_CNC\n        )\n        print(f\"Placed basket buy order: {order_response.get('orderId')}\")\n        \n        # After some time, exit the basket\n        # (This would normally be based on some strategy or time delay)\n        exit_response = client.place_basket_exit_order(\n            trading_symbol=basket_symbol,\n            exchange=client.EXCHANGE_WZR,\n            transaction_type=client.TRANSACTION_TYPE_SELL,\n            quantity=1,\n            exchange_token=exchange_token\n        )\n        print(f\"Placed basket exit order: {exit_response.get('orderId')}\")\n        \n    except Exception as e:\n        print(f\"Error during basket trading: {e}\")\n\n# Rebalance the basket (e.g., to adjust weightages or change stocks)\n    try:\n        rebalance_response = client.rebalance_basket(\n            trading_symbol=basket_symbol,\n            instruments=[\n                \"NSE:SBIN:3045\",\n                \"NSE:HDFCBANK:1333\",\n                \"NSE:ICICIBANK:4963\",\n                \"NSE:AXISBANK:5900\"  # Replacing BANKBARODA with AXISBANK\n            ]\n        )\n        print(f\"Rebalanced basket successfully\")\n    except Exception as e:\n        print(f\"Error during basket rebalancing: {e}\")\n\n# Run the basket trading example\ncreate_and_trade_basket()\n```\n\n## Common Use Cases\n\n### Backtesting with Historical Data\n\n```python\nfrom wiz_trader import WizzerClient\nimport pandas as pd\nimport numpy as np\nfrom datetime import datetime\n\n# Initialize client\nclient = WizzerClient(\n    base_url=\"https://api-url.in\",\n    token=\"your-jwt-token\"\n)\n\ndef backtest_simple_strategy(symbol, exchange, token, start_date, end_date, \n                             fast_period=10, slow_period=30):\n    # Get historical data\n    instrument_id = f\"{exchange}:{symbol}:{token}\"\n    data = client.get_historical_ohlcv(\n        instruments=[instrument_id],\n        start_date=start_date,\n        end_date=end_date,\n        ohlcv=[\"open\", \"high\", \"low\", \"close\", \"volume\"],\n        interval=\"1d\"\n    )\n    \n    if not data or not data[0].get('data'):\n        print(\"No data available for the specified period\")\n        return\n    \n    # Convert to DataFrame\n    df = pd.DataFrame(data[0]['data'])\n    df['date'] = pd.to_datetime(df['date'])\n    df.set_index('date', inplace=True)\n    \n    # Calculate moving averages\n    df['fast_ma'] = df['close'].rolling(window=fast_period).mean()\n    df['slow_ma'] = df['close'].rolling(window=slow_period).mean()\n    \n    # Generate signals\n    df['signal'] = 0\n    df.loc[df['fast_ma'] > df['slow_ma'], 'signal'] = 1  # Buy signal\n    df.loc[df['fast_ma'] < df['slow_ma'], 'signal'] = -1  # Sell signal\n    \n    # Calculate returns\n    df['returns'] = df['close'].pct_change()\n    df['strategy_returns'] = df['signal'].shift(1) * df['returns']\n    \n    # Calculate cumulative returns\n    df['cumulative_returns'] = (1 + df['returns']).cumprod() - 1\n    df['strategy_cumulative_returns'] = (1 + df['strategy_returns']).cumprod() - 1\n    \n    # Calculate statistics\n    total_days = len(df)\n    winning_days = len(df[df['strategy_returns'] > 0])\n    win_rate = winning_days / total_days if total_days > 0 else 0\n    \n    strategy_return = df['strategy_cumulative_returns'].iloc[-1]\n    buy_hold_return = df['cumulative_returns'].iloc[-1]\n    \n    print(f\"Backtest Results for {symbol} ({start_date} to {end_date}):\")\n    print(f\"Strategy Return: {strategy_return:.2%}\")\n    print(f\"Buy & Hold Return: {buy_hold_return:.2%}\")\n    print(f\"Win Rate: {win_rate:.2%}\")\n    print(f\"Total Trades: {df['signal'].diff().abs().sum() / 2:.0f}\")\n    \n    return df\n\n# Run a backtest\nresult_df = backtest_simple_strategy(\n    symbol=\"SBIN\",\n    exchange=\"NSE\",\n    token=3045,\n    start_date=\"2023-01-01\",\n    end_date=\"2023-12-31\",\n    fast_period=10,\n    slow_period=30\n)\n\n# Plot the results \nimport matplotlib.pyplot as plt\n\nplt.figure(figsize=(12, 8))\n\n# Plot prices and moving averages\nplt.subplot(2, 1, 1)\nplt.plot(result_df.index, result_df['close'], label='Close Price')\nplt.plot(result_df.index, result_df['fast_ma'], label=f'Fast MA ({10} days)')\nplt.plot(result_df.index, result_df['slow_ma'], label=f'Slow MA ({30} days)')\nplt.title('Price and Moving Averages')\nplt.legend()\nplt.grid(True)\n\n# Plot cumulative returns\nplt.subplot(2, 1, 2)\nplt.plot(result_df.index, result_df['cumulative_returns'], label='Buy & Hold')\nplt.plot(result_df.index, result_df['strategy_cumulative_returns'], label='Strategy')\nplt.title('Cumulative Returns')\nplt.legend()\nplt.grid(True)\n\nplt.tight_layout()\nplt.show()\n```\n\n### Real-time Portfolio Monitoring\n\n```python\nfrom wiz_trader import QuotesClient, WizzerClient\nimport pandas as pd\nimport time\nfrom datetime import datetime\n\n# Initialize clients\nquotes_client = QuotesClient(\n    base_url=\"wss://websocket-url/quotes\",\n    token=\"your-jwt-token\",\n    log_level=\"info\"\n)\n\nwizzer_client = WizzerClient(\n    base_url=\"https://api-url.in\",\n    token=\"your-jwt-token\",\n    log_level=\"info\"\n)\n\nclass PortfolioMonitor:\n    def __init__(self):\n        self.portfolio = {}\n        self.last_update_time = None\n        self.update_interval = 60  # seconds\n        \n    def on_tick(self, ws, tick):\n        \"\"\"Process incoming market data\"\"\"\n        if 'instrument' in tick and 'ltp' in tick:\n            instrument = tick['instrument']\n            ltp = tick['ltp']\n            \n            if instrument in self.portfolio:\n                # Update the current price\n                self.portfolio[instrument]['current_price'] = ltp\n                \n                # Calculate P&L\n                avg_price = self.portfolio[instrument]['avg_price']\n                qty = self.portfolio[instrument]['qty']\n                \n                if qty > 0:  # Long position\n                    pnl = (ltp - avg_price) * qty\n                    pnl_percent = ((ltp / avg_price) - 1) * 100\n                else:  # Short position\n                    pnl = (avg_price - ltp) * abs(qty)\n                    pnl_percent = ((avg_price / ltp) - 1) * 100\n                \n                self.portfolio[instrument]['pnl'] = pnl\n                self.portfolio[instrument]['pnl_percent'] = pnl_percent\n                \n                # Display portfolio if update interval has passed\n                current_time = time.time()\n                if (self.last_update_time is None or \n                    current_time - self.last_update_time > self.update_interval):\n                    self.display_portfolio()\n                    self.last_update_time = current_time\n    \n    def on_connect(self, ws):\n        \"\"\"Handle connection to quotes server\"\"\"\n        print(f\"Connected to quotes server at {datetime.now()}\")\n        # Fetch holdings and subscribe to them\n        self.fetch_holdings()\n    \n    def fetch_holdings(self):\n        \"\"\"Fetch holdings from the API and update portfolio\"\"\"\n        try:\n            holdings = wizzer_client.get_holdings()\n            \n            # Extract holding information and update portfolio\n            instruments_to_subscribe = []\n            for holding in holdings:\n                if holding.get('qty', 0) > 0:\n                    instrument = holding.get('identifier', '')\n                    if instrument:\n                        self.portfolio[instrument] = {\n                            'symbol': holding.get('tradingSymbol', ''),\n                            'exchange': holding.get('exchange', ''),\n                            'qty': holding.get('qty', 0),\n                            'avg_price': holding.get('avgPrice', 0),\n                            'invested_value': holding.get('investedValue', 0),\n                            'current_price': 0,\n                            'pnl': 0,\n                            'pnl_percent': 0\n                        }\n                        instruments_to_subscribe.append(instrument)\n            \n            # Subscribe to these instruments for real-time updates\n            if instruments_to_subscribe:\n                quotes_client.subscribe(instruments_to_subscribe)\n                print(f\"Subscribed to {len(instruments_to_subscribe)} instruments\")\n            else:\n                print(\"No holdings found to monitor\")\n        \n        except Exception as e:\n            print(f\"Error fetching holdings: {e}\")\n    \n    def display_portfolio(self):\n        \"\"\"Display the current portfolio status\"\"\"\n        if not self.portfolio:\n            print(\"Portfolio is empty\")\n            return\n        \n        print(\"\\n\" + \"=\"*80)\n        print(f\"Portfolio Status as of {datetime.now()}\")\n        print(\"=\"*80)\n        \n        # Create a pandas DataFrame for nicer display\n        df = pd.DataFrame.from_dict(self.portfolio, orient='index')\n        df['pnl'] = df['pnl'].round(2)\n        df['pnl_percent'] = df['pnl_percent'].round(2)\n        \n        # Sort by P&L\n        df = df.sort_values('pnl', ascending=False)\n        \n        print(df[['symbol', 'qty', 'avg_price', 'current_price', 'pnl', 'pnl_percent']])\n        \n        # Calculate total values\n        total_invested = df['invested_value'].sum()\n        total_current = (df['current_price'] * df['qty']).sum()\n        total_pnl = df['pnl'].sum()\n        total_pnl_percent = ((total_current / total_invested) - 1) * 100 if total_invested > 0 else 0\n        \n        print(\"-\"*80)\n        print(f\"Total Invested: \u20b9{total_invested:.2f}\")\n        print(f\"Total Current Value: \u20b9{total_current:.2f}\")\n        print(f\"Total P&L: \u20b9{total_pnl:.2f} ({total_pnl_percent:.2f}%)\")\n        print(\"=\"*80 + \"\\n\")\n\n# Create and run the portfolio monitor\nmonitor = PortfolioMonitor()\n\n# Set up callbacks\nquotes_client.on_tick = monitor.on_tick\nquotes_client.on_connect = monitor.on_connect\nquotes_client.on_error = lambda ws, error: print(f\"Error: {error}\")\n\n# Start monitoring (blocking call)\ntry:\n    quotes_client.connect()\nexcept KeyboardInterrupt:\n    print(\"\\nPortfolio monitoring stopped by user\")\n    quotes_client.stop()\n```\n\n### Multi-Strategy Trading\n\n```python\nfrom wiz_trader import QuotesClient, WizzerClient\nimport pandas as pd\nimport threading\nimport time\nfrom datetime import datetime\nimport numpy as np\n\n# Initialize API clients\nquotes_client = QuotesClient(\n    base_url=\"wss://websocket-url/quotes\",\n    token=\"your-jwt-token\",\n    log_level=\"info\"\n)\n\nwizzer_client = WizzerClient(\n    base_url=\"https://api-url.in\",\n    token=\"your-jwt-token\",\n    log_level=\"info\"\n)\n\nclass TradingStrategy:\n    \"\"\"Base class for trading strategies\"\"\"\n    def __init__(self, name, symbols):\n        self.name = name\n        self.symbols = symbols\n        self.active = False\n        self.positions = {}\n        self.prices = {}\n        \n    def on_tick(self, tick):\n        \"\"\"Process tick data - should be implemented by subclasses\"\"\"\n        pass\n    \n    def start(self):\n        \"\"\"Start the strategy\"\"\"\n        self.active = True\n        print(f\"Strategy {self.name} started at {datetime.now()}\")\n    \n    def stop(self):\n        \"\"\"Stop the strategy\"\"\"\n        self.active = False\n        print(f\"Strategy {self.name} stopped at {datetime.now()}\")\n        \n        # Close any open positions\n        self.close_all_positions()\n    \n    def close_all_positions(self):\n        \"\"\"Close all open positions\"\"\"\n        for symbol, position in list(self.positions.items()):\n            if position != 0:\n                try:\n                    self.execute_order(\n                        symbol=symbol.split(':')[1],\n                        exchange=symbol.split(':')[0],\n                        transaction_type=\"SELL\" if position > 0 else \"BUY\",\n                        quantity=abs(position)\n                    )\n                    print(f\"Closed position for {symbol}: {position} units\")\n                    self.positions[symbol] = 0\n                except Exception as e:\n                    print(f\"Error closing position for {symbol}: {e}\")\n    \n    def execute_order(self, symbol, exchange, transaction_type, quantity):\n        \"\"\"Execute an order through the API\"\"\"\n        try:\n            response = wizzer_client.place_order(\n                exchange=exchange,\n                trading_symbol=symbol,\n                transaction_type=transaction_type,\n                quantity=quantity,\n                order_type=wizzer_client.ORDER_TYPE_MARKET,\n                product=wizzer_client.PRODUCT_CNC\n            )\n            print(f\"Order executed: {exchange}:{symbol} {transaction_type} {quantity} units\")\n            return response.get('orderId')\n        except Exception as e:\n            print(f\"Order execution error: {e}\")\n            return None\n\nclass MovingAverageCrossover(TradingStrategy):\n    \"\"\"Moving Average Crossover Strategy\"\"\"\n    def __init__(self, name, symbols, fast_period=10, slow_period=30):\n        super().__init__(name, symbols)\n        self.fast_period = fast_period\n        self.slow_period = slow_period\n        self.price_history = {s: [] for s in symbols}\n    \n    def on_tick(self, tick):\n        if not self.active:\n            return\n            \n        instrument = tick.get('instrument')\n        ltp = tick.get('ltp')\n        \n        if instrument in self.symbols and ltp is not None:\n            # Store the current price\n            self.prices[instrument] = ltp\n            \n            # Add to price history\n            self.price_history[instrument].append(ltp)\n            \n            # Keep only enough prices for the slow MA\n            if len(self.price_history[instrument]) > self.slow_period:\n                self.price_history[instrument].pop(0)\n            \n            # Check for trading signals if we have enough data\n            if len(self.price_history[instrument]) >= self.slow_period:\n                self.check_signals(instrument)\n    \n    def check_signals(self, instrument):\n        prices = self.price_history[instrument]\n        \n        # Calculate moving averages\n        fast_ma = sum(prices[-self.fast_period:]) / self.fast_period\n        slow_ma = sum(prices) / self.slow_period\n        \n        # Get current position and price\n        current_position = self.positions.get(instrument, 0)\n        current_price = self.prices[instrument]\n        \n        # Generate signals\n        if fast_ma > slow_ma and current_position <= 0:\n            # Buy signal\n            quantity = 10  # Fixed quantity for simplicity\n            \n            # Close any short position first\n            if current_position < 0:\n                self.execute_order(\n                    symbol=instrument.split(':')[1],\n                    exchange=instrument.split(':')[0],\n                    transaction_type=\"BUY\",\n                    quantity=abs(current_position)\n                )\n                self.positions[instrument] = 0\n            \n            # Enter long position\n            self.execute_order(\n                symbol=instrument.split(':')[1],\n                exchange=instrument.split(':')[0],\n                transaction_type=\"BUY\",\n                quantity=quantity\n            )\n            self.positions[instrument] = quantity\n            \n            print(f\"{self.name}: BUY {quantity} units of {instrument} at {current_price}\")\n            \n        elif fast_ma < slow_ma and current_position >= 0:\n            # Sell signal\n            \n            # Close any long position\n            if current_position > 0:\n                self.execute_order(\n                    symbol=instrument.split(':')[1],\n                    exchange=instrument.split(':')[0],\n                    transaction_type=\"SELL\",\n                    quantity=current_position\n                )\n                self.positions[instrument] = 0\n                \n                print(f\"{self.name}: SELL {current_position} units of {instrument} at {current_price}\")\n            \n            # Option: Enter short position (if allowed)\n            # quantity = 10  # Fixed quantity for simplicity\n            # self.execute_order(\n            #     symbol=instrument.split(':')[1],\n            #     exchange=instrument.split(':')[0],\n            #     transaction_type=\"SELL\",\n            #     quantity=quantity\n            # )\n            # self.positions[instrument] = -quantity\n            # print(f\"{self.name}: SHORT {quantity} units of {instrument} at {current_price}\")\n\nclass BollingerBands(TradingStrategy):\n    \"\"\"Bollinger Bands Strategy\"\"\"\n    def __init__(self, name, symbols, period=20, std_dev=2):\n        super().__init__(name, symbols)\n        self.period = period\n        self.std_dev = std_dev\n        self.price_history = {s: [] for s in symbols}\n    \n    def on_tick(self, tick):\n        if not self.active:\n            return\n            \n        instrument = tick.get('instrument')\n        ltp = tick.get('ltp')\n        \n        if instrument in self.symbols and ltp is not None:\n            # Store the current price\n            self.prices[instrument] = ltp\n            \n            # Add to price history\n            self.price_history[instrument].append(ltp)\n            \n            # Keep only enough prices for the calculation\n            if len(self.price_history[instrument]) > self.period:\n                self.price_history[instrument].pop(0)\n            \n            # Check for trading signals if we have enough data\n            if len(self.price_history[instrument]) >= self.period:\n                self.check_signals(instrument)\n    \n    def check_signals(self, instrument):\n        prices = self.price_history[instrument]\n        \n        # Calculate Bollinger Bands\n        sma = sum(prices) / len(prices)\n        std = np.std(prices)\n        upper_band = sma + (std * self.std_dev)\n        lower_band = sma - (std * self.std_dev)\n        \n        # Get current position and price\n        current_position = self.positions.get(instrument, 0)\n        current_price = self.prices[instrument]\n        \n        # Generate signals\n        if current_price < lower_band and current_position <= 0:\n            # Buy signal (price below lower band)\n            quantity = 10  # Fixed quantity for simplicity\n            \n            # Close any short position first\n            if current_position < 0:\n                self.execute_order(\n                    symbol=instrument.split(':')[1],\n                    exchange=instrument.split(':')[0],\n                    transaction_type=\"BUY\",\n                    quantity=abs(current_position)\n                )\n                self.positions[instrument] = 0\n            \n            # Enter long position\n            self.execute_order(\n                symbol=instrument.split(':')[1],\n                exchange=instrument.split(':')[0],\n                transaction_type=\"BUY\",\n                quantity=quantity\n            )\n            self.positions[instrument] = quantity\n            \n            print(f\"{self.name}: BUY {quantity} units of {instrument} at {current_price} (below lower band {lower_band:.2f})\")\n            \n        elif current_price > upper_band and current_position >= 0:\n            # Sell signal (price above upper band)\n            \n            # Close any long position\n            if current_position > 0:\n                self.execute_order(\n                    symbol=instrument.split(':')[1],\n                    exchange=instrument.split(':')[0],\n                    transaction_type=\"SELL\",\n                    quantity=current_position\n                )\n                self.positions[instrument] = 0\n                \n                print(f\"{self.name}: SELL {current_position} units of {instrument} at {current_price} (above upper band {upper_band:.2f})\")\n\nclass MultiStrategyManager:\n    \"\"\"Manages multiple trading strategies\"\"\"\n    def __init__(self, quotes_client):\n        self.quotes_client = quotes_client\n        self.strategies = {}\n        \n    def add_strategy(self, strategy):\n        \"\"\"Add a strategy to the manager\"\"\"\n        self.strategies[strategy.name] = strategy\n        \n        # Subscribe to all strategy symbols\n        for symbol in strategy.symbols:\n            if not symbol.startswith('NSE:') and not symbol.startswith('BSE:'):\n                print(f\"Warning: Symbol {symbol} does not include exchange prefix\")\n        \n    def on_tick(self, ws, tick):\n        \"\"\"Process ticks and distribute to strategies\"\"\"\n        for strategy in self.strategies.values():\n            strategy.on_tick(tick)\n    \n    def on_connect(self, ws):\n        \"\"\"Handle connection to quotes server\"\"\"\n        print(f\"Connected to quotes server at {datetime.now()}\")\n        \n        # Collect all symbols from all strategies\n        all_symbols = set()\n        for strategy in self.strategies.values():\n            all_symbols.update(strategy.symbols)\n        \n        # Subscribe to all symbols\n        if all_symbols:\n            ws.subscribe(list(all_symbols))\n            print(f\"Subscribed to {len(all_symbols)} symbols\")\n    \n    def start_all(self):\n        \"\"\"Start all strategies\"\"\"\n        for strategy in self.strategies.values():\n            strategy.start()\n    \n    def stop_all(self):\n        \"\"\"Stop all strategies\"\"\"\n        for strategy in self.strategies.values():\n            strategy.stop()\n    \n    def start_strategy(self, name):\n        \"\"\"Start a specific strategy\"\"\"\n        if name in self.strategies:\n            self.strategies[name].start()\n        else:\n            print(f\"Strategy {name} not found\")\n    \n    def stop_strategy(self, name):\n        \"\"\"Stop a specific strategy\"\"\"\n        if name in self.strategies:\n            self.strategies[name].stop()\n        else:\n            print(f\"Strategy {name} not found\")\n    \n    def run(self):\n        \"\"\"Run the strategy manager\"\"\"\n        # Set up callbacks\n        self.quotes_client.on_tick = self.on_tick\n        self.quotes_client.on_connect = self.on_connect\n        self.quotes_client.on_error = lambda ws, error: print(f\"Error: {error}\")\n        \n        # Start all strategies\n        self.start_all()\n        \n        # Start the quotes client (blocking call)\n        try:\n            self.quotes_client.connect()\n        except KeyboardInterrupt:\n            print(\"\\nMulti-strategy manager stopped by user\")\n            self.stop_all()\n            self.quotes_client.stop()\n\n# Create strategies\nma_strategy = MovingAverageCrossover(\n    name=\"MA Crossover\",\n    symbols=[\"NSE:SBIN:3045\", \"NSE:ICICIBANK:4963\"],\n    fast_period=10,\n    slow_period=30\n)\n\nbb_strategy = BollingerBands(\n    name=\"Bollinger Bands\",\n    symbols=[\"NSE:RELIANCE:2885\", \"NSE:TCS:2953\"],\n    period=20,\n    std_dev=2\n)\n\n# Create and run the multi-strategy manager\nmanager = MultiStrategyManager(quotes_client)\nmanager.add_strategy(ma_strategy)\nmanager.add_strategy(bb_strategy)\nmanager.run()\n```\n\n## Error Handling\n\nThe SDK provides several mechanisms for handling errors:\n\n### Exception Handling\n\nAll API calls can throw exceptions, which should be caught and handled:\n\n```python\ntry:\n    order_response = client.place_order(\n        exchange=client.EXCHANGE_NSE,\n        trading_symbol=\"SBIN\",\n        transaction_type=client.TRANSACTION_TYPE_BUY,\n        quantity=10,\n        order_type=client.ORDER_TYPE_MARKET,\n        product=client.PRODUCT_CNC\n    )\n    print(f\"Order placed successfully: {order_response.get('orderId')}\")\nexcept Exception as e:\n    print(f\"Error placing order: {e}\")\n```\n\n### Callback Error Handling\n\nFor the WebSocket client, errors are also sent via the `on_error` callback:\n\n```python\ndef on_error(ws, error):\n    \"\"\"Handle WebSocket errors\"\"\"\n    print(f\"WebSocket error: {error}\")\n    \n    # You could implement reconnection logic or alerting here\n    if isinstance(error, ConnectionRefusedError):\n        print(\"Connection refused. Check server status.\")\n    elif isinstance(error, TimeoutError):\n        print(\"Connection timed out. Check network.\")\n\nquotes_client.on_error = on_error\n```\n\n### Logging\n\nBoth clients support different log levels:\n\n```python\nclient = WizzerClient(\n    base_url=\"https://api-url.in\",\n    token=\"your-jwt-token\",\n    log_level=\"debug\"  # Options: \"error\", \"info\", \"debug\"\n)\n```\n\nThe logs can help diagnose issues during development and production.\n\n## Troubleshooting\n\n### Common Issues\n\n#### Authentication Issues\n\nIf you're facing authentication errors:\n\n1. Check that your token is valid and not expired\n2. Ensure you're using the correct base_url for production or development\n3. Verify environment variables if you're using them\n\nExample of token validation:\n```python\ndef is_token_valid(token):\n    \"\"\"Basic validation of JWT token format\"\"\"\n    parts = token.split('.')\n    if len(parts) != 3:\n        return False\n    \n    # Check if the token is expired\n    import base64\n    import json\n    import time\n    \n    try:\n        # Decode the payload\n        payload = parts[1]\n        # Add padding if needed\n        payload += '=' * (4 - len(payload) % 4) if len(payload) % 4 != 0 else ''\n        decoded = base64.b64decode(payload)\n        data = json.loads(decoded)\n        \n        # Check expiration\n        if 'exp' in data:\n            return data['exp'] > time.time()\n        return True\n    except Exception:\n        return False\n\n# Check if token is valid\nif not is_token_valid(token):\n    print(\"Token is invalid or expired. Please get a new token.\")\n```\n\n#### WebSocket Connection Issues\n\nIf you're having trouble connecting to the WebSocket server:\n\n1. Check network connectivity and firewall settings\n2. Verify the WebSocket URL is correct\n3. Check if the server supports SSL/TLS if using 'wss://' protocol\n4. Try with a smaller `max_message_size` to rule out size limitations\n\n#### Order Placement Failures\n\nIf orders are not being placed successfully:\n\n1. Check the error message from the API response\n2. Verify that you're using the correct exchange, symbol, and token\n3. Ensure you have sufficient funds/holdings for the trade\n4. Check that market hours are active for the segment you're trading\n\n## API Reference\n\nFor a complete list of all available methods and parameters, refer to the class docstrings within the SDK.\n\n```python\n# Example of getting detailed help on a method\nhelp(WizzerClient.place_order)\n```\n\n### Environment Variables\n\nAll supported environment variables:\n\n- `WZ__QUOTES_BASE_URL`: WebSocket URL for the quotes server\n- `WZ__API_BASE_URL`: Base URL for the Wizzer's REST API\n- `WZ__TOKEN`: JWT token for authentication\n- `WZ__STRATEGY_ID`: Default strategy ID to use if not provided in methods\n\n### Full Method List\n\n#### QuotesClient\n- `__init__(base_url, token, log_level, max_message_size, batch_size)`\n- `connect()` - Connect in blocking mode\n- `connect_async()` - Connect in non-blocking mode\n- `stop()` - Stop the WebSocket connection\n- `subscribe(instruments)` - Subscribe to instruments\n- `unsubscribe(instruments)` - Unsubscribe from instruments\n\n#### WizzerClient\n- `__init__(base_url, token, strategy_id, log_level)`\n- `get_indices(trading_symbol, exchange)`\n- `get_index_components(trading_symbol, exchange)`\n- `get_historical_ohlcv(instruments, start_date, end_date, ohlcv, interval)`\n- `place_order(exchange, trading_symbol, transaction_type, quantity, ...)`\n- `modify_order(order_id, **params)`\n- `cancel_order(order_id)`\n- `get_order(order_id)`\n- `get_positions(position_status)`\n- `get_open_positions()`\n- `get_closed_positions()`\n- `get_holdings(portfolios)`\n- `create_basket(name, instruments, weightage_scheme, capital, instrument_types)`\n- `get_baskets()`\n- `get_basket(basket_id)`\n- `get_basket_instruments(basket_id)`\n- `place_basket_order(trading_symbol, transaction_type, quantity, ...)`\n- `place_basket_exit_order(trading_symbol, exchange, transaction_type, quantity, exchange_token, **kwargs)`\n- `modify_basket_order(order_id, **params)`\n- `rebalance_basket(trading_symbol, instruments)`\n- `exit_all_positions()`\n- `exit_strategy_positions(strategy_id)`\n\n# Indian Industry Classification Table\n\n| MacroSector | Sector | Industry | BasicIndustries |\n|-------------|---------|----------|-----------------|\n| Commodities | Chemicals | Chemicals & Petrochemicals | Commodity Chemicals |\n|  |  |  | Specialty Chemicals |\n|  |  |  | Carbon Black |\n|  |  |  | Dyes And Pigments |\n|  |  |  | Explosives |\n|  |  |  | Petrochemicals |\n|  |  |  | Printing Inks |\n|  |  |  | Trading - Chemicals |\n|  |  |  | Industrial Gases |\n|  |  | Fertilizers & Agrochemicals | Fertilizers |\n|  |  |  | Pesticides & Agrochemicals |\n|  | Construction Materials | Cement & Cement Products | Cement & Cement Products |\n|  |  | Other Construction Materials | Other Construction Materials |\n|  | Metals & Mining | Ferrous Metals | Ferro & Silica Manganese |\n|  |  |  | Pig Iron |\n|  |  |  | Sponge Iron |\n|  |  |  | Iron & Steel |\n|  |  | Non - Ferrous Metals | Aluminium |\n|  |  |  | Copper |\n|  |  |  | Zinc |\n|  |  |  | Precious Metals |\n|  |  | Diversified Metals | Diversified Metals |\n|  |  | Minerals & Mining | Industrial Minerals |\n|  |  | Metals & Minerals Trading | Trading - Metals |\n|  |  |  | Trading - Minerals |\n|  | Forest Materials | Paper, Forest & Jute Products | Paper & Paper Products |\n|  |  |  | Forest Products |\n|  |  |  | Jute & Jute Products |\n| Consumer Discretionary | Automobile and Auto Components | Automobiles | Passenger Cars & Utility Vehicles |\n|  |  |  | 2/3 Wheelers |\n|  |  |  | Auto Dealer |\n|  |  | Auto Components | Auto Components & Equipments |\n|  |  |  | Tyres & Rubber Products |\n|  |  |  | Trading - Auto Components |\n|  | Consumer Durables | Consumer Durables | Cycles |\n|  |  |  | Consumer Electronics |\n|  |  |  | Furniture, Home Furnishing |\n|  |  |  | Ceramics |\n|  |  |  | Granites & Marbles |\n|  |  |  | Gems, Jewellery And Watches |\n|  |  |  | Glass - Consumer |\n|  |  |  | Household Appliances |\n|  |  |  | Houseware |\n|  |  |  | Leather And Leather Products |\n|  |  |  | Leisure Products |\n|  |  |  | Plastic Products - Consumer |\n|  |  |  | Plywood Boards/Laminates |\n|  |  |  | Sanitary Ware |\n|  |  |  | Paints |\n|  |  |  | Diversified consumer products |\n|  |  |  | Footwear |\n|  | Textiles | Textiles & Apparels | Garments & Apparels |\n|  |  |  | Other Textile Products |\n|  |  |  | Trading - Textile Products |\n|  | Media,Entertainment & Publication | Media | Advertising & Media Agencies |\n|  |  |  | Electronic Media |\n|  |  |  | Web based media and service |\n|  |  |  | Print Media |\n|  |  | Entertainment | Film Production,Distribution & Exhibition |\n|  |  |  | Digital Entertainment |\n|  |  |  | Media & Entertainment |\n|  |  |  | TV Broadcasting & Software Production |\n|  |  | Printing & Publication | Printing & Publication |\n|  | Realty | Realty | Residential,Commercial Projects |\n|  |  |  | Real Estate related services |\n|  |  |  | Real Estate Investment Trusts(REITs) |\n|  | Consumer Services | Leisure Services | Hotels & Resorts |\n|  |  |  | Restaurants |\n|  |  |  | Amusement Parks/Other Recreation |\n|  |  |  | Wellness |\n|  |  |  | Tour, Travel Related Services |\n|  |  | Other Consumer Services | Education |\n|  |  |  | E-Learning |\n|  |  |  | Food Storage Facilities |\n|  |  |  | Other Consumer Services |\n|  |  | Retailing | Speciality Retail  |\n|  |  |  | Pharmacy Retail |\n|  |  |  | Diversified Retail |\n|  |  |  | E-Retail/ ECommerce |\n|  |  |  | Internet & Catalogue Retail |\n|  |  |  | Distributors |\n| Energy | Oil, Gas & Consumable Fuels | Gas | Gas Transmission/Marketing |\n|  |  |  | LPG/CNG/PNG/LNG Supplier |\n|  |  |  | Trading - Gas |\n|  |  | Oil | Oil Exploration & Production |\n|  |  |  | Offshore Support Solution Drilling |\n|  |  |  | Oil Storage & Transportation |\n|  |  |  | Oil Equipment & Services |\n|  |  | Petroleum Products | Refineries & Marketing |\n|  |  |  | Lubricants |\n|  |  | Consumable Fuels | Coal |\n|  |  |  | Trading - Coal |\n| Fast Moving Consumer Goods | Fast Moving Consumer Goods | Agricultural Food & other Products | Edible Oil |\n|  |  |  | Sugar |\n|  |  |  | Tea & Coffee |\n|  |  |  | Other Agricultural Products |\n|  |  |  | Other Beverages |\n|  |  | Beverages | Breweries & Distilleries |\n|  |  | Cigarettes & Tobacco Products | Cigarettes & Tobacco Products |\n|  |  | Food Products | Animal Feed |\n|  |  |  | Dairy Products |\n|  |  |  | Other Food Products |\n|  |  |  | Packaged Foods |\n|  |  |  | Seafood |\n|  |  |  | Meat Products including Poultry |\n|  |  | Personal Products | Personal Care |\n|  |  | Household Products | Household Products |\n|  |  |  | Stationary |\n|  |  | Diversified FMCG | Diversified FMCG |\n| Financial Services | Financial Services | Finance | Financial Institution |\n|  |  |  | Housing Finance Company |\n|  |  |  | Investment Company |\n|  |  |  | Non Banking Financial Company (NBFC) |\n|  |  |  | Other Financial Services |\n|  |  |  | Holding Company |\n|  |  |  | Microfinance Institutions |\n|  |  |  | Securitisation |\n|  |  | Banks | Public Sector Bank |\n|  |  |  | Private Sector Bank |\n|  |  |  | Other Bank |\n|  |  | Capital Markets | Asset Management Company |\n|  |  |  | Depositories,Clearing Houses and Other Intermediaries |\n|  |  |  | Financial Products Distributor |\n|  |  |  | Ratings |\n|  |  |  | Exchange and Data Platform |\n|  |  |  | Stockbroking & Allied |\n|  |  |  | Other Capital Market related Services |\n|  |  | Insurance | General Insurance |\n|  |  |  | Life Insurance |\n|  |  |  | Other Insurance Companies |\n|  |  |  | Insurance Distributors |\n|  |  | Financial Technology (Fintech) | Financial Technology (Fintech) |\n| Healthcare | Healthcare | Pharmaceuticals & Biotechnology | Pharmaceuticals |\n|  |  |  | Biotechnology |\n|  |  | Healthcare Equipment & Supplies | Medical Equipment & Supplies |\n|  |  | Healthcare Services | Hospital |\n|  |  |  | Healthcare Service Provider |\n|  |  |  | Healthcare Research, Analytics & Technology |\n| Industrials | Construction | Construction | Civil Construction |\n|  | Capital Goods | Aerospace & Defense | Aerospace & Defense |\n|  |  | Agricultural,Commercial & Construction Vehicles | Tractors |\n|  |  |  | Commercial Vehicles |\n|  |  |  | Construction Vehicles |\n|  |  |  | Dealers-Commercial Vehicles, Tractors, Construction Vehicles |\n|  |  | Electrical Equipment | Heavy Electrical Equipment |\n|  |  |  | Other Electrical Equipment |\n|  |  | Industrial Manufacturing | Railway Wagons |\n|  |  |  | Ship Building & Allied Services |\n|  |  |  | Industrial Products |\n|  |  | Industrial Products | Cables - Electricals |\n|  |  |  | Castings & Forgings |\n|  |  |  | Packaging |\n|  |  |  | Plastic Products - Industrial |\n|  |  |  | Rubber |\n|  |  |  | Other Industrial Products |\n|  |  |  | Glass - Industrial |\n|  |  |  | Aluminium, Copper & Zinc Products |\n|  |  |  | Iron & Steel Products |\n|  |  |  | Abrasives & Bearings |\n|  |  |  | Compressors,Pumps & Diesel Engines |\n|  |  |  | Electrodes & Refractories |\n| Information Technology | Information Technology | IT - Software | Computers - Software & Consulting |\n|  |  |  | Software Products |\n|  |  | IT - Services | IT Enabled Services |\n|  |  | IT - Hardware | Computers Hardware & Equipments |\n| Services | Services | Engineering Services | Dredging |\n|  |  | Transport Services | Airline |\n|  |  |  | Logistics Solution Provider |\n|  |  |  | Railways |\n|  |  |  | Road Transport |\n|  |  |  | Shipping |\n|  |  |  | Transport Related Services |\n|  |  | Transport Infrastructure | Airport & Airport services |\n|  |  |  | Port & Port services |\n|  |  |  | Road Assets-Toll, Annuity, HybridAnnuity |\n|  |  | Commercial Services & Supplies | Trading & Distributors |\n|  |  |  | Consulting Services |\n|  |  |  | Data Processing Services |\n|  |  |  | Diversified Commercial Services |\n|  |  |  | Business Process Outsourcing (BPO)/ Knowledge Process Outsourcing (KPO) |\n|  |  | Public Services | Urban Local Bodies |\n|  |  |  | Development Authority |\n| Telecommunication | Telecommunication | Telecom - Services | Telecom - Cellular & Fixed line services |\n|  |  |  | Telecom - Infrastructure |\n|  |  |  | Other Telecom Services |\n|  |  | Telecom - Equipment & Accessories | Telecom - Equipment & Accessories |\n| Utilities | Power | Power | Power Generation |\n|  |  |  | Integrated Power Utilities |\n|  |  |  | Power Trading |\n|  |  |  | Power - Transmission |\n|  |  |  | Power Distribution |\n|  | Utilities | Other Utilities | Water Supply & Management |\n|  |  |  | Waste Management |\n|  |  |  | Emergency Services |\n|  |  |  | Multi Utilities |\n|  |  |  | Other Utilities |\n| Diversified | Diversified | Diversified | Diversified |\n\n\n## Available Screener Fields\n\nThe screener supports filtering instruments using various financial, technical, and fundamental data points. Use `client.get_screener_fields()` to get the complete list of available fields with their metadata.\n\n### Instrument Properties\n\n| Field | Description | Data Type | Supported Operations |\n|--- |--- |--- |--- |\n| `exchange` | Stock exchange where the instrument is traded | String | `$eq`, `$ne`, `$in`, `$nin`, `$like`, `$nlike`, `$ilike` |\n| `tradingSymbol` | Trading symbol of the instrument | String | `$eq`, `$ne`, `$in`, `$nin`, `$like`, `$nlike`, `$ilike` |\n| `macroEconomicSector` | Macro economic sector classification | String | `$eq`, `$ne`, `$in`, `$nin`, `$like`, `$nlike`, `$ilike` |\n| `sector` | Sector classification | String | `$eq`, `$ne`, `$in`, `$nin`, `$like`, `$nlike`, `$ilike` |\n| `industry` | Industry classification | String | `$eq`, `$ne`, `$in`, `$nin`, `$like`, `$nlike`, `$ilike` |\n| `basicIndustry` | Basic industry classification | String | `$eq`, `$ne`, `$in`, `$nin`, `$like`, `$nlike`, `$ilike` |\n| `indices` | List of indices the instrument belongs to | Array(String) | `$in`, `$nin` |\n| `issuedSize` | Total issued shares (listed shares count) | UInt64 | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `marketCap` | Market capitalization (issuedSize \u00d7 latest closing price) | Float64 | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `logMarketCap` | Logarithm of Market Capitalization | Nullable(Float64) | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Financial Data\n\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `reportDate` | Date of the financial report | Date | - | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `latestReportDate_daily` | Date of the latest financial report (daily derived) | Date | - | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `companyName` | Company name | String | - | `$eq`, `$ne`, `$like`, `$nlike`, `$ilike` |\n| `period` | Financial reporting period (Q1, Q2, Q3, Q4, FY) | String | - | `$eq`, `$ne`, `$in`, `$nin` |\n| `filingDate` | Date when the report was filed | Date | - | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `natureOfReport` | Type of financial report (Annual, Quarterly, etc.) | String | - | `$eq`, `$ne`, `$in`, `$nin` |\n| `auditedUnaudited` | Audited or Unaudited status of the financial report | String | - | `$eq`, `$ne`, `$in`, `$nin` |\n\n## Banking-Specific Metrics\n\n### Interest Income & Expense\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `interestEarnedQuarterly` | Interest Earned - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `interestEarnedAnnual` | Interest Earned - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `interestExpenseQuarterly` | Interest Expense - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `interestExpenseAnnual` | Interest Expense - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### NPA & Asset Quality\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `grossNpaRatioQuarterly` | Gross NPA Ratio - quarterly | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `grossNpaRatioAnnual` | Gross NPA Ratio - annual | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `netNpaRatioQuarterly` | Net NPA Ratio - quarterly | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `netNpaRatioAnnual` | Net NPA Ratio - annual | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `gnpaPct` | Gross Non-Performing Assets Percentage | Float | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Capital Adequacy\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `cet1RatioQuarterly` | CET1 Capital Ratio - quarterly | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `cet1RatioAnnual` | CET1 Capital Ratio - annual | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `tier1CapitalRatioQuarterly` | Tier 1 Capital Ratio - quarterly | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `tier1CapitalRatioAnnual` | Tier 1 Capital Ratio - annual | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `totalCapitalRatioQuarterly` | Total Capital Ratio - quarterly | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `totalCapitalRatioAnnual` | Total Capital Ratio - annual | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Banking Assets & Liabilities\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `advancesQuarterly` | Advances - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `advancesAnnual` | Advances - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `depositsQuarterly` | Deposits - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `depositsAnnual` | Deposits - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `investmentsQuarterly` | Investments - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `investmentsAnnual` | Investments - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `cashBankBalanceQuarterly` | Cash and Bank Balance - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `cashBankBalanceAnnual` | Cash and Bank Balance - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n## Balance Sheet Items\n\n### Fixed Assets\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `ppeQuarterly` | Property, Plant & Equipment - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `ppeAnnual` | Property, Plant & Equipment - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `goodwillQuarterly` | Goodwill - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `goodwillAnnual` | Goodwill - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `intangibleAssetsQuarterly` | Intangible Assets - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `intangibleAssetsAnnual` | Intangible Assets - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `cwipQuarterly` | Capital Work in Progress - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `cwipAnnual` | Capital Work in Progress - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `intangiblesUnderDevQuarterly` | Intangibles Under Development - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `intangiblesUnderDevAnnual` | Intangibles Under Development - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `investmentPropertyQuarterly` | Investment Property - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `investmentPropertyAnnual` | Investment Property - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Current Assets\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `inventoriesQuarterly` | Inventories - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `inventoriesAnnual` | Inventories - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `tradeReceivablesQuarterly` | Trade Receivables - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `tradeReceivablesAnnual` | Trade Receivables - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `otherReceivablesQuarterly` | Other Receivables - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `otherReceivablesAnnual` | Other Receivables - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `cashEquivalentsQuarterly` | Cash and Cash Equivalents - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `cashEquivalentsAnnual` | Cash and Cash Equivalents - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Total Assets & Equity\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `totalAssetsQuarterly` | Total Assets - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `totalAssetsAnnual` | Total Assets - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `totalEquityQuarterly` | Total Equity - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `totalEquityAnnual` | Total Equity - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `equityShareCapitalQuarterly` | Equity Share Capital - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `equityShareCapitalAnnual` | Equity Share Capital - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `totalLiabilitiesQuarterly` | Total Liabilities - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `totalLiabilitiesAnnual` | Total Liabilities - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n## Income Statement Items\n\n### Revenue & Income\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `revenueOperationsQuarterly` | Revenue from Operations - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `revenueOperationsAnnual` | Revenue from Operations - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `otherIncomeQuarterly` | Other Income - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `otherIncomeAnnual` | Other Income - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `totalIncomeQuarterly` | Total Income - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `totalIncomeAnnual` | Total Income - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `dividendIncomeQuarterly` | Dividend Income - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `dividendIncomeAnnual` | Dividend Income - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Expenses\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `materialCostQuarterly` | Material Cost - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `materialCostAnnual` | Material Cost - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `employeeExpenseQuarterly` | Employee Expenses - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `employeeExpenseAnnual` | Employee Expenses - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `financeCostsQuarterly` | Finance Costs - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `financeCostsAnnual` | Finance Costs - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `depreciationAmortisationQuarterly` | Depreciation & Amortisation - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `depreciationAmortisationAnnual` | Depreciation & Amortisation - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `otherExpensesQuarterly` | Other Expenses - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `otherExpensesAnnual` | Other Expenses - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `totalExpensesQuarterly` | Total Expenses - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `totalExpensesAnnual` | Total Expenses - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Profit & Loss\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `profitBeforeTaxQuarterly` | Profit Before Tax - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `profitBeforeTaxAnnual` | Profit Before Tax - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `currentTaxQuarterly` | Current Tax - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `currentTaxAnnual` | Current Tax - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `deferredTaxQuarterly` | Deferred Tax - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `deferredTaxAnnual` | Deferred Tax - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `taxExpenseQuarterly` | Tax Expense - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `taxExpenseAnnual` | Tax Expense - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `netProfitQuarterly` | Net Profit - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `netProfitAnnual` | Net Profit - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `ebitda` | Earnings Before Interest, Taxes, Depreciation, and Amortization | Nullable(Float64) | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n## Cash Flow Statement\n\n### Operating Activities\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `operatingCashFlowQuarterly` | Operating Cash Flow - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `operatingCashFlowAnnual` | Operating Cash Flow - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `netOperatingCashQuarterly` | Net Operating Cash - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `netOperatingCashAnnual` | Net Operating Cash - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Investing Activities\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `investingCashFlowQuarterly` | Investing Cash Flow - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `investingCashFlowAnnual` | Investing Cash Flow - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `netInvestingCashQuarterly` | Net Investing Cash - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `netInvestingCashAnnual` | Net Investing Cash - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `ppePurchasesQuarterly` | PPE Purchases - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `ppePurchasesAnnual` | PPE Purchases - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `ppeSaleProceedsQuarterly` | PPE Sale Proceeds - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `ppeSaleProceedsAnnual` | PPE Sale Proceeds - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `purchaseInvestmentsQuarterly` | Purchase of Investments - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `purchaseInvestmentsAnnual` | Purchase of Investments - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `saleInvestmentsQuarterly` | Sale of Investments - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `saleInvestmentsAnnual` | Sale of Investments - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Financing Activities\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `financingCashFlowQuarterly` | Financing Cash Flow - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `financingCashFlowAnnual` | Financing Cash Flow - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `netFinancingCashQuarterly` | Net Financing Cash - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `netFinancingCashAnnual` | Net Financing Cash - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `borrowingProceedsQuarterly` | Borrowing Proceeds - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `borrowingProceedsAnnual` | Borrowing Proceeds - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `borrowingRepaymentsQuarterly` | Borrowing Repayments - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `borrowingRepaymentsAnnual` | Borrowing Repayments - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `dividendsPaidQuarterly` | Dividends Paid - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `dividendsPaidAnnual` | Dividends Paid - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `shareIssueProceedsQuarterly` | Share Issue Proceeds - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `shareIssueProceedsAnnual` | Share Issue Proceeds - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `shareBuybackQuarterly` | Share Buyback - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `shareBuybackAnnual` | Share Buyback - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Net Cash Changes\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `netCashChangeQuarterly` | Net Cash Change - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `netCashChangeAnnual` | Net Cash Change - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `cashCashflowStmtQuarterly` | Cash from Cashflow Statement - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `cashCashflowStmtAnnual` | Cash from Cashflow Statement - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `freeCashFlow` | Free Cash Flow | Nullable(Float64) | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `netCash` | Net Cash Position | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n## NBFC-Specific Metrics\n\n### Revenue & Income\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `feesCommissionIncomeQuarterly` | Fees & Commission Income - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `feesCommissionIncomeAnnual` | Fees & Commission Income - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `fairValueGainsQuarterly` | Fair Value Gains - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `fairValueGainsAnnual` | Fair Value Gains - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `rentalIncomeQuarterly` | Rental Income - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `rentalIncomeAnnual` | Rental Income - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Expenses\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `feesCommissionExpenseQuarterly` | Fees & Commission Expense - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `feesCommissionExpenseAnnual` | Fees & Commission Expense - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `fairValueLossesQuarterly` | Fair Value Losses - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `fairValueLossesAnnual` | Fair Value Losses - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `impairmentFinancialInstrumentsQuarterly` | Impairment of Financial Instruments - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `impairmentFinancialInstrumentsAnnual` | Impairment of Financial Instruments - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### NBFC Assets\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `loansQuarterly` | Loans - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `loansAnnual` | Loans - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `otherFinancialAssetsQuarterly` | Other Financial Assets - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `otherFinancialAssetsAnnual` | Other Financial Assets - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n## Insurance-Specific Metrics\n\n### Premium Income\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `grossPremiumIncomeQuarterly` | Gross Premium Income - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `grossPremiumIncomeAnnual` | Gross Premium Income - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `netPremiumIncomeQuarterly` | Net Premium Income - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `netPremiumIncomeAnnual` | Net Premium Income - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Insurance Ratios\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `solvencyRatioQuarterly` | Solvency Ratio - quarterly | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `solvencyRatioAnnual` | Solvency Ratio - annual | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `expensesOfManagementRatioQuarterly` | Expenses of Management Ratio - quarterly | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `expensesOfManagementRatioAnnual` | Expenses of Management Ratio - annual | Float64 | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n## Financial Ratios\n\n### Valuation Ratios\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `peRatio` | Price-to-Earnings Ratio | Nullable(Float32) | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `pbRatio` | Price-to-Book Ratio | Nullable(Float32) | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `evEbitda` | Enterprise Value to EBITDA Ratio | Nullable(Float32) | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `fcfYield` | Free Cash Flow Yield | Nullable(Float32) | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Leverage Ratios\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `debtEquityRatioQuarterly` | Debt to Equity Ratio - quarterly | Float64 | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `debtEquityRatioAnnual` | Debt to Equity Ratio - annual | Float64 | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `debtEquity` | Debt to Equity Ratio | Float | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `debtServiceRatioQuarterly` | Debt Service Ratio - quarterly | Float64 | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `debtServiceRatioAnnual` | Debt Service Ratio - annual | Float64 | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `interestCoverageRatioQuarterly` | Interest Coverage Ratio - quarterly | Float64 | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `interestCoverageRatioAnnual` | Interest Coverage Ratio - annual | Float64 | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `interestCov` | Interest Coverage Ratio | Float | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Profitability Ratios\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `basicEpsQuarterly` | Basic EPS - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `basicEpsAnnual` | Basic EPS - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `dilutedEpsQuarterly` | Diluted EPS - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `dilutedEpsAnnual` | Diluted EPS - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `roe` | Return on Equity | Float | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `roa` | Return on Assets | Nullable(Float32) | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `patMargin` | Profit After Tax Margin | Float | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `grossMargin` | Gross Profit Margin | Nullable(Float32) | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `operatingMargin` | Operating Profit Margin | Nullable(Float32) | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `ebitMargin` | Earnings Before Interest and Taxes Margin | Nullable(Float32) | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Efficiency Ratios\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `assetTurnover` | Asset Turnover Ratio | Float | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `currentRatio` | Current Ratio | Float | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `ocfPat` | Operating Cash Flow to PAT Ratio | Float | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `ocfNetProfit` | Operating Cash Flow to Net Profit Ratio | Nullable(Float32) | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n## Technical Indicators\n\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `fiftyDayMA` | 50-Day Moving Average | Nullable(Float32) | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `hundredDayMA` | 100-Day Moving Average | Nullable(Float32) | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `twoHundredDayMA` | 200-Day Moving Average | Nullable(Float32) | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `rsi` | Relative Strength Index | Nullable(Float32) | index | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `macd` | Moving Average Convergence Divergence | Nullable(Float32) | index | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `macdSignal` | MACD Signal Line | Nullable(Float32) | index | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `bollingerUpper` | Bollinger Band Upper | Nullable(Float32) | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `bollingerLower` | Bollinger Band Lower | Nullable(Float32) | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `atr` | Average True Range | Nullable(Float32) | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `volumeRatio` | Volume Ratio | Nullable(Float32) | ratio | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `thirtyDayVolatility` | 30-Day Volatility | Nullable(Float32) | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `sixMMaxDrawdown` | Six Month Maximum Drawdown | Nullable(Float32) | % | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n## Segment Analysis\n\n### Segment Financial Data\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `segmentRevenueQuarterly` | Segment Revenue - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `segmentRevenueAnnual` | Segment Revenue - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `segmentProfitBeforeTaxQuarterly` | Segment Profit Before Tax - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `segmentProfitBeforeTaxAnnual` | Segment Profit Before Tax - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `segmentAssetsQuarterly` | Segment Assets - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `segmentAssetsAnnual` | Segment Assets - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `segmentLiabilitiesQuarterly` | Segment Liabilities - quarterly | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `segmentLiabilitiesAnnual` | Segment Liabilities - annual | Float64 | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Historical Market Data\n\n| Field | Description | Data Type | Unit | Supported Operations |\n|--- |--- |--- |--- |--- |\n| `hmdOpen` | Opening price of the trading session | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `hmdHigh` | Highest price during the trading session | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `hmdLow` | Lowest price during the trading session | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `hmdClose` | Closing price of the trading session | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `hmdLtp` | Last Traded Price | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `hmdPrevClose` | Previous day closing price | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `hmdVolume` | Trading volume (number of shares traded) | UInt64 | shares | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `hmdTurnover` | Trading turnover (total value of shares traded) | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `hmdTotalTrades` | Total number of trades executed | UInt64 | count | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `hmdPriceBandLower` | Lower price band limit | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `hmdPriceBandUpper` | Upper price band limit | Float | currency | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n| `hmdDate` | Trading date | Date | - | `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$between` |\n\n### Supported Operations\n\n- **Comparison**: `$eq` (equal), `$ne` (not equal), `$gt` (greater than), `$gte` (greater than or equal), `$lt` (less than), `$lte` (less than or equal)\n- **Range**: `$between` (between two values)\n- **Array**: `$in` (in array), `$nin` (not in array)\n- **Pattern**: `$like` (case-sensitive pattern), `$nlike` (case-sensitive not pattern), `$ilike` (case-insensitive pattern)\n- **Logical**: `$and` (all conditions must be true), `$or` (at least one condition must be true)\n\n### Example Usage\n\n```python\n# Get all available screener fields\nfields = client.get_screener_fields()\nprint(json.dumps(fields, indent=2))\n\n# Screen for high ROE companies in Finance sector\nresults = client.run_screener(\n    filters={\n        \"$and\": [\n            {\"sector\": {\"$eq\": \"Finance\"}},\n            {\"roe\": {\"$gt\": 0.15}}\n        ]\n    },\n    sort=[{\"roe\": -1}],\n    limit=10\n)\n```\n\n## KV Store Integration\n\nThe WizzerClient includes comprehensive Key-Value (KV) store functionality for persistent data management. This feature allows you to store configuration data, state information, user preferences, and other persistent data associated with your trading strategies.\n\n### Supported Data Types\n\nThe KV store supports all JSON-serializable data types:\n\n- **STRING**: Text values (`\"production\"`, `\"user123\"`)\n- **NUMBER**: Integer and float values (`42`, `150.25`)\n- **BOOLEAN**: True/false values (`True`, `False`)\n- **ARRAY**: Lists of values (`[\"AAPL\", \"GOOGL\", \"MSFT\"]`)\n- **OBJECT**: Dictionaries/objects (`{\"positions\": 30, \"cash\": 50000}`)\n\n### Available Constants\n\n```python\nclient.KV_TYPE_STRING   # \"string\"\nclient.KV_TYPE_NUMBER   # \"number\" \nclient.KV_TYPE_BOOLEAN  # \"boolean\"\nclient.KV_TYPE_ARRAY    # \"array\"\nclient.KV_TYPE_OBJECT   # \"object\"\n```\n\n### Core CRUD Operations\n\n#### Create Key-Value Pair\n\n```python\n# Store different data types\nclient.create_kv(\"environment\", \"production\")\nclient.create_kv(\"trade_count\", 42)\nclient.create_kv(\"is_active\", True)\nclient.create_kv(\"symbols\", [\"AAPL\", \"GOOGL\", \"MSFT\"])\n\n# Store complex configuration with TTL (expires in 1 hour)\nconfig = {\n    \"risk_level\": \"medium\",\n    \"max_positions\": 10,\n    \"stop_loss_pct\": 0.05,\n    \"take_profit_pct\": 0.15\n}\nclient.create_kv(\"strategy_config\", config, ttl=3600)\n```\n\n#### Retrieve Key-Value Pair\n\n```python\n# Get a single KV pair\ndata = client.get_kv(\"strategy_config\")\nprint(data[\"value\"])          # The stored object\nprint(data[\"type\"])           # \"object\"\nprint(data[\"ttl\"])            # Remaining time to live (if set)\n\n# Access nested values\nrisk_level = data[\"value\"][\"risk_level\"]  # \"medium\"\n```\n\n#### Update Key-Value Pair (Complete Replacement)\n\n```python\n# Complete replacement of existing key\nnew_config = {\"risk_level\": \"high\", \"max_positions\": 5}\nclient.update_kv(\"strategy_config\", new_config, ttl=1800)\n```\n\n#### Patch Key-Value Pair (Partial Update)\n\n```python\n# For objects - merges with existing data\nclient.patch_kv(\"strategy_config\", {\"last_updated\": \"2024-01-15\"})\n\n# For non-objects - replaces entirely  \nclient.patch_kv(\"trade_count\", 50)\n\n# Update only TTL\nclient.patch_kv(\"strategy_config\", ttl=7200)\n```\n\n#### Delete Key-Value Pair\n\n```python\nresponse = client.delete_kv(\"old_config\")\nif response[\"success\"]:\n    print(\"Key deleted successfully\")\n```\n\n### List Operations\n\n#### Get All KV Pairs (with values)\n\n```python\n# Get first page (20 items)\nkvs = client.get_all_kvs(page_no=1)\n\n# Get all pages automatically\nall_kvs = client.get_all_kvs(paginate=True)\n\nfor kv in all_kvs:\n    print(f\"Key: {kv['key']}\")\n    print(f\"Type: {kv['type']}\")\n    print(f\"Value: {kv['value']}\")\n```\n\n#### Get Keys Only (memory efficient)\n\n```python\n# Get all keys without values (faster for large datasets)\nkeys = client.get_kv_keys(paginate=True)\n\nfor key_info in keys:\n    print(f\"Key: {key_info['key']}, Type: {key_info['type']}\")\n    if 'ttl' in key_info:\n        print(f\"  TTL: {key_info['ttl']} seconds remaining\")\n```\n\n### Advanced Usage Examples\n\n#### Strategy Configuration Management\n\n```python\n# Store strategy parameters\nparams = {\n    \"moving_average_period\": 20,\n    \"rsi_oversold\": 30,\n    \"rsi_overbought\": 70,\n    \"position_size\": 0.02\n}\nclient.create_kv(\"strategy_params\", params)\n\n# Update specific parameters using patch (merges with existing)\nclient.patch_kv(\"strategy_params\", {\"moving_average_period\": 50})\n```\n\n#### State Persistence\n\n```python\n# Save current portfolio state\nportfolio_state = {\n    \"cash_balance\": 50000,\n    \"open_positions\": 5,\n    \"daily_pnl\": 1250.75,\n    \"last_updated\": \"2024-01-15T15:30:00Z\"\n}\nclient.create_kv(\"portfolio_state\", portfolio_state, ttl=3600)\n\n# Update state periodically\nclient.patch_kv(\"portfolio_state\", {\n    \"daily_pnl\": 1500.25,\n    \"last_updated\": \"2024-01-15T16:00:00Z\"\n})\n```\n\n#### Feature Flags\n\n```python\n# Enable/disable features dynamically\nfeatures = {\n    \"advanced_charts\": True,\n    \"paper_trading\": True,\n    \"options_trading\": False,\n    \"algo_trading\": True\n}\nclient.create_kv(\"feature_flags\", features)\n\n# Toggle a feature\nclient.patch_kv(\"feature_flags\", {\"options_trading\": True})\n```\n\n#### Data Caching with TTL\n\n```python\n# Cache market data with short TTL (5 minutes)\nmarket_status = {\n    \"nse_open\": True,\n    \"bse_open\": True,\n    \"last_checked\": \"2024-01-15T09:15:00Z\"\n}\nclient.create_kv(\"market_status\", market_status, ttl=300)\n```\n\n### Object Merge Behavior\n\nFor OBJECT type data, the `patch_kv` method performs intelligent merging:\n\n```python\n# Initial object\nclient.create_kv(\"user_prefs\", {\n    \"theme\": \"dark\",\n    \"notifications\": True,\n    \"language\": \"en\"\n})\n\n# Patch merges new fields with existing ones\nclient.patch_kv(\"user_prefs\", {\n    \"notifications\": False,  # Updates existing field\n    \"timezone\": \"UTC\"        # Adds new field\n})\n\n# Result: {\"theme\": \"dark\", \"notifications\": False, \"language\": \"en\", \"timezone\": \"UTC\"}\n```\n\n### Delete All KV Pairs\n\nThe `delete_all_kv` method allows you to remove all key-value pairs for a strategy at once:\n\n```python\n# Delete all KV pairs for the current strategy\nresponse = client.delete_all_kv()\nprint(f\"Deleted {response['deleted']} key-value pairs\")\n\n# Example response:\n# {\n#     \"success\": True,\n#     \"deleted\": 15,\n#     \"message\": \"Successfully deleted 15 key-value pairs\"\n# }\n\n# Common usage - reset strategy state before reinitialization\ndef reset_strategy_state():\n    \"\"\"Reset all persistent state for the strategy.\"\"\"\n    # Clear all existing KV pairs\n    result = client.delete_all_kv()\n    print(f\"Cleared {result['deleted']} KV pairs\")\n    \n    # Reinitialize with default configuration\n    client.create_kv(\"config\", {\n        \"mode\": \"production\",\n        \"risk_percentage\": 0.02,\n        \"max_positions\": 10\n    })\n    client.create_kv(\"state\", {\n        \"initialized\": True,\n        \"start_time\": datetime.now().isoformat()\n    })\n    print(\"Strategy state reset successfully\")\n\n# Use with caution - this operation cannot be undone!\n```\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A Python SDK for connecting to the Wizzer.",
    "version": "0.35.0",
    "project_urls": {
        "Bug Tracker": "https://bitbucket.org/wizzer-tech/quotes_sdk/issues",
        "Homepage": "https://bitbucket.org/wizzer-tech/quotes_sdk.git"
    },
    "split_keywords": [
        "finance",
        " trading",
        " sdk"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "54280ca39bb09777c20bba195f760a2b3cec6c75f7f112c66ff3a6b9766e2404",
                "md5": "7f3179fcdee7f387a5e01a00d1b078bc",
                "sha256": "305e0f3fd949571d6b4e34ca9f99d351a1cd0b9db317b2228f820c8a60316dce"
            },
            "downloads": -1,
            "filename": "wiz_trader-0.35.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7f3179fcdee7f387a5e01a00d1b078bc",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 53300,
            "upload_time": "2025-07-22T20:31:38",
            "upload_time_iso_8601": "2025-07-22T20:31:38.217785Z",
            "url": "https://files.pythonhosted.org/packages/54/28/0ca39bb09777c20bba195f760a2b3cec6c75f7f112c66ff3a6b9766e2404/wiz_trader-0.35.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "26849fc21ff1d93bbc3dda0ebfc458d2b46f7e1ad7f2262c47269e77286da57e",
                "md5": "0c0c5a026aa07604a518c672d87778f3",
                "sha256": "d1aa6dac8152bc15731de73a1f8490a9b3201276f4cd6808aff113eef4b034e7"
            },
            "downloads": -1,
            "filename": "wiz_trader-0.35.0.tar.gz",
            "has_sig": false,
            "md5_digest": "0c0c5a026aa07604a518c672d87778f3",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 116507,
            "upload_time": "2025-07-22T20:31:39",
            "upload_time_iso_8601": "2025-07-22T20:31:39.783267Z",
            "url": "https://files.pythonhosted.org/packages/26/84/9fc21ff1d93bbc3dda0ebfc458d2b46f7e1ad7f2262c47269e77286da57e/wiz_trader-0.35.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-22 20:31:39",
    "github": false,
    "gitlab": false,
    "bitbucket": true,
    "codeberg": false,
    "bitbucket_user": "wizzer-tech",
    "bitbucket_project": "quotes_sdk",
    "lcname": "wiz-trader"
}
        
Elapsed time: 0.45898s