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

# Trader Positions

> Stream full position snapshots, price ticks, and resolutions for tracked traders.

<Note>
  **Room ID:** `polymarket_trader_positions` \
  **Endpoint:** `wss://api.struct.to/ws` \
  **Rate:** 0.005 credits per message
</Note>

Stream per-position updates for tracked traders, batched per block. The room emits three envelope types: full rows on trades, compact price ticks on mark-to-market refreshes, and resolution ticks when a position's market resolves.

<Tip>
  **Related guide:** [Real-time positions tracking](/guides/real-time-positions-tracking) seeds a portfolio from REST and keeps it live through this room.
</Tip>

## Envelope types

| Event | Trigger | dirty\_kinds |
| - | - | - |
| `trader_position_batch` | A trade landed | `["trade"]` (may include others) |
| `trader_position_price_batch` | Mark-to-market refresh | `["price"]` |
| `trader_position_resolution_batch` | The position's market resolved | `["position_resolved"]` |

Each envelope is shaped `{ type, room_id, block, data: [ ...rows ] }`. Empty batches are not sent. Resolution rows cover lifetime non-redeemers as well as fresh resolutions.

### dirty\_kinds

| Value | Meaning |
| - | - |
| `trade` | A buy, sell, merge, split, redemption, or NegRisk convert landed |
| `price` | An outcome price moved (mark-to-market refresh) |
| `position_resolved` | The position's market resolved |

## Subscribe

The `traders` filter is required.

### Filters

| Filter | Type | Required | Description |
| - | - | - | - |
| `traders` | `string[]` | Yes | EVM wallet addresses (0x-prefixed), non-empty |
| `dirty_kinds` | `string[]` | No | Subset of `["trade","price","position_resolved"]`, or `["all"]`. A row is delivered only if its `dirty_kinds` intersects this set. |

### Example

```json theme={null}
{
  "type": "join_room",
  "payload": {
    "room_id": "polymarket_trader_positions"
  }
}
```

```json theme={null}
{
  "type": "room_message",
  "payload": {
    "room_id": "polymarket_trader_positions",
    "message": {
      "action": "subscribe",
      "traders": ["0x1234567890abcdef1234567890abcdef12345678"]
    }
  }
}
```

### Response

```json theme={null}
{
  "type": "trader_positions_stream_subscribe_response",
  "room_id": "polymarket_trader_positions",
  "data": {
    "traders": ["0x1234567890abcdef1234567890abcdef12345678"],
    "rejected": [],
    "error": null
  }
}
```

## Events

### `trader_position_batch`

Full position rows, fired on trades.

```json theme={null}
{
  "type": "trader_position_batch",
  "room_id": "polymarket_trader_positions",
  "block": 68420001,
  "data": [
    {
      "trader": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      "position_id": "12345678901234567",
      "condition_id": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
      "market_slug": "will-bitcoin-hit-100k",
      "event_slug": "bitcoin-price-markets",
      "title": "Will Bitcoin hit $100k?",
      "question": "Will Bitcoin hit $100k by end of year?",
      "image_url": "https://polymarket.com/images/market.png",
      "outcome": "Yes",
      "outcome_index": 0,
      "open": true,
      "won": null,
      "total_buys": 3,
      "total_sells": 1,
      "converted_count": 0,
      "converted_shares_gained": 0.0,
      "converted_shares_lost": 0.0,
      "total_shares_bought": 1500.0,
      "total_shares_sold": 500.0,
      "total_buy_usd": 975.0,
      "total_sell_usd": 350.0,
      "redemption_usd": 0.0,
      "merge_usd": 0.0,
      "avg_entry_price": 0.65,
      "avg_exit_price": 0.7,
      "avg_price": 0.66,
      "realized_pnl_usd": 125.5,
      "realized_pnl_pct": 12.87,
      "total_fees": 2.65,
      "first_trade_at": 1742000000000,
      "last_trade_at": 1743500000000,
      "current_price": 0.72,
      "current_shares_balance": 1000.0,
      "current_value": 720.0,
      "last_traded_price": 0.71,
      "end_date": 1751328000,
      "is_neg_risk": false,
      "redeemable": false,
      "mergeable": false,
      "dirty_kinds": ["trade"]
    }
  ]
}
```

All fields are nullable.

| Field | Type | Description |
| - | - | - |
| `position_id` | `string` | ERC-1155 token ID (decimal string) |
| `condition_id` | `string` | Condition ID |
| `market_slug` | `string` | Market slug |
| `event_slug` | `string` | Owning event slug |
| `title` | `string` | Market title |
| `question` | `string` | Market question |
| `image_url` | `string` | Market image URL |
| `outcome` | `string` | Outcome label (for example `Yes`) |
| `outcome_index` | `int` | Outcome index |
| `open` | `bool` | Whether the position is open |
| `won` | `bool` | Set once the market resolves |
| `total_buys` | `int64` | Buy count |
| `total_sells` | `int64` | Sell count |
| `converted_count` | `int64` | NegRisk conversion count |
| `converted_shares_gained` | `number` | Shares gained via conversion |
| `converted_shares_lost` | `number` | Shares lost via conversion |
| `total_shares_bought` | `number` | Cumulative shares bought |
| `total_shares_sold` | `number` | Cumulative shares sold |
| `total_buy_usd` | `number` | Buy spend in USD |
| `total_sell_usd` | `number` | Sell proceeds in USD |
| `redemption_usd` | `number` | Redemption proceeds in USD |
| `merge_usd` | `number` | Merge proceeds in USD |
| `avg_entry_price` | `number` | Volume-weighted entry price (0-1) |
| `avg_exit_price` | `number` | Volume-weighted exit price (0-1) |
| `avg_price` | `number` | Volume-weighted price across buys and sells |
| `realized_pnl_usd` | `number` | Realized PnL in USD |
| `realized_pnl_pct` | `number` | Realized PnL as a percentage |
| `total_fees` | `number` | Total fees in USD |
| `first_trade_at` | `int64` | First trade (**Unix milliseconds**) |
| `last_trade_at` | `int64` | Last trade (**Unix milliseconds**) |
| `current_price` | `number` | Current outcome price |
| `current_shares_balance` | `number` | Current shares held |
| `current_value` | `number` | `current_price` times `current_shares_balance` |
| `last_traded_price` | `number` | Last on-chain traded price |
| `end_date` | `int64` | Resolution deadline (Unix seconds) |
| `is_neg_risk` | `bool` | Whether the market is NegRisk |
| `redeemable` | `bool` | Resolved and still holding shares |
| `mergeable` | `bool` | NegRisk, unresolved, and holding shares |
| `dirty_kinds` | `string[]` | What triggered this row |

### `trader_position_price_batch`

Compact price ticks. `dirty_kinds` is always `["price"]`.

```json theme={null}
{
  "type": "trader_position_price_batch",
  "room_id": "polymarket_trader_positions",
  "block": 68420002,
  "data": [
    {
      "trader": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      "position_id": "12345678901234567",
      "condition_id": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
      "current_price": 0.74,
      "current_value": 740.0,
      "realized_pnl_usd": 125.5,
      "realized_pnl_pct": 12.87,
      "last_block": 68420002,
      "last_trade_at": 1743500000000,
      "dirty_kinds": ["price"]
    }
  ]
}
```

| Field | Type | Description |
| - | - | - |
| `trader` | `string` | Wallet address |
| `position_id` | `string` | ERC-1155 token ID (decimal string) |
| `condition_id` | `string` | Condition ID |
| `current_price` | `number` | Current outcome price |
| `current_value` | `number` | Current position value in USD |
| `realized_pnl_usd` | `number` | Realized PnL in USD |
| `realized_pnl_pct` | `number` | Realized PnL as a percentage |
| `last_block` | `int64` | Block of this tick |
| `last_trade_at` | `int64` | Last trade (Unix milliseconds) |
| `dirty_kinds` | `string[]` | Always `["price"]` |

### `trader_position_resolution_batch`

Resolution ticks. `dirty_kinds` is always `["position_resolved"]`.

```json theme={null}
{
  "type": "trader_position_resolution_batch",
  "room_id": "polymarket_trader_positions",
  "block": 68420003,
  "data": [
    {
      "trader": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      "position_id": "12345678901234567",
      "condition_id": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
      "resolved": true,
      "won": true,
      "realized_pnl_usd": 350.25,
      "realized_pnl_pct": 35.9,
      "last_block": 68420003,
      "last_trade_at": 1743500000000,
      "dirty_kinds": ["position_resolved"]
    }
  ]
}
```

| Field | Type | Description |
| - | - | - |
| `trader` | `string` | Wallet address |
| `position_id` | `string` | ERC-1155 token ID (decimal string) |
| `condition_id` | `string` | Condition ID |
| `resolved` | `bool` | Whether the market resolved |
| `won` | `bool \| null` | Whether the position won |
| `realized_pnl_usd` | `number` | Realized PnL in USD |
| `realized_pnl_pct` | `number` | Realized PnL as a percentage |
| `last_block` | `int64` | Block of this tick |
| `last_trade_at` | `int64` | Last trade (Unix milliseconds) |
| `dirty_kinds` | `string[]` | Always `["position_resolved"]` |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.