The sol-kol-trades dataset is 1.5 million-plus KOL buy/sell rows (included with Business), and every single row carries price_usd_at_trade and market_cap_usd_at_trade stamped at the moment of execution, plus the tx_signature to anchor it. Coverage runs 2026-05-15 to present — the fully-priced era. That one design choice is what makes a real copy-trade backtest possible: because the price is recorded at execution, you can compute realized entry and exit PnL directly, with no price oracle to query and no look-ahead bias from back-filling historical prices. This post explains why at-trade pricing is the moat and walks a worked (illustrative) backtest end to end. Download the file at /datasets/sol-kol-trades.
Why at-trade pricing is the whole game
Most "KOL trade" exports are just wallet + token + timestamp + signature. To turn that into PnL you have to reconstruct the price at each trade — usually by hitting an oracle or a candle API keyed on the block time. Two problems ruin the result. First, oracle prices are pool-level and lag; for a low-liquidity memecoin at launch the "price" you back-fill can be wildly off the fill the KOL actually got. Second, and worse for research: if your price source has any smoothing or forward-fill, you leak future information into a past trade — classic look-ahead bias that makes a strategy look profitable in backtest and fail live.
sol-kol-trades removes both failure modes. The price and market cap are the values at the trade, captured when we parsed the swap — not a reconstruction. Your PnL is realized, not modeled. That is the difference between a backtest you can trust and a spreadsheet that flatters your idea.
What's in each row
| Column | Meaning |
|---|
wallet | Scrubbed KOL wallet key (pseudonymous, no name) |
token | Traded token mint |
side | Buy or sell |
price_usd_at_trade | USD price stamped at execution |
market_cap_usd_at_trade | Token market cap stamped at execution |
tx_signature | On-chain signature to verify the fill |
block_time | Trade timestamp |
Like every MadeOnSol dataset it ships as CSV.gz, is identity-scrubbed and wallet-keyed, SHA-256 checksummed, and comes with a free 5,000-row sample so you can validate the schema before buying.
A worked backtest (illustrative numbers)
The numbers below are hypothetical and for illustration only — they show the mechanics, not a promised return. The point is that with at-trade pricing, every step is arithmetic on columns you already have.
Strategy. Copy every KOL buy where market_cap_usd_at_trade is under $500k (early entries only), size each position at a flat $100, and exit when the same wallet sells the same token. Skip positions that never sell within the window.
Step 1 — match buys to sells. Group by wallet + token, order by block_time, and pair each buy with the wallet's next sell of that token. The tx_signature on each side lets you spot-check any pair on-chain.
Step 2 — compute per-trade return. For a matched pair, realized return is simply sell.price_usd_at_trade / buy.price_usd_at_trade - 1. No oracle call. Suppose a sample of 5,000 matched pairs produces a mean return of +18% and a median of −4% — a typical memecoin shape where a few large winners carry a mostly-losing distribution.
Step 3 — apply frictions. Subtract a realistic slippage-plus-fee haircut per side. If you assume 3% each way, the mean drops from +18% to roughly +11% and the win rate barely moves — the tail winners survive, the marginal ones don't.
Step 4 — aggregate. At $100 per position across 5,000 pairs ($500k deployed, ignoring turnover), an +11% net mean implies ~$55k of realized gain in this illustrative slice. The honest read is in the distribution, not the headline: check what share of total PnL comes from the top 1% of trades, because if it's most of it, your live results depend entirely on catching those specific launches.
Step 5 — segment. Because each row is wallet-keyed, re-run the whole thing per wallet to find which KOLs actually produce copyable edge versus which just trade a lot. This is where the dataset earns its price — you are grading signal sources, not guessing.
Guard against the obvious traps
Two things separate a backtest you can act on from one that lies to you. First, survivorship: if you only pair buys that eventually sold, you silently drop every position a KOL is still bagholding — often the losers. Decide up front how to treat open positions (mark to a cutoff price, or exclude them consistently) rather than letting the join quietly do it for you. Second, latency: a live copy-trader never fills at the KOL's exact price. Add a delay-and-slippage assumption to your entry — the market cap at trade tells you how thin the token was, so scale the haircut with size. Both adjustments push the illustrative +11% down, which is the point: the priced data lets you model the friction honestly instead of pretending it away.
Filter the wallets first
A copy-trade backtest is only as good as the wallets you copy. Pair this file with the sol-smart-money dataset to pre-filter for wallets with a real sample size and a low bot signal before you copy them — copying a bot's fills makes you its exit liquidity, not its peer. For the on-site mechanics of building a copy-trade bot and how KOL wallets are tracked in the first place, see the copy-trade bot tutorial and the KOL-tracking methodology across 1,069 wallets. This dataset is the frozen, priced version of that same tracking — the full datasets hub has the other three sets.
FAQ
How many KOL trades are in the dataset?
sol-kol-trades contains more than 1.5 million KOL buy and sell rows, covering the fully-priced era from 2026-05-15 to present. Each row includes the transaction signature.
Why does at-trade pricing matter for a backtest?
Because price_usd_at_trade and market_cap_usd_at_trade are recorded at the moment of execution, you compute realized PnL as pure arithmetic on the columns — no external price oracle, and no look-ahead bias from back-filled prices that would make a strategy look better than it is.
Can I verify the trades are real?
Yes. Every row carries the on-chain tx_signature, so any buy/sell pair in your backtest can be checked against Solana directly.
What sizing should I use in the example?
The worked example uses a flat $100 per position purely for illustration; the returns quoted are hypothetical and demonstrate the calculation, not an expected result. Substitute your own sizing and frictions.
Do I need a live API for this?