> ## Documentation Index
> Fetch the complete documentation index at: https://docs.limitless.exchange/llms.txt
> Use this file to discover all available pages before exploring further.

# Portfolio & Positions

> Track positions and history with the Python SDK

## Overview

The `PortfolioFetcher` class retrieves your profile, open positions, and portfolio data from the Limitless Exchange API. It requires an authenticated `HttpClient`.

## Setup

```python theme={null}
from limitless_sdk.api import HttpClient
from limitless_sdk.portfolio import PortfolioFetcher

http_client = HttpClient()  # loads LIMITLESS_API_KEY from env
portfolio = PortfolioFetcher(http_client)
```

<Note>
  `PortfolioFetcher` requires an authenticated client. Configure `LIMITLESS_API_KEY`, pass `api_key` to `HttpClient`, or use HMAC credentials through the root `Client` for partner/backend flows.
</Note>

## Current Profile

Use `get_current_profile()` to fetch the authenticated caller's private profile via `GET /profiles/me`. This is the preferred helper when the client is already authenticated and you do not want to pass a wallet address.

```python theme={null}
profile = await portfolio.get_current_profile()

print(profile["id"])       # numeric profile ID
print(profile["account"])  # authenticated wallet address
print(profile.get("rank", {}).get("feeRateBps"))
```

Use `get_profile(address)` only when you need the address-based route:

```python theme={null}
profile_by_address = await portfolio.get_profile("0xYOUR_WALLET_ADDRESS")
```

<Note>
  `get_current_profile()` calls `GET /profiles/me`; `get_profile(address)` calls `GET /profiles/:account`. Both return raw API responses matching the private profile schema.
</Note>

## Fetching Positions

Use `get_positions()` to retrieve all your open positions:

```python theme={null}
positions = await portfolio.get_positions()
```

The response is a dictionary with the following top-level keys:

| Key                  | Type         | Description                                       |
| -------------------- | ------------ | ------------------------------------------------- |
| `clob`               | `list[dict]` | Positions on CLOB (order book) markets            |
| `amm`                | `list[dict]` | Positions on AMM (automated market maker) markets |
| `accumulativePoints` | `dict`       | Accumulated points and rewards data               |

## Iterating CLOB Positions

Each entry in the `clob` list contains the market details and your position size:

```python theme={null}
positions = await portfolio.get_positions()

for pos in positions.get("clob", []):
    market_title = pos["market"]["title"]
    size = pos["size"]
    outcome = pos.get("outcomeIndex", "N/A")
    print(f"{market_title} — size: {size}, outcome index: {outcome}")
```

<Accordion title="Example response structure">
  ```python theme={null}
  {
      "clob": [
          {
              "market": {
                  "title": "BTC above 100k by March 2025?",
                  "slug": "btc-above-100k-march-2025",
              },
              "size": "15.5",
              "outcomeIndex": 0,
              # ... additional fields
          },
          # ... more positions
      ],
      "amm": [
          # ... AMM positions
      ],
      "accumulativePoints": {
          # ... points data
      },
  }
  ```
</Accordion>

<Note>
  The `PortfolioFetcher` returns **raw API responses** without heavy parsing or transformation. Field names and types match the REST API directly. Refer to the [API Reference](/api-reference/portfolio/positions) for the complete response schema.
</Note>

## Complete Example

```python theme={null}
import asyncio
from limitless_sdk.api import HttpClient
from limitless_sdk.portfolio import PortfolioFetcher

async def main():
    http_client = HttpClient()
    portfolio = PortfolioFetcher(http_client)

    positions = await portfolio.get_positions()

    clob_positions = positions.get("clob", [])
    amm_positions = positions.get("amm", [])

    print(f"CLOB positions: {len(clob_positions)}")
    for pos in clob_positions:
        print(f"  {pos['market']['title']} — size: {pos['size']}")

    print(f"\nAMM positions: {len(amm_positions)}")
    for pos in amm_positions:
        print(f"  {pos['market']['title']} — size: {pos['size']}")

    points = positions.get("accumulativePoints", {})
    print(f"\nAccumulative points: {points}")

    await http_client.close()

asyncio.run(main())
```
