Performance
P&L, expectancy and win rate over a period you choose.
Performance reports on trades that have already closed. Pick a period, and the bot rebuilds it from the exchange's own record of your fills - every trade on the account, not only the ones it placed itself.
Before the rows, one thing the rest of the page depends on. The card is built in three tiers, and they know different amounts about your trading:
| Block | Built from | Covers |
|---|---|---|
| P&L, win rate, drawdown, streaks, trades, hold time | the exchange's record of closed trades | every trade on the account |
| π― EV and π Avg R | what the bot planned to risk, from its own ledger | only trades the bot placed and ledgered |
| πΌ Balance and π Acct DD | daily balance snapshots the bot records | only days it has a snapshot for |
A row whose tier has nothing to measure is left off the card entirely - not shown as a dash, and not shown as zero. That distinction is the whole point: a zero that means not measured is indistinguishable from a zero that means zero, and the second one is a real result. Coverage at the end of this page is how to tell which you are looking at.
Where to find it
Main menu β π Performance, or send /performance.
| Button | Period |
|---|---|
| Today | From local midnight to right now. |
| This Week | From local Monday midnight to right now. |
| This Month | From the 1st, local midnight, to right now. |
| Last 50 / 100 / 200 | The most recent 50, 100 or 200 closed trades, however long ago they were. |
| Custom | Either of the above, to your own number or dates. |
The first three are periods so far - they end at this moment, not at the end of the day, week or month. A "This Month" report opened on the 3rd covers three days.
Local means your offset, not UTC
Every boundary here is a local one, taken from the same π UTC Offset that Daily Loss Limit and Trading Days use. There is one clock per account and this is it.
A trade closing exactly on a boundary belongs to the next period, so two adjacent periods can never both count it.
Custom asks for a reply:
Reply with a number of trades (e.g. 50) or a date range (e.g. 2026-08-01..2026-08-24).Those are the only two forms. Both dates in a range are inclusive, and the end date's full
day is covered. A count above 500 is quietly reduced to 500. A reply that is neither
form is refused with the format restated, rather than a bare no:
Send either a number of trades (e.g. 50) or a date range (e.g. 2026-08-01..2026-08-24).A reply that is the right shape but wrong - a date that does not exist, or an end date before its start - is refused in its own words instead, naming what was wrong with it. Either way the prompt is asked again in place and nothing is saved.
/performance on its own opens this picker. /performance with an argument skips it
and sends the card straight into the chat - today, week, this week, month,
this month, a trade count, or a date range all work. That version arrives as a plain
message, with an equity curve attached whenever the
period has trades in it, and no buttons on it - the drill-downs are reachable only from the
panel.
That attached chart is the same curve as the one on the Charts menu, drawn plainly: it is
titled Performance Analytics rather than Equity Curve ($), and it carries no drawdown
shading. For the shaded version, and for the other three charts, go through the panel.
The card is built when you ask for it
Choosing a period replaces the panel with Building This Month⦠while the bot catches up
with the exchange - closed P&L and fills, going back as far as 730 days the first time.
That work happens in the background, which is why the panel acknowledges you before the
card appears.
If the catch-up fails, the error is shown rather than a card:
β Error building performance reportA report is never built on a half-synced mirror. Silently under-reporting recent trading would be worse than showing the failure. If the API key has been revoked at Bybit, the panel says so specifically and points at connect one from your account page instead.
Opening a report is also what records the day's balance snapshot - see Coverage.
The card
$178.50 (7.31%)
π― EV +0.83R
π Win Rate 60% (6W / 3L / 1BE)
π Avg R +1.90R / -1.02R
π Max DD -$23.10
π₯ Streaks 2W max Β· 1L max
π’ Trades 10 (0.83/day)
β±οΈ Avg Hold 3h 0m
πΌ Balance $2,465.20 β $2,645.30
π Acct DD 0.00%
π How this panel works9:35 PMEvery figure above is computed from an example account: ten fictional closed trades over a fortnight, six wins, three losses and one breakeven. Nothing on it is typed out by hand, so the arithmetic below is the arithmetic your own card does.
Three buttons sit under it - π Breakdowns, βοΈ Execution and π Charts - leading to the slices, the execution card and the charts for this same period. β Back returns to the period picker.
P&L is what you kept
$178.50 is net: the exchange's realized profit and loss with the fees you actually paid
already taken out. It is the sum of the period's closed trades and nothing else - open
positions contribute nothing until they close.
The percentage in brackets is not that figure divided by your balance. It is the account's own movement over the period, computed from the balance snapshots described below, which is why the two can disagree: money you deposit or withdraw moves the balance without any trade doing it. When there is no balance coverage, the bracket is absent and P&L renders alone.
An arrow - β² or βΌ - is appended when a comparable earlier period exists, comparing this
P&L against that one.
EV is the average trade, measured in R
+0.83R says that across the period, the average trade returned 0.83 times what it was
risking. One "R" is the dollar risk the bot planned for that trade, so a trade that made
exactly what it stood to lose is +1.00R.
It is the mean of every enriched trade's net P&L Γ· planned risk. That is identical to
win rate Γ average win R β loss rate Γ average loss R, so it can be read either way. A
breakeven trade counts as 0.00R and pulls the average toward zero, which is correct - it
consumed risk and returned nothing.
EV is a tier two figure. It describes only trades the bot placed and ledgered, never the whole period, and the row disappears when the period contains none.
Win Rate counts three outcomes, not two
60% (6W / 3L / 1BE) - six wins, three losses, one breakeven, out of ten trades.
The percentage is wins Γ· all trades, so the breakeven trade is in the denominator and
not in the numerator: it lowers the win rate rather than being ignored. A trade is a win
above zero, a loss below it, and breakeven at exactly zero - all after fees. The BE
segment only appears when there is at least one, and the percentage is rounded to a whole
number.
Avg R is the two halves EV is made of
+1.90R / -1.02R is the average winner and the average loser, each in R. The example's
winners returned nearly twice their risk on average; its losers cost about what they were
supposed to.
The pair is what makes EV readable. A modest win rate is fine when the left figure dwarfs
the right; a high win rate is not enough when it does not. The row appears only when the
period has at least one enriched winner, and the right-hand side falls back to β when
there is no loser to average.
Max DD is the worst run of trades, not the worst the account looked
-$23.10 is the largest peak-to-trough fall in cumulative trade P&L: the running total's
best point so far, minus its worst point after that. In the example it is the single loss
that landed immediately after the first winner.
It is measured on the trade curve, so it is unaffected by how much money was in the account at the time. That is deliberately a different measurement from π Acct DD below, which is a percentage of the balance - the two can move quite differently, and pairing them on one line would invite reading the percentage as "that dollar figure as a share of the account". It is not.
Streaks are the longest runs, and a breakeven ends one
2W max Β· 1L max - the longest run of consecutive wins and the longest run of consecutive
losses in the period.
A breakeven trade ends whichever run was in progress and starts nothing. Counting it as either would misstate both figures, so a win, a breakeven and a win is two runs of one, not a run of two.
Trades carries the pace as well as the count
10 (0.83/day) is the trade count and the trades-per-day rate.
The rate's denominator is the period's own span in local days, including days you did not trade at all. For a Last N trades period, which has no span of its own, the span from the first traded day to the last is used instead - that is narrower than the window the trades really came from, and it is the best available answer rather than the whole one.
The execution card shows the other half of this: how many of those days actually saw a trade.
β±οΈ Avg Hold is the mean time from a trade's first fill to its close, deliberately
coarse - under an hour it reads as minutes, under a day as 3h 0m, beyond that as 2d 4h.
The balance block is about the account, not the trades
πΌ Balance $2,465.20 β $2,645.30
π Acct DD 0.00%The two figures are the first and last recorded balances of the period, and the deepest fall below a balance peak within it, as a percentage of that peak.
What is being measured is your total account value: the exchange's realized wallet balance plus whatever you have set as Collateral Balance. It is realized only - unrealized profit on positions that are still open is not in it, so the figure tracks money banked rather than what the position screen currently says.
That is why $2,645.30 above is larger than the Bybit: $2145.30 the
Risk Management panel shows for this same example account. That
panel is reporting the exchange's own balance; this block adds the $500.00 set as
Collateral Balance to it, reaching the Total: $2645.30 the same panel prints beside it.
The whole block is absent until the bot holds at least two snapshots for the period, counting the day after it ends - a day's closing balance is the next day's first snapshot. A Today report therefore never shows it. One balance is a position, not a return.
The comparison line
When a comparable earlier window exists, one italic line closes the card:
vs Last Month: $112.40 over 7 tradesThe figures there are an example; the label is the bot's own. It is Yesterday for a Today
report, Last Week, Last Month, or Previous for a custom range - and a partial period is
compared against the same elapsed slice of the earlier one, so a month-to-date report on
the 2nd is not measured against a whole month. A Last N trades period has no time span
to shift, so it never gets this line.
Coverage: a missing row is not a zero
Everything above hangs on this. The three tiers cover different subsets of the same period, and the card would be misleading if it let a figure from one of them look like a figure about all of it.
Tier two - the R rows. The exchange never knew what you planned to risk; only the bot did, and only for trades it placed. A trade is enriched when the bot's own ledger recorded a planned dollar risk above zero for it. Trades you placed yourself in the Bybit app, and trades from before the ledger existed, are counted in every figure in the first tier and carry no R at all.
When only part of the period is enriched, the card says so in one line:
R metrics cover 21 of 214 trades (from 2026-08-18)The figures there are an example; the sentence is the bot's own. The date is the first
enriched trade in the period. The line appears only when coverage
is partial - the example card above has none, because all ten of its trades are enriched.
When nothing in the period is enriched, the EV and Avg R rows are dropped from the card
altogether and the line reads 0 of N, which is the difference between "no R to report" and
"an R of zero".
Tier three - the balance block. Balance snapshots are written forward only. Bybit publishes no history of past balances, and reconstructing one by walking trades backwards would be wrong the moment money is paid in or taken out, since that movement is not a trade. So there is no backfill, ever: periods from before you first opened a report have no balance rows and never will.
One snapshot is recorded per local day, the first time a report is built that day, and it holds the balance at that moment. A later report the same day changes nothing, on purpose - a later balance overwriting the first one would quietly skew every percentage built on the series. A day the balance could not be fetched is left as a gap rather than written as a zero.
A section you cannot see is a section that could not be measured
If a card is missing EV, Avg R, the balance block or the ROI percentage beside P&L, nothing
is broken. Those rows were not computable for the period you chose, and the alternative -
printing 0.00 or N/A - would have been a number you could act on wrongly.
The fix, where there is one, is coverage: trades placed through the bot earn the R rows, and opening a report on more days earns the balance block.
When the period is empty
A period with no closed trades in it renders one line and stops:
No trades in this period.Nothing is wrong with the account. Trades count toward the period they closed in, so a position opened last week and still open is in no period at all yet.