Skip to main content

A Python SDK for connecting to the Wizzer.

Project description

WizTrader SDK Documentation

Table of Contents

  1. Introduction
  2. Installation
  3. Authentication
  4. Quotes Client
  5. Wizzer Client
  6. Common Use Cases
  7. Error Handling
  8. Troubleshooting
  9. 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:

pip install wiz_trader

To install the development version from GitHub:

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:

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:

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:

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:

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:

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:

client.connect()

Non‑Blocking Connection

Run alongside your own asyncio code:

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
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:

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.

# 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

Account Events

The QuotesClient now supports automatic reception of account-related events (orders, trades, positions, holdings) from the quotes server. These events are automatically pushed to SDK users via dedicated callback handlers based on the event type.

Event Handlers

Register event handlers to receive real-time updates for your account activity:

def on_order(ws, order):
    print(f"Order event: {order}")

def on_trade(ws, trade):
    print(f"Trade event: {trade}")

def on_position(ws, position):
    print(f"Position event: {position}")

def on_holding(ws, holding):
    print(f"Holding event: {holding}")

# Register event handlers
client.on_order = on_order
client.on_trade = on_trade
client.on_position = on_position
client.on_holding = on_holding

Key Features

  • Automatic Event Reception: No explicit subscription needed - events are automatically sent based on your JWT token's account ID and strategy ID
  • Optional Handlers: Events are silently dropped if no handler is registered - you only receive what you need
  • Message Normalization: The SDK automatically handles different message formats and delivers clean, flattened event data to your handlers
  • Error Resilience: Handler exceptions are caught and logged without breaking the event flow
  • Backward Compatible: Existing tick and Greeks functionality remains unchanged

Event Data Structure

All event handlers receive flattened event data with the event type preserved:

# Example order event data
{
    "_id": "order_01k10np7weemkv812nx55bppw5",
    "accountEntityType": "client",
    "accountId": "user_01j9brznsffphvzqn9gzyj1frw",
    "avgPrice": 72.65,
    "broker": "wizzer",
    "brokerOrderId": "dssorder_175344314711184",
    "brokerTimestamp": "2025-07-25T11:32:28.147Z",
    "cancelledQty": 0,
    "completedAt": "2025-07-25T11:32:28.147Z",
    "createdAt": "2025-07-25T11:32:27.722Z",
    "disclosedQty": 0,
    "exchange": "NSE",
    "exchangeOrderId": "dssx_1753443147",
    "exchangeToken": 11184,
    "exchangeUpdateTimestamp": "2025-07-25T11:32:28.147Z",
    "executionType": "regular",
    "filledQty": 1,
    "guid": "t0lVueivgBgcEh2k_BP",
    "instrumentType": "EQLC",
    "isDealer": false,
    "isOrderModified": false,
    "legs": [],
    "marginUsed": 0,
    "meta": {
        "dss": {"orderId": "order_01k10np7weemkv812nx55bppw5"},
        "source": "wizzer.dss",
        "wizzer": {"mode": "paper_trading"}
    },
    "orderType": "MARKET",
    "parentOrderId": "",
    "pendingQty": 1,
    "placedBy": "user_01j9brznsffphvzqn9gzyj1frw",
    "price": 0,
    "product": "CNC",
    "qty": 1,
    "remarks": "",
    "segment": "NSECM",
    "slPrice": 0,
    "slTriggerPrice": 0,
    "sqOffHoldingId": "",
    "sqOffPositionId": "",
    "status": "COMPLETED",
    "stoploss": 0,
    "stoplossOrderId": "",
    "strategy": {
        "id": "stgy_01jtn7t3erf8ss78spqy40k8en",
        "identifier": "S-608377",
        "name": "Test 1122"
    },
    "target": 0,
    "targetOrderId": "",
    "tradingSymbol": "IDFCFIRSTB",
    "transactionType": "BUY",
    "triggerId": "",
    "triggerPrice": 0,
    "updatedAt": "2025-07-25T11:32:28.254Z",
    "userId": "user_01j9brznsffphvzqn9gzyj1frw",
    "validity": "DAY",
    "variety": "REGULAR"
}

# Example trade event data
{
    "_id": "trade_01k10np8rqef793zr93ctqj0wt",
    "accountId": "user_01j9brznsffphvzqn9gzyj1frw",
    "avgPrice": 72.65,
    "broker": "wizzer",
    "brokerOrderId": "dssorder_175344314711184",
    "createdAt": "2025-07-25T11:32:28.567Z",
    "exchange": "NSE",
    "exchangeOrderId": "dssx_1753443147",
    "exchangeTimestamp": "2025-07-25T11:32:28.147Z",
    "exchangeToken": 11184,
    "isDividend": false,
    "meta": {
        "dss": {"orderId": "order_01k10np7weemkv812nx55bppw5"},
        "source": "wizzer.dss",
        "wizzer": {"mode": "paper_trading"}
    },
    "orderId": "order_01k10np7weemkv812nx55bppw5",
    "orderType": "MARKET",
    "parentOrderId": "",
    "parentTradeId": "",
    "product": "CNC",
    "qty": 1,
    "segment": "NSECM",
    "strategy": {
        "id": "stgy_01jtn7t3erf8ss78spqy40k8en",
        "identifier": "S-608377",
        "name": "Test 1122"
    },
    "tradeId": "dsstrade_50PccSfWvsCg-Cr5dQE",
    "tradingSymbol": "IDFCFIRSTB",
    "transactionType": "BUY",
    "updatedAt": "2025-07-25T11:32:28.567Z",
    "userId": "user_01j9brznsffphvzqn9gzyj1frw"
}

# Example position event data
{
    "_id": "pos_01k10np8t7e0fs63q52hacbx8m",
    "accountEntityType": "client",
    "accountId": "user_01j9brznsffphvzqn9gzyj1frw",
    "bep": 0,
    "broker": "wizzer",
    "buyAvgPrice": 72.65,
    "buyOrders": ["order_01k10np7weemkv812nx55bppw5"],
    "buyQty": 1,
    "buyTrades": ["trade_01k10np8rqef793zr93ctqj0wt"],
    "buyValue": 72.65,
    "closePrice": 0,
    "createdAt": "2025-07-25T11:32:28.614Z",
    "exchange": "NSE",
    "exchangeToken": 11184,
    "instrumentType": "EQLC",
    "lotSize": 1,
    "meta": {
        "source": "wizzer.dss",
        "wizzer": {"mode": "paper_trading"}
    },
    "netQty": 1,
    "pnlPercentage": 0,
    "product": "CNC",
    "realisedPnlToday": 0,
    "segment": "NSECM",
    "sellAvgPrice": 0,
    "sellOrders": [],
    "sellQty": 0,
    "sellTrades": [],
    "sellValue": 0,
    "slPrice": null,
    "slTriggerPrice": null,
    "status": "open",
    "stoploss": 0,
    "strategy": {
        "id": "stgy_01jtn7t3erf8ss78spqy40k8en",
        "identifier": "S-608377",
        "name": "Test 1122"
    },
    "target": 0,
    "tradingSymbol": "IDFCFIRSTB",
    "unrealisedPnlToday": 0,
    "updatedAt": "2025-07-25T11:32:28.614Z",
    "userId": "user_01j9brznsffphvzqn9gzyj1frw"
}

# Example holding event data
{
    "_id": "holding_01k10np8t7e0fs63q52hacbx8m",
    "accountEntityType": "client",
    "accountId": "user_01j9brznsffphvzqn9gzyj1frw",
    "bep": 0,
    "broker": "wizzer",
    "buyAvgPrice": 72.65,
    "buyOrders": ["order_01k10np7weemkv812nx55bppw5"],
    "buyQty": 1,
    "buyTrades": ["trade_01k10np8rqef793zr93ctqj0wt"],
    "buyValue": 72.65,
    "closePrice": 0,
    "createdAt": "2025-07-25T11:32:28.614Z",
    "exchange": "NSE",
    "exchangeToken": 11184,
    "instrumentType": "EQLC",
    "lotSize": 1,
    "meta": {
        "source": "wizzer.dss",
        "wizzer": {"mode": "paper_trading"}
    },
    "netQty": 1,
    "pnlPercentage": 0,
    "product": "CNC",
    "realisedPnlToday": 0,
    "segment": "NSECM",
    "sellAvgPrice": 0,
    "sellOrders": [],
    "sellQty": 0,
    "sellTrades": [],
    "sellValue": 0,
    "slPrice": null,
    "slTriggerPrice": null,
    "status": "open",
    "stoploss": 0,
    "strategy": {
        "id": "stgy_01jtn7t3erf8ss78spqy40k8en",
        "identifier": "S-608377",
        "name": "Test 1122"
    },
    "target": 0,
    "tradingSymbol": "IDFCFIRSTB",
    "unrealisedPnlToday": 0,
    "updatedAt": "2025-07-25T11:32:28.614Z",
    "userId": "user_01j9brznsffphvzqn9gzyj1frw"
}

Complete Event Handling Example

from wiz_trader import QuotesClient

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

def on_order(ws, order):    
    # React to order status changes
    if order['status'] == ORDER_STATUS_COMPLETED:
        print(f"Order {order['_id']} completed!")
    elif order['status'] == ORDER_STATUS_REJECTED:
        print(f"Order {order['_id']} rejected: {order.get('remarks', 'Unknown')}")

def on_trade(ws, trade):
    print(f"Trade executed: {trade['qty']} x {trade['tradingSymbol']} @ {trade['avgPrice']}")

def on_position(ws, position):
    print(f"Position update: {position['tradingSymbol']} = {position['netQty']} (PnL: {position.get('unrealisedPnlToday', 0)})")

def on_holding(ws, holding):
    print(f"Holding update: {holding['tradingSymbol']} = {holding['netQty']}")

def on_connect(ws):
    print("Connected! Ready to receive events.")
    # Also subscribe to some ticks if needed
    ws.subscribe(["NSE:SBIN:3045"], mode="ticks")

# Register all handlers
client.on_order = on_order
client.on_trade = on_trade
client.on_position = on_position
client.on_holding = on_holding
client.on_connect = on_connect

# Connect and receive events
client.connect()

Event-Driven Trading Strategy Example

class EventDrivenStrategy:
    def __init__(self):
        self.orders = {}
        self.positions = {}
        self.pending_orders = set()
    
    def on_order_event(self, ws, order):
        order_id = order['_id']
        self.orders[order_id] = order
        
        # Track pending orders
        if order['status'] == ORDER_STATUS_OPEN:
            self.pending_orders.add(order_id)
        elif order_id in self.pending_orders:
            self.pending_orders.remove(order_id)
        
        # Log order lifecycle
        print(f"Order {order_id}: {order['status']}")
        
        # React to rejections
        if order['status'] == ORDER_STATUS_REJECTED:
            print(f"Order rejected! Reason: {order.get('remarks', 'Unknown')}")
            # Implement retry logic or alternative strategy
    
    def on_position_event(self, ws, position):
        symbol = position['tradingSymbol']
        self.positions[symbol] = position
        
        # Monitor position changes
        print(f"Position {symbol}: Qty={position['netQty']}, PnL={position.get('unrealisedPnlToday', 0)}")
        
        # Implement stop-loss or take-profit logic
        pnl = position.get('unrealisedPnlToday', 0)
        if pnl < -100:  # Stop loss at -100
            print(f"Stop loss triggered for {symbol}")
            # Place exit order
        elif pnl > 200:  # Take profit at 200
            print(f"Take profit triggered for {symbol}")
            # Place exit order
    
    def on_trade_event(self, ws, trade):
        print(f"Trade executed: {trade['qty']} @ {trade['avgPrice']}")
        # Update internal trade log, calculate VWAP, etc.

# Initialize strategy
strategy = EventDrivenStrategy()

# Set up client with strategy handlers
client = QuotesClient(base_url="wss://...", token="...")
client.on_order = strategy.on_order_event
client.on_position = strategy.on_position_event
client.on_trade = strategy.on_trade_event

client.connect()

Corporate Events

The QuotesClient supports automatic reception of corporate events from the server. These include corporate actions (dividends, stock splits, bonus issues) and corporate announcements (earnings reports, AGM notices, company announcements).

Corporate Event Handlers

from wiz_trader import QuotesClient

def handle_corporate_action(client, event):
    """Handle corporate actions like dividends, splits, bonus issues"""
    print(f"Corporate Action: {event['data']['eventText']}")
    print(f"Symbol: {event['data']['tradingSymbol']}")
    print(f"Date: {event['data']['date']}")
    
    # Handle specific action categories
    action_category = event['data'].get('actionCategory', '').lower()
    if action_category == 'dividend':
        amount = event['data'].get('primaryAmount')
        print(f"Dividend Amount: ₹{amount} per share")
    elif action_category == 'split':
        print(f"Stock Split - Face Value Change from ₹{event['data'].get('oldFaceValue')} to ₹{event['data'].get('newFaceValue')}")
    elif action_category == 'bonus':
        ratio_num = event['data'].get('ratioNumerator')
        ratio_den = event['data'].get('ratioDenominator')
        if ratio_num and ratio_den:
            print(f"Bonus Shares: {ratio_num}:{ratio_den} ratio")

def handle_corporate_announcement(client, event):
    """Handle corporate announcements like earnings, AGM notices"""
    print(f"Announcement: {event['data']['announcement']}")
    print(f"Symbol: {event['data']['tradingSymbol']}")
    print(f"Date: {event['data']['date']}")
    print(f"Event Description: {event['data']['eventsDescriptions']}")
    
    # Check for attachment file
    if 'attachmentFile' in event['data']:
        print(f"Attachment: {event['data']['attachmentFile']}")

# Register corporate event handlers
client.on_corporate_action = handle_corporate_action
client.on_corporate_announcement = handle_corporate_announcement

Corporate Event Types

Corporate Actions (type: 'events.corporate.actions'):

  • Dividends: Cash dividends, special dividends
  • Stock Splits: Forward splits, reverse splits
  • Bonus Issues: Bonus share distributions
  • Rights Issues: Rights share offerings
  • Mergers & Acquisitions: Corporate restructuring events

Corporate Announcements (type: 'events.corporate.announcements'):

  • Earnings Reports: Quarterly and annual results
  • AGM/EGM Notices: Annual and extraordinary general meetings
  • Board Meetings: Board meeting announcements
  • Company Updates: Material announcements, regulatory filings

Example Event Data Structures

Corporate Action Example:

{
    "data": {
        "actionCategory": "dividend",
        "actionSubcategory": "",
        "assetClass": "sme",
        "date": "19-08-2025",
        "eventText": "DIVIDEND - RS 2 PER SHARE",
        "events": "corporate_actions.other_corporate_action",
        "eventsDescriptions": "OTHER CORPORATE ACTION",
        "faceValue": 10,
        "hasAgm": false,
        "hasBonus": false,
        "hasDividend": true,
        "newFaceValue": null,
        "oldFaceValue": null,
        "percentageValue": null,
        "primaryAmount": 2,
        "ratioDenominator": null,
        "ratioNumerator": null,
        "secondaryAmount": null,
        "series": "SM",
        "tradingSymbol": "SBIN"
    },
    "timestamp": "2025-08-19T19:04:47.789Z",
    "type": "events.corporate.actions"
}

Corporate Announcement Example:

{
    "data": {
        "announcement": "Manglam Infra & Engineering Limited has informed the Exchange about award of Additional Work from BRO under Project Deepak, Himachal Pradesh.",
        "assetClass": "sme",
        "attachmentFile": "https://nsearchives.nseindia.com/corporate/MANGLAMINFRA_19082025133231_addition.pdf",
        "date": "19-08-2025",
        "events": "corporate_announcements.general_updates",
        "eventsDescriptions": "General Updates",
        "hasXbrl": false,
        "industry": "",
        "tradingSymbol": "SBIN"
    },
    "timestamp": "2025-08-19T19:04:30.511Z",
    "type": "events.corporate.announcements"
}

Complete Corporate Events Example

from wiz_trader import QuotesClient
from datetime import datetime

# Initialize client
client = QuotesClient(
    base_url="url",
    token="your-jwt-token",
    log_level="info"
)

def handle_corporate_action(client, event):
    """Comprehensive corporate action handler"""
    print(f"\n🏢 CORPORATE ACTION - {datetime.now()}")
    data = event.get('data', {})
    
    print(f"Symbol: {data.get('tradingSymbol')}")
    print(f"Action: {data.get('eventText')}")
    print(f"Date: {data.get('date')}")
    print(f"Event: {data.get('eventsDescriptions')}")
    print(f"Asset Class: {data.get('assetClass')}")
    print(f"Face Value: ₹{data.get('faceValue')}")
    
    # Action-specific handling based on actionCategory
    action_category = data.get('actionCategory', '').lower()
    if action_category == 'dividend' and data.get('hasDividend'):
        amount = data.get('primaryAmount')
        print(f"💰 Dividend: ₹{amount} per share")
        # Implement dividend tracking logic
    elif action_category == 'bonus' and data.get('hasBonus'):
        ratio_num = data.get('ratioNumerator')
        ratio_den = data.get('ratioDenominator')
        if ratio_num and ratio_den:
            print(f"🎁 Bonus Shares: {ratio_num}:{ratio_den} ratio")
        # Update portfolio for bonus shares
    elif action_category == 'split':
        old_fv = data.get('oldFaceValue')
        new_fv = data.get('newFaceValue')
        if old_fv and new_fv:
            print(f"📊 Stock Split: Face value changed from ₹{old_fv} to ₹{new_fv}")
        # Adjust position quantities

def handle_corporate_announcement(client, event):
    """Comprehensive corporate announcement handler"""
    print(f"\n📢 CORPORATE ANNOUNCEMENT - {datetime.now()}")
    data = event.get('data', {})
    
    print(f"Symbol: {data.get('tradingSymbol')}")
    print(f"Announcement: {data.get('announcement')}")
    print(f"Date: {data.get('date')}")
    print(f"Event: {data.get('eventsDescriptions')}")
    print(f"Asset Class: {data.get('assetClass')}")
    
    # Check for attachment file
    if 'attachmentFile' in data:
        print(f"📎 Attachment: {data['attachmentFile']}")
    
    # Event-specific handling based on events field
    events = data.get('events', '').lower()
    if 'earnings' in events or 'results' in events:
        print("📈 Earnings/Results announcement detected")
        # Implement earnings analysis
    elif 'general_updates' in events:
        print("📋 General company update")
        # Handle general announcements

# Register handlers
client.on_corporate_action = handle_corporate_action
client.on_corporate_announcement = handle_corporate_announcement

# Optional: Subscribe to market data as well
instruments = ["NSE:RELIANCE-EQ", "NSE:TCS-EQ"]
client.subscribe(instruments, mode="ticks")

# Start listening for events
client.connect()

Complete Examples

Blocking Example

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

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
{
  "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:

{
  "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:

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:

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
  • Order status: ORDER_STATUS_OPEN, ORDER_STATUS_CANCELLED, ORDER_STATUS_REJECTED, ORDER_STATUS_PENDING, ORDER_STATUS_COMPLETED
  • 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:

# 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:

# 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.

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

List Classification Values

Retrieve all values for a specific classification type.

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)
# 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.

# 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.

# 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.

# 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.

get_screener_fields()

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

# 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.

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

    client.run_screener(filters={"exchange": {"$eq": "NSE"}})
    
  3. Find all instruments with a Return on Equity (ROE) greater than 15%.

    client.run_screener(filters={"roe": {"$gt": 0.15}})
    
Set and Range Operators
  1. Find all instruments in the 'Energy' or 'Healthcare' sectors.

    client.run_screener(filters={"sector": {"$in": ["Energy", "Healthcare"]}})
    
  2. Find instruments with a PAT Margin between 5% and 10%.

    client.run_screener(filters={"patMargin": {"$between": [0.05, 0.10]}})
    
Pattern Matching
  1. Find all instruments with 'Bank' in their name (case-insensitive).
    client.run_screener(filters={"companyName": {"$ilike": "%bank%"}})
    
Logical Combinations
  1. Find instruments in the 'IT' sector with a ROE greater than 20%.

    client.run_screener(
        filters={
            "$and": [
                {"sector": {"$eq": "Information Technology"}},
                {"roe": {"$gt": 0.20}}
            ]
        }
    )
    
  2. 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.

    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
  1. Find the top 10 companies by highest ROE.

    client.run_screener(
        filters={},
        sort=[{"roe": -1}],
        limit=10
    )
    
  2. Find companies in the 'Pharmaceuticals' sector, sort them by the highest PAT margin, and then by the lowest Debt-to-Equity ratio.

    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 raw per-trade ticks all the way to monthly aggregated data.

Supported Intervals

Tick & Sub-minute Intervals

  • 1t - Raw per-trade ticks (every individual trade event, with full market depth)
  • 1s - 1-second OHLCV bars aggregated from raw ticks

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, Second and Tick Intervals

  • Format: YYYY-MM-DD HH:MM:SS
  • Example: "2024-01-15 09:15:00"

Tick-Only Fields (1t interval only)

When using INTERVAL_1_TICK, you can request the following extra fields in addition to standard OHLCV. These fields are not available for any aggregated interval (1s, 1m, … 1M).

Field Description
ltp Last traded price at this tick
lastTradedQty Quantity of the individual trade that triggered this tick
buyQty Cumulative buy quantity in the order book
sellQty Cumulative sell quantity in the order book
avgPrice Volume-weighted average price for the day
netChange Net price change from previous close
bidsPrices List of 5 bid prices (market depth)
bidsVolumes List of 5 bid volumes
bidsOrders List of 5 bid order counts
offersPrices List of 5 ask/offer prices
offersVolumes List of 5 ask/offer volumes
offersOrders List of 5 ask/offer order counts

Use client.TICK_FIELDS to access the full list programmatically.

Using Constants

The client provides constants for all intervals:

from wiz_trader import WizzerClient

client = WizzerClient(...)

# Tick & sub-minute intervals
client.INTERVAL_1_TICK       # "1t"  — raw per-trade ticks
client.INTERVAL_1_SECOND     # "1s"  — 1-second OHLCV bars

# 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"

# All tick-only field names (only valid for INTERVAL_1_TICK)
client.TICK_FIELDS
# ['ltp', 'lastTradedQty', 'buyQty', 'sellQty', 'avgPrice', 'netChange',
#  'bidsPrices', 'bidsVolumes', 'bidsOrders', 'offersPrices', 'offersVolumes', 'offersOrders']

Usage Examples

1. Raw tick data with full market depth

# Get the last 50 ticks for a stock with complete market depth
tick_data = client.get_historical_ohlcv(
    instruments=["NSE:SBIN:3045"],
    ohlcv=["ltp", "lastTradedQty", "buyQty", "sellQty", "volume",
           "avgPrice", "netChange", "open", "high", "low", "close",
           "bidsPrices", "bidsVolumes", "bidsOrders",
           "offersPrices", "offersVolumes", "offersOrders"],
    interval=client.INTERVAL_1_TICK,
    candles=50,
    end_date="2026-06-04",
)

# Each tick in response:
# {
#   "date": "2026-06-04 09:15:00.123",  # millisecond precision
#   "ltp": 972.20,
#   "lastTradedQty": 25,
#   "buyQty": 1871661, "sellQty": 374492,
#   "volume": 27943629,
#   "avgPrice": 948.56, "netChange": 15.55,
#   "open": 953.75, "high": 974.0, "low": 937.2, "close": 956.65,
#   "bidsPrices": [971.55, 971.50, 971.30, 971.25, 971.20],
#   "bidsVolumes": [70, 419, 99, 1, 2],
#   "bidsOrders": [1, 3, 2, 1, 1],
#   "offersPrices": [972.20, 972.50, 972.90, 972.95, 973.00],
#   "offersVolumes": [59, 45, 986, 95, 6170],
#   "offersOrders": [1, 2, 4, 2, 8]
# }

2. Tick data for a specific time window

# Get all ticks in the first 30 seconds of market open
tick_window = client.get_historical_ohlcv(
    instruments=["NSE:WIPRO:3787"],
    ohlcv=["ltp", "lastTradedQty", "volume", "bidsPrices", "offersPrices"],
    interval=client.INTERVAL_1_TICK,
    start_date="2026-06-04 09:15:00",
    end_date="2026-06-04 09:15:30",
)

3. Per-second OHLCV bars

# Get 1-second bars for precise entry/exit analysis
second_data = client.get_historical_ohlcv(
    instruments=["NSE:SBIN:3045"],
    ohlcv=["open", "high", "low", "close", "volume"],
    interval=client.INTERVAL_1_SECOND,
    candles=100,
    end_date="2026-06-04",
)

# Each bar in response:
# {
#   "date": "2026-06-04 09:15:01.000",
#   "open": 971.50, "high": 972.15, "low": 971.50, "close": 971.50,
#   "volume": 689
# }

4. Get 5-minute intraday data

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

5. Get 1-minute data using candles mode

# Get last 100 one-minute candles (no start_date needed)
scalping_data = client.get_historical_ohlcv(
    instruments=["NSE:RELIANCE:2885", "NSE:TCS:2953"],
    ohlcv=["open", "high", "low", "close", "volume"],
    interval=client.INTERVAL_1_MINUTE,
    candles=100,
    end_date="2024-01-15",
)

6. Get hourly data for swing trading

hourly_data = client.get_historical_ohlcv(
    instruments=["NSE:NIFTY 50:26000"],
    ohlcv=["open", "high", "low", "close", "volume"],
    interval=client.INTERVAL_1_HOUR,
    start_date="2024-01-15 09:15:00",
    end_date="2024-01-19 15:30:00",
)

7. Get daily data

daily_data = client.get_historical_ohlcv(
    instruments=["NSE:SBIN:3045"],
    ohlcv=["open", "high", "low", "close", "volume"],
    interval=client.INTERVAL_1_DAY,
    start_date="2024-01-01",
    end_date="2024-01-31",
)

8. Get monthly data for long-term analysis

monthly_data = client.get_historical_ohlcv(
    instruments=["NSE:SBIN:3045"],
    ohlcv=["close", "volume"],
    interval=client.INTERVAL_1_MONTH,
    start_date="2023-01-01",
    end_date="2023-12-31",
)

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

# Continuous futures across contract months
continuous_futures = client.get_historical_ohlcv(
    instruments=["NSE:SBIN25MAYFUT:57515"],
    ohlcv=["close", "oi"],
    interval=client.INTERVAL_1_DAY,
    start_date="2023-01-01",
    end_date="2024-12-31",
    continuous=True,
)

Response Structure

For Tick Interval (1t)

{
  "instrument": {
    "exchange": "NSE",
    "tradingSymbol": "SBIN",
    "exchangeToken": 3045,
    "identifier": "NSE:SBIN:3045"
  },
  "data": [
    {
      "date": "2026-06-04 09:15:00.123",
      "ltp": 972.20,
      "lastTradedQty": 25,
      "buyQty": 1871661,
      "sellQty": 374492,
      "volume": 27943629,
      "avgPrice": 948.56,
      "netChange": 15.55,
      "open": 953.75,
      "high": 974.0,
      "low": 937.2,
      "close": 956.65,
      "oi": 0,
      "bidsPrices": [971.55, 971.50, 971.30, 971.25, 971.20],
      "bidsVolumes": [70, 419, 99, 1, 2],
      "bidsOrders": [1, 3, 2, 1, 1],
      "offersPrices": [972.20, 972.50, 972.90, 972.95, 973.00],
      "offersVolumes": [59, 45, 986, 95, 6170],
      "offersOrders": [1, 2, 4, 2, 8]
    }
  ]
}

For Second Interval (1s)

{
  "instrument": { "identifier": "NSE:SBIN:3045", "..." : "..." },
  "data": [
    {
      "date": "2026-06-04 09:15:01.000",
      "open": 971.50,
      "high": 972.15,
      "low": 971.50,
      "close": 971.50,
      "volume": 689,
      "oi": 0
    }
  ]
}

For Daily/Monthly Intervals

{
  "instrument": { "identifier": "NSE:SBIN:3045", "...": "..." },
  "data": [
    {
      "date": "2024-01-15",
      "open": 750.0,
      "high": 765.0,
      "low": 745.0,
      "close": 760.0,
      "volume": 1000000
    }
  ]
}

For Intraday Intervals (1m1h)

{
  "instrument": { "identifier": "NSE:SBIN:3045", "...": "..." },
  "data": [
    {
      "date": "2024-01-15 09:15:00",
      "open": 750.0,
      "high": 752.0,
      "low": 749.0,
      "close": 751.0,
      "volume": 50000
    }
  ]
}

Advanced Usage Examples

Multiple Timeframe Analysis

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

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

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

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:

# 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:

# 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:

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

Get Order Details

Fetch details of a specific order:

# 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:

# 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:

# 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:

# 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:

# 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:

# 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:

# 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:

# 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:

# 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:

# 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:

[
    {
        # 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:

# 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:

{
  "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:

client.OPTION_TYPE_CE  # Call option
client.OPTION_TYPE_PE  # Put option

Moneyness Types:

client.MONEYNESS_ATM  # At-the-money
client.MONEYNESS_ITM  # In-the-money
client.MONEYNESS_OTM  # Out-of-the-money

Expiry Preferences:

# 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:

# 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:

{
    # 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
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
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:

# 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:

[
    {
        # 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

Analytics API

The Analytics API provides comprehensive financial analysis and market data tools for stocks and indices. It includes fundamentals analysis, valuation metrics, returns calculation, market data, ownership analysis, metrics, and macro data.

Fundamentals Analysis

Get key financial metrics and ratios for stocks:

# Net Profit Margin
margin = client.get_net_profit_margin("INFY", period="quarterly", quarter="Q1FY24")
print(f"Net Profit Margin: {margin['netProfitMargin']}%")

# Return on Equity (ROE)
roe = client.get_roe("TCS", period="annual", consolidated=True)
print(f"ROE: {roe['roe']}%")

# Return on Assets (ROA)
roa = client.get_roa("WIPRO", period="annual", consolidated=True)
print(f"ROA: {roa['roa']}%")

# EBIT Margin
ebit = client.get_ebit_margin("INFY", period="annual", consolidated=True)
print(f"EBIT Margin: {ebit['ebitMargin']}%")

# Operating Cash Flow to Net Profit Ratio
ocf_ratio = client.get_ocf_netprofit_ratio("TCS", period="annual")
print(f"OCF/Net Profit Ratio: {ocf_ratio['ocfNetprofitRatio']}")

# EPS CAGR (Compound Annual Growth Rate)
eps_cagr = client.get_eps_cagr("INFY", start_year=2019, end_year=2023)
print(f"EPS CAGR (2019-2023): {eps_cagr['epsCagr']}%")

# Book to Market Ratio
btm = client.get_book_to_market("NSE:INFY", as_of="2024-03-31")
print(f"Book to Market: {btm['bookToMarket']}")

# Market Cap to Sales Ratio
mts = client.get_marketcap_to_sales("RELIANCE", as_of="2024-03-31")
print(f"Market Cap to Sales: {mts['marketcapToSales']}")

# Cash to Market Cap Ratio
ctm = client.get_cash_to_marketcap("TCS", as_of="2024-03-31")
print(f"Cash to Market Cap: {ctm['cashToMarketcap']}")

Valuation Metrics

Get key valuation ratios:

# Price to Earnings (P/E) Ratio
pe = client.get_pe_ratio("RELIANCE", date="2024-12-31", ttm=False, consolidated=True)
print(f"P/E Ratio: {pe['peRatio']}")

# Price to Book (P/B) Ratio
pb = client.get_pb_ratio("HDFC", date="2024-12-31", consolidated=True)
print(f"P/B Ratio: {pb['pbRatio']}")

# Enterprise Value to EBITDA
ev_ebitda = client.get_ev_ebitda("TCS", date="2024-06-30", ttm=False, consolidated=True)
print(f"EV/EBITDA: {ev_ebitda['evEbitda']}")

# Free Cash Flow Yield
fcf_yield = client.get_fcf_yield("HDFCAMC", date="2024-06-30", ttm=False, consolidated=True)
print(f"FCF Yield: {fcf_yield['fcfYield']}%")

Returns Analysis

Calculate returns over different time periods:

# CAGR (Compound Annual Growth Rate)
cagr_data = client.get_cagr(
    symbol="RELIANCE",
    start_date="2020-01-01",
    end_date="2024-01-01",
    adjusted=True
)
print(f"Annual CAGR: {cagr_data['cagr']}%")
print(f"Start Price: ₹{cagr_data['startPrice']}")
print(f"End Price: ₹{cagr_data['endPrice']}")

# Quarterly Returns
quarterly_returns = client.get_quarterly_returns(
    symbol="INFY",
    start_date="2024-01-01",
    end_date="2024-12-31",
    adjusted=True
)

# Monthly Returns
monthly_returns = client.get_monthly_returns(
    symbol="TCS",
    start_date="2024-01-01",
    end_date="2024-12-31",
    adjusted=True
)

Market Data

Get historical price data and market capitalization:

# Daily OHLCV Data
ohlcv_data = client.get_analytics_ohlcv_daily(
    symbol="RELIANCE",
    start_date="2024-01-01",
    end_date="2024-01-31",
    adjusted=True
)
print(f"Retrieved {len(ohlcv_data['data'])} days of data")

# Historical Prices (same as OHLCV)
historical_prices = client.get_analytics_historical_prices(
    symbol="SBIN",
    start_date="2024-01-01",
    end_date="2024-01-31",
    adjusted=True
)

# Free-Float Market Capitalization
free_float_mcap = client.get_free_float_market_cap("RELIANCE", date="2024-07-31")
print(f"Free-Float Market Cap: ₹{free_float_mcap['freeFloatMarketCap']} Crores")
print(f"Total Market Cap: ₹{free_float_mcap['marketCap']} Crores")
print(f"Promoter Holding: {free_float_mcap['promoterHoldingPercent']}%")

# Index OHLC Daily Data
index_data = client.get_index_ohlc_daily(
    symbol="NIFTY50",
    start_date="2024-01-01",
    end_date="2024-01-31"
)
print(f"Retrieved {len(index_data['data'])} days of index data")

Ownership Analysis

Analyze institutional holdings and their changes:

# FII and DII Holdings
fii_dii = client.get_fii_dii_holdings("RELIANCE", quarter="Q4FY23")
print(f"FII Holdings: {fii_dii['fiiPercent']}%")
print(f"DII Holdings: {fii_dii['diiPercent']}%")

# FII Change from Previous Quarter
fii_change = client.get_fii_change("INFY")
print(f"FII Change: {fii_change['fiiChange']}%")
print(f"Current FII: {fii_change['currentFii']}%")
print(f"Previous FII: {fii_change['previousFii']}%")

# DII Change from Previous Quarter
dii_change = client.get_dii_change("INFY")
print(f"DII Change: {dii_change['diiChange']}%")
print(f"Current DII: {dii_change['currentDii']}%")
print(f"Previous DII: {dii_change['previousDii']}%")

Metrics (Risk-Adjusted Performance)

Get risk-adjusted performance metrics:

# Sortino Ratio
sortino = client.get_sortino_ratio(
    symbol="HDFCBANK",
    start_date="2024-01-01",
    end_date="2024-12-31",
    rf=0.065,
    interval="daily"
)
print(f"Sortino Ratio: {sortino['sortinoRatio']}")
print(f"Annualized Return: {sortino['annualizedReturn']}")
print(f"Downside Deviation: {sortino['downsideDeviation']}")

# Upside Capture Ratio
upside_capture = client.get_upside_capture(
    symbol="ICICIBANK",
    benchmark_symbol="NIFTY50",
    start_date="2024-01-01",
    end_date="2024-12-31"
)
print(f"Upside Capture Ratio: {upside_capture['upsideCaptureRatio']}%")
print(f"Periods Analyzed: {upside_capture['periodsAnalyzed']}")

Macro Economic Data

Get macroeconomic indicators:

# Risk-Free Rate
risk_free_rate = client.get_risk_free_rate(
    start_date="2024-01-01",
    end_date="2024-12-31",
    tenor="10Y",
    country="IN",
    method="average"
)
print(f"Risk-Free Rate (10Y): {risk_free_rate['riskFreeRate']}")
print(f"Country: {risk_free_rate['country']}")
print(f"Source: {risk_free_rate['source']}")

Risk Analysis

Get risk metrics and volatility measures:

# Maximum Drawdown (Peak-to-trough decline)
max_drawdown = client.get_max_drawdown(
    symbol="RELIANCE",
    start_date="2024-01-01",
    end_date="2024-12-31"
)
print(f"Maximum Drawdown: {max_drawdown['maxDrawdown']}%")
print(f"Drawdown Start Date: {max_drawdown['drawdownStartDate']}")
print(f"Drawdown End Date: {max_drawdown['drawdownEndDate']}")
print(f"Days in Drawdown: {max_drawdown['daysInDrawdown']}")

# Returns Volatility (Standard Deviation)
volatility = client.get_returns_volatility(
    symbol="NIFTY50",
    start_date="2024-01-01",
    end_date="2024-12-31",
    interval="daily"
)
print(f"Volatility (Daily): {volatility['volatility']}%")
print(f"Annualized Volatility: {volatility['annualizedVolatility']}%")
print(f"Mean Return: {volatility['meanReturn']}%")

Sector Classification

Get comprehensive sector and industry classification:

# Complete Sector Classification Data
sector_data = client.get_sector_classification("RELIANCE")
print(f"Company: {sector_data['companyName']}")
print(f"Sector: {sector_data['sector']}")
print(f"Industry: {sector_data['industry']}")
print(f"Sub-Industry: {sector_data['subIndustry']}")
print(f"GICS Sector Code: {sector_data['gicsSectorCode']}")
print(f"Industry Group: {sector_data['industryGroup']}")
print(f"Market Cap Tier: {sector_data['marketCapTier']}")

Leverage Analysis

Analyze financial leverage and debt ratios:

# Debt-to-Equity Ratio
debt_equity = client.get_debt_equity_ratio(
    symbol="RELIANCE",
    period="annual",
    consolidated=True
)
print(f"Debt-to-Equity Ratio: {debt_equity['debtEquityRatio']}")
print(f"Total Debt: ₹{debt_equity['totalDebt']} Crores")
print(f"Total Equity: ₹{debt_equity['totalEquity']} Crores")
print(f"Period: {debt_equity['period']}")
print(f"Data Date: {debt_equity['dataDate']}")

Advanced Returns Analysis

Calculate compound annual growth rates:

# CAGR (Compound Annual Growth Rate)
cagr = client.get_cagr(
    symbol="TCS",
    start_date="2020-01-01",
    end_date="2024-01-01",
    adjusted=True
)
print(f"CAGR (4-Year): {cagr['cagr']}%")
print(f"Total Return: {cagr['totalReturn']}%")
print(f"Start Price: ₹{cagr['startPrice']}")
print(f"End Price: ₹{cagr['endPrice']}")
print(f"Years: {cagr['years']}")

Complete Analytics Example

Here's a comprehensive example that combines multiple analytics features:

from wiz_trader import WizzerClient

def analyze_stock(symbol):
    client = WizzerClient(
        base_url="https://api-url.in",
        token="your-jwt-token"
    )
    
    print(f"=== Analysis for {symbol} ===\n")
    
    # Fundamentals
    print("[FUNDAMENTALS]:")
    try:
        margin = client.get_net_profit_margin(symbol)
        print(f"  Net Profit Margin: {margin.get('netProfitMargin', 'N/A')}%")
        
        roe = client.get_roe(symbol)
        print(f"  ROE: {roe.get('roe', 'N/A')}%")
        
        roa = client.get_roa(symbol)
        print(f"  ROA: {roa.get('roa', 'N/A')}%")
        
        eps_cagr = client.get_eps_cagr(symbol, start_year=2019, end_year=2023)
        print(f"  EPS CAGR (5Y): {eps_cagr.get('epsCagr', 'N/A')}%")
    except Exception as e:
        print(f"  Error fetching fundamentals: {e}")
    
    # Valuation
    print("\n[VALUATION]:")
    try:
        pe = client.get_pe_ratio(symbol)
        print(f"  P/E Ratio: {pe.get('peRatio', 'N/A')}")
        
        pb = client.get_pb_ratio(symbol)
        print(f"  P/B Ratio: {pb.get('pbRatio', 'N/A')}")
        
        ev_ebitda = client.get_ev_ebitda(symbol)
        print(f"  EV/EBITDA: {ev_ebitda.get('evEbitda', 'N/A')}")
    except Exception as e:
        print(f"  Error fetching valuation: {e}")
    
    # Returns
    print("\n📈 RETURNS:")
    try:
        cagr_data = client.get_cagr(
            symbol=symbol,
            start_date="2020-01-01",
            end_date="2024-01-01"
        )
        print(f"  4-Year CAGR: {cagr_data.get('cagr', 'N/A')}%")
        print(f"  Start Price: ₹{cagr_data.get('startPrice', 'N/A')}")
        print(f"  End Price: ₹{cagr_data.get('endPrice', 'N/A')}")
    except Exception as e:
        print(f"  Error fetching returns: {e}")
    
    # Ownership
    print("\n[OWNERSHIP]:")
    try:
        fii_dii = client.get_fii_dii_holdings(symbol)
        print(f"  FII Holdings: {fii_dii.get('fiiPercent', 'N/A')}%")
        print(f"  DII Holdings: {fii_dii.get('diiPercent', 'N/A')}%")
        
        fii_change = client.get_fii_change(symbol)
        print(f"  FII Change: {fii_change.get('fiiChange', 'N/A')}%")
    except Exception as e:
        print(f"  Error fetching ownership: {e}")
    
    # Market Cap
    print("\n[MARKET DATA]:")
    try:
        mcap = client.get_free_float_market_cap(symbol)
        print(f"  Market Cap: ₹{mcap.get('marketCap', 'N/A')} Crores")
        print(f"  Free-Float Market Cap: ₹{mcap.get('freeFloatMarketCap', 'N/A')} Crores")
        print(f"  Promoter Holding: {mcap.get('promoterHoldingPercent', 'N/A')}%")
    except Exception as e:
        print(f"  Error fetching market data: {e}")
    
    # Risk Analysis
    print("\n[RISK ANALYSIS]:")
    try:
        max_drawdown = client.get_max_drawdown(
            symbol=symbol,
            start_date="2024-01-01",
            end_date="2024-12-31"
        )
        print(f"  Maximum Drawdown: {max_drawdown.get('maxDrawdown', 'N/A')}%")
        
        volatility = client.get_returns_volatility(
            symbol=symbol,
            start_date="2024-01-01",
            end_date="2024-12-31"
        )
        print(f"  Returns Volatility: {volatility.get('volatility', 'N/A')}%")
    except Exception as e:
        print(f"  Error fetching risk metrics: {e}")
    
    # Sector Classification
    print("\n[SECTOR CLASSIFICATION]:")
    try:
        sector = client.get_sector_classification(symbol)
        print(f"  Sector: {sector.get('sector', 'N/A')}")
        print(f"  Industry: {sector.get('industry', 'N/A')}")
        print(f"  Market Cap Tier: {sector.get('marketCapTier', 'N/A')}")
    except Exception as e:
        print(f"  Error fetching sector data: {e}")
    
    # Leverage Analysis
    print("\n[LEVERAGE ANALYSIS]:")
    try:
        debt_equity = client.get_debt_equity_ratio(symbol)
        print(f"  Debt-to-Equity Ratio: {debt_equity.get('debtEquityRatio', 'N/A')}")
    except Exception as e:
        print(f"  Error fetching leverage metrics: {e}")

# Analyze multiple stocks
stocks = ["RELIANCE", "TCS", "INFY", "HDFC", "SBIN"]
for stock in stocks:
    analyze_stock(stock)
    print("\n" + "="*50 + "\n")

Advanced Market Data Analysis

Advanced volume and drawdown analysis:

# Average Traded Volume
volume_data = client.get_average_traded_volume(
    symbol="HDFCBANK",
    start_date="2024-04-01",
    end_date="2024-06-30",
    interval="daily"
)
print(f"Average Volume: {volume_data['averageVolume']} shares")

# Index Maximum Drawdown
index_drawdown = client.get_index_max_drawdown(
    index_symbol="NIFTY50",
    start_date="2023-01-01",
    end_date="2024-01-01",
    interval="daily"
)
print(f"Max Drawdown: {index_drawdown['maxDrawdown']}%")

# Drawdown Duration Analysis
drawdown_duration = client.get_drawdown_duration(
    symbol="INFY",
    start_date="2022-01-01",
    end_date="2024-01-01",
    interval="daily"
)
print(f"Max Drawdown Duration: {drawdown_duration['maxDrawdownDuration']} days")

Technical Price Analysis

Rolling price analysis and volatility:

# Rolling Peak Price Analysis
rolling_peak = client.get_rolling_peak_price(
    symbol="NSE:TCS",
    start_date="2024-01-01",
    end_date="2024-06-30",
    window=20,
    adjusted=True
)
print(f"Rolling peak data points: {len(rolling_peak['data'])}")

# Rolling Price Mean
rolling_mean = client.get_rolling_price_mean(
    symbol="HDFCBANK",
    start_date="2024-01-01",
    end_date="2024-06-30",
    window=50,
    adjusted=True
)
print(f"Rolling mean data points: {len(rolling_mean['data'])}")

# Realized Volatility
volatility = client.get_realized_volatility(
    symbol="NSE:ITC",
    start_date="2024-01-01",
    end_date="2024-06-30",
    adjusted=True
)
print(f"Realized Volatility: {volatility['realizedVolatility']}%")
print(f"Annualized Volatility: {volatility['annualizedVolatility']}%")

Advanced Risk Metrics

CAMP Beta analysis:

# 90-Day Beta Analysis
beta_90d = client.get_beta_90d(
    symbol="ITC",
    benchmark="NIFTY50"
)
print(f"90-Day Beta: {beta_90d['beta']}")
print(f"Correlation: {beta_90d['correlation']}")
print(f"R-Squared: {beta_90d['rSquared']}")

# Custom Period Beta
beta_custom = client.get_beta_custom_period(
    symbol="TCS",
    benchmark="NIFTY50",
    start_date="2020-01-01",
    end_date="2024-12-31"
)
print(f"Custom Period Beta: {beta_custom['beta']}")
print(f"Alpha: {beta_custom['alpha']}")

# Strategy Max Drawdown
strategy_drawdown = client.get_strategy_max_drawdown(
    strategy_id="str_01jspb8z36edjsp5pecqq0mpm3",
    start_date="2023-01-01",
    end_date="2024-12-31",
    interval="daily"
)
print(f"Strategy Max Drawdown: {strategy_drawdown['maxDrawdown']}")
print(f"Peak Date: {strategy_drawdown['peakDate']}")

# Product Max Drawdown
product_drawdown = client.get_product_max_drawdown(
    product_id="prd_01jyrg7ffkemq9hz3rkeznh9dr",
    start_date="2023-01-01",
    end_date="2024-12-31",
    interval="monthly"
)
print(f"Product Max Drawdown: {product_drawdown['maxDrawdown']}")

# Average True Range (ATR)
atr_data = client.get_atr(
    symbol="AXISBANK",
    start_date="2023-01-01",
    end_date="2024-12-31",
    window=14,
    adjusted=True,
    interval="daily"
)
print(f"Latest ATR: {atr_data['atr'][-1]['atrValue']}")

# Simple Return
simple_return = client.get_simple_return(
    symbol="NIFTY_IT",
    start_date="2023-01-01",
    end_date="2024-12-31",
    adjusted=True,
    interval="daily",
    benchmark="NIFTY 50"
)
print(f"Total Return: {simple_return['totalReturn']}")
print(f"Relative Return: {simple_return['relativeReturn']}")

# Corporate Actions and Announcements
corporate_events = client.get_corporate_actions_events()
print(f"Available Corporate Action Types: {corporate_events}")

# Filter Corporate Actions
corporate_actions = client.get_corporate_actions_filter(
    symbol="RELIANCE",
    events="corporate_actions.agm",
    fromDate="2024-01-01",
    toDate="2024-12-31",
    hasDividend=True,
    page=1,
    pageSize=20
)
print(f"Found {corporate_actions['totalCount']} corporate actions")

# Corporate Announcements
announcement_events = client.get_corporate_announcements_events()
print(f"Available Announcement Types: {announcement_events}")

# Filter Corporate Announcements
announcements = client.get_corporate_announcements_filter(
    symbol="TCS",
    events="corporate_announcements.agm",
    fromDate="2024-01-01",
    toDate="2024-12-31",
    announcementContains="dividend",
    page=1,
    pageSize=10
)
print(f"Found {announcements['totalCount']} announcements")

Corporate Analytics API Reference

Corporate Actions Filter Parameters

Parameter Type Required Description Example
symbol string No Trading symbol to filter by RELIANCE, TCS
events string No Event type to filter by Dividend, BONUS
actionCategory string No Action category to filter by DIVIDEND, BONUS, SPLIT
fromDate string (date) No Ex-date from (YYYY-MM-DD) 2024-01-01
toDate string (date) No Ex-date to (YYYY-MM-DD) 2024-12-31
exchange string No Exchange to filter by NSE, BSE
hasDividend boolean No Filter for dividend actions true, false
hasBonus boolean No Filter for bonus actions true, false
hasAgm boolean No Filter for AGM actions true, false
eventTextContains string No Search text within event description bonus, dividend
faceValue number No Face value to filter by 10, 1
ratioNumerator integer No Ratio numerator value 1, 2
ratioDenominator integer No Ratio denominator value 1, 10
actionSubcategory string No Action subcategory to filter by INTERIM, FINAL
primaryAmount number No Primary amount to filter by 5.50, 10.00
secondaryAmount number No Secondary amount to filter by 2.50
oldFaceValue number No Old face value to filter by 10
newFaceValue number No New face value to filter by 1
page integer No Page number for pagination (default: 1) 1, 2
pageSize integer No Records per page (default: 20, max: 100) 20, 50

Corporate Announcements Filter Parameters

Parameter Type Required Description Example
symbol string No Trading symbol to filter by 20MICRONS, FINCABLES
events string No Event type to filter by AGM, Results Update
fromDate string (date) No Date from (YYYY-MM-DD) 2012-01-01
toDate string (date) No Date to (YYYY-MM-DD) 2012-12-31
announcementDateFrom string (date) No Announcement date from (YYYY-MM-DD) 2010-01-01
announcementDateTo string (date) No Announcement date to (YYYY-MM-DD) 2010-12-31
exchange string No Exchange to filter by NSE, BSE
announcementContains string No Search text within announcement dividend, merger
hasXbrl boolean No Filter for announcements with XBRL true, false
page integer No Page number for pagination (default: 1) 1, 2
pageSize integer No Records per page (default: 20, max: 100) 20, 50

Key Features:

  • Comprehensive Coverage: 47+ analytics endpoints covering fundamentals, valuation, returns, market data, ownership, metrics, macro data, risk analysis, sector classification, leverage analysis, advanced technical analysis, and corporate actions/announcements
  • Corporate Actions: Track dividends, bonus issues, stock splits, rights issues, AGMs, and buybacks with comprehensive filtering
  • Corporate Announcements: Monitor board meetings, financial results, AGM notifications, and regulatory announcements with XBRL support
  • Fundamentals Analysis: 9 methods including ROE, ROA, margins, ratios, book-to-market, market cap-to-sales, and cash-to-market cap
  • Valuation Metrics: P/E, P/B, EV/EBITDA, FCF yield with TTM and consolidated/standalone options
  • Risk-Adjusted Metrics: Sortino ratio, upside capture ratio, maximum drawdown, and returns volatility for comprehensive risk analysis
  • Sector & Industry Analysis: Complete GICS classification with sector, industry, sub-industry, and market cap tier data
  • Leverage Analysis: Debt-to-equity ratios and comprehensive financial leverage metrics
  • Institutional Analysis: Track FII/DII holdings and their quarterly changes
  • Returns Calculation: Calculate CAGR over custom time periods with flexible date ranges
  • Macro Economic Data: Risk-free rates for various tenors and countries
  • Index Support: Historical OHLC data for major indices like NIFTY50, SENSEX
  • Error Handling: Robust error handling with comprehensive parameter validation
  • Modern API Design: Updated parameter names following camelCase convention

Wizzer Client Examples

Market Data and Analysis Example

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

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

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

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

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

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:

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:

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:

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:

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.

# 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

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 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
bookValue Book Value Nullable(Float64) currency $eq, $ne, $gt, $gte, $lt, $lte, $between
shareholderEquity Shareholder Equity Nullable(Float64) currency $eq, $ne, $gt, $gte, $lt, $lte, $between
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

Debt & Cash

Field Description Data Type Unit Supported Operations
totalDebt Total Debt Float64 currency $eq, $ne, $gt, $gte, $lt, $lte, $between
netCash Net Cash (Cash - Total Debt) Float64 currency $eq, $ne, $gt, $gte, $lt, $lte, $between

Income Statement Items

Revenue & Income

Field Description Data Type Unit Supported Operations
revenue Total Revenue Nullable(Float64) currency $eq, $ne, $gt, $gte, $lt, $lte, $between
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
netIncome Net Income Nullable(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

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
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
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
freeCashFlow Free Cash Flow Nullable(Float64) currency $eq, $ne, $gt, $gte, $lt, $lte, $between
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

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

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
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

Valuation Ratios

Field Description Data Type Unit Supported Operations
peRatio Price to Earnings Ratio Float ratio $eq, $ne, $gt, $gte, $lt, $lte, $between
pbRatio Price to Book Ratio Float ratio $eq, $ne, $gt, $gte, $lt, $lte, $between
evEbitda Enterprise Value to EBITDA Float ratio $eq, $ne, $gt, $gte, $lt, $lte, $between
fcfYield Free Cash Flow Yield Float % $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 Nullable(Float32) % $eq, $ne, $gt, $gte, $lt, $lte, $between
roa Return on Assets Nullable(Float32) % $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
ebitMargin Earnings Before Interest and Taxes Margin Nullable(Float32) % $eq, $ne, $gt, $gte, $lt, $lte, $between
EPS Earnings Per Share Nullable(Float64) currency $eq, $ne, $gt, $gte, $lt, $lte, $between
epsCagr EPS Compounded Annual Growth Rate Float % $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
ocfNPRatio Operating Cash Flow to Net Profit Ratio Nullable(Float64) ratio $eq, $ne, $gt, $gte, $lt, $lte, $between
ocfPat Operating Cash Flow to PAT Ratio Float ratio $eq, $ne, $gt, $gte, $lt, $lte, $between

Shareholding Patterns

Current Holdings

Field Description Data Type Unit Supported Operations
currentFiiHoldings Current FII holdings percentage (latest quarter) Float64 % $eq, $ne, $gt, $gte, $lt, $lte, $between
currentDiiHoldings Current DII holdings percentage (latest quarter) Float64 % $eq, $ne, $gt, $gte, $lt, $lte, $between
currentPromoterHoldings Current Promoter holdings percentage (latest quarter) Float64 % $eq, $ne, $gt, $gte, $lt, $lte, $between
currentInstitutionalHoldings Current total institutional holdings percentage (latest quarter) Float64 % $eq, $ne, $gt, $gte, $lt, $lte, $between
freeFloatPercentage Free float percentage (latest quarter) Float64 % $eq, $ne, $gt, $gte, $lt, $lte, $between
freeFloatMarketCap Free-float market capitalization (latest trading day) Float64 currency $eq, $ne, $gt, $gte, $lt, $lte, $between

Quarter-on-Quarter Changes

Field Description Data Type Unit Supported Operations
qoqInstitutionalChange Quarter-on-quarter change in institutional holdings (%) Float64 % $eq, $ne, $gt, $gte, $lt, $lte, $between
qoqFiiChange Quarter-on-quarter change in FII holdings (%) Float64 % $eq, $ne, $gt, $gte, $lt, $lte, $between
qoqDiiChange Quarter-on-quarter change in DII holdings (%) Float64 % $eq, $ne, $gt, $gte, $lt, $lte, $between
qoqPromoterChange Quarter-on-quarter change in Promoter holdings (%) Float64 % $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
MarketCap Logarithm of Market Capitalization Float64 log_currency $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

# 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

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

# 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

# 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)

# 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)

# 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

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

List Operations

Get All KV Pairs (with values)

# 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)

# 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

# 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

# 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

# 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

# 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:

# 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:

# 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!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wiz_trader-0.43.0.tar.gz (159.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wiz_trader-0.43.0-py3-none-any.whl (75.4 kB view details)

Uploaded Python 3

File details

Details for the file wiz_trader-0.43.0.tar.gz.

File metadata

  • Download URL: wiz_trader-0.43.0.tar.gz
  • Upload date:
  • Size: 159.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for wiz_trader-0.43.0.tar.gz
Algorithm Hash digest
SHA256 df4abf25c7b5e34a95e8c5c51858fddb6e63c7dc48a209eecfd8f744c780d0a3
MD5 25710de8db6c6b4e86ed61e4cb39e01b
BLAKE2b-256 02ec8910753e8a808d39e986a7ad83e9f45450d0002edb506aa2678c7aede2d0

See more details on using hashes here.

File details

Details for the file wiz_trader-0.43.0-py3-none-any.whl.

File metadata

  • Download URL: wiz_trader-0.43.0-py3-none-any.whl
  • Upload date:
  • Size: 75.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for wiz_trader-0.43.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1fdf33ae00027206e738caa78978f9e7d243abdbf0f35bbc436f52cefc133907
MD5 87fefc81d147e955c497ced9033b5fcc
BLAKE2b-256 ae97be1fe7a88caf3d91d7b9da602e12e96c16a1efb26a06999f5e553b9b73f8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page