Feeds
Live Order Updates
Real-time order status updates via WebSocket
Live Order Updates
The Live Order Update feed provides real-time notifications whenever an order status changes. Get instant updates on order execution, modification, cancellation, and rejection.
Accessing Live Order Updates
import { DhanFeed, DhanEnv } from 'dhan-ts';
const config = {
accessToken: process.env.DHAN_ACCESS_TOKEN!,
clientId: process.env.DHAN_CLIENT_ID!,
env: DhanEnv.PROD,
};
const feed = new DhanFeed(config);
const orderFeed = feed.liveOrderUpdate;Methods
Connect
Establish WebSocket connection for order updates.
async connect(): Promise<void>Example
async function connectToOrderUpdates() {
try {
await orderFeed.connect();
console.log('Connected to order updates');
} catch (error) {
console.error('Connection error:', error);
}
}Disconnect
Close the connection.
disconnect(): voidExample
orderFeed.disconnect();
console.log('Disconnected from order updates');Events
orderUpdate
Emitted when an order status changes.
orderFeed.on('orderUpdate', (update: LiveOrderUpdate) => {
const data = update.Data;
console.log('Order ID:', data.orderNo);
console.log('Symbol:', data.symbol);
console.log('Status:', data.status);
console.log('Transaction Type:', data.txnType);
console.log('Quantity:', data.quantity);
console.log('Traded Qty:', data.tradedQty);
console.log('Price:', data.price);
console.log('Avg Traded Price:', data.avgTradedPrice);
console.log('Remarks:', data.remarks);
});authenticated
Emitted when authentication succeeds.
orderFeed.on('authenticated', () => {
console.log('Successfully authenticated for order updates');
});authError
Emitted when authentication fails.
orderFeed.on('authError', (error: Error) => {
console.error('Authentication failed:', error);
});error
Emitted on connection or data errors.
orderFeed.on('error', (error: Error) => {
console.error('Error:', error);
});disconnected
Emitted when connection is lost.
orderFeed.on('disconnected', (data: { code: number; reason: string }) => {
console.log('Disconnected:', data.reason);
console.log('Code:', data.code);
});TypeScript Types
LiveOrderUpdate
interface LiveOrderUpdate {
Data: {
exchange: string;
segment: string;
source: string;
securityId: string;
clientId: string;
exchOrderNo: string;
orderNo: string;
product: string;
txnType: string; // BUY or SELL
orderType: string;
validity: string;
discQuantity: number;
discQtyRem: number;
remainingQuantity: number;
quantity: number;
tradedQty: number;
price: number;
triggerPrice: number;
tradedPrice: number;
avgTradedPrice: number;
algoOrdNo: string;
offMktFlag: string;
orderDateTime: string;
exchOrderTime: string;
lastUpdatedTime: string;
remarks: string;
mktType: string;
reasonDescription: string;
legNo: number;
instrument: string;
symbol: string;
productName: string;
status: string; // Order status
lotSize: number;
strikePrice: number;
expiryDate: string;
optType: string;
displayName: string;
isin: string;
series: string;
goodTillDaysDate: string;
refLtp: number;
tickSize: number;
algoId: string;
multiplier: number;
};
Type: string; // "order_alert"
}Complete Example
import { DhanFeed, DhanHqClient, DhanEnv } from 'dhan-ts';
async function trackOrderExecution() {
const config = {
accessToken: process.env.DHAN_ACCESS_TOKEN!,
clientId: process.env.DHAN_CLIENT_ID!,
env: DhanEnv.PROD,
};
const client = new DhanHqClient(config);
const feed = new DhanFeed(config);
const orderFeed = feed.liveOrderUpdate;
// Connect to order update feed
await orderFeed.connect();
// Track order execution
orderFeed.on('orderUpdate', (update) => {
const data = update.Data;
console.log(`\nOrder Update: ${data.orderNo}`);
console.log(`Symbol: ${data.symbol}`);
console.log(`Status: ${data.status}`);
console.log(`Traded: ${data.tradedQty}/${data.quantity}`);
if (data.status === 'TRADED') {
console.log(`✓ Order fully executed at ₹${data.avgTradedPrice}`);
} else if (data.status === 'REJECTED') {
console.log(`✗ Order rejected: ${data.reasonDescription}`);
} else if (data.status === 'PART_TRADED') {
console.log(`⚡ Partial fill: ${data.tradedQty} executed`);
}
});
// Place an order
const orderRequest = {
dhanClientId: config.clientId,
transactionType: 'BUY',
exchangeSegment: 'NSE_EQ',
productType: 'INTRADAY',
orderType: 'LIMIT',
validity: 'DAY',
securityId: '1333',
quantity: 1,
price: 1850.00,
afterMarketOrder: false,
};
const response = await client.orders.placeOrder(orderRequest);
console.log('Order placed:', response.orderId);
// Keep running to receive updates
process.on('SIGINT', () => {
orderFeed.disconnect();
process.exit();
});
}
trackOrderExecution();Common Patterns
Order Execution Tracker
const orderTracking = new Map<string, {
placed: Date;
status: string;
fills: number[];
}>();
orderFeed.on('orderUpdate', (update) => {
const data = update.Data;
const orderId = data.orderNo;
if (!orderTracking.has(orderId)) {
orderTracking.set(orderId, {
placed: new Date(),
status: data.status,
fills: [],
});
}
const tracking = orderTracking.get(orderId)!;
tracking.status = data.status;
if (data.tradedQty > 0) {
tracking.fills.push(data.tradedPrice);
}
if (data.status === 'TRADED') {
const executionTime = Date.now() - tracking.placed.getTime();
console.log(`Order ${orderId} executed in ${executionTime}ms`);
console.log(`Avg Price: ₹${data.avgTradedPrice}`);
}
});Auto-notification System
async function sendNotification(message: string) {
// Send SMS/Email/Push notification
console.log('NOTIFICATION:', message);
}
orderFeed.on('orderUpdate', (update) => {
const data = update.Data;
switch (data.status) {
case 'TRADED':
sendNotification(
`Order executed: ${data.symbol} ${data.txnType} ${data.quantity} @ ₹${data.avgTradedPrice}`
);
break;
case 'REJECTED':
sendNotification(
`Order rejected: ${data.symbol} - ${data.reasonDescription}`
);
break;
case 'CANCELLED':
sendNotification(
`Order cancelled: ${data.symbol} ${data.orderNo}`
);
break;
}
});Order Fill Rate Monitor
const fillStats = {
total: 0,
filled: 0,
partial: 0,
rejected: 0,
};
orderFeed.on('orderUpdate', (update) => {
const data = update.Data;
if (data.status === 'TRADED') {
fillStats.total++;
fillStats.filled++;
} else if (data.status === 'PART_TRADED') {
fillStats.total++;
fillStats.partial++;
} else if (data.status === 'REJECTED') {
fillStats.total++;
fillStats.rejected++;
}
const fillRate = (fillStats.filled / fillStats.total) * 100;
console.log(`Fill Rate: ${fillRate.toFixed(2)}%`);
});Features
Automatic Reconnection
- Retries up to 10 times on connection loss
- Exponential backoff with jitter
- Automatic re-authentication after reconnection
Heartbeat Monitoring
- Sends ping every 5 seconds
- Detects dead connections (no pong for 40s)
- Automatic reconnection on connection death
Event-driven Architecture
- Non-blocking, event-based updates
- Multiple listeners per event
- Clean disconnect handling
Best Practices
- Connect before placing orders to avoid missing updates
- Handle all event types (authenticated, error, disconnected)
- Implement retry logic for critical operations
- Log order updates for audit trail
- Monitor connection health via heartbeat events
- Clean disconnect when shutting down
- Handle partial fills appropriately
Order updates are sent in real-time. The feed will notify you of every status change, including modifications, partial fills, and rejections.
Order Status Flow
PENDING → TRANSIT → [TRIGGERED] → PART_TRADED → TRADED
↓
REJECTED
↓
CANCELLEDRelated APIs
- Orders API - Place and manage orders
- Live Feed - Real-time market data
- Portfolio API - View positions after execution