betas.jl (2061B)
1 # -------------------------------------------------------------------------------------------------- 2 # betas.jl 3 4 # estimating regressions on financial data ... 5 6 7 # List of exported functions 8 # -------------------------------------------------------------------------------------------------- 9 10 11 # -------------------------------------------------------------------------------------------------- 12 """ 13 calculate_rolling_betas(X, y; window=60, min_data=nothing, method=:linalg) 14 15 Calculate rolling betas using `window` months of returns. 16 """ 17 function calculate_rolling_betas(X, y; 18 window=60, min_data=nothing, 19 method = :linalg) 20 21 n, p = size(X) 22 _min_data = something(min_data, p) 23 24 res = Array{Union{Missing, Float64}}(missing, (n,p)) 25 26 if method == :linalg 27 for i in window:n 28 X_window = @view X[i-window+1:i, :] 29 y_window = @view y[i-window+1:i] 30 31 non_missing = .!any(ismissing.(X_window), dims=2)[:] .& .!ismissing.(y_window) 32 (sum(non_missing) < _min_data) && continue 33 34 X_non_missing = @view X_window[non_missing, :] 35 y_non_missing = @view y_window[non_missing] 36 37 res[i, :] = qr(X_non_missing) \ y_non_missing 38 end 39 elseif method == :lm 40 for i in window:n 41 X_window = @view X[i-window+1:i, :] 42 y_window = @view y[i-window+1:i] 43 44 non_missing = .!any(ismissing.(X_window), dims=2)[:] .& .!ismissing.(y_window) 45 (sum(non_missing) < _min_data) && continue 46 47 X_non_missing = @view X_window[non_missing, :] 48 y_non_missing = @view y_window[non_missing] 49 50 res[i, :] = coef(lm(disallowmissing(X_non_missing), disallowmissing(y_non_missing))) 51 end 52 else 53 throw(ArgumentError("method must be one of: :linalg, :lm")) 54 end 55 56 return res 57 end 58 # -------------------------------------------------------------------------------------------------- 59 60 61 # --------------------------------------------------------------------------------------------------