PeerPerformance evaluates the performance of investment
funds relative to their peers, with a correction for luck that
is robust to false discoveries. For each fund \(i\) it estimates three peer
performance ratios that sum to one:
The estimators implement the methodology of Ardia and Boudt (2018, Journal of Banking & Finance); the modified Sharpe ratio test follows Ardia and Boudt (2015, Finance Research Letters). A naive percentile rank ignores that many funds may be statistically indistinguishable; the false-discovery-rate (FDR) correction of Storey (2002) corrects for this.
alphaScreening() runs all pairwise tests and returns the
three ratios for each fund. With factors = NULL it compares
raw returns; supply a factors matrix to compare
risk-adjusted alphas.
set.seed(1234)
rets <- hfdata[, 1:15]
sc <- alphaScreening(rets, control = list(nCore = 1))
round(rbind(pipos = sc$pipos, pizero = sc$pizero, pineg = sc$pineg), 3)[, 1:6]
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> pipos 0.000 0 0.025 0 0.46 0.00
#> pizero 0.975 1 0.975 1 0.54 0.54
#> pineg 0.025 0 0.000 0 0.00 0.46The three ratios sum to one for every fund. A summary()
method ranks the funds and reports the win/loss counts:
summary(sc, top = 3)
#>
#> Peer performance screening summary (alpha)
#> Funds: 15
#>
#> alpha distribution: min -0.0060 | 25% -0.0002 | med 0.0022 | mean 0.0021 | 75% 0.0035 | max 0.0124
#>
#> Top funds (by alpha):
#> fund n npeer estimate lambda pizero pipos pineg wins losses net rank
#> Fund 12 60 14 0.0124 0.7000 0.0000 1.0000 0.0000 2 0 2 1
#> Fund 13 60 14 0.0080 0.7000 0.0000 0.9286 0.0714 0 0 0 2
#> Fund 15 60 14 0.0040 0.6000 0.3573 0.6427 0.0000 1 0 1 3
#>
#> Top funds (by outperformance ratio pi+):
#> fund n npeer estimate lambda pizero pipos pineg wins losses net rank
#> Fund 12 60 14 0.0124 0.7000 0.0000 1.0000 0.0000 2 0 2 1
#> Fund 13 60 14 0.0080 0.7000 0.0000 0.9286 0.0714 0 0 0 2
#> Fund 15 60 14 0.0040 0.6000 0.3573 0.6427 0.0000 1 0 1 3The ratios are point estimates; confint() attaches
confidence intervals by a nonparametric peer (pairwise) bootstrap that
resamples each fund’s peers:
set.seed(1234)
round(confint(sc, parm = "pipos")[1:6, ], 3)
#> 2.5% 97.5%
#> Fund 1 0 0.140
#> Fund 2 0 0.000
#> Fund 3 0 0.386
#> Fund 4 0 0.369
#> Fund 5 0 0.821
#> Fund 6 0 0.214The plot() method reproduces the Ardia and Boudt (2018)
screening plot (funds sorted by performance; stacked
out-/equal-/under-performance bars with the naive percentile-rank
diagonal):
The Y argument (or the convenience wrapper
targetPeerPerformance()) screens a chosen fund, or subset
of funds, against a separate universe.
All screening/testing functions share a control list.
Common fields include nCore (parallel cores),
lambda (the \(\lambda\)
threshold for \(\hat\pi^0\),
NULL = data-driven),
gammaPos/gammaNeg (the one-sided thresholds,
default 0.4/0.6), hac (HAC
standard errors), and for the Sharpe/mSR routines type
(asymptotic/bootstrap), nBoot, and bBoot. See
?alphaScreening.