Api reference
Portfolio API
View holdings, positions, and convert positions between product types
Portfolio API
The Portfolio API provides access to your holdings, positions, and allows you to convert positions between different product types.
Accessing the Portfolio API
import { DhanHqClient, DhanEnv } from 'dhan-ts';
const client = new DhanHqClient({
accessToken: process.env.DHAN_ACCESS_TOKEN!,
clientId: process.env.DHAN_CLIENT_ID!,
env: DhanEnv.PROD,
});
const portfolio = client.portfolio;Methods
Get Holdings
Retrieve all your holdings (long-term investments).
async getHoldings(): Promise<HoldingsResponse[]>Example
async function viewHoldings() {
try {
const holdings = await client.portfolio.getHoldings();
holdings.forEach(holding => {
console.log(`Symbol: ${holding.tradingSymbol}`);
console.log(`Exchange: ${holding.exchange}`);
console.log(`Total Quantity: ${holding.totalQty}`);
console.log(`Available Quantity: ${holding.availableQty}`);
console.log(`Average Cost: ₹${holding.avgCostPrice}`);
console.log(`ISIN: ${holding.isin}`);
console.log('---');
});
} catch (error) {
console.error('Error fetching holdings:', error);
}
}Get Positions
Retrieve all open positions for the day.
async getPositions(): Promise<PositionResponse[]>Example
async function viewPositions() {
try {
const positions = await client.portfolio.getPositions();
positions.forEach(position => {
console.log(`Symbol: ${position.tradingSymbol}`);
console.log(`Position Type: ${position.positionType}`);
console.log(`Product Type: ${position.productType}`);
console.log(`Net Quantity: ${position.netQty}`);
console.log(`Buy Avg: ₹${position.buyAvg}`);
console.log(`Sell Avg: ₹${position.sellAvg}`);
console.log(`Realized P&L: ₹${position.realizedProfit}`);
console.log(`Unrealized P&L: ₹${position.unrealizedProfit}`);
console.log('---');
});
} catch (error) {
console.error('Error fetching positions:', error);
}
}Convert Position
Convert a position from one product type to another (e.g., INTRADAY to CNC).
async convertPosition(request: ConvertPositionRequest): Promise<OrderResponse>Example
import { ProductType, PositionType, ExchangeSegment } from 'dhan-ts';
async function convertIntradayToDelivery() {
try {
const convertRequest = {
dhanClientId: 'your-client-id',
fromProductType: ProductType.INTRADAY,
toProductType: ProductType.CNC,
exchangeSegment: ExchangeSegment.NSE_EQ,
positionType: PositionType.LONG,
securityId: '1333',
tradingSymbol: 'RELIANCE',
convertQty: 10,
};
const response = await client.portfolio.convertPosition(convertRequest);
console.log('Conversion Order ID:', response.orderId);
console.log('Status:', response.orderStatus);
} catch (error) {
console.error('Error converting position:', error);
}
}Position conversion must be done before market close. You can convert INTRADAY positions to CNC (delivery) to avoid square-off.
TypeScript Types
HoldingsResponse
interface HoldingsResponse {
exchange: string;
tradingSymbol: string;
securityId: string;
isin: string;
totalQty: number;
dpQty: number; // Demat quantity
t1Qty: number; // T+1 quantity
availableQty: number; // Available for trading
collateralQty: number; // Pledged as collateral
avgCostPrice: number;
}PositionResponse
interface PositionResponse {
dhanClientId: string;
tradingSymbol: string;
securityId: string;
positionType: PositionType;
exchangeSegment: ExchangeSegment;
productType: ProductType;
buyAvg: number;
buyQty: number;
sellAvg: number;
sellQty: number;
netQty: number;
realizedProfit: number;
unrealizedProfit: number;
rbiReferenceRate: number;
multiplier: number;
carryForwardBuyQty: number;
carryForwardSellQty: number;
carryForwardBuyValue: number;
carryForwardSellValue: number;
dayBuyQty: number;
daySellQty: number;
dayBuyValue: number;
daySellValue: number;
drvExpiryDate?: string;
drvOptionType?: DrvOptionType;
drvStrikePrice?: number;
crossCurrency: boolean;
}ConvertPositionRequest
interface ConvertPositionRequest {
dhanClientId: string;
fromProductType: ProductType;
toProductType: ProductType;
exchangeSegment: ExchangeSegment;
positionType: PositionType;
securityId: string;
tradingSymbol: string;
convertQty: number;
}Enums
PositionType
enum PositionType {
LONG = "LONG",
SHORT = "SHORT",
CLOSED = "CLOSED",
}Common Patterns
Calculate Total P&L
async function calculateTotalPnL() {
const positions = await client.portfolio.getPositions();
const totalRealized = positions.reduce(
(sum, pos) => sum + pos.realizedProfit,
0
);
const totalUnrealized = positions.reduce(
(sum, pos) => sum + pos.unrealizedProfit,
0
);
console.log(`Total Realized P&L: ₹${totalRealized}`);
console.log(`Total Unrealized P&L: ₹${totalUnrealized}`);
console.log(`Total P&L: ₹${totalRealized + totalUnrealized}`);
}Get Holdings Value
async function calculateHoldingsValue() {
const holdings = await client.portfolio.getHoldings();
const totalInvestment = holdings.reduce(
(sum, holding) => sum + (holding.avgCostPrice * holding.totalQty),
0
);
console.log(`Total Investment: ₹${totalInvestment.toFixed(2)}`);
}Auto-convert Intraday Positions
async function autoConvertIntradayPositions() {
const positions = await client.portfolio.getPositions();
const intradayLongPositions = positions.filter(
pos =>
pos.productType === ProductType.INTRADAY &&
pos.positionType === PositionType.LONG &&
pos.netQty > 0
);
for (const position of intradayLongPositions) {
try {
const response = await client.portfolio.convertPosition({
dhanClientId: 'your-client-id',
fromProductType: ProductType.INTRADAY,
toProductType: ProductType.CNC,
exchangeSegment: position.exchangeSegment,
positionType: PositionType.LONG,
securityId: position.securityId,
tradingSymbol: position.tradingSymbol,
convertQty: position.netQty,
});
console.log(`Converted ${position.tradingSymbol}: ${response.orderId}`);
} catch (error) {
console.error(`Failed to convert ${position.tradingSymbol}:`, error);
}
}
}Best Practices
- Fetch positions regularly to monitor real-time P&L
- Convert positions before market close to avoid auto square-off charges
- Verify available quantity in holdings before selling
- Track T+1 holdings separately as they cannot be sold immediately
- Monitor collateral quantity if you've pledged securities
- Use position type filters to separate long and short positions
- Calculate net P&L including both realized and unrealized profits
Related APIs
- Orders API - Place orders based on portfolio
- Funds API - Check fund requirements for position conversion
- Market Data - Get current prices for P&L calculation