Agent skill

portfolio

Portfolio management with OpenAlgo - funds, positions, holdings, order book, trade book, margin calculator, and account management

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/development/portfolio

SKILL.md

OpenAlgo Portfolio Management

Manage your trading portfolio using OpenAlgo's unified Python SDK. Access funds, positions, holdings, orders, trades, and margin information.

Environment Setup

python
from openalgo import api

client = api(
    api_key='your_api_key_here',
    host='http://127.0.0.1:5000'
)

Quick Start Scripts

Portfolio Summary

bash
python scripts/portfolio.py --summary

View Positions

bash
python scripts/portfolio.py --positions

View Holdings

bash
python scripts/portfolio.py --holdings

Calculate Margin

bash
python scripts/margin.py --symbol NIFTY30JAN2526000CE --exchange NFO --action SELL --quantity 75

Core API Methods

1. Funds

Get account balance and margin information:

python
response = client.funds()

Response:

json
{
  "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 trades
  • collateral: Pledged collateral value
  • m2mrealized: Realized Mark-to-Market P&L
  • m2munrealized: Unrealized Mark-to-Market P&L
  • utiliseddebits: Margin utilized for open positions

2. Position Book

Get all open positions:

python
response = client.positionbook()

Response:

json
{
  "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):

python
response = client.holdings()

Response:

json
{
  "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:

python
response = client.orderbook()

Response:

json
{
  "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 executed
  • open: Order pending
  • cancelled: Order cancelled
  • rejected: Order rejected
  • trigger_pending: SL/SL-M waiting for trigger

5. Trade Book

Get all executed trades:

python
response = client.tradebook()

Response:

json
{
  "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:

python
response = client.orderstatus(
    order_id="250408000989443",
    strategy="MyStrategy"
)

Response:

json
{
  "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:

python
response = client.openposition(
    strategy="MyStrategy",
    symbol="RELIANCE",
    exchange="NSE",
    product="MIS"
)

Response:

json
{
  "status": "success",
  "quantity": "10"
}

Margin Calculator

Single Position Margin

python
response = client.margin(positions=[
    {
        "symbol": "NIFTY30JAN2526000CE",
        "exchange": "NFO",
        "action": "SELL",
        "product": "NRML",
        "pricetype": "MARKET",
        "quantity": "75"
    }
])

Response:

json
{
  "status": "success",
  "data": {
    "total_margin_required": 125000.00,
    "span_margin": 95000.00,
    "exposure_margin": 30000.00
  }
}

Multi-Leg Margin (Spread Benefit)

python
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:

python
response = client.closeposition(strategy="MyStrategy")

Response:

json
{
  "status": "success",
  "message": "All Open Positions Squared Off"
}

Cancel All Orders

Cancel all pending orders:

python
response = client.cancelallorder(strategy="MyStrategy")

Response:

json
{
  "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

python
response = client.analyzerstatus()

Response:

json
{
  "status": "success",
  "data": {
    "analyze_mode": true,
    "mode": "analyze",
    "total_logs": 25
  }
}

Toggle Analyzer Mode

python
# Enable paper trading
response = client.analyzertoggle(mode=True)

# Disable paper trading (live mode)
response = client.analyzertoggle(mode=False)

Telegram Alerts

Send trading notifications:

python
response = client.telegram(
    username="your_openalgo_username",
    message="NIFTY crossed 26000! Entry triggered."
)

Response:

json
{
  "status": "success",
  "message": "Notification sent successfully"
}

Common Patterns

Daily P&L Summary

python
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

python
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

python
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

python
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

python
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

python
response = client.holidays(year=2025)

for holiday in response.get('data', []):
    print(f"{holiday['date']}: {holiday['description']}")

Exchange Timings

python
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

Didn't find tool you were looking for?

Be as detailed as possible for better results