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
- 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.
- 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.
- 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.
-
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
MISSEDand excluded from Win Rate. - 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.
- 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.