get_top_traders
Retrieve top Polymarket traders ranked by realized P&L, win rate, or volume. Filter by minimum trades and limit results.
Instructions
Get the top Polymarket traders ranked by realized P&L, win rate, or volume from the Beefy P&L subgraph.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| first | No | Number of traders to return (1-100) | |
| orderBy | No | Metric to rank traders by | totalRealizedPnl |
| minTrades | No | Minimum number of trades to filter out inactive accounts |
Implementation Reference
- src/index.ts:472-543 (registration)Registration of the 'get_top_traders' tool via server.registerTool with name 'get_top_traders'.
// Tool 11: get_top_traders // --------------------------------------------------------------------------- server.registerTool( "get_top_traders", { description: "Get the top Polymarket traders ranked by realized P&L, win rate, or volume from the Beefy P&L subgraph.", inputSchema: { first: z.number().min(1).max(100).default(10).describe("Number of traders to return (1-100)"), orderBy: z .enum(["totalRealizedPnl", "collateralVolume", "winRate", "profitFactor", "numTrades"]) .default("totalRealizedPnl") .describe("Metric to rank traders by"), minTrades: z .number() .min(1) .default(10) .describe("Minimum number of trades to filter out inactive accounts"), }, }, async ({ first, orderBy, minTrades }) => { try { const beefyQuery = `{ accounts( first: ${first}, orderBy: ${orderBy}, orderDirection: desc, where: { numTrades_gte: "${minTrades}" } ) { id numTrades collateralVolume totalRealizedPnl totalUnrealizedPnl totalFeesPaid winRate profitFactor maxDrawdown numWinningPositions numLosingPositions lastTradedTimestamp } }`; // Fetch top OB-volume accounts to surface OB-only traders absent from Beefy rankings const obQuery = `{ accounts(first: ${first}, orderBy: totalVolume, orderDirection: desc) { id totalVolume tradesQuantity } }`; const [beefyData, obData] = await Promise.all([ querySubgraph(SUBGRAPHS.beefy_pnl.ipfsHash, beefyQuery), querySubgraph(SUBGRAPHS.orderbook.ipfsHash, obQuery).catch(() => null), ]); const bd = beefyData as { accounts?: Array<{ id: string; collateralVolume?: string }> }; const od = obData as { accounts?: Array<{ id: string; totalVolume: string; tradesQuantity: string }> } | null; const beefyIds = new Set((bd.accounts ?? []).map((a) => a.id)); const obById = new Map((od?.accounts ?? []).map((a) => [a.id, a])); // Flag beefy rows where OB-tracked volume significantly exceeds Beefy-tracked volume const annotated = (bd.accounts ?? []).map((a) => { const ob = obById.get(a.id); const beefyVol = parseFloat(a.collateralVolume || "0"); const obVol = ob ? parseFloat(ob.totalVolume) : null; const flag = obVol !== null && obVol > beefyVol * 1.5 && obVol - beefyVol > 1000 ? `⚠ OB volume ($${obVol.toFixed(0)}) exceeds Beefy-tracked volume ($${beefyVol.toFixed(0)}) — P&L ranking may be incomplete` : undefined; return { ...a, ...(flag ? { reliabilityWarning: flag } : {}) }; }); // Surface high-volume OB traders completely absent from Beefy leaderboard const obOnlyTraders = (od?.accounts ?? []) .filter((a) => !beefyIds.has(a.id)) .map((a) => ({ address: a.id, obVolume: a.totalVolume, obTrades: a.tradesQuantity, note: "not tracked by Beefy P&L subgraph — P&L unavailable" })); return textResult({ traders: annotated, ...(obOnlyTraders.length > 0 ? { obOnlyTradersNotInLeaderboard: obOnlyTraders } : {}), }); } catch (error) { return errorResult(error); } } ); - src/index.ts:492-543 (handler)Handler function for get_top_traders. Queries the Beefy P&L subgraph for top traders ranked by totalRealizedPnl (or other metrics), cross-references with Orderbook subgraph to detect OB-only traders and flag incomplete P&L rankings.
async ({ first, orderBy, minTrades }) => { try { const beefyQuery = `{ accounts( first: ${first}, orderBy: ${orderBy}, orderDirection: desc, where: { numTrades_gte: "${minTrades}" } ) { id numTrades collateralVolume totalRealizedPnl totalUnrealizedPnl totalFeesPaid winRate profitFactor maxDrawdown numWinningPositions numLosingPositions lastTradedTimestamp } }`; // Fetch top OB-volume accounts to surface OB-only traders absent from Beefy rankings const obQuery = `{ accounts(first: ${first}, orderBy: totalVolume, orderDirection: desc) { id totalVolume tradesQuantity } }`; const [beefyData, obData] = await Promise.all([ querySubgraph(SUBGRAPHS.beefy_pnl.ipfsHash, beefyQuery), querySubgraph(SUBGRAPHS.orderbook.ipfsHash, obQuery).catch(() => null), ]); const bd = beefyData as { accounts?: Array<{ id: string; collateralVolume?: string }> }; const od = obData as { accounts?: Array<{ id: string; totalVolume: string; tradesQuantity: string }> } | null; const beefyIds = new Set((bd.accounts ?? []).map((a) => a.id)); const obById = new Map((od?.accounts ?? []).map((a) => [a.id, a])); // Flag beefy rows where OB-tracked volume significantly exceeds Beefy-tracked volume const annotated = (bd.accounts ?? []).map((a) => { const ob = obById.get(a.id); const beefyVol = parseFloat(a.collateralVolume || "0"); const obVol = ob ? parseFloat(ob.totalVolume) : null; const flag = obVol !== null && obVol > beefyVol * 1.5 && obVol - beefyVol > 1000 ? `⚠ OB volume ($${obVol.toFixed(0)}) exceeds Beefy-tracked volume ($${beefyVol.toFixed(0)}) — P&L ranking may be incomplete` : undefined; return { ...a, ...(flag ? { reliabilityWarning: flag } : {}) }; }); // Surface high-volume OB traders completely absent from Beefy leaderboard const obOnlyTraders = (od?.accounts ?? []) .filter((a) => !beefyIds.has(a.id)) .map((a) => ({ address: a.id, obVolume: a.totalVolume, obTrades: a.tradesQuantity, note: "not tracked by Beefy P&L subgraph — P&L unavailable" })); return textResult({ traders: annotated, ...(obOnlyTraders.length > 0 ? { obOnlyTradersNotInLeaderboard: obOnlyTraders } : {}), }); } catch (error) { return errorResult(error); } } ); - src/index.ts:479-491 (schema)Input schema for get_top_traders: 'first' (1-100, default 10), 'orderBy' (enum of metrics like totalRealizedPnl, collateralVolume, winRate, profitFactor, numTrades), and 'minTrades' (minimum trade count filter, default 10).
inputSchema: { first: z.number().min(1).max(100).default(10).describe("Number of traders to return (1-100)"), orderBy: z .enum(["totalRealizedPnl", "collateralVolume", "winRate", "profitFactor", "numTrades"]) .default("totalRealizedPnl") .describe("Metric to rank traders by"), minTrades: z .number() .min(1) .default(10) .describe("Minimum number of trades to filter out inactive accounts"), }, },