Performance
The Performance page surfaces trade-derived analytics across your full trading history. It replaces the older account-scoped P&L summary cards with a unified surface that filters and slices by date range, broker, account, and strategy.
Tabs
The page is organised as six tabs. The first five read from the same filter bar at the top; the Reports tab is a discovery list and ignores the filter bar.
| Tab | What it shows |
|---|---|
| Overview | The equity curve at the top (see Equity curve below), then quick metrics (total P&L, win rate, profit factor, expectancy), distribution stats, activity summary, and a drawdown summary. The equity curve leads because it is the first thing you want when assessing performance. |
| Monthly Returns | Year-by-month grid of percent returns with compounded year totals, per-year max drawdown, and an averages row. |
| Strategy Comparison | Per-strategy summary table plus an Expected vs Actual table when any strategy has expected metrics set. |
| Trades | Per-trade list with derived columns (trade cost, percent P&L, normalised P&L) and pagination. Every column header is sortable; sorting runs server-side across your whole trade history, not just the visible page, and resets to page 1. Defaults to trades that had market exposure; see below. |
| Execution | Per-strategy fill and failure rates: how many attempted trades actually reached the market versus failed or expired. |
| Reports | A discovery list of every strategy and account, each row linking to its full performance report. Where a back-test exists the row shows a tracking-verdict teaser; otherwise it shows a "No back-test" hint. |
The page answers two separate questions. The P&L tabs (Overview, Monthly Returns, Strategy Comparison) measure performance from trades that actually happened, and compute their metrics from closed trades only. The Execution tab answers the secondary question — what fraction of attempted trades failed or expired — and is the only tab that counts non-closed statuses.
Trades tab status filter
The Trades tab defaults to trades that were active at some point: open, closed, and partialClose. Trades that never became a position (pending, expired, cancelled, failed, superseded) carry no P&L and would inflate the implicit trade count, so they are excluded by default.
Use the status dropdown on the Trades tab to add any of those statuses back when you want to inspect, for example, every order that failed at the broker. Clearing the dropdown shows every status.
Execution tab
The Execution tab is an execution-health view, not a P&L view, so it counts every status rather than closed trades only.
- Active is
open + closed + partialClose— trades that became a position. - Fill rate is
active / (active + failed + expired). - Fail rate is
(failed + expired) / (active + failed + expired). - Cancelled is reported separately but excluded from the rates: a cancellation is a deliberate user or broker action, not an execution failure.
pending(still in flight) andsuperseded(signal replaced before execution) are excluded from the rates entirely.
Rows are per strategy with a pooled TOTAL, so a strategy whose orders are frequently rejected or expiring stands out without crowding the P&L story.
Filters
The filter bar above the tabs is the single source of truth. Filter state lives in URL search params, so links are shareable, browser back and forward work, and reloading preserves your view.
| Filter | Notes |
|---|---|
| Date range | Presets are 7d, 30d, 90d, YTD, 1y, all, plus custom (native date inputs). Custom range overrides the preset. |
| Broker | Multi-select. Empty means all brokers. |
| Account | Multi-select, grouped by broker. Empty means all accounts. |
| Strategy | Multi-select. Empty means all strategies. Trades with no strategy are still included in totals when this is empty. Disabled while the equity curve source is set to Account balance, because broker balance has no strategy dimension. |
| Account type | Live, paper, or all. Until you pick one, this follows the global Live/Paper pill, so opening Performance in LIVE mode shows live data by default. Choosing an option pins it to the URL and later pill toggles no longer move it; Reset clears your choice and returns the page to following the pill. |
Filters combine with AND. Choosing two strategies on one account narrows trades to that account AND those strategies.
Equity curve
The equity curve sits at the top of the Overview tab. It is the first thing you want when assessing performance, so it leads the tab rather than living on its own.
It renders as two stacked charts that share one x-axis: equity on top and the shaded underwater drawdown below it at about a third the height. Splitting the two means the equity line is no longer squeezed against a second axis, so both the curve shape and the depth of drawdowns read clearly. The drawdown summary card directly below restates the same max and current drawdown figures as numbers.
The toggles above the curve control the source (Trading P&L, Account balance, or Net return), the mode and scale (covered under Standardised equity curve and Equity curve source below), and the drawdown unit (covered under Drawdown units).
Standardised equity curve
The standardised toggle on the equity curve normalises each trade to a fixed dollar size so curves from differently sized strategies can be visually compared by shape rather than dollar magnitude.
The system default is STANDARD_TRADE_VALUE = 1000. Each strategy may override this on the strategy form (Strategies → Edit → Standard trade value). When a trade carries a strategy with an override, the override applies; otherwise the default applies.
The override only affects the standardised equity curve. It does not affect the raw equity curve, monthly returns, or the per-trade P&L numbers in the Trades tab.
Equity curve source
The equity curve plots one of two sources, switched with the Trading P&L / Account balance toggle. The choice persists in the URL, so a shared link reopens on the same source.
- Trading P&L is the cumulative closed-trade profit and loss. It is immune to deposits and withdrawals and answers "how good is the trading". This is the default and supports the trade-by-trade or day-by-day mode and the raw or standardised scale.
- Account balance is the broker-reported account equity through time, including deposits and withdrawals, so it answers "how much is in the account". It is a single day-by-day series in raw dollars, so the mode and scale toggles do not apply and are hidden in this source. Balances forward-fill across partial-sync days, so a day where only some accounts reported still reflects every account in scope.
The strategy filter is disabled in Account balance mode, because broker balance is recorded per account and has no strategy dimension. The drawdown summary card recomputes its figures from the balance series in this source, so the numbers always match the plotted curve rather than the trade-derived metrics.
A brand-new account with no balance snapshots yet shows the empty-state message until the balance-snapshot job records its first day.
Drawdown units
The DD $ / DD % switch changes the units on the shaded underwater chart for both sources. Dollars show the drawdown magnitude; percent shows each point's drawdown as a fraction of the running peak equity up to that point. The equity chart above stays in dollars regardless. The switch is display-only and is not stored in the URL.
Expected vs Actual
The Expected vs Actual table on the Strategy Comparison tab compares your live results against backtest expectations stored on each strategy.
To populate the comparison, edit a strategy and fill in the Expected metrics accordion:
| Field | Description |
|---|---|
| Expected TPY | Expected trades per year. |
| Expected accuracy | Expected win rate as a percentage (0 to 100). |
| Expected payoff | Expected payoff ratio (average win / average loss). |
| Expected mean % | Expected mean return per trade as a percentage. |
| Expected stdev % | Expected standard deviation of returns per trade. |
Edge is derived from accuracy and payoff using the Van Tharp formula and is not stored. The live edge is computed from your actual trades the same way.
The table only renders when at least one strategy in scope has expected metrics set. Rows where the actual value is materially better than expected are coloured green, materially worse are red, within plus or minus 2 percent are neutral. The standard deviation column inverts the rule (lower is better).
Empty states
If the filter range matches zero closed trades, each tab shows an explanatory card. The Expected vs Actual table simply hides when no strategy in scope has expected metrics.
Strategy performance report
Each strategy has its own formatted report at /performance/report/strategy/<id>. It is reached from three places, all resolving to that one URL: the Reports tab on the Performance page (the primary discovery list), the Performance report item in a strategy's row menu on the Strategies page, and the daily email deep link. Where the Performance page is the interactive, portfolio-level explorer, the report is a per-strategy document built to be read top to bottom and printed to PDF. The Performance sidebar item stays highlighted while you read a report, and the report header carries a back arrow to the Reports tab (/performance?tab=reports), the report index you came from.
The report carries four things:
- Tracking verdict. A plain-language headline in the header (Ahead, On track, Below expectation, or At risk) with the Eq and DD scores shown beside the word. The verdict reads where your live equity sits inside the Monte-Carlo expectation cone, then applies a one-sided drawdown veto: a deep realised drawdown can only ever worsen the verdict, never improve it, and when it fires the badge spells out why (for example, "At risk - needs attention"). The verdict is computed once on the server so the web report and the daily email always agree.
- Expectation cone. The realised equity line laid over the Monte-Carlo percentile bands, with a linked underwater drawdown panel and the expected MDD95 and MDD99 lines. A basis toggle switches the cone and verdict between day-by-day (the default) and trade-by-trade; a tri-colour or fan toggle restyles the bands without recomputing anything.
- Two expected-vs-actual tables. A trade-by-trade table and a day-by-day table, each putting your live metrics next to the back-test benchmark. Cells that do not yet have enough live data to trust are dimmed and annotated ("meaningful from N; X so far") rather than hidden, and the back-test benchmark is always kept. Payoff and Edge need at least five wins and five losses before they show, Accuracy needs at least one loss, and the realised drawdown tail needs roughly sixty days. This is a correctness guard: a ratio with no losing side is a divide-by-zero, not a measurement. The Trade Count row counts the trades that had market exposure (
open,closed, andpartialClose) so it reconciles with the All Trades list; the realised metrics beside it (accuracy, payoff, edge, and the rest) are computed from closed trades only, since open trades have no realised result. - Summary banner and All Trades. The quick-metrics banner (Total Trades, total P&L, win rate, payoff, profit factor) and a paginated list of the trades that had market exposure (
open,closed, andpartialClose), with the same derived columns as the Trades tab. Every column header sorts the full result set server-side and resets to page 1; an explicit sort overrides the default open-first ordering. Total Trades counts that same actual set so the headline matches the list total; the other banner figures (win rate, payoff, profit factor) are closed-trade only. Never-filled trades (pending,expired,cancelled,failed,superseded) are excluded from both the count and the list.
Before a back-test is uploaded
The report works immediately on your live results. Until you upload a RealTest back-test CSV for the strategy, the cone and the Back-Test columns are replaced with an upload zone and the verdict is hidden; the live banner and trade list still render.
The upload zone is the per-strategy entry point. Drop a RealTest export onto it, or browse to one, and the file is linked to this strategy by its ID, so there is no filename matching to get right. The upload then steps through:
- Validating. The file is parsed and checked. A malformed file is rejected on the spot, naming the offending row and column (for example, "Row 412, column DateOut: could not read the date"), and nothing is saved. Fix the file and upload again.
- Computing. A valid file is stored and the Monte-Carlo expectation is queued. Your live results keep showing while it computes.
- Ready. Once the compute settles, the cone, the verdict, and the Back-Test columns appear.
Uploading back-test data in bulk
The Back-test data page at /performance/backtests, reached from the Back-test data button on the Performance page, manages every object's back-test in one place. It carries two things:
- Bulk upload with a confirm step. Drop several RealTest exports at once. The page suggests a target strategy or account from each filename, but the suggestion is only a hint: you confirm the link for every file before anything is saved, and a file with no confident match must be resolved (or set to Ignore) before you can confirm. Confirming uploads each file to its chosen object by ID, exactly as the per-strategy upload does, and queues the Monte-Carlo compute. Account files map to the account's daily-returns series.
- Status of every object. A table of every strategy and account showing whether a back-test is present, the file and date it was uploaded, and its state (no back-test, computing, ready, or failed). Each row has an Upload or Replace action to set or swap that object's back-test directly.
Association is always by the object's stable ID, never by the filename, so renaming an export never breaks the link.
Print to PDF
The report is dark on screen, matching the rest of the app. Use the Print button (or your browser's print command) and it switches to a light, print-ready document and drops the interactive controls. Charts are on-screen SVG, so they print faithfully; save as PDF from the print dialogue.
Account performance report
Each account has its own report at /performance/report/account/<id>, reached from the Reports tab on the Performance page or the Performance report button on an account's expanded card on the Accounts page, both resolving to that one URL. It shares the strategy report's shell, cone, verdict, and gated expected-vs-actual tables, and adds the account-level sections in this order:
- Summary banner. Start equity, current account value, account P&L (with its percentage), and trading P&L, in the account's own currency.
- Expectation cone, directly after the banner, with the same basis and palette toggles as the strategy report.
- Account Details and Recent Daily P&L, side by side on desktop and stacked on smaller screens. Account Details reconciles the account growth into trading P&L plus other income and costs (dividends, interest, and fees), so the three figures add up; deposits and withdrawals come from the cash-flow feed. Recent Daily P&L lists the last few sessions with a balance, the day's P&L, and the percentage move, plus a pooled total.
- Day-by-Day and Trade-by-Trade tables, the same gated expected-vs-actual analysis as the strategy report.
- Daily return distribution. A three-panel statistical composite comparing the account's live daily returns against the back-test day-by-day distribution: a histogram of the live returns (with the back-test shape overlaid as a step line, plus mean and ±1σ/±2σ markers), a Q-Q plot of the matched quantiles against a 45° perfect-match line, and a CDF (percentile) plot of daily gain versus percentile with the back-test as a line and each live day plotted as a green (gain) or red (loss) dot. A "Statistical Analysis" box reports three goodness-of-fit measures with plain-English readings: the Kolmogorov-Smirnov two-sample test, a chi-squared goodness-of-fit, and the Pearson correlation on the Q-Q quantiles. The panels sit side by side on desktop and stack on phone and tablet. It appears only once the account has both a back-test distribution and a live track; on a short track the stat box says when a sample is too thin rather than erroring.
- Monthly returns grid, the compounded month-by-month returns for the account (scrolls horizontally on a phone).
- Strategy Breakdown. Every strategy that traded in the account, with its P&L, Eq and DD health dots, the actual metrics against the back-test benchmarks in parentheses, and the same small-sample gating. Each row links to that strategy's own report, and the TOTAL row carries the account's Eq and DD scores and reconciles the per-strategy P&L back to the account trading P&L.
- All Trades, paginated, with the still-open positions listed first. The list shows only the trades that had market exposure (
open,closed, andpartialClose); the never-filled states (pending,expired,cancelled,failed,superseded) are excluded.
A single currency is shown per account; mixed-currency accounts (AUD/USD splits and the FX-impact residual) are not modelled yet. As with the strategy report, the account report is useful from your live results immediately: until an account daily-returns back-test CSV is uploaded, the cone and the back-test columns are replaced with a prompt and the verdict is hidden, while every live section still renders. Print to PDF works the same way.
Daily report email
You can receive a daily performance digest by email: a single combined message with a full card for each of your accounts. Each card carries the account's tracking verdict badge, headline stats (account value, today's change, and trading P&L), the recent daily P&L with a Total row, a per-strategy breakdown whose Total reconciles to the account's trading P&L, and a View full report link to that account's report. The verdict and figures come from the same read path as the on-screen report, so the email and the web agree.
The digest is opt-in and off by default. Turn it on under Settings -> Notifications by enabling the email channel for Daily Report. The email itself is a light, mobile-friendly layout with no charts (the charts live in the linked web report).
The digest is sent once the end-of-day reconciliation has settled, so the figures are final rather than mid-session, and every date in it is shown in your configured timezone. An account with no back-test still appears, with its live figures and a "No back-test" badge in place of the verdict.
Related
- Strategies - configure expected metrics and the per-strategy standard trade value.
- Trades - the underlying trade list this page derives from.