The official Python client for communicating with the Upstox API, providing complete trading and investment platform functionality.
Calculate brokerage charges, required margins, access market timings and holidays information, and analyze trading costs for informed decision making.
Calculate brokerage charges and fees for trades before execution.
def get_brokerage(instrument_token: str, quantity: int, product: str, transaction_type: str, price: float, api_version: str) -> GetBrokerageResponse:
"""
Calculate brokerage charges for a trade.
Parameters:
- instrument_token: Instrument identifier
- quantity: Number of shares/units
- product: Product type ('I', 'D', 'M', 'CO', 'BO')
- transaction_type: 'BUY' or 'SELL'
- price: Trade price
- api_version: API version ('2.0')
Returns:
GetBrokerageResponse with detailed charge breakdown
"""from upstox_client.api import ChargeApi
from upstox_client import Configuration, ApiClient
# Setup
config = Configuration()
config.access_token = 'your_access_token'
api_client = ApiClient(config)
charge_api = ChargeApi(api_client)
# Calculate brokerage for a trade
brokerage_response = charge_api.get_brokerage(
instrument_token="NSE_EQ|INE002A01018", # Reliance
quantity=100,
product="D", # Delivery
transaction_type="BUY",
price=1500.0,
api_version='2.0'
)
charges = brokerage_response.data
print("Trade Cost Breakdown:")
print(f"Trade Value: ₹{100 * 1500:.2f}")
print(f"Brokerage: ₹{charges.brokerage:.2f}")
print(f"STT: ₹{charges.stt:.2f}")
print(f"Exchange Charges: ₹{charges.exchange_charges:.2f}")
print(f"GST: ₹{charges.gst:.2f}")
print(f"SEBI Charges: ₹{charges.sebi_charges:.2f}")
print(f"Stamp Duty: ₹{charges.stamp_duty:.2f}")
print(f"Total Charges: ₹{charges.total_charges:.2f}")
print(f"Net Amount: ₹{charges.total_charges + (100 * 1500):.2f}")
# Calculate for different scenarios
scenarios = [
{"product": "I", "description": "Intraday"},
{"product": "D", "description": "Delivery"},
{"product": "M", "description": "Margin"}
]
print("\nCharge Comparison:")
for scenario in scenarios:
response = charge_api.get_brokerage(
instrument_token="NSE_EQ|INE002A01018",
quantity=100,
product=scenario["product"],
transaction_type="BUY",
price=1500.0,
api_version='2.0'
)
charges = response.data
print(f"{scenario['description']}: ₹{charges.total_charges:.2f}")Calculate required margin for trades and positions.
def post_margin(body: MarginRequest) -> PostMarginResponse:
"""
Calculate required margin for trades.
Parameters:
- body: Margin calculation request with trade details
Returns:
PostMarginResponse with margin requirements
"""from upstox_client.models import MarginRequest
# Calculate margin for multiple orders
margin_request = MarginRequest(
instruments=[
{
"instrument_token": "NSE_EQ|INE002A01018",
"quantity": 100,
"price": 1500.0,
"product": "M", # Margin product
"transaction_type": "BUY"
},
{
"instrument_token": "NSE_EQ|INE009A01021",
"quantity": 50,
"price": 3000.0,
"product": "M",
"transaction_type": "BUY"
}
]
)
margin_response = charge_api.post_margin(margin_request)
print("Margin Requirements:")
for instrument_margin in margin_response.data:
print(f"Instrument: {instrument_margin.instrument_token}")
print(f" Required Margin: ₹{instrument_margin.required_margin:.2f}")
print(f" Available Margin: ₹{instrument_margin.available_margin:.2f}")
print(f" Used Margin: ₹{instrument_margin.used_margin:.2f}")
print(f" Margin Shortfall: ₹{max(0, instrument_margin.required_margin - instrument_margin.available_margin):.2f}")
print()
print(f"Total Required Margin: ₹{sum(m.required_margin for m in margin_response.data):.2f}")Access market schedules, trading hours, and current market status.
def get_market_status(exchange: str) -> GetMarketStatusResponse:
"""
Get current market status for an exchange.
Parameters:
- exchange: Exchange name ('NSE', 'BSE', 'MCX', 'NCDEX')
Returns:
GetMarketStatusResponse with current market status
"""
def get_exchange_timings(date: str) -> GetExchangeTimingResponse:
"""
Get exchange trading timings for a specific date.
Parameters:
- date: Date in YYYY-MM-DD format
Returns:
GetExchangeTimingResponse with trading hours
"""from upstox_client.api import MarketHolidaysAndTimingsApi
from datetime import datetime
timing_api = MarketHolidaysAndTimingsApi(api_client)
# Check current market status
exchanges = ['NSE', 'BSE', 'MCX', 'NCDEX']
print("Current Market Status:")
for exchange in exchanges:
status_response = timing_api.get_market_status(exchange)
for segment in status_response.data:
print(f"{exchange} {segment.segment}: {segment.status}")
if segment.status == 'open':
print(f" Trading until: {segment.end_time}")
elif segment.status == 'close':
print(f" Next opening: {segment.start_time}")
# Get trading timings for today
today = datetime.now().strftime('%Y-%m-%d')
timing_response = timing_api.get_exchange_timings(today)
print(f"\nTrading Timings for {today}:")
for timing in timing_response.data:
print(f"{timing.exchange} {timing.segment}:")
print(f" Pre-open: {timing.pre_open_start} - {timing.pre_open_end}")
print(f" Normal: {timing.market_open} - {timing.market_close}")
if timing.post_close_start:
print(f" Post-close: {timing.post_close_start} - {timing.post_close_end}")Access market holiday information and trading calendar.
def get_holidays() -> GetHolidayResponse:
"""
Get list of all market holidays.
Returns:
GetHolidayResponse with holiday calendar
"""
def get_holiday(date: str) -> GetHolidayResponse:
"""
Check if a specific date is a market holiday.
Parameters:
- date: Date in YYYY-MM-DD format
Returns:
GetHolidayResponse with holiday status for the date
"""# Get all holidays for the year
holidays_response = timing_api.get_holidays()
print("Market Holidays:")
for holiday in holidays_response.data:
print(f"{holiday.date}: {holiday.description}")
print(f" Exchanges: {', '.join(holiday.exchanges)}")
print(f" Type: {holiday.holiday_type}")
print()
# Check specific date
check_date = "2024-10-02" # Gandhi Jayanti
holiday_check = timing_api.get_holiday(check_date)
if holiday_check.data:
print(f"{check_date} is a market holiday: {holiday_check.data[0].description}")
else:
print(f"{check_date} is a trading day")
# Get upcoming holidays (next 30 days)
from datetime import datetime, timedelta
today = datetime.now()
upcoming_holidays = []
for holiday in holidays_response.data:
holiday_date = datetime.strptime(holiday.date, '%Y-%m-%d')
if today <= holiday_date <= today + timedelta(days=30):
upcoming_holidays.append(holiday)
print("Upcoming holidays in next 30 days:")
for holiday in sorted(upcoming_holidays, key=lambda x: x.date):
print(f"{holiday.date}: {holiday.description}")Comprehensive analysis of trading costs across different scenarios.
def analyze_trading_costs(instrument_token, quantity, price):
"""Analyze trading costs across different product types and scenarios"""
products = [
("I", "Intraday"),
("D", "Delivery"),
("M", "Margin")
]
transactions = ["BUY", "SELL"]
print(f"Trading Cost Analysis for {quantity} shares @ ₹{price}")
print("=" * 60)
for product_code, product_name in products:
print(f"\n{product_name} ({product_code}):")
print("-" * 40)
total_buy_charges = 0
total_sell_charges = 0
for transaction in transactions:
response = charge_api.get_brokerage(
instrument_token=instrument_token,
quantity=quantity,
product=product_code,
transaction_type=transaction,
price=price,
api_version='2.0'
)
charges = response.data
if transaction == "BUY":
total_buy_charges = charges.total_charges
print(f" {transaction}: ₹{charges.total_charges:.2f}")
else:
total_sell_charges = charges.total_charges
print(f" {transaction}: ₹{charges.total_charges:.2f}")
total_charges = total_buy_charges + total_sell_charges
trade_value = quantity * price
cost_percentage = (total_charges / trade_value) * 100
print(f" Total Round-trip: ₹{total_charges:.2f} ({cost_percentage:.3f}%)")
print(f" Breakeven: ₹{price + (total_charges / quantity):.2f}")
# Analyze costs for different scenarios
analyze_trading_costs("NSE_EQ|INE002A01018", 100, 1500.0) # Reliance
analyze_trading_costs("NSE_EQ|INE009A01021", 50, 3000.0) # InfosysHelper functions for optimizing trading costs.
def find_optimal_quantity(instrument_token, price, max_cost_percentage=0.5):
"""Find optimal quantity to keep costs under specified percentage"""
quantities = [10, 25, 50, 100, 200, 500, 1000]
print(f"Cost optimization for trades under {max_cost_percentage}%:")
print("Quantity | Cost | Cost% | Breakeven")
print("-" * 40)
for qty in quantities:
buy_response = charge_api.get_brokerage(
instrument_token=instrument_token,
quantity=qty,
product="D", # Delivery
transaction_type="BUY",
price=price,
api_version='2.0'
)
sell_response = charge_api.get_brokerage(
instrument_token=instrument_token,
quantity=qty,
product="D",
transaction_type="SELL",
price=price,
api_version='2.0'
)
total_charges = buy_response.data.total_charges + sell_response.data.total_charges
trade_value = qty * price
cost_percentage = (total_charges / trade_value) * 100
breakeven = price + (total_charges / qty)
status = "✓" if cost_percentage <= max_cost_percentage else "✗"
print(f"{qty:8d} | {total_charges:5.2f} | {cost_percentage:5.3f}% | {breakeven:8.2f} {status}")
# find_optimal_quantity("NSE_EQ|INE002A01018", 1500.0, 0.3)class MarginRequest:
instruments: list[MarginInstrument]
class MarginInstrument:
instrument_token: str
quantity: int
price: float
product: str
transaction_type: str
class GetBrokerageResponse:
status: str
data: BrokerageData
class BrokerageData:
brokerage: float
stt: float # Securities Transaction Tax
exchange_charges: float
clearing_charges: float
gst: float # Goods & Services Tax
sebi_charges: float
stamp_duty: float
total_charges: float
class PostMarginResponse:
status: str
data: list[MarginData]
class MarginData:
instrument_token: str
required_margin: float
available_margin: float
used_margin: float
margin_utilization: float # Percentage of margin used
class GetMarketStatusResponse:
status: str
data: list[MarketStatusData]
class MarketStatusData:
exchange: str
segment: str # 'equity', 'derivative', 'commodity'
status: str # 'open', 'close', 'break', 'pre_open', 'post_close'
start_time: str # Next/current session start time
end_time: str # Current session end time
class GetExchangeTimingResponse:
status: str
data: list[ExchangeTimingData]
class ExchangeTimingData:
exchange: str
segment: str
pre_open_start: str # Pre-market start time
pre_open_end: str # Pre-market end time
market_open: str # Regular session start
market_close: str # Regular session end
post_close_start: str # Post-market start (if applicable)
post_close_end: str # Post-market end (if applicable)
is_trading_day: bool
class GetHolidayResponse:
status: str
data: list[HolidayData]
class HolidayData:
date: str # Holiday date in YYYY-MM-DD format
description: str # Holiday name/description
holiday_type: str # 'national', 'regional', 'exchange_specific'
exchanges: list[str] # Affected exchangesAccess expired futures and options contracts data and historical information for analysis.
class ExpiredInstrumentApi:
def get_expired_future_contracts(instrument_key: str, expiry_date: str) -> GetExpiredFuturesContractResponse:
"""
Get expired futures contracts for analysis.
Parameters:
- instrument_key: Instrument identifier
- expiry_date: Expiry date to filter contracts
Returns:
GetExpiredFuturesContractResponse with expired contract details
"""
def get_expired_option_contracts(instrument_key: str, expiry_date: str) -> GetExpiredOptionContractResponse:
"""
Get expired options contracts for analysis.
Parameters:
- instrument_key: Instrument identifier
- expiry_date: Expiry date to filter contracts
Returns:
GetExpiredOptionContractResponse with expired contract details
"""
def get_expired_historical_candle_data(expired_instrument_key: str, interval: str, to_date: str, from_date: str) -> GetHistoricalCandleResponse:
"""
Get historical candle data for expired contracts.
Parameters:
- expired_instrument_key: Key for expired instrument
- interval: Time interval ('1m', '5m', '1d', etc.)
- to_date: End date for data
- from_date: Start date for data
Returns:
GetHistoricalCandleResponse with candle data
"""
def get_expiries(instrument_key: str) -> GetExpiriesResponse:
"""
Get available expiry dates for an instrument.
Parameters:
- instrument_key: Instrument identifier
Returns:
GetExpiriesResponse with available expiry dates
"""import upstox_client
# Setup
configuration = upstox_client.Configuration()
configuration.access_token = 'your_access_token'
api_client = upstox_client.ApiClient(configuration)
expired_api = upstox_client.ExpiredInstrumentApi(api_client)
# Get expired futures for analysis
expired_futures = expired_api.get_expired_future_contracts(
instrument_key='NSE_FO|42965', # Nifty futures
expiry_date='2024-01-25'
)
# Analyze historical data for expired contract
historical_data = expired_api.get_expired_historical_candle_data(
expired_instrument_key='NSE_FO|42965',
interval='1d',
to_date='2024-01-25',
from_date='2024-01-01'
)
print(f"Found {len(historical_data.data.candles)} candles for analysis")# 1. Compare costs across product types before trading
def compare_costs(instrument_token, quantity, price):
products = ['I', 'D', 'M']
for product in products:
# Calculate and compare costs
pass
# 2. Consider minimum brokerage for small trades
def check_minimum_viable_quantity(instrument_token, price, min_profit_target):
# Calculate minimum quantity needed to overcome costs
pass
# 3. Plan for round-trip costs
def calculate_breakeven_price(buy_price, charges):
return buy_price + (charges / quantity)# Check market status before placing orders
status = timing_api.get_market_status('NSE')
if status.data[0].status == 'open':
# Place order
pass
else:
print(f"Market closed. Next opening: {status.data[0].start_time}")
# Avoid trading on holidays
if not timing_api.get_holiday(trade_date).data:
# Safe to trade
pass# Calculate total margin requirement before trading
total_margin_required = sum(
calculate_margin(instrument, quantity, price)
for instrument, quantity, price in planned_trades
)
if total_margin_required <= available_margin:
# Execute trades
pass
else:
print(f"Insufficient margin. Required: ₹{total_margin_required}")Install with Tessl CLI
npx tessl i tessl/pypi-upstox-python-sdk