Returns buffer state: private API
Types
PortfolioOptimisers.ReturnsBufferState — Type
struct ReturnsBufferState{__T_nx, __T_X, __T_nf, __T_F, __T_nb, __T_B, __T_ts, __T_pnl, __T_max_history} <: AbstractPartialFitStateCarries the fold context an optimiser keeps beside its prior, so that a read-out can rebuild the ReturnsResult the batch path reads.
The state of the optimiser's online step, decided by #867. An optimiser forwards each observation to its prior and to nothing else, and a read-out runs the ordinary batch path over a ReturnsResult rebuilt from the state — because every meta-optimiser hands its inner optimisers a view of the caller's carrier, and every UniverseSets constraint resolves by asset name, so a read-out that handed the batch path a bare matrix would hand it an empty panel and no names.
The returns are owned once, by the prior at the bottom of the chain, which carries them in its own state; this state holds them only where no prior sits beneath the optimiser — EqualWeighted and RandomWeighted, which read the observations and hold no prior. The factor column is owned once on the same terms: the prior's buffer records it wherever the prior's estimator tree reads it, and this state keeps it only where the tree never does — needs_factor_returns answering false — or where no prior sits beneath. Everything else the carrier holds and the prior does not is here: the benchmark column as a buffer of its own, the timestamps, and the context that is pinned by the first step and checked at every step after it — the asset, factor and benchmark names, and a static AssetPanel. A time-varying panel is not pinned: its masks ride with the observations they explain into the returns buffer, and the read-out rebuilds the panel from them.
Every column buffer is a SampleBufferState, so the orientation, the cap, the merge, the copy and the asset slice are inherited per column, and max_history is one cap over every column. A single-column benchmark is held as a plain vector, as the timestamps are, because a vector benchmark is not indexed by asset and a slice leaves it alone.
Fields
nx: Names of the asset columns, pinned by the first step.
X: Buffer of the asset returns,observations × assets.nothingwhen a prior beneath the optimiser carries the rows, which is every case but a prior-less head.
nf: Names of the factor columns, pinned by the first step.
F: Buffer of the factor returns,observations × factors.nothingwhen the carrier holds none, and when the prior beneath the optimiser records them in its own buffer, which is every prior whose tree reads them.
nb: Names of the benchmark columns, pinned by the first step.
B: Buffer of the benchmark, aSampleBufferStateofobservations × assetsfor a matrix benchmark and a plain vector for a single column, ornothingwhen the carrier holds none.
ts: Timestamps of the observations folded, in order, ornothingwhen the carrier holds none.
pnl: The staticAssetPanelof the universe, pinned by the first step, ornothing. A time-varying panel is never held here.
max_history: Optional cap on the number of observations the carry buffer keeps.nothingkeeps every observation folded so far. A cap bounds memory and nothing else: it does not make the estimator windowed, because an estimate that folds exactly is fitted over every observation whatever the buffer holds.
Constructors
ReturnsBufferState(; nx::Option{<:VecStr} = nothing, X::Option{<:SampleBufferState} = nothing, nf::Option{<:VecStr} = nothing, F::Option{<:SampleBufferState} = nothing, nb::Option{<:VecStr} = nothing, B::Option{<:Union{<:SampleBufferState, <:AbstractVector}} = nothing, ts::Option{<:AbstractVector} = nothing, pnl::Option{<:AssetPanel} = nothing, max_history::Option{<:Integer} = nothing) -> ReturnsBufferStateKeywords correspond to the struct's fields. The default is the empty seed a first step fills, and the cap is the one knob a caller sets on it.
Validation
max_history > 0when it is notnothing. ADomainErroris thrown otherwise.pnlis static when it is notnothing. AnArgumentErroris thrown otherwise, because a time-varying panel's masks belong in the returns buffer.
View parameters
When port_opt_view is called on this type, its fields are subset to the selected assets:
nx,X,pnl: Sliced to the selected assets.nb,B: Sliced when the benchmark is a matrix over the assets, and carried unchanged when it is a single column.nf,F,ts: Carried unchanged, because none of them is indexed by asset.
Related
Functions
PortfolioOptimisers.assert_pinned_context — Function
assert_pinned_context(pinned, given, name::Symbol)
Refuses a step whose carrier disagrees with the context the first step pinned.
The names and the static panel are context, not sample: they are fixed at the first step and every step after it must carry the same, because a state that silently took a new asset axis would fold the next observation onto the wrong column. Two carriers agree when both hold the field and the values are equal, or when neither holds it.
Arguments
pinned: The value the first step pinned.given: The value this step carries.name: The field, for the message.
Validation
isequal(pinned, given). AnArgumentErroris thrown otherwise.
Returns
nothing.
Related
PortfolioOptimisers.pinned_agree — Function
pinned_agree(a, b) -> Bool
Answers whether two pinned values are the same value, by content.
isequal is not enough for the context a step pins: an AssetPanel is an immutable struct holding arrays, and a struct with no equality of its own compares its array fields by identity, so two panels of one universe built by two views of one carrier — which is what every step of a walk-forward hands over — would compare unequal. This walks structs field by field and arrays element by element, and compares the leaves by isequal.
Arguments
a: The value the first step pinned.b: The value this step carries.
Returns
agree::Bool:truewhen the two are the same value.
Related
PortfolioOptimisers.pinned_repr — Function
pinned_repr(x) -> Any
Renders a pinned value for a refusal message: a name vector in full, and anything larger by its summary.
Related
PortfolioOptimisers.assert_column_presence — Function
assert_column_presence(
buffer,
column,
n::Integer,
name::Symbol
)
Refuses a step that adds a column the first step did not carry, or drops one it did.
Whether the carrier holds a factor matrix, a benchmark or timestamps is fixed by the first step, exactly as a SampleBufferState fixes whether it records a mask: a column present for some observations and absent for others cannot be rebuilt into a matrix. A buffer that has folded nothing has nothing to disagree with, so an empty state accepts either.
Arguments
buffer: The column's buffer in the state, ornothing.column: The column this step carries, ornothing.n: Number of observations the state holds.name: The field, for the message.
Validation
isnothing(buffer) == isnothing(column), oncen > 0. AnArgumentErroris thrown otherwise.
Returns
nothing.
Related
PortfolioOptimisers.context_count — Function
context_count(state::ReturnsBufferState) -> Any
Number of observations a ReturnsBufferState holds.
The count is read off the first column the state keeps, because every column is appended to together and holds the same number of rows; a state that keeps no column at all — a carrier of returns and names alone, whose rows the prior holds — answers zero. The read-out checks the count against the prior's buffer rather than trusting it.
Arguments
state: The state to count.
Returns
n::Int: The number of observations folded.
Related
PortfolioOptimisers.column_count — Function
column_count(buffer::Nothing)
column_count(buffer::SampleBufferState)
column_count(buffer::AbstractVector)Number of observations one column of a ReturnsBufferState holds, or nothing for a column the state does not keep.
Related
PortfolioOptimisers.fold_column — Function
fold_column(buffer::Option{<:SampleBufferState}, column::Option{<:MatNum}, max_history)
fold_column(buffer::Option{<:AbstractVector}, column::Option{<:AbstractVector}, max_history)Appends one block of a column to its buffer, seeding the buffer on the first step.
A matrix column is a SampleBufferState and takes its block arm; a vector column — the timestamps, a single-column benchmark — is a plain vector, appended to and trimmed to the cap from the front. A column the carrier does not hold stays nothing.
Arguments
buffer: The column's buffer, ornothingbefore the first step.column: The block to append, ornothing.max_history: The cap every column of the state shares.
Returns
- The buffer after the block, or
nothing.
Related
PortfolioOptimisers.fold_column_masked — Function
fold_column_masked(
buffer::Union{Nothing, SampleBufferState},
X::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
amsk::Union{Nothing, AbstractMatrix{<:Bool}},
max_history::Union{Nothing, Integer}
) -> Any
Appends a block of returns to the buffer a prior-less head owns, with the active mask of its panel.
fold_column for the one column that carries a mask: a time-varying panel's active mask rides into the buffer beside the rows, so the read-out rebuilds the panel from it, and a static panel contributes none.
Arguments
buffer: The returns buffer, ornothingbefore the first step.X: The block to append.amsk: The active mask of the block, ornothing.max_history: The cap of the state.
Returns
buffer::SampleBufferState: The buffer after the block.
Related
PortfolioOptimisers.returns_result — Method
returns_result(state::ReturnsBufferState, rows::SampleBufferState)Rebuilds the ReturnsResult the observations folded so far describe.
The reconstitution verb of the optimiser's read-out. rows is the buffer that holds the returns — the prior's, or the state's own when the head holds no prior — and the state holds every other column and the pinned context. The factor column comes from the state where it owns one, and from rows otherwise, through factor_buffer: a prior whose tree reads F records it beside its rows, so the two are owned once and read from where they live. Every array is materialised, not viewed: a buffer's backing matrix is written and reallocated by the next fold, and a carrier holding a view of it would change under its holder.
The panel comes from one of two places. A static panel was pinned by the first step and is returned as it was given. A time-varying panel was never held: its active mask rode into the returns buffer, and it is rebuilt here with the estimation mask equal to the active one, because the estimation mask does not travel the step (see partial_fit! on an optimiser).
Arguments
state: The fold context.rows: The buffer holding the returns.
Validation
rowsand the state hold the same number of observations, where the state holds any column. ADimensionMismatchis thrown otherwise.
Returns
rd::ReturnsResult: The carrier, equal field by field to the one a batch fit over the same observations would have read.
Related
PortfolioOptimisers.column_matrix — Function
column_matrix(buffer::Nothing)
column_matrix(buffer::SampleBufferState)
column_matrix(buffer::AbstractMatrix)
column_matrix(buffer::AbstractVector)Materialises one column of a ReturnsBufferState, or the factor rows a prior's buffer holds, for the carrier a read-out rebuilds.
Arguments
buffer: The column's buffer, the valid region of the prior's factor rows, ornothing.
Returns
- The column as a fresh array, or
nothing.
Related
PortfolioOptimisers.merge_column — Function
merge_column(a::Nothing, b::Nothing)
merge_column(a::SampleBufferState, b::SampleBufferState)
merge_column(a::AbstractVector, b::AbstractVector)Concatenates one column of two ReturnsBufferState.
Related
Base.copy — Method
copy(
x::ReturnsBufferState
) -> ReturnsBufferState{__T_nx, __T_X, __T_nf, __T_F, __T_nb, __T_B, __T_ts, __T_pnl, __T_max_history} where {__T_nx<:Union{Nothing, AbstractVector{<:AbstractString}}, __T_X<:Union{Nothing, SampleBufferState}, __T_nf<:Union{Nothing, AbstractVector{<:AbstractString}}, __T_F<:Union{Nothing, SampleBufferState}, __T_nb<:Union{Nothing, AbstractVector{<:AbstractString}}, __T_B<:Union{Nothing, SampleBufferState, AbstractVector}, __T_ts<:Union{Nothing, AbstractVector}, __T_pnl<:Union{Nothing, AssetPanel}, __T_max_history<:Union{Nothing, Integer}}
Copies a ReturnsBufferState, so the copy shares no array with the original.
Arguments
x: The state to copy.
Returns
state::ReturnsBufferState: A fresh state, equal tox.
Related
PortfolioOptimisers.copy_column — Function
copy_column(x::Nothing)
copy_column(x)Copies one column of a ReturnsBufferState, passing an absent one through.
Related