(You can run the script online and see the results for yourself at https://rdrr.io/snippets/. Just paste the script there and, delete/comment the irrelevant lines following !!!
and click "Run".)
library(MASS)
library(GRS.test)
data("data") # Fama-French data: market's excess return and 25 portfolios (5x5, sorted on SMB and HML)
data=data/100 # because original data was in percent
N=25
T=nrow(data) # 630
Sigma=cov(data[,c(8:32,2)]) # empirical covariance matrix; the last column is the market, the other 25 columns are the portfolios
# !!! Choose one of the two following lines for H0 vs. H1:
alpha =rep(0,N+1) # Jensen's alpha, in this case zero for all assets
set.seed(-1); alpha=runif(n=N+1,min=-0.1001,max=0.1001) # Jensen's alpha, in this case nonzero for all assets
beta_m=rep(NA,N+1); for(i in 1:(N+1)) beta_m[i]=Sigma[i,N+1]/Sigma[N+1,N+1] # actual betas from Fama-French data
mu_mte=rep(mean(data[,2]),T) # expected value of market excess return, in this case time-constant and in line with Fama-French data
# Generate a matrix of returns according to the CAPM (normality is mainly for convenience):
set.seed(1); r_matrix=mvrnorm(n=T, mu=alpha+beta_m*mean(mu_mte), Sigma=Sigma)
# !!! Factor return matrix for the function GRS.test():
# choose one of the two following lines for the true underlying factor vs. a random, unrelated factor:
f_matrix=cbind(r_matrix[,N+1]) # true underlying factor returns
set.seed(999); f_matrix=cbind(rnorm(T,mean=5)) # random, unrelated factor returns
# GRS test
result=GRS.test(r_matrix[,1:N],f_matrix); print(round(c(result$GRS.stat,result$GRS.pval),3))
# Individual t-tests and individual estimates of alphas and betas
# (full dots ~ true, hollow circles ~ estimated):
par(mfrow=c(5,5),mar=c(2,2,0.5,0.5))
for(i in 1:N){
m1=lm(r_matrix[,i]~f_matrix); print(summary(m1))
true=c(alpha[i],beta_m[i]); estimated=as.numeric(m1$coef); ylim1=c(-0.05,2)
plot(estimated,ylim=ylim1,xlab="",ylab=""); points(true,pch=19)
}; par(mfrow=c(1,1),mar=c(5.1,4.1,4.1,2.1))