Websockate is automatically closing

Found Security ID: 50995 for NIFTY-Jun2025-24650-CE
:mag: Using Security ID: 50995 (type: <class ‘str’>)
:electric_plug: Initiating WebSocket connection…
:white_check_mark: WebSocket connection established
:alarm_clock: Current IST time: 2025-06-18 13:43:21 IST
:arrows_counterclockwise: Awaiting next WebSocket data packet at 13:43:21 IST…
:alarm_clock: Current IST time: 2025-06-18 13:43:21 IST
:alarm_clock: Current IST time: 2025-06-18 13:43:21 IST
:satellite: Received data at 13:43:21 IST: {‘type’: ‘Full Data’, ‘exchange_segment’: 2, ‘security_id’: 50995, ‘LTP’: ‘187.25’, ‘LTQ’: 75, ‘LTT’: ‘13:43:20’, ‘avg_price’: ‘203.88’, ‘volume’: 9838125, ‘total_sell_quantity’: 107475, ‘total_buy_quantity’: 177225, ‘OI’: 784125, ‘oi_day_high’: 925050, ‘oi_day_low’: 496425, ‘open’: ‘200.00’, ‘close’: ‘235.55’, ‘high’: ‘326.20’, ‘low’: ‘160.80’, ‘depth’: [{‘bid_quantity’: 300, ‘ask_quantity’: 300, ‘bid_orders’: 3, ‘ask_orders’: 4, ‘bid_price’: ‘187.15’, ‘ask_price’: ‘187.55’}, {‘bid_quantity’: 150, ‘ask_quantity’: 1125, ‘bid_orders’: 1, ‘ask_orders’: 8, ‘bid_price’: ‘187.10’, ‘ask_price’: ‘187.60’}, {‘bid_quantity’: 525, ‘ask_quantity’: 600, ‘bid_orders’: 6, ‘ask_orders’: 7, ‘bid_price’: ‘187.05’, ‘ask_price’: ‘187.65’}, {‘bid_quantity’: 2100, ‘ask_quantity’: 675, ‘bid_orders’: 9, ‘ask_orders’: 5, ‘bid_price’: ‘187.00’, ‘ask_price’: ‘187.70’}, {‘bid_quantity’: 150, ‘ask_quantity’: 600, ‘bid_orders’: 1, ‘ask_orders’: 3, ‘bid_price’: ‘186.95’, ‘ask_price’: ‘187.75’}]}
:chart_with_upwards_trend: Received LTP: 187.25 for Security ID: 50995
:alarm_clock: Current IST time: 2025-06-18 13:43:21 IST
:alarm_clock: Current minute offset: 3.36, Window check: False
:alarm_clock: 4th minute check: time_diff_minutes=3.36
:clock3: 4th minute check (3:00–5:00): 3-min high=0, 4th min LTPs=[187.25], 4th min high=187.25
:chart_with_downwards_trend: Breakout failed: 4th min high 187.25 <= 3-min high 0 or LTP 187.25 outside range (189 to 192)
:alarm_clock: Current IST time: 2025-06-18 13:43:21 IST
:arrows_counterclockwise: Awaiting next WebSocket data packet at 13:43:21 IST…
:alarm_clock: Current IST time: 2025-06-18 13:43:21 IST
:alarm_clock: Current IST time: 2025-06-18 13:43:21 IST
:satellite: Received data at 13:43:21 IST: {‘type’: ‘OI Data’, ‘exchange_segment’: 2, ‘security_id’: 50995, ‘OI’: 784125}
:information_source: Received non-Full Data packet: OI Data, skipping…
:alarm_clock: Current IST time: 2025-06-18 13:43:22 IST
:arrows_counterclockwise: Awaiting next WebSocket data packet at 13:43:22 IST…
:alarm_clock: Current IST time: 2025-06-18 13:43:22 IST
:alarm_clock: Current IST time: 2025-06-18 13:43:52 IST
:warning: No WebSocket data received for 30 seconds at 13:43:52 IST
:arrows_counterclockwise: Retry 1/5 after timeout
Connection closed!
:electric_plug: Connection closed (attempt 2/5): no close frame received or sent
:x: Program terminated with error: no close frame received or

Can some one help why websocketbis automatically closing

Hey @Vinaya_Sagara_Reddy

Can you confirm if this is the Dhan python library code or something you have created on your own? You can also add print for reason of such closures, for you to better understand disconnection reasons.

This is the code i have created using dhanhq library with my own logiv but untill morning 10 this was working fine I am using this for around a month now below is the code

import asyncio
import json
import uuid
import pandas as pd
import requests
import websockets
from datetime import datetime, time
import pytz
from dhanhq import DhanContext, dhanhq, MarketFeed

──────────────────────────────────────────────────────────────

:wrench: CONFIGURATION

CLIENT_ID = “1107042532”
ACCESS_TOKEN = “eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJkaGFuIiwicGFydG5lcklkIjoiIiwiZXhwIjoxNzUyODI3OTE1LCJ0b2tlbkNvbnN1bWVyVHlwZSI6IlNFTEYiLCJ3ZWJob29rVXJsIjoiIiwiZGhhbkNsaWVudElkIjoiMTEwNzA0MjUzMiJ9.splNe0x9bItfGxFSrnDDkOF0BeTDKvXXXQvxx02mRK2bovrDx7t3vpk30m6dkCgCwCtohpBh9asPXcFQ_Z-6ww”

STRIKE_PRICE = 24850
BUY_PRICE = 300 # Adjusted to recent LTP (~188–189)
TOTAL_LOTS = 24

OPTION_TYPE = “CE”
EXPIRY = “Jun2025”

print(BUY_PRICE)
MAX_UNITS_PER_ORDER = 1800
TRADING_END_TIME = “15:30:00” # 3:30 PM IST
LOT_SIZE = 75
TARGET_PROFIT = 10
STOPLOSS = 20
SYMBOL = “NIFTY”

──────────────────────────────────────────────────────────────

:white_check_mark: Initialize Dhan Client

dhan_context = DhanContext(CLIENT_ID, ACCESS_TOKEN)
dhan = dhanhq(dhan_context)

Global variables

order_placed = False
active_orders =
current_ltp = None
candle_data = {} # Store per-minute candle data: {candle_start_timestamp: [ltps]}

def get_ist_time():
“”“Get current time in IST.”“”
return datetime.now(pytz.timezone(“Asia/Kolkata”))

def get_security_id(symbol, expiry, strike, option_type):
“”“Fetch security ID from CSV.”“”
try:
df = pd.read_csv(“api-scrip-master.csv”, low_memory=False)
trading_symbol = f"{symbol}-{expiry}-{strike}-{option_type}"
filtered_df = df[
(df[“SEM_EXM_EXCH_ID”] == “NSE”)
& (df[“SEM_TRADING_SYMBOL”] == trading_symbol)
]
if not filtered_df.empty:
security_id = filtered_df.iloc[0][“SEM_SMST_SECURITY_ID”]
print(f"Found Security ID: {security_id} for {trading_symbol}“)
return str(security_id).strip()
else:
raise ValueError(f"Security ID not found for {trading_symbol}”)
except Exception as e:
print(f":x: Error fetching security ID: {e}")
return None

def is_within_first_3_minutes(current_time):
“”“Check if within first 3 minutes of a 5-minute candle.”“”
minutes = current_time - get_candle_start_time(current_time)
minute_offset = minutes.total_seconds() / 60
print(
f":alarm_clock: Current minute offset: {minute_offset:.2f}, Window check: {minute_offset < 3}"
)
return minute_offset < 3

def is_fourth_minute(current_time, candle_start):
“”“Check if in the 4th minute (3:00–4:00) of a 5-minute candle.”“”
time_diff_minutes = (current_time - candle_start).total_seconds() / 60
print(f":alarm_clock: 4th minute check: time_diff_minutes={time_diff_minutes:.2f}")
return 3 <= time_diff_minutes < 4

def get_candle_start_time(current_time):
“”“Get the start time of the current 5-minute candle.”“”
minutes = current_time.minute
candle_start_minute = minutes - (minutes % 5)
return current_time.replace(minute=candle_start_minute, second=0, microsecond=0)

async def place_super_order(buy_price, security_id, quantity):
“”“Place a Super Order with target and stop-loss.”“”
try:
correlation_id = str(uuid.uuid4())
payload = {
“dhanClientId”: CLIENT_ID,
“correlationId”: correlation_id,
“transactionType”: “BUY”,
“exchangeSegment”: “NSE_FNO”,
“productType”: “INTRADAY”,
“orderType”: “MARKET”,
“securityId”: str(security_id),
“quantity”: quantity,
“price”: 0.0,
“targetPrice”: float(buy_price + TARGET_PROFIT),
“stopLossPrice”: float(buy_price - STOPLOSS),
“trailingJump”: 0,
}
url = “i had put correct url but cannot post so removeing”
headers = {“Content-Type”: “application/json”, “access-token”: ACCESS_TOKEN}
print(f":outbox_tray: Sending Super Order: {json.dumps(payload, indent=2)}“)
response = requests.post(url, headers=headers, json=payload)
print(f":clipboard: Super Order Response: {response.status_code} - {response.text}”)
if response.status_code == 200:
data = response.json()
print(
f":white_check_mark: Super Order Placed: Order ID {data.get(‘orderId’)}, Qty {quantity}"
)
return data
else:
print(
f":x: Failed to place Super Order: {response.status_code} - {response.text}"
)
return None
except Exception as e:
print(f":x: Error placing order: {e}")
return None

async def monitor_position(security_id, entry_price):
“”“Monitor position for target, stop-loss, or session end.”“”
global current_ltp
end_time = time.fromisoformat(TRADING_END_TIME)
while True:
try:
current_time = get_ist_time().time()
if current_time >= end_time:
print(“:alarm_clock: Trading session ended, closing position”)
await close_position()
break
if current_ltp:
ltp = float(current_ltp)
if ltp >= entry_price + TARGET_PROFIT:
print(f":dart: Target profit reached: LTP {ltp}, Exiting")
await close_position()
break
elif ltp <= entry_price - STOPLOSS:
print(f":stop_sign: Stop-loss triggered: LTP {ltp}, Exiting")
await close_position()
break
await asyncio.sleep(1)
except Exception as e:
print(f":x: Error in position monitoring: {e}")
await asyncio.sleep(5)

async def close_position():
“”“Close all active orders and positions.”“”
global order_placed, active_orders
try:
for order in active_orders:
order_id = order.get(“orderId”)
if order_id:
try:
dhan.cancel_order(order_id)
print(f":white_check_mark: Order {order_id} cancelled")
except Exception as e:
print(f":x: Failed to cancel order {order_id}: {e}“)
order_placed = False
active_orders.clear()
except Exception as e:
print(f":x: Error closing position: {e}”)

async def trading_strategy():
“”“Main trading strategy logic.”“”
global order_placed, current_ltp, active_orders, candle_data
security_id = get_security_id(SYMBOL, EXPIRY, STRIKE_PRICE, OPTION_TYPE)
if not security_id:
print(“:x: Failed to retrieve security ID. Exiting.”)
return
print(f":mag: Using Security ID: {security_id} (type: {type(security_id)})")

# Subscribe to Full Packet data for LTP
subscribe_inst = [(MarketFeed.NSE_FNO, str(security_id), MarketFeed.Full)]
market_feed = MarketFeed(dhan_context, subscribe_inst, version="v2")

async def on_data_received():
    global current_ltp, order_placed, active_orders, candle_data
    max_retries = 5
    retry_delay = 5
    retries = 0
    while retries < max_retries:
        try:
            if not market_feed.ws:
                print("🔌 WebSocket not connected, attempting to reconnect...")
                await market_feed.connect()
                await asyncio.sleep(2)
            data = await market_feed.get_instrument_data()
            print(f"Raw data: {data}")
            if not isinstance(data, dict):
                print(f"❌ Invalid data (not a dict): {data}")
                return True
            data_type = data.get("type")
            if data_type == "OI Data":
                print(
                    f"📊 Received OI Data: OI={data.get('OI')}, skipping processing"
                )
                return True  # Skip OI Data and continue receiving next message
            if data_type != "Full Data":
                print(f"❌ Invalid data type: {data_type}, expected 'Full Data'")
                return True
            data_security_id = str(data.get("security_id")).strip()
            print(
                f"🔍 Comparing security IDs: Data ID={data_security_id} (type: {type(data_security_id)}, len: {len(data_security_id)}), Expected ID={security_id} (type: {type(security_id)}, len: {len(security_id)})"
            )
            if data_security_id == security_id:
                current_ltp = data.get("LTP")
                try:
                    ltp = float(current_ltp)
                    print(
                        f"📈 Received LTP: {current_ltp} for Security ID: {security_id}"
                    )
                    current_time = get_ist_time()
                    candle_start = get_candle_start_time(current_time)
                    minute_offset = int(
                        (current_time - candle_start).total_seconds() // 60
                    )

                    # Initialize candle data for this 5-minute candle
                    if candle_start not in candle_data:
                        candle_data[candle_start] = [
                            [] for _ in range(5)
                        ]  # List for each minute

                    # Store LTP for the current minute
                    candle_data[candle_start][minute_offset].append(ltp)

                    # Clean up old candle data (keep last 2 candles)
                    old_candles = [
                        k
                        for k in candle_data
                        if k < candle_start - pd.Timedelta(minutes=5)
                    ]
                    for k in old_candles:
                        del candle_data[k]

                    if order_placed:
                        print(f"📊 Order already placed, monitoring LTP: {ltp}")
                        return False  # Stop processing after order is placed

                    # Existing Condition: Buy in first 3 minutes if LTP in range
                    if is_within_first_3_minutes(current_time):
                        if BUY_PRICE <= ltp <= BUY_PRICE + 3:
                            print(f"📈 Buy condition met (price range): LTP {ltp}")
                            total_quantity = LOT_SIZE * TOTAL_LOTS
                            quantities = []
                            if total_quantity > MAX_UNITS_PER_ORDER:
                                while total_quantity > 0:
                                    qty = min(total_quantity, MAX_UNITS_PER_ORDER)
                                    quantities.append(qty)
                                    total_quantity -= qty
                            else:
                                quantities.append(total_quantity)
                            for qty in quantities:
                                order = await place_super_order(
                                    BUY_PRICE, security_id, qty
                                )
                                if order:
                                    active_orders.append(order)
                            order_placed = True
                            asyncio.create_task(
                                monitor_position(security_id, BUY_PRICE)
                            )
                            return False  # Stop processing after placing order
                        else:
                            print(
                                f"📉 LTP {ltp} outside buy range ({BUY_PRICE} to {BUY_PRICE + 2})"
                            )
                    # New Condition: Buy in 4th minute (3:00–4:00) if any LTP breaks 3-minute high and current LTP in range
                    elif is_fourth_minute(current_time, candle_start):
                        # Calculate 3-minute candle high (minutes 0–2)
                        three_min_high = (
                            max(
                                max(candle_data[candle_start][i], default=0)
                                for i in range(3)
                                if candle_data[candle_start][i]
                            )
                            if any(candle_data[candle_start][i] for i in range(3))
                            else 0
                        )
                        # Max LTP in 4th minute (minute 3)
                        fourth_min_ltps = candle_data[candle_start][3]
                        fourth_min_high = max(fourth_min_ltps, default=ltp)
                        print(
                            f"🕒 4th minute check (3:00–4:00): 3-min high={three_min_high}, 4th min LTPs={fourth_min_ltps}, 4th min high={fourth_min_high}"
                        )
                        if (
                            three_min_high > 0
                            and fourth_min_high > three_min_high
                            and BUY_PRICE <= ltp <= BUY_PRICE + 3
                        ):
                            print(
                                f"📈 Buy condition met (4th min breakout): LTP {ltp}, 4th min high {fourth_min_high} > 3-min high {three_min_high}"
                            )
                            total_quantity = LOT_SIZE * TOTAL_LOTS
                            quantities = []
                            if total_quantity > MAX_UNITS_PER_ORDER:
                                while total_quantity > 0:
                                    qty = min(total_quantity, MAX_UNITS_PER_ORDER)
                                    quantities.append(qty)
                                    total_quantity -= qty
                            else:
                                quantities.append(total_quantity)
                            for qty in quantities:
                                order = await place_super_order(
                                    ltp, security_id, qty
                                )
                                if order:
                                    active_orders.append(order)
                            order_placed = True
                            asyncio.create_task(monitor_position(security_id, ltp))
                            return False  # Stop processing after placing order
                        else:
                            print(
                                f"📉 Breakout failed: 4th min high {fourth_min_high} <= 3-min high {three_min_high} or LTP {ltp} outside range ({BUY_PRICE} to {BUY_PRICE + 2})"
                            )
                except ValueError:
                    print(f"❌ Invalid LTP value: {current_ltp}")
            else:
                print(
                    f"❌ Security ID mismatch: Expected '{security_id}' (type: {type(security_id)}), Got '{data_security_id}' (type: {type(data_security_id)})"
                )
            return True
        except websockets.exceptions.ConnectionClosed as e:
            retries += 1
            print(f"🔌 Connection closed (attempt {retries}/{max_retries}): {e}")
            await market_feed.disconnect()
            await asyncio.sleep(retry_delay)
        except Exception as e:
            retries += 1
            print(
                f"❌ Error in data processing (attempt {retries}/{max_retries}): {e}"
            )
            if retries == max_retries:
                print("❌ Max retries reached, exiting data processing.")
                raise
            await market_feed.disconnect()
            await asyncio.sleep(retry_delay)
    return False

try:
    print("🔌 Initiating WebSocket connection...")
    await market_feed.connect()
    print("✅ WebSocket connection established")
    while True:
        if order_placed:
            print(
                "✅ Order placed, stopping trading strategy. Restart script manually to continue."
            )
            break
        if not await on_data_received():
            print("✅ Order placed or session ended, stopping trading strategy.")
            break
        await asyncio.sleep(0.1)
except asyncio.CancelledError:
    print("⏹ Program interrupted")
except Exception as e:
    print(f"❌ Program terminated with error: {e}")
finally:
    try:
        if hasattr(market_feed, "ws") and market_feed.ws:
            await market_feed.disconnect()
            print("🔌 WebSocket connection closed")
    except Exception as e:
        print(f"❌ Error closing WebSocket: {e}")

Run the trading strategy

if name == “main”:
try:
asyncio.run(trading_strategy())
except KeyboardInterrupt:
print(“:stop_button: Program interrupted by user”)
except Exception as e:
print(f":x: Program terminated with error: {e}")

@Hardik let me know why I am getting this suddenly today only

I have removed v2 url in code as new people cannot paste in post

@Hardik The error is no close frame received or sent comes from the websockets library, which dhanhq uses under the hood.

@Hardik @Himangshu again today morning it was working now again stoped