DEV Community

Cover image for Trading metrics look simple until you hit these 6 edge cases
Edgelog
Edgelog

Posted on Fully Autonomous

Trading metrics look simple until you hit these 6 edge cases

Win rate is wins divided by trades. Profit factor is money won divided by money lost. You can write both in five minutes.

Then real trade history shows up: fees, trades that close at exactly zero, accounts that never lost, deposits in the middle of a run. We build Edgelog, a free trading journal, and these are the six cases that changed our formulas the most. If you ever build anything that summarizes trades (or any wins and losses), they apply to you too.

1. Decide what "net" means before anything else

A broker gives you a profit number and a fee number. If you classify wins on the gross number, a trade that made $10 and paid $12 in fees counts as a win. Your trader lost $2.

We compute everything on one value:

const tradeNet = (t: { pnl: number; fees: number }) => t.pnl - t.fees; // fees are a positive cost
Enter fullscreen mode Exit fullscreen mode

Win, loss, totals, averages: all from tradeNet. One definition, used everywhere, beats a "gross" and a "net" version that slowly drift apart.

2. Zero is its own outcome (and floats make zero hard)

Some trades close at exactly breakeven. If you count them as losses, you punish the trader for a scratch. If you count them as wins, you flatter them.

So there are three outcomes, and the comparison happens on cents, not raw floats:

function outcome(net: number): 'win' | 'loss' | 'breakeven' {
  const cents = Math.sign(net) * Math.round(Math.abs(net) * 100); // half away from zero
  return cents > 0 ? 'win' : cents < 0 ? 'loss' : 'breakeven';
}
Enter fullscreen mode Exit fullscreen mode

Without the rounding, 0.1 + 0.2 - 0.3 is a tiny positive number and becomes a "win".

Breakeven trades are left out of win rate (wins / (wins + losses)), but they stay in the trade count and in expectancy, because they still happened.

3. Profit factor with no losing trades is not infinity

Profit factor is gross profit divided by gross loss. A new account with five winning trades has a gross loss of 0, and x / 0 in JavaScript is Infinity. Show that on a dashboard and people screenshot it.

We return null and render "—" with a short note ("No losing trades yet"). With losers but no winners, it's a real 0. Typing it as number | null forces every screen to handle the empty case on purpose.

4. Expectancy should divide by every trade

Expectancy answers "what does one trade earn me on average?" We use net P&L divided by total trades, breakevens included. Dropping breakevens from the denominator makes the number look better than the trader's real experience.

5. Drawdown needs a starting point, and a choice

Max drawdown is the biggest fall from a peak. Two details matter:

  • The first peak is the starting balance, not the first trade. Otherwise a losing first week shows no drawdown at all.
  • Percent drawdown is ambiguous. The largest dollar drop and the largest percentage drop can happen at different times. We report the percentage at the point of the largest absolute drop, and we documented that choice so nobody "fixes" it into a different number later.

6. Deposits are not profit

Synced accounts often start with a small first deposit, then more money arrives later. If you measure gain against that first deposit, a modest month can show a gain of several hundred percent.

For synced accounts we use net deposits as the base: current balance minus the net P&L of closed trades. Starting balance plus every trade's net then lands exactly on the broker's balance, which is a nice built-in check.

One more thing: write the definitions down

Every one of these was a bug report before it was a rule. What helped most wasn't clever code. It was keeping a plain document that says, for each metric, the exact formula, what happens with empty input, and which edge cases are deliberate. Tests point at that document, and so do code reviews.

If you want to see these numbers on your own trades, Edgelog is free (1 connected account, up to 10,000 stored trades) and syncs MT4/MT5, Binance, Bybit and OKX read-only, or imports a CSV.

Which metric gave you the most trouble? Share the edge case you hit.

Trading involves risk. Edgelog is a journal, not financial advice.

Top comments (0)