Build a Binance Listing Sniper Bot in Python
Last updated
A listing sniper bot does one thing well: it reacts to a new-listing announcement faster than a human ever could, then places an order before the crowd catches up. This tutorial walks through a complete, consumer-side sniper in Python — you subscribe to a real-time announcement feed, parse the ticker the instant it arrives, and fire a buy order on a trading venue such as Binance Futures. No page-scraping, no refresh loops. Just a socket that pushes you the event the moment it happens.
How a listing sniper bot works
Every sniper bot has the same three stages, and the design question is only how fast each one runs:
- Detect — learn that an exchange just announced a listing, and extract the ticker symbol.
- Decide — filter the event: is it a spot listing, a futures listing, a delisting? On which exchange? Does it match your strategy?
- Execute — place the order on a venue where the token already trades (or lists moments later), sized and risk-managed.
The naive way to build stage one is to have your bot poll the exchange's announcement page every few seconds and diff the HTML. That approach is slow, brittle, and rate-limited — and by the time your poller notices the change, faster traders have already moved the price. As we explain in how to detect new crypto listings, polling and social-media relays add seconds of delay you cannot afford.
The shortcut is to skip detection entirely and consume a feed that has already done it. That is what CryptoListing.ws provides: a WebSocket that pushes a structured JSON message — ticker and listing type pre-extracted — the moment an announcement is published on Binance, Upbit, or Bithumb. Your sniper connects once and waits. When a listing drops, the event arrives with no refresh loop on your side, so all of your latency budget goes into stage three: execution.
Prerequisites
- An API key. Grab a free SpeedTrial key to build and test the pipeline end to end. SpeedTrial delivers every event with accurate publisher, listing type and timestamps at zero added delay — enough to wire up and validate your bot. It redacts the ticker on tradeable events (you get
ticker = ""); upgrade to a paid tier when you want the symbol delivered for live trading. - Python 3.10+ and the
websocketslibrary, version 14 or newer. - Venue API credentials for wherever you place the order (Binance Futures in this example). We use ccxt so the same code targets Bybit or Bitget with a one-line change.
pip install "websockets>=14" ccxt
Step 1 — Connect to the announcement feed
Authentication is a single X-API-Key header on the WebSocket handshake. With websockets v14+ you pass it via additional_headers:
# websockets>=14 import asyncio, json, websockets API_KEY = "YOUR_KEY" FEED_URL = "wss://cryptolisting.ws?cex=binance" # filter to Binance only async def run(): async with websockets.connect( FEED_URL, additional_headers={"X-API-Key": API_KEY}, ) as ws: async for raw in ws: msg = json.loads(raw) await handle(msg) asyncio.run(run())
The ?cex=binance query parameter narrows the stream to Binance announcements. Drop it to receive Binance, Upbit and Bithumb, or set ?cex=binance,upbit for a subset. Korea-based bots trading Upbit can point at wss://kr.cryptolisting.ws instead — that endpoint runs in AWS Seoul and dispatches Upbit events only. The library answers the server's keep-alive PING frames automatically, so you do not manage heartbeats yourself.
Step 2 — Understand the message you receive
Every event is a binary WebSocket frame carrying UTF-8 JSON. A real Binance spot listing looks like this:
{
"type": "announcement",
"title": "Binance Will List TOKEN (TOKEN)",
"ticker": "TOKEN",
"publisher": "binance",
"listingType": "spot_listing",
"detectedTimestampUs": 1710345000005000,
"dispatchTimestampUs": 1710345000006000,
"abnormalDetectionLatency": false
}
Three things every robust handler must do:
- Branch on
type. You will also receive awelcomemessage on connect and aheartbeatevery 30 s. Only act ontype == "announcement". - Split the ticker. A single announcement can list several tokens, delivered comma-separated (
"ABC,DEF,GHI"). Always dodata["ticker"].split(","). - Ignore unknown fields. New fields may be added at any time. Never use strict schema validation that rejects extras.
The listingType tells you what happened. The values you will care about most for a long-biased sniper are spot_listing and futures_listing; a delisting bot watches spot_delisting and futures_delisting. The full enumeration lives in the message reference.
ticker is empty for tradeable events. You still receive the event, the publisher, the listing type and the microsecond timestamps — everything you need to build and time your pipeline. To trade on the symbol itself, upgrade to a paid tier (Basic, FreeDelayed, or Premium) that delivers the full ticker. Build on SpeedTrial, then flip one key.
Step 3 — Decide: filter for actionable events
Turn the raw message into a decision. Keep this fast and boring — no network calls, no heavy logic inside the handler:
ACTIONABLE = {"spot_listing", "futures_listing"}
async def handle(msg):
if msg.get("type") != "announcement":
return
if msg["listingType"] not in ACTIONABLE:
return
tickers = [t for t in msg["ticker"].split(",") if t]
if not tickers:
return # SpeedTrial redacts the ticker — nothing to trade on
for ticker in tickers:
await place_order(ticker, msg)
Step 4 — Execute: place the buy order
Now the sniper acts. This example fires a market buy on Binance USDⓈ-M Futures via ccxt. The key idea: the trading symbol is derived mechanically from the announced ticker, and the order is submitted the instant the event lands.
import ccxt exchange = ccxt.binanceusdm({ "apiKey": "VENUE_API_KEY", "secret": "VENUE_API_SECRET", }) QUOTE_USDT = 50 # notional per snipe async def place_order(ticker, msg): symbol = f"{ticker}/USDT:USDT" # USDT-margined perpetual try: # futures market-buy amount is in base units — convert notional at the live price price = exchange.fetch_ticker(symbol)["last"] order = exchange.create_market_buy_order(symbol, QUOTE_USDT / price) print(f"SNIPED {ticker}: order {order['id']}") except ccxt.BaseError as e: print(f"order failed for {ticker}: {e}")
Two production caveats the tutorial keeps deliberately simple. First, the perpetual for a freshly announced token may not exist yet on your venue at the exact instant of the spot announcement — real sniper bots pre-resolve the symbol, handle the "market not found" case, and retry with backoff as the market opens. Second, exchanges enforce lot-size and price-precision rules; call exchange.load_markets() at startup and round your amount to the symbol's precision. Treat the snippet as the skeleton, not a turnkey trading system.
Step 5 — Measure your latency
Every announcement carries two microsecond timestamps so you can measure exactly where your time goes. Log this on every event while you tune:
import time def log_latency(msg): now_us = int(time.time() * 1_000_000) network_ms = (now_us - msg["dispatchTimestampUs"]) / 1000 total_ms = (now_us - msg["detectedTimestampUs"]) / 1000 print(f"network={network_ms:.2f}ms total={total_ms:.2f}ms")
network_ms is the wire time from our dispatch to your process; total_ms is from detection to your code. Watch these numbers and you will quickly see that the dominant remaining cost is your execution path — the venue round-trip — not detection. That is the whole point of consuming a feed instead of polling: you spend zero milliseconds discovering the listing, so every optimization you make is on the part you actually control.
Why your sniper does not need to poll
A do-it-yourself sniper spends most of its engineering effort fighting stage one — scraping announcement pages, dodging rate limits, and still arriving late because a REST poll every 30–60 seconds simply cannot see an event the instant it publishes. By subscribing to a push feed, your bot inverts that: it sleeps until the socket wakes it, and the event arrives already parsed. There is no poll interval to lose the race in, because there is no poll at all on your side. Your competitive edge becomes execution quality and colocation, which is where a sniper's edge should live.
Start on the free SpeedTrial tier to build and validate the full loop against live events, keep the API documentation open as you go, and upgrade when you are ready to trade on the ticker. For exchange-specific behavior and the events you can snipe, see the Binance listing alert reference.
This article is an engineering tutorial for informational purposes only and is not financial or trading advice. Automated trading carries substantial risk. CryptoListing.ws is a technical data feed service — see Legal.
Related
- How to Detect New Crypto Listings in Real-Time — every detection method compared, and why WebSocket wins.
- Why Binance Listing Announcements Move Markets — the price mechanics a sniper is trading against.
- Binance Listing Alerts — the full list of Binance event types the feed delivers.
Build your sniper on a free key
Real-time listing announcements from Binance, Upbit, and Bithumb over WebSocket. See pricing & tiers — free SpeedTrial key to prototype, paid tiers deliver the full ticker for live trading.
Get started on Telegram