NoLimitNodes
PricingDocsBlogAbout
SupportContact
Log in
Blog/Guides

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…

N
NoLimitNodes Team
Community & Tutorials
Jan 27, 2025updated Jun 8, 20266 min read
On this page +
  • 01What We're Building
  • 02What Is Drawdown Trading?
  • 03How a Drawdown Trading Bot Works
  • 04Building the Bot
  • 05Finally

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:

  1. Track Price Peaks: The bot monitors the market in real time and records the peak price of each asset.
  2. Identify Drawdowns: When the price drops by a defined percentage from the peak, the bot marks it as a drawdown.
  3. Trigger a Pullback Buy: If the price recovers from the trough by a set percentage, the bot triggers a buy.
  4. 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_PERCENT and STOP_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 exceeds DRAW_DOWN_TRACE_PRICE and it's not in draw_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 exceeds DRAW_DOWN_PERCENT , the trough price is recorded.
  • Trigger Pullback Buys:
    If the price recovers by DRAW_DOWN_PULLBACK_PERCENT from the trough, the bot triggers a buy and moves the token to sell_dict.
  • Monitor for Profit or Stop Loss:
    Tokens in sell_dict are sold when they hit PROFIT_PERCENT or fall below STOP_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.

  1. You'll land on the Replit dashboard with the project name "Trading Bot with NolimitNodes."
  2. Log in to your Replit account (or create one if you don't have one).
  3. Click the "Remix this app" button just below the project name.
  4. Choose your preferences for the project.
  5. The editor opens with the main.py file.
  6. Hit the Run button to follow the user instructions.
  7. Check the right corner to locate the file name containing the code.
  8. 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.

///Related resources
Enhanced Streams

Decoded Solana events for bots, dashboards, and analytics.

PumpFun data

Launches, trades, graduations, and creator-wallet signals.

Solana RPC nodes

Private Solana RPC endpoints for builders and trading systems.

Yellowstone gRPC nodes

Low-latency real-time Solana streams over gRPC.

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

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

On this page
  • 01What We're Building
  • 02What Is Drawdown Trading?
  • 03How a Drawdown Trading Bot Works
  • 04Building the Bot
  • 05Finally
↑ 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
Mastering Pump.fun with WebSocket: A Tutorial on Trailing Stop-Loss Strategies
Newer →
Crypto Domination: Create a Trading Bot for Pump.fun That Knows When to Buy and Sell
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