Mastering Pump.fun with WebSocket: A Tutorial on Trailing Stop-Loss Strategies
Part two of the Pump.Fun trading bot series replaces the fixed take-profit exit with a trailing stop-loss: the bot tracks each coin's peak price in real time over WebSocket and sells when price falls a set distance…
On this page +

Part two of the Pump.Fun trading bot series replaces the fixed take-profit exit with a trailing stop-loss: the bot tracks each coin's peak price in real time over WebSocket and sells when price falls a set distance below that peak.
If you missed the basics, like the WebSocket connection setup or account registration, start with Mastering Pump.fun trade with WebSocket Series 1.
What We're Building
This bot monitors pump.fun over WebSocket, tracking new coins and market transactions continuously and recording the peak price of each position. It compares how far price has fallen from that peak against a predefined trailing price, and uses the comparison to decide when to sell. The goal is to ride a coin up while it keeps making new highs, then exit near the top instead of at an arbitrary fixed target. A stop-loss backstops the whole thing.
What Is the Trailing Price?
The trailing price is a fixed difference between the peak price (the highest price reached) and the trade price. It adjusts with the market, always maintaining a specific distance below the peak.
How the Trailing Price Is Used
On every transaction, the program calculates the difference between the peak price and the current trade price, then compares that difference to the set trailing price. If the difference exceeds the trailing price, the sell condition triggers.
Example:
Say the trade price moves like this: 10, 11, 12, 13 ... 15, 16, 17.5, 16, 15, and so on.
- The peak price is 17.5, and the trailing price is set at 2.
- As the trade price changes, the program continuously checks the difference between the peak price and the current trade price.
When the trade price drops to 15, the difference between the peak (17.5) and the current price (15) is:
17.5 - 15 = 2.5, which exceeds the set trailing price (2).
At this point the trailing stop triggers and a sell notification is sent.
Getting Set Up
Prerequisites
Make sure you have the following before starting:
- Python (Version 3.x+ recommended).
- A registered account on nolimitnodes.com to get your free API key.
Writing the Code
Open your favorite IDE (I use PyCharm) and create a new script called trading_bot_pumpfun.py.
Start with the libraries the bot depends on:
import websocket
import json
import threading
Next, define the constants that set the strategy's initial conditions:
buy_price: The price at which you decide to purchase a coin.takeProfit_price: The target price at which you plan to sell to lock in profits.trailing_amount: The threshold amount below the peak price. If the coin's price falls below this level, it triggers a sell condition to limit losses or secure profits.
# Constants
BUY_PRICE = 0.0000001000
TAKE_PROFIT_PRICE = 0.0000001500
TRAILING_AMT = 0.0000000200
STOP_LOSS_PRICE = 0.0000000800
buy_trade = 0
profit_trade = 0
loss_trade = 0
URL = "wss://api.nolimitnodes.com/pump-fun?api_key=YOUR_API_KEY"
Next, the subscription requests that tell the server which streams we want:
# Subscription messages
SUBSCRIBE_NEW_COIN = {
"method": "pumpFunCreateEventSubscribe",
"params": {"eventType": "coin", "referenceId": "hello"}
}
SUBSCRIBE_PUMP_FUN_TRADE = {
"method": "pumpFunTradeSubscribe",
"params": {"referenceId": "hello", "coinAddress": "all"}
}
Two dictionaries track the bot's open opportunities:
# Data storage
buy_dict = {}
sell_dict = {}
Now the part that matters: the handlers that implement the strategy.
Trading Logic:
- When a transaction has a coin in the Buylist:
- If the coin's price exceeds the
Buy_priceand is less than theTakeProfit_Price, send a buy notification. The coin moves from the Buylist to the Selllist, and the peak price is stored.
- If the coin's price exceeds the
- When a transaction has a coin in the Selllist:
- If the transaction price exceeds the stored peak price, the peak price is updated.
- If the coin's price exceeds the
TakeProfit_Priceor drops below the peak price bytrailing_amount, send a sell notification. The coin is then removed from the Selllist.
def handle_new_coin_message(ws, message):
global buy_dict
data = json.loads(message)
if data.get("method") == "createEventNotification":
coin_details = data["result"]
coin_mint = coin_details["mint"]
# print(f"coin added {coin_details['symbol']}")
if (coin_mint not in buy_dict):
buy_dict[coin_mint] = {
"name": coin_details["name"],
"symbol": coin_details["symbol"]
}
def handle_transaction_message(ws, message):
global buy_trade, profit_trade, loss_trade, buy_dict, sell_dict
data = json.loads(message)
if data.get("method") == "tradeEventNotification":
trade_details = data["result"]
trade_token_out = trade_details["token_out"]["token"]
trade_price = float(trade_details["price"]["sol"])
# Handle Buy Condition
if ((trade_token_out in buy_dict) and (trade_price >= BUY_PRICE) and (trade_price <TAKE_PROFIT_PRICE)):
coin = buy_dict.pop(trade_token_out)
coin["peak_price"] = trade_price
sell_dict[trade_token_out] = coin
buy_trade += 1
print(f"#Bought:{buy_trade}#Profit:{profit_trade}#Loss:{loss_trade}# BUY - Condition met : [{coin['symbol']}] at price [{trade_price:.10f}] (Address: {trade_token_out})")
# Handle Sell Conditions
elif (trade_token_out in sell_dict):
coin = sell_dict[trade_token_out]
if (trade_price > coin.get("peak_price", 0)):
coin["peak_price"] = trade_price
peak_price = coin["peak_price"]
peak_diff = (peak_price - trade_price)
if ((trade_price >= TAKE_PROFIT_PRICE) or (TRAILING_AMT < peak_diff)):
if trade_price >= BUY_PRICE:
profit_trade += 1
else:
loss_trade += 1
reason = "Target Achieved :" if (trade_price >= TAKE_PROFIT_PRICE) else "Trailing threshold Met:"
print(f"#Bought:{buy_trade}#Profit:{profit_trade}#Loss:{loss_trade}# SELL - {reason} [{coin['symbol']}] at price [{trade_price:.10f}] (Address: {trade_token_out})")
del sell_dict[trade_token_out]
elif (trade_price < STOP_LOSS_PRICE):
loss_trade += 1
print(f"#Bought:{buy_trade}#Profit:{profit_trade}#Loss:{loss_trade}# SELL - Stop loss triggered : [{coin['symbol']}] at price [{trade_price:.10f}] (Address: {trade_token_out})")
del sell_dict[trade_token_out]Finally, a function to manage the WebSocket connections, with threading so both streams run at the same time:
# Function to create and run a WebSocket connection
def run_websocket(url, on_message, subscription_message):
ws = websocket.WebSocketApp(
url,
on_message=on_message,
on_error=on_error,
on_close=on_close
)
ws.on_open = lambda ws: on_open(ws, subscription_message)
ws.run_forever()
# Threads for WebSocket connections
thread_new_coin = threading.Thread(target=run_websocket, args=(URL, handle_new_coin_message, SUBSCRIBE_NEW_COIN))
thread_transaction = threading.Thread(target=run_websocket, args=(URL, handle_transaction_message, SUBSCRIBE_PUMP_FUN_TRADE))
thread_new_coin.start()
thread_transaction.start()
thread_new_coin.join()
thread_transaction.join()
Ready to run it? Follow these steps to get started with Replit:
Click the "Open on Replit" button provided in the editor below.
- You'll be taken to the Replit dashboard with the project name "Trading Bot with NolimitNodes."
- Log in to Replit (or sign up if you're new).
- Hit the "Remix this app" button below the project name.
- Choose your preferred settings for the project.
- The editor opens with the
main.pyfile. - Click the Run button to follow the user instructions.
- Check the right corner to locate the file name containing the code.
- Remember to add your "YOUR_API_KEY", or nothing will connect.
That's the bot set up and running.
Rounding It Off
You now have a bot that monitors new coins, compares each one's peak price against a predefined trailing price, and trades accordingly: buying when entry conditions are met and selling when the take-profit, trailing stop, or stop-loss fires. In practice, the bot is:
- Collecting newly created coins
- Tracking peak prices and trailing distances to time exits
- Entering at your buy price and selling on take-profit or trailing-stop conditions
The trailing stop is the real improvement over part one. A fixed take-profit caps your upside on every winner; a trailing stop lets a strong move keep running and only exits once the move has clearly turned.
For more on the other pump.fun APIs, check out https://nolimitnodes.com/blog/pump-fun-websocket-build-a-real-time-crypto-trading-bot-with-nolimitnodes-price-data/
If you run into issues or need help with anything crypto-related, drop me an email at robert.king@nolimitnodes.com and I'll respond as soon as I can, usually within 24 hours.
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.