---
title: "Wallet Analytics"
description: "Public wallet analytics for Polymarket: trade history, positions, portfolio value, top holders, profiles, and flow analysis. No authentication required."
icon: "wallet"
---

<Note>
  **Pro Feature.** Requires a Pro or Ultra subscription. [Get started at api.mathematicalcompany.com](https://api.mathematicalcompany.com)
</Note>

# Wallet Analytics

Horizon provides read-only access to Polymarket's public Data API for wallet-level analytics. Fetch any wallet's trade history, open positions, portfolio value, and public profile - no authentication or private keys required.

<Note>
  All wallet analytics use Polymarket's public Data API. You only need a wallet address (0x...) to look up any trader. This is useful for flow analysis, whale tracking, copy trading research, and competitive intelligence.
</Note>

## Overview

<CardGroup cols={2}>
  <Card title="Trade History" icon="clock-rotate-left">
    `hz.get_wallet_trades()` and `hz.get_market_trades()` for per-wallet and per-market trade feeds.
  </Card>
  <Card title="Open Positions" icon="chart-pie">
    `hz.get_wallet_positions()` with PnL, entry price, current price, and multiple sort options.
  </Card>
  <Card title="Top Holders" icon="ranking-star">
    `hz.get_top_holders()` to see the largest positions in any market.
  </Card>
  <Card title="Flow Analysis" icon="wave-pulse">
    `hz.analyze_market_flow()` aggregates buy/sell volume, net flow, and top buyers/sellers.
  </Card>
</CardGroup>

---

## Trade History

### hz.get_market_trades

Fetch recent trades for a specific market.

```python
import horizon as hz

trades = hz.get_market_trades(
    condition_id="0xabc123...",   # Market condition ID
    limit=100,                    # Max trades (up to 10,000)
    offset=0,                     # Pagination offset
    side="BUY",                   # Filter: "BUY", "SELL", or None (both)
    min_size=10.0,                # Minimum trade size in USDC
)

for t in trades:
    print(f"{t.wallet[:10]}... {t.side} {t.size:.0f} @ {t.price:.2f} ({t.market_title})")
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `condition_id` | `str` | required | Market condition ID (0x-prefixed) |
| `limit` | `int` | `100` | Max trades to return (max 10,000) |
| `offset` | `int` | `0` | Pagination offset |
| `side` | `str or None` | `None` | Filter by `"BUY"` or `"SELL"` |
| `min_size` | `float` | `0.0` | Minimum trade size in USDC |

Returns newest trades first.

### hz.get_wallet_trades

Fetch all trades for a specific wallet.

```python
trades = hz.get_wallet_trades(
    address="0x1234...",          # Wallet address
    limit=100,
    condition_id="0xabc...",      # Optional: filter to one market
)

total_volume = sum(t.usdc_size for t in trades)
print(f"Total volume: ${total_volume:,.2f}")
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `address` | `str` | required | Wallet address (0x...) |
| `limit` | `int` | `100` | Max trades to return |
| `offset` | `int` | `0` | Pagination offset |
| `condition_id` | `str or None` | `None` | Filter to a specific market |

---

## Positions

### hz.get_wallet_positions

Fetch open positions for a wallet with full PnL data.

```python
positions = hz.get_wallet_positions(
    address="0x1234...",
    limit=100,
    sort_by="CASHPNL",           # Sort by realized PnL
)

for p in positions:
    print(f"{p.market_title}")
    print(f"  {p.outcome} {p.size:.0f} contracts @ {p.avg_price:.2f}")
    print(f"  Current: {p.current_price:.2f}  PnL: ${p.pnl:+.2f} ({p.pnl_percent:+.1f}%)")
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `address` | `str` | required | Wallet address |
| `limit` | `int` | `100` | Max positions (max 500) |
| `offset` | `int` | `0` | Pagination offset |
| `condition_id` | `str or None` | `None` | Filter to one market |
| `sort_by` | `str` | `"TOKENS"` | Sort field (see below) |

**Sort options:**

| Value | Description |
|-------|-------------|
| `"TOKENS"` | Position size (default) |
| `"CURRENT"` | Current market value |
| `"INITIAL"` | Initial cost basis |
| `"CASHPNL"` | Realized cash PnL |
| `"PERCENTPNL"` | Percentage return |
| `"PRICE"` | Current market price |
| `"AVGPRICE"` | Average entry price |

### hz.get_wallet_value

Get total USD value of all open positions.

```python
value = hz.get_wallet_value("0x1234...")
print(f"Portfolio value: ${value:,.2f}")
```

Returns `0.0` on error or if the wallet has no positions.

---

## Top Holders

### hz.get_top_holders

Get the largest position holders in a market.

```python
holders = hz.get_top_holders(
    condition_id="0xabc...",
    limit=20,                     # Max 20
)

for h in holders:
    name = h.pseudonym or h.wallet[:10] + "..."
    print(f"{name}: {h.amount:,.0f} tokens (outcome {h.outcome_index})")
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `condition_id` | `str` | required | Market condition ID |
| `limit` | `int` | `20` | Max holders (max 20) |

Results are sorted by position size (descending).

---

## Wallet Profile

### hz.get_wallet_profile

Fetch public profile for a Polymarket wallet.

```python
profile = hz.get_wallet_profile("0x1234...")

if profile:
    print(f"Name: {profile.pseudonym or profile.name}")
    print(f"Bio: {profile.bio}")
    print(f"Twitter: @{profile.x_username}")
    print(f"Joined: {profile.created_at}")
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `address` | `str` | required | Wallet address |

Returns `None` if no profile exists for the address.

---

## Flow Analysis

### hz.analyze_market_flow

Aggregate trade flow analytics for a market - buy/sell volume, net flow, unique wallets, and top buyers/sellers.

```python
flow = hz.analyze_market_flow(
    condition_id="0xabc...",
    trade_limit=500,              # Analyze last 500 trades
    top_n=10,                     # Top 10 buyers/sellers
)

print(f"Total trades:    {flow.total_trades}")
print(f"Buy volume:      ${flow.buy_volume:,.2f}")
print(f"Sell volume:     ${flow.sell_volume:,.2f}")
print(f"Net flow:        ${flow.net_flow:+,.2f}")
print(f"Unique wallets:  {flow.unique_wallets}")

print("\nTop Buyers:")
for wallet, volume in flow.top_buyers:
    print(f"  {wallet[:10]}... ${volume:,.2f}")

print("\nTop Sellers:")
for wallet, volume in flow.top_sellers:
    print(f"  {wallet[:10]}... ${volume:,.2f}")
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `condition_id` | `str` | required | Market condition ID |
| `trade_limit` | `int` | `500` | Number of recent trades to analyze |
| `top_n` | `int` | `10` | Number of top buyers/sellers |

---

## Data Types

### Trade

```python
trade.wallet         # "0x1234..." (proxy wallet address)
trade.side           # "BUY" or "SELL"
trade.outcome        # "Yes" or "No"
trade.size           # Token amount
trade.price          # Trade price (0 to 1)
trade.usdc_size      # USD value (size * price)
trade.timestamp      # Unix timestamp
trade.market_slug    # Market slug
trade.market_title   # Market title
trade.condition_id   # Condition ID
trade.token_id       # Token ID
trade.tx_hash        # Transaction hash (optional)
trade.pseudonym      # Trader pseudonym (optional)
```

### WalletPosition (PolymarketPosition)

```python
pos.wallet           # Wallet address
pos.market_slug      # Market slug
pos.market_title     # Market title
pos.condition_id     # Condition ID
pos.token_id         # Token ID
pos.outcome          # "Yes" or "No"
pos.size             # Position size
pos.avg_price        # Average entry price
pos.current_price    # Current market price
pos.current_value    # Current USD value
pos.pnl              # Realized cash PnL
pos.pnl_percent      # Percentage return
```

<Tip>
  `WalletPosition` is imported as `hz.PolymarketPosition` to distinguish it from the engine's internal `Position` type.
</Tip>

### Holder

```python
holder.wallet         # Wallet address
holder.amount         # Token amount held
holder.token_id       # Token ID
holder.outcome_index  # 0 = Yes, 1 = No
holder.pseudonym      # Pseudonym (optional)
holder.name           # Display name (optional)
```

### WalletProfile

```python
profile.wallet         # Wallet address
profile.pseudonym      # Display pseudonym
profile.name           # Full name (optional)
profile.bio            # Profile bio (optional)
profile.profile_image  # Avatar URL (optional)
profile.x_username     # X/Twitter handle (optional)
profile.created_at     # Account creation date (optional)
```

### MarketFlow

```python
flow.condition_id     # Market condition ID
flow.total_trades     # Number of trades analyzed
flow.buy_volume       # Total buy volume in USD
flow.sell_volume      # Total sell volume in USD
flow.net_flow         # buy_volume - sell_volume
flow.unique_wallets   # Number of unique wallets
flow.top_buyers       # list[(wallet, volume)] top buyers
flow.top_sellers      # list[(wallet, volume)] top sellers
```

---

## Examples

### Whale Tracking

```python
import horizon as hz

# Find top holders in an election market
holders = hz.get_top_holders("0xabc123...")

for h in holders[:5]:
    profile = hz.get_wallet_profile(h.wallet)
    name = profile.pseudonym if profile else h.wallet[:10]

    # Get their trade history
    trades = hz.get_wallet_trades(h.wallet, limit=20)
    recent_side = trades[0].side if trades else "N/A"

    print(f"{name}: {h.amount:,.0f} tokens, last action: {recent_side}")
```

### Smart Money Flow

```python
import horizon as hz

# Analyze recent flow
flow = hz.analyze_market_flow("0xabc123...", trade_limit=1000)

if flow.net_flow > 0:
    print(f"Bullish flow: ${flow.net_flow:,.0f} net buying")
else:
    print(f"Bearish flow: ${abs(flow.net_flow):,.0f} net selling")

# Who's behind the flow?
print(f"\nTop buyer: {flow.top_buyers[0][0][:10]}... (${flow.top_buyers[0][1]:,.0f})")
```

### Portfolio Snapshot

```python
import horizon as hz

address = "0x1234..."

value = hz.get_wallet_value(address)
positions = hz.get_wallet_positions(address, sort_by="CURRENT")
profile = hz.get_wallet_profile(address)

print(f"Trader: {profile.pseudonym if profile else address[:10]}")
print(f"Portfolio: ${value:,.2f}")
print(f"Positions: {len(positions)}")

for p in positions[:5]:
    emoji = "+" if p.pnl > 0 else ""
    print(f"  {p.market_title[:40]}: {p.outcome} {p.size:.0f} @ {p.avg_price:.2f} → PnL {emoji}${p.pnl:.2f}")
```

<Warning>
  Wallet analytics use Polymarket's public Data API and are currently only available for Polymarket markets. Kalshi does not provide public wallet-level data. Rate limiting may apply for high-frequency requests.
</Warning>
