Created
November 4, 2016 20:12
-
-
Save jaymon0703/2a9195796a733db7822e7d91261bfbd1 to your computer and use it in GitHub Desktop.
R-view of Profit Hurdle in Harvey & Liu (2014)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### Required returns due to testing multiplicity ------ Harvey and Liu | |
### (2014): "Backtesting", Duke University | |
Profit_Hurdle <- function (num_tests, num_obs, alpha_sig, vol_annual, RHO){ | |
############################### | |
####### Parameter inputs ###### | |
### 'num_tests': No. of tests one allows for in multiple tests; | |
### 'num_obs': No. of monthly observations for a strategy; | |
### 'alpha_sig': Significance level (e.g., 5#); | |
### 'vol_annual': Annual return volatility (e.g., 0.05 or 5#). | |
NN <- num_tests | |
Obs <- num_obs | |
alpha0 <- alpha_sig | |
vol_anu <- vol_annual | |
###Independent test #### | |
#B_ind = norminv( (1- alpha0/2),0,1); | |
B_ind <- qnorm( (1- alpha0/2),0,1) | |
###Bonferroni #### | |
p0_mat <- alpha0/NN | |
t0_mat <- qnorm( (1-p0_mat/2),0,1) | |
BF <- t0_mat | |
###Input for Holm and BHY #### | |
###Parameter input from Harvey, Liu and Zhu (2014) ####### | |
para0 <- matrix(c(0, 1295, 3.9660*0.1, 5.4995*0.001, | |
0.2, 1377, 4.4589*0.1, 5.5508*0.001, | |
0.4, 1476, 4.8604*0.1, 5.5413*0.001, | |
0.6, 1773, 5.9902*0.1, 5.5512*0.001, | |
0.8, 3109, 8.3901*0.1, 5.5956*0.001), | |
nrow = 5, ncol = 4, byrow = TRUE) | |
### Interpolated parameter values based on user specified level of correlation RHO %%%%%%%%%% | |
if (RHO >= 0 & RHO < 0.2){ | |
para_inter <- ((0.2 - RHO)/0.2)*para0[1,] + ((RHO - 0)/0.2)*para0[2,] | |
} else if (RHO >= 0.2 & RHO < 0.4) { | |
para_inter <- ((0.4 - RHO)/0.2)*para0[2,] + ((RHO - 0.2)/0.2)*para0[3,] | |
} else if (RHO >= 0.4 & RHO < 0.6){ | |
para_inter <- ((0.6 - RHO)/0.2)*para0[3,] + ((RHO - 0.4)/0.2)*para0[4,] | |
} else if (RHO >= 0.6 & RHO < 0.8){ | |
para_inter <- ((0.8 - RHO)/0.2)*para0[4,] + ((RHO - 0.6)/0.2)*para0[5,] | |
} else if (RHO >= 0.8 & RHO < 1.0){ | |
para_inter <- ((0.8 - RHO)/0.2)*para0[4,] + ((RHO - 0.6)/0.2)*para0[5,] | |
} else { | |
### Default: para_vec = [0.2, 1377, 4.4589*0.1, 5.5508*0.001,M_simu] | |
para_inter <- para0[2,] ### Set at the preferred level if RHO is misspecified | |
} | |
WW <- 2000; ### Number of repetitions | |
### Generate a panel of t-ratios (WW*Nsim_tests) ### | |
Nsim_tests <- (floor(NN/para_inter[2]) + 1)*floor(para_inter[2]+1); # make sure Nsim_test >= num_tests | |
t_sample <- sample_random_multests(para_inter[1], Nsim_tests, para_inter[3], para_inter[4], WW) | |
### Holm ##### | |
HL_mat <- NULL | |
for(ww in 1:WW){ | |
yy <- t_sample[ww, 1:NN] ### Use the ww'th row of t-sample ### | |
p_sub <- 2*(1-pnorm(yy)) | |
p_new <- sort(p_sub) | |
KK <- length(p_new) | |
comp_vec <- NULL | |
for(kk in 1:KK){ | |
comp_vec[kk] <- alpha0/(KK + 1-kk) | |
} | |
comp_res <- p_new > comp_vec | |
comp_new <- cumsum(as.numeric(comp_res)) | |
if(sum(comp_new) == 0){ | |
HL <- 1.96 | |
} else { | |
p0 <- p_new[comp_new == 1] | |
HL <- qnorm((1 - p0/2),0,1) | |
} | |
HL_mat <- append(HL_mat, HL) | |
} | |
### BHY #### | |
BHY_mat <- NULL | |
for(ww in 1:WW){ | |
yy <- t_sample[ww, 1:NN] ### Use the ww'th row of t-sample ### | |
p_sub <- 2*(1-pnorm(yy)) | |
if(length(p_new) <= 1){ | |
BH00 <- 1.96 | |
} else { | |
p_new11 <- sort(p_sub, decreasing = TRUE) | |
KK <- length(p_new11) | |
comp_vec0 <- NULL | |
cons_vec <- 1:KK | |
cons_norm <- sum(1/cons_vec) | |
for(kk in 1:KK){ | |
comp_vec0[kk] <- (alpha0*kk)/(KK*cons_norm) | |
} | |
comp_vec <- sort(comp_vec0, decreasing = TRUE) | |
comp_res11 <- as.numeric(p_new11 <= comp_vec) | |
if(sum(comp_res11) == 0){ | |
BH00 <- 1.96; | |
} else { | |
p0 <- p_new11[comp_res11 ==1] | |
b0 <- which(abs(p_new11 - p0[1]) == min(abs(p_new11 - p0[1]))) | |
if(b0 == 1){ | |
p1 <- p0[1] | |
} else { | |
p1 <- p_new11[(b0-1)] | |
} | |
BH00 <- qnorm((1 - (p0[1]+p1)/4),0,1) | |
} | |
} | |
BHY_mat <- append(BHY_mat,BH00) | |
} | |
tcut_vec <- c(B_ind, BF, median(HL_mat), median(BHY_mat)) | |
ret_hur <- ((vol_anu/sqrt(12))/sqrt(Obs))*tcut_vec | |
print('Inputs:') | |
print(paste('Significance Level = ',alpha0*100)) | |
print(paste('Number of Observations = ', num_obs)) | |
print(paste('Annualized Return Volatility = ', vol_anu*100)) | |
print(paste('Assumed Number of Tests = ', NN)) | |
print(paste('Assumed Average Correlation = ', RHO)) | |
print('Outputs:') | |
print('Minimum Average Monthly Return:') | |
print(paste('Independent = ', ret_hur[1]*100)) | |
print(paste('Bonferroni = ', ret_hur[2]*100)) | |
print(paste('Holm = ', ret_hur[3]*100)) | |
print(paste('BHY = ', ret_hur[4]*100)) | |
print(paste('Average for Multiple Tests = ', mean(ret_hur[-1])*100)) | |
} | |
Profit_Hurdle(300, 240, 0.05, 0.1, 0.4) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment