The official Python client for communicating with the Upstox API, providing complete trading and investment platform functionality.
Manage portfolio positions, holdings, conversions between product types, and comprehensive profit & loss analysis with historical trade data.
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
"""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}%)")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
"""# 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")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
"""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}")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
"""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}")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
"""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}")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"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"EQ" - Equity (Cash market)"FO" - Futures & Options"COM" - Commodity"CD" - Currency Derivatives# 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'
)# 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')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