Custom value expected returns

PortfolioOptimisers.CustomExpectedReturnsValueAlgorithmType
abstract type CustomExpectedReturnsValueAlgorithm <: AbstractCustomValue

Abstract supertype for custom expected returns value algorithms. These are used to define the type of the val field in CustomValueExpectedReturns.

Interfaces

In order to implement a new concrete custom expected returns value algorithm type that works seamlessly with the library, subtype CustomExpectedReturnsValueAlgorithm and make it callable such that it returns a vector of length consistent with the returns matrix:

  • (alg::MyCustomValAlg)(X::MatNum; dims::Int=1, kwargs...) -> Vector{<:Number}

Where:

  • alg: Custom expected returns value algorithm.
  • X: Data matrix of asset returns.
  • dims: Dimension along which to compute the expected returns (1 for columns/assets, 2 for rows/observations).
  • kwargs...: Additional keyword arguments.

Examples

julia> struct MyCustomValAlg <: PortfolioOptimisers.CustomExpectedReturnsValueAlgorithm endjulia> function (alg::MyCustomValAlg)(X::PortfolioOptimisers.MatNum; dims::Int = 1, kwargs...)           return fill(0.0, size(X, setdiff((1, 2), (dims,))[1]))       endjulia> mean(CustomValueExpectedReturns(; val = MyCustomValAlg()), [1 2 3; 4 5 6])3-element Vector{Float64}: 0.0 0.0 0.0

Related

source
PortfolioOptimisers.CustomValueExpectedReturnsType
struct CustomValueExpectedReturns{__T_val} <: AbstractExpectedReturnsEstimator

Returns a caller-supplied value for each asset instead of estimating one from the data.

val holds a scalar, a per-asset vector, or a callable that the estimator calls with the data matrix. The type of val selects the branch that mean(me::CustomValueExpectedReturns, X::MatNum; dims::Int = 1, kwargs...) takes, and any other type is rejected by the CER_Func_Num_VecNum bound of the field.

The constructor checks only that a vector is not empty, because the number of assets is not known until the data arrive. The length of a stored vector, and the shape and the length of what a callable returns, are checked at the point of use by assert_custom_expected_returns_val.

Fields

  • val: Custom expected returns value.

    • If a scalar, every asset is assigned this value.
    • If a vector, each element is one asset's value.
    • If a callable, it is called as val(X; dims = dims, kwargs...) and must return one value per asset.

Constructors

CustomValueExpectedReturns(;    val::CER_Func_Num_VecNum = 0.0) -> CustomValueExpectedReturns

Keywords correspond to the struct's fields.

Validation

  • If val is a vector, !isempty(val).

Examples

julia> CustomValueExpectedReturns()CustomValueExpectedReturns  val ┴ Float64: 0.0

Related

source
Statistics.meanMethod
Statistics.mean(me::CustomValueExpectedReturns, X::MatNum;
                dims::Int = 1, kwargs...)

Compute expected returns as custom values.

Mathematical definition

Returns a user-supplied constant, vector, or function result as the expected returns:

\[\begin{align} \hat{\mu}_j &= v_j, \quad j = 1, \ldots, N\,. \end{align}\]

Where:

  • $\hat{\mu}_j$: Expected return of asset $j$.
  • $v_j$: $j$-th element of the custom value me.val (broadcast from a scalar, taken directly from a vector, or evaluated from a callable).
  • $N$: Number of assets.

Algorithm

  1. Check dims.

  2. Read the asset count _ncols from X and dims, as the size of the dimension that dims does not name.

  3. Take the branch that the type of me.val selects.

    • me.val::Number: Fill a vector of length _ncols with me.val.
    • me.val::VecNum: Check the stored me.val against _ncols with assert_custom_expected_returns_val, and take it unchanged.
    • me.val::Function or me.val::CustomExpectedReturnsValueAlgorithm: Call me.val(X; dims = dims, kwargs...), giving val, and check val against _ncols with assert_custom_expected_returns_val.
  4. On the first two branches, insert the reduced dimension with insertdims. The callable branch returns val unchanged, and inserts no dimension.

Arguments

  • me: Custom value expected returns estimator.
  • X: Data matrix of asset returns (observations × assets).
  • dims: Dimension along which to perform the computation.
  • kwargs...: Additional keyword arguments. The callable branch passes them to me.val; the other two branches ignore them.

Validation

Returns

  • mu: Expected returns, one value per asset. The shape depends on the branch.

    • me.val::Number and me.val::VecNum: A Matrix{<:Number}, shaped as (1, N) if dims == 1 or (N, 1) if dims == 2, as the other expected returns estimators return.
    • me.val::Function and me.val::CustomExpectedReturnsValueAlgorithm: The vector the callable returned, of length N, passed through unchanged. This branch inserts no dimension.

Related

source
Statistics.meanMethod
mean(
    me::CustomValueExpectedReturns{<:Union{var"#s1761", var"#s1760"} where {var"#s1761"<:Function, var"#s1760"<:CustomExpectedReturnsValueAlgorithm}},
    X::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}};
    dims,
    kwargs...
) -> Any

Function overload of mean(me::CustomValueExpectedReturns, X::MatNum; dims::Int = 1, kwargs...). Delegates to the callable me.val with the same arguments, and validates the value it returns against the number of assets.

source
PortfolioOptimisers.port_opt_viewMethod
port_opt_view(
    me::CustomValueExpectedReturns{<:VecNum},
    i,
    args...
) -> CustomValueExpectedReturns

port_opt_view method for the per-asset vector shape of CustomValueExpectedReturns: slices val to the selected assets.

val is the one field of the estimator, and it sits on the asset axis in this shape alone. A scalar is universe-independent, and a callable receives the already-reduced matrix and answers one value per column of it, so both keep the identity method of AbstractExpectedReturnsEstimator. A stored vector is one entry per asset of the universe the caller wrote it against, so a reduction that left it whole would carry the full universe into a narrower sample, and mean(me::CustomValueExpectedReturns, X::MatNum; dims::Int = 1, kwargs...) would throw a DimensionMismatch against the sample it was handed.

The bound of val is a union of the three shapes, so this declaration is a method on the shape that is on the asset axis rather than an @vprop tag on the field, which would slice all three.

Algorithm

  1. Return a new estimator whose val is view(me.val, i).

Arguments

  • me::CustomValueExpectedReturns{<:VecNum}: The estimator whose val is one entry per asset.
  • i: Asset index or mask to select.
  • args...: Threaded tail, unused.

Returns

  • me::CustomValueExpectedReturns: A new estimator whose val is restricted to the selected assets.

Related

source