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…
On this page +
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:
- buy_dict: Tracks tokens the bot has purchased.
- sell_dict: Keeps a record of tokens sold.
- 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_PRICEand track their associated wallets. - Trigger Buys: If the number of wallets exceeds the threshold (
min_wallet_number), initiate a buy and move the token tosell_dict. - Monitor Sell Opportunities: Tokens in
sell_dictare sold when they hit either thePROFIT_PERCENTtarget or fall below theSTOP_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.
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.