As with correlation, there are different ways to compute beta-values; in particular, if you aim to actually forecast them. But OLS-beta can be written as correlation times the ratio of volatilities of stock (regressand) and index (regressor).
Here is a small reproducible example:
P <- structure(c(3257.85, 3234.84, 3246.3, 3237.17, 3253.05, 3274.7,
3265.35, 3288.1, 3283.09, 3289.3, 3316.81, 3329.59,
1898.01, 1874.97, 1902.88, 1906.86, 1891.97, 1901.05,
1883.16, 1891.3, 1869.44, 1862.02, 1877.94, 1864.72,
160.62, 158.62, 159.03, 157.58, 160.09, 162.09, 161.34,
163.28, 162.13, 163.18, 166.17, 167.1),
.Dim = c(12L, 3L),
.Dimnames = list(c("2020-01-02", "2020-01-03", "2020-01-06",
"2020-01-07", "2020-01-08", "2020-01-09",
"2020-01-10", "2020-01-13", "2020-01-14",
"2020-01-15", "2020-01-16", "2020-01-17"),
c("SPX", "AMZN", "MSFT")))
## SPX AMZN MSFT
## 2020-01-02 3257.85 1898.01 160.62
## 2020-01-03 3234.84 1874.97 158.62
## 2020-01-06 3246.30 1902.88 159.03
## 2020-01-07 3237.17 1906.86 157.58
## 2020-01-08 3253.05 1891.97 160.09
## 2020-01-09 3274.70 1901.05 162.09
## 2020-01-10 3265.35 1883.16 161.34
## 2020-01-13 3288.10 1891.30 163.28
## 2020-01-14 3283.09 1869.44 162.13
## 2020-01-15 3289.30 1862.02 163.18
## 2020-01-16 3316.81 1877.94 166.17
## 2020-01-17 3329.59 1864.72 167.10
library("PMwR") ## for function 'returns'
R <- returns(P)
Correlations:
cor(R)
## SPX AMZN MSFT
## SPX 1.0000000 0.6143659 0.9518773
## AMZN 0.6143659 1.0000000 0.4572081
## MSFT 0.9518773 0.4572081 1.0000000
For beta, you'll need the volatilities, stored below in s. The resulting matrix holds the desired betas. The columns indicate the regressors, in the rows the regressand. So, for instance,
MSFT has a beta of 2.057 when regressed on SPX. Note that this matrix will not be symmetric.
s <- apply(R, 2, sd)
(1/s) %*% t(s) * cor(R)
## SPX AMZN MSFT
## [1,] 1.0000000 1.1226870 2.0574562
## [2,] 0.3361983 1.0000000 0.5407941
## [3,] 0.4403838 0.3865413 1.0000000
Some checks:
## beta of AMZN on SPX
lm(R[, "AMZN"] ~ R[, "SPX"])
## Call:
## lm(formula = R[, "AMZN"] ~ R[, "SPX"])
##
## Coefficients:
## (Intercept) R[, "SPX"]
## -0.003808 1.122687
## beta of MSFT on SPX
lm(R[, "MSFT"] ~ R[, "SPX"])
## Call:
## lm(formula = R[, "MSFT"] ~ R[, "SPX"])
##
## Coefficients:
## (Intercept) R[, "SPX"]
## -0.0004474 2.0574562
More convenient is to combine such regressions into one:
lm.fit(cbind(constant = 1, beta = R[, 1]), R[, -1])$coefficients
## AMZN MSFT
## constant -0.003808244 -0.0004474033
## beta 1.122686957 2.0574561738
lm.fit(cbind(constant = 1, beta = R[, 1]), R[, -1])$coefficients[2, ]
## AMZN MSFT
## 1.122687 2.057456
Compare this last result with the first row of the matrix computed initially.