most people think you can only make money when prices go up. grid trading is the opposite idea — it makes money when the price goes sideways.
the concept is simple. you set a price range, divide it into a grid of buy and sell orders, and let it run. every time the price drops to a grid level, you buy. every time it rises to the next level, you sell. each round trip is a small profit.
it's boring. it's mechanical. and it works surprisingly well in choppy markets.
how a grid works
let's say SOL is trading at $150 and you think it'll stay between $130 and $170 for a while.
you divide that range into 10 levels:
$170 — sell
$166 — sell
$162 — sell
$158 — sell
$154 — sell
$150 — current price
$146 — buy
$142 — buy
$138 — buy
$134 — buy
$130 — buy
you place buy orders at every level below the current price and sell orders above it. when the price dips to $146, your buy order fills. when it bounces back to $150, your sell order fills. that's a $4 profit on that grid level.
multiply that by 10 levels, running 24/7, and the small profits add up.
the math
here's the basic calculation:
price_range_high = 170
price_range_low = 130
num_grids = 10
investment = 1000 # in USD
grid_spacing = (price_range_high - price_range_low) / num_grids
profit_per_grid = grid_spacing # $4 per grid in this case
amount_per_grid = investment / num_grids # $100 per level
# each round trip profit
units_per_grid = amount_per_grid / price_range_low # ~0.77 SOL
profit_per_trip = units_per_grid * grid_spacing # ~$3.07
print(f"grid spacing: ${grid_spacing}")
print(f"profit per round trip: ${profit_per_trip:.2f}")
print(f"if price oscillates 3x daily across 5 grids: ${profit_per_trip * 5 * 3:.2f}/day")
output:
grid spacing: $4.0
profit per round trip: $3.07
if price oscillates 3x daily across 5 grids: $46.05/day
obviously that's an optimistic scenario. real markets don't hit every grid level every day. but even getting 20-30% of that theoretical max adds up over weeks.
building a basic grid bot
here's the skeleton of a grid bot in python:
class GridBot:
def __init__(self, low, high, grids, total_investment):
self.low = low
self.high = high
self.grids = grids
self.grid_levels = []
self.active_orders = {}
self.investment_per_grid = total_investment / grids
# calculate grid levels
spacing = (high - low) / grids
for i in range(grids + 1):
self.grid_levels.append(round(low + (spacing * i), 2))
def check_price(self, current_price):
actions = []
for level in self.grid_levels:
if level < current_price and level not in self.active_orders:
# price is above this level and we don't have a position
# place a buy order at this level
actions.append(('BUY', level))
self.active_orders[level] = 'pending_buy'
elif level > current_price and self.active_orders.get(level) == 'filled_buy':
# price dropped below a level where we bought
# wait for it to come back up
pass
# check if any buy orders got filled
for level in list(self.active_orders.keys()):
if self.active_orders[level] == 'pending_buy' and current_price <= level:
self.active_orders[level] = 'filled_buy'
actions.append(('FILLED_BUY', level))
elif self.active_orders[level] == 'filled_buy':
# find the next grid level up for the sell
sell_level = self.get_next_level_up(level)
if sell_level and current_price >= sell_level:
actions.append(('SELL', sell_level))
del self.active_orders[level]
return actions
def get_next_level_up(self, level):
idx = self.grid_levels.index(level)
if idx + 1 < len(self.grid_levels):
return self.grid_levels[idx + 1]
return None
this is simplified. a real bot needs to handle:
- actual order placement via exchange API or on-chain swaps
- order tracking and state management
- fee calculations (fees eat into your grid profit)
- position sizing
- error handling and recovery
what kills grid bots
1. breakout moves
if SOL breaks above $170 in our example, you've sold everything and you're sitting in cash while it moons. you captured grid profits but missed the big move. this is the main opportunity cost.
if it drops below $130, you're fully in SOL at a loss. you bought at every level on the way down and now you're holding bags.
2. fees
each round trip involves a buy and a sell. if your exchange charges 0.1% per trade, that's 0.2% per round trip. on a grid with $4 spacing on a $150 token, that's about $0.30 in fees vs $3.07 profit. manageable, but on tighter grids it eats more.
on-chain swaps on solana are cheaper (maybe 0.25% on jupiter) but you also pay transaction fees. on solana those are like $0.001 so basically nothing.
3. impermanent loss
this is the same concept from LP provision. you end up buying the dips and selling the rips, which means you accumulate the depreciating asset and sell the appreciating one. if the price trends hard in one direction, you would have been better off just holding.
when to use grid trading
grid trading works best when:
- the market is ranging (no clear trend)
- you're trading a pair with decent liquidity
- the asset isn't likely to go to zero
- you have patience (it's a slow grind, not a moonshot)
it does NOT work when:
- you're in a strong bull or bear trend
- the token has low liquidity (slippage kills your margins)
- grid spacing is too tight relative to fees
grid trading on solana specifically
solana is actually a good chain for grid trading because:
- transaction fees are basically zero (~$0.001)
- block times are fast (400ms)
- there are good DEX aggregators (jupiter) for best execution
- you can run a bot on a cheap VPS 24/7
the main challenge is managing on-chain orders. unlike centralized exchanges where you can place limit orders, on-chain you need to either:
- use a DEX with limit order support (jupiter has this now)
- poll the price and market-swap when it hits your levels
- use a protocol that supports on-chain grid orders
option 2 is the most common for custom bots. you just check the price every few seconds and swap when it crosses a grid level.
import time
bot = GridBot(low=130, high=170, grids=10, total_investment=1000)
while True:
price = get_current_price('SOL/USDC') # your price feed
actions = bot.check_price(price)
for action_type, level in actions:
if action_type == 'BUY':
execute_swap('USDC', 'SOL', bot.investment_per_grid)
elif action_type == 'SELL':
execute_swap('SOL', 'USDC', bot.investment_per_grid / level)
time.sleep(5) # check every 5 seconds
try it yourself
i built a python grid trading bot for solana that handles all the edge cases — order management, fee tracking, position sizing, and recovery from crashes. it runs on any VPS and connects to solana directly.
if you want to try it out: sol-grid-bot
or build your own using the code above as a starting point. the grid logic is straightforward — the hard part is the reliable execution and state management.
final thoughts
grid trading won't make you rich overnight. it's a slow, steady strategy that works in ranging markets. the key is picking good ranges, keeping grids wide enough to cover fees, and accepting that you'll miss big moves in exchange for consistent small profits.
start with paper trading (just log what you would have done) before putting real money in. run it for a week, check the results, adjust your grid parameters, and go from there.
the most common mistake is making grids too tight. wider grids = fewer trades but higher profit per trade and less fee drag. start wide and tighten later if the market cooperates.
Top comments (0)