portfolio
npx machina-cli add skill marketcalls/openalgo-claude-plugin/portfolio --openclawOpenAlgo Portfolio Management
Manage your trading portfolio using OpenAlgo's unified Python SDK. Access funds, positions, holdings, orders, trades, and margin information.
Environment Setup
from openalgo import api
client = api(
api_key='your_api_key_here',
host='http://127.0.0.1:5000'
)
Quick Start Scripts
Portfolio Summary
python scripts/portfolio.py --summary
View Positions
python scripts/portfolio.py --positions
View Holdings
python scripts/portfolio.py --holdings
Calculate Margin
python scripts/margin.py --symbol NIFTY30JAN2526000CE --exchange NFO --action SELL --quantity 75
Core API Methods
1. Funds
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 positions
2. Position Book
Get 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:
- Positive quantity = Long position
- Negative quantity = Short position
- P&L is calculated as (LTP - Avg Price) * Quantity
3. Holdings
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
}
}
}
4. Order Book
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 trigger
5. Trade Book
Get 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
}
]
}
6. Order Status
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
}
}
7. Open Position
Get position for a specific symbol:
response = client.openposition(
strategy="MyStrategy",
symbol="RELIANCE",
exchange="NSE",
product="MIS"
)
Response:
{
"status": "success",
"quantity": "10"
}
Margin Calculator
Single Position Margin
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
}
}
Multi-Leg Margin (Spread Benefit)
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
Account Actions
Close All Positions
Square off all open positions:
response = client.closeposition(strategy="MyStrategy")
Response:
{
"status": "success",
"message": "All Open Positions Squared Off"
}
Cancel All Orders
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": []
}
Analyzer Mode
Test strategies without real execution:
Check Analyzer Status
response = client.analyzerstatus()
Response:
{
"status": "success",
"data": {
"analyze_mode": true,
"mode": "analyze",
"total_logs": 25
}
}
Toggle Analyzer Mode
# Enable paper trading
response = client.analyzertoggle(mode=True)
# Disable paper trading (live mode)
response = client.analyzertoggle(mode=False)
Telegram Alerts
Send trading notifications:
response = client.telegram(
username="your_openalgo_username",
message="NIFTY crossed 26000! Entry triggered."
)
Response:
{
"status": "success",
"message": "Notification sent successfully"
}
Common Patterns
Daily P&L Summary
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}")
Check Available Margin
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}")
Risk Management - Position Limits
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
End of Day Square Off
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
Portfolio Snapshot
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', []))}")
Market Information
Trading Holidays
response = client.holidays(year=2025)
for holiday in response.get('data', []):
print(f"{holiday['date']}: {holiday['description']}")
Exchange Timings
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')}")
Notes
- Always check funds before placing large orders
- Use Analyzer mode for testing strategies
- Monitor positions regularly for risk management
- Set up Telegram alerts for important events
- Position book updates in real-time during market hours
- Holdings update T+1 after delivery trades
Source
git clone https://github.com/marketcalls/openalgo-claude-plugin/blob/main/plugins/openalgo-python/skills/portfolio/SKILL.mdView on GitHub Overview
OpenAlgo Portfolio Management offers a unified Python SDK to access funds, positions, holdings, orders, trades, and margin information. It centralizes portfolio visibility for balance, P&L, and exposure across your account. This skill helps you monitor and audit your portfolio with ready-to-use API responses and quick-start scripts.
How This Skill Works
Initialize the OpenAlgo client with your API key and host, then call core methods such as funds(), positionbook(), holdings(), and orderbook() to retrieve structured data. The responses include fields like availablecash, pnl, ltp, average_price, and order statuses, which you can use to compute metrics and automate reporting.
When to Use It
- Before placing a new trade to check available cash and margin usage
- To review all open positions and their unrealized P&L (P&L) with LTP and average price
- To inspect CNC/Cash-and-Carry or other holdings and overall portfolio statistics
- To audit today’s orders, their status, and performance metrics
- To calculate required margin for a proposed trade using margin calculations
Quick Start
- Step 1: Set up the client with your API key and host (example: api_key='your_api_key_here', host='http://127.0.0.1:5000')
- Step 2: Fetch a portfolio summary with the quick-start script: python scripts/portfolio.py --summary
- Step 3: View positions and holdings: python scripts/portfolio.py --positions and python scripts/portfolio.py --holdings (optional: use python scripts/margin.py to calculate margin for a new trade)
Best Practices
- Securely store and rotate your API key and host endpoint; use environment variables where possible
- Use the provided quick-start scripts to validate connectivity and data integrity before trading
- Cross-check P&L by comparing LTP, average_price, and quantity in position/holdings data
- Be mindful of data types in responses (e.g., numeric values as strings) when parsing funds fields
- Automate periodic portfolio refreshes to monitor exposure, risk, and compliance
Example Use Cases
- Check current cash balance and margin usage from funds()
- List all open positions with symbol, exchange, quantity, average_price, and pnl from positionbook()
- Review CNC holdings with quantity and total pnl from holdings()
- Audit today’s orders and their statuses from orderbook()
- Calculate required margin for a proposed NFO SELL order using margin concepts