0
# Charges & Analytics
1
2
Calculate brokerage charges, required margins, access market timings and holidays information, and analyze trading costs for informed decision making.
3
4
## Capabilities
5
6
### Brokerage Calculation
7
8
Calculate brokerage charges and fees for trades before execution.
9
10
```python { .api }
11
def get_brokerage(instrument_token: str, quantity: int, product: str, transaction_type: str, price: float, api_version: str) -> GetBrokerageResponse:
12
"""
13
Calculate brokerage charges for a trade.
14
15
Parameters:
16
- instrument_token: Instrument identifier
17
- quantity: Number of shares/units
18
- product: Product type ('I', 'D', 'M', 'CO', 'BO')
19
- transaction_type: 'BUY' or 'SELL'
20
- price: Trade price
21
- api_version: API version ('2.0')
22
23
Returns:
24
GetBrokerageResponse with detailed charge breakdown
25
"""
26
```
27
28
#### Usage Example
29
30
```python
31
from upstox_client.api import ChargeApi
32
from upstox_client import Configuration, ApiClient
33
34
# Setup
35
config = Configuration()
36
config.access_token = 'your_access_token'
37
api_client = ApiClient(config)
38
charge_api = ChargeApi(api_client)
39
40
# Calculate brokerage for a trade
41
brokerage_response = charge_api.get_brokerage(
42
instrument_token="NSE_EQ|INE002A01018", # Reliance
43
quantity=100,
44
product="D", # Delivery
45
transaction_type="BUY",
46
price=1500.0,
47
api_version='2.0'
48
)
49
50
charges = brokerage_response.data
51
print("Trade Cost Breakdown:")
52
print(f"Trade Value: ₹{100 * 1500:.2f}")
53
print(f"Brokerage: ₹{charges.brokerage:.2f}")
54
print(f"STT: ₹{charges.stt:.2f}")
55
print(f"Exchange Charges: ₹{charges.exchange_charges:.2f}")
56
print(f"GST: ₹{charges.gst:.2f}")
57
print(f"SEBI Charges: ₹{charges.sebi_charges:.2f}")
58
print(f"Stamp Duty: ₹{charges.stamp_duty:.2f}")
59
print(f"Total Charges: ₹{charges.total_charges:.2f}")
60
print(f"Net Amount: ₹{charges.total_charges + (100 * 1500):.2f}")
61
62
# Calculate for different scenarios
63
scenarios = [
64
{"product": "I", "description": "Intraday"},
65
{"product": "D", "description": "Delivery"},
66
{"product": "M", "description": "Margin"}
67
]
68
69
print("\nCharge Comparison:")
70
for scenario in scenarios:
71
response = charge_api.get_brokerage(
72
instrument_token="NSE_EQ|INE002A01018",
73
quantity=100,
74
product=scenario["product"],
75
transaction_type="BUY",
76
price=1500.0,
77
api_version='2.0'
78
)
79
charges = response.data
80
print(f"{scenario['description']}: ₹{charges.total_charges:.2f}")
81
```
82
83
### Margin Calculation
84
85
Calculate required margin for trades and positions.
86
87
```python { .api }
88
def post_margin(body: MarginRequest) -> PostMarginResponse:
89
"""
90
Calculate required margin for trades.
91
92
Parameters:
93
- body: Margin calculation request with trade details
94
95
Returns:
96
PostMarginResponse with margin requirements
97
"""
98
```
99
100
#### Usage Example
101
102
```python
103
from upstox_client.models import MarginRequest
104
105
# Calculate margin for multiple orders
106
margin_request = MarginRequest(
107
instruments=[
108
{
109
"instrument_token": "NSE_EQ|INE002A01018",
110
"quantity": 100,
111
"price": 1500.0,
112
"product": "M", # Margin product
113
"transaction_type": "BUY"
114
},
115
{
116
"instrument_token": "NSE_EQ|INE009A01021",
117
"quantity": 50,
118
"price": 3000.0,
119
"product": "M",
120
"transaction_type": "BUY"
121
}
122
]
123
)
124
125
margin_response = charge_api.post_margin(margin_request)
126
127
print("Margin Requirements:")
128
for instrument_margin in margin_response.data:
129
print(f"Instrument: {instrument_margin.instrument_token}")
130
print(f" Required Margin: ₹{instrument_margin.required_margin:.2f}")
131
print(f" Available Margin: ₹{instrument_margin.available_margin:.2f}")
132
print(f" Used Margin: ₹{instrument_margin.used_margin:.2f}")
133
print(f" Margin Shortfall: ₹{max(0, instrument_margin.required_margin - instrument_margin.available_margin):.2f}")
134
print()
135
136
print(f"Total Required Margin: ₹{sum(m.required_margin for m in margin_response.data):.2f}")
137
```
138
139
### Market Timings & Status
140
141
Access market schedules, trading hours, and current market status.
142
143
```python { .api }
144
def get_market_status(exchange: str) -> GetMarketStatusResponse:
145
"""
146
Get current market status for an exchange.
147
148
Parameters:
149
- exchange: Exchange name ('NSE', 'BSE', 'MCX', 'NCDEX')
150
151
Returns:
152
GetMarketStatusResponse with current market status
153
"""
154
155
def get_exchange_timings(date: str) -> GetExchangeTimingResponse:
156
"""
157
Get exchange trading timings for a specific date.
158
159
Parameters:
160
- date: Date in YYYY-MM-DD format
161
162
Returns:
163
GetExchangeTimingResponse with trading hours
164
"""
165
```
166
167
#### Usage Example
168
169
```python
170
from upstox_client.api import MarketHolidaysAndTimingsApi
171
from datetime import datetime
172
173
timing_api = MarketHolidaysAndTimingsApi(api_client)
174
175
# Check current market status
176
exchanges = ['NSE', 'BSE', 'MCX', 'NCDEX']
177
print("Current Market Status:")
178
179
for exchange in exchanges:
180
status_response = timing_api.get_market_status(exchange)
181
182
for segment in status_response.data:
183
print(f"{exchange} {segment.segment}: {segment.status}")
184
if segment.status == 'open':
185
print(f" Trading until: {segment.end_time}")
186
elif segment.status == 'close':
187
print(f" Next opening: {segment.start_time}")
188
189
# Get trading timings for today
190
today = datetime.now().strftime('%Y-%m-%d')
191
timing_response = timing_api.get_exchange_timings(today)
192
193
print(f"\nTrading Timings for {today}:")
194
for timing in timing_response.data:
195
print(f"{timing.exchange} {timing.segment}:")
196
print(f" Pre-open: {timing.pre_open_start} - {timing.pre_open_end}")
197
print(f" Normal: {timing.market_open} - {timing.market_close}")
198
if timing.post_close_start:
199
print(f" Post-close: {timing.post_close_start} - {timing.post_close_end}")
200
```
201
202
### Market Holidays
203
204
Access market holiday information and trading calendar.
205
206
```python { .api }
207
def get_holidays() -> GetHolidayResponse:
208
"""
209
Get list of all market holidays.
210
211
Returns:
212
GetHolidayResponse with holiday calendar
213
"""
214
215
def get_holiday(date: str) -> GetHolidayResponse:
216
"""
217
Check if a specific date is a market holiday.
218
219
Parameters:
220
- date: Date in YYYY-MM-DD format
221
222
Returns:
223
GetHolidayResponse with holiday status for the date
224
"""
225
```
226
227
#### Usage Example
228
229
```python
230
# Get all holidays for the year
231
holidays_response = timing_api.get_holidays()
232
233
print("Market Holidays:")
234
for holiday in holidays_response.data:
235
print(f"{holiday.date}: {holiday.description}")
236
print(f" Exchanges: {', '.join(holiday.exchanges)}")
237
print(f" Type: {holiday.holiday_type}")
238
print()
239
240
# Check specific date
241
check_date = "2024-10-02" # Gandhi Jayanti
242
holiday_check = timing_api.get_holiday(check_date)
243
244
if holiday_check.data:
245
print(f"{check_date} is a market holiday: {holiday_check.data[0].description}")
246
else:
247
print(f"{check_date} is a trading day")
248
249
# Get upcoming holidays (next 30 days)
250
from datetime import datetime, timedelta
251
252
today = datetime.now()
253
upcoming_holidays = []
254
255
for holiday in holidays_response.data:
256
holiday_date = datetime.strptime(holiday.date, '%Y-%m-%d')
257
if today <= holiday_date <= today + timedelta(days=30):
258
upcoming_holidays.append(holiday)
259
260
print("Upcoming holidays in next 30 days:")
261
for holiday in sorted(upcoming_holidays, key=lambda x: x.date):
262
print(f"{holiday.date}: {holiday.description}")
263
```
264
265
### Trading Cost Analysis
266
267
Comprehensive analysis of trading costs across different scenarios.
268
269
#### Usage Example
270
271
```python
272
def analyze_trading_costs(instrument_token, quantity, price):
273
"""Analyze trading costs across different product types and scenarios"""
274
275
products = [
276
("I", "Intraday"),
277
("D", "Delivery"),
278
("M", "Margin")
279
]
280
281
transactions = ["BUY", "SELL"]
282
283
print(f"Trading Cost Analysis for {quantity} shares @ ₹{price}")
284
print("=" * 60)
285
286
for product_code, product_name in products:
287
print(f"\n{product_name} ({product_code}):")
288
print("-" * 40)
289
290
total_buy_charges = 0
291
total_sell_charges = 0
292
293
for transaction in transactions:
294
response = charge_api.get_brokerage(
295
instrument_token=instrument_token,
296
quantity=quantity,
297
product=product_code,
298
transaction_type=transaction,
299
price=price,
300
api_version='2.0'
301
)
302
303
charges = response.data
304
if transaction == "BUY":
305
total_buy_charges = charges.total_charges
306
print(f" {transaction}: ₹{charges.total_charges:.2f}")
307
else:
308
total_sell_charges = charges.total_charges
309
print(f" {transaction}: ₹{charges.total_charges:.2f}")
310
311
total_charges = total_buy_charges + total_sell_charges
312
trade_value = quantity * price
313
cost_percentage = (total_charges / trade_value) * 100
314
315
print(f" Total Round-trip: ₹{total_charges:.2f} ({cost_percentage:.3f}%)")
316
print(f" Breakeven: ₹{price + (total_charges / quantity):.2f}")
317
318
# Analyze costs for different scenarios
319
analyze_trading_costs("NSE_EQ|INE002A01018", 100, 1500.0) # Reliance
320
analyze_trading_costs("NSE_EQ|INE009A01021", 50, 3000.0) # Infosys
321
```
322
323
### Cost Optimization Tools
324
325
Helper functions for optimizing trading costs.
326
327
```python
328
def find_optimal_quantity(instrument_token, price, max_cost_percentage=0.5):
329
"""Find optimal quantity to keep costs under specified percentage"""
330
331
quantities = [10, 25, 50, 100, 200, 500, 1000]
332
333
print(f"Cost optimization for trades under {max_cost_percentage}%:")
334
print("Quantity | Cost | Cost% | Breakeven")
335
print("-" * 40)
336
337
for qty in quantities:
338
buy_response = charge_api.get_brokerage(
339
instrument_token=instrument_token,
340
quantity=qty,
341
product="D", # Delivery
342
transaction_type="BUY",
343
price=price,
344
api_version='2.0'
345
)
346
347
sell_response = charge_api.get_brokerage(
348
instrument_token=instrument_token,
349
quantity=qty,
350
product="D",
351
transaction_type="SELL",
352
price=price,
353
api_version='2.0'
354
)
355
356
total_charges = buy_response.data.total_charges + sell_response.data.total_charges
357
trade_value = qty * price
358
cost_percentage = (total_charges / trade_value) * 100
359
breakeven = price + (total_charges / qty)
360
361
status = "✓" if cost_percentage <= max_cost_percentage else "✗"
362
print(f"{qty:8d} | {total_charges:5.2f} | {cost_percentage:5.3f}% | {breakeven:8.2f} {status}")
363
364
# find_optimal_quantity("NSE_EQ|INE002A01018", 1500.0, 0.3)
365
```
366
367
## Request/Response Types
368
369
```python { .api }
370
class MarginRequest:
371
instruments: list[MarginInstrument]
372
373
class MarginInstrument:
374
instrument_token: str
375
quantity: int
376
price: float
377
product: str
378
transaction_type: str
379
380
class GetBrokerageResponse:
381
status: str
382
data: BrokerageData
383
384
class BrokerageData:
385
brokerage: float
386
stt: float # Securities Transaction Tax
387
exchange_charges: float
388
clearing_charges: float
389
gst: float # Goods & Services Tax
390
sebi_charges: float
391
stamp_duty: float
392
total_charges: float
393
394
class PostMarginResponse:
395
status: str
396
data: list[MarginData]
397
398
class MarginData:
399
instrument_token: str
400
required_margin: float
401
available_margin: float
402
used_margin: float
403
margin_utilization: float # Percentage of margin used
404
405
class GetMarketStatusResponse:
406
status: str
407
data: list[MarketStatusData]
408
409
class MarketStatusData:
410
exchange: str
411
segment: str # 'equity', 'derivative', 'commodity'
412
status: str # 'open', 'close', 'break', 'pre_open', 'post_close'
413
start_time: str # Next/current session start time
414
end_time: str # Current session end time
415
416
class GetExchangeTimingResponse:
417
status: str
418
data: list[ExchangeTimingData]
419
420
class ExchangeTimingData:
421
exchange: str
422
segment: str
423
pre_open_start: str # Pre-market start time
424
pre_open_end: str # Pre-market end time
425
market_open: str # Regular session start
426
market_close: str # Regular session end
427
post_close_start: str # Post-market start (if applicable)
428
post_close_end: str # Post-market end (if applicable)
429
is_trading_day: bool
430
431
class GetHolidayResponse:
432
status: str
433
data: list[HolidayData]
434
435
class HolidayData:
436
date: str # Holiday date in YYYY-MM-DD format
437
description: str # Holiday name/description
438
holiday_type: str # 'national', 'regional', 'exchange_specific'
439
exchanges: list[str] # Affected exchanges
440
```
441
442
## Expired Instruments Analysis
443
444
Access expired futures and options contracts data and historical information for analysis.
445
446
```python { .api }
447
class ExpiredInstrumentApi:
448
def get_expired_future_contracts(instrument_key: str, expiry_date: str) -> GetExpiredFuturesContractResponse:
449
"""
450
Get expired futures contracts for analysis.
451
452
Parameters:
453
- instrument_key: Instrument identifier
454
- expiry_date: Expiry date to filter contracts
455
456
Returns:
457
GetExpiredFuturesContractResponse with expired contract details
458
"""
459
460
def get_expired_option_contracts(instrument_key: str, expiry_date: str) -> GetExpiredOptionContractResponse:
461
"""
462
Get expired options contracts for analysis.
463
464
Parameters:
465
- instrument_key: Instrument identifier
466
- expiry_date: Expiry date to filter contracts
467
468
Returns:
469
GetExpiredOptionContractResponse with expired contract details
470
"""
471
472
def get_expired_historical_candle_data(expired_instrument_key: str, interval: str, to_date: str, from_date: str) -> GetHistoricalCandleResponse:
473
"""
474
Get historical candle data for expired contracts.
475
476
Parameters:
477
- expired_instrument_key: Key for expired instrument
478
- interval: Time interval ('1m', '5m', '1d', etc.)
479
- to_date: End date for data
480
- from_date: Start date for data
481
482
Returns:
483
GetHistoricalCandleResponse with candle data
484
"""
485
486
def get_expiries(instrument_key: str) -> GetExpiriesResponse:
487
"""
488
Get available expiry dates for an instrument.
489
490
Parameters:
491
- instrument_key: Instrument identifier
492
493
Returns:
494
GetExpiriesResponse with available expiry dates
495
"""
496
```
497
498
### Usage Example
499
500
```python
501
import upstox_client
502
503
# Setup
504
configuration = upstox_client.Configuration()
505
configuration.access_token = 'your_access_token'
506
api_client = upstox_client.ApiClient(configuration)
507
expired_api = upstox_client.ExpiredInstrumentApi(api_client)
508
509
# Get expired futures for analysis
510
expired_futures = expired_api.get_expired_future_contracts(
511
instrument_key='NSE_FO|42965', # Nifty futures
512
expiry_date='2024-01-25'
513
)
514
515
# Analyze historical data for expired contract
516
historical_data = expired_api.get_expired_historical_candle_data(
517
expired_instrument_key='NSE_FO|42965',
518
interval='1d',
519
to_date='2024-01-25',
520
from_date='2024-01-01'
521
)
522
523
print(f"Found {len(historical_data.data.candles)} candles for analysis")
524
```
525
526
## Trading Sessions & Timings
527
528
### Standard Trading Hours (IST)
529
530
#### NSE Equity
531
- **Pre-open**: 9:00 AM - 9:15 AM
532
- **Normal**: 9:15 AM - 3:30 PM
533
- **Post-close**: 3:40 PM - 4:00 PM
534
535
#### NSE Derivatives
536
- **Pre-open**: 9:00 AM - 9:15 AM
537
- **Normal**: 9:15 AM - 3:30 PM
538
539
#### BSE Equity
540
- **Pre-open**: 9:00 AM - 9:15 AM
541
- **Normal**: 9:15 AM - 3:30 PM
542
543
#### MCX Commodities
544
- **Morning**: 9:00 AM - 5:00 PM
545
- **Evening**: 5:00 PM - 11:30 PM (select contracts)
546
547
### Special Sessions
548
- **Muhurat Trading**: Special Diwali session (usually 1 hour)
549
- **Settlement Holidays**: No trading, only settlement activities
550
551
## Cost Components
552
553
### Equity Delivery
554
- **Brokerage**: As per plan (flat fee or percentage)
555
- **STT**: 0.1% on sell side
556
- **Exchange Charges**: ~0.00345%
557
- **GST**: 18% on (brokerage + exchange charges)
558
- **SEBI Charges**: ₹10 per crore
559
- **Stamp Duty**: 0.015% on buy side
560
561
### Equity Intraday
562
- **Brokerage**: As per plan (usually lower than delivery)
563
- **STT**: 0.025% on sell side
564
- **Exchange Charges**: ~0.00345%
565
- **GST**: 18% on (brokerage + exchange charges)
566
- **SEBI Charges**: ₹10 per crore
567
568
### Futures & Options
569
- **STT**: 0.01% on sell side (futures), 0.05% on sell side (options)
570
- **Exchange Charges**: Vary by exchange and contract type
571
- **Other charges**: Similar to equity
572
573
## Best Practices
574
575
### Cost Management
576
```python
577
# 1. Compare costs across product types before trading
578
def compare_costs(instrument_token, quantity, price):
579
products = ['I', 'D', 'M']
580
for product in products:
581
# Calculate and compare costs
582
pass
583
584
# 2. Consider minimum brokerage for small trades
585
def check_minimum_viable_quantity(instrument_token, price, min_profit_target):
586
# Calculate minimum quantity needed to overcome costs
587
pass
588
589
# 3. Plan for round-trip costs
590
def calculate_breakeven_price(buy_price, charges):
591
return buy_price + (charges / quantity)
592
```
593
594
### Market Timing
595
```python
596
# Check market status before placing orders
597
status = timing_api.get_market_status('NSE')
598
if status.data[0].status == 'open':
599
# Place order
600
pass
601
else:
602
print(f"Market closed. Next opening: {status.data[0].start_time}")
603
604
# Avoid trading on holidays
605
if not timing_api.get_holiday(trade_date).data:
606
# Safe to trade
607
pass
608
```
609
610
### Margin Planning
611
```python
612
# Calculate total margin requirement before trading
613
total_margin_required = sum(
614
calculate_margin(instrument, quantity, price)
615
for instrument, quantity, price in planned_trades
616
)
617
618
if total_margin_required <= available_margin:
619
# Execute trades
620
pass
621
else:
622
print(f"Insufficient margin. Required: ₹{total_margin_required}")
623
```