How to Build a Trading Journal for Hyperliquid
Build a Hyperliquid trading journal: turn fills into closed trades with entry, exit, fees, funding and hold time, and keep history past 10,000 fills.

A trading journal answers the questions a trader asks after the fact: which trades made money, how long did I hold the winners, what did fees and funding cost me, do I trade worse on Mondays.
Why traders keep one:
• To find out what actually works. Memory flatters; a record shows which setups made money.
• To spot bad habits, like holding losers too long or overtrading after a loss.
• To see the real cost of trading. Fees and funding quietly eat into profit.
• To stay accountable to a plan, with a note on why each trade was taken.
Most journal apps make you import a CSV from your exchange. On Hyperliquid, every trade is on-chain, so a journal can fill itself in from a wallet address.
Why should you choose to build a trading journal on Hyperliquid?
• Every trader asks these questions. Few can answer them from their trade history.
• Trade history lists fills, not trades. A position closed in 30 pieces is 30 rows. One busy wallet in our test made 15,414 fills in 12 days, which added up to 66 trades. Nobody reviews that by hand.
• No CSV, no API key. Every Hyperliquid trade is public, so your journal needs only a wallet address.
• It's easy to try. A trader pastes an address and sees their trades in seconds, which makes the journal easy to put in front of people.
• It can earn two ways. Charge a subscription, or make it the review tab of a trading app whose orders carry your builder code.
Getting a wallet's raw fills is covered in our trade history guide. Here the focus is the journal itself: turning fills into trades, and keeping the history long enough to be useful.
How we tested. We gave both APIs the same job on 31 October 2026: take one busy wallet and turn its last 90 days into a list of closed trades. Each code block is the full prototype.
The unit of a journal is a trade, not a fill
A fill is one piece of an order. One position can take hundreds: one ZEC short we looked at closed after 193 fills. A journal row should be the whole position: opened, added to, closed.
Hyperliquid API
You build trades yourself from fills. The prototype pages back through the wallet's fills with userFillsByTime (2,000 per page), then counts a trade as closed each time the position returns to zero or flips side, using startPosition, the size before each fill:
import time, requests
USER = "0xda3768e9299e1fd81708ec030dac5ea37125f7b5"
start, fills, page = int(time.time() * 1000) - 90 * 86400000, {}, [0] * 2000
while len(page) == 2000:
page = requests.post("https://api.hyperliquid.xyz/info", json={
"type": "userFillsByTime", "user": USER, "startTime": start}).json()
fills.update({(f["time"], f["tid"]): f for f in page})
start = page[-1]["time"]
def ends(f): # a trade ends when size hits 0 or flips
b = float(f["startPosition"])
a = b + float(f["sz"]) * (1 if f["side"] == "B" else -1)
return b != 0 and (abs(a) < 1e-9 or a * b < 0)
print(len(fills), "fills since", time.ctime(min(fills)[0] / 1000), "/",
sum(map(ends, fills.values())), "closed trades")15414 fills since Mon Oct 19 08:25:27 2026 / 66 closed tradesThe counting works: over the 10 days both APIs covered, it found exactly the same 48 closed trades as Hydromancer. The history doesn't. Asked for 90 days, Hyperliquid stopped 12 days back, after 15,414 fills. Its docs say fill requests reach the 10,000 most recent fills; across five wallets we tested, the real reach ran from 12,101 to more than 78,000 fills. For a busy trader, that's still only days or weeks. The day where it stopped came back short too: 717 fills that day, against more than 2,000 on Hydromancer.
For a full journal row you also add up closedPnl and fee per trade and match funding from userFunding by time.
Hydromancer API
userCompletedTradesByTime returns each closed position as one row, with entry and exit price, size, leverage, fees, funding, net PnL, hold time, maker fills and the builder that closed it. The prototype pages until it has 90 days:
import os, time, requests
H = {"Authorization": "Bearer " + os.environ["HYDROMANCER_API_KEY"]}
body = {"type": "userCompletedTradesByTime", "limit": 500,
"user": "0xda3768e9299e1fd81708ec030dac5ea37125f7b5",
"startTime": int(time.time() * 1000) - 90 * 86400000}
trades, page = [], [None] * 500
while len(page) == 500:
page = requests.post("https://api.hydromancer.xyz/info", headers=H,
json=body).json()
trades += page
body["cursor"] = f"{page[-1]['close_time']}_{page[-1]['tx_index']}"
wins = sum(float(t["net_pnl"]) > 0 for t in trades)
print(len(trades), "closed trades in 90 days,", wins, "winners")416 closed trades in 90 days, 214 winnersSide by side
| Hyperliquid API | Hydromancer API | |
|---|---|---|
| History returned (asked for 90 days) | 12 days | 90 days |
| Closed trades | 66, rebuilt from 15,414 fills | 416, one row each |
| Worked | 2 of 2 runs | 3 of 3 runs |
| Time to finish (median) | 2.9 s | 0.2 s |
| Requests | 8 | 1 |
| Rate-limit cost | 931 weight (limit: 1,200 a minute per IP) | 20 points (limit: 20,000 a minute on the Growth plan) |
| Data received over REST (uncompressed) | 5.8 MB | 0.2 MB |
A journal that only remembers the last 12 days can't answer "do I trade worse on Mondays?". Hydromancer's history starts on 28 July 2025 and covers most traders, but leaves out some very high-volume addresses, so check the counts for your heaviest users.
Other ways to keep history
For a light trader, Hyperliquid's reach is plenty: tens of thousands of fills can be years. Check how often your users trade before deciding. Two more ways to keep a full record:
• Record it yourself. Once a user connects, store their fills as they happen from the userFills stream. You never lose anything after that day, but you can't go back before it.
• Download the archives. Hyperliquid's S3 archive (node_fills_by_block) has every fill, which you index yourself. Reservoir, Hydromancer's free archive, has daily fill files for every wallet from August 2025. Both come through AWS S3, so you need an AWS account and pay the download charges. See how to query Reservoir, which includes pulling one wallet's full history.
What to put on the journal page
Here's what that wallet's last 90 days looked like in a later pull, straight from those trade rows (413 trades, as the 90-day window had moved since the test above):
| Metric | Value |
|---|---|
| Closed trades | 413 |
| Winners | 216 (52.3%) |
| Average win / average loss | +$20,447 / -$17,884 |
| Median hold, winners / losers | 7.3 hours / 22.0 hours |
| Fees paid / funding earned | $13,607 / +$429,395 |
| Net PnL | +$893,342 |
Two things a journal would point out to this trader. Losing trades were held about three times longer than winning ones, the classic "letting losers run". And funding earned was almost half of the net profit, so the edge wasn't only in the entries.
From one row per trade you can build: win rate, average win vs average loss, PnL by coin, by weekday and by hour, hold time of winners vs losers, fees and funding as a share of PnL, leverage used, and maker vs taker share (each trade row counts its maker fills). Let users tag trades with a setup name and a note, then group by tag: that's what turns a history into a strategy review. Show realized PnL from closed trades and label it as such; open positions belong on a separate "now" panel.
A journal on its own sends no orders, so it sells as a subscription. Put it inside a trading app as the "review" tab instead, and the trades users place after reviewing can carry your builder code.
FAQ
Can I build a Hyperliquid trading journal without the user's keys?
Yes. All trades are public, so a wallet address is enough. Ask users to sign a message if you want to prove the wallet is theirs.
How far back does Hyperliquid's API go for my trades?
Count fills, not days. A quiet wallet's recent-fills window can hold years of trading; the busy wallet in our test ran out after 12 days. Past that, use one of the three routes above.
How do I turn fills into trades?
Follow startPosition, the size before each fill: a trade closes when the position returns to zero or flips side. Our prototype did this on Hyperliquid's fills and matched Hydromancer's completed trades exactly. Hydromancer's completed-trades requests do it for you.
Related reading
• How to get a Hyperliquid wallet's trade history
• How to query Reservoir's Hyperliquid data
• Hyperliquid funding rates
• Hyperliquid fees and revenue
Sources
- Hyperliquid docs: Info endpoint
- Hydromancer docs: userCompletedTradesByTime, userFillsByTime, Reservoir
Read next

How to Build a Hyperliquid TWAP Execution Tool
Build a TWAP execution tool on Hyperliquid: native TWAP orders vs your own slicing, tracking slice fills, and seeing every active TWAP in a market.

How to Build a Trading Terminal on Hyperliquid
Build a Hyperliquid trading terminal: charts, order book, trades and order entry, plus 1-second candles and older chart history. Tested on both APIs.

How to Run a Trading Competition on Hyperliquid
Run a Hyperliquid trading competition: register wallets, score PnL over your own start and end time, filter out cheating, and track it live. Tested.