BlogDeveloper

How to Build a Hyperliquid Funding Rate Arbitrage Tool

Build a Hyperliquid funding rate arbitrage scanner: rank every market's rate, compare with Binance and Bybit, check liquidity and costs. Tested on both APIs.

HydromancerTeam
How to Build a Hyperliquid Funding Rate Arbitrage Tool

Funding rate arbitrage means holding two positions that cancel each other's price risk, so the only thing left is the funding payment.

Why people run this trade, and why they want a tool for it:

• To collect the funding payment. When a perp trades above the coin's price, longs pay shorts, and the arbitrage sits on the side being paid.
• To earn without betting on direction. It doesn't matter whether the price goes up or down.
• To put idle capital to work. When rates are high, the payment can beat what stablecoins earn sitting in a wallet.
• Because the opportunities move fast. Rates shift across hundreds of markets, too many to check by hand, so a tool finds them and prices them.

On Hyperliquid, funding is paid every hour, every rate is public, and the same request returns it for every market. That makes it a good place to build a tool that finds these trades and works out whether they're worth taking.

Why should you choose to build a funding rate arbitrage tool on Hyperliquid?

Funding keeps a perp's price close to the real price: the crowded side pays the other. On Hyperliquid, those payments can be large.

• The rates can be big. In our test, Paragon's TOTAL2 paid longs 0.317% an hour, about $32 an hour on a $10,000 position, while it lasted. The biggest rates are often on markets you can't hedge, which is why a scanner checks (Step 4).
• Funding is paid every hour. Most coins on Binance and Bybit paid every 4 hours when we checked, so a rate change reaches a Hyperliquid account sooner.
• There are hundreds of markets. We counted 345 live perps, on the main DEX and 10 HIP-3 DEXs run by other teams. The HIP-3 markets carry most of the extreme rates.
• Both legs fit in one account. Spot and perp sit on the same exchange, and trading costs no gas.
• Traders need the pricing done for them. The biggest rate is rarely the best trade once you price it against the order book. That pricing is the scanner's job.
• You earn when they act. If the scanner opens the trade, your builder code earns a fee on the orders it sends: perps both ways, spot on sells.

You'll build the scanner part: the tool that ranks opportunities and prices them. Holding the trade and keeping it balanced is covered in our delta-neutral bot guide. How funding itself works is covered in our funding rates guide, so we won't repeat it here.

There are two ways to run the trade:

Trade The two legs Collects
Spot and perp on HyperliquidBuy the coin on spot, short the same coin's perpThe perp's funding, when it's positive
Hyperliquid against another exchangeShort the perp where funding is higher, go long where it's lowerThe gap between the two rates

How we tested. Every step below was run as a small prototype on both APIs on 31 October and 1 November 2026, with time, requests and rate-limit use recorded. Funding rates change every hour, so your numbers will differ from ours. To run the code yourself: pip install requests websockets. The examples that read a .txt file expect one full wallet address per line.

This explains how to build the tool. It isn't financial advice, and nothing here says these trades are profitable.

How Hyperliquid funding works, in four lines

• Who pays whom. When the perp trades above the spot oracle price, the rate is positive and longs pay shorts. Below it, shorts pay longs.
• How often. Every hour, at one eighth of an 8-hour rate, so Hyperliquid pays 24 times a day where most exchanges pay three.
• The base rate. An interest part fixed at 0.01% per 8 hours (0.00125% an hour, which Hyperliquid quotes as 11.6% APR paid to shorts) plus a premium that moves with the market.
• The cap. 4% an hour, much looser than on centralized exchanges, which is why extreme rates show up here.

All four come from Hyperliquid's funding docs. The payment is position size times the oracle price times the rate, not the mark price.

Step 1: Rank every market's Hyperliquid funding rate

Your scanner starts by pulling the current rate for every perp and sorting by size.

Hyperliquid API

Hyperliquid's allDexsAssetCtxs stream sends the current state of every perp on every DEX, the main one and the HIP-3 DEXs other teams run, in a single message, including each market's current funding rate. This prototype lists the markets, takes one message from the stream and ranks the rates:

code
import json, requests
from websockets.sync.client import connect

metas = requests.post("https://api.hyperliquid.xyz/info",
                      json={"type": "allPerpMetas"}).json()
assets = {m["universe"][0]["name"].rpartition(":")[0]: m["universe"]
          for m in metas}                     # "" is the main DEX
with connect("wss://api.hyperliquid.xyz/ws", max_size=None) as ws:
    ws.send(json.dumps({"method": "subscribe",
                        "subscription": {"type": "allDexsAssetCtxs"}}))
    while (m := json.loads(ws.recv()))["channel"] != "allDexsAssetCtxs":
        pass
rates = [(float(c["funding"]), a["name"]) for dex, ctxs in m["data"]["ctxs"]
         for a, c in zip(assets[dex], ctxs) if not a.get("isDelisted")]
print(len(rates), "markets:", sorted(rates, key=lambda r: abs(r[0]))[-3:])
code
345 markets: [(0.0006641086, 'xyz:TWST'), (-0.000689811, 'BLUR'), (0.0014590614, 'para:TREAD')]

Hydromancer API

Hydromancer's fundingRates stream sends one message an hour with the rate that was actually charged on every market, HIP-3 included. Hydromancer added this endpoint for builder convenience; it isn't part of Hyperliquid's original API, and orders still go through Hyperliquid. This prototype waits for the next message and ranks it:

code
import json, os
from websockets.sync.client import connect

URL = "wss://api.hydromancer.xyz/ws?token="
with connect(URL + os.environ["HYDROMANCER_API_KEY"], max_size=None) as ws:
    ws.send(json.dumps({"method": "subscribe",
                        "subscription": {"type": "fundingRates"}}))
    while (m := json.loads(ws.recv()))["type"] != "fundingRates":
        if m["type"] == "ping":                # answer keep-alives
            ws.send(json.dumps({"type": "pong"}))
rates = [(float(r["funding_rate"]), r["coin"]) for r in m["data"]["rates"]]
print(len(rates), "markets:", sorted(rates, key=lambda r: abs(r[0]))[-3:])
code
343 markets: [(0.000422096, 'xyz:CAMBRICON'), (-0.000431114, 'BLUR'), (0.0004940798, 'xyz:RELIANCE')]

The two outputs were taken a day apart, so the top markets differ. Hydromancer's message arrived 2 seconds after the hour.

Side by side

Hyperliquid API Hydromancer API
What it returnsThe current rate, for 345 live marketsThe rate just charged, for every market that paid
When you get itAny time, in under a secondOnce an hour, 1 to 2 seconds after the hour
Time to finish (median)0.9 sUntil the next funding hour
Rate-limit cost20 weight (limit: 1,200 a minute per IP)none (live stream)
Worked2 of 2 runs1 of 1 runs
Requests10 (live stream)
Data received over REST (uncompressed)under 0.1 MBnot measured (live stream)

For ranking right now, use Hyperliquid's API: it answers in under a second, any time. Hydromancer's stream is for the other job: recording the rate each position was actually charged, the moment it's charged, which is what a scanner shows as "what you would have earned".

The biggest rates are usually on HIP-3 markets, the perps other teams deploy on Hyperliquid. In an earlier snapshot, at 11:12 UTC on 31 October, the four largest were Paragon's TOTAL2 (-0.317% an hour), Markets.xyz's BVIV (-0.262%), Paragon's DRV (-0.084%) and Trade[XYZ]'s CAMBRICON (+0.061%), and 38.6% of markets sat exactly at the base rate of 0.00125% an hour. A negative rate means shorts pay longs. Step 4 shows why the biggest number isn't the best trade.

Step 2: Compare with Binance and Bybit

For the cross-exchange trade, you need the same coin's rate on other exchanges, in the same units. Hyperliquid's predictedFundings request returns its own predicted rate next to Binance's and Bybit's for every coin, with each venue's payment interval:

code
import requests

URL = "https://api.hyperliquid.xyz/info"
rows = requests.post(URL, json={"type": "predictedFundings"}).json()
gaps = []
for coin, venues in rows:
    hourly = {v: float(x["fundingRate"]) / x["fundingIntervalHours"]
              for v, x in venues if x and x.get("fundingIntervalHours")}
    if "HlPerp" in hourly and "BinPerp" in hourly:
        gaps.append((hourly["HlPerp"] - hourly["BinPerp"], coin))
print(sorted(gaps)[-5:])

Binance and Bybit pay every 1, 4 or 8 hours depending on the coin, and Hyperliquid every hour, so the code divides each rate by its own interval before comparing. Some coins have no Binance or Bybit entry (46 and 49 of 235 coins), so skip those.

This step runs on Hyperliquid's API, whichever data API you use for the rest.

Step 3: Check the history before you trust a rate

One hour's rate says little. Before you show a trade, check how long the rate has stayed there, and once users hold positions, how much they've actually been paid.

Hyperliquid API

fundingHistory returns a market's rate for each hour, up to 500 rows per request: 60 days of ETH (1,440 hours) took three requests. For your own payments, userFunding returns up to 500 rows per request, and payments older than about a week come back merged into one row per coin per day (nSamples: 24).

Hydromancer API

fundingHistory returned the same 60 days of ETH in three requests, with identical rates and timestamps (if your scanner uses the premium field, take it from Hyperliquid's version). userFunding keeps every payment as its own hourly row, up to 2,000 per request.

Side by side

We pulled one wallet's funding for the past year from both:

Hyperliquid API Hydromancer API
Market rate history (60 days of ETH)3 requests3 requests, same numbers
Your payments over a year: rowsAbout 1,80025,689
Total received$117,713.02$117,713.02
Hour each payment landedLast week only; older rows are dailyEvery payment

Nothing is lost on Hyperliquid's API; the totals match to the cent. What you lose is the hour each payment landed. Use Hydromancer if your scanner charts income by the hour.

Step 4: Price the trade against the order book

A high rate on a thin market can cost more to enter than it pays. The scanner has to answer: what would it cost to trade the size I want, right now and over the day? Both prototypes price a $10,000 buy of Paragon's TOTAL2.

Hyperliquid API

l2Book returns the top 20 price levels on each side. This prototype walks the asks to estimate what a $10,000 buy costs right now:

code
import requests

COIN, USD = "para:TOTAL2", 10_000
book = requests.post("https://api.hyperliquid.xyz/info",
                     json={"type": "l2Book", "coin": COIN}).json()
bids, asks = book["levels"]
mid = (float(bids[0]["px"]) + float(asks[0]["px"])) / 2
left, cost = USD, 0.0
for lvl in asks:                          # walk up to 20 ask levels
    px, sz = float(lvl["px"]), float(lvl["sz"])
    take = min(left, px * sz)
    cost, left = cost + take * (px / mid - 1), left - take
note = "" if left < 1 else " (book too thin for the full size)"
print(COIN, "cost to buy $10,000 now:", round(cost / USD * 1e4), "bps" + note)
code
para:TOTAL2 cost to buy $10,000 now: 15 bps

Hydromancer API

slippageHistory estimates the cost of a trade of the size you choose, every 15 minutes, so you see how bad it gets over a day, not just now:

code
import os, time, requests

H = {"Authorization": "Bearer " + os.environ["HYDROMANCER_API_KEY"]}
body = {"type": "slippageHistory", "coin": "para:TOTAL2", "amount": 10000,
        "startTime": int(time.time() * 1000) - 86400000}  # every 15 min
rows = requests.post("https://api.hydromancer.xyz/info", headers=H,
                     json=body).json()
buys = sorted(r["buySlippageBps"] for r in rows if r["buySlippageBps"])
print(len(buys), "samples in 24 h: median", buys[len(buys) // 2],
      "bps, worst", buys[-1], "bps")
code
97 samples in 24 h: median 15.86 bps, worst 524.22 bps

Side by side

Hyperliquid API Hydromancer API
What it tells youThe cost right nowThe cost every 15 minutes for the last 24 hours
Worked3 of 3 runs3 of 3 runs
Time to finish (median)0.2 s0.2 s
Requests11
Rate-limit cost2 weight (limit: 1,200 a minute per IP)10 points (limit: 20,000 a minute on the Growth plan)
Data received over REST (uncompressed)under 0.1 MBunder 0.1 MB

Both are fast, and they answer different questions. Right now, TOTAL2 cost about 15 bps to buy, the same as its 24-hour median, but at its worst in those 24 hours it cost 524 bps. One snapshot can't show that. On Hyperliquid alone, you'd record the book yourself every few minutes, or rebuild rough estimates from its L2 snapshot archive (s3://hyperliquid-archive/market_data), which updates about monthly and may have gaps. marketLiquidity adds how much size sits within 2, 5, 10 and 25 bps of the mid price, if you'd rather size from depth.

Together, they told this story for the four biggest rates in that earlier snapshot:

Market Hourly rate Spread Cost to buy $10,000 then (Hyperliquid) Last 24 hours (Hydromancer)
para:TOTAL2-0.317%41 bps32 bpsmedian 14 bps, worst 779 bps
mkts:BVIV-0.262%36 bps104 bpsmedian 117 bps, worst 436 bps
para:DRV-0.084%27 bpsnot enough depth in 20 levelsmedian 186 bps, worst 233 bps
xyz:CAMBRICON+0.061%285 bps857 bpsmedian 217 bps, worst 945 bps

*1 basis point (bps) = 0.01%.*

At -0.317% an hour (about 32 bps), TOTAL2's funding would repay a 32 bps entry in about an hour, and its worst moment in those 24 hours (779 bps) in about 25 hours, before fees. But TOTAL2 has no spot market on Hyperliquid, and predictedFundings covers main-DEX coins only, so there's nothing on this list to hedge it with. Collecting that rate means holding the price risk. Of the four markets above, only DRV had a spot token with the same name on Hyperliquid (about $360,000 traded that day; check it's the same asset), so the scanner should flag whether a market has a hedge at all, and how deep it is.

Step 5: Subtract the fees

Every arbitrage pays fees four times: two legs in, two legs out. At Hyperliquid's base tier (fees), a taker pays 0.045% on perps and 0.070% on spot:

code
spot buy + perp short + spot sell + perp buy
= 0.070% + 0.045% + 0.070% + 0.045% = 0.23% of the position
0.23% ÷ 0.00125% an hour = 184 hours (about 7.7 days) at the base rate

So at the base rate, a spot-and-perp trade opened and closed with taker orders needs about a week of funding just to cover fees. Maker orders, volume-tier discounts and higher rates shorten that. HIP-3 markets can charge more: their deployers can add a fee share of up to 300%, and above 100% the protocol fee rises to match.

Scanner score = expected hourly funding × hours you expect to hold − four legs of fees − the cost of getting in and out (Step 4), flagged when there's no spot leg to hedge it.

Before flagging a spot-and-perp trade, check the spot leg is real: only 8 main-DEX coins had a spot market trading more than $1M a day. Our delta-neutral bot guide lists them and what to check about wrapped tokens.

Step 6: See who's actually being paid

The rate tells you who should be paid. The payments tell you who was, and how much. A scanner can use that to show where funding really flows, or to check its own users' income each hour. Both prototypes add up the latest hour's funding for the same 100 active wallets.

Hyperliquid API

userFunding returns one wallet's payments, so this prototype asks for each wallet in turn. Each request weighs 20 of the 1,200 a minute, so it waits between requests to stay inside the limit:

code
import time, requests

hour = int(time.time() // 3600 * 3600 * 1000)      # latest funding payment
paid = {}
for u in open("wallets.txt").read().split():
    rows = requests.post("https://api.hyperliquid.xyz/info", json={
        "type": "userFunding", "user": u, "startTime": hour,
        "endTime": hour + 60000}).json()
    if rows:
        paid[u] = sum(float(r["delta"]["usdc"]) for r in rows)
    time.sleep(1.2)                         # 20 weight each, 1,200 a minute
got = sum(v for v in paid.values() if v > 0)
print(len(paid), "wallets: received $", round(got), "paid $",
      round(got - sum(paid.values())))
code
93 wallets: received $ 12492 paid $ 3179

Hydromancer API

fundingPayments returns every funding payment from the latest hour, for every wallet and market, as one compressed file. This prototype picks out the same 100 wallets (it also needs pip install msgpack zstandard):

code
import os, msgpack, requests, zstandard

H = {"Authorization": "Bearer " + os.environ["HYDROMANCER_API_KEY"]}
r = requests.post("https://api.hydromancer.xyz/info", headers=H,
                  json={"type": "fundingPayments"})
raw = zstandard.ZstdDecompressor().stream_reader(r.content).read()
hour, markets = msgpack.unpackb(raw)          # every wallet, latest hour
mine, paid = set(open("wallets.txt").read().split()), {}
for coin, rate, users, amounts, sizes in markets:
    for u, amt in zip(users, amounts):
        if u in mine:
            paid[u] = paid.get(u, 0) + float(amt)
got = sum(v for v in paid.values() if v > 0)
print(len(paid), "wallets: received $", round(got), "paid $",
      round(got - sum(paid.values())))
code
93 wallets: received $ 12492 paid $ 3179

Side by side

Hyperliquid API Hydromancer API
Wallets coveredOnly the ones you listEvery wallet that paid or received
Worked1 of 1 runs3 of 3 runs
Time to finish (median)137 s0.6 s
Requests1001
Rate-limit cost2,221 weight (limit: 1,200 a minute per IP)1 download of the 5 allowed every 10 minutes
Data received over REST (uncompressed)1.1 MB8.6 MB

Same wallets, same hour, the same totals to the dollar (93 of the 100 had funding that hour). The Hyperliquid version took over two minutes and most of the minute's rate limit for 100 wallets. The Hydromancer file covers everyone: for one hour it held 417,549 payments to 139,564 wallets across 344 markets, with $100,731 changing hands. It's limited to 5 downloads every 10 minutes (rate limits), so fetch it once an hour. Without either, Hyperliquid's S3 archive (misc_events_by_block) has the raw funding events for everyone, which you download and add up yourself.

Charging for an "open trade" button

A scanner that only ranks rates sells as a subscription. Add a button that opens the trade, and your builder code earns on every order it routes. Price it with Step 5 in mind: each basis point you charge pushes your user's break-even further out. How builder fees fall across the four legs is in the delta-neutral bot guide.

Which API for which step

Take live rates, the Binance and Bybit comparison and rate history from Hyperliquid's free API. Reach for Hydromancer when the scanner needs to price a trade against a full day of liquidity, chart a user's income by the hour, or see every wallet's funding at once.

FAQ

What is funding rate arbitrage on Hyperliquid?

Holding two positions whose price moves cancel out, such as spot HYPE and a HYPE perp short, so you collect funding payments instead of betting on price.

Which Hyperliquid markets have the highest funding rates?

It changes every hour. The largest are usually HIP-3 markets with thin order books. Rank them all from one allDexsAssetCtxs message, then check liquidity before trusting the rate.

Can I compare Hyperliquid funding with Binance?

Yes. The official predictedFundings request returns Hyperliquid, Binance and Bybit rates side by side. Divide each by its payment interval before comparing.

How long does it take to cover fees?

At the base tier with taker orders on both legs, about 184 hours at the base rate of 0.00125% an hour. Higher rates, maker orders and fee discounts shorten it.

Is funding arbitrage risk-free?

No. Rates flip sign, the perp leg can be liquidated if its margin runs out, the two legs fill at different moments, and fees and slippage come off every trade.

• Hyperliquid funding rates: how they work
• How to build a delta-neutral bot on Hyperliquid
• Hyperliquid fees and revenue
• Hyperliquid builder codes
• Hyperliquid rate limits explained

Sources

- Hyperliquid docs: Funding, Fees, Builder codes, Info endpoint
- Hydromancer docs: slippageHistory, marketLiquidity, fundingPayments, fundingRates

Continue