has any one try to fetch ticker options data or real-time option-chain from the Dhan API?
Hey @Lauren_Menezes ,
Yes , you can fetch ticker option data and real-time option chain using the Dhan APIs, and both work correctly.
For ticker option data Live Market Feed - DhanHQ Ver 2.0 / API Document
And for option chain data Option Chain - DhanHQ Ver 2.0 / API Document .
I have gone through this link and tried in my code but it is just fetching the strike and sometimes the expiry
Code: [import os
import logging
import asyncio
import threading
from typing import Dict, List, Any, Optional
from datetime import datetime
from dhanhq import dhanhq, marketfeed
from dotenv import load_dotenv
Load environment variables
load_dotenv()
logger = logging.getLogger(“DhanBridge”)
logging.basicConfig(level=logging.INFO)
class DhanBridge:
def init(self):
self.client_id = os.getenv(“DHAN_CLIENT_ID”)
self.access_token = os.getenv(“DHAN_ACCESS_TOKEN”)
self.dhan = None
self.feed = None
self.subscribed_instruments = set()
self.market_data = {} # Store latest ticks: {security_id: {ltp: …, …}}
self.on_tick_callback = None
if self.client_id and self.access_token:
try:
self.dhan = dhanhq(self.client_id, self.access_token)
logger.info("Dhan API Client Initialized")
except Exception as e:
logger.error(f"Failed to initialize Dhan API: {e}")
else:
logger.warning("Dhan credentials not found in .env")
def get_option_chain(self, symbol: str, expiry: str) -> Dict[str, Any]:
"""
Fetch option chain for a symbol and expiry.
"""
if not self.dhan:
return {"error": "Dhan API not initialized"}
# Map common symbols to Security IDs (NSE)
# NIFTY: 13, BANKNIFTY: 23
security_id = "13" if symbol.upper() == "NIFTY" else "23" if symbol.upper() == "BANKNIFTY" else None
if not security_id:
return {"error": f"Symbol {symbol} not supported for automatic ID lookup. Only NIFTY/BANKNIFTY supported currently."}
try:
response = self.dhan.option_chain(
under_security_id=security_id,
under_exchange_segment="IDX_I",
expiry=expiry
)
return response
except Exception as e:
logger.error(f"Error fetching option chain: {e}")
return {"error": str(e)}
async def start_websocket(self, instruments: List[tuple], callback):
"""
Start WebSocket and subscribe to instruments.
instruments: List of (exchange_segment, security_id)
"""
if not self.client_id or not self.access_token:
logger.error("Cannot start WebSocket without credentials")
return
self.on_tick_callback = callback
try:
# If feed already exists, just subscribe
if self.feed:
self.subscribe(instruments)
return
logger.info(f"Starting WebSocket with {len(instruments)} instruments")
self.feed = marketfeed.DhanFeed(
self.client_id,
self.access_token,
instruments,
version="v2"
)
self.feed.on_connect = self._on_connect
self.feed.on_message = self._on_message
self.feed.on_error = self._on_error
self.feed.on_close = self._on_close
# Run in a separate thread
t = threading.Thread(target=self.feed.run_forever)
t.daemon = True
t.start()
logger.info("WebSocket thread started")
except Exception as e:
logger.error(f"Error starting WebSocket: {e}")
def _on_connect(self, instance):
logger.info("Connected to Dhan WebSocket")
def _on_message(self, instance, message):
# logger.info(f"Tick received: {message}") # Debug logging
if 'LTP' in message:
security_id = message.get('security_id')
self.market_data[security_id] = message
if self.on_tick_callback:
self.on_tick_callback(message)
def _on_error(self, instance, error):
logger.error(f"WebSocket Error: {error}")
def _on_close(self, instance):
logger.info("WebSocket Connection Closed")
def subscribe(self, subscription_list: List[tuple]):
if self.feed:
try:
self.feed.subscribe_symbols(subscription_list)
logger.info(f"Subscribed to {len(subscription_list)} symbols")
except Exception as e:
logger.error(f"Error subscribing: {e}")
dhan_bridge = DhanBridge() ]
Console : [ ng:
on_event is deprecated, use lifespan event handlers instead.
Read more about it in the
[FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/).
@app.on_event(“startup”)
INFO: Will watch for changes in these directories: [‘C:\Users\inkstall\OneDrive\Desktop\Option\dhan_options_app\backend’]
INFO: Uvicorn running on (Press CTRL+C to quit)
INFO: Started reloader process [33680] using WatchFiles
INFO:DhanBridge:Dhan API Client Initialized
INFO: Started server process [22704]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO:watchfiles.main:5 changes detected
INFO: 127.0.0.1:52929 - “WebSocket /socket.io/?EIO=4&transport=websocket” [accepted]
INFO: connection open
INFO:Main:Fetching option chain for NIFTY expiry 2025-11-25
INFO: 127.0.0.1:55342 - “GET /api/option-chain/NIFTY/2025-11-25 HTTP/1.1” 200 OK
INFO:Main:Fetching option chain for NIFTY expiry 2025-11-25
INFO: 127.0.0.1:55342 - “GET /api/option-chain/NIFTY/2025-11-25 HTTP/1.1” 200 OK
INFO:Main:Fetching option chain for BANKNIFTY expiry 2025-11-25
INFO: 127.0.0.1:51036 - “GET /api/option-chain/BANKNIFTY/2025-11-25 HTTP/1.1” 200 OK
INFO:Main:Fetching option chain for NIFTY expiry 2025-11-25
INFO: 127.0.0.1:51036 - “GET /api/option-chain/NIFTY/2025-11-25 HTTP/1.1” 200 OK ]
Please Give me the solution for this asap as I have deadlines to be submited .