Skip to content

Commit

Permalink
Sortino
Browse files Browse the repository at this point in the history
  • Loading branch information
femtotrader committed Apr 23, 2024
1 parent 0a1c28f commit 72a61e9
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/OnlinePortfolioAnalytics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export CumulativeReturn
export DrawDowns, ArithmeticDrawDowns
export AssetReturnMoments
export Sharpe
export Sortino

export fit!, value

Expand All @@ -25,6 +26,7 @@ include("std_dev.jl")
include("drawdowns.jl")
include("moments.jl")
include("sharpe.jl")
include("sortino.jl")

include("value_at_risk.jl")

Expand Down
26 changes: 26 additions & 0 deletions src/sortino.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
mutable struct Sortino{T} <: PortfolioAnalytics{T}
value::T
n::Int

mean_ret::Mean
stddev_neg_ret::StdDev

period::Int
risk_free::T

function Sortino{T}(; period=252, risk_free=0) where {T}
new{T}(T(0), 0, Mean(), StdDev{T}(), period, risk_free)
end
end

function OnlineStatsBase._fit!(stat::Sortino, ret)
fit!(stat.mean_ret, ret)
if ret < 0
fit!(stat.stddev_neg_ret, ret)
end
stat.n += 1
mean_return = value(stat.mean_ret)
stddev_neg_return = value(stat.stddev_neg_ret)
sortino = sqrt(stat.period) * (mean_return - stat.risk_free) / stddev_neg_return
stat.value = sortino
end
22 changes: 21 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,28 @@ const weights = [0.4, 0.4, 0.2]
push!(sharpes, value)
end
subscribe!(mapped_source, observer)

@test isapprox(sharpes[end], 0.2886, atol = ATOL)
end

@testset "Sortino" begin
source = from(TSLA)
_ret = SimpleAssetReturn{Float64}()
_sortino = Sortino{Float64}()

mapped_source =
source |>
map(Union{Missing,Float64}, price -> (fit!(_ret, price);
value(_ret))) |>
filter(!ismissing) |>
map(Any, r -> (fit!(_sortino, r); value(_sortino)))

sortinos = Float64[]
function observer(value)
push!(sortinos, value)
end
subscribe!(mapped_source, observer)

@test isapprox(sortinos[end], 11.4992, atol = ATOL)
end
end

0 comments on commit 72a61e9

Please sign in to comment.