API
View as Markdown

Stats

Aggregate stats over a date range, with parallel totals (per-row, real-money correct) and decisions (one signal regardless of copies) breakdowns.

GET /stats/summary

Scope: read:trades

Aggregate stats over a date range. Returns range (echoed for clarity) plus two parallel breakdowns:

  • totals — per-row counts: trade_rows, total_net_pnl, total_gross_pnl, total_fees, best_trade, worst_trade, avg_pnl. Every copy counts as its own row (real-money correct).
  • decisions — grouped by COALESCE(source_trade_id, trade_id): count, wins, losses, breakevens, win_rate_pct, avg_win, avg_loss, expectancy, profit_factor. Use this for win rate (one signal = one decision, regardless of how many accounts copied it).
ParamTypeDescription
fromdateDefault: 30 days ago.
todateDefault: today.
rangeenumShortcut: today, yesterday, 7d, 30d, 90d, mtd, ytd, all. Overrides from/to.
account / account_idint or stringEither alias works.

Breakeven offset classification

Win / loss / breakeven counts on every stats endpoint honor your account's breakeven_offset_low and breakeven_offset_high — same logic the in-app stats page uses. A decision P&L inside the BE window is counted as breakeven, not as a tiny win or tiny loss. The window in effect is echoed back in the response as breakeven_offset: {low, high}.

Which offset is used:

  • Filter by account_id: that account's offset.
  • Filter by account name: resolved account's offset.
  • No account filter (all accounts): the user's first non-archived account's offset (matches the website's group-mode rule).

GET /stats/by-symbol

Scope: read:trades

GET /stats/by-strategy

Scope: read:trades

GET /stats/by-symbol and GET /stats/by-strategy accept the same parameter set as GET /stats/summary. Both buckets are decision-grouped: a single trading decision copied across multiple accounts counts as one entry (with P&L summed across the copies), not as N separate rows. wins / losses / breakevens honor the same BE-offset window described above.