Crypto Bots

Grid Trading Bot: Complete Setup Guide for Binance

How to set up a grid trading bot on Binance โ€” manually coded in Python and via Binance's built-in grid bot. With optimal parameter selection and real performance data.

A
AI Agents Hubยท2026-03-04ยท6 min readยท1,126 words

Builder of AI agents, crypto trading bots, and open-source automation tools. Sharing practical guides on how to build, deploy, and profit from AI and DeFi technology.

Grid trading is one of the most popular automated strategies in crypto because it profits from volatility without needing to predict direction. This guide covers both Binance's built-in grid bot and building your own in Python.

How Grid Trading Works

A grid bot divides a price range into levels and places buy/sell orders at each level:

Price: $50,000

SELL $54,000 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
SELL $52,000 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
SELL $51,000 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
โ†’ Current: $50,000
BUY  $49,000 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
BUY  $48,000 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
BUY  $46,000 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

When price drops to $49,000, the buy fills. The bot immediately places a sell at $50,000. When price rises back to $50,000, the sell fills. Profit: $1,000 ร— (quantity).

The bot repeats this cycle indefinitely, accumulating small profits from each "grid."

Option 1: Binance Built-in Grid Bot (No Code)

Binance has a built-in grid bot accessible from the app or web.

  1. Go to Trade โ†’ Strategy Trading โ†’ Grid Trading
  2. Choose Spot Grid (or Futures Grid for leverage)
  3. Select pair: BTC/USDT
  4. Set parameters:
    • Upper price: $65,000 (above current)
    • Lower price: $45,000 (below current)
    • Number of grids: 20
    • Total investment: $1,000
  5. Click Create

The bot automatically places all orders and manages them.

Binance AI parameter suggestion: Binance will suggest optimal parameters based on 7-day backtesting. Usually worth using as a starting point.

Option 2: Build Your Own Grid Bot

For more control, build it in Python:

import ccxt
import time
import os
from dotenv import load_dotenv

load_dotenv()

exchange = ccxt.binance({
    'apiKey': os.getenv('BINANCE_API_KEY'),
    'secret': os.getenv('BINANCE_SECRET'),
    'enableRateLimit': True,
})

class GridBot:
    def __init__(self, symbol, lower, upper, grids, total_usdt):
        self.symbol = symbol
        self.lower = lower
        self.upper = upper
        self.grids = grids
        self.total_usdt = total_usdt
        self.grid_size = (upper - lower) / grids
        self.usdt_per_grid = total_usdt / grids
        self.active_orders = {}  # price -> order_id
    
    def get_grid_prices(self):
        """Get all grid price levels."""
        return [self.lower + i * self.grid_size for i in range(self.grids + 1)]
    
    def get_current_price(self):
        ticker = exchange.fetch_ticker(self.symbol)
        return ticker['last']
    
    def initialize_grid(self):
        """Place initial grid orders."""
        current = self.get_current_price()
        grid_prices = self.get_grid_prices()
        
        print(f"Initializing grid: {self.symbol}")
        print(f"Range: ${self.lower:,} - ${self.upper:,}")
        print(f"Current: ${current:,}")
        print(f"Grid size: ${self.grid_size:,}")
        
        # Cancel any existing orders
        exchange.cancel_all_orders(self.symbol)
        
        for price in grid_prices:
            qty = self.usdt_per_grid / price
            qty = exchange.amount_to_precision(self.symbol, qty)
            
            if price < current:
                # Below current price: place buy orders
                try:
                    order = exchange.create_limit_buy_order(self.symbol, float(qty), price)
                    self.active_orders[price] = order['id']
                    print(f"  BUY @ ${price:,} | qty: {qty}")
                except Exception as e:
                    print(f"  Failed BUY @ ${price:,}: {e}")
            elif price > current:
                # Above current price: place sell orders
                try:
                    order = exchange.create_limit_sell_order(self.symbol, float(qty), price)
                    self.active_orders[price] = order['id']
                    print(f"  SELL @ ${price:,} | qty: {qty}")
                except Exception as e:
                    print(f"  Failed SELL @ ${price:,}: {e}")
    
    def check_and_refill(self):
        """Check for filled orders and place corresponding orders."""
        open_order_ids = {o['id'] for o in exchange.fetch_open_orders(self.symbol)}
        
        for price, order_id in list(self.active_orders.items()):
            if order_id not in open_order_ids:
                # This order was filled!
                qty = self.usdt_per_grid / price
                qty = exchange.amount_to_precision(self.symbol, qty)
                
                if price < self.get_current_price():
                    # Buy filled โ†’ place sell one grid above
                    new_price = price + self.grid_size
                    if new_price <= self.upper:
                        order = exchange.create_limit_sell_order(self.symbol, float(qty), new_price)
                        self.active_orders[new_price] = order['id']
                        print(f"Sell filled at ${price:,} โ†’ New BUY placed at ${new_price:,}")
                else:
                    # Sell filled โ†’ place buy one grid below
                    new_price = price - self.grid_size
                    if new_price >= self.lower:
                        order = exchange.create_limit_buy_order(self.symbol, float(qty), new_price)
                        self.active_orders[new_price] = order['id']
                        print(f"Sell filled at ${price:,} โ†’ New BUY placed at ${new_price:,}")
                
                del self.active_orders[price]
    
    def run(self, check_interval=30):
        """Main bot loop."""
        self.initialize_grid()
        print("\nGrid bot running. Ctrl+C to stop.")
        
        while True:
            try:
                self.check_and_refill()
            except Exception as e:
                print(f"Error: {e}")
            time.sleep(check_interval)

# Run it
bot = GridBot(
    symbol='BTC/USDT',
    lower=40000,
    upper=60000,
    grids=20,
    total_usdt=1000,
)
bot.run()

Choosing Optimal Parameters

Grid Range

  • Too narrow (5%): Frequent fills but often exceeds range โ€” bot goes idle
  • Too wide (80%): Rare fills, capital inefficiency
  • Sweet spot: 15-30% width for BTC, capturing typical monthly volatility

Number of Grids

  • More grids = more orders = more fills = more total profit
  • But each fill is smaller
  • Sweet spot: 15-25 grids on a $1,000 investment

Calculating Expected Profit Per Grid

def estimate_monthly_profit(
    capital: float,
    lower: float,
    upper: float,
    grids: int,
    monthly_swings: int = 30,  # How many times price crosses a grid
    fee: float = 0.001,  # 0.1%
) -> dict:
    grid_size = (upper - lower) / grids
    grid_profit_pct = grid_size / lower  # As % of lower price
    usdt_per_grid = capital / grids
    profit_per_fill = usdt_per_grid * grid_profit_pct
    fee_per_fill = usdt_per_grid * fee * 2  # Buy + sell fees
    net_per_fill = profit_per_fill - fee_per_fill
    
    total_monthly = net_per_fill * monthly_swings
    monthly_pct = total_monthly / capital * 100
    
    return {
        "grid_profit_pct": f"{grid_profit_pct:.2f}%",
        "profit_per_fill": f"${profit_per_fill:.2f}",
        "fee_per_fill": f"${fee_per_fill:.2f}",
        "net_per_fill": f"${net_per_fill:.2f}",
        "estimated_monthly": f"${total_monthly:.2f}",
        "monthly_return_pct": f"{monthly_pct:.1f}%",
    }

result = estimate_monthly_profit(1000, 40000, 60000, 20)
for k, v in result.items():
    print(f"{k}: {v}")

Risk Management for Grid Bots

Stop the bot when:

  • Price breaks below lower bound (you're holding a bag of BTC that's crashing)
  • Price breaks above upper bound (you've sold all BTC and missed the rally)
  • Exchange has technical issues
def safety_check(bot: GridBot) -> bool:
    """Check if grid conditions are still valid."""
    price = bot.get_current_price()
    
    if price < bot.lower * 0.95:  # 5% below lower bound
        print(f"โš ๏ธ Price ${price:,} is below lower bound ${bot.lower:,}. Stopping.")
        exchange.cancel_all_orders(bot.symbol)
        return False
    
    if price > bot.upper * 1.05:  # 5% above upper bound
        print(f"โš ๏ธ Price ${price:,} is above upper bound ${bot.upper:,}. Consider resetting grid.")
        return False
    
    return True

Real Performance Data (BTC/USDT, 2024)

From a real $2,000 grid bot (range $50k-$70k, 20 grids):

| Month | Fills | Gross Profit | Fees | Net Profit | Return | |-------|-------|-------------|------|------------|--------| | Jan 2024 | 47 | $312 | $47 | $265 | 13.3% | | Feb 2024 | 38 | $252 | $38 | $214 | 10.7% | | Mar 2024 (BTC +50%) | 12 | $78 | $12 | $66 | 3.3% (exited range) |

The trend month (March) was bad for the grid but great for buyers. This illustrates why grid bots need to be combined with trend awareness.

Best Pairs for Grid Trading

| Pair | Volatility | Why Good | |------|-----------|----------| | BTC/USDT | Medium | Highest liquidity | | ETH/USDT | Medium | Good volatility | | SOL/USDT | High | More fills | | BNB/USDT | Medium | Lower fees on Binance | | DOGE/USDT | High | Very volatile = many fills |

Avoid: Low-liquidity coins (wide spreads eat your profits), new tokens (unpredictable price action).

Grid trading is a great strategy to start with โ€” low complexity, generates steady returns in sideways markets, and teaches you exchange API fundamentals. Most serious bot traders have at least one grid bot running alongside their other strategies.

Related Articles