Build a Crypto Trading Bot with Python — Free API, No Exchange Account Needed
Learn how to build a cryptocurrency trading bot using Python and a free REST API that gives you real-time access to 229 perpetual futures markets — prices, orderbooks, OHLCV candles, and funding rates. No exchange API keys, no KYC, no signup.
1 Why Build a Crypto Trading Bot?
Crypto markets trade 24/7 across hundreds of exchanges. No human can monitor 229 markets simultaneously, but a bot can. Here's what a trading bot gives you:
- React to price movements in milliseconds — not minutes
- Scan all 229 perpetual futures for arbitrage, momentum, or mean-reversion signals
- Track funding rates across every market to find carry trade opportunities
- Backtest strategies on historical candle data before risking capital
- No emotions — execute your rules consistently, every time
Most tutorials require you to create exchange accounts, deal with KYC, generate API keys, and navigate complex rate limits. This tutorial uses a free, unified REST API that proxies Hyperliquid's market data — so you can start building in 30 seconds with just curl.
2 Bot Architecture & API Overview
Your bot needs three things: data (what's happening in the market), logic (when to act), and execution (placing orders). This tutorial focuses on data and logic. Here's the API:
| Endpoint | What It Returns | Use Case |
|---|---|---|
GET /api/prices | All 229 mid-prices in one call | Market scanner, portfolio tracker |
GET /api/price/:symbol | Single asset price | Quick price check, alerts |
GET /api/book/:symbol | L2 orderbook (bids + asks) | Spread analysis, liquidity detection |
GET /api/candles/:symbol | OHLCV candles (1m to 1M) | Technical analysis, backtesting |
GET /api/funding/:symbol | Funding rate history | Carry trade, sentiment analysis |
GET /api/markets | All markets with metadata | Discovery, universe selection |
GET /api/market/:symbol | Single market details | Max leverage, symbol info |
3 Setup & First API Call
No SDK needed. The API returns JSON over plain HTTP. Let's start with curl to verify everything works:
# Get the current BTC price
curl https://agent-gateway-kappa.vercel.app/v1/defi-trading/api/price/BTC
Now let's set up a Python project:
# Create project directory
mkdir crypto-bot && cd crypto-bot
# Install the only dependency
pip install requests
Create a base client that all your bot modules will use:
import requests
BASE_URL = "https://agent-gateway-kappa.vercel.app/v1/defi-trading"
def get(path, params=None):
"""Make a GET request to the DeFi Trading API."""
resp = requests.get(f"{BASE_URL}{path}", params=params, timeout=10)
resp.raise_for_status()
return resp.json()
def get_price(symbol):
"""Get current price for a symbol."""
return float(get(f"/api/price/{symbol}")["price"])
def get_all_prices():
"""Get all 229 market prices in one call."""
data = get("/api/prices")
return {k: float(v) for k, v in data["prices"].items()}
def get_candles(symbol, interval="1h"):
"""Get OHLCV candles for backtesting."""
return get(f"/api/candles/{symbol}", {"interval": interval})["candles"]
def get_orderbook(symbol, depth=3):
"""Get L2 orderbook."""
return get(f"/api/book/{symbol}", {"depth": depth})
def get_funding(symbol):
"""Get funding rate history."""
return get(f"/api/funding/{symbol}")["funding"]
Test it:
from client import get_price, get_all_prices
# Single price
btc = get_price("BTC")
print(f"BTC: ${btc:,.2f}")
# All 229 prices in one request
prices = get_all_prices()
print(f"Tracking {len(prices)} markets")
print(f"Top 5: {dict(sorted(prices.items(), key=lambda x: -x[1])[:5])}")
4 Fetching Market Data — Prices, Orderbooks, Candles
Multi-Market Price Scanner
A trading bot needs to monitor multiple markets simultaneously. Here's a scanner that tracks price changes across all 229 markets:
import time
from client import get_all_prices
def scan_markets(interval_sec=60):
"""Monitor all markets for significant price moves."""
prev_prices = get_all_prices()
print(f"Monitoring {len(prev_prices)} markets...")
while True:
time.sleep(interval_sec)
curr_prices = get_all_prices()
movers = []
for symbol, price in curr_prices.items():
if symbol in prev_prices and prev_prices[symbol] > 0:
change = (price - prev_prices[symbol]) / prev_prices[symbol] * 100
if abs(change) >= 1.0: # 1% move threshold
movers.append((symbol, change, price))
if movers:
movers.sort(key=lambda x: abs(x[1]), reverse=True)
print(f"\n--- Movers ({time.strftime('%H:%M:%S')}) ---")
for sym, chg, px in movers[:10]:
direction = "+" if chg > 0 else ""
print(f" {sym:<10} {direction}{chg:.2f}% ${px:,.4f}")
prev_prices = curr_prices
scan_markets()
Orderbook Spread Analysis
The spread between the best bid and best ask tells you about market liquidity. Wide spreads = less liquid, potentially more volatile:
from client import get_orderbook, get_all_prices
def analyze_spreads(symbols):
"""Analyze bid-ask spreads for given symbols."""
for symbol in symbols:
book = get_orderbook(symbol, depth=3)
levels = book["levels"]
# levels[0] = bids, levels[1] = asks
best_bid = float(levels[0][0]["px"])
best_ask = float(levels[1][0]["px"])
mid = (best_bid + best_ask) / 2
spread_bps = (best_ask - best_bid) / mid * 10000
bid_depth = sum(float(l["sz"]) for l in levels[0])
ask_depth = sum(float(l["sz"]) for l in levels[1])
imbalance = bid_depth / (bid_depth + ask_depth) * 100
print(f"{symbol:<8} Spread: {spread_bps:.1f}bps "
f"Bid depth: {bid_depth:.1f} Ask depth: {ask_depth:.1f} "
f"Imbalance: {imbalance:.0f}% buy")
# Analyze the top markets
analyze_spreads(["BTC", "ETH", "SOL", "DOGE", "ARB"])
OHLCV Candles for Technical Analysis
Candle data is essential for backtesting. The API provides 9 intervals from 1-minute to 1-month:
from client import get_candles
def compute_sma(candles, period):
"""Simple moving average over closing prices."""
closes = [float(c["c"]) for c in candles]
if len(closes) < period:
return None
return sum(closes[-period:]) / period
def compute_rsi(candles, period=14):
"""Relative Strength Index."""
closes = [float(c["c"]) for c in candles]
if len(closes) < period + 1:
return None
gains, losses = [], []
for i in range(1, len(closes)):
delta = closes[i] - closes[i-1]
gains.append(max(delta, 0))
losses.append(max(-delta, 0))
avg_gain = sum(gains[-period:]) / period
avg_loss = sum(losses[-period:]) / period
if avg_loss == 0:
return 100
rs = avg_gain / avg_loss
return 100 - (100 / (1 + rs))
# Analyze BTC on 1-hour candles
candles = get_candles("BTC", "1h")
sma_20 = compute_sma(candles, 20)
rsi = compute_rsi(candles)
current = float(candles[-1]["c"])
print(f"BTC Current: ${current:,.0f}")
print(f"BTC SMA(20): ${sma_20:,.0f}")
print(f"BTC RSI(14): {rsi:.1f}")
print(f"Signal: {'ABOVE' if current > sma_20 else 'BELOW'} SMA")
print(f"RSI: {'Overbought' if rsi > 70 else 'Oversold' if rsi < 30 else 'Neutral'}")
5 Building a Simple Trading Strategy
Let's build a momentum scanner that finds markets where price just crossed above the 20-period SMA with RSI between 40-60 (not already overbought):
from client import get, get_candles
def momentum_scan():
"""Find markets with bullish momentum signals."""
# Get all available markets
markets = get("/api/markets")["markets"]
symbols = [m["symbol"] for m in markets]
signals = []
for symbol in symbols[:30]: # Top 30 by market cap
try:
candles = get_candles(symbol, "1h")
if len(candles) < 21:
continue
closes = [float(c["c"]) for c in candles]
current = closes[-1]
prev = closes[-2]
# SMA crossover
sma_now = sum(closes[-20:]) / 20
sma_prev = sum(closes[-21:-1]) / 20
crossed_above = prev < sma_prev and current > sma_now
# RSI filter
gains, losses = [], []
for i in range(1, len(closes)):
d = closes[i] - closes[i-1]
gains.append(max(d, 0))
losses.append(max(-d, 0))
ag = sum(gains[-14:]) / 14
al = sum(losses[-14:]) / 14
rsi = 100 - (100 / (1 + ag/al)) if al > 0 else 100
if crossed_above and 40 < rsi < 60:
signals.append({
"symbol": symbol,
"price": current,
"rsi": rsi,
"sma": sma_now,
"distance_pct": (current - sma_now) / sma_now * 100
})
except Exception:
continue
if signals:
print("=== BULLISH SMA CROSSOVER SIGNALS ===")
for s in signals:
print(f" {s['symbol']:<8} ${s['price']:>10,.2f} "
f"RSI: {s['rsi']:.0f} "
f"+{s['distance_pct']:.2f}% above SMA")
else:
print("No crossover signals right now.")
return signals
momentum_scan()
6 Funding Rate Arbitrage Scanner
Perpetual futures have funding rates — periodic payments between longs and shorts to keep the price anchored to spot. When funding is highly positive, shorts get paid. When negative, longs get paid. This creates arbitrage opportunities:
from client import get, get_funding
def scan_funding_rates():
"""Find extreme funding rates for carry trade opportunities."""
markets = get("/api/markets")["markets"]
rates = []
for m in markets[:50]: # Top 50 markets
try:
funding = get_funding(m["symbol"])
if not funding:
continue
# Get last 24 funding payments
recent = funding[:24]
rates_list = [float(f["fundingRate"]) for f in recent]
avg_rate = sum(rates_list) / len(rates_list)
annualized = avg_rate * 3 * 365 * 100 # 3 payments/day * 365
rates.append({
"symbol": m["symbol"],
"current_rate": float(funding[0]["fundingRate"]),
"avg_24h": avg_rate,
"annualized_pct": annualized,
"leverage": m.get("maxLeverage", "?")
})
except Exception:
continue
# Sort by absolute annualized rate
rates.sort(key=lambda x: abs(x["annualized_pct"]), reverse=True)
print("=== FUNDING RATE SCANNER ===")
print(f"{'Symbol':<8} {'Current':>10} {'Avg 24h':>10} {'Annual':>10} {'Leverage':>8}")
print("-" * 52)
for r in rates[:15]:
direction = "LONGS PAY" if r["current_rate"] > 0 else "SHORTS PAY"
print(f"{r['symbol']:<8} {r['current_rate']:>+10.6f} "
f"{r['avg_24h']:>+10.6f} {r['annualized_pct']:>+9.1f}% "
f"{r['leverage']:>5}x {direction}")
scan_funding_rates()
7 Real-Time Monitoring Dashboard
Combine everything into a terminal dashboard that monitors your watchlist with live prices, RSI, and funding rates:
import time, os
from client import get_price, get_candles, get_funding
WATCHLIST = ["BTC", "ETH", "SOL", "DOGE", "ARB", "AVAX"]
def dashboard():
while True:
os.system("clear")
print(f" CRYPTO TRADING BOT DASHBOARD | {time.strftime('%H:%M:%S UTC')}")
print("=" * 72)
print(f"{'Symbol':<8} {'Price':>12} {'RSI':>6} {'SMA20':>12} {'Funding':>10}")
print("-" * 72)
for symbol in WATCHLIST:
try:
price = get_price(symbol)
candles = get_candles(symbol, "1h")
closes = [float(c["c"]) for c in candles]
# SMA
sma = sum(closes[-20:]) / 20 if len(closes) >= 20 else 0
# RSI
gains = [max(closes[i]-closes[i-1], 0) for i in range(1, len(closes))]
losses = [max(closes[i-1]-closes[i], 0) for i in range(1, len(closes))]
ag = sum(gains[-14:])/14
al = sum(losses[-14:])/14
rsi = 100-(100/(1+ag/al)) if al > 0 else 100
# Funding
funding = get_funding(symbol)
fr = float(funding[0]["fundingRate"]) if funding else 0
rsi_label = f"{rsi:.0f}"
print(f"{symbol:<8} ${price:>11,.2f} {rsi_label:>6} ${sma:>11,.2f} {fr:>+10.6f}")
except Exception as e:
print(f"{symbol:<8} {'error':>12}")
print("\nRefreshing in 60s... (Ctrl+C to exit)")
time.sleep(60)
dashboard()
8 Next Steps & Going to Production
You now have a complete market data pipeline. Here's how to take it further:
Get an API Key for More Requests
The free tier gives you 100 requests/day. For a real trading bot, create an API key to get 50 free credits (each request = 1 credit):
# Create an API key (50 free credits included)
curl -X POST https://agent-gateway-kappa.vercel.app/v1/defi-trading/api/keys/create
# Use it in requests
curl -H "Authorization: Bearer dt_your_key_here" \
https://agent-gateway-kappa.vercel.app/v1/defi-trading/api/prices
# Check your balance
curl -H "Authorization: Bearer dt_your_key_here" \
https://agent-gateway-kappa.vercel.app/v1/defi-trading/api/keys/balance
Need more? Top up with USDC on Base — 500 credits per USDC (min 0.5 USDC). See GET /api/payments/info for details.
Add to Your Python Client
# Updated client with API key support
API_KEY = "dt_your_key_here" # From POST /api/keys/create
def get(path, params=None):
headers = {}
if API_KEY:
headers["Authorization"] = f"Bearer {API_KEY}"
resp = requests.get(f"{BASE_URL}{path}", params=params,
headers=headers, timeout=10)
# Check remaining credits from response headers
remaining = resp.headers.get("X-Credits-Remaining")
if remaining:
print(f"Credits remaining: {remaining}")
resp.raise_for_status()
return resp.json()
Production Checklist
- Add order execution — connect to Hyperliquid, Binance, or Bybit for placing trades
- Paper trading — simulate orders against live data before going live
- Logging — record every signal, every decision, for later analysis
- Error handling — retry on network failures, handle rate limits gracefully
- Backtesting framework — use candle data to test strategies on historical periods
- Alerting — send Telegram/Discord notifications on high-confidence signals
Start Building Your Trading Bot
229 perpetual futures markets. Real-time prices, orderbooks, candles, and funding rates. Free to start.
Explore API DocsRelated APIs
- Free Crypto Price API — prices for 500+ tokens including spot markets
- Build an AI Agent with Crypto Wallet — give your bot a wallet to trade with
- Getting Started Guide — overview of all 39 available APIs