Portfolio management with OpenAlgo - funds, positions, holdings, order book, trade book, margin calculator, and account management
Retrieves real-time portfolio data including funds, positions, holdings, orders, and trades. Use when users need to check account balance, open positions, or trading history.
/plugin marketplace add marketcalls/openalgo-claude-plugin/plugin install marketcalls-openalgo-python-plugins-openalgo-python@marketcalls/openalgo-claude-pluginThis skill inherits all available tools. When active, it can use any tool Claude has access to.
requirements.txtscripts/margin.pyscripts/portfolio.pyManage your trading portfolio using OpenAlgo's unified Python SDK. Access funds, positions, holdings, orders, trades, and margin information.
from openalgo import api
client = api(
api_key='your_api_key_here',
host='http://127.0.0.1:5000'
)
python scripts/portfolio.py --summary
python scripts/portfolio.py --positions
python scripts/portfolio.py --holdings
python scripts/margin.py --symbol NIFTY30JAN2526000CE --exchange NFO --action SELL --quantity 75
Get account balance and margin information:
response = client.funds()
Response:
{
"status": "success",
"data": {
"availablecash": "320.66",
"collateral": "0.00",
"m2mrealized": "3.27",
"m2munrealized": "-7.88",
"utiliseddebits": "679.34"
}
}
Fields Explained:
availablecash: Cash available for new tradescollateral: Pledged collateral valuem2mrealized: Realized Mark-to-Market P&Lm2munrealized: Unrealized Mark-to-Market P&Lutiliseddebits: Margin utilized for open positionsGet all open positions:
response = client.positionbook()
Response:
{
"status": "success",
"data": [
{
"symbol": "RELIANCE",
"exchange": "NSE",
"product": "MIS",
"quantity": "10",
"average_price": "1180.50",
"ltp": "1189.90",
"pnl": "94.00"
},
{
"symbol": "SBIN",
"exchange": "NSE",
"product": "MIS",
"quantity": "-5",
"average_price": "770.20",
"ltp": "769.80",
"pnl": "2.00"
}
]
}
Notes:
Get delivery holdings (CNC):
response = client.holdings()
Response:
{
"status": "success",
"data": {
"holdings": [
{
"symbol": "RELIANCE",
"exchange": "NSE",
"product": "CNC",
"quantity": 10,
"pnl": -149.0,
"pnlpercent": -11.1
},
{
"symbol": "TATASTEEL",
"exchange": "NSE",
"product": "CNC",
"quantity": 5,
"pnl": -15.0,
"pnlpercent": -10.41
}
],
"statistics": {
"totalholdingvalue": 17680.0,
"totalinvvalue": 20010.0,
"totalprofitandloss": -2330.0,
"totalpnlpercentage": -11.65
}
}
}
Get all orders for the day:
response = client.orderbook()
Response:
{
"status": "success",
"data": {
"orders": [
{
"action": "BUY",
"symbol": "RELIANCE",
"exchange": "NSE",
"orderid": "250408000989443",
"product": "MIS",
"quantity": "1",
"price": 1186.0,
"pricetype": "MARKET",
"order_status": "complete",
"trigger_price": 0.0,
"timestamp": "08-Apr-2025 13:58:03"
},
{
"action": "BUY",
"symbol": "YESBANK",
"exchange": "NSE",
"orderid": "250408001002736",
"product": "MIS",
"quantity": "1",
"price": 16.5,
"pricetype": "LIMIT",
"order_status": "open",
"trigger_price": 0.0,
"timestamp": "08-Apr-2025 14:13:45"
}
],
"statistics": {
"total_buy_orders": 2.0,
"total_sell_orders": 0.0,
"total_completed_orders": 1.0,
"total_open_orders": 1.0,
"total_rejected_orders": 0.0
}
}
}
Order Statuses:
complete: Order executedopen: Order pendingcancelled: Order cancelledrejected: Order rejectedtrigger_pending: SL/SL-M waiting for triggerGet all executed trades:
response = client.tradebook()
Response:
{
"status": "success",
"data": [
{
"action": "BUY",
"symbol": "RELIANCE",
"exchange": "NSE",
"orderid": "250408000989443",
"product": "MIS",
"quantity": 1,
"average_price": 1180.1,
"timestamp": "13:58:03",
"trade_value": 1180.1
}
]
}
Get status of a specific order:
response = client.orderstatus(
order_id="250408000989443",
strategy="MyStrategy"
)
Response:
{
"status": "success",
"data": {
"action": "BUY",
"average_price": 1180.1,
"exchange": "NSE",
"order_status": "complete",
"orderid": "250408000989443",
"price": 0,
"pricetype": "MARKET",
"product": "MIS",
"quantity": "1",
"symbol": "RELIANCE",
"timestamp": "08-Apr-2025 13:58:03",
"trigger_price": 0
}
}
Get position for a specific symbol:
response = client.openposition(
strategy="MyStrategy",
symbol="RELIANCE",
exchange="NSE",
product="MIS"
)
Response:
{
"status": "success",
"quantity": "10"
}
response = client.margin(positions=[
{
"symbol": "NIFTY30JAN2526000CE",
"exchange": "NFO",
"action": "SELL",
"product": "NRML",
"pricetype": "MARKET",
"quantity": "75"
}
])
Response:
{
"status": "success",
"data": {
"total_margin_required": 125000.00,
"span_margin": 95000.00,
"exposure_margin": 30000.00
}
}
response = client.margin(positions=[
{
"symbol": "NIFTY30JAN2526000CE",
"exchange": "NFO",
"action": "BUY",
"product": "NRML",
"pricetype": "MARKET",
"quantity": "75"
},
{
"symbol": "NIFTY30JAN2526500CE",
"exchange": "NFO",
"action": "SELL",
"product": "NRML",
"pricetype": "MARKET",
"quantity": "75"
}
])
# Spread margin will be lower than naked option margin
Square off all open positions:
response = client.closeposition(strategy="MyStrategy")
Response:
{
"status": "success",
"message": "All Open Positions Squared Off"
}
Cancel all pending orders:
response = client.cancelallorder(strategy="MyStrategy")
Response:
{
"status": "success",
"message": "Canceled 5 orders. Failed to cancel 0 orders.",
"canceled_orders": ["250408001042620", "250408001042667"],
"failed_cancellations": []
}
Test strategies without real execution:
response = client.analyzerstatus()
Response:
{
"status": "success",
"data": {
"analyze_mode": true,
"mode": "analyze",
"total_logs": 25
}
}
# Enable paper trading
response = client.analyzertoggle(mode=True)
# Disable paper trading (live mode)
response = client.analyzertoggle(mode=False)
Send trading notifications:
response = client.telegram(
username="your_openalgo_username",
message="NIFTY crossed 26000! Entry triggered."
)
Response:
{
"status": "success",
"message": "Notification sent successfully"
}
def get_daily_pnl():
"""Calculate total daily P&L from positions."""
positions = client.positionbook()
if positions.get('status') != 'success':
return None
total_pnl = 0
for pos in positions.get('data', []):
total_pnl += float(pos.get('pnl', 0))
return total_pnl
pnl = get_daily_pnl()
print(f"Today's P&L: ₹{pnl:,.2f}")
def check_margin_available():
"""Check if sufficient margin is available."""
funds = client.funds()
if funds.get('status') != 'success':
return 0
return float(funds['data'].get('availablecash', 0))
available = check_margin_available()
print(f"Available Margin: ₹{available:,.2f}")
def check_position_limit(symbol, exchange, product, max_quantity):
"""Check if position is within limits."""
position = client.openposition(
strategy="RiskManager",
symbol=symbol,
exchange=exchange,
product=product
)
if position.get('status') != 'success':
return True # Allow if can't check
current_qty = abs(int(position.get('quantity', 0)))
if current_qty >= max_quantity:
print(f"Position limit reached for {symbol}: {current_qty}/{max_quantity}")
return False
return True
# Usage
if check_position_limit("NIFTY30JAN25FUT", "NFO", "NRML", 500):
# Place order
pass
from datetime import datetime
def eod_squareoff():
"""Square off all MIS positions before market close."""
now = datetime.now()
# Check if it's near market close (3:15 PM)
if now.hour == 15 and now.minute >= 10:
response = client.closeposition(strategy="EOD_Squareoff")
print(f"EOD Square off: {response}")
return response
return None
def portfolio_snapshot():
"""Get complete portfolio snapshot."""
funds = client.funds()
positions = client.positionbook()
holdings = client.holdings()
orders = client.orderbook()
snapshot = {
'timestamp': datetime.now().isoformat(),
'funds': funds.get('data', {}),
'positions': positions.get('data', []),
'holdings': holdings.get('data', {}),
'orders': orders.get('data', {})
}
return snapshot
snapshot = portfolio_snapshot()
print(f"Available: ₹{snapshot['funds'].get('availablecash', 0)}")
print(f"Open Positions: {len(snapshot['positions'])}")
print(f"Holdings: {len(snapshot['holdings'].get('holdings', []))}")
response = client.holidays(year=2025)
for holiday in response.get('data', []):
print(f"{holiday['date']}: {holiday['description']}")
response = client.timings(date="2025-01-15")
for timing in response.get('data', []):
exchange = timing['exchange']
start = datetime.fromtimestamp(timing['start_time'] / 1000)
end = datetime.fromtimestamp(timing['end_time'] / 1000)
print(f"{exchange}: {start.strftime('%H:%M')} - {end.strftime('%H:%M')}")
Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks, access control, Payload API). Use when debugging validation errors, security issues, relationship queries, transactions, or hook behavior.