FinanceRoutines.jl

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

PortfolioUtils.jl (1601B)


      1 @testset "Portfolio Return Calculations" begin
      2 
      3     import Dates: Date, Month
      4 
      5     # Create test data: 3 stocks, 12 months
      6     dates = repeat(Date(2020,1,1):Month(1):Date(2020,12,1), inner=3)
      7     df = DataFrame(
      8         datem = dates,
      9         permno = repeat([1, 2, 3], 12),
     10         ret = rand(36) .* 0.1 .- 0.05,
     11         mktcap = repeat([100.0, 200.0, 300.0], 12)
     12     )
     13 
     14     # Equal-weighted returns
     15     df_ew = calculate_portfolio_returns(df, :ret, :datem; weighting=:equal)
     16     @test nrow(df_ew) == 12
     17     @test "port_ret" in names(df_ew)
     18 
     19     # Value-weighted returns
     20     df_vw = calculate_portfolio_returns(df, :ret, :datem;
     21                                          weighting=:value, weight_col=:mktcap)
     22     @test nrow(df_vw) == 12
     23     @test "port_ret" in names(df_vw)
     24 
     25     # Grouped portfolios (e.g., by size group)
     26     df.group = repeat([1, 1, 2], 12)
     27     df_grouped = calculate_portfolio_returns(df, :ret, :datem;
     28                                               weighting=:value, weight_col=:mktcap,
     29                                               groups=:group)
     30     @test nrow(df_grouped) == 24  # 12 months x 2 groups
     31 
     32     # Error cases
     33     @test_throws ArgumentError calculate_portfolio_returns(df, :ret, :datem; weighting=:value)
     34     @test_throws ArgumentError calculate_portfolio_returns(df, :ret, :datem; weighting=:foo)
     35 
     36     # Missing handling
     37     allowmissing!(df, :ret)
     38     df.ret[1] = missing
     39     df_ew2 = calculate_portfolio_returns(df, :ret, :datem; weighting=:equal)
     40     @test nrow(df_ew2) == 12
     41     @test !ismissing(df_ew2.port_ret[1])  # should compute from non-missing stocks
     42 
     43 end