> ## 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.

# Backtesting

> Replay a leader's real trades through your copy-trade configuration, before you point real money at it.

A backtest takes one wallet's **actual trade history** and replays it through **your
copy-trade configuration**, then tells you what that configuration would have done.

<Info>
  A backtest never places an order and never moves funds. It reads a tape and does
  arithmetic. Nothing you do in the backtester touches your Polymarket account.
</Info>

The backtester lives in the [web terminal](/terminal/backtester).

## What you configure

### The run

| Field                | Notes                                                                                                                                                                                                                                                                                                                                                                                                                            |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Target wallet**    | The leader whose history is replayed.                                                                                                                                                                                                                                                                                                                                                                                            |
| **Starting capital** | The simulated account's opening cash, spent down and topped back up as positions close. It does **not** scale your orders — sizing is a percentage of the leader's trade or a fixed USDC amount either way, and spend caps are absolute figures. What it decides is **affordability**: orders your filters admitted but the cash could not cover are reported as the run's *missed amount*. There is no margin and no borrowing. |
| **Window**           | Entered as "the last N days" — 7, 14, 30, 60, 90 or 180. **180 days is the hard ceiling**, because window width drives how much tape has to be fetched, which is the expensive part of a run. A window ending in the future is refused.                                                                                                                                                                                          |

### The strategy

The strategy half of the form is the **deployable subset of a copy trade**: sizing,
sides, reverse copy, the price and value bands, the per-trade bounds, the spend caps
and the market gates. The field names and the accepted ranges are identical to the
live form, on purpose: a configuration that backtests must be one you can **save** as
a copy trade without editing it. Each is documented in
[Copy trade settings](/guides/copy-trade-settings).

That is a promise about the form, not about the outcome. The same numbers do not
always *behave* the same live — slippage inverts, decisions are made per fill rather
than per swept order, and spend caps revolve in the simulator but not live. See
[Backtest fidelity](/guides/backtest-fidelity) before you deploy one.

Four controls are **simulation-only** and have no copy-trade equivalent. The form
badges them, and a result names the ones the run actually engaged:

* **Starting capital**
* **Category allowlist**
* **Required keywords** and **excluded keywords** (matched against the market)

### Slippage means something different here

In a live copy trade, slippage is a **tolerance**: how far the book may have moved and
still fill you. In the backtester it is a **cost**: the fill is booked at a worse
price, and it always happens.

Because of that, the backtester defaults to **1%**, not the live default of 30. A run
left at 30 would charge a 30% haircut on every single fill — on one measured wallet,
that one substitution accounted for around 85% of the gap between a reported −$788k
and the +$2.09M the same tape produces at a realistic cost.

An explicit **0** is a real setting and is honoured: fills are priced at the leader's
own price. It does not mean "unset".

<Warning>
  Deploying a backtested configuration as a live copy trade **deliberately does not
  carry the slippage over**. Carrying a 1% simulated cost across as a 1% live
  tolerance would silently turn a validated configuration into one that rejects most
  of the fills it was validated on. The deploy leaves both fields blank and the live
  default of 30 stands.
</Warning>

### What the backtester refuses

Take-profit, stop-loss and balance-level TP/SL cannot be submitted. All six arm
against a continuous price path between fills, and a tape only has prices at the
leader's own fills.

They are **rejected, not ignored**. A request carrying `sl_percentage` comes back as
an error rather than a result that reads "your stop-loss strategy made money" for a
simulation that never had a stop-loss. The same guard catches a misspelled field
name, which would otherwise run the whole simulation at the wrong size.

## The queue

Runs are queued, not executed inline.

<Steps>
  <Step title="Queued">
    You may hold **two pending-or-running backtests at a time**. Submitting a third
    is refused with a message saying so — the only thing that clears it is one of
    your own runs finishing.
  </Step>

  <Step title="Fetching the leader's trade tape">
    The slow part. A full tape is pulled page by page from an upstream with an
    account-wide rate limit that live copy trading also spends. This is why a run
    takes minutes and why a page view will never start one for you.
  </Step>

  <Step title="Loading market metadata and resolutions">
    Every market the leader touched has to be priced and, where it resolved, settled.
  </Step>

  <Step title="Simulating your configuration against the tape">
    Your filters, sizing and caps, fill by fill.
  </Step>
</Steps>

The run page shows the stage and a progress percentage while it works, and you can
leave and come back — the run is not tied to your browser.

<Note>
  Submitting a configuration **identical** to one already queued or running reopens
  that run instead of starting a second: it is the same deterministic answer bought
  twice with heavy upstream quota.

  A **finished** run is never handed back in its place. The tape genuinely changes
  underneath a fixed window — old fills gain detail later, markets in the window
  resolve after it, and a run may have been cut short by its fetch budget. Re-running
  is the honest default.
</Note>

## Afterwards

A finished run keeps its result, the exact configuration that produced it, and the
window it covered. From there you can:

* **Read it** — see [Reading a result](/guides/reading-a-result) for what the
  reliability banner is telling you.
* **Trust it appropriately** — every result ships with a standing list of the ways
  the simulation is not reality. See [Backtest fidelity](/guides/backtest-fidelity).
* **Deploy it** as a copy trade. The deployable half of the configuration is carried
  across, the simulation-only controls are dropped, and the copy trade is created
  **paused** so nothing mirrors until you switch it on.

A backtest also harvests the leader's tape as a side effect, which is what fills in
the taker share and execution profile on their
[trader profile](/guides/trader-profiles).

## What to read next

<CardGroup cols={2}>
  <Card title="Backtest fidelity" icon="scale-balanced" href="/guides/backtest-fidelity">
    Every way a simulated fill differs from a real one.
  </Card>

  <Card title="Reading a result" icon="chart-line" href="/guides/reading-a-result">
    Reliability, boundary exposure, data gaps and fee confidence.
  </Card>

  <Card title="Copy trade settings" icon="sliders" href="/guides/copy-trade-settings">
    The strategy half of the form, field by field.
  </Card>

  <Card title="The backtester" icon="flask" href="/terminal/backtester">
    Using it in the terminal.
  </Card>
</CardGroup>
