← Back to All Tutorials

Tutorial 11: Polymarket Whale Scanner Beginner-Friendly

Table of Contents
  1. What Does This Scanner Do?
  2. Key Concepts
  3. Code Walkthrough
  4. Dependencies
  5. Glossary

1. What Does This Scanner Do?

This is a live WebSocket scanner that connects to Polymarket's real-time data feed and displays every trade worth $1,000 or more across ALL markets. It shows colorful "whale alerts" in your terminal as they happen - like a police scanner for big trades.

Simple Analogy: Imagine standing in a crowded marketplace. Most people are buying and selling small amounts, but occasionally someone walks in and drops $10,000 on a single bet. This scanner is like having a friend who taps you on the shoulder every time someone makes a big purchase, telling you who they are, what they bought, and how much they spent.

2. Key Concepts

What is a "Whale"?

In crypto/trading slang, a whale is someone who trades very large amounts. In this scanner, a whale is anyone who trades $1,000 or more in a single transaction on Polymarket.

Why track whales? Large trades can indicate:

WebSocket - Real-Time Data

HTTP (regular): You ask the server "any new trades?" every 10 seconds. The server says "yes" or "no."

WebSocket: You open a permanent connection to the server. The server pushes new trades to you the millisecond they happen. No asking needed - it just streams in.

This is like the difference between checking your mail every hour vs. having someone hand you each letter as it arrives.

Ping/Pong Heartbeat

WebSocket connections can silently die if neither side sends data for a while. The scanner sends a ping every 30 seconds to keep the connection alive. If the server doesn't respond, it knows the connection is dead and reconnects.

3. Code Walkthrough

1 Configuration

MIN_WHALE_USD = 1_000     # Only show trades >= $1,000
WEBSOCKET_URL = "wss://ws-live-data.polymarket.com"
PING_INTERVAL = 30        # Keep connection alive
HEARTBEAT_INTERVAL = 10   # Fun status line every 10s

What it does: Sets up the connection parameters. The WebSocket URL is Polymarket's live data endpoint. The minimum whale threshold filters out small trades.

2 WebSocket Handlers

def on_open(ws):
    # Connection established!
    print("Connected to Polymarket live data!")
    # Start heartbeat thread
    start_heartbeat()

def on_message(ws, message):
    # New trade data arrived!
    trade = json.loads(message)
    process_trade(trade)

def on_error(ws, error):
    # Something went wrong
    print(f"WebSocket error: {error}")

def on_close(ws, code, reason):
    # Connection closed - auto-reconnect
    if not shutdown_flag:
        connect_websocket()  # Reconnect!

What it does: These four functions handle the WebSocket lifecycle:

3 process_trade() - Filter and Display

def process_trade(trade):
    size = float(trade.get('size', 0))
    price = float(trade.get('price', 0))
    usd_value = size * price

    # Only show trades >= $1,000
    if usd_value >= MIN_WHALE_USD:
        print_whale(trade, usd_value)
        stats['whales_printed'] += 1
        if usd_value > stats['biggest_whale_usd']:
            stats['biggest_whale_usd'] = usd_value

What it does: For every incoming trade, calculates the USD value. If it's $1,000+, displays a colorful whale alert and updates the session statistics (tracking the biggest whale seen).

4 Heartbeat Loop - Keeping Things Fun

def heartbeat_loop():
    while not shutdown_flag:
        # Rotate through fun phrases
        phrase = random.choice(HEARTBEAT_PHRASES)
        spinner = SPINNER_FRAMES[frame % 4]
        print(f"  {spinner} {phrase}...")
        time.sleep(HEARTBEAT_INTERVAL)

What it does: Every 10 seconds, prints a fun rotating status line to show the scanner is still alive and working. Phrases like "scanning the deep blue for whales" and "sonar pinging the deep" keep the terminal lively.

5 Graceful Shutdown

def signal_handler(signum, frame):
    # Ctrl+C pressed - clean up nicely
    shutdown_flag = True
    ws_app.close()

    # Print final statistics
    print(f"Session: {stats['trades_seen']} trades, "
          f"{stats['whales_printed']} whales")
    print(f"Biggest whale: ${stats['biggest_whale_usd']:,.2f}")

What it does: When you press Ctrl+C, sets the shutdown flag, closes the WebSocket connection cleanly, and prints your session statistics before exiting. No orphaned connections or hanging processes.

4. Dependencies

pip install websocket-client termcolor

Only two packages! No API keys needed - Polymarket's live data feed is public.

5. Glossary

TermMeaning
WhaleA trader who makes very large trades (typically $1,000+)
WebSocketA protocol for real-time two-way communication between client and server
Ping/PongSmall messages sent to keep a connection alive and detect disconnections
HeartbeatA periodic signal showing the scanner is still running
ReconnectAutomatically re-establishing a dropped connection
ThreadA separate unit of execution running in parallel with the main program
Signal HandlerA function that runs when the OS sends a signal (like Ctrl+C)
Graceful ShutdownClosing all connections and cleaning up before exiting

6. Full Code: Python to Pseudo-Code Translation

Configuration & State

# --- PYTHON ---
MIN_WHALE_USD = 1_000
WEBSOCKET_URL = "wss://ws-live-data.polymarket.com"
PING_INTERVAL = 30
HEARTBEAT_INTERVAL = 10
shutdown_flag = False
stats = {'trades_seen': 0, 'whales_printed': 0,
         'biggest_whale_usd': 0.0, 'started_at': time.time()}
WHALE_EMOJIS = ['🐋', '🐳', '🦈', '🌊', '💰', '💎', '🚀', '🔥']

# --- PSEUDO-CODE ---
SET minimum whale trade size to $1,000
SET WebSocket URL to Polymarket's live data endpoint
SET ping interval to 30 seconds (keep connection alive)
SET heartbeat interval to 10 seconds (fun status updates)

INITIALIZE shutdown flag to FALSE (bot is running)
INITIALIZE statistics tracker:
    trades_seen: 0 (how many total trades streamed in)
    whales_printed: 0 (how many big trades were displayed)
    biggest_whale_usd: $0 (largest trade seen so far)
    started_at: current time

SET list of rotating whale emojis for fun display

WebSocket Handlers

# --- PYTHON ---
def on_open(ws):
    print("Connected!")
    start_heartbeat()

def on_message(ws, message):
    trade = json.loads(message)
    process_trade(trade)

def on_error(ws, error):
    print(f"Error: {error}")

def on_close(ws, code, reason):
    if not shutdown_flag:
        connect_websocket()  # auto-reconnect

# --- PSEUDO-CODE ---
FUNCTION on_open(websocket):
    This runs when the connection is first established
    PRINT "Connected to Polymarket live data!"
    START the heartbeat thread (periodic fun status messages)

FUNCTION on_message(websocket, raw message text):
    This runs EVERY TIME a new trade comes in
    PARSE the message from JSON text into a data object
    CALL process_trade() to analyze and maybe display it

FUNCTION on_error(websocket, error):
    This runs if something goes wrong
    PRINT the error

FUNCTION on_close(websocket, close code, reason):
    This runs when the connection drops
    IF we didn't intentionally shut down:
        RECONNECT automatically (the connection just died)

process_trade() - Filter & Display Whales

# --- PYTHON ---
def process_trade(trade):
    size = float(trade.get('size', 0))
    price = float(trade.get('price', 0))
    usd_value = size * price
    stats['trades_seen'] += 1
    if usd_value >= MIN_WHALE_USD:
        print_whale(trade, usd_value)
        stats['whales_printed'] += 1
        if usd_value > stats['biggest_whale_usd']:
            stats['biggest_whale_usd'] = usd_value
            stats['biggest_whale_market'] = trade.get('market', '')

# --- PSEUDO-CODE ---
FUNCTION process_trade(trade data):
    EXTRACT the trade size (how many shares)
    EXTRACT the trade price (how much per share)
    CALCULATE the total USD value = size x price

    ADD 1 to the total trades counter

    IF the trade value is $1,000 or more (it's a WHALE!):
        CALL print_whale() to display a colorful alert
        ADD 1 to the whales printed counter

        IF this is the biggest whale we've seen so far:
            UPDATE the record tracker with this trade's details

heartbeat_loop() - Keep Things Fun

# --- PYTHON ---
def heartbeat_loop():
    while not shutdown_flag:
        phrase = random.choice(HEARTBEAT_PHRASES)
        spinner = SPINNER_FRAMES[frame % 4]
        print(f"  {spinner} {phrase}...")
        time.sleep(HEARTBEAT_INTERVAL)

# --- PSEUDO-CODE ---
FUNCTION heartbeat_loop():
    LOOP until the user shuts down:
        PICK a random fun phrase from the list
            e.g., "scanning the deep blue for whales"
            e.g., "sonar pinging the deep"
            e.g., "patience pays - whales are coming"
        PICK the next spinner animation frame (🌊 rotating)
        PRINT the spinner + phrase to the terminal
        WAIT 10 seconds
        REPEAT

signal_handler() - Graceful Shutdown

# --- PYTHON ---
def signal_handler(signum, frame):
    global shutdown_flag
    shutdown_flag = True
    ws_app.close()
    elapsed = time.time() - stats['started_at']
    print(f"Session: {stats['trades_seen']} trades, "
          f"{stats['whales_printed']} whales in {elapsed/60:.0f} min")
    print(f"Biggest whale: ${stats['biggest_whale_usd']:,.2f}")

# --- PSEUDO-CODE ---
FUNCTION signal_handler(triggered when user presses Ctrl+C):
    SET shutdown flag to TRUE (tell all loops to stop)
    CLOSE the WebSocket connection cleanly

    CALCULATE how long the session lasted
    PRINT session summary:
        Total trades seen through the stream
        Total whales (trades >= $1,000) displayed
        Session duration in minutes
        The biggest whale trade seen (and which market)
    EXIT the program cleanly