0
# Portfolio Management
1
2
Manage portfolio positions, holdings, conversions between product types, and comprehensive profit & loss analysis with historical trade data.
3
4
## Capabilities
5
6
### Holdings Management
7
8
Access current stock holdings in your demat account.
9
10
```python { .api }
11
def get_holdings(api_version: str) -> GetHoldingsResponse:
12
"""
13
Retrieve current holdings in demat account.
14
15
Parameters:
16
- api_version: API version ('2.0')
17
18
Returns:
19
GetHoldingsResponse with holdings data
20
"""
21
```
22
23
#### Usage Example
24
25
```python
26
from upstox_client.api import PortfolioApi
27
from upstox_client import Configuration, ApiClient
28
29
# Setup
30
config = Configuration()
31
config.access_token = 'your_access_token'
32
api_client = ApiClient(config)
33
portfolio_api = PortfolioApi(api_client)
34
35
# Get holdings
36
holdings_response = portfolio_api.get_holdings(api_version='2.0')
37
38
print("Current Holdings:")
39
total_investment = 0
40
total_current_value = 0
41
42
for holding in holdings_response.data:
43
investment = holding.average_price * holding.quantity
44
current_value = holding.last_price * holding.quantity
45
pnl = current_value - investment
46
pnl_percent = (pnl / investment) * 100 if investment > 0 else 0
47
48
total_investment += investment
49
total_current_value += current_value
50
51
print(f"{holding.tradingsymbol}:")
52
print(f" Quantity: {holding.quantity}")
53
print(f" Avg Price: ₹{holding.average_price:.2f}")
54
print(f" Current Price: ₹{holding.last_price:.2f}")
55
print(f" Investment: ₹{investment:.2f}")
56
print(f" Current Value: ₹{current_value:.2f}")
57
print(f" P&L: ₹{pnl:.2f} ({pnl_percent:.2f}%)")
58
print(f" T1 Quantity: {holding.t1_quantity}")
59
print()
60
61
total_pnl = total_current_value - total_investment
62
total_pnl_percent = (total_pnl / total_investment) * 100 if total_investment > 0 else 0
63
64
print(f"Portfolio Summary:")
65
print(f"Total Investment: ₹{total_investment:.2f}")
66
print(f"Current Value: ₹{total_current_value:.2f}")
67
print(f"Total P&L: ₹{total_pnl:.2f} ({total_pnl_percent:.2f}%)")
68
```
69
70
### Position Management
71
72
Access and manage open trading positions.
73
74
```python { .api }
75
def get_positions(api_version: str) -> GetPositionResponse:
76
"""
77
Retrieve current trading positions.
78
79
Parameters:
80
- api_version: API version ('2.0')
81
82
Returns:
83
GetPositionResponse with position data
84
"""
85
86
def get_mtf_positions() -> GetPositionResponse:
87
"""
88
Get Margin Trading Facility (MTF) positions.
89
90
Returns:
91
GetPositionResponse with MTF position data
92
"""
93
```
94
95
#### Usage Example
96
97
```python
98
# Get all positions
99
positions_response = portfolio_api.get_positions(api_version='2.0')
100
101
print("Current Positions:")
102
for position in positions_response.data:
103
if position.quantity != 0: # Only show non-zero positions
104
print(f"{position.tradingsymbol} ({position.exchange}):")
105
print(f" Net Quantity: {position.quantity}")
106
print(f" Product: {position.product}")
107
print(f" Buy Quantity: {position.buy_quantity}, Avg: ₹{position.buy_price:.2f}")
108
print(f" Sell Quantity: {position.sell_quantity}, Avg: ₹{position.sell_price:.2f}")
109
print(f" Last Price: ₹{position.last_price:.2f}")
110
print(f" Unrealized P&L: ₹{position.unrealised:.2f}")
111
print(f" Realized P&L: ₹{position.realised:.2f}")
112
print(f" Day P&L: ₹{position.day_buy_value - position.day_sell_value:.2f}")
113
print()
114
115
# Get MTF positions
116
mtf_positions = portfolio_api.get_mtf_positions()
117
print(f"MTF Positions: {len(mtf_positions.data)} positions")
118
```
119
120
### Position Conversion
121
122
Convert positions between different product types (Intraday, Delivery, Margin).
123
124
```python { .api }
125
def convert_positions(body: ConvertPositionRequest, api_version: str) -> ConvertPositionResponse:
126
"""
127
Convert position from one product type to another.
128
129
Parameters:
130
- body: Conversion request parameters
131
- api_version: API version ('2.0')
132
133
Returns:
134
ConvertPositionResponse with conversion status
135
"""
136
```
137
138
#### Usage Example
139
140
```python
141
from upstox_client.models import ConvertPositionRequest
142
143
# Convert intraday position to delivery
144
convert_request = ConvertPositionRequest(
145
instrument_token="NSE_EQ|INE002A01018", # Reliance
146
new_product="D", # Delivery
147
old_product="I", # From Intraday
148
transaction_type="BUY",
149
quantity=10
150
)
151
152
convert_response = portfolio_api.convert_positions(
153
convert_request,
154
api_version='2.0'
155
)
156
157
print(f"Position converted: {convert_response.status}")
158
for result in convert_response.data:
159
print(f"Symbol: {result.instrument_token}")
160
print(f"Status: {result.status}")
161
print(f"Message: {result.message}")
162
```
163
164
### Profit & Loss Analysis
165
166
Comprehensive P&L analysis with charges breakdown and trade-wise details.
167
168
```python { .api }
169
def get_profit_and_loss_charges(segment: str, financial_year: str, api_version: str) -> GetProfitAndLossChargesResponse:
170
"""
171
Get profit & loss summary with charges breakdown.
172
173
Parameters:
174
- segment: Market segment ('EQ', 'FO', 'COM')
175
- financial_year: Financial year in YYYY-YY format (e.g., '2024-25')
176
- api_version: API version ('2.0')
177
178
Returns:
179
GetProfitAndLossChargesResponse with P&L and charges
180
"""
181
182
def get_trade_wise_profit_and_loss_data(segment: str, financial_year: str, page_number: str, page_size: str, api_version: str) -> GetTradeWiseProfitAndLossDataResponse:
183
"""
184
Get detailed trade-wise profit & loss data.
185
186
Parameters:
187
- segment: Market segment ('EQ', 'FO', 'COM')
188
- financial_year: Financial year in YYYY-YY format
189
- page_number: Page number for pagination
190
- page_size: Number of records per page
191
- api_version: API version ('2.0')
192
193
Returns:
194
GetTradeWiseProfitAndLossDataResponse with trade-wise P&L
195
"""
196
197
def get_trade_wise_profit_and_loss_meta_data(segment: str, financial_year: str, api_version: str) -> GetTradeWiseProfitAndLossMetaDataResponse:
198
"""
199
Get metadata for trade-wise P&L report.
200
201
Parameters:
202
- segment: Market segment ('EQ', 'FO', 'COM')
203
- financial_year: Financial year in YYYY-YY format
204
- api_version: API version ('2.0')
205
206
Returns:
207
GetTradeWiseProfitAndLossMetaDataResponse with P&L metadata
208
"""
209
```
210
211
#### Usage Example
212
213
```python
214
from upstox_client.api import TradeProfitAndLossApi
215
216
pnl_api = TradeProfitAndLossApi(api_client)
217
218
# Get P&L charges summary
219
pnl_charges = pnl_api.get_profit_and_loss_charges(
220
segment='EQ',
221
financial_year='2024-25',
222
api_version='2.0'
223
)
224
225
charges_data = pnl_charges.data
226
print("P&L Summary with Charges:")
227
print(f"Gross P&L: ₹{charges_data.total_profit_and_loss:.2f}")
228
print(f"Brokerage: ₹{charges_data.total_brokerage:.2f}")
229
print(f"Taxes: ₹{charges_data.total_taxes:.2f}")
230
print(f"Net P&L: ₹{charges_data.net_profit_and_loss:.2f}")
231
232
# Get trade-wise P&L data
233
trade_pnl = pnl_api.get_trade_wise_profit_and_loss_data(
234
segment='EQ',
235
financial_year='2024-25',
236
page_number='1',
237
page_size='50',
238
api_version='2.0'
239
)
240
241
print("\nTrade-wise P&L:")
242
for trade in trade_pnl.data:
243
print(f"{trade.tradingsymbol}:")
244
print(f" Buy: {trade.buy_quantity} @ ₹{trade.buy_average:.2f}")
245
print(f" Sell: {trade.sell_quantity} @ ₹{trade.sell_average:.2f}")
246
print(f" Gross P&L: ₹{trade.gross_profit_and_loss:.2f}")
247
print(f" Charges: ₹{trade.charges:.2f}")
248
print(f" Net P&L: ₹{trade.net_profit_and_loss:.2f}")
249
print()
250
251
# Get P&L metadata
252
pnl_metadata = pnl_api.get_trade_wise_profit_and_loss_meta_data(
253
segment='EQ',
254
financial_year='2024-25',
255
api_version='2.0'
256
)
257
258
print(f"Total Records: {pnl_metadata.data.total_records}")
259
print(f"Total Pages: {pnl_metadata.data.total_pages}")
260
```
261
262
### Historical Trade Data
263
264
Access historical trade data by date range for analysis and reporting.
265
266
```python { .api }
267
def get_trades_by_date_range(start_date: str, end_date: str, page_number: int, page_size: int, segment: str = None) -> TradeHistoryResponse:
268
"""
269
Get historical trade data for a date range.
270
271
Parameters:
272
- start_date: Start date in YYYY-MM-DD format (required)
273
- end_date: End date in YYYY-MM-DD format (required)
274
- page_number: Page number for pagination (required)
275
- page_size: Number of records per page (required)
276
- segment: Market segment ('EQ', 'FO', 'COM', 'CD', 'MF') (optional)
277
278
Returns:
279
TradeHistoryResponse with historical trade data
280
"""
281
```
282
283
#### Usage Example
284
285
```python
286
from upstox_client.api import PostTradeApi
287
288
post_trade_api = PostTradeApi(api_client)
289
290
# Get trades for last month
291
trade_history = post_trade_api.get_trades_by_date_range(
292
start_date='2024-08-01',
293
end_date='2024-08-31',
294
page_number='1',
295
page_size='100'
296
)
297
298
print("Trade History:")
299
for trade in trade_history.data.trades:
300
print(f"{trade.trade_date} - {trade.tradingsymbol}:")
301
print(f" {trade.transaction_type} {trade.quantity} @ ₹{trade.price:.2f}")
302
print(f" Value: ₹{trade.trade_value:.2f}")
303
print(f" Charges: ₹{trade.charges:.2f}")
304
print()
305
306
print(f"Page: {trade_history.data.page_details.page_number}")
307
print(f"Total Pages: {trade_history.data.page_details.total_pages}")
308
print(f"Total Records: {trade_history.data.page_details.total_records}")
309
```
310
311
## Request/Response Types
312
313
```python { .api }
314
class ConvertPositionRequest:
315
instrument_token: str # Instrument to convert
316
new_product: str # Target product type ('I', 'D', 'M')
317
old_product: str # Current product type ('I', 'D', 'M')
318
transaction_type: str # 'BUY' or 'SELL'
319
quantity: int # Quantity to convert
320
321
class GetHoldingsResponse:
322
status: str
323
data: list[HoldingsData]
324
325
class HoldingsData:
326
instrument_token: str
327
isin: str # ISIN code
328
cnc_used_quantity: int # CNC used quantity
329
collateral_type: str # Collateral classification
330
company_name: str
331
haircut: float # Haircut percentage for collateral
332
exchange: str
333
instrument_type: str
334
product: str
335
quantity: int # Total quantity
336
tradingsymbol: str
337
last_price: float # Current market price
338
close_price: float # Previous day close
339
average_price: float # Average purchase price
340
collateral_quantity: int # Quantity pledged as collateral
341
collateral_update_quantity: int
342
t1_quantity: int # T+1 settlement quantity
343
pnl: float # Profit & Loss
344
345
class GetPositionResponse:
346
status: str
347
data: list[PositionData]
348
349
class PositionData:
350
exchange: str
351
instrument_token: str
352
tradingsymbol: str
353
product: str
354
quantity: int # Net quantity (buy - sell)
355
buy_quantity: int
356
sell_quantity: int
357
buy_price: float # Average buy price
358
sell_price: float # Average sell price
359
last_price: float # Current market price
360
unrealised: float # Unrealized P&L
361
realised: float # Realized P&L
362
multiplier: int # Contract multiplier
363
buy_value: float # Total buy value
364
sell_value: float # Total sell value
365
day_buy_quantity: int # Day's buy quantity
366
day_sell_quantity: int # Day's sell quantity
367
day_buy_price: float # Day's average buy price
368
day_sell_price: float # Day's average sell price
369
day_buy_value: float # Day's buy value
370
day_sell_value: float # Day's sell value
371
372
class ConvertPositionResponse:
373
status: str
374
data: list[ConvertPositionData]
375
376
class ConvertPositionData:
377
instrument_token: str
378
status: str
379
message: str
380
381
class GetProfitAndLossChargesResponse:
382
status: str
383
data: ProfitAndLossChargesWrapperData
384
385
class ProfitAndLossChargesWrapperData:
386
total_profit_and_loss: float
387
total_brokerage: float
388
total_taxes: float
389
net_profit_and_loss: float
390
data: list[ProfitAndLossChargesData]
391
392
class ProfitAndLossChargesData:
393
segment: str
394
charges: ProfitAndLossChargesTaxes
395
profit_and_loss: float
396
397
class ProfitAndLossChargesTaxes:
398
brokerage: float
399
stt: float # Securities Transaction Tax
400
exchange_charges: float
401
clearing_charges: float
402
gst: float # Goods & Services Tax
403
sebi_charges: float
404
stamp_duty: float
405
406
class GetTradeWiseProfitAndLossDataResponse:
407
status: str
408
data: list[TradeWiseProfitAndLossData]
409
410
class TradeWiseProfitAndLossData:
411
instrument_token: str
412
tradingsymbol: str
413
buy_quantity: int
414
sell_quantity: int
415
buy_average: float
416
sell_average: float
417
gross_profit_and_loss: float
418
charges: float
419
net_profit_and_loss: float
420
trade_date: str
421
422
class TradeHistoryResponse:
423
status: str
424
data: TradeHistoryResponsePageData
425
426
class TradeHistoryResponsePageData:
427
page_details: TradeHistoryResponseMetaData
428
trades: list[TradeHistoryResponseTradeData]
429
430
class TradeHistoryResponseMetaData:
431
total_records: int
432
total_pages: int
433
page_number: int
434
page_size: int
435
436
class TradeHistoryResponseTradeData:
437
exchange: str
438
instrument_token: str
439
tradingsymbol: str
440
trade_id: str
441
order_id: str
442
trade_date: str
443
trade_time: str
444
transaction_type: str # 'BUY' or 'SELL'
445
quantity: int
446
price: float
447
trade_value: float
448
charges: float
449
```
450
451
## Product Types
452
453
### Position Product Types
454
- `"I"` - Intraday: Square off before market close
455
- `"D"` - Delivery: Hold for delivery (CNC)
456
- `"M"` - Margin: Margin trading positions
457
- `"CO"` - Cover Order: Intraday with compulsory stop loss
458
- `"BO"` - Bracket Order: Intraday with target and stop loss
459
460
### Market Segments
461
- `"EQ"` - Equity (Cash market)
462
- `"FO"` - Futures & Options
463
- `"COM"` - Commodity
464
- `"CD"` - Currency Derivatives
465
466
## Common Workflows
467
468
### Daily Portfolio Review
469
```python
470
# 1. Check holdings performance
471
holdings = portfolio_api.get_holdings(api_version='2.0')
472
473
# 2. Review open positions
474
positions = portfolio_api.get_positions(api_version='2.0')
475
476
# 3. Analyze P&L for current financial year
477
pnl_data = pnl_api.get_profit_and_loss_charges(
478
segment='EQ',
479
financial_year='2024-25',
480
api_version='2.0'
481
)
482
```
483
484
### Position Management
485
```python
486
# 1. Convert intraday to delivery before market close
487
convert_request = ConvertPositionRequest(
488
instrument_token="NSE_EQ|INE002A01018",
489
new_product="D", # Convert to delivery
490
old_product="I", # From intraday
491
transaction_type="BUY",
492
quantity=10
493
)
494
495
# 2. Execute conversion
496
conversion = portfolio_api.convert_positions(convert_request, api_version='2.0')
497
```
498
499
### Risk Management
500
Monitor portfolio exposure, P&L, and positions to manage risk effectively:
501
502
```python
503
# Calculate portfolio metrics
504
total_exposure = sum(abs(pos.buy_value - pos.sell_value) for pos in positions_data)
505
unrealized_pnl = sum(pos.unrealised for pos in positions_data)
506
day_pnl = sum(pos.day_buy_value - pos.day_sell_value for pos in positions_data)
507
508
print(f"Total Exposure: ₹{total_exposure:.2f}")
509
print(f"Unrealized P&L: ₹{unrealized_pnl:.2f}")
510
print(f"Day P&L: ₹{day_pnl:.2f}")
511
```