| Title: | Luck-Corrected Peer Performance Analysis in R |
|---|---|
| Description: | Provides functions to perform the peer performance analysis of funds' returns as described in Ardia and Boudt (2018) <doi:10.1016/j.jbankfin.2017.10.014>. |
| Authors: | David Ardia [aut, cre, cph, fnd] (ORCID: <https://orcid.org/0000-0003-2823-782X>), Nabil Bouamara [ctb], Kris Boudt [aut] (ORCID: <https://orcid.org/0000-0002-1000-5142>), Sebastien Legros [ctb], Murilo Andre Peres Pereira [ctb] (ORCID: <https://orcid.org/0009-0007-0086-4801>), Benjamin Seguin [ctb] |
| Maintainer: | David Ardia <[email protected]> |
| License: | GPL (>= 2) |
| Version: | 2.4.0 |
| Built: | 2026-06-25 11:43:28 UTC |
| Source: | https://github.com/ardiad/peerperformance |
Function which performs the screening of a universe of returns, and computes the alpha outperformance ratio.
alphaScreening( X, factors = NULL, control = list(), screen_beta = NULL, Y = NULL )alphaScreening( X, factors = NULL, control = list(), screen_beta = NULL, Y = NULL )
X |
Matrix |
factors |
Matrix |
control |
Control parameters (see *Details*). |
screen_beta |
Boolean to screen all factors' coefficients (beta).
Default: |
Y |
Optional matrix |
The alpha measure (Treynor and Black 1973, Carhart 1997, Fung and Hsieh 2004) is one industry standard for measuring the absolute risk adjusted performance of hedge funds. We propose to complement the alpha measure with the fund's alpha outperformance ratio, defined as the percentage number of funds that have a significantly lower alpha. In a pairwise testing framework, a fund can have a significantly higher alpha because of luck. We correct for this by applying the false discovery rate approach by Storey (2002).
The methodology proceeds as follows:
(1) compute all pairwise tests of alpha differences. This means that for a universe of
funds, we perform tests. The algorithm has
been parallelized and the computational burden can be split across several
cores. The number of cores can be defined in control, see below.
(2) for each fund, the false discovery rate approach by Storey (2002) is used to determine the proportions of over, equal, and underperforming funds, in terms of alpha, in the database.
The argument control is a list that can supply any of the following
components:
'hac' Heteroscedastic-autocorrelation consistent
standard errors. Default: hac = FALSE.
'minObs' Minimum number of concordant observations to compute the ratios. Default:
minObs = 10.
'minObsPi' Minimum number of observations
for computing the p-values). Default: minObsPi = 1.
'nCore' Number of cores used to perform the screening. Default:
nCore = 1.
'lambda' Threshold value to compute pi0.
Default: lambda = NULL, i.e. data driven choice.
'gammaPos' One-sided quantile level (of the standard Normal
distribution) used as the critical value for counting outperformed peers.
Default: gammaPos = 0.4 (the value recommended in Ardia and Boudt, 2018).
'gammaNeg' One-sided quantile level (of the standard Normal
distribution) used as the critical value for counting peers that outperform
the focal fund. Default: gammaNeg = 0.6.
'screen_beta' Screen the factor exposures (betas) in addition to
the alpha; see the screen_beta argument. Default:
screen_beta = FALSE.
A list with the following components:
n: Vector (of length ) of number of non-NA
observations.
npeer: Vector (of length ) of number of available peers.
alpha: Vector (of length ) of unconditional alpha.
dalpha: Matrix (of size ) of alpha
differences.
tstat: Matrix (of size ) of t-statistics.
pval: Matrix (of size ) of p-values of test for alpha
differences.
lambda: Vector (of length ) of lambda values.
pizero: Vector (of length ) of probability of equal
performance.
pipos: Vector (of length ) of probability of outperformance
performance.
pineg: Vector (of length ) of probability of underperformance
performance.
Further details on the methodology with an application to the hedge fund industry is given in Ardia and Boudt (2018).
Application of the false discovery rate approach applied to the mutual fund industry has been presented in Barras, Scaillet and Wermers (2010).
Currently, the HAC asymptotic and studentized circular block bootstrap
presented in Ledoit and Wolf (2008) are not supported by the
alphaScreening function.
David Ardia and Kris Boudt.
Ardia, D., Boudt, K. (2015). Testing equality of modified Sharpe ratios. Finance Research Letters 13, pp.97–104. doi:10.1016/j.frl.2015.02.008
Ardia, D., Boudt, K. (2018). The peer performance ratios of hedge funds. Journal of Banking and Finance 87, pp.351–368. doi:10.1016/j.jbankfin.2017.10.014
Barras, L., Scaillet, O., Wermers, R. (2010). False discoveries in mutual fund performance: Measuring luck in estimated alphas. Journal of Finance 65(1), pp.179–216.
Carhart, M. (1997). On persistence in mutual fund performance. Journal of Finance 52(1), pp.57–82.
Fama, E., French, K. (2010). Luck versus skill in the cross-section of mutual fund returns. Journal of Finance 65(5), pp.1915–1947.
Fung, W., Hsieh, D. (2004). Hedge fund benchmarks: A risk based approach. Financial Analysts Journal 60(5), pp.65–80.
Storey, J. (2002). A direct approach to false discovery rates. Journal of the Royal Statistical Society B 64(3), pp.479–498.
Treynor, J. L., Black, F. (1973). How to use security analysis to improve portfolio selection. Journal of Business 46(1), pp.66–86.
sharpeScreening and msharpeScreening.
## Load the data (randomized data of monthly hedge fund returns) data("hfdata") rets = hfdata[,1:4] ## Run alpha screening ctr = list(nCore = 1) alphaScreening(rets, control = ctr) ## Run alpha screening with HAC standard deviation ctr = list(nCore = 1, hac = TRUE) alphaScreening(rets, control = ctr) ## Cross-group screening: a single focal fund against a peer group alphaScreening(hfdata[, 1], Y = hfdata[, 11:20], control = list(nCore = 1)) ## Cross-group screening: peer group X against peer group Y alphaScreening(hfdata[, 1:5], Y = hfdata[, 11:20], control = list(nCore = 1))## Load the data (randomized data of monthly hedge fund returns) data("hfdata") rets = hfdata[,1:4] ## Run alpha screening ctr = list(nCore = 1) alphaScreening(rets, control = ctr) ## Run alpha screening with HAC standard deviation ctr = list(nCore = 1, hac = TRUE) alphaScreening(rets, control = ctr) ## Cross-group screening: a single focal fund against a peer group alphaScreening(hfdata[, 1], Y = hfdata[, 11:20], control = list(nCore = 1)) ## Cross-group screening: peer group X against peer group Y alphaScreening(hfdata[, 1:5], Y = hfdata[, 11:20], control = list(nCore = 1))
Function which performs the testing of the difference of alpha outperformance ratios.
alphaTesting(x, y, factors = NULL, control = list(), screen_beta = NULL)alphaTesting(x, y, factors = NULL, control = list(), screen_beta = NULL)
x |
Vector (of length |
y |
Vector (of length |
factors |
Matrix |
control |
Control parameters (see *Details*). |
screen_beta |
Boolean to screen all factors' coefficients (beta).
Default: |
The alpha measure (Treynor and Black 1973, Carhart 1997, Fung and Hsieh 2004) is one industry standard for measuring the absolute risk adjusted performance of hedge funds. This function performs the testing of alpha outperformance ratio difference for two funds.
For the testing, only the intersection of non-NA observations for the
two funds are used.
The argument control is a list that can supply any of the following
components:
'hac' Heteroscedastic-autocorrelation consistent
standard errors. Default: hac = FALSE.
A list with the following components:
n: Number of non-NA concordant observations.
alpha: Vector (of length 2) of the two funds' unconditional alphas.
dalpha: Difference of the two funds' alphas.
tstat: t-stat of the alpha difference.
pval: p-value of the test of equal alpha.
When screen_beta = TRUE, alpha is a matrix (one row per
coefficient, the first being the alpha) and dalpha, tstat and
pval are vectors with one entry per coefficient; the print
method reports the alpha (first) coefficient only.
Further details on the methodology with an application to the hedge fund industry is given in Ardia and Boudt (2018).
Some internal functions where adapted from Michael Wolf MATLAB code.
David Ardia and Kris Boudt.
Ardia, D., Boudt, K. (2015). Testing equality of modified Sharpe ratios. Finance Research Letters 13, 97–104.
Ardia, D., Boudt, K. (2018). The peer performance ratios of hedge funds. Journal of Banking and Finance 87, 351–368.
Barras, L., Scaillet, O., Wermers, R. (2010). False discoveries in mutual fund performance: Measuring luck in estimated alphas. Journal of Finance 65(1), 179–216.
Sharpe, W.F. (1994). The Sharpe ratio. Journal of Portfolio Management 21(1), 49–58.
Ledoit, O., Wolf, M. (2008). Robust performance hypothesis testing with the Sharpe ratio. Journal of Empirical Finance 15(5), 850–859.
Storey, J. (2002). A direct approach to false discovery rates. Journal of the Royal Statistical Society B 64(3), 479–498.
## Load the data (randomized data of monthly hedge fund returns) data("hfdata") x = hfdata[,1] y = hfdata[,2] ## Run alpha testing alphaTesting(x, y)## Load the data (randomized data of monthly hedge fund returns) data("hfdata") x = hfdata[,1] y = hfdata[,2] ## Run alpha testing alphaTesting(x, y)
Returns a tidy data.frame with one row per fund (or, when
the screening was run with screen_beta = TRUE, one row per
fund/coefficient), suitable for downstream filtering, ranking, and plotting.
## S3 method for class 'SCREENING' as.data.frame(x, row.names = NULL, optional = FALSE, ...)## S3 method for class 'SCREENING' as.data.frame(x, row.names = NULL, optional = FALSE, ...)
x |
A |
row.names, optional
|
Currently ignored. |
... |
Further arguments (ignored). |
A data.frame with columns fund, the performance measure
(alpha, sharpe, or msharpe), pipos, pizero,
pineg, npeer, and lambda; a coefficient column is
added when screen_beta = TRUE.
David Ardia and Kris Boudt.
data("hfdata") sc <- alphaScreening(hfdata[, 1:10], control = list(nCore = 1)) head(as.data.frame(sc))data("hfdata") sc <- alphaScreening(hfdata[, 1:10], control = list(nCore = 1)) head(as.data.frame(sc))
Computes confidence intervals for one of the peer performance
ratios (, , or ) of a
SCREENING object, by a nonparametric peer (pairwise) bootstrap: for
each focal fund its peers are resampled with replacement and the ratio is
recomputed from the stored pairwise p-values and test statistics. The
interval therefore reflects the peer-composition and aggregation uncertainty,
holding the individual pairwise test statistics fixed.
## S3 method for class 'SCREENING' confint( object, parm = c("pipos", "pizero", "pineg"), level = 0.95, ..., nBoot = 499L, gammaPos = 0.4, gammaNeg = 0.6 )## S3 method for class 'SCREENING' confint( object, parm = c("pipos", "pizero", "pineg"), level = 0.95, ..., nBoot = 499L, gammaPos = 0.4, gammaNeg = 0.6 )
object |
A |
parm |
Which ratio to bound: |
level |
Confidence level. Default: |
... |
Unused. |
nBoot |
Number of bootstrap resamples. Default: |
gammaPos, gammaNeg
|
One-sided thresholds used to recompute the ratios
(should match those of the original screening). Defaults: |
A matrix with one row per fund and two columns (lower and upper
bounds); the point estimate is attached as attribute "estimate".
David Ardia and Kris Boudt.
data("hfdata") set.seed(1234) sc <- alphaScreening(hfdata[, 1:15], control = list(nCore = 1)) confint(sc, parm = "pipos")data("hfdata") set.seed(1234) sc <- alphaScreening(hfdata[, 1:15], control = list(nCore = 1)) confint(sc, parm = "pipos")
Aggregates the per-fund equal-performance ratios of a
screen_beta = TRUE alphaScreening into the
factor-by-factor heterogeneity measure of Ardia et al. (2023). For each
coefficient (the alpha and each factor beta) it reports the average
equal-exposure ratio and the
heterogeneity : the share of peers that are significantly
differentiated on coefficient . A value close to one indicates large
heterogeneity (much room to differentiate); close to zero, homogeneity.
exposureHeterogeneity(object)exposureHeterogeneity(object)
object |
A |
A data.frame of class exposureHeterogeneity with columns
coefficient, equalExposure (), and
heterogeneity ().
David Ardia and Kris Boudt.
Ardia, D., Bluteau, K., Lortie-Cloutier, G., Tran, D. (2023). Factor exposure heterogeneity in green and brown stocks. Finance Research Letters 55, Part A, 103900.
data("hfdata") set.seed(1234) fac <- matrix(rnorm(nrow(hfdata) * 2), ncol = 2, dimnames = list(NULL, c("MKT", "SMB"))) sc <- alphaScreening(hfdata[, 1:20], factors = fac, screen_beta = TRUE, control = list(nCore = 1)) exposureHeterogeneity(sc)data("hfdata") set.seed(1234) fac <- matrix(rnorm(nrow(hfdata) * 2), ncol = 2, dimnames = list(NULL, c("MKT", "SMB"))) sc <- alphaScreening(hfdata[, 1:20], factors = fac, screen_beta = TRUE, control = list(nCore = 1)) exposureHeterogeneity(sc)
The matrix hfdata contains randomized and modified monthly returns of hedge funds.
data(hfdata)data(hfdata)
A matrix of size 60 x 100, containing 60 monthly net returns for 100 hedge funds. Returns have been modified.
HFR database
Function which computes the modified Sharpe ratio
msharpe(X, level = 0.9, na.rm = TRUE, na.neg = TRUE)msharpe(X, level = 0.9, na.rm = TRUE, na.neg = TRUE)
X |
Vector (of length |
level |
Modified Value-at-Risk level. Default: |
na.rm |
A logical value indicating whether |
na.neg |
A logical value indicating whether |
The modified Sharpe ratio (Favre and Galeano 2002) is one industry standard for measuring the absolute risk adjusted performance of hedge funds.
Scalar or a vector (of size ) with the modified Sharpe
ratios.
David Ardia and Kris Boudt.
Ardia, D., Boudt, K. (2015). Testing equality of modified Sharpe ratios. Finance Research Letters 13, 97–104.
Ardia, D., Boudt, K. (2018). The peer performance ratios of hedge Funds. Journal of Banking and Finance 87, 351–368.
Favre, L., Galeano, J.A. (2002). Mean-modified Value-at-Risk Optimization with Hedge Funds. Journal of Alternative Investments 5(2), 21–25.
Gregoriou, G. N., Gueyie, J.-P. (2003). Risk-adjusted performance of funds of hedge funds using a modified Sharpe ratio. Journal of Wealth Management 6(3), 77–83.
msharpeTesting, msharpeScreening and
sharpe.
## Load the data (randomized data of monthly hedge fund returns) data('hfdata') out = msharpe(hfdata) print(out) out = msharpe(hfdata, na.rm = FALSE) print(out)## Load the data (randomized data of monthly hedge fund returns) data('hfdata') out = msharpe(hfdata) print(out) out = msharpe(hfdata, na.rm = FALSE) print(out)
Function which performs the screening of a universe of returns, and computes the modified Sharpe outperformance ratio.
msharpeScreening(X, level = 0.9, na.neg = TRUE, control = list(), Y = NULL)msharpeScreening(X, level = 0.9, na.neg = TRUE, control = list(), Y = NULL)
X |
Matrix |
level |
Modified Value-at-Risk level. Default: |
na.neg |
A logical value indicating whether |
control |
Control parameters (see *Details*). |
Y |
Optional matrix |
The modified Sharpe ratio (Favre and Galeano 2002, Gregoriou and Gueyie 2003) is one industry standard for measuring the absolute risk adjusted performance of hedge funds. We propose to complement the modified Sharpe ratio with the fund's outperformance ratio, defined as the percentage number of funds that have a significantly lower modified Sharpe ratio. In a pairwise testing framework, a fund can have a significantly higher modified Sharpe ratio because of luck. We correct for this by applying the false discovery rate approach by Storey (2002).
For the testing, only the intersection of non-NA observations for the
two funds are used.
The argument control is a list that can supply any of the following
components:
'type' Asymptotic approach (type = 1) or
studentized circular bootstrap approach (type = 2). Default:
type = 1.
'ttype' Test based on ratio (type = 1)
or product (type = 2). Default: type = 2.
'hac' heteroscedastic-autocorrelation consistent standard
errors. Default: hac = FALSE.
'nBoot' Number of
bootstrap replications for computing the p-value. Default: nBoot =
499.
'bBoot' Block length in the circular bootstrap. Default:
bBoot = 1, i.e. iid bootstrap. (The data-driven choice
bBoot = 0 is only available in msharpeTesting, not in
screening.)
'pBoot' Symmetric p-value (pBoot = 1) or
asymmetric p-value (pBoot = 2). Default: pBoot = 1.
'nCore' Number of cores to be used. Default: nCore = 1.
'minObs' Minimum number of concordant observations to compute
the ratios. Default: minObs = 10.
'minObsPi' Minimum number of observations to compute pi0. Default: minObsPi = 1.
'lambda' Threshold value to compute pi0. Default: lambda
= NULL, i.e. data driven choice.
'gammaPos' One-sided quantile level (of the standard Normal
distribution) used as the critical value for counting outperformed peers.
Default: gammaPos = 0.4 (the value recommended in Ardia and Boudt, 2018).
'gammaNeg' One-sided quantile level (of the standard Normal
distribution) used as the critical value for counting peers that outperform
the focal fund. Default: gammaNeg = 0.6.
A list with the following components:
n: Vector (of length ) of number of non-NA
observations.
npeer: Vector (of length ) of number of available peers.
msharpe: Vector (of length ) of unconditional modified Sharpe
ratios.
dmsharpe: Matrix (of size ) of modified Sharpe
ratios differences.
tstat: Matrix (of size ) of t-statistics.
pval: Matrix (of size ) of p-values of test for
modified Sharpe ratios differences.
lambda: Vector (of length ) of lambda values.
pizero: Vector (of length ) of probability of equal
performance.
pipos: Vector (of length ) of probability of outperformance
performance.
pineg: Vector (of length ) of probability of underperformance
performance.
Further details on the methodology with an application to the hedge fund industry is given in Ardia and Boudt (2018).
Some internal functions where adapted from Michael Wolf MATLAB code.
Application of the false discovery rate approach applied to the mutual fund industry has been presented in Barras, Scaillet and Wermers (2010).
David Ardia and Kris Boudt.
Ardia, D., Boudt, K. (2015). Testing equality of modified Sharpe ratios. Finance Research Letters 13, 97–104.
Ardia, D., Boudt, K. (2018). The peer performance ratios of hedge funds. Journal of Banking and Finance 87, 351–368.
Barras, L., Scaillet, O., Wermers, R. (2010). False discoveries in mutual fund performance: Measuring luck in estimated alphas. Journal of Finance 65(1), 179–216.
Favre, L., Galeano, J.A. (2002). Mean-modified Value-at-Risk Optimization with Hedge Funds. Journal of Alternative Investments 5(2), 21–25.
Gregoriou, G. N., Gueyie, J.-P. (2003). Risk-adjusted performance of funds of hedge funds using a modified Sharpe ratio. Journal of Wealth Management 6(3), 77–83.
Ledoit, O., Wolf, M. (2008). Robust performance hypothesis testing with the Sharpe ratio. Journal of Empirical Finance 15(5), 850–859.
Storey, J. (2002). A direct approach to false discovery rates. Journal of the Royal Statistical Society B 64(3), 479–498.
msharpe, msharpeTesting,
sharpeScreening and alphaScreening.
## Load the data (randomized data of monthly hedge fund returns) data("hfdata") rets = hfdata[,1:4] ## Modified Sharpe screening msharpeScreening(rets, control = list(nCore = 1)) ## Modified Sharpe screening with bootstrap and HAC standard deviation msharpeScreening(rets, control = list(nCore = 1, type = 2, hac = TRUE))## Load the data (randomized data of monthly hedge fund returns) data("hfdata") rets = hfdata[,1:4] ## Modified Sharpe screening msharpeScreening(rets, control = list(nCore = 1)) ## Modified Sharpe screening with bootstrap and HAC standard deviation msharpeScreening(rets, control = list(nCore = 1, type = 2, hac = TRUE))
Function which performs the testing of the difference of modified Sharpe ratios.
msharpeTesting(x, y, level = 0.9, na.neg = TRUE, control = list())msharpeTesting(x, y, level = 0.9, na.neg = TRUE, control = list())
x |
Vector (of length |
y |
Vector (of length |
level |
Modified Value-at-Risk level. Default: |
na.neg |
A logical value indicating whether |
control |
Control parameters (see *Details*). |
The modified Sharpe ratio (Favre and Galeano 2002) is one industry standard for measuring the absolute risk adjusted performance of hedge funds. This function performs the testing of modified Sharpe ratio difference for two funds using a similar approach than Ledoit and Wolf (2002). See also Gregoriou and Gueyie (2003).
For the testing, only the intersection of non-NA observations for the
two funds are used.
The argument control is a list that can supply any of the following
components:
'type' Asymptotic approach (type = 1) or
studentized circular bootstrap approach (type = 2). Default:
type = 1.
'ttype' Test based on ratio (type = 1)
or product (type = 2). Default: type = 2.
'hac' Heteroscedastic-autocorrelation consistent standard
errors. Default: hac = FALSE.
'minObs' Minimum number of concordant observations to compute the ratios. Default: minObs =
10.
'nBoot' Number of bootstrap replications for computing the
p-value. Default: nBoot = 499.
'bBoot' Block length in
the circular bootstrap. Default: bBoot = 1, i.e. iid bootstrap.
bBoot = 0 uses optimal block-length.
'pBoot' Symmetric
p-value (pBoot = 1) or asymmetric p-value (pBoot = 2).
Default: pBoot = 1.
A list with the following components:
n: Number of non-NA concordant observations.
msharpe: Vector (of length 2) of unconditional modified Sharpe
ratios.
dmsharpe: Modified Sharpe ratios difference.
tstat: t-stat of modified Sharpe ratios differences.
pval: pvalues of test of modified Sharpe ratios differences.
Further details on the methodology with an application to the hedge fund industry is given in Ardia and Boudt (2018).
Some internal functions where adapted from Michael Wolf MATLAB code.
David Ardia and Kris Boudt.
Ardia, D., Boudt, K. (2015). Testing equality of modified Sharpe ratios. Finance Research Letters 13, pp.97–104. doi:10.1016/j.frl.2015.02.008
Ardia, D., Boudt, K. (2018). The peer performance ratios of hedge funds. Journal of Banking and Finance 87, pp.351–368. doi:10.1016/j.jbankfin.2017.10.014
Barras, L., Scaillet, O., Wermers, R. (2010). False discoveries in mutual fund performance: Measuring luck in estimated alphas. Journal of Finance 65(1), pp.179–216.
Favre, L., Galeano, J.A. (2002). Mean-modified Value-at-Risk Optimization with Hedge Funds. Journal of Alternative Investments 5(2), pp.21–25.
Gregoriou, G. N., Gueyie, J.-P. (2003). Risk-adjusted performance of funds of hedge funds using a modified Sharpe ratio. Journal of Wealth Management 6(3), pp.77–83.
Ledoit, O., Wolf, M. (2008). Robust performance hypothesis testing with the Sharpe ratio. Journal of Empirical Finance 15(5), pp.850–859.
Storey, J. (2002). A direct approach to false discovery rates. Journal of the Royal Statistical Society B 64(3), pp.479–498.
msharpe, msharpeScreening and
sharpeTesting.
## Load the data (randomized data of monthly hedge fund returns) data("hfdata") x = hfdata[,1] y = hfdata[,2] ## Run modified Sharpe testing (asymptotic) ctr = list(type = 1) out = msharpeTesting(x, y, level = 0.95, control = ctr) print(out) ## Run modified Sharpe testing (asymptotic hac) ctr = list(type = 1, hac = TRUE) out = msharpeTesting(x, y, level = 0.95, control = ctr) print(out) ## Run modified Sharpe testing (iid bootstrap) set.seed(1234) ctr = list(type = 2, nBoot = 250) out = msharpeTesting(x, y, level = 0.95, control = ctr) print(out) ## Run modified Sharpe testing (circular bootstrap) set.seed(1234) ctr = list(type = 2, nBoot = 250, bBoot = 5) out = msharpeTesting(x, y, level = 0.95, control = ctr) print(out)## Load the data (randomized data of monthly hedge fund returns) data("hfdata") x = hfdata[,1] y = hfdata[,2] ## Run modified Sharpe testing (asymptotic) ctr = list(type = 1) out = msharpeTesting(x, y, level = 0.95, control = ctr) print(out) ## Run modified Sharpe testing (asymptotic hac) ctr = list(type = 1, hac = TRUE) out = msharpeTesting(x, y, level = 0.95, control = ctr) print(out) ## Run modified Sharpe testing (iid bootstrap) set.seed(1234) ctr = list(type = 2, nBoot = 250) out = msharpeTesting(x, y, level = 0.95, control = ctr) print(out) ## Run modified Sharpe testing (circular bootstrap) set.seed(1234) ctr = list(type = 2, nBoot = 250, bBoot = 5) out = msharpeTesting(x, y, level = 0.95, control = ctr) print(out)
PeerPerformance is an R package for the peer-performance evaluation of financial investments with
luck-correction, useful in the financial industry. In particular, it implements the peer performance ratios of Ardia and Boudt
(2018) which measure the percentage of peers a focal (hedge) fund outperforms and underperforms, after
correction for luck. It is useful for fund or portfolio managers to benchmark their investments or screen a universe of new funds.
In addition, the package implements the testing framework for the Sharpe and modified Sharpe ratios, described in
Ledoit and Wolf (2008) and Ardia and Boudt (2015). See also Ardia et al. (2022,2023) for applications in sustainable finance.
Alpha: alphaTesting and alphaScreening;
Sharpe ratio: sharpe, sharpeTesting and sharpeScreening;
Modified Sharpe ratio: msharpe, msharpeTesting and msharpeScreening;
Screening: alphaScreening, sharpeScreening, and msharpeScreening.
The latest version of the package is available at https://github.com/ArdiaD/PeerPerformance
By using PeerPerformance you agree to the following rules: (1) You must cite Ardia and Boudt (2018) in
working papers and published papers that use PeerPerformance (use citation("PeerPerformance")), (2) you
must place the URL https://CRAN.R-project.org/package=PeerPerformance in a footnote to help
others find PeerPerformance, and (3) you assume all risk for the use of PeerPerformance.
Full description of the methodologies implemented in the various functions is available in Ledoit and Wolf (2008) and Ardia and Boudt (2015, 2018).
David Ardia and Kris Boudt.
Ardia, D., Boudt, K. (2015). Testing equality of modified Sharpe ratios. Finance Research Letters 13, 97–104.
Ardia, D., Boudt, K. (2018). The peer performance ratios of hedge Funds. Journal of Banking and Finance 87, 351–368.
Ardia, D., Bluteau, K., Tran, D. (2022). How easy is it for investment managers to deploy their talent in green and brown stocks? Finance Research Letters 48, 102992.
Ardia, D., Bluteau, K., Lortie-Cloutier, G., Tran, D. (2023). Factor exposure heterogeneity in green and brown stocks. Finance Research Letters 55, Part A, 103900.
Barras, L., Scaillet, O., Wermers, R. (2010). False discoveries in mutual fund performance: Measuring luck in estimated alphas. Journal of Finance 65(1), 179–216.
Favre, L., Galeano, J.A. (2002). Mean-modified Value-at-Risk Optimization with Hedge Funds. Journal of Alternative Investments 5(2), 21–25.
Gregoriou, G. N., Gueyie, J.-P. (2003). Risk-adjusted performance of funds of hedge funds using a modified Sharpe ratio. Journal of Wealth Management 6(3), 77–83.
Ledoit, O., Wolf, M. (2008). Robust performance hypothesis testing with the Sharpe ratio. Journal of Empirical Finance 15(5), 850–859.
Sharpe, W.F. (1994). The Sharpe ratio. Journal of Portfolio Management 21(1), 49–58.
Storey, J. (2002). A direct approach to false discovery rates. Journal of the Royal Statistical Society B 64(3), 479–498.
Bar plot of the heterogeneity measure returned by
exposureHeterogeneity.
## S3 method for class 'exposureHeterogeneity' plot(x, ...)## S3 method for class 'exposureHeterogeneity' plot(x, ...)
x |
An |
... |
Further arguments passed to |
Invisibly returns x.
David Ardia and Kris Boudt.
data("hfdata") sc <- alphaScreening(hfdata[, 1:10], factors = hfdata[, 50:51], control = list(nCore = 1, screen_beta = TRUE)) plot(exposureHeterogeneity(sc))data("hfdata") sc <- alphaScreening(hfdata[, 1:10], factors = hfdata[, 50:51], control = list(nCore = 1, screen_beta = TRUE)) plot(exposureHeterogeneity(sc))
Time-series plot of the rolling peer performance ratios produced
by rollScreening.
## S3 method for class 'rollScreening' plot(x, what = NULL, legend = TRUE, ...)## S3 method for class 'rollScreening' plot(x, what = NULL, legend = TRUE, ...)
x |
A |
what |
Either |
legend |
A logical value indicating whether to draw a legend. Default:
|
... |
Further graphical arguments. |
Invisibly returns x.
David Ardia and Kris Boudt.
data("hfdata") roll <- rollScreening(hfdata[, 1:15], width = 36, by = 12, control = list(nCore = 1)) plot(roll)data("hfdata") roll <- rollScreening(hfdata[, 1:15], width = 36, by = 12, control = list(nCore = 1)) plot(roll)
Plot method for the SCREENING object returned by
alphaScreening, sharpeScreening and
msharpeScreening. It reproduces the peer performance
screening plot of Ardia and Boudt (2018): funds are sorted by their
performance measure and, for each fund, the estimated outperformance
(), equal-performance () and underperformance
() ratios are displayed as a horizontal stacked bar. The
dashed diagonal lines depict the naive percentile-rank benchmark
(); the gap between the black area and the
diagonal visualizes the luck correction.
## S3 method for class 'SCREENING' plot( x, nblock = NULL, reference = NULL, band = 27.5, colorset = c(grDevices::gray(0), grDevices::gray(0.8), grDevices::gray(0.5)), ... )## S3 method for class 'SCREENING' plot( x, nblock = NULL, reference = NULL, band = 27.5, colorset = c(grDevices::gray(0), grDevices::gray(0.8), grDevices::gray(0.5)), ... )
x |
A |
nblock |
Optional number of equally-sized blocks into which the funds
(sorted by performance) are aggregated by averaging, as in Ardia and Boudt
(2018). Default: |
reference |
A logical value indicating whether the dashed
percentile-rank reference lines should be drawn. Default:
|
band |
Half-width (in percentage points) of the reference band drawn
around the central diagonal. Default: |
colorset |
Vector of three colors for the |
... |
Further graphical arguments passed to |
If the screening was run with screen_beta = TRUE, the alpha
(first) coefficient is used.
Invisibly returns the (sorted, possibly aggregated) matrix of ratios that is plotted.
David Ardia and Kris Boudt.
Ardia, D., Boudt, K. (2018). The peer performance ratios of hedge funds. Journal of Banking and Finance 87, pp.351–368. doi:10.1016/j.jbankfin.2017.10.014
alphaScreening, sharpeScreening and
msharpeScreening.
data("hfdata") set.seed(1234) sc <- alphaScreening(hfdata[, 1:30], control = list(nCore = 1)) plot(sc)data("hfdata") set.seed(1234) sc <- alphaScreening(hfdata[, 1:30], control = list(nCore = 1)) plot(sc)
Print method for the SCREENING object returned by
alphaScreening, sharpeScreening and
msharpeScreening.
## S3 method for class 'SCREENING' print(x, ...)## S3 method for class 'SCREENING' print(x, ...)
x |
A |
... |
Further arguments passed to or from other methods. |
Invisibly returns x.
David Ardia and Kris Boudt.
alphaScreening, sharpeScreening,
msharpeScreening and plot.SCREENING.
Print method for the object returned by
summary.SCREENING.
## S3 method for class 'summary.SCREENING' print(x, ...)## S3 method for class 'summary.SCREENING' print(x, ...)
x |
A |
... |
Further arguments (ignored). |
Invisibly returns x.
Murilo Andre Peres Pereira, David Ardia and Kris Boudt.
Print method for the TESTING object returned by
sharpeTesting, msharpeTesting and
alphaTesting.
## S3 method for class 'TESTING' print(x, ...)## S3 method for class 'TESTING' print(x, ...)
x |
A |
... |
Further arguments passed to or from other methods. |
Invisibly returns x.
David Ardia and Kris Boudt.
sharpeTesting, msharpeTesting and
alphaTesting.
Runs a peer performance screening on a rolling time window and
returns the time series of cross-sectionally averaged peer performance
ratios. This is the design underlying the dynamic analyses of Ardia et al.
(2022, 2023): on each window the screening is computed and the ratios are
averaged across funds (per coefficient when screen_beta = TRUE),
yielding a series of (factor exposure) heterogeneity measures.
rollScreening( X, factors = NULL, Y = NULL, screen = c("alpha", "sharpe", "msharpe"), width = 36L, by = 1L, level = 0.9, na.neg = TRUE, control = list(), dates = NULL )rollScreening( X, factors = NULL, Y = NULL, screen = c("alpha", "sharpe", "msharpe"), width = 36L, by = 1L, level = 0.9, na.neg = TRUE, control = list(), dates = NULL )
X |
Matrix |
factors |
Matrix |
Y |
Optional matrix |
screen |
Performance measure to screen on: |
width |
Window length (number of observations). Default: |
by |
Step (in observations) between successive windows. Default:
|
level |
Modified Value-at-Risk level (for |
na.neg |
A logical value passed to |
control |
Control parameters passed to the screening function (see
|
dates |
Optional vector of length |
A data.frame of class rollScreening with one row per
window (or per window/coefficient when screen_beta = TRUE), with
columns window, index (end-of-window row), optionally
date, coefficient, the averaged pizero/pipos/
pineg, and heterogeneity ().
David Ardia and Kris Boudt.
Ardia, D., Bluteau, K., Tran, D. (2022). How easy is it for investment managers to deploy their talent in green and brown stocks? Finance Research Letters 48, 102992.
Ardia, D., Bluteau, K., Lortie-Cloutier, G., Tran, D. (2023). Factor exposure heterogeneity in green and brown stocks. Finance Research Letters 55, Part A, 103900.
alphaScreening, exposureHeterogeneity.
data("hfdata") set.seed(1234) roll <- rollScreening(hfdata, screen = "alpha", width = 36, by = 6, control = list(nCore = 1)) plot(roll)data("hfdata") set.seed(1234) roll <- rollScreening(hfdata, screen = "alpha", width = 36, by = 6, control = list(nCore = 1)) plot(roll)
Function which computes the Sharpe ratio.
sharpe(X, na.rm = TRUE)sharpe(X, na.rm = TRUE)
X |
Vector (of length |
na.rm |
A logical value indicating whether |
The Sharpe ratio (Sharpe 1994) is one industry standard for measuring the absolute risk adjusted performance of hedge funds.
A scalar or a vector (of size ) with the Sharpe ratios.
David Ardia and Kris Boudt.
Ardia, D., Boudt, K. (2015). Testing equality of modified Sharpe ratios. Finance Research Letters 13, pp.97–104. doi:10.1016/j.frl.2015.02.008
Ardia, D., Boudt, K. (2016). The Peer Ratios Performance of Hedge Funds. Working paper. doi:10.2139/ssrn.2000901
Sharpe, W.F. (1994). The Sharpe ratio. Journal of Portfolio Management 21(1), pp.49–58. doi:10.3905/jpm.1994.409501
sharpeTesting, sharpeScreening and
msharpe.
## Load the data data('hfdata') ## Compute the Sharpe ratio out = sharpe(hfdata) print(out) out = sharpe(hfdata, na.rm = FALSE) print(out)## Load the data data('hfdata') ## Compute the Sharpe ratio out = sharpe(hfdata) print(out) out = sharpe(hfdata, na.rm = FALSE) print(out)
Function which performs the screening of a universe of returns, and computes the Sharpe outperformance ratio.
sharpeScreening(X, control = list(), Y = NULL)sharpeScreening(X, control = list(), Y = NULL)
X |
Matrix |
control |
Control parameters (see *Details*). |
Y |
Optional matrix |
The Sharpe ratio (Sharpe 1994) is one industry standard for measuring the absolute risk adjusted performance of hedge funds. We propose to complement the Sharpe ratio with the fund's outperformance ratio, defined as the percentage number of funds that have a significantly lower Sharpe ratio. In a pairwise testing framework, a fund can have a significantly higher Sharpe ratio because of luck. We correct for this by applying the false discovery rate approach by Storey (2002).
For the testing, only the intersection of non-NA observations for the
two funds are used.
The methodology proceeds as follows:
(1) compute all
pairwise tests of Sharpe differences using the bootstrap approach of Ledoit
and Wolf (2002). This means that for a universe of funds, we perform
tests. The algorithm has been parallelized and the
computational burden can be split across several cores. The number of cores
can be defined in control, see below.
(2) for each fund, the false discovery rate approach by Storey (2002) is used to determine the proportions over, equal, and underperforming funds, in terms of Sharpe ratio, in the database.
The argument control is a list that can supply any of the following
components:
'type' Asymptotic approach (type = 1) or
studentized circular bootstrap approach (type = 2). Default:
type = 1.
'ttype' Test based on ratio (type = 1)
or product (type = 2). Default: type = 2.
'hac' Heteroscedastic-autocorrelation consistent standard
errors. Default: hac = FALSE.
'nBoot' Number of bootstrap replications for computing the p-value. Default: nBoot =
499.
'bBoot' Block length in the circular bootstrap. Default:
bBoot = 1, i.e. iid bootstrap. (The data-driven choice
bBoot = 0 is only available in sharpeTesting, not in
screening.)
'pBoot' Symmetric p-value (pBoot = 1) or
asymmetric p-value (pBoot = 2). Default: pBoot = 1.
'nCore' Number of cores to be used. Default: nCore = 1.
'minObs' Minimum number of concordant observations to compute
the ratios. Default: minObs = 10.
'minObsPi' Minimum
number of observations to compute pi0. Default: minObsPi = 1.
'lambda' Threshold value to compute pi0. Default: lambda
= NULL, i.e. data driven choice.
'gammaPos' One-sided quantile level (of the standard Normal
distribution) used as the critical value for counting outperformed peers.
Default: gammaPos = 0.4 (the value recommended in Ardia and Boudt, 2018).
'gammaNeg' One-sided quantile level (of the standard Normal
distribution) used as the critical value for counting peers that outperform
the focal fund. Default: gammaNeg = 0.6.
A list with the following components:
n: Vector (of length ) of number of non-NA
observations.
npeer: Vector (of length ) of number of available peers.
sharpe: Vector (of length ) of unconditional Sharpe ratios.
dsharpe: Matrix (of size ) of Sharpe ratios
differences.
tstat: Matrix (of size ) of t-statistics.
pval: Matrix (of size ) of pvalues of test for Sharpe
ratios differences.
lambda: vector (of length ) of lambda values.
pizero: vector (of length ) of probability of equal
performance.
pipos: vector (of length ) of probability of outperformance
performance.
pineg: Vector (of length ) of probability of underperformance
performance.
Further details on the methodology with an application to the hedge fund industry is given in Ardia and Boudt (2018).
Some internal functions where adapted from Michael Wolf MATLAB code.
Application of the false discovery rate approach applied to the mutual fund industry has been presented in Barras, Scaillet and Wermers (2010).
David Ardia and Kris Boudt.
Ardia, D., Boudt, K. (2015). Testing equality of modified Sharpe ratios. Finance Research Letters 13, 97–104.
Ardia, D., Boudt, K. (2018). The peer performance ratios of hedge funds. Journal of Banking and Finance 87, 351–368.
Barras, L., Scaillet, O., Wermers, R. (2010). False discoveries in mutual fund performance: Measuring luck in estimated alphas. Journal of Finance 65(1), 179–216.
Sharpe, W.F. (1994). The Sharpe ratio. Journal of Portfolio Management 21(1), 49–58.
Ledoit, O., Wolf, M. (2008). Robust performance hypothesis testing with the Sharpe ratio. Journal of Empirical Finance 15(5), 850–859.
Storey, J. (2002). A direct approach to false discovery rates. Journal of the Royal Statistical Society B 64(3), 479–498.
sharpe, sharpeTesting,
msharpeScreening and alphaScreening.
## Load the data (randomized data of monthly hedge fund returns) data("hfdata") rets = hfdata[,1:4] ## Sharpe screening sharpeScreening(rets, control = list(nCore = 1)) ## Sharpe screening with bootstrap and HAC standard deviation sharpeScreening(rets, control = list(nCore = 1, type = 2, hac = TRUE))## Load the data (randomized data of monthly hedge fund returns) data("hfdata") rets = hfdata[,1:4] ## Sharpe screening sharpeScreening(rets, control = list(nCore = 1)) ## Sharpe screening with bootstrap and HAC standard deviation sharpeScreening(rets, control = list(nCore = 1, type = 2, hac = TRUE))
Function which performs the testing of the difference of Sharpe ratios.
sharpeTesting(x, y, control = list())sharpeTesting(x, y, control = list())
x |
Vector (of length |
y |
Vector (of length |
control |
Control parameters (see *Details*). |
The Sharpe ratio (Sharpe 1994) is one industry standard for measuring the absolute risk adjusted performance of hedge funds. This function performs the testing of Sharpe ratio difference for two funds using the approach by Ledoit and Wolf (2002).
For the testing, only the intersection of non-NA observations for the
two funds are used.
The argument control is a list that can supply any of the following
components:
'type' Asymptotic approach (type = 1) or
studentized circular bootstrap approach (type = 2). Default:
type = 1.
'ttype' Test based on ratio (type = 1)
or product (type = 2). Default: type = 2.
'hac' Heteroscedastic-autocorrelation consistent standard
errors. Default: hac = FALSE.
'nBoot' Number of bootstrap replications for computing the p-value. Default: nBoot =
499.
'bBoot' Block length in the circular bootstrap. Default:
bBoot = 1, i.e. iid bootstrap. bBoot = 0 uses optimal
block-length.
'pBoot' Symmetric p-value (pBoot = 1) or
asymmetric p-value (pBoot = 2). Default: pBoot = 1.
A list with the following components:
n: Number of non-NA concordant observations.
sharpe: Vector (of length 2) of unconditional Sharpe ratios.
dsharpe: Sharpe ratios difference.
tstat: t-stat of Sharpe ratios differences.
pval: pvalues of test of Sharpe ratios differences.
Further details on the methodology with an application to the hedge fund industry is given in Ardia and Boudt (2018).
Some internal functions where adapted from Michael Wolf MATLAB code.
David Ardia and Kris Boudt.
Ardia, D., Boudt, K. (2015). Testing equality of modified Sharpe ratios. Finance Research Letters 13, 97–104.
Ardia, D., Boudt, K. (2018). The peer performance ratios of hedge funds. Journal of Banking and Finance 87, 351–368.
Barras, L., Scaillet, O., Wermers, R. (2010). False discoveries in mutual fund performance: Measuring luck in estimated alphas. Journal of Finance 65(1), 179–216.
Sharpe, W.F. (1994). The Sharpe ratio. Journal of Portfolio Management 21(1), 49–58.
Ledoit, O., Wolf, M. (2008). Robust performance hypothesis testing with the Sharpe ratio. Journal of Empirical Finance 15(5), 850–859.
Storey, J. (2002). A direct approach to false discovery rates. Journal of the Royal Statistical Society B 64(3), 479–498.
sharpe, sharpeScreening and
msharpeTesting.
## Load the data (randomized data of monthly hedge fund returns) data("hfdata") x = hfdata[,1] y = hfdata[,2] ## Run Sharpe testing (asymptotic) ctr = list(type = 1) out = sharpeTesting(x, y, control = ctr) print(out) ## Run Sharpe testing (asymptotic hac) ctr = list(type = 1, hac = TRUE) out = sharpeTesting(x, y, control = ctr) print(out) ## Run Sharpe testing (iid bootstrap) set.seed(1234) ctr = list(type = 2, nBoot = 100) out = sharpeTesting(x, y, control = ctr) print(out) ## Run Sharpe testing (circular bootstrap) set.seed(1234) ctr = list(type = 2, nBoot = 100, bBoot = 5) out = sharpeTesting(x, y, control = ctr) print(out)## Load the data (randomized data of monthly hedge fund returns) data("hfdata") x = hfdata[,1] y = hfdata[,2] ## Run Sharpe testing (asymptotic) ctr = list(type = 1) out = sharpeTesting(x, y, control = ctr) print(out) ## Run Sharpe testing (asymptotic hac) ctr = list(type = 1, hac = TRUE) out = sharpeTesting(x, y, control = ctr) print(out) ## Run Sharpe testing (iid bootstrap) set.seed(1234) ctr = list(type = 2, nBoot = 100) out = sharpeTesting(x, y, control = ctr) print(out) ## Run Sharpe testing (circular bootstrap) set.seed(1234) ctr = list(type = 2, nBoot = 100, bBoot = 5) out = sharpeTesting(x, y, control = ctr) print(out)
Produces a ranked summary of a screening: distribution of the performance measure, the peer performance ratios, optional win/loss counts from the pairwise tests, and the top/bottom funds (overall and by out-/underperformance ratio). Originally contributed by Murilo Andre Peres Pereira.
## S3 method for class 'SCREENING' summary(object, coef = 1L, top = 5L, p_level = 0.05, ...)## S3 method for class 'SCREENING' summary(object, coef = 1L, top = 5L, p_level = 0.05, ...)
object |
A |
coef |
For a |
top |
Number of best/worst funds to display. Default: 5. |
p_level |
Significance level for the win/loss counts (used only when the
object carries square |
... |
Further arguments (ignored). |
An object of class summary.SCREENING.
Murilo Andre Peres Pereira, David Ardia and Kris Boudt.
data("hfdata") sc <- alphaScreening(hfdata[, 1:10], control = list(nCore = 1)) summary(sc)data("hfdata") sc <- alphaScreening(hfdata[, 1:10], control = list(nCore = 1)) summary(sc)
Performs peer-performance screening for a user-selected subset of
funds (the “focal” funds) against the whole universe, returning
detailed outputs for those focal funds only. It is a convenience wrapper that
calls the corresponding screening function with the cross-group argument
Y set to the full matrix X; equivalently,
targetPeerPerformance(X, funds, "alpha") is
alphaScreening(X[, funds], Y = X).
targetPeerPerformance( X, funds, method = c("alpha", "sharpe", "msharpe"), factors = NULL, level = 0.9, na.neg = TRUE, control = list() )targetPeerPerformance( X, funds, method = c("alpha", "sharpe", "msharpe"), factors = NULL, level = 0.9, na.neg = TRUE, control = list() )
X |
Matrix |
funds |
Integer indices or character column names identifying the focal
funds. The output preserves the order provided in |
method |
Screening method: |
factors |
Optional matrix of factor returns (only when
|
level |
Modified Value-at-Risk level (only when |
na.neg |
Logical; return |
control |
Control parameters (see |
A SCREENING object (see alphaScreening) whose
fund-level components (pizero, pipos, pineg, the
performance measure, npeer, ...) cover the focal funds only, and
whose pval/tstat/difference matrices have one row per focal fund
and one column per universe fund. Works with the print, plot,
summary, and as.data.frame methods.
Murilo Andre Peres Pereira, David Ardia and Kris Boudt.
alphaScreening, sharpeScreening,
msharpeScreening.
data("hfdata") rets <- hfdata[, 1:10] ## focal Sharpe screening (funds by index) against the whole universe out <- targetPeerPerformance(rets, funds = c(2, 5, 7), method = "sharpe", control = list(nCore = 1)) out$sharpedata("hfdata") rets <- hfdata[, 1:10] ## focal Sharpe screening (funds by index) against the whole universe out <- targetPeerPerformance(rets, funds = c(2, 5, 7), method = "sharpe", control = list(nCore = 1)) out$sharpe