Meucci Entropy Pooling

PortfolioOptimisers.MeucciEntropyPoolingPriorType
struct MeucciEntropyPoolingPrior{__T_pe, __T_mu_views, __T_var_views, __T_cvar_views, __T_sigma_views, __T_sk_views, __T_kt_views, __T_cov_views, __T_rho_views, __T_sets, __T_ds_opt, __T_dm_opt, __T_opt, __T_w, __T_alg} <: AbstractLowOrderPriorEstimator_AF

Reweights the observations of a prior so that its moments meet a set of views, and root-finds a CVaR view.

MeucciEntropyPoolingPrior is a low order prior estimator that computes the mean and covariance of asset returns using entropy pooling. It supports views on the mean, the value at risk, the conditional value at risk, the variance, the covariance, the correlation, the skewness and the kurtosis, and it takes custom prior weights and solver configuration.

This is the earlier of the library's two entropy pooling estimators, and it is kept because its CVaR route is a different algorithm, not a different formulation of the same problem: a CVaR view is a target hunted by the recursive algorithm of Meucci, Ardia and Keel, where ConditionalValueatRiskEntropyPooling root-finds the value at risk level and re-solves the whole entropy pooling problem at each candidate. That route takes equality CVaR views alone, one asset per view.

Reach for EntropyPoolingPrior instead where a tail view has to be an inequality, name two assets, or land on the entropic value at risk: there each tail view is a constraint of the single entropy pooling problem, so one solve answers every view.

Fields

  • pe: Prior estimator.
  • mu_views: Expected returns views estimator or result.
  • var_views: Value-at-risk views estimator or result.
  • cvar_views: Conditional value-at-risk views estimator or result.
  • sigma_views: Variance views estimator or result.
  • sk_views: Skewness views estimator or result.
  • kt_views: Kurtosis views estimator or result.
  • cov_views: Covariance views estimator or result.
  • rho_views: Correlation views estimator or result.
  • sets: Sets used to map estimator values to assets.
  • ds_opt: Thin wrapper for arguments and keyword arguments used in Roots.findzero for use with a single conditional value-at-risk view.
  • dm_opt: Optimiser for multiple conditional value at risk views.
  • opt: Entropy pooling optimisation estimator.
  • w: Prior observation probability weights. If nothing, uniform weights are used.
  • alg: Entropy pooling algorithm.

Constructors

MeucciEntropyPoolingPrior(;    pe::AbstractLowOrderPriorEstimator_A_F_AF = EmpiricalPrior(),    mu_views::Option{<:LinearConstraintEstimator} = nothing,    var_views::Option{<:VV_VecVV} = nothing,    cvar_views::Option{<:CVV_VecCVV} = nothing,    sigma_views::Option{<:LinearConstraintEstimator} = nothing,    sk_views::Option{<:LinearConstraintEstimator} = nothing,    kt_views::Option{<:LinearConstraintEstimator} = nothing,    cov_views::Option{<:LinearConstraintEstimator} = nothing,    rho_views::Option{<:LinearConstraintEstimator} = nothing,    sets::Option{<:UniverseSets} = nothing,    ds_opt::Option{<:ConditionalValueatRiskEntropyPooling} = nothing,    dm_opt::Option{<:OptimEntropyPooling} = nothing,    opt::NonCVaREP = OptimEntropyPooling(),    w::Option{<:StatsBase.ProbabilityWeights} = nothing,    alg::AbstractEntropyPoolingAlgorithm = H1_EntropyPooling()) -> MeucciEntropyPoolingPrior

Keywords correspond to the struct's fields.

Validation

  • If any view constraint is not nothing, sets must not be nothing.
  • If var_views is a vector, !isempty(var_views).
  • If w is not nothing, it must be non-empty and match the number of observations.

Propagated parameters

When factory is called on this type, the following @fprop-tagged fields are automatically propagated:

View parameters

When port_opt_view is called on this type, the following @vprop-tagged fields are automatically subset to the selected indices:

Observation weight parameters

When obs_weights_view is called on this type, the following fields are automatically indexed to the selected observations:

Details

  • If w is not nothing, it is normalised to sum to 1; otherwise, uniform weights are used when prior is called.

View comparison operators

The comparison operators accepted in each view's constraint strings depend on the moment being constrained. An unsupported operator raises a ParseError listing the operators allowed for that view.

  • mu_views, sigma_views, sk_views, kt_views, cov_views, rho_views accept ==, >= and <=.
  • var_views (Value at Risk) accepts only == and >=.
  • cvar_views (Conditional Value at Risk) accepts only ==.

Examples

julia> MeucciEntropyPoolingPrior(;                                 sets = UniverseSets(; xkey = "nx",                                                     dict = Dict("nx" => ["A", "B", "C"])),                                 mu_views = LinearConstraintEstimator(;                                                                      val = ["A == 0.03",                                                                             "B + C == 0.04"]))MeucciEntropyPoolingPrior           pe ┼ EmpiricalPrior              │        ce ┼ PortfolioOptimisersCovariance              │           │   ce ┼ Covariance              │           │      │    me ┼ SimpleExpectedReturns              │           │      │       │   w ┴ nothing              │           │      │    ce ┼ GeneralCovariance              │           │      │       │   ce ┼ StatsBase.SimpleCovariance: StatsBase.SimpleCovariance(true)              │           │      │       │    w ┴ nothing              │           │      │   alg ┴ FullMoment()              │           │   mp ┼ MatrixProcessing              │           │      │     pdm ┼ Posdef              │           │      │         │      alg ┼ UnionAll: NearestCorrelationMatrix.Newton              │           │      │         │   kwargs ┴ @NamedTuple{}: NamedTuple()              │           │      │      dn ┼ nothing              │           │      │      dt ┼ nothing              │           │      │     alg ┼ nothing              │           │      │   order ┴ NTuple{4, Symbol}: (:pdm, :dn, :dt, :alg)              │        me ┼ SimpleExpectedReturns              │           │   w ┴ nothing              │   horizon ┴ nothing     mu_views ┼ LinearConstraintEstimator              │   val ┼ Vector{String}: ["A == 0.03", "B + C == 0.04"]              │   key ┴ nothing    var_views ┼ nothing   cvar_views ┼ nothing  sigma_views ┼ nothing     sk_views ┼ nothing     kt_views ┼ nothing    cov_views ┼ nothing    rho_views ┼ nothing         sets ┼ UniverseSets              │    xkey ┼ String: "nx"              │   uxkey ┼ String: "ux"              │    fkey ┼ String: "nf"              │   ufkey ┼ String: "uf"              │    zkey ┼ String: "nz"              │    dict ┴ Dict{String, Vector{String}}: Dict("nx" => ["A", "B", "C"])       ds_opt ┼ nothing       dm_opt ┼ nothing          opt ┼ OptimEntropyPooling              │     args ┼ Tuple{}: ()              │   kwargs ┼ @NamedTuple{}: NamedTuple()              │      sc1 ┼ Int64: 1              │      sc2 ┼ Float64: 1000.0              │      alg ┼ ExpEntropyPooling()              │      err ┴ nothing            w ┼ nothing          alg ┴ H1_EntropyPooling()

Related

References

  • [80] A. Meucci. Fully flexible views: theory and practice. Risk 21, 97–102 (2008).
  • [82] A. Meucci, D. Ardia and S. Keel. Fully flexible extreme views. The Journal of Risk 14, 39–49 (2011).
  • [81] A. Vorobets. Sequential entropy pooling heuristics. Available at SSRN 3936392 (2021).
source
PortfolioOptimisers.ep_cvar_views_solve!Function
ep_cvar_views_solve!(cvar_views::Nothing, epc::AbstractDict, ::Any, ::Any,
                     w::StatsBase.ProbabilityWeights, opt::AbstractEntropyPoolingOptimiser, ::Any, ::Any;
                     kwargs...)

Solve the entropy pooling problem when no CVaR views are specified.

ep_cvar_views_solve! is an internal API compatibility method that solves the entropy pooling problem when no conditional value at risk (CVaR) view constraints are present (cvar_views = nothing). It delegates to the main entropy pooling solver using the provided prior weights, constraint dictionary, and optimiser.

Arguments

  • cvar_views: Indicates that no CVaR view constraints are specified.
  • epc: Dictionary of entropy pooling constraints, mapping keys to (lhs, rhs) pairs.
  • ::Any: Prior result, ignored on this path.
  • ::Any: Asset set, ignored on this path.
  • w: Prior probability weights.
  • opt: Entropy pooling optimiser.
  • ::Any: CVaR-specific optimiser, ignored on this path.
  • ::Any: General optimiser, ignored on this path.
  • kwargs...: Additional keyword arguments forwarded to the solver.

Returns

  • pw::StatsBase.ProbabilityWeights: Posterior probability weights satisfying the constraints.

Details

  • This method is used for API compatibility when CVaR views are not present.
  • Calls entropy_pooling with the provided arguments.

Related

source
ep_cvar_views_solve!(cvar_views::CVV_VecCVV, epc::AbstractDict,
                     pr::AbstractPriorResult, sets::UniverseSets,
                     w::StatsBase.ProbabilityWeights, opt::AbstractEntropyPoolingOptimiser,
                     ds_opt::Option{<:ConditionalValueatRiskEntropyPooling},
                     dm_opt::Option{<:OptimEntropyPooling}; strict::Bool = false)

Solve the entropy pooling problem with Conditional Value-at-Risk (CVaR) view constraints.

ep_cvar_views_solve! parses and validates CVaR view constraints, replaces prior references, and constructs the corresponding entropy pooling constraint system. It then solves for posterior probability weights using either root-finding (for single CVaR view) or optimisation (for multiple views), depending on the number of constraints and the provided optimiser. Throws informative errors if views are infeasible or too extreme.

Arguments

  • cvar_views: CVaR view constraints.
  • epc: Dictionary of entropy pooling constraints, mapping keys to (lhs, rhs) pairs.
  • pr: Prior result containing asset return information.
  • sets: Asset set mapping asset names to indices.
  • w: Prior probability weights.
  • opt: Main entropy pooling optimiser.
  • ds_opt: CVaR-specific optimiser (for single view).
  • dm_opt: General optimiser (for multiple views).
  • strict: If true, throws error for missing assets; otherwise, issue warnings.

Returns

  • pw::StatsBase.ProbabilityWeights: Posterior probability weights satisfying CVaR view constraints.

Details

  • Parses CVaR view equations and replaces prior references.
  • Validates that only equality constraints are present and that each view targets a single asset.
  • Checks that views are not too extreme i.e. not greater than the worst realisation.
  • The search runs over the value at risk levels etas, one per view, each bounded by [0, B]. This is a continuous relaxation of the recursive algorithm, which searches over discrete tail sizes instead; it reaches the same target and it takes more than one view.
  • For a single CVaR view, uses root-finding via ConditionalValueatRiskEntropyPooling.
  • For multiple CVaR views, uses optimisation via OptimEntropyPooling.
  • Throws errors if optimisation fails or views are infeasible.

Related

References

  • [82] A. Meucci, D. Ardia and S. Keel. Fully flexible extreme views. The Journal of Risk 14, 39–49 (2011).
source
PortfolioOptimisers.priorFunction
prior(pe::MeucciEntropyPoolingPrior, X::MatNum, F::Option{<:MatNum} = nothing;
      dims::Int = 1, strict::Bool = false, kwargs...)

Compute entropy pooling prior moments for asset returns.

prior orients the data with respect to dims and delegates to ep_prior, which dispatches on the entropy pooling algorithm pe.alg. H0_EntropyPooling enforces every view in a single optimisation. StagedEP, the union of H1_EntropyPooling and H2_EntropyPooling, enforces the views in stages, from lower to higher moments.

Arguments

  • pe: Entropy pooling prior estimator.
  • X: Asset returns matrix (observations × assets).
  • F: Optional factor matrix.
  • dims: Dimension along which to perform the computation.
  • strict: If true, throws error for missing assets; otherwise, issues warnings.
  • kwargs...: Additional keyword arguments passed to underlying estimators and solvers.

Validation

  • dims in (1, 2).

Returns

  • pr::LowOrderPrior: Result object containing asset returns, posterior mean vector, posterior covariance matrix, weights, effective number of scenarios, Kullback-Leibler divergence, and optional factor moments.

Related

source
PortfolioOptimisers.ep_priorMethod
ep_prior(alg::StagedEP, pe::MeucciEntropyPoolingPrior, X::MatNum, F::Option{<:MatNum};
         strict::Bool = false, kwargs...)

Compute entropy pooling prior moments for asset returns with iterative constraint enforcement.

ep_prior estimates the mean and covariance of asset returns using the entropy pooling framework, supporting iterative constraint enforcement via the H1_EntropyPooling and H2_EntropyPooling algorithms. It integrates moment and view constraints (mean, variance, CVaR, skewness, kurtosis, correlation), flexible confidence specification, and composable optimisation algorithms. The method iteratively applies constraints, updating prior weights and moments at each step, and ensures that higher moment views do not inadvertently alter lower moments.

Mathematical definition

Entropy pooling finds posterior weights $\boldsymbol{p}$ by minimising the Kullback-Leibler divergence from the prior $\boldsymbol{q}$:

\[\begin{align} \underset{\boldsymbol{p}}{\min} &\sum_{t=1}^{T} p_t \ln\!\frac{p_t}{q_t} \quad \text{s.t.} \quad \mathbf{A}_{\mathrm{eq}} \boldsymbol{p} = \boldsymbol{b}_{\mathrm{eq}}, \quad \mathbf{A}_{\mathrm{ineq}} \boldsymbol{p} \leq \boldsymbol{b}_{\mathrm{ineq}}, \quad \boldsymbol{p} \geq \boldsymbol{0}, \quad \boldsymbol{1}^\intercal \boldsymbol{p} = 1\,. \end{align}\]

Where:

  • $\boldsymbol{p}$: $T \times 1$ posterior weight vector.
  • $\boldsymbol{q}$: $T \times 1$ prior weight vector.
  • $\mathbf{A}_{\mathrm{eq}}$, $\boldsymbol{b}_{\mathrm{eq}}$: Equality constraint matrix and vector.
  • $\mathbf{A}_{\mathrm{ineq}}$, $\boldsymbol{b}_{\mathrm{ineq}}$: Inequality constraint matrix and vector.
  • $T$: Number of observations.

Posterior moments are then computed as probability-weighted sample statistics using $\boldsymbol{p}^*$.

Arguments

  • alg: Staged entropy pooling algorithm, taken from pe.alg by prior.
  • pe: Entropy pooling prior estimator.
  • X: Asset returns matrix (observations × assets), oriented by prior.
  • F: Optional factor matrix, oriented by prior.
  • strict: If true, throws error for missing assets; otherwise, issues warnings.
  • kwargs...: Additional keyword arguments passed to underlying estimators and solvers.

Validation

  • If any view constraint is not nothing, !isnothing(sets).
  • If prior weights pe.w are provided, length(pe.w) == T, where T is the number of observations.

Returns

  • pr::LowOrderPrior: Result object containing asset returns, posterior mean vector, posterior covariance matrix, weights, effective number of scenarios, Kullback-Leibler divergence, and optional factor moments.

Details

  • If isnothing(pe.w), prior weights are initialised to 1/T where T is the number of observations; otherwise, provided weights are normalised.
  • Constraints are enforced iteratively, from lower to higher moments.
  • Moment and view constraints are parsed and added to the constraint dictionary.
  • The initial weights for each stage is selected according to pe.alg.
  • At each stage, the prior weights are updated by solving the entropy pooling optimisation with the current set of constraints. If present, the CVaR views are also enforced at every stage.
  • Lower moments are fixed as needed to prevent distortion by higher moment views. If asset i has a view enforced on moment N that uses moments n < N to compute, then all moments n for asset i are fixed.
  • The final result includes the effective number of scenarios and Kullback-Leibler divergence between prior and posterior weights.

Related

source
PortfolioOptimisers.ep_priorMethod
ep_prior(alg::H0_EntropyPooling, pe::MeucciEntropyPoolingPrior, X::MatNum,
         F::Option{<:MatNum}; strict::Bool = false, kwargs...)

Compute entropy pooling prior moments for asset returns with single-shot constraint enforcement.

ep_prior estimates the mean and covariance of asset returns using the entropy pooling framework, enforcing all moment and view constraints in a single optimisation step via the H0_EntropyPooling algorithm. This approach is fast but may distort lower moments when higher moment views are present, as all constraints are applied simultaneously.

Mathematical definition

Entropy pooling finds posterior weights $\boldsymbol{p}$ by minimising the Kullback-Leibler divergence from the prior $\boldsymbol{q}$ subject to all constraints simultaneously:

\[\begin{align} \underset{\boldsymbol{p}}{\min} &\sum_{t=1}^{T} p_t \ln\!\frac{p_t}{q_t} \quad \text{s.t.} \quad \mathbf{A}_{\mathrm{eq}} \boldsymbol{p} = \boldsymbol{b}_{\mathrm{eq}}, \quad \mathbf{A}_{\mathrm{ineq}} \boldsymbol{p} \leq \boldsymbol{b}_{\mathrm{ineq}}, \quad \boldsymbol{p} \geq \boldsymbol{0}, \quad \boldsymbol{1}^\intercal \boldsymbol{p} = 1\,. \end{align}\]

Where:

  • $\boldsymbol{p}$: $T \times 1$ posterior weight vector.
  • $\boldsymbol{q}$: $T \times 1$ prior weight vector.
  • $\mathbf{A}_{\mathrm{eq}}$, $\boldsymbol{b}_{\mathrm{eq}}$: Equality constraint matrix and vector.
  • $\mathbf{A}_{\mathrm{ineq}}$, $\boldsymbol{b}_{\mathrm{ineq}}$: Inequality constraint matrix and vector.
  • $T$: Number of observations.

Arguments

  • alg: Single-shot entropy pooling algorithm, taken from pe.alg by prior.
  • pe: Entropy pooling prior estimator.
  • X: Asset returns matrix (observations × assets), oriented by prior.
  • F: Optional factor matrix, oriented by prior.
  • strict: If true, throws error for missing assets; otherwise, issues warnings.
  • kwargs...: Additional keyword arguments passed to underlying estimators and solvers.

Validation

  • If any view constraint is not nothing, !isnothing(pe.sets).
  • If prior weights pe.w are provided, length(pe.w) == T, where T is the number of observations

Returns

  • pr::LowOrderPrior: Result object containing asset returns, posterior mean vector, posterior covariance matrix, weights, effective number of scenarios, Kullback-Leibler divergence, and optional factor moments.

Details

  • If isnothing(pe.w), prior weights are initialised to 1/T where T is the number of observations; otherwise, provided weights are normalised.
  • All constraints are parsed and added to the constraint dictionary at once. This means that lower moments may be distorted by higher moment views, since they cannot be fixed at any point.
  • A single optimisation is performed to solve for the posterior weights, enforcing all constraints at once.
  • The final result includes the effective number of scenarios and Kullback-Leibler divergence between prior and posterior weights.

Related

source

References

[80]
A. Meucci. Fully flexible views: theory and practice. Risk 21, 97–102 (2008).
[81]
A. Vorobets. Sequential entropy pooling heuristics. Available at SSRN 3936392 (2021).
[82]
A. Meucci, D. Ardia and S. Keel. Fully flexible extreme views. The Journal of Risk 14, 39–49 (2011).