NoLimitNodes
PricingDocsBlogAbout
SupportContact
Log in
Blog/Guides

Pump.fun WebSocket Guide: Build a Crypto Trading Bot for Popular Coins

The fourth bot in the Pump.Fun series trades on popularity rather than price action alone: it counts unique wallets interacting with each token over the live WebSocket trade stream, buys once the wallet count crosses a…

N
NoLimitNodes Team
Community & Tutorials
Feb 4, 2025updated Jun 10, 20266 min read
On this page +
  • 01What's Being Built Today?

The fourth bot in the Pump.Fun series trades on popularity rather than price action alone: it counts unique wallets interacting with each token over the live WebSocket trade stream, buys once the wallet count crosses a threshold, and exits on a profit or stop-loss percentage.

The idea is that a token attracting many distinct wallets is showing real demand, not one whale moving price. That's a usable signal, and it's cheap to compute from the trade feed.

If you're new here or missed the earlier lessons, like setting up WebSocket connections or creating your account, start with Mastering Pump.Fun Trading with WebSocket: Series 1 first.

What's Being Built Today?

We're building a popular coin trading bot for the Pump.Fun platform that uses WebSocket streams to monitor live market transactions and token prices in real time.

Here's how it works:

  • The bot identifies coins trading above a predefined threshold price.
  • It tracks unique wallets interacting with the coin, gauging its popularity.
  • Once the number of wallets passes a set limit, the bot flags the token as "popular" and executes a buy order.
  • After buying, the bot keeps monitoring the trade price and sells at either the profit margin or the loss margin, securing gains or cutting losses.

The result is a bot that trades on observable market interest instead of guesswork, without requiring constant manual effort from you.

Example:

Tracking Price:
The price of Token X rises above $0.0001. The bot starts monitoring transactions.

Wallet Count Validation:
Unique wallets begin interacting with Token X:

  • Transaction 1: Wallet A interacts with Token X. Wallet count: 1.
  • Transaction 15: Wallet P interacts with Token X. Wallet count: 15.
  • Transaction 35: Wallet Z interacts with Token X. Wallet count exceeds 30.

Buy Triggered:
The bot identifies Token X as "popular" because the wallet count has surpassed 30 and the price is still above $0.0001.

  • Buy executed: The bot buys Token X at $0.00012.

Profit or Stop-Loss:
The bot continues tracking the price of Token X:

  • If the price rises:
    • The price reaches $0.000132 (profit threshold).
    • Sell executed: The bot sells Token X for a profit.
    • Profit logged: Gain = $0.000012 per token.
  • If the price falls:
    • The price drops to $0.000114 (stop-loss threshold).
    • Sell executed: The bot sells Token X to minimize loss.
    • Loss logged: Loss = $0.000006 per token.

Each step runs automatically, so trades execute in response to market activity without delay.

Time to Create the Bot

Preconditions

Before starting, make sure you have the following ready:

  • Python: Ensure you have Python installed (version 3.x or higher is recommended).
  • API Key: Register for a free account at nolimitnodes.com to obtain your API key.
  • IDE: Open your favorite IDE and create a new script. Name the script: popularCoinTradingBot.py.

Getting Started

Start with the libraries the bot needs:

import websocket
import json
import threading
from threading import Lock

Global Variables

A few variables define the bot's behavior:

  • TRACKING_PRICE: The base price used as the threshold to start monitoring tokens.
  • PROFIT_PERCENT: The profit percentage at which the bot sells the token.
  • STOP_LOSS_PERCENT: The percentage loss that triggers a sell to limit risk.
  • min_wallet_number: The wallet-count threshold used to validate the buy condition.

Adjust these to fit the trading scenario you're targeting.

Data Structures

The bot keeps its state in a few simple structures:

  1. buy_dict: Tracks tokens the bot has purchased.
  2. sell_dict: Keeps a record of tokens sold.
  3. lock: A threading lock to ensure safe, simultaneous access to shared resources.

Statistical variables (buy_trade, profit_trade, loss_trade, and TOTAL_PROFIT_PRICE) track the bot's performance as it runs.

# Constants
TRACKING_PRICE = 0.0000001000
PROFIT_PERCENT = 10.0  # % of profit to trigger Sell
STOP_LOSS_PERCENT = 5.0  # % of loss to trigger Sell
min_wallet_number = 10
min_price =0

# Shared Resources
buy_dict = {}
sell_dict = {}
lock = Lock()

# Statistics
buy_trade = 0
profit_trade = 0
loss_trade = 0
TOTAL_PROFIT_PRICE = 0

# WebSocket URL and subscription message
URL = "wss://api.nolimitnodes.com/pump-fun?api_key=YOUR_API_KEY"

Next, the subscription request that asks the server for the trade stream:

SUBSCRIBE_PUMP_FUN_TRADE = {
    "method": "pumpFunTradeSubscribe",
    "params": {"referenceId": "hello", "coinAddress": "all"}
}

Now the handler that does the actual work.

How the Bot Processes Trade Events

Each trade event runs through this sequence:

  • Track Tokens for Buy Signals: Monitor tokens whose prices exceed TRACKING_PRICE and track their associated wallets.
  • Trigger Buys: If the number of wallets exceeds the threshold (min_wallet_number), initiate a buy and move the token to sell_dict.
  • Monitor Sell Opportunities: Tokens in sell_dict are sold when they hit either the PROFIT_PERCENT target or fall below the STOP_LOSS_PERCENT.
  • Update Metrics: Maintain and log statistics for buy trades, profitable sells, and stop-loss hits.
def handle_transaction_message(ws, message):
    global buy_trade, profit_trade, loss_trade, TOTAL_PROFIT_PRICE, min_wallet_number

    try:
        data = json.loads(message)
    except json.JSONDecodeError:
        print("Received invalid JSON data")
        return

    if data.get("method") == "tradeEventNotification":
        trade_details = data["result"]
        trade_price = float(trade_details["price"]["sol"])
        trade_wallet = trade_details["wallet"]["address"]
        trade_token_out = trade_details["token_out"]["token"]

        with lock:  # Ensure thread safety
            # Start tracking if price is above TRACKING_PRICE
            if trade_price > TRACKING_PRICE:
                if ((trade_token_out not in buy_dict) and (trade_token_out not in sell_dict)):
                    buy_dict[trade_token_out] = {"wallets": [trade_wallet], "count": 1}
                
                if( trade_token_out in buy_dict):
                    if (trade_wallet not in buy_dict[trade_token_out]["wallets"]):
                        buy_dict[trade_token_out]["wallets"].append(trade_wallet)
                        buy_dict[trade_token_out]["count"] += 1

                    if (buy_dict[trade_token_out]["count"] > min_wallet_number):
                        buy_price = trade_price
                        buy_dict[trade_token_out]["buyPrice"] = buy_price
                        coin = buy_dict.pop(trade_token_out)
                        sell_dict[trade_token_out] = coin
                        buy_trade += 1
                        
                        print(f"#Bought:{buy_trade}#Profit:{profit_trade}#Loss:{loss_trade}#  BUY  - Condition met   : Trade_price [{trade_price:.10f}], Buy_price [{buy_price:.10f}], Total_price profit/loss [{TOTAL_PROFIT_PRICE:.10f}], (Address: {trade_token_out})"
                            )

                elif (trade_token_out in sell_dict):
                    buy_price = sell_dict[trade_token_out]["buyPrice"]

                    if trade_price >= buy_price * (1 + PROFIT_PERCENT / 100.0):
                        profit_trade += 1
                        # TOTAL_PROFIT_PERCENT += (((trade_price / buy_price) - 1) * 100)
                        TOTAL_PROFIT_PRICE += ((trade_price - buy_price) * (10.0 / buy_price))
                        # print(f"TOTAL_PROFIT_PRICE {TOTAL_PROFIT_PRICE}");
                        print(f"#Bought:{buy_trade}#Profit:{profit_trade}#Loss:{loss_trade}#  SELL - Target Achieved : Trade_price [{trade_price:.10f}], Buy_price [{buy_price:.10f}], Total_price profit/loss [{TOTAL_PROFIT_PRICE:.10f}], (Address: {trade_token_out})"
                            )  
                        sell_dict.pop(trade_token_out, None)

                    elif trade_price <= buy_price * (1 - STOP_LOSS_PERCENT / 100.0):
                        loss_trade += 1
                        # TOTAL_LOSS_PERCENT += ((1 - (trade_price / buy_price)) * 100)
                        TOTAL_PROFIT_PRICE += ((trade_price - buy_price) * (10.0 / buy_price))
                        # print(f"TOTAL_PROFIT_PRICE {TOTAL_PROFIT_PRICE}");
                        print(f"#Bought:{buy_trade}#Profit:{profit_trade}#Loss:{loss_trade}#  SELL - Stop loss       : Trade_price [{trade_price:.10f}], Buy_price [{buy_price:.10f}], Total_price profit/loss [{TOTAL_PROFIT_PRICE:.10f}], (Address: {trade_token_out})"
                        )
                        sell_dict.pop(trade_token_out, None)

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

def on_close(ws, close_status_code, close_msg):
    print("WebSocket closed")

def on_open(ws):
    print("WebSocket connection opened")
    ws.send(json.dumps(SUBSCRIBE_PUMP_FUN_TRADE))
    print(f"Subscription message sent: {SUBSCRIBE_PUMP_FUN_TRADE}")

Managing the WebSocket Connection

A small function manages the WebSocket connection and runs it in a thread:

def run_websocket(url):
    ws = websocket.WebSocketApp(
        url,
        on_message=lambda ws, msg: handle_transaction_message(ws, msg),
        on_error=on_error,
        on_close=on_close
    )
    ws.on_open = on_open
    ws.run_forever()

# Start WebSocket in a separate thread
thread_transaction = threading.Thread(target=run_websocket, args=(URL,))
thread_transaction.start()
thread_transaction.join()

Running the Bot on Replit

  • Tap the "Open on Replit" button below to get started.
    • You'll arrive at the Replit dashboard with the project titled "Trading Bot with NolimitNodes."
    • Log in to your Replit account, or create one if you're new to Replit.
    • Click the "Remix this app" button below the project name to create your own copy.
    • Adjust the project settings to suit your preferences.
    • The editor loads with the main.py file.
    • Hit the Run button and follow the on-screen instructions provided by the bot.
    • Check the right panel to find the file where the code resides.
    • Replace "YOUR_API_KEY" with your actual API key to enable functionality.

That's it. Let it run for a few minutes and watch the buy and sell lines accumulate in the console.

You've Built a Popular Coin Trading Bot

The bot now monitors live market prices, tracks which tokens are drawing real wallet activity, and executes buy and sell decisions against your thresholds. Specifically, it can:

  • Spot tokens with genuine buying interest before entering.
  • Exit winners at a defined profit percentage.
  • Protect positions with a stop-loss.

Tune min_wallet_number and the percentage thresholds against live data; the defaults are just a starting point.

Did You Miss Series 3?

Series 3 covers the drawdown bot, which tracks pullbacks and buys recoveries off the trough. Catch up here: Mastering Pump.Fun Drawdown with WebSocket: Series 3.

Need Help?

Got questions or need advice on crypto trading? Reach out anytime.
Email: robert.king@nolimitnodes.com
(Emails are checked daily.)

Happy trading.

#solana#pumpfun#websocket#trading#tutorial
N
NoLimitNodes Team
Community & Tutorials

Tutorials, market notes, and product walkthroughs from across the NoLimitNodes team.

On this page
  • 01What's Being Built Today?
↑ back to top
///Read next
GuidesJun 19, 2026

Yellowstone gRPC in Python (2026): Setup, 5 Core Patterns & a Real-Time PumpFun Detector

A complete Python guide to Yellowstone gRPC: proto generation, a reusable auth helper, five working patterns from wallet watcher to memcmp filter, a full PumpFun token-launch detector, and production reconnect with exponential backoff.

#yellowstone#grpc#python
18 min read
GuidesMay 19, 2026

Yellowstone gRPC vs WebSockets: choosing a real-time Solana data pipeline

Both transports stream the same chain, but they come from different places inside the validator and fail in different ways. A field guide to choosing and operating the right pipeline for your workload.

#yellowstone#grpc#websocket
16 min read
← Older
Crypto Domination: Create a Trading Bot for Pump.fun That Knows When to Buy and Sell
Newer →
Solana RPC Node Setup & Best Practices: A Complete Guide with NoLimitNodes
Run it yourself

Every benchmark in this blog runs against our public endpoints.

Spin up an RPC, WebSocket, or gRPC endpoint in under a minute. Flat pricing, no request caps. Reproduce the numbers for your own workload.

See pricing

Ready to get started?

Get your free API key and start building in under 30 seconds.

Talk to Sales
NoLimitNodes

Solana RPC infrastructure built for performance and scale.

RPC Access
  • HTTP RPC
  • WebSocket
  • gRPC
Infrastructure
  • Compute Platform
  • VPS
  • VDS
  • Bare Metal
  • Geyser Plugin Hosting
Enhanced Streams
  • PumpFun
  • PumpSwap
  • Raydium
  • Orca
  • Meteora
  • System Events
  • Browse All →
Program Streams
  • PumpFun
  • PumpSwap
  • Raydium CLMM
  • Orca Whirlpool
  • Meteora DLMM
  • Jupiter Swap
  • Jupiter Perps
  • Kamino Lending
  • Browse All 37 →
Trading
  • EZWallet
Analytics
  • Historical Datasets
  • Historical Raw Blocks
Company
  • About
Resources
  • Pricing
  • Custom Development
  • Documentation
  • Blog
  • Support
  • Contact Sales
Compare
  • Yellowstone gRPC vs LaserStream
  • Triton vs Helius
  • Raydium API vs Helius
  • PumpSwap API vs Bitquery
  • QuickNode Streams vs NLN
  • All comparisons →
Legal
  • Terms & Conditions
  • Privacy Policy
© 2026 CLR3 Inc., operating as NoLimitNodes. Registered in Ontario, Canada. All rights reserved.solana mainnet