Package Logo
polymarket-pnl
polymarket-pnl@v1.0.0
Total Downloads
1289
Published
yesterday
Network
polygon polygon
Publisher
User Avatar PaulieB14

Readme

Polymarket P&L Substreams


Overview

Comprehensive Substreams package for tracking Polymarket P&L with SQL sink support for persistent state accumulation. Tracks all trading activity from both CTF Exchange and Neg Risk Exchange contracts.

Key Features

Feature Description
Real P&L Tracking Realized & unrealized P&L with cost basis
SQL Sink PostgreSQL/Clickhouse for persistent state
Trader Analytics Volume, win rate, max drawdown
Market Stats Price, volume, trade counts per market
Whale Detection Large trade tracking with trader context

Quick Start

Stream Data (No Database)

# Install CLI
brew install streamingfast/tap/substreams

# Authenticate
substreams auth

# Stream order fills
substreams run https://spkg.io/PaulieB14/polymarket-pnl-v1.0.0.spkg \
  map_order_fills \
  -e polygon.substreams.pinax.network:443 \
  -s 65000000 -t +1000

# Stream user P&L
substreams run https://spkg.io/PaulieB14/polymarket-pnl-v1.0.0.spkg \
  map_user_pnl \
  -e polygon.substreams.pinax.network:443 \
  -s 65000000 -t +1000

Sink to PostgreSQL (Required for P&L)

Important: P&L requires accumulated state. Use the SQL sink for accurate calculations.

# Install sink
brew install streamingfast/tap/substreams-sink-sql

# Create database
createdb polymarket_pnl

# Setup schema
substreams-sink-sql setup \
  "psql://localhost:5432/polymarket_pnl?sslmode=disable" \
  https://spkg.io/PaulieB14/polymarket-pnl-v1.0.0.spkg

# Run sink (start from beginning for full history)
substreams-sink-sql run \
  "psql://localhost:5432/polymarket_pnl?sslmode=disable" \
  https://spkg.io/PaulieB14/polymarket-pnl-v1.0.0.spkg \
  -e polygon.substreams.pinax.network:443

Query Your Data

-- Top traders by P&L
SELECT * FROM leaderboard_pnl LIMIT 20;

-- Whale trades with trader stats
SELECT * FROM whale_trades;

-- User positions
SELECT * FROM user_positions
WHERE user_address = '0x...' AND quantity > 0;

-- Daily stats
SELECT date, total_volume, total_trades
FROM daily_stats ORDER BY date DESC;

Architecture

                    Polygon Blockchain
                           │
                           ▼
              ┌─────────────────────────┐
              │     Firehose Blocks     │
              └─────────────────────────┘
                           │
         ┌─────────────────┼─────────────────┐
         ▼                 ▼                 ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ map_order_fills │ │map_token_transf │ │map_usdc_transf  │
│  (CTF + NegRisk)│ │    (ERC1155)    │ │    (USDC)       │
└─────────────────┘ └─────────────────┘ └─────────────────┘
         │                 │                   │
         └─────────────────┼───────────────────┘
                           ▼
              ┌─────────────────────────┐
              │    STORES (State)       │
              │  • user_positions       │
              │  • user_cost_basis      │
              │  • user_realized_pnl    │
              │  • latest_prices        │
              └─────────────────────────┘
                           │
                           ▼
              ┌─────────────────────────┐
              │      map_user_pnl       │
              │   (Computed Analytics)  │
              └─────────────────────────┘
                           │
                           ▼
              ┌─────────────────────────┐
              │         db_out          │
              │      (SQL Sink)         │
              └─────────────────────────┘
                           │
                           ▼
              ┌─────────────────────────┐
              │       PostgreSQL        │
              └─────────────────────────┘

Modules

Layer 1: Event Extraction

Module Description
map_order_fills OrderFilled events from CTF & NegRisk exchanges
map_token_transfers ERC1155 TransferSingle events
map_usdc_transfers USDC transfer events

Layer 2: State Stores

Store Key Description
store_user_positions {user}:{token} Position quantities
store_user_cost_basis {user}:{token} Total cost basis
store_user_realized_pnl {user} Realized P&L
store_user_volume {user} Trading volume
store_user_trade_count {user} Trade count
store_market_volume {token} Market volume
store_latest_prices {token} Latest prices

Layer 3: Analytics

Module Description
map_user_pnl Real-time P&L calculations
map_market_stats Market-level statistics

Layer 4: Sink

Module Description
db_out Database changes for SQL sink

Database Schema

Tables

Table Description
trades All order fills with price, amount, side
user_pnl Aggregated P&L per user
user_positions Current positions with cost basis
markets Market statistics
daily_stats Daily aggregates

Views

View Description
leaderboard_pnl Top 1000 by P&L
leaderboard_volume Top 1000 by volume
whale_trades Trades >$10K

Contract Addresses

Contract Address Start Block
CTF Exchange 0x4bfb41d5b3570defd03c39a9a4d8de6bd8b8982e 33,605,403
NegRisk Exchange 0xC5d563A36AE78145C45a50134d48A1215220f80a 50,505,492
Conditional Tokens 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045 4,023,686
USDC 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 4,023,686

Build from Source

# Clone
git clone https://github.com/PaulieB14/Polymarket-P-L-Substreams
cd Polymarket-P-L-Substreams

# Build
substreams build

# Test
substreams run substreams.yaml map_order_fills \
  -e polygon.substreams.pinax.network:443 \
  -s 65000000 -t +100

# Package & publish
substreams pack substreams.yaml -o polymarket-pnl-v1.0.0.spkg
substreams publish polymarket-pnl-v1.0.0.spkg

Why SQL Sink?

P&L calculation requires state accumulation over time:

Without Sink With SQL Sink
No history Full history persisted
P&L = $0 Accurate P&L
Stateless Tracks cost basis
Demo only Production ready

Related


License

MIT

Documentation

Modules

Maps icon
Maps

map
map_order_fills

c6d4e782ebde58c7966e4a5c79ce64952b561ed0
map map_order_fills (
blocksf.ethereum.type.v2.Block
)  -> pnl.v1.OrderFills

Extracts OrderFilled events from both CTF Exchange and NegRisk Exchange. This is the primary source of trading activity.

substreams gui polymarket-pnl@v1.0.0 map_order_fills

map
map_token_transfers

85961cb6579b1cc7106fccf2d3e7cd0c0febb693
map map_token_transfers (
)  -> pnl.v1.TokenTransfers

Extracts ERC1155 TransferSingle events for position tracking.

substreams gui polymarket-pnl@v1.0.0 map_token_transfers

map
map_usdc_transfers

52a074bf8e7468bcc01af82dc5f9c266bdbd9b3e
map map_usdc_transfers (
)  -> pnl.v1.UsdcTransfers

Extracts USDC (ERC20) transfer events for collateral tracking.

substreams gui polymarket-pnl@v1.0.0 map_usdc_transfers

map
map_user_pnl

e647965e02d6ecbc718f109649af79ab02dc4312

Computes real-time P&L for users based on their positions and trades. Outputs user P&L updates when positions change.

substreams gui polymarket-pnl@v1.0.0 map_user_pnl

map
map_market_stats

497ed714f315443aa94a41a1ca8ddc9933a16c41
map map_market_stats (
store_market_volumeDELTAS<add,bigint>
)  -> pnl.v1.MarketStats

Computes market-level statistics (volume, trades, prices).

substreams gui polymarket-pnl@v1.0.0 map_market_stats

map
db_out

f62f3472debcf0d46e6f55131f5ad4c2a02f3b0f
Default param : min_trade_size=1000000

Outputs database changes for SQL sink (PostgreSQL/Clickhouse). Creates/updates tables: trades, user_pnl, user_positions, markets

substreams gui polymarket-pnl@v1.0.0 db_out

map
ethcommon:all_events

963652a247fd23d0823dde62d21ae54c783b6073
map ethcommon:all_events (
)  -> sf.substreams.ethereum.v1.Events

all_events gives you all the events in a block (from successful transactions), with basic block hash/number/timestamp and transaction hash

substreams gui polymarket-pnl@v1.0.0 ethcommon:all_events
Stores icon
Stores

store
store_user_positions

fd1882699a0c7996f2fb4089ea1060539a5e30c2
store <add,bigint> store_user_positions (
)

Accumulates user positions per token. Tracks quantity held. Key: {user_address}:{token_id}

substreams gui polymarket-pnl@v1.0.0 store_user_positions

store
store_user_cost_basis

47d95c210dfcb5773fd1f4d7c755f1110e7c6f18
store <add,bigint> store_user_cost_basis (
)

Tracks total cost basis per user per token for average price calculation. Key: {user_address}:{token_id}

substreams gui polymarket-pnl@v1.0.0 store_user_cost_basis

store
store_user_realized_pnl

b1675be6592cc31e422b36c60105089debb1ac4f
store <add,bigint> store_user_realized_pnl (
)

Accumulates realized P&L when users sell positions. Key: {user_address}

substreams gui polymarket-pnl@v1.0.0 store_user_realized_pnl

store
store_user_volume

41715d831f1fecf1594e8f8ff52a8e77720b68d6
store <add,bigint> store_user_volume (
)

Tracks total trading volume per user. Key: {user_address}

substreams gui polymarket-pnl@v1.0.0 store_user_volume

store
store_user_trade_count

06f9fda8109469a8ca37379348ac382b33135ae0
store <add,int64> store_user_trade_count (
)

Tracks number of trades per user. Key: {user_address}

substreams gui polymarket-pnl@v1.0.0 store_user_trade_count

store
store_market_volume

f083e9da251f7dde2cc48fe528c3ebf41dac742c
store <add,bigint> store_market_volume (
)

Tracks total volume per market (token_id). Key: {token_id}

substreams gui polymarket-pnl@v1.0.0 store_market_volume

store
store_latest_prices

dadf4c378dec7e96dca953c71849337a2ba19dda
store <set,pnl.v1.TokenPrice> store_latest_prices (
)

Stores latest price per token for unrealized P&L calculation. Key: {token_id}

substreams gui polymarket-pnl@v1.0.0 store_latest_prices
Block Indexes icon
Block Indexes

blockIndex
ethcommon:index_events

87255243f80f5d4755cd826ec57bf70696a4d7b6

index_events sets the following keys on the block:

  • Event signatures evt_sig:0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef (signature in hex, prefixed by 0x)
  • Event address evt_addr:0x0123456789abcdef0123456789abcdef01234567 (address in hex, prefixed by 0x)
substreams gui polymarket-pnl@v1.0.0 ethcommon:index_events
Protobuf

Protobuf Docs Explorer

pnl.v1
sf.ethereum.type.v2
sf.ethereum.substreams.v1