Account
Positions
Position changes as the venue reports them.
WSSawait stream.watch_positions(market_ids=None)SDK stream · your process · venue credentials
Self-hosted. Opened from your own process straight to the venue. Nothing here runs on Synpath's servers.
Each event carries a Position, net on the YES leg. Polymarket has no position channel; read positions over REST there.
Venues
| Venue | Support | Notes |
|---|---|---|
| Polymarket | Not offered | No position channel on the venue. has["watch_positions"] is false. |
| Kalshi | Supported | |
| Polymarket US | Supported | |
| Opinion | Not offered |
Parameters
| Name | Type | Description |
|---|---|---|
market_ids | list[str] | None | Only these markets. Omit for every market. |
PositionEvent
A position changed.
| Name | Type | Description |
|---|---|---|
venue | string | Which venue the event came from. |
received_at | integer | When this process received it, ms since epoch. |
position | Position | The position, as in the REST API. |
import asyncio
from synpath import PolymarketTrading, PolymarketUserStream, load_credentials, require
trading = PolymarketTrading(require("polymarket", load_credentials()))
stream = PolymarketUserStream(trading=trading) # derives the CLOB credentials
from synpath import PositionEvent
async def main():
async with stream:
await stream.watch_positions() # Polymarket: not offered, read REST instead
async for event in stream:
if isinstance(event, PositionEvent):
p = event.position
print(p.market_id, p.side, p.contracts)
asyncio.run(main())PositionEvent
{
"venue": "kalshi",
"received_at": 1790077592174,
"position": {
"market_id": "kalshi:KXELONMARS-99",
"side": "long",
"contracts": "2",
"entry_price": "0.10",
"…": "the full Position"
}
}
