# Как читать позиции и активность кошельков Polymarket

> Polymarket разносит свой API по трём хостам, и позиции кошельков живут только на одном из них. Data API принимает адрес и возвращает содержимое кошелька — при лимите 150 запросов за 10 секунд, считаемом по IP.

- Источник: https://papaproxy.net/ru/blog/polymarket-data-api-positions.php
- Опубликовано: 2026-08-08
- Автор: Alex Young
- Рубрика: API и данные · Блог PapaProxy.net

---

## Ключевые выводы

- Позиции кошельков живут только на `data-api.polymarket.com`; Gamma отдаёт метаданные рынков, а CLOB — стаканы, цены и ваш собственный аутентифицированный журнал.
- Запрашивать нужно **User Profile Address** аккаунта, а какой это адрес — зависит от типа: EOA, `POLY_PROXY`, `GNOSIS_SAFE` или `POLY_1271`; для простого EOA фандером служит сам EOA. При неверном адресе вернётся пустой массив, а не ошибка.
- У `/positions` по умолчанию `sizeThreshold=1.0` и `limit=100` (максимум 500, `offset` до 10 000): ставьте порог в 0, листайте через `offset` и читайте `outcomeIndex` вместе с `size`.
- `/activity` принимает двенадцать типов, а не шесть: к торговым добавлены DEPOSIT, WITHDRAWAL, YIELD, MAKER_REBATE, TAKER_REBATE и REFERRAL_REWARD; для депозитов и выводов нужен `excludeDepositsWithdrawals=false`, `start`/`end` задаются в секундах эпохи, а `offset` за пределом 5 000 отклоняется с кодом 400.
- Лимиты считаются по IP: `/positions` и `/closed-positions` — 150 запросов за 10 секунд, `/trades` — 200, Data API в целом — 1 000. Документация описывает очередь, но наш тест августа 2026 года показал немедленные 429 без плавного замедления.
- Чтение полностью публично; аутентификация L1/L2 — с типом подписи и адресом фандера, подобранными под тип аккаунта, — нужна только для торговли и для собственного журнала.

## Где живёт Data API

Базовый адрес — `https://data-api.polymarket.com`, отдельно от Gamma (рынки и события) и от CLOB (стаканы и торговля). Модель, которая экономит больше всего времени: Gamma говорит, что существует, CLOB — сколько это стоит, а Data API — кто это держит.

Эндпоинт позиций Data API — обычный GET, которому не нужны ни ключ, ни подпись, ни аккаунт: документация описывает маршруты Data API как публичные.

TextКопировать код

```text
GET https://data-api.polymarket.com/positions?user=0x...&sizeThreshold=50&limit=500
```

Эндпоинту позиций пользователя обязателен только параметр `user`, а сверху навешиваются полезные фильтры. `market` принимает один или несколько condition ID списком через запятую, `eventId` делает то же самое для событий и взаимоисключающ с `market`. `sizeThreshold` задаёт минимальный размер позиции для включения в ответ и по умолчанию равен 1.0 — то есть пыль тихо отсекается; поставьте 0, если нужно всё. `redeemable` и `mergeable` сужают ответ до позиций в этих состояниях, а пагинация работает через `limit` (по умолчанию 100, максимум 500) и `offset` (максимум 10 000). Сортировка доступна через `sortBy` — CURRENT, INITIAL, TOKENS, CASHPNL, PERCENTPNL, TITLE, RESOLVING, PRICE или AVGPRICE, по умолчанию TOKENS — с `sortDirection` в значениях ASC или DESC.

Пример ответа эндпоинта позиций содержит объекты с полями `proxyWallet`, `conditionId`, `asset`, `size`, `avgPrice`, `initialValue`, `currentValue`, `cashPnl`, `percentPnl`, `realizedPnl`, `curPrice`, `redeemable`, `mergeable`, `negativeRisk` плюс рыночный контекст — `title`, `slug`, `outcome`, `outcomeIndex`, `oppositeOutcome`, `endDate`.

Два поля заслуживают внимания до того, как вы начнёте на них опираться. Параметр `user` документирован как **User Profile Address**, и какой это адрес — зависит от типа аккаунта: Polymarket поддерживает аккаунты на обычном EOA наряду с типами подписи `POLY_PROXY`, `GNOSIS_SAFE` и `POLY_1271`, причём для простого EOA фандером выступает сам EOA. Так что правило «всегда запрашивайте прокси» неверно; верное — запрашивать адрес, который держит позицию при этом типе аккаунта, и именно его ответ возвращает в поле `proxyWallet`. Запрос подписывающего ключа, который не является профильным адресом, вернёт пустой массив, а не ошибку, — поэтому логируйте, какой адрес вы спрашивали. А `outcomeIndex` важен не меньше `size`: у одного рынка есть сторона Yes и сторона No, поэтому позиция осмысленна только вместе с исходом, к которому относится.

PythonКопировать код

```python
import requests

DATA = "https://data-api.polymarket.com"
PAGE = 500                                    # документированный максимум

def positions(profile_address, min_size=0):
    out, offset = [], 0
    while offset <= 10000:                    # документированный потолок offset
        r = requests.get(f"{DATA}/positions",
                         params={"user": profile_address, "sizeThreshold": min_size,
                                 "limit": PAGE, "offset": offset,
                                 "sortBy": "CURRENT", "sortDirection": "DESC"},
                         timeout=10)
        r.raise_for_status()
        page = r.json()
        out.extend(page)
        if len(page) < PAGE:                  # неполная страница — значит, последняя
            break
        offset += PAGE
    return out

for p in positions("0x0000000000000000000000000000000000000000")[:5]:
    print(f"{p['title'][:45]:<45} {p['outcome']:<4} "
          f"size={p['size']:>10.2f} value=${p['currentValue']:>10.2f} pnl=${p['cashPnl']:>9.2f}")
```

На что смотреть: `sizeThreshold=0` перекрывает значение по умолчанию 1.0, поэтому пыль не отсекается молча, а цикл идёт по `offset`, а не останавливается на первых 500 — иначе кошелёк с широким портфелем оказался бы обрезан без всякой ошибки. Цикл завершается на неполной странице и не пытается уйти за документированный потолок `offset` в 10 000, который и есть реальный предел глубины этого эндпоинта. Для кошелька без открытых позиций вызов вернёт пустой список — ровно ту же форму, что и при запросе адреса, не являющегося профильным для аккаунта.

## Откуда взять список кошельков

Позиции бесполезны, пока неизвестно, чьи именно читать, — для этого и нужен лидерборд. Data API отдаёт рейтинг топ-трейдеров по прибыли или объёму за выбранное окно, а рядом существует лидерборд билдеров — приложений, которые направляют поток ордеров через билдер-программу Polymarket. Документация лидерборда тоньше остальной поверхности, а форма ответа менялась не раз, поэтому сверяйте текущий ответ со своим парсером, а не доверяйте списку полей из чужой статьи — включая эту.

Операционный паттерн тот же, что и на любой площадке с такой связкой: рейтинги двигаются медленно, позиции — постоянно. Забирайте лидерборд по медленному расписанию, кешируйте список кошельков и тратьте бюджет запросов на вызовы позиций, которые действительно меняются. Если нужен итог по портфелю, а не разбивка по позициям, `/value` вернёт совокупную стоимость кошелька одним вызовом — заметно дешевле, чем тянуть все позиции и суммировать самому.

## Как читать сделки и активность

Позиции говорят, где кошелёк находится сейчас; эндпоинт активности — как он туда пришёл. `GET /activity?user=0x...` возвращает ончейн-активность, упорядоченную по времени от свежего к старому, а фильтр `type` принимает двенадцать значений: TRADE, SPLIT, MERGE, REDEEM, REWARD, CONVERSION, DEPOSIT, WITHDRAWAL, YIELD, MAKER_REBATE, TAKER_REBATE и REFERRAL_REWARD. Этот список стоит прочитать дважды, потому что сделкой из них является только первое: сплиты и мерджи перекладывают средства между дополняющими токенами исходов, редемпшены закрывают разрешившиеся рынки, ребейты и доходность — это поступления, а не активность, и если считать всё это сделками, любая метрика объёма окажется завышенной.

Три параметра ловят людей регулярно. `start` и `end` задаются в **секундах**, а не в миллисекундах — конвенция, обратная большинству биржевых API. Депозиты и выводы по умолчанию исключены: `excludeDepositsWithdrawals` имеет значение `true` по умолчанию, и это значение побеждает, даже если вы указали DEPOSIT или WITHDRAWAL в `type`, — чтобы их увидеть, нужно явно передать `false`. А история по умолчанию ограничена окном: без `start` или при `start=0` вернутся примерно последние три года, тогда как положительная отметка вроде `1` открывает полную историю. `side` фильтрует BUY или SELL, но применяется только к сделкам, поэтому в сочетании с фильтром REDEEM вернёт пустоту.

Пагинация здесь ведёт себя иначе, чем у `/positions`, и разница важна. Потолок `offset` равен 5 000, причём запросы за его пределами отклоняются с кодом 400, а не обрезаются молча; чтобы уйти глубже, нужно листать внутри окон `start`/`end`, у каждого из которых свой бюджет offset. Порядок стабилен в обе стороны, поэтому страницы стыкуются без пропусков и повторов. Сортировка идёт через `sortBy` со значениями TIMESTAMP, TOKENS или CASH.

Отдельно по исполнениям: `/trades` возвращает сделки по адресу кошелька с необязательными фильтрами и несёт собственный, более жёсткий бюджет — 200 запросов за 10 секунд. Со стороны рынка, а не кошелька, работает эндпоинт держателей: `GET /holders?market=...` возвращает крупнейших держателей токенов исхода конкретного рынка — прямой способ находить новые кошельки, достойные наблюдения, вообще не обходя лидерборд.

## Позиции в двух других API

Регулярный поисковый запрос — эндпоинт позиций в CLOB или эндпоинт позиций в Gamma, и честный ответ таков: на август 2026 года позиции кошельков не живут ни там, ни там. Это не пробел в вашем чтении, а способ разделения поверхностей.

CLOB на `https://clob.polymarket.com` — поверхность торговли и рыночных данных: стаканы через `/book` и `/books`, цены через `/price`, `/midpoint` и `/prices-history`, а собственный журнал — через `/data/orders` и `/data/trades`. Последние два ограничены аккаунтом и требуют аутентификации, то есть показывают, что делали *вы*, а не что держит произвольный кошелёк. Gamma на `https://gamma-api.polymarket.com` — поверхность метаданных: события, рынки, теги, поиск. Она отвечает на вопрос «что это за рынок и какие у него condition ID», а это ровно то, что нужно, чтобы превратить `conditionId` из ответа по позициям в человекочитаемый рынок.

Поэтому практическая форма трекера — три хоста с тремя задачами: Data API для состояния кошельков, Gamma для рыночного контекста, CLOB для живых цен. У каждого свой бюджет лимитов, и это скорее плюс, чем неудобство: обогащение позиций метаданными рынка тратит квоту Gamma, а не ту, которую расходует ваш опрос позиций.

## Аутентификация для аккаунтных эндпоинтов

Всё вышеописанное публично. Аутентификация появляется только там, где вы выставляете ордера или читаете собственный журнал, и устроена она в два уровня. L1 — подпись вашим приватным ключом, которая создаёт или выводит API-ключ; L2 — сам этот ключ, используемый как HMAC-заголовки в последующих запросах. Спотыкаются же на паре «подписант — фандер», потому что это не всегда один и тот же адрес: Polymarket поддерживает несколько типов аккаунтов — обычный EOA наряду с типами подписи `POLY_PROXY`, `GNOSIS_SAFE` и `POLY_1271`, — и клиенту нужно сообщить и применимый тип подписи, и адрес, который фактически держит средства. Для аккаунта на EOA фандером выступает сам EOA; для прокси- и Safe-типов — нет. Ошибитесь в этой паре — и ордера не пройдут валидацию, хотя сам ключ верен.

Отсюда два следствия. Первое: конвейеру наблюдения за кошельками учётные данные не нужны вовсе — если вы только читаете позиции, активность и сделки по адресу, неаутентифицированный клиент и есть правильная конструкция. Второе: когда торговля всё же добавляется, эндпоинты API-ключей несут собственный лимит в 100 запросов за 10 секунд, а ордера и отмены в CLOB дополнительно управляются токен-бакетными лимитами на подписанта, которые лежат за пределами IP-ориентированных чисел ниже.

## Лимиты и что они значат для масштаба

Лимиты Polymarket считаются по IP и применяются через Cloudflare на скользящих, а не фиксированных окнах. Документация утверждает, что лишние запросы задерживаются и ставятся в очередь, но [наш тест августа 2026 года показал немедленные 429 без плавного замедления](/ru/blog/polymarket-api-rate-limits.php#_3). Следите и за задержкой, и за кодами статуса, а также ведите собственные счётчики запросов по эндпоинтам вместо расчёта на один неизменный сигнал.

Документированные бюджеты Data API:

| Эндпоинт | Лимит |
| --- | --- |
| Общий | 1 000 запросов / 10 с |
| `/positions` | 150 запросов / 10 с |
| `/closed-positions` | 150 запросов / 10 с |
| `/trades` | 200 запросов / 10 с |

Для сравнения: общая квота Gamma — 4 000 за 10 секунд, у CLOB — 9 000, а глобальный потолок по всему сразу — 15 000.

Один вызов позиций на кошелёк превращает 150 за 10 секунд в арифметику. Если планировать примерно на 70% от лимита, чтобы держаться в стороне от троттлинга, один адрес обслуживает около 105 чтений кошельков за десятисекундный цикл:

| Кошельков под наблюдением | Обновление раз в 10 с | раз в 30 с | раз в 60 с |
| --- | --- | --- | --- |
| 100 | 1 | 1 | 1 |
| 500 | 5 | 2 | 1 |
| 1 000 | 10 | 4 | 2 |
| 5 000 | 48 | 16 | 8 |

Это расчёты по опубликованным лимитам, а не замеры: считайте их отправной точкой планирования и проверяйте на собственном трафике.

Прежде чем добавлять мощность, потратьте программные рычаги — большинство трекеров расточительны одинаково, в трёх местах. Группируйте по рынку, а не по кошельку, где это возможно: `/holders` отвечает на вопрос «кто держит этот рынок» одним вызовом, заменяя десятки чтений по кошелькам. Используйте `/value`, когда нужен итог по портфелю, а не каждая строка. И разносите опрос по уровням: кошелькам с крупной живой экспозицией нужен короткий интервал, спящим — длинный, а равномерный таймер тратит большую часть бюджета на подтверждение того, что ничего не изменилось.

За этими рычагами ограничением остаётся то, что бюджет принадлежит IP-адресу, а не аккаунту, — поэтому широкий трекер либо замедляется, либо распределяется по адресам. Эту часть и закрывают наши [персональные прокси](/ru/individual.php): выделенные IPv4-адреса, статичные на весь срок плана, к каждому применяется собственная документированная поадресная квота — но реальное масштабирование стоит проверять на своей нагрузке, а не считать линейным по умолчанию. Изоляция воркеров заодно не даёт ответам лимитера или очереди одной задачи тормозить другую.
