The first metric everyone reaches for when evaluating a Solana KOL is winrate. It's intuitive — what percentage of their trades closed in profit? — and it's how most leaderboards rank wallets by default. But on a memecoin chart, winrate alone is a terrible predictor of whether copy-trading a wallet will make you money.
Consider two KOLs over the same 30-day window:
- Wallet A: 75% winrate, average winning trade +20%, average losing trade −60%.
- Wallet B: 45% winrate, average winning trade +180%, average losing trade −35%.
Wallet A wins more often but is mathematically a money-loser: 75% × 20% − 25% × 60% = −0%. Wallet B wins less than half the time but expects 45% × 180% − 55% × 35% = +62% per trade. If you ranked by winrate, you'd pick A; if you ranked by P&L outcome, you'd pick B. Memecoin trading lives in this regime — fat-tailed wins, asymmetric losses — and winrate is the wrong default.
The MadeOnSol KOL leaderboard exposes two metrics that fix this: profit factor and percentile rank. This post walks through what each measures, when to use which, and a worked-example wallet filter that beats sort=winrate.
Profit factor: the simplest sound metric
Profit factor is the ratio of total gains to total losses:
profit_factor = SUM(positive_trade_pnl) / |SUM(negative_trade_pnl)|
A profit factor of 1.0 means gains equal losses (break-even). 1.5 means gains are 1.5× losses (net positive). Above 2.0 is genuinely strong. Below 1.0 is a money-losing wallet, regardless of winrate.
It's the right starting metric for memecoin trading because it folds win/loss frequency AND win/loss size into one number. A 75% winrate wallet with profit factor of 0.95 is losing money; a 40% winrate wallet with profit factor of 2.3 is making money. The single number tells you which.
The MadeOnSol API serves profit_factor_7d and profit_factor_30d on every wallet in mv_kol_scores, exposed on the leaderboard, single-wallet profiles, and comparison endpoints:
curl -H "Authorization: Bearer msk_..." \
"https://madeonsol.com/api/v1/kol/leaderboard?period=30d&sort=profit_factor&limit=20"
That sorts the 30-day window's wallets by profit factor descending — the natural "best KOLs to follow" ranking. Typical wallets at the top of that list have profit factors between 1.8 and 3.5; anything above 4 is suspicious enough to inspect manually (likely small sample or one outlier trade carrying everything).
Percentile rank: how good is a wallet vs the peer group?
A profit factor of 2.1 sounds good in absolute terms. The harder question: how does it compare to the rest of the KOL universe?
That's what percentile ranks answer. The leaderboard returns four percentile fields per wallet:
{
"name": "@somealpha",
"wallet": "AbCdEf...",
"win_rate": 64.2,
"profit_factor": 2.41,
"percentile_pnl_7d": 91,
"percentile_winrate_7d": 78,
"percentile_pnl_30d": 88,
"percentile_winrate_30d": 72
}
A percentile_pnl_30d of 88 means: this wallet sits at the 88th percentile for 30-day P&L across all scored wallets — better than 88% of the peer group.
The four-field shape lets you read both axes at both timeframes:
percentile_pnl_* — where they rank by total PnL outcome.
percentile_winrate_* — where they rank by winrate.
- 7d vs 30d — short-term form vs longer-term consistency.
A wallet at the 90th percentile on both PnL and winrate across both windows is genuinely top-quartile. A wallet at 90 PnL / 30 winrate is a fat-tailed gambler — they made money but on a few outlier wins. A wallet at 30 PnL / 90 winrate is the inverse — they win often but lose more when they lose.
For copy-trading, the right pattern depends on your own risk tolerance:
- Risk-tolerant — follow the high-
percentile_pnl_*, ignore winrate. You're buying their best trade outcome.
- Risk-averse — require both percentile_pnl AND percentile_winrate to be high. You want consistent grinders, not outlier hits.
- Diversified portfolio — mix both styles, weighted appropriately.
Worked example: a quality wallet filter
Suppose you want a tight set of wallets for a copy-trade pipeline: high profit factor, top-quartile in both PnL and winrate, with enough trading activity to be statistically meaningful.
import { MadeOnSol } from "madeonsol";
const client = new MadeOnSol({ apiKey: process.env.MADEONSOL_API_KEY! });
async function qualityWallets() {
// Pull leaderboard sorted by profit factor; filter on percentile + activity
const res = await client.kol.leaderboard({
period: "30d",
sort: "profit_factor",
min_winrate: 40, // floor — don't follow sub-40% wallets even if profit factor is high
limit: 50,
});
return res.leaderboard.filter((k) => {
if ((k.profit_factor ?? 0) < 1.8) return false;
if ((k.percentile_pnl_30d ?? 0) < 75) return false;
if ((k.percentile_winrate_30d ?? 0) < 65) return false;
if (k.is_cold) return false;
return true;
});
}
The filter combines four signals: profit factor ≥ 1.8, PnL percentile ≥ 75, winrate percentile ≥ 65, and an activity flag (is_cold === false). On a typical day this returns 8-15 wallets — small enough to manually inspect, large enough to diversify across. Once you have a quality wallet set like this, wiring it into an autonomous trader is straightforward — we show one in build an AI agent that buys Solana KOL signals in 20 lines of Python.
Compare to the naive sort=winrate ranking which surfaces some grinders with 70%+ winrate and profit factor of 0.9 — wallets that look elite on the surface and are actually break-even or worse.
The is_heating_up / is_cold activity flags
Two boolean fields on mv_kol_scores filter on activity recency, not skill:
is_heating_up — the wallet's recent activity rate is meaningfully higher than its baseline. They've increased trading frequency in the last few days.
is_cold — the wallet has not traded recently relative to its history. Could be deliberate (taking a break) or could mean they've moved to a different wallet.
Use these as a complementary filter to skill metrics. A high-profit-factor wallet with is_cold: true may have stopped trading entirely — copying them gives you no signal. Conversely, is_heating_up: true on a high-skill wallet often precedes a productive run.
Why two windows matter
profit_factor_7d and profit_factor_30d (and the equivalent percentile fields) answer different questions.
- 7d captures current form. A wallet hot for the last week. Tighter sample, noisier.
- 30d captures sustained skill. Bigger sample, smoother. Less reactive to current memecoin meta.