> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ballista.gg/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Ballista is a trading client for Polymarket, not an exchange. Every order Ballista places goes to Polymarket's CLOB.
> There are three end-user surfaces — the Telegram bot, the web terminal and the Chrome extension — and they share ONE account and ONE balance. Never attribute a feature to a surface without checking that surface's source.
> Every user registers in the Telegram bot first. The terminal and the extension sign in with the Telegram login widget. There is no other sign-up path.
> Deposits arrive through EVM, Solana and Bitcoin bridge addresses and a Polymarket proxy wallet, with a $10 minimum. There is NO withdrawal UI — Export Keys is how a user takes custody of their funds.
> Feature parity is uneven and must never be assumed. The full ~30-field copy-trade form exists only in Telegram; the terminal's copy form has 7 fields; the backtester, leaderboard and trader profiles are terminal-only; alerts and notifications are extension-only; referrals are Telegram-only.
> Slippage means two different things. On a live copy trade it is a fill tolerance (default 30). In a backtest it is the simulated fill price (default 1). Deploying a backtest does not carry its slippage over to the live copy trade.
> Take-profit and stop-loss run on live copy trades but are NOT simulated in backtests — the backtest API rejects those fields.
> A backtest never places an order and never moves funds. Its fidelity caveats are published with every result and must be quoted, not paraphrased.
> Leaderboard PnL is own-tape: harvested by Ballista from its own trade tape. The leaderboard sorts by one transparent metric at a time and there is NO composite score or grade. The sparkline exists only for harvested wallets — a blank sparkline means unmeasured, never zero.
> Copy friction (slip) and a toxic flag DO exist and are own-engine: the wallet's own 30-day fills replayed as a taker (1% slippage per fill plus the real Polymarket taker fee schedule) against its actual 30-day PnL over the same fills, so the delta is pure friction. slip_pct is already a percentage, not a 0-1 fraction. The toxic flag is server-computed under evidence guards and is never re-derived client-side. Slip is not a sortable column. Blank means unmeasured — never zero and never clean.
> Copyability is a taker share, reported in aggressive (≥60%), passive (≤30%) and mixed bands. It is never a score.
> Do not document Feeds, the Twitter Tracker, the Telegram Settings button, percentage buy buttons, GTD orders, the Discord bot, or withdrawals.

# The leaderboard

> Who appears on the board, what it ranks on, and why a blank cell is never a zero.

The leaderboard is a list of Polymarket wallets Ballista maintains statistics for,
sorted by one metric at a time. It lives in the
[web terminal](/terminal/leaderboard); rows open a
[trader profile](/guides/trader-profiles).

## Who appears

A wallet is on the board when both of these hold:

* **It is in the maintained universe.** Wallets enter it from a leaderboard page
  published by Ballista's market-data provider, from Ballista's own live trade feed,
  or by being added by hand — a pasted address or a wallet somebody backtested. A
  wallet that rotates out keeps its row and its history but stops being a candidate to
  copy.
* **It has traded recently.** The activity filter is applied on the server and cannot
  be switched off. The terminal offers **7, 30 or 90 days**, defaulting to 30.

"Recently" means the newer of two things: the last fill in the trade tape Ballista
holds, and the last time Ballista's own live feed saw the wallet trade. The tape is
authoritative but only as current as the wallet's turn in the harvest queue; the feed
is instant.

<Info>
  **Small active traders are found too.** A provider leaderboard ranks lifetime P\&L,
  so it cannot see a wallet that started printing last month, and Ballista's own feed
  notices any wallet trading in modest size rather than only the whales. A wallet
  found that way arrives **unranked**, in a reserved pool that cannot displace a
  measured wallet, and becomes rankable once the harvest has measured a 30-day P\&L
  for it — the same bar every other candidate clears. The funnel is wider; the
  quality gate is not lower.
</Info>

<Note>
  A wallet with **no recorded activity at all** fails the filter. "We have never
  established that this wallet is active" is not "this wallet is active", and
  admitting unknowns would put the entire unmeasured tail of the universe onto a
  board that promises recency.
</Note>

90 days is the ceiling, because the board's recent-performance columns look back 30
days at most — past that, a wider filter only re-admits wallets that nothing else in
the row describes.

## What it ranks on

**One transparent metric at a time.** There is no composite score, no weighted blend
and no proprietary index. You pick a column, the row carries the value that column
was sorted on, and a wallet's position is always explainable from what is on screen.

The sortable columns are:

| Column            | What it is                                                                                                                                                           |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **30d P\&L**      | Realized P\&L over the last 30 days. **The default sort.**                                                                                                           |
| **7d P\&L**       | Realized P\&L over the last 7 days.                                                                                                                                  |
| **Last active**   | When the wallet last traded.                                                                                                                                         |
| **Realized P\&L** | Lifetime, settled markets only.                                                                                                                                      |
| **Total P\&L**    | Lifetime, realized plus unrealized.                                                                                                                                  |
| **Win rate**      | Wins over settled markets. Blank for a wallet that has settled nothing — zero would read as "loses everything".                                                      |
| **Profit factor** | Gross profit over gross loss. Blank when there are no losses to divide by; a wallet that has never lost has no finite profit factor and Ballista will not print one. |
| **Volume**        | Lifetime notional.                                                                                                                                                   |

Every one is more-is-better, so a newly clicked column starts descending.

### Why the default is 30-day P\&L

It used to be lifetime realized P\&L, which led the board with wallets that made tens
of millions two years ago and have been idle or bleeding since — a number nobody can
follow into a trade. Lifetime realized P\&L is still a column, and it still breaks
ties in the rank, but it is no longer the first thing the board answers with.

<Info>
  The **#** column is a maintained rank on 30-day P\&L, not the row order. Sort by
  anything else and it will not run in sequence — that is expected.
</Info>

## Where the numbers come from

The recent-performance block — 30-day P\&L, 7-day P\&L and the trend line — is computed
from **trade tape Ballista harvests itself**, settled the way the backtester settles.
It is not an upstream P\&L feed. Positions still open are not in it, so these are
realized figures over the window.

The **30d trend** sparkline is cumulative P\&L over the last 30 days, one point per UTC
day, from that same tape. It appears on the leaderboard row and on the trader profile,
and only for wallets whose tape has been harvested.

## Copy friction on the board

Two more columns describe what copying a wallet would cost rather than what it earned.

The **Slip** column is the share of the wallet's own 30-day profit that copy friction —
1% slippage per fill plus the real taker fee schedule — would take, measured by
replaying its own fills over the same markets its 30-day P\&L is computed from. The
value is already a percentage.

Beside the wallet, a **toxic** badge marks a measured wallet that loses 25% or more of
its recent profit to that friction. It is a server-side verdict, and it appears only
for a wallet that was both measured and judged — never derived from the number in the
Slip cell.

[Choosing a trader](/guides/choosing-a-trader) explains the measurement, the guards
behind a blank, and what to do about a toxic wallet.

<Note>
  **Slip is not sortable**, deliberately. It is blank for most of the board until
  those wallets' recent markets settle, and ordering a board by a column two rows in
  three have no value for would rank the measured against the unmeasured. The same
  applies to the rank, wallet, trend, positions and taker-share columns: a column with
  no server-side sort key is not clickable rather than clickable and quietly wrong.
</Note>

## Blank is not zero

Every statistic on the board can legitimately be unmeasured, and a dash always means
unmeasured rather than nil.

| What you see                    | What it means                                                                                                                                                                                                                                                                                                 |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **harvesting recent activity…** | The wallet is genuinely active — the feed just saw it trade — but the tape sweep has not reached it yet. This resolves on its own; nothing here is zero.                                                                                                                                                      |
| **—** in a lifetime column      | The wallet is registered but no refresh sweep has produced that number yet.                                                                                                                                                                                                                                   |
| **—** in the Taker column       | No tape has been harvested for this wallet yet. The sweep gets to board wallets on its own, but [running a backtest](/guides/backtesting) harvests one immediately. It can also mean a tape *is* held and carries no notional to weigh — the [trader profile](/guides/trader-profiles) distinguishes the two. |
| **—** in the Slip column        | The friction measurement has not been published for this wallet — either its tape has not been swept, or one of the evidence guards fired. It is not zero and it is not clean. The [trader profile](/guides/trader-profiles) names which.                                                                     |
| **no toxic badge**              | Either the wallet was measured and came out under the threshold, or it was never measured. The absence of a badge is not a clean bill of health; the Slip cell is what tells you which case you are in.                                                                                                       |
| **—** where the trend line goes | Either no tape, or a stored series Ballista no longer stands behind and will not draw.                                                                                                                                                                                                                        |

The sweep walks the whole universe and re-harvests a wallet's tape about **once a
day**, so a blank on a board wallet usually fills itself in without you doing
anything. Viewing a trader's profile never starts a harvest; running a backtest on one
does, straight away.

## Filters

Beyond the activity window, three optional floors narrow the board:

* **Min P\&L** — a floor on *total* P\&L. May be negative; "show me everyone above
  −1000" is a real query.
* **Min volume** — a floor on lifetime volume. Must not be negative.
* **Min positions** — a floor on position count. A whole number, not negative.

Fifty rows per page. The board carries no total count, so "is there a next page" is
answered by whether a full page came back. The whole view — sort, order, window,
filters, page — lives in the URL, so a link reproduces exactly what was on screen.

<Note>
  Every column on this board stands on its own. There is no overall grade and no
  composite score anywhere on it — a blended number would bury the disagreement
  between two columns, such as a large 30-day P\&L next to a toxic slip rate, which is
  the most useful thing the board can show you.
</Note>

## What to read next

<CardGroup cols={2}>
  <Card title="Trader profiles" icon="id-card" href="/guides/trader-profiles">
    What a row expands into.
  </Card>

  <Card title="Choosing a trader" icon="magnifying-glass-chart" href="/guides/choosing-a-trader">
    Whether a wallet at the top of the board can be copied at all.
  </Card>

  <Card title="Backtesting" icon="flask" href="/guides/backtesting">
    Test a candidate against your own configuration.
  </Card>

  <Card title="The leaderboard screen" icon="ranking-star" href="/terminal/leaderboard">
    Using it in the terminal.
  </Card>
</CardGroup>
