Methodology — How We Calculate Win Rate, P&L and ROI

Every number you see next to a trader on PNL Mama — on the home page, on the trader profile, on the SEO review page — is computed by one and the same function. If the home page says a trader has a 52% win rate, the trader's own page agrees, and so do the meta tags Google indexes. This page documents the formula.

How we verify each signal

  1. Capture. Every message a trader publishes in their public Telegram channel — text plus any chart screenshot — is saved as-is, with the exact publication timestamp. That timestamp is the anchor for everything that follows.
  2. Read. Our extraction model pulls out the coin, direction (long/short), entry, take-profits, stop-loss and leverage. If a number is drawn on the chart, OCR reads it off. We don't invent missing prices; gaps go to step 3.
  3. Standardize. When a trader posts an incomplete plan we apply the same defaults to every signal so they can be compared: stop-loss = entry × (1 − 1/leverage), leverage = 10× when undisclosed, market entry, and three synthetic take-profits at 33% / 66% / 100% of the entry-to-stop distance.
  4. Slippage gate. If by the time the post lands the market has already eaten more than 70% of the path from entry to TP1, no honest follower could have filled at that price — the signal is marked MISSED and excluded from Win Rate.
  5. Backtest. Surviving signals are replayed against real minute-by-minute OHLC candles from the exchange. The fill price is the open of the publication-minute candle. The simulated position uses a fixed $100 margin at the signal's leverage — a common scale for USDT P&L across traders, not position-sizing advice.
  6. Record. Each closed trade gets a realized PnL in USDT (after leverage) and an ROI %. These trades feed the Win Rate, P&L and ROI numbers below.

What counts as a closed trade

A signal is treated as closed only when its status is one of: CLOSED_FULL, CLOSED_PARTIAL.

  • CLOSED_FULL — all take-profit levels hit, or the stop-loss closed the position.
  • CLOSED_PARTIAL — at least TP1 hit and the rest of the position closed afterwards.

Active, pending and errored signals are excluded from Win Rate and P&L.

How a closed trade is classified

Every closed trade has a result — profit or loss in USDT, after leverage. That result puts the trade into one of four buckets:

  • Win — closed in profit.
  • Loss — closed in the red.
  • Break-even — closed flat. Not a win, but not a loss either — still counts toward the total number of closed trades.
  • Excluded — closed, but we couldn't compute the result (rare). Dropped from the stats.

Win Rate

Win Rate is the share of wins among closed trades: Win Rate = wins ÷ all closed trades × 100%. "All closed trades" means wins + losses + break-even — everything whose outcome we know. Rounded to two decimal places.

P&L and ROI

  • P&L (USDT) — total profit or loss across all closed trades. Each one is simulated with the same $100 margin (step 5), and only realized results add up — open positions don't move this number.
  • ROI % — the average of every trade's ROI (with leverage). It's the average return per signal — every trade with equal weight, no reinvestment. Not a portfolio return.

What time period we count

By default — the last 30 days, by the signal's publication date. On the trader profile the window can be changed: for example, just the past week or all time.

What we do not (yet) account for

  • Position size — every trade is simulated with the same $100 (step 5), so traders can be compared on the same scale. We don't know the trader's real account size or how much they put into a specific signal.
  • Exchange slippage and fees — we use the prices in the signal and don't subtract real-world execution costs. On a live exchange the result will be slightly worse.
  • Partial closes — if a trader hit the first take-profit and closed the rest manually, we still count the trade as a full win. A stricter methodology would give a slightly lower Win Rate than ours.

The full implementation lives in core/stats_service.py; this page and that file are updated together.

← Back to traders