Plotting: private API
PortfolioOptimisers.relevant_assets — Function
relevant_assets(
w::AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
M::Integer
) -> Tuple{Any, Any}
relevant_assets(
w::AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
M::Integer,
N_opt::Union{Nothing, Number}
) -> Tuple{Any, Any}
Select the top-N assets from a weight vector by absolute weight magnitude.
The ranking is taken over finite_magnitudes, so a non-investable asset ranks below every live one and counts for nothing. The frame is unchanged when the count does not truncate, which is the drawn plots' rule.
Arguments
w::VecNum: Portfolio weight vector.M::Integer: Total number of assets (upper bound forN).N_opt::Option{<:Number} = nothing: Asset-count specification.nothingauto-selects vianumber_effective_assets.
Returns
Tuple{Int, Vector{Int}}:(N, idx)whereNis the number of selected assets andidxis a permutation vector sorted descending by|w|, with a non-finite entry last.
Details
- When
N_optisnothing,N_eff = number_effective_assets(finite_magnitudes(w)). - When
0 < N_eff ≤ 1,N_effis treated as a concentration threshold:Nis the smallest index such that the cumulative normalised absolute weight covers at least1 - N_effof the total; falls back toMif no such index exists. - Otherwise
N_effis treated as a count:N = clamp(ceil(Int, N_eff), 1, M).
Related
PortfolioOptimisers.finite_magnitudes — Function
finite_magnitudes(
v::AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}}
) -> Any
Take the ranking magnitudes of a per-asset vector, with a non-finite entry ranked last.
A figure that shows the top assets sorts by the size of a per-asset number. A non-investable asset carries NaN in that number, and NaN sorts first under rev = true, so a blank bar would take the top slot from a live asset. The same NaN poisons every reduction the ranking needs: inv(dot(v, v)) and sum(v) are both NaN, and ceil(Int, NaN) throws an InexactError.
Mapping a non-finite entry to zero settles all three. The entry ranks below every live asset, it counts for nothing, and the frame is unchanged when the count does not truncate. A vector whose entries are all finite is untouched, because the ranking already read abs.
Arguments
v: A per-asset number the figure ranks by, such as an expected return, a volatility, a centrality score or a weight.
Returns
m::Vector:abs(vᵢ)at every finite entry, and zero at every other.
Related
PortfolioOptimisers.finite_symmetric_clim — Function
finite_symmetric_clim(
A::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}}
) -> Tuple{Any, Any}
Take the symmetric colour limits of a heatmap over its finite entries alone.
maximum(abs, A) is NaN when any entry of A is, and a NaN colour limit paints every cell one colour. A drawn plot of a Prior Result keeps the full universe, so it does meet a NaN: a non-investable asset carries one down its row and its column. The limits are therefore taken over the finite entries, and the blank cell is drawn against the scale the live cells set.
Arguments
A: The matrix the heatmap draws.
Returns
clim::Tuple:(-c, c), wherecis the largest finite absolute entry ofA.
Related
PortfolioOptimisers.finite_columns — Function
finite_columns(
X::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
idx::AbstractVector{<:Integer}
) -> Vector
Keep the columns of idx whose column of X is finite throughout.
A figure that draws one line per asset keeps a gapped asset, and the break in its line is the delisting. A figure that sums several assets into one aggregate line cannot: a single NaN in the sum poisons every date of it, at any weight, the zero an optimiser gave a non-investable asset included. Such a series draws nothing at all, so the aggregate excludes the asset instead of carrying it.
The rule reads the column rather than a mask, because the aggregate is formed from a returns matrix the caller holds and no prior travels with it.
Arguments
X: Asset returns matrix (observations × assets).idx: Column indices the aggregate would sum.
Returns
keep::VecInt: The entries ofidxwhose column ofXholds no non-finite entry.
Related
PortfolioOptimisers.investable_plot_view — Function
investable_plot_view(pr::AbstractPriorResult, nx = nothing, w = nothing)
investable_plot_view(rd::AbstractReturnsResult, nx = nothing, w = nothing)
investable_plot_view(imsk::Nothing, pr::AbstractPriorResult, nx, w)
investable_plot_view(imsk::BitVector, pr::AbstractPriorResult, nx, w)Reduce a prior result, the axis names and the weights a computed figure draws to the Investable Mask.
A drawn plot keeps the frame: a heatmap or a bar chart of a Prior Result shows the full universe, and the backend leaves a blank cell and a missing bar where the asset is not investable. A computed plot has no such option. eigvals(Symmetric(sigma)) refuses a NaN, and a phylogeny or a centrality score is fitted by a plain moment estimator, which refuses one too. Such a figure reduces here instead, and it draws the investable universe alone.
The reduction is the one port_opt_view the prior's owner already writes, so a new block cannot be forgotten and the reduced pr.X carries no dead column. The names and the weights ride the asset axis, so they take the mask directly.
A ReturnsResult carries no moments, so no mask exists to derive and it passes through. That is what lets one door state the reduction once and dispatch decide whether it happens.
No diagnostic is emitted. A figure is a drawing rather than a number a caller acts on, and the docstring of each computed plot says that a non-investable asset is not drawn.
Algorithm
- Return the three arguments unchanged when the carrier is a returns result.
- Derive the Investable Mask once with
investable_mask. - Return the three unchanged when every asset is investable.
- Otherwise return a
port_opt_viewof the prior atfindall(imsk), and the views of the names and the weights at the mask.
Arguments
pr: Prior result, orReturnsResult.nx: Asset names of the axis, ornothing.w: Portfolio weights the figure sizes by, ornothing.imsk: The Investable Mask, ornothingwhen every asset is investable.
Returns
(pr, nx, w): The three reduced to the Investable Mask, or unchanged.
Related
PortfolioOptimisers.attribution_plot_axis — Function
attribution_plot_axis(fa::FactorAttributionResult, by_family::Bool, rd::ReturnsResult,
nf::Option{<:AbstractVector})Return the axis of a FactorAttributionResult a plot draws, and the labels of its rows.
The four attribution plots share one choice: the factor axis or the family axis, and where the labels of that axis come from. The family axis carries its own labels, because they are derived from the block; the factor axis carries none, because the factor names are carried input, so they come from nf, from rd.nf, or from the row's position.
Arguments
fa: Factor attribution result.by_family: Whether to draw the family axis rather than the factor axis.rd: Returns result providing the factor names throughrd.nf.nf: Factor names; overridesrd.nfwhen provided.
Validation
- If
by_familyistrue,fa.fmbdis notnothing, else anArgumentErroris raised.
Returns
bd::AttributionBreakdown: The axis the plot draws.labels::AbstractVector: The label of each row of that axis.
Related