FinanceRoutines.jl

Financial data routines for Julia
Log | Files | Refs | README | LICENSE

betas.jl (3260B)


      1 @testset verbose=true "betas tests ... " begin
      2 
      3     import Dates: Date, Month
      4     import Statistics: mean
      5 
      6 
      7 # -- generate a test dataframe
      8     function gen_dataset(; 
      9         return_noise = 0.0,
     10         missing_ratio = 0.0
     11         )
     12 
     13         dates = [ 
     14             Date(2010,1,1):Month(1):Date(2022,12,31),
     15             Date(2017,1,1):Month(1):Date(2024,12,31),
     16             Date(2000,1,1):Month(1):Date(2015,12,31)
     17             ]
     18         n = length(dates)
     19         firms = [1, 2, 3]
     20         α = [0, 0.1, 0.05]
     21         β = [0.8 1 1.2; 0.2 -0.3 0; -0.8 0.1 0]
     22 
     23         # generate aggregate factors
     24         date_factors = minimum(minimum.(dates)):Month(1):maximum(maximum.(dates))
     25         df_factors = DataFrame(
     26             datem = date_factors,
     27             mkt = accumulate((x,ϵ) -> 0.9*x + 0.1 * ϵ, randn(length(date_factors))),
     28             F1  = accumulate((x,ϵ) -> 0.5*x + 0.5 * ϵ, randn(length(date_factors))), 
     29             F2  = accumulate((x,ϵ) -> 0.05*x + 0.9 * ϵ, randn(length(date_factors)))
     30             )
     31         
     32         df_firms = [
     33             leftjoin(
     34                 DataFrame(
     35                     datem = dates[i], firm_id = firms[i], 
     36                     α = α[i], βmkt = β[1, i], βF1 = β[2, i], βF2 = β[3, i]),
     37                 df_factors, on = :datem)
     38             for i in 1:3]
     39         df_firms = reduce(vcat, df_firms)
     40         
     41         # -- estimate the return with some noise
     42         # @transform!(df_firms, 
     43         #     :ret = :α + :βmkt .* :mkt + :βF1 .* :F1 + :βF2 .* :F2 + 0.0.*randn(nrow(df_firms)) )
     44         transform!(df_firms,
     45             AsTable([:α, :βmkt, :mkt, :βF1, :F1, :βF2, :F2]) => 
     46             (n -> n.α + n.βmkt .* n.mkt + n.βF1 .* n.F1 + n.βF2 .* n.F2 + 0.0.*randn(nrow(df_firms))) => 
     47             :ret)
     48         allowmissing!(df_firms, :ret)
     49 
     50         # put some random missing ...     
     51         df_firms[rand(1:nrow(df_factors), round(Int, missing_ratio*nrow(df_factors))), :ret] .= missing;
     52         sort!(df_firms, [:firm_id, :datem])
     53 
     54         return df_firms
     55     end
     56 
     57 
     58 # -- test the function when we have fixed betas ... but we are running rolling regressions
     59     df_firms = gen_dataset()
     60     insertcols!(df_firms, :a => missing, :bmkt => missing, :bF1 => missing, :bF2 => missing)
     61 
     62     for subdf in groupby(df_firms, :firm_id)
     63         β = calculate_rolling_betas(
     64             [ones(nrow(subdf)) subdf.mkt subdf.F1 subdf.F2],
     65             subdf.ret; 
     66             window=60, min_data=nothing
     67         )
     68         # Create and assign columns for β coefficients
     69         subdf[!, [:a, :bmkt, :bF1, :bF2]] = β
     70     end
     71     
     72     df_test1 = @p df_firms |>
     73         subset(__, :a => ByRow(x -> !ismissing(x))) |>
     74         select(__, :datem, :firm_id, 
     75             [:a, :α]       => ByRow((x,y) -> x - y) => :Δ_a, 
     76             [:bmkt, :βmkt] => ByRow((x,y) -> x - y) => :Δ_bmkt, 
     77             [:bF1, :βF1]   => ByRow((x,y) -> x - y) => :Δ_bF1, 
     78             [:bF2, :βF2]   => ByRow((x,y) -> x - y) => :Δ_bF2) |> 
     79         groupby(__, :firm_id) |>
     80         combine(__, [:Δ_a, :Δ_bmkt, :Δ_bF1, :Δ_bF2] .=> mean, renamecols=false)
     81     
     82     @test isapprox.(0.0,
     83         maximum(abs.(Array(combine(df_test1, [:Δ_a, :Δ_bmkt, :Δ_bF1, :Δ_bF2] .=> mean)[1, :]))),
     84         atol = 1E-10)
     85 
     86 
     87 
     88 end
     89 
     90 
     91 
     92 
     93 
     94 
     95 
     96 
     97