In high-frequency trading, such as sniping new tokens on Solana, execution speed and high-quality, ultra-low latency data are two non-negotiable prerequisites that can make or break your strategy.
Beyond that, profitability comes down to identifying the right token and timing the exit.
In this article, we will build a paper trading Solana sniper bot in Python that focuses on accurate data and fast execution using CoinGecko’s Websocket API.

What is a Solana Sniper Bot?
A Solana sniper bot is essentially an automated trading system that scans for newly launched tokens right after liquidity is added to their pools, then swiftly executes buys to capitalize on early price surges. These bots thrive in the memecoin and DeFi ecosystems, where volatility creates windows of opportunity for short-term profits.
Disclaimer: This guide is for educational purposes only and does not constitute financial advice. Cryptocurrency trading involves significant risks. Always do your own research before investing or trading.
What Is the Architecture of a Solana Sniper Bot?
The architecture of a Solana sniper bot consists of three main parts:
- Discovery: This involves scanning for newly created liquidity pools on the Solana network to spot fresh token launches as soon as they happen.
- Decision: The bot evaluates the discovered pools using predefined filters to determine if they exhibit characteristics that could lead to profitable snipes, such as sufficient liquidity or early momentum.
- Execution: Once a promising token is identified, the bot triggers a buy (simulated in our paper trading setup) and monitors for exit conditions to sell at a profit (take-profit) or cut losses (stop-loss).
This architecture forms a streamlined loop that ensures the bot acts swiftly and intelligently in the volatile Solana memecoin and DeFi ecosystem. The below diagram visualizes the sniper bot’s operational logic in a simple flow:

Prerequisites:
- CoinGecko API: A paid API subscription (Analyst plan and above) is required to access the WebSocket API for sub-second data streams. However, a free Demo plan is sufficient to access the REST API endpoints used in this guide. If you don't have one, read this guide on how to get started with CoinGecko API.
- Python 3.11+ environment
- CoinGecko API Key: A paid API subscription (Analyst plan and above) is required to access the WebSocket API for sub-second data streams. However, a free Demo plan is sufficient to access the REST API endpoints used in this guide. If you don't have one, read this guide on how to get your free Demo API key.
- Required libraries: requests, python-dotenv, Websockets, dataclass-wizard
Step 1: How to Find New Solana Token Launches
To find new Token Launches on Solana, we’ll use CoinGecko’s API to retrieve the most recent liquidity pools by making a request to the New Pools by Network endpoint. This allows us to query the latest pools using the provided blockchain network, and is a crucial step for our Discovery stage.
Start by creating a CoinGecko wrapper under services/coingecko.py. We’ll define a dedicated class responsible for making authenticated requests to the CoinGecko API, along with a get_new_pools() method to fetch newly created liquidity pools.
The response will resemble the following structure:
To make it easier to work with the response data and safely access its properties, including nested objects, we’re going to model it using Python’s @dataclass decorator.
Under models/pool.py, define a Pools dataclass, which contains a list of “pool” objects.
The Pools class inherits from the JSONWizard base class provided by the dataclass-wizard library. This adds automatic JSON serialisation and deserialisation, allowing a raw JSON response to be converted directly into typed Python objects without manually mapping each field.
We can then modify get_new_pools() to return a mapped object. Note that this API endpoint is paginated, meaning that by default it only returns a maximum of 20 results per page. For a larger dataset, we’ll need to call the API multiple times and consolidate the paginated responses into a single Pools object:
This implementation allows us to fetch multiple pages in a single function execution by using the num_pages argument and iterating through multiple pages before returning the final result.
Step 2: How to Filter Profitable Tokens to Snipe
To identify potentially profitable tokens to snipe, we’ll build a function that parses the pool data from the previous steps and returns a list of pools that match our buying criteria.
This acts as the decision-making layer. Any pools returned here are treated as buy signals, so the filters you choose should match your risk tolerance and desired approach. Under the same CoinGecko class, define a new function called filter_pools():
This function takes our original Pools response and applies filtering based on the following criteria:
Pool Age
Defined via the min_pool_age_minutes and max_pool_age_minutes arguments.
Very young pools may still be under the radar, giving you the chance to enter before broader awareness or social attention spreads. This can be important in sniping strategies where being early matters.
Older pools have been around longer and are more likely to have established trading patterns and initial buy/sell activity. By setting minimum and maximum age thresholds, you control whether you want to target extremely new pools for early-entry opportunities or slightly older pools that have started to gather activity and initial market interest.
Liquidity Check
Defined through the min_liquidity_usd argument, this ensures you avoid pools with very low liquidity.
Low-liquidity pools are risky because even small trades can drastically move the price, and it may be hard to sell your tokens later. By setting a minimum liquidity threshold, you focus only on pools that are sufficiently large enough to trade, mitigating extreme slippage and the risk of being unable to exit a position.
Volume
This is an optional check using the min_volume argument. It filters out pools that haven’t experienced much trading activity yet. A higher initial volume indicates early buy pressure and momentum, suggesting that the token is attracting interest.
Remember to experiment with the pool age, liquidity, and volume values to find a combination that fits your strategy and risk tolerance. You can do this risk-free by simulating trades locally with paper-trading which we will cover next.
Step 3: How to Build the Sniping Logic and Trigger
To build the sniping logic and trigger, start by creating a simple trade service that places trades according to your desired parameters. This represents the execution layer of the application.
But first, we need to define what a trade looks like. Under models/trade.py create a new Trade dataclass:
A trade represents any action taken by the trading bot, such as opening or closing a position. Alongside trades, we also need a clear definition of what an Order is.
Unlike a Trade, an Order represents an asset that is currently held in the portfolio and reflects an active position rather than an action. We can define an Order under models/order.py as follows:
Since both objects share many similar fields, an Order can inherit all the properties of a Trade and extend it by adding two additional fields: tp and sl, representing take-profit and stop-loss levels as percentage values.
The main difference, however, is that Orders are temporary. Once a position is closed, the corresponding order should be removed from the data store.
With that in place, start by creating a TradeService class under services/trade_service.py and define the execution logic:
Upon successfully placing a paper trade, you’ll see a log in the console similar to the following:

The function also returns an Order object for the newly opened position:
At this stage, the trading bot is technically functional, but it’s missing a data storage and an exit (sell) logic component.
Step 4: How to Store Trade and Order Data
Storing the trades and orders placed by the bot is a crucial prerequisite for tracking performance and for managing open positions, including closing them via take-profit or stop-loss conditions.
Under data, create two new JSON files called orders.json and trades.json. Inside each file, define an empty array ([]), so they are syntactically correct.
In the same directory, create a new file called data_manager.py, which will be responsible for reading from and writing to the JSON files.
Specifically, the DataManager should support the following operations:
- Get all orders or trades
- Get an order or trade by ID
- Save a new order or trade
- Delete an order or trade by ID
- Update an existing order or trade
To save your trades and orders, insert the following two lines immediately before the return statement within the TradeService.buy() method:
Step 5: How to Build Real-Time Price Monitoring for Trade Exits
To improve our chances of success and build a robust exit strategy, we’re going to subscribe to CoinGecko’s OnchainSimpleTokenPrice WebSocket channel. This gives us access to real-time, sub-second price updates, allowing the bot to react instantly and close trades as quickly as possible when the market meets our predefined exit conditions.
Under services/trade_service.py, define a new sell method:
This will calculate the trade’s profit and loss (PnL). Next, log a new trade entry with the realised profit or loss, and remove the existing order from the portfolio since the position has been closed.
Now, let’s extend the CoinGecko class by adding a new method to stream real-time price data.
Since our websocket is async, we will define an async function that monitors prices, inside main.py
The method stops immediately if there are no open orders, which prevents unnecessarily opening a WebSocket connection when there are no trades.
Price updates are handled asynchronously and streamed in real time, meaning the bot reacts to incoming data rather than polling on an interval. After a position is sold, the orders are reloaded from storage to prevent duplicate sells or stale state.
All that’s left to do is add a method to handle the buy logic, and define our main entry-point for our Solana sniping bot:
After running the bot, you should see output that includes real-time price updates and your floating (unrealized) Profit and Loss (PnL), reflecting current market movements.

Further Enhancements
Once your logic is profitable in simulation, consider these enhancements for production.
Wallet Integration
To place real trades, you'll need to connect the bot to a Solana wallet and signing layer. This can be done using libraries like solana.py, Solders, or by integrating directly with a Solana DEX trading API.
Slippage Protection
In fast-moving markets, especially memecoins, prices can change dramatically between the time a trade is submitted and when it's executed. Adding slippage controls helps prevent trades from executing at significantly worse prices than expected, which is critical when volatility is high.
Integrate Token Launchpad Data
If you're sniping tokens from memecoin launchpads such as Pump.fun, Bonk.fun, or Four.meme, you can further improve your edge by integrating launchpad-specific data. Tracking bonding curve progress or graduation events can help you time entries and exits more effectively.
Integrate to Other Blockchains
This setup is chain-agnostic. Since pricing and pool data are sourced via the CoinGecko API, extending the bot to other blockchains is largely plug-and-play. In most cases, the only required change is adjusting the network parameter on supported endpoints, making it easy to deploy the same logic across ecosystems like Ethereum, BNB, and Base.
Conclusion
In this guide, we explored how to build a fully data-driven Solana sniper bot. It finds pools based on predefined criteria, filters them based on liquidity, age, and volume, and executes trades with real-time monitoring for take-profit and stop-loss exits by leveraging CoinGecko’s WebSocket API.
For a functional implementation of this Solana sniper bot, visit and clone this GitHub repo.
High-frequency trading requires timely data. For higher rate limits and access to sub-second real-time market data via WebSocket connections, consider subscribing to a paid API plan.
Disclaimer: This guide is for educational purposes only and does not constitute financial advice. Always trade responsibly and understand the risks involved.
Subscribe to the CoinGecko Daily Newsletter!

Ethereum Mainnet
Base Mainnet
BNB Smart Chain
Arbitrum
Avalanche
Fantom
Flare
Gnosis
Linea
Optimism
Polygon
Polygon zkEVM
Scroll
Stellar
Story
Syscoin
Telos
X Layer
Xai