Futures Against Spot: Earning the Funding Rate
Lesson 14 of the arbitrage course. What a perpetual future and its funding rate are, how to hold one coin on the spot market and the opposite position on the future, and what the fees, a negative rate and a liquidation do to the result. Short Python code with numbers you can check by hand.
Lesson 14 of the course "Build your own arbitrage bot". Until now the bot looked for gaps that close in seconds. Today it gets a second strategy that earns slowly and steadily, and has a different kind of risk.
Two ways to own the same coin
You can buy a coin on the spot market: you pay money, you get the coin, it is yours.
You can also trade a future on that coin. A future is a contract whose price follows the coin. You do not get the coin. You get a position: if you are long and the price goes up by 10, you earn 10 per coin, and if it goes down by 10 you lose 10. If you are short, it is the other way round. A future needs only a part of the money as a deposit (called margin), so it comes with leverage.
The exchanges you meet most often sell perpetual futures: a contract with no expiry date. That raises a problem. A dated future is forced back to the spot price on its last day. A perpetual never ends, so what keeps its price near the spot price?
The funding rate
The answer is a payment between traders, called the funding rate. Every 8 hours (on many exchanges) one side pays the other.
- If the perpetual trades above spot, the rate is positive and longs pay shorts.
- If it trades below spot, the rate is negative and shorts pay longs.
The payment is the rate times the size of the position. A long position that is too popular becomes expensive to hold, so some people close it, and the price drifts back to spot. That is the whole mechanism.
The idea of the strategy
Hold both sides at once: buy 1 coin on the spot market and open a short position of 1 coin on the perpetual. Now the price of the coin does not matter. If it goes up by 10, the coin earns 10 and the short loses 10. If it goes down, the opposite. Your total is flat, which traders call delta neutral.
What is left is the funding. When the rate is positive, you hold the short side and you receive the payment every 8 hours. You are paid for holding a position that has no price risk. This is called cash-and-carry or funding arbitrage.
The head-on way: read the yearly number
Suppose the rate is 0.01 percent per 8 hours. That is 3 payments a day, so 3 × 365 × 0.01 percent = 10.95 percent a year. The blunt conclusion: put in 100 and receive 10.95 a year with no risk, so do it with all the money.
Check this with a loop that takes more into account. The next code opens the pair at price 100, runs through 90 funding payments (30 days), and adds the fees. Fees: the spot trade costs 0.1 percent, the perpetual trade costs 0.05 percent, and you pay each when you open and when you close.
SPOT_FEE, PERP_FEE = 0.001, 0.0005 # taker fees, per trade
price = 100.0
# funding rate per 8 hours, 3 payments a day, 30 days = 90 payments
rates = [0.0001] * 45 + [0.00005] * 20 + [-0.0001] * 15 + [0.0001] * 10
def carry(rates, exit_when_negative=False):
cost_in = price * SPOT_FEE + price * PERP_FEE # buy spot, open short
cost_out = price * SPOT_FEE + price * PERP_FEE # sell spot, close short
income = 0.0
for r in rates:
if exit_when_negative and r < 0:
break
income += price * r # the short side receives r * notional
return income - cost_in - cost_out, income
for name, flag in [("hold all 30 days", False), ("leave at first negative", True)]:
net, gross = carry(rates, flag)
print(f"{name:24} funding {gross:6.3f} fees {2*(price*SPOT_FEE+price*PERP_FEE):.3f} net {net:+.3f}")
fees = 2 * (price * SPOT_FEE + price * PERP_FEE)
print("payments to cover fees", round(fees / (price * 0.0001)), "=", round(fees / (price * 0.0001) / 3, 1), "days")
Output:
hold all 30 days funding 0.500 fees 0.300 net +0.200
leave at first negative funding 0.550 fees 0.300 net +0.250
payments to cover fees 30 = 10.0 days
Read it.
- The rates in the test are not constant: 45 payments at 0.01 percent, then 20 at half of that, then 15 negative payments, then 10 back to 0.01 percent. That mimics a real market, where the rate changes with the mood of traders.
- Holding all 30 days: funding of 0.45 + 0.10 − 0.15 + 0.10 = 0.50. The fees are 0.30 (0.15 to open, 0.15 to close). The net result is +0.20 on 100, which is 0.2 percent for a month, about 2.4 percent a year, not the 10.95 percent from the headline.
- Leaving as soon as the rate turns negative gains 0.05 more: the 15 negative payments cost 0.15, the last 10 good ones bring back 0.10.
- The fees need 30 payments at the full rate, 10 days, only to break even. A trader who opens the pair for 3 days at 0.01 percent loses money.
So the 10.95 percent is a ceiling that exists only if the rate stays at 0.01 percent and you stay in the position for a long time. The loop shows why the first idea is too optimistic: the rate changes sign, and the fees are paid on both ends.
What the bot checks before it opens the pair
- Current and expected rate. An average of the last days, not only the last value.
- Fees on both ends. Include them in the break-even time and compare it with how long the rate has been stable.
- Which exchange pays. The same coin has a different rate on different exchanges. The bot may use the spot market on one exchange and the perpetual on another, which also adds the cost of keeping money in two places.
- Exit rule. A rule such as "leave when the average rate turns negative" written down and tested, as in the loop above.
The real danger: the short is on margin
The spot coin and the short sit on different accounts. The short is a leveraged position, and the exchange closes it by force (liquidation) when the loss eats the margin. A rough formula, ignoring small maintenance margin, is that a short with leverage L is liquidated when the price rises by about 100 / L percent:
for L in (2, 5, 10):
print(f"leverage {L:>2}: perp short liquidated near price {price*(1+1/L):6.1f} (+{100/L:.0f}%)")
leverage 2: perp short liquidated near price 150.0 (+50%)
leverage 5: perp short liquidated near price 120.0 (+20%)
leverage 10: perp short liquidated near price 110.0 (+10%)
Now the picture changes. If the price rises 20 percent with leverage 5, the coin you hold has earned 20, but the exchange has already closed your short at a loss of 20 and you are left with an open coin position and a price risk you did not plan for. The total was flat on paper, and the forced close broke it. The fix is boring and works: use low leverage (1 to 2), keep spare money that the bot can move into the margin account when the price rises, and let a risk limit from lesson 12 stop everything when the margin level gets low.
Let an AI agent write and test it
A vague request:
Build a funding rate arbitrage bot.
A request with checks built in:
Write carry.py with carry(rates, price, spot_fee, perp_fee, exit_when_negative) returning (net, gross). With price 100, fees 0.001 and 0.0005, and the list of rates from lesson 14 (45 times 0.0001, 20 times 0.00005, 15 times -0.0001, 10 times 0.0001) it must return net 0.2 for holding all, and net 0.25 with exit_when_negative. Add break_even_payments(rate, price, spot_fee, perp_fee) that must return 30 for rate 0.0001. Add liquidation_price(entry, leverage) = entry * (1 + 1 / leverage). No network calls, no real orders.
Check the three numbers by hand before you trust the code.
Your exercise
- Run the code and compare each printed number with the lesson.
- Change the spot fee to 0.0002 and the perpetual fee to 0.0002 (a trader with a discount). How many days of full rate are needed to break even now? Compute by hand first: fees are 2 × (0.02 + 0.02) = 0.08.
- Change the list of rates so that the negative part lasts 40 payments. Which is better now, to hold or to leave at the first negative payment? By how much?
- For the 5 times leverage case, the price moves up 20 percent in one day. Write on paper what happens on the spot side and on the short side, and what the bot would have to do before the move to stay safe.
What comes next
The bot now has two strategies, the quick gap between exchanges and the slow funding income. Lesson 15 gives it a third, which you may choose: trading a pair of coins that move together (statistical arbitrage), or a machine learning filter on the signals you already have.