Built and run by one person.

Beat Rate

The share of rolling periods where a fund beat its benchmark.

Source data: AMFI daily NAV (38,000+ schemes, 37M+ rows since April 2006) + Nifty benchmark indices · Last updated: 2026-07-02
Live tool

Analyze any Indian mutual fund or portfolio across 30+ return, risk and benchmark metrics in the live MFPRO tool.

What is Beat Rate?

Beat Rate tells you how often a fund outperformed its benchmark over rolling periods. If a fund has a 1Y Beat Rate of 75%, it means that in 75% of all possible 1-year holding periods, the fund delivered a higher return than Nifty 50. It answers a simple question: "If I picked a random 1-year window, what are the odds this fund beat the market?"

How We Compute It

For every trading day, we compute the rolling return for the fund AND the benchmark over the same window (e.g., 1 year). Then we count how often the fund's rolling return was higher than the benchmark's.

Beat Rate = (Number of days where fund rolling return > benchmark rolling return) / (Total paired observations) x 100

The rolling return for both fund and benchmark uses the same window and the same CAGR/absolute return formula. For windows > 1 year, both are annualized to CAGR. For shorter windows (3M, 6M), both are simple percentage returns.

SQL (simplified)

WITH rolling AS (
  -- Fund rolling returns (ASOF JOIN for lookback)
  SELECT a.scheme_code, a.date,
    (POWER(a.nav/b.nav, 365.0/(a.date-b.date))-1)*100 AS ret
  FROM nav_master a
  ASOF JOIN nav_master b
    ON a.scheme_code = b.scheme_code
    AND b.date <= a.date - INTERVAL '365 days'
  WHERE a.nav > 0 AND b.nav > 0
),
bench_rolling AS (
  -- Benchmark rolling returns (same window)
  SELECT ba.date,
    (POWER(ba.nav/bb.nav, 365.0/(ba.date-bb.date))-1)*100 AS ret
  FROM index_nav ba
  ASOF JOIN index_nav bb
    ON bb.index_name = ba.index_name
    AND bb.date <= ba.date - INTERVAL '365 days'
  WHERE ba.index_name = 'INDEX_NIFTY50'
)
SELECT scheme_code,
  COUNT(*) FILTER (WHERE br.ret IS NOT NULL
    AND r.ret > br.ret) * 100.0
  / NULLIF(COUNT(*) FILTER (WHERE br.ret IS NOT NULL), 0)
    AS beat_rate
FROM rolling r
LEFT JOIN bench_rolling br ON r.date = br.date
GROUP BY scheme_code

Worked Example

Imagine Fund ABC and Nifty 50 with 1-year rolling returns computed on 10 trading days:

DateFund ABC 1Y ReturnNifty 50 1Y ReturnFund Beats?
2025-01-0218.5%14.2%Yes
2025-01-0317.8%15.0%Yes
2025-01-0616.2%16.5%No
2025-01-0715.9%16.1%No
2025-01-0819.3%13.8%Yes
2025-01-0920.1%12.5%Yes
2025-01-1011.4%14.9%No
2025-01-1322.0%15.5%Yes
2025-01-1414.7%16.0%No
2025-01-1518.9%13.1%Yes

Fund beats the benchmark in 6 out of 10 observations.

Beat Rate = 6 / 10 x 100 = 60.0%

In practice, a full-history 1Y rolling beat rate is computed over 2,000+ observations, not 10. The example above is simplified to show the counting logic.

How to Interpret

Important Notes

Related metrics

More Returns methodology from the MFPRO analytics tool: