Pump.fun WebSocket Tutorial: Master Drawdown Strategies for Maximizing Pullback Gains
Part three of the Pump.Fun trading bot series covers drawdown trading: the bot tracks each token's peak price over WebSocket, waits for a defined percentage drop, then buys the recovery off the trough and exits on a…
On this page +
Part three of the Pump.Fun trading bot series covers drawdown trading: the bot tracks each token's peak price over WebSocket, waits for a defined percentage drop, then buys the recovery off the trough and exits on a profit target or stop-loss.
If you're new or missed the fundamentals, like setting up WebSocket connections or registering an account, start with Mastering Pump.Fun Trading with WebSocket: Series 1.
What We're Building
This is a drawdown trading bot for the Pump.fun platform. It uses WebSocket streams to monitor live market transactions and token prices in real time, tracks peak prices, detects drawdowns, and calculates pullback percentages to find entry points. Once in a position, automated profit-taking and stop-loss rules decide when to sell. The point is to react to price structure, peak, trough, recovery, without you watching the tape manually.
What Is Drawdown Trading?
Drawdown trading is a strategy built around price declines. A drawdown is the fall in an asset's price from its peak to a trough, usually measured as a percentage. Traders use it to find buying opportunities during dips and selling opportunities once the price recovers.
For example, if a cryptocurrency or stock falls 10% from its peak and then starts recovering, a trader might buy near the trough and sell once it rises by a specific percentage (the profit target). Drawdown trading also typically includes stop-loss levels to cap losses if the price keeps falling below a threshold.
How a Drawdown Trading Bot Works
A drawdown trading bot automates the tracking, detection, and execution. The cycle looks like this:
- Track Price Peaks: The bot monitors the market in real time and records the peak price of each asset.
- Identify Drawdowns: When the price drops by a defined percentage from the peak, the bot marks it as a drawdown.
- Trigger a Pullback Buy: If the price recovers from the trough by a set percentage, the bot triggers a buy.
- Sell on Profit or Stop Loss: After buying, the bot tracks the price and either sells at the profit percentage or cuts losses at the stop-loss.
Example:
- Peak Price Tracking:
The price of Token A rises to $100 and is recorded as the peak. - Drawdown Detected:
The price drops to $90 (10% drop). The bot identifies this as a drawdown and sets $90 as the trough price. - Pullback Buy Triggered:
The price recovers to $94.50 (5% pullback). The bot buys Token A at $94.50. - Profit or Stop Loss:If the price rises to $99.23 (5% profit), the bot sells for a profit.If the price falls to $92.61 (2% loss), the bot sells to minimize losses.
Building the Bot
Requirements
Before starting, make sure you have:
- Python (Version 3.x or higher is recommended).
- A registered account on nolimitnodes.com to obtain your free API key.
Open your favorite IDE and create a new script named drawdown_bot_pumpfun.py.
Start with the imports:
import websocket
import json
import threading
Universal Variables
The bot's trading parameters live in a handful of constants:
DRAW_DOWN_TRACE_PRICE: Minimum price above which tokens are monitored.DRAW_DOWN_PERCENT: Percentage drop from the peak price that defines a drawdown.DRAW_DOWN_PULLBACK_PERCENT: Recovery percentage from the trough that triggers a buy.PROFIT_PERCENTandSTOP_LOSS_PERCENT: Conditions for selling after a buy.
Data Types
draw_down_dict: Stores tokens being tracked for drawdown.sell_dict: Tracks tokens that have been bought and are being monitored for selling.
# Define constants
DRAW_DOWN_TRACK_PRICE = 0.0000001000
DRAW_DOWN_PERCENT = 10.0 / 100.0
DRAW_DOWN_PULLBACK_PERCENT = 5.0 / 100.0
PROFIT_PERCENT = 10.0 / 100.0
STOP_LOSS_PERCENT = 5.0 / 100.0
# Data storage
draw_down_dict = {}
sell_dict = {}
buy_trade = profit_trade = loss_trade = 0
URL = "wss://api.nolimitnodes.com/pump-fun?api_key=YOUR_API_KEY"
Next, the subscription request that asks the server for the trade stream:
# Subscription messages
SUBSCRIBE_PUMP_FUN_TRADE = {
"method": "pumpFunTradeSubscribe",
"params": {"referenceId": "hello", "coinAddress": "all"}
}
Now the core of the bot: a set of small handlers, each owning one step of the strategy.
Code Breakdown and Logic:
Every trade event runs through this sequence:
- Track Tokens with Drawdown Potential:
If a token's price exceedsDRAW_DOWN_TRACE_PRICEand it's not indraw_down_dict, the bot starts monitoring it. - Update Peak Prices:
If the price rises further, the token's peak price is updated. - Identify Drawdowns:
If the price falls below the peak, the bot calculates the drawdown percentage. If it exceedsDRAW_DOWN_PERCENT, the trough price is recorded. - Trigger Pullback Buys:
If the price recovers byDRAW_DOWN_PULLBACK_PERCENTfrom the trough, the bot triggers a buy and moves the token tosell_dict. - Monitor for Profit or Stop Loss:
Tokens insell_dictare sold when they hitPROFIT_PERCENTor fall belowSTOP_LOSS_PERCENT.
# Helper Functions
def handle_new_token(trade_token_out, trade_price):
if trade_token_out not in draw_down_dict and trade_price >= DRAW_DOWN_TRACK_PRICE:
draw_down_dict[trade_token_out] = {
"DrawDownPeakPrice": trade_price,
"DrawDownBottomPrice": None,
"BuyPrice": None,
}
def handle_peak_price_update(trade_token_out, trade_price):
if trade_token_out in draw_down_dict:
current_data = draw_down_dict[trade_token_out]
if trade_price > current_data["DrawDownPeakPrice"] and current_data["DrawDownBottomPrice"] is None:
current_data["DrawDownPeakPrice"] = trade_price
def handle_price_fall(trade_token_out, trade_price):
if trade_token_out in draw_down_dict:
current_data = draw_down_dict[trade_token_out]
peak_price = current_data["DrawDownPeakPrice"]
if trade_price < peak_price:
fall_percentage = (peak_price - trade_price) / peak_price
if fall_percentage >= DRAW_DOWN_PERCENT:
bottom_trade_price = current_data.get("DrawDownBottomPrice")
if bottom_trade_price is None or bottom_trade_price > trade_price:
current_data["DrawDownBottomPrice"] = trade_price
def handle_pullback_and_buy(trade_token_out, trade_price):
global buy_trade, sell_dict
if trade_token_out in draw_down_dict:
current_data = draw_down_dict[trade_token_out]
bottom_price = current_data["DrawDownBottomPrice"]
if bottom_price is not None and trade_price > bottom_price:
pullback_percentage = (trade_price - bottom_price) / bottom_price
if pullback_percentage >= DRAW_DOWN_PULLBACK_PERCENT:
current_data["BuyPrice"] = trade_price
sell_dict[trade_token_out] = draw_down_dict.pop(trade_token_out)
buy_trade += 1
print(f"#Bought:{buy_trade}#Profit:{profit_trade}#Loss:{loss_trade}# BUY - Condition met: Trade_price [{trade_price:.10f}], Peak_price [{current_data['DrawDownPeakPrice']:.10f}], Bottom_price [{bottom_price:.10f}], (Address: {trade_token_out})")
def handle_sell_conditions(trade_token_out, trade_price):
global profit_trade, loss_trade, sell_dict
if trade_token_out in sell_dict:
sell_data = sell_dict[trade_token_out]
buy_price = sell_data["BuyPrice"]
bottom_price = sell_data["DrawDownBottomPrice"]
peak_price = sell_data["DrawDownPeakPrice"]
profit_threshold = buy_price * (1 + PROFIT_PERCENT)
loss_threshold = buy_price * (1 - STOP_LOSS_PERCENT)
if trade_price >= profit_threshold:
profit_trade += 1
print(f"#Bought:{buy_trade}#Profit:{profit_trade}#Loss:{loss_trade}# SELL - Target Achieved: Trade_price [{trade_price:.10f}], Peak_price [{peak_price:.10f}], Buy_price [{buy_price:.10f}], Bottom_price [{bottom_price:.10f}], (Address: {trade_token_out})")
sell_dict.pop(trade_token_out)
elif trade_price <= loss_threshold:
loss_trade += 1
print(f"#Bought:{buy_trade}#Profit:{profit_trade}#Loss:{loss_trade}# SELL - Stop loss triggered: Trade_price [{trade_price:.10f}], Peak_price [{peak_price:.10f}], Buy_price [{buy_price:.10f}], Bottom_price [{bottom_price:.10f}], (Address: {trade_token_out})")
sell_dict.pop(trade_token_out)
# Main Function to handle transaction messages
def handle_transaction_message(ws, message):
try:
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_new_token(trade_token_out, trade_price)
handle_peak_price_update(trade_token_out, trade_price)
handle_price_fall(trade_token_out, trade_price)
handle_pullback_and_buy(trade_token_out, trade_price)
handle_sell_conditions(trade_token_out, trade_price)
except json.JSONDecodeError as e:
print(f"[ERROR] JSON Decode Error: {e}")
except Exception as e:
print(f"[ERROR] Exception occurred: {e}")
Finally, a function to manage the WebSocket connection, run in a thread:
# Function to create and run a WebSocket connection
def run_websocket():
ws = websocket.WebSocketApp(
URL,
on_message=handle_transaction_message,
on_error=on_error,
on_close=on_close
)
ws.on_open = on_open
ws.run_forever()
# Start WebSocket in a thread
thread_transaction = threading.Thread(target=run_websocket)
thread_transaction.start()
thread_transaction.join()
Want to run the bot? Here's how to get started on Replit:
Click the "Open on Replit" button in the editor below.
- You'll land on the Replit dashboard with the project name "Trading Bot with NolimitNodes."
- Log in to your Replit account (or create one if you don't have one).
- Click the "Remix this app" button just below the project name.
- Choose your preferences for the project.
- The editor opens with the
main.pyfile. - Hit the Run button to follow the user instructions.
- Check the right corner to locate the file name containing the code.
- Remember to use your own API key in place of "YOUR_API_KEY".
That's the bot set up and running.
Finally
You've built a trading bot that monitors live market prices, tracks pullbacks, and makes calculated buy and sell decisions. It finds entries off drawdowns, takes profit at your target, and protects the position with a stop-loss. The percentages in this script are starting values; adjust them to match how aggressive you want the entries to be.
Did you miss Series 2, the bot that tracks trailing prices? Click through to Mastering Pump.Fun Trading with WebSocket: Series 2 to catch up.
To explore more of the pump.fun APIs, visit https://nolimitnodes.com/blog/pump-fun-websocket-build-a-real-time-crypto-trading-bot-with-nolimitnodes-price-data/.
If you run into any issues or need general advice on anything crypto-related, feel free to reach out. You can email me at robert.king@nolimitnodes.com; I typically check my email once a day.
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.