CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-upstox-python-sdk

The official Python client for communicating with the Upstox API, providing complete trading and investment platform functionality.

Overview
Eval results
Files

portfolio-management.mddocs/

Portfolio Management

Manage portfolio positions, holdings, conversions between product types, and comprehensive profit & loss analysis with historical trade data.

Capabilities

Holdings Management

Access current stock holdings in your demat account.

def get_holdings(api_version: str) -> GetHoldingsResponse:
    """
    Retrieve current holdings in demat account.
    
    Parameters:
    - api_version: API version ('2.0')
    
    Returns:
    GetHoldingsResponse with holdings data
    """

Usage Example

from upstox_client.api import PortfolioApi
from upstox_client import Configuration, ApiClient

# Setup
config = Configuration()
config.access_token = 'your_access_token'
api_client = ApiClient(config)
portfolio_api = PortfolioApi(api_client)

# Get holdings
holdings_response = portfolio_api.get_holdings(api_version='2.0')

print("Current Holdings:")
total_investment = 0
total_current_value = 0

for holding in holdings_response.data:
    investment = holding.average_price * holding.quantity
    current_value = holding.last_price * holding.quantity
    pnl = current_value - investment
    pnl_percent = (pnl / investment) * 100 if investment > 0 else 0
    
    total_investment += investment
    total_current_value += current_value
    
    print(f"{holding.tradingsymbol}:")
    print(f"  Quantity: {holding.quantity}")
    print(f"  Avg Price: ₹{holding.average_price:.2f}")
    print(f"  Current Price: ₹{holding.last_price:.2f}")
    print(f"  Investment: ₹{investment:.2f}")
    print(f"  Current Value: ₹{current_value:.2f}")
    print(f"  P&L: ₹{pnl:.2f} ({pnl_percent:.2f}%)")
    print(f"  T1 Quantity: {holding.t1_quantity}")
    print()

total_pnl = total_current_value - total_investment
total_pnl_percent = (total_pnl / total_investment) * 100 if total_investment > 0 else 0

print(f"Portfolio Summary:")
print(f"Total Investment: ₹{total_investment:.2f}")
print(f"Current Value: ₹{total_current_value:.2f}")
print(f"Total P&L: ₹{total_pnl:.2f} ({total_pnl_percent:.2f}%)")

Position Management

Access and manage open trading positions.

def get_positions(api_version: str) -> GetPositionResponse:
    """
    Retrieve current trading positions.
    
    Parameters:
    - api_version: API version ('2.0')
    
    Returns:
    GetPositionResponse with position data
    """

def get_mtf_positions() -> GetPositionResponse:
    """
    Get Margin Trading Facility (MTF) positions.
    
    Returns:
    GetPositionResponse with MTF position data
    """

Usage Example

# Get all positions
positions_response = portfolio_api.get_positions(api_version='2.0')

print("Current Positions:")
for position in positions_response.data:
    if position.quantity != 0:  # Only show non-zero positions
        print(f"{position.tradingsymbol} ({position.exchange}):")
        print(f"  Net Quantity: {position.quantity}")
        print(f"  Product: {position.product}")
        print(f"  Buy Quantity: {position.buy_quantity}, Avg: ₹{position.buy_price:.2f}")
        print(f"  Sell Quantity: {position.sell_quantity}, Avg: ₹{position.sell_price:.2f}")
        print(f"  Last Price: ₹{position.last_price:.2f}")
        print(f"  Unrealized P&L: ₹{position.unrealised:.2f}")
        print(f"  Realized P&L: ₹{position.realised:.2f}")
        print(f"  Day P&L: ₹{position.day_buy_value - position.day_sell_value:.2f}")
        print()

# Get MTF positions
mtf_positions = portfolio_api.get_mtf_positions()
print(f"MTF Positions: {len(mtf_positions.data)} positions")

Position Conversion

Convert positions between different product types (Intraday, Delivery, Margin).

def convert_positions(body: ConvertPositionRequest, api_version: str) -> ConvertPositionResponse:
    """
    Convert position from one product type to another.
    
    Parameters:
    - body: Conversion request parameters
    - api_version: API version ('2.0')
    
    Returns:
    ConvertPositionResponse with conversion status
    """

Usage Example

from upstox_client.models import ConvertPositionRequest

# Convert intraday position to delivery
convert_request = ConvertPositionRequest(
    instrument_token="NSE_EQ|INE002A01018",  # Reliance
    new_product="D",  # Delivery
    old_product="I",  # From Intraday
    transaction_type="BUY",
    quantity=10
)

convert_response = portfolio_api.convert_positions(
    convert_request, 
    api_version='2.0'
)

print(f"Position converted: {convert_response.status}")
for result in convert_response.data:
    print(f"Symbol: {result.instrument_token}")
    print(f"Status: {result.status}")
    print(f"Message: {result.message}")

Profit & Loss Analysis

Comprehensive P&L analysis with charges breakdown and trade-wise details.

def get_profit_and_loss_charges(segment: str, financial_year: str, api_version: str) -> GetProfitAndLossChargesResponse:
    """
    Get profit & loss summary with charges breakdown.
    
    Parameters:
    - segment: Market segment ('EQ', 'FO', 'COM')
    - financial_year: Financial year in YYYY-YY format (e.g., '2024-25')
    - api_version: API version ('2.0')
    
    Returns:
    GetProfitAndLossChargesResponse with P&L and charges
    """

def get_trade_wise_profit_and_loss_data(segment: str, financial_year: str, page_number: str, page_size: str, api_version: str) -> GetTradeWiseProfitAndLossDataResponse:
    """
    Get detailed trade-wise profit & loss data.
    
    Parameters:
    - segment: Market segment ('EQ', 'FO', 'COM')
    - financial_year: Financial year in YYYY-YY format
    - page_number: Page number for pagination
    - page_size: Number of records per page
    - api_version: API version ('2.0')
    
    Returns:
    GetTradeWiseProfitAndLossDataResponse with trade-wise P&L
    """

def get_trade_wise_profit_and_loss_meta_data(segment: str, financial_year: str, api_version: str) -> GetTradeWiseProfitAndLossMetaDataResponse:
    """
    Get metadata for trade-wise P&L report.
    
    Parameters:
    - segment: Market segment ('EQ', 'FO', 'COM')
    - financial_year: Financial year in YYYY-YY format
    - api_version: API version ('2.0')
    
    Returns:
    GetTradeWiseProfitAndLossMetaDataResponse with P&L metadata
    """

Usage Example

from upstox_client.api import TradeProfitAndLossApi

pnl_api = TradeProfitAndLossApi(api_client)

# Get P&L charges summary
pnl_charges = pnl_api.get_profit_and_loss_charges(
    segment='EQ',
    financial_year='2024-25',
    api_version='2.0'
)

charges_data = pnl_charges.data
print("P&L Summary with Charges:")
print(f"Gross P&L: ₹{charges_data.total_profit_and_loss:.2f}")
print(f"Brokerage: ₹{charges_data.total_brokerage:.2f}")
print(f"Taxes: ₹{charges_data.total_taxes:.2f}")
print(f"Net P&L: ₹{charges_data.net_profit_and_loss:.2f}")

# Get trade-wise P&L data
trade_pnl = pnl_api.get_trade_wise_profit_and_loss_data(
    segment='EQ',
    financial_year='2024-25',
    page_number='1',
    page_size='50',
    api_version='2.0'
)

print("\nTrade-wise P&L:")
for trade in trade_pnl.data:
    print(f"{trade.tradingsymbol}:")
    print(f"  Buy: {trade.buy_quantity} @ ₹{trade.buy_average:.2f}")
    print(f"  Sell: {trade.sell_quantity} @ ₹{trade.sell_average:.2f}")
    print(f"  Gross P&L: ₹{trade.gross_profit_and_loss:.2f}")
    print(f"  Charges: ₹{trade.charges:.2f}")
    print(f"  Net P&L: ₹{trade.net_profit_and_loss:.2f}")
    print()

# Get P&L metadata
pnl_metadata = pnl_api.get_trade_wise_profit_and_loss_meta_data(
    segment='EQ',
    financial_year='2024-25',
    api_version='2.0'
)

print(f"Total Records: {pnl_metadata.data.total_records}")
print(f"Total Pages: {pnl_metadata.data.total_pages}")

Historical Trade Data

Access historical trade data by date range for analysis and reporting.

def get_trades_by_date_range(start_date: str, end_date: str, page_number: int, page_size: int, segment: str = None) -> TradeHistoryResponse:
    """
    Get historical trade data for a date range.
    
    Parameters:
    - start_date: Start date in YYYY-MM-DD format (required)
    - end_date: End date in YYYY-MM-DD format (required)
    - page_number: Page number for pagination (required)
    - page_size: Number of records per page (required)
    - segment: Market segment ('EQ', 'FO', 'COM', 'CD', 'MF') (optional)
    
    Returns:
    TradeHistoryResponse with historical trade data
    """

Usage Example

from upstox_client.api import PostTradeApi

post_trade_api = PostTradeApi(api_client)

# Get trades for last month
trade_history = post_trade_api.get_trades_by_date_range(
    start_date='2024-08-01',
    end_date='2024-08-31',
    page_number='1',
    page_size='100'
)

print("Trade History:")
for trade in trade_history.data.trades:
    print(f"{trade.trade_date} - {trade.tradingsymbol}:")
    print(f"  {trade.transaction_type} {trade.quantity} @ ₹{trade.price:.2f}")
    print(f"  Value: ₹{trade.trade_value:.2f}")
    print(f"  Charges: ₹{trade.charges:.2f}")
    print()

print(f"Page: {trade_history.data.page_details.page_number}")
print(f"Total Pages: {trade_history.data.page_details.total_pages}")
print(f"Total Records: {trade_history.data.page_details.total_records}")

Request/Response Types

class ConvertPositionRequest:
    instrument_token: str  # Instrument to convert
    new_product: str  # Target product type ('I', 'D', 'M')
    old_product: str  # Current product type ('I', 'D', 'M')
    transaction_type: str  # 'BUY' or 'SELL'
    quantity: int  # Quantity to convert

class GetHoldingsResponse:
    status: str
    data: list[HoldingsData]

class HoldingsData:
    instrument_token: str
    isin: str  # ISIN code
    cnc_used_quantity: int  # CNC used quantity
    collateral_type: str  # Collateral classification
    company_name: str
    haircut: float  # Haircut percentage for collateral
    exchange: str
    instrument_type: str
    product: str
    quantity: int  # Total quantity
    tradingsymbol: str
    last_price: float  # Current market price
    close_price: float  # Previous day close
    average_price: float  # Average purchase price
    collateral_quantity: int  # Quantity pledged as collateral
    collateral_update_quantity: int
    t1_quantity: int  # T+1 settlement quantity
    pnl: float  # Profit & Loss

class GetPositionResponse:
    status: str
    data: list[PositionData]

class PositionData:
    exchange: str
    instrument_token: str
    tradingsymbol: str
    product: str
    quantity: int  # Net quantity (buy - sell)
    buy_quantity: int
    sell_quantity: int
    buy_price: float  # Average buy price
    sell_price: float  # Average sell price
    last_price: float  # Current market price
    unrealised: float  # Unrealized P&L
    realised: float  # Realized P&L
    multiplier: int  # Contract multiplier
    buy_value: float  # Total buy value
    sell_value: float  # Total sell value
    day_buy_quantity: int  # Day's buy quantity
    day_sell_quantity: int  # Day's sell quantity
    day_buy_price: float  # Day's average buy price
    day_sell_price: float  # Day's average sell price
    day_buy_value: float  # Day's buy value
    day_sell_value: float  # Day's sell value

class ConvertPositionResponse:
    status: str
    data: list[ConvertPositionData]

class ConvertPositionData:
    instrument_token: str
    status: str
    message: str

class GetProfitAndLossChargesResponse:
    status: str
    data: ProfitAndLossChargesWrapperData

class ProfitAndLossChargesWrapperData:
    total_profit_and_loss: float
    total_brokerage: float
    total_taxes: float
    net_profit_and_loss: float
    data: list[ProfitAndLossChargesData]

class ProfitAndLossChargesData:
    segment: str
    charges: ProfitAndLossChargesTaxes
    profit_and_loss: float

class ProfitAndLossChargesTaxes:
    brokerage: float
    stt: float  # Securities Transaction Tax
    exchange_charges: float
    clearing_charges: float
    gst: float  # Goods & Services Tax
    sebi_charges: float
    stamp_duty: float

class GetTradeWiseProfitAndLossDataResponse:
    status: str
    data: list[TradeWiseProfitAndLossData]

class TradeWiseProfitAndLossData:
    instrument_token: str
    tradingsymbol: str
    buy_quantity: int
    sell_quantity: int
    buy_average: float
    sell_average: float
    gross_profit_and_loss: float
    charges: float
    net_profit_and_loss: float
    trade_date: str

class TradeHistoryResponse:
    status: str
    data: TradeHistoryResponsePageData

class TradeHistoryResponsePageData:
    page_details: TradeHistoryResponseMetaData
    trades: list[TradeHistoryResponseTradeData]

class TradeHistoryResponseMetaData:
    total_records: int
    total_pages: int
    page_number: int
    page_size: int

class TradeHistoryResponseTradeData:
    exchange: str
    instrument_token: str
    tradingsymbol: str
    trade_id: str
    order_id: str
    trade_date: str
    trade_time: str
    transaction_type: str  # 'BUY' or 'SELL'
    quantity: int
    price: float
    trade_value: float
    charges: float

Product Types

Position Product Types

  • "I" - Intraday: Square off before market close
  • "D" - Delivery: Hold for delivery (CNC)
  • "M" - Margin: Margin trading positions
  • "CO" - Cover Order: Intraday with compulsory stop loss
  • "BO" - Bracket Order: Intraday with target and stop loss

Market Segments

  • "EQ" - Equity (Cash market)
  • "FO" - Futures & Options
  • "COM" - Commodity
  • "CD" - Currency Derivatives

Common Workflows

Daily Portfolio Review

# 1. Check holdings performance
holdings = portfolio_api.get_holdings(api_version='2.0')

# 2. Review open positions
positions = portfolio_api.get_positions(api_version='2.0')

# 3. Analyze P&L for current financial year
pnl_data = pnl_api.get_profit_and_loss_charges(
    segment='EQ', 
    financial_year='2024-25', 
    api_version='2.0'
)

Position Management

# 1. Convert intraday to delivery before market close
convert_request = ConvertPositionRequest(
    instrument_token="NSE_EQ|INE002A01018",
    new_product="D",  # Convert to delivery
    old_product="I",  # From intraday
    transaction_type="BUY",
    quantity=10
)

# 2. Execute conversion
conversion = portfolio_api.convert_positions(convert_request, api_version='2.0')

Risk Management

Monitor portfolio exposure, P&L, and positions to manage risk effectively:

# Calculate portfolio metrics
total_exposure = sum(abs(pos.buy_value - pos.sell_value) for pos in positions_data)
unrealized_pnl = sum(pos.unrealised for pos in positions_data)
day_pnl = sum(pos.day_buy_value - pos.day_sell_value for pos in positions_data)

print(f"Total Exposure: ₹{total_exposure:.2f}")
print(f"Unrealized P&L: ₹{unrealized_pnl:.2f}")
print(f"Day P&L: ₹{day_pnl:.2f}")

Install with Tessl CLI

npx tessl i tessl/pypi-upstox-python-sdk

docs

authentication.md

charges-analytics.md

index.md

market-data.md

order-management.md

portfolio-management.md

websocket-streaming.md

tile.json