From 0c3b5cf2a97858bcfb00787482625df7956e3316 Mon Sep 17 00:00:00 2001 From: femtotrader Date: Sat, 27 Apr 2024 19:17:46 +0200 Subject: [PATCH] empty! --- docs/src/api.md | 7 ++++++ src/asset_return.jl | 19 ++++++++++++++- src/cumulative_return.jl | 6 +++++ src/drawdowns.jl | 14 +++++++++++ src/moments.jl | 6 +++++ src/sharpe.jl | 9 ++++++- src/std_dev.jl | 10 ++++++-- test/runtests.jl | 51 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 118 insertions(+), 4 deletions(-) diff --git a/docs/src/api.md b/docs/src/api.md index 7ba23b4..b20266e 100644 --- a/docs/src/api.md +++ b/docs/src/api.md @@ -12,6 +12,13 @@ CurrentModule = OnlinePortfolioAnalytics OnlinePortfolioAnalytics.OnlinePortfolioAnalytics ``` +### Functions + +```@docs +OnlineStats.fit! +Base.empty! +``` + ### Asset return ```@docs diff --git a/src/asset_return.jl b/src/asset_return.jl index a3e6638..45c9629 100644 --- a/src/asset_return.jl +++ b/src/asset_return.jl @@ -60,10 +60,19 @@ function OnlineStatsBase._fit!(stat::SimpleAssetReturn, data) end end +function Base.empty!(stat::SimpleAssetReturn{T}) where {T} + stat.value = missing + stat.n = 0 + stat.ready = false + stat.input_values.value = [] + stat.input_values.n = 0 +end + function expected_return_types(::Type{SimpleAssetReturn{T}}) where {T} (Union{Missing,T},) end + @doc """ $(TYPEDEF) @@ -114,7 +123,7 @@ function OnlineStatsBase._fit!(stat::LogAssetReturn, data) stat.n += 1 if stat.n > stat.period data_prev = stat.input_values[end-stat.period] - stat.value = log(data / data_prev) # log=ln (Neperian log not decimal log) + stat.value = log(data / data_prev) # log=ln (natural log not decimal log) return stat.value else stat.ready = true @@ -123,6 +132,14 @@ function OnlineStatsBase._fit!(stat::LogAssetReturn, data) end end +function Base.empty!(stat::LogAssetReturn{T}) where {T} + stat.value = missing + stat.n = 0 + stat.ready = false + stat.input_values.value = [] + stat.input_values.n = 0 +end + function expected_return_types(::Type{LogAssetReturn{T}}) where {T} (Union{Missing,T},) end diff --git a/src/cumulative_return.jl b/src/cumulative_return.jl index 1887bcc..9f816b0 100644 --- a/src/cumulative_return.jl +++ b/src/cumulative_return.jl @@ -23,3 +23,9 @@ function OnlineStatsBase._fit!(stat::CumulativeReturn, data) stat.n += 1 stat.value = value(stat.prod) end + +function Base.empty!(stat::CumulativeReturn{T}) where {T} + stat.value = zero(T) + stat.n = 0 + stat.prod = Prod(T) +end diff --git a/src/drawdowns.jl b/src/drawdowns.jl index 4c4f576..b951465 100644 --- a/src/drawdowns.jl +++ b/src/drawdowns.jl @@ -30,6 +30,13 @@ function OnlineStatsBase._fit!(stat::DrawDowns, ret) stat.value = ddowns end +function Base.empty!(stat::DrawDowns{T}) where {T} + stat.value = zero(T) + stat.n = 0 + stat.prod = Prod(T) + stat.extrema = Extrema(T) +end + @doc """ $(TYPEDEF) @@ -59,3 +66,10 @@ function OnlineStatsBase._fit!(stat::ArithmeticDrawDowns, ret) ddowns = (r1 / max_cumulative_returns) - 1 stat.value = ddowns end + +function Base.empty!(stat::ArithmeticDrawDowns{T}) where {T} + stat.value = zero(T) + stat.n = 0 + stat.sum = Sum(T) + stat.extrema = Extrema(T) +end diff --git a/src/moments.jl b/src/moments.jl index 2f25b03..05e1f89 100644 --- a/src/moments.jl +++ b/src/moments.jl @@ -28,6 +28,12 @@ function OnlineStatsBase._fit!(stat::AssetReturnMoments, ret) ) end +function Base.empty!(stat::AssetReturnMoments{T}) where {T} + stat.value = (mean = zero(T), std = zero(T), skewness = zero(T), kurtosis = zero(T)) + stat.n = 0 + stat.moments = Moments() +end + function expected_return_types(::Type{AssetReturnMoments{T}}) where {T} #return NamedTuple{ # (:mean, :std, :skewness, :kurtosis), diff --git a/src/sharpe.jl b/src/sharpe.jl index c8b5384..df270c1 100644 --- a/src/sharpe.jl +++ b/src/sharpe.jl @@ -21,7 +21,7 @@ mutable struct Sharpe{T} <: PortfolioAnalyticsSingleOutput{T} risk_free::T function Sharpe{T}(; period = 252, risk_free = 0) where {T} - new{T}(zero(T), 0, Mean(), StdDev{T}(), period, risk_free) + new{T}(zero(T), 0, Mean(T), StdDev{T}(), period, risk_free) end end @@ -34,3 +34,10 @@ function OnlineStatsBase._fit!(stat::Sharpe, data) sharpe = sqrt(stat.period) * (mean_return - stat.risk_free) / std_dev stat.value = sharpe end + +function Base.empty!(stat::Sharpe{T}) where {T} + stat.value = zero(T) + stat.n = 0 + stat.mean = Mean(T) + stat.stddev = StdDev(T) +end diff --git a/src/std_dev.jl b/src/std_dev.jl index 2f16ec2..5845d1e 100644 --- a/src/std_dev.jl +++ b/src/std_dev.jl @@ -12,8 +12,8 @@ mutable struct StdDev{T} <: PortfolioAnalyticsSingleOutput{T} variance::Variance function StdDev{T}() where {T} - variance = Variance() - new{T}(1, 0, variance) + variance = Variance(T) + new{T}(one(T), 0, variance) end end @@ -22,3 +22,9 @@ function OnlineStatsBase._fit!(stat::StdDev, data) stat.n += 1 stat.value = sqrt(value(stat.variance)) end + +function Base.empty!(stat::StdDev{T}) where {T} + stat.value = one(T) + stat.n = 0 + stat.variance = Variance(T) +end diff --git a/test/runtests.jl b/test/runtests.jl index f3c26ae..2016d68 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -61,6 +61,11 @@ const ATOL = 0.0001 ] @test sum(ismissing.(returns)) == sum(ismissing.(expected_returns)) @test all(isapprox.(returns[2:end], expected_returns[2:end], atol = ATOL)) + + empty!(stat) + @test ismissing(value(stat)) + @test stat.n == 0 + end end @@ -104,6 +109,10 @@ const ATOL = 0.0001 ] @test sum(ismissing.(returns)) == sum(ismissing.(expected_returns)) @test all(isapprox.(returns[2:end], expected_returns[2:end], atol = ATOL)) + + empty!(stat) + @test ismissing(value(stat)) + @test stat.n == 0 end end @@ -134,6 +143,11 @@ const ATOL = 0.0001 end subscribe!(mapped_source, observer) @test isapprox(stddev_returns[end], 0.1496, atol = ATOL) + + empty!(_stddev) + @test value(_stddev) == 1 + @test _stddev.n == 0 + @test value(_stddev.variance) == 1 end end @@ -220,6 +234,10 @@ const ATOL = 0.0001 ] @test all(isapprox.(cum_returns, expected_cum_returns, atol = ATOL)) + empty!(cum_ret) + @test cum_ret.n == 0 + @test value(cum_ret) == 0.0 + @test value(cum_ret.prod) == 1.0 end @testset "DrawDowns" begin @@ -259,6 +277,12 @@ const ATOL = 0.0001 -0.0768, ] @test all(isapprox.(drawdowns, expected_drawdowns, atol = ATOL)) + + empty!(_ddowns) + @test _ddowns.n == 0 + @test value(_ddowns) == 0.0 + @test value(_ddowns.prod) == 1.0 + @test _ddowns.extrema == Extrema() end @testset "Arithmetic" begin @@ -297,6 +321,12 @@ const ATOL = 0.0001 -0.0482, ] @test all(isapprox.(drawdowns, expected_drawdowns, atol = ATOL)) + + empty!(_ddowns) + @test _ddowns.n == 0 + @test value(_ddowns) == 0.0 + @test value(_ddowns.sum) == 0.0 + @test _ddowns.extrema == Extrema() end end @@ -333,6 +363,14 @@ const ATOL = 0.0001 @test isapprox(moments_latest.std, 0.1496, atol = ATOL) @test isapprox(moments_latest.skewness, 1.3688, atol = ATOL) @test isapprox(moments_latest.kurtosis, 2.1968, atol = ATOL) + + empty!(_moments) + @test _moments.n == 0 + @test value(_moments).mean == 0.0 + @test value(_moments).std == 0.0 + @test value(_moments).skewness == 0.0 + @test value(_moments).kurtosis == 0.0 + @test _moments.moments == Moments() end @testset "Sharpe" begin @@ -357,6 +395,12 @@ const ATOL = 0.0001 subscribe!(mapped_source, observer) @test isapprox(sharpes[end], 0.2886, atol = ATOL) + + #empty!(_sharpe) + #@test _sharpe.n == 0 + #@test value(_sharpe) == 0.0 + #@test _sharpe.mean == Mean() + #@test _sharpe.stddev == StdDev() end @testset "Sortino" begin @@ -381,6 +425,13 @@ const ATOL = 0.0001 subscribe!(mapped_source, observer) @test isapprox(sortinos[end], 11.4992, atol = ATOL) + + #empty!(_sortino) + #@test _sortino.n == 0 + #@test value(_sortino) == 0.0 + #@test _sortino.mean == Mean() + #@test _sortino.stddev == StdDev() + end end