Skip to content

Commit ee1e87c

Browse files
committed
cagr refactor
1 parent 8a6d767 commit ee1e87c

File tree

4 files changed

+14
-13
lines changed

4 files changed

+14
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Added
66

77
- `mean_excess` and `std_excess` helpers for allocation‑free mean and standard deviation of differences.
8+
- `cagr` function for calculating the compound annual growth rate of a series of returns, with support for simple and log returns.
89

910
### Changed
1011

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ log_returns(prices::AbstractMatrix; drop_first=false, first_value=NaN)
2020
total_return(returns::AbstractVector; method=:simple)
2121
total_return(returns::AbstractVector; method=:log)
2222

23-
cagr(returns::AbstractVector; periods_per_year::Real, method=:simple)
23+
cagr(returns::AbstractVector, periods_per_year::Real; method=:simple)
2424

2525
volatility(returns::AbstractVector; multiplier=1.0)
2626

src/returns.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ function total_return(returns::AbstractVector; method::Symbol=:simple)
449449
end
450450

451451
"""
452-
cagr(returns::AbstractVector; periods_per_year, method=:simple)
452+
cagr(returns::AbstractVector, periods_per_year; method=:simple)
453453
454454
Compute the Compound Annual Growth Rate (CAGR) from a series of periodic returns.
455455
Supports either simple returns (`method = :simple`) or log returns (`method = :log`).
@@ -484,16 +484,16 @@ julia> using RiskPerf
484484
485485
julia> monthly_r = fill((1.5)^(1/36) - 1, 36); # 3 years of monthly returns growing total 50%
486486
487-
julia> cagr(monthly_r; periods_per_year=12)
487+
julia> cagr(monthly_r, 12)
488488
0.1447146268169922 # ≈ (1.5)^(1/3) - 1
489489
490490
julia> log_monthly = log.(1 .+ monthly_r);
491491
492-
julia> cagr(log_monthly; periods_per_year=12, method=:log) ≈ cagr(monthly_r; periods_per_year=12)
492+
julia> cagr(log_monthly, 12; method=:log) ≈ cagr(monthly_r, 12)
493493
true
494494
```
495495
"""
496-
function cagr(returns::AbstractVector; periods_per_year::Real, method::Symbol=:simple)
496+
function cagr(returns::AbstractVector, periods_per_year::Real; method::Symbol=:simple)
497497
n = length(returns)
498498
n == 0 && return 0.0
499499
ppy = float(periods_per_year)

test/returns.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ end
9090
monthly_r = fill(monthly_growth^(1 / n) - 1, n)
9191
# Direct formula
9292
expected = monthly_growth^(1 / n_years) - 1
93-
@test cagr(monthly_r; periods_per_year=periods_per_year) expected atol = 1e-12
93+
@test cagr(monthly_r, periods_per_year) expected atol = 1e-12
9494

9595
# Log returns variant
9696
log_r = log.(1 .+ monthly_r)
97-
@test cagr(log_r; periods_per_year=periods_per_year, method=:log) expected atol = 1e-12
97+
@test cagr(log_r, periods_per_year; method=:log) expected atol = 1e-12
9898

9999
# Weekly example using simple returns
100100
weekly_growth = 2.0 # total double
@@ -103,16 +103,16 @@ end
103103
n2 = weeks_per_year * years
104104
weekly_r = fill(weekly_growth^(1 / n2) - 1, n2)
105105
expected2 = weekly_growth^(1 / years) - 1
106-
@test cagr(weekly_r; periods_per_year=weeks_per_year) expected2 atol = 1e-12
106+
@test cagr(weekly_r, weeks_per_year) expected2 atol = 1e-12
107107

108108
# Empty input
109-
@test cagr(Float64[]; periods_per_year=12) == 0.0
109+
@test cagr(Float64[], 12) == 0.0
110110

111111
# Invalid method
112-
@test_throws ArgumentError cagr(monthly_r; periods_per_year=12, method=:foo)
112+
@test_throws ArgumentError cagr(monthly_r, 12; method=:foo)
113113

114114
# Invalid periods_per_year values
115-
@test_throws ArgumentError cagr(monthly_r; periods_per_year=0)
116-
@test_throws ArgumentError cagr(monthly_r; periods_per_year=-12)
117-
@test_throws ArgumentError cagr(monthly_r; periods_per_year=Inf)
115+
@test_throws ArgumentError cagr(monthly_r, 0)
116+
@test_throws ArgumentError cagr(monthly_r, -12)
117+
@test_throws ArgumentError cagr(monthly_r, Inf)
118118
end

0 commit comments

Comments
 (0)