Entropy Pooling: private API
PortfolioOptimisers.AbstractSequentialTailViewConstraint — Type
abstract type AbstractSequentialTailViewConstraint <: AbstractEntropyPoolingTailViewAbstract supertype for the carriers of the sequential convex tail view formulations.
A sequential carrier splits the assets of an oriented lower-bound view into a dual side, whose measures are concave in the posterior probabilities and take their exact dual blocks, and a primal side, whose measures enter with a negative coefficient and take a linear upper bound read at a fixed posterior. The three subtypes differ in the measure alone, and the two verbs that read a carrier, add_ep_tail_view! and ep_refine_tail_view, have one method for the whole family. Each subtype supplies ep_tail_dual_block! and ep_tail_surrogate_row for its measure.
Related
PortfolioOptimisers.VecEP — Type
const VecEP = AbstractVector{<:Union{<:EntropyPoolingPrior, <:MeucciEntropyPoolingPrior}}Alias for an abstract vector of entropy pooling prior estimators of either family.
Related
PortfolioOptimisers.LinearConditionalValueatRiskViewConstraint — Type
struct LinearConditionalValueatRiskViewConstraint{__T_x, __T_coef, __T_alpha, __T_rhs} <: AbstractEntropyPoolingTailViewCarries the loss series and coefficient of every asset, the significance level and the target of a linear conditional value-at-risk view.
The view parser produces one of these per view that takes the linear formulation. add_ep_tail_view! then writes the dual representation of CVaR into the model from it, one block per asset. Every coefficient is positive: a view whose coefficients carry both signs takes another formulation.
Fields
x: Per asset the view names, its loss series (-returns).
coef: Per asset, the coefficient the view gives its risk measure.
alpha: Significance level of the view.
rhs: Target value of the view.
Constructors
LinearConditionalValueatRiskViewConstraint(x, coef, alpha, rhs)Arguments correspond to the fields above.
Related
References
- [1] D. Cajas. Entropy Pooling with CVaR and EVaR Views. Available at SSRN 7120258 (2026).
PortfolioOptimisers.IntegerConditionalValueatRiskViewConstraint — Type
struct IntegerConditionalValueatRiskViewConstraint{__T_ord, __T_x, __T_coef, __T_alpha, __T_op, __T_rhs} <: AbstractEntropyPoolingTailViewCarries the ordered tail window of every asset an integer conditional value-at-risk view names.
Each entry of ord, x pairs one asset named by the view with its coefficient in coef, so an absolute view carries one entry and a relative view carries two. The window is sorted ascending, so the largest loss is last and the tail the binary vector marks is a suffix of it.
Fields
ord: Per asset, the indices of the largest losses in ascending order, so the largest loss is last.
x: Loss series of the asset the view names (-returns).
coef: Per asset, the coefficient the view gives its risk measure.
alpha: Significance level of the view.
op: Comparison operator of the view, one of:eq,:geqand:leq.
rhs: Target value of the view.
Constructors
IntegerConditionalValueatRiskViewConstraint(ord, x, coef, alpha, op, rhs)Arguments correspond to the fields above.
Related
References
- [1] D. Cajas. Entropy Pooling with CVaR and EVaR Views. Available at SSRN 7120258 (2026).
PortfolioOptimisers.ConicEntropicValueatRiskViewConstraint — Type
struct ConicEntropicValueatRiskViewConstraint{__T_x, __T_coef, __T_alpha, __T_rhs} <: AbstractEntropyPoolingTailViewCarries the loss series and coefficient of every asset, the significance level and the target of a conic entropic value-at-risk view.
The view parser produces one of these per view that takes the conic formulation. add_ep_tail_view! then writes the relative entropy cone that is the dual representation of EVaR from it, one per asset. Every coefficient is positive: a view whose coefficients carry both signs takes another formulation.
Fields
x: Per asset the view names, its loss series (-returns).
coef: Per asset, the coefficient the view gives its risk measure.
alpha: Significance level of the view.
rhs: Target value of the view.
Constructors
ConicEntropicValueatRiskViewConstraint(x, coef, alpha, rhs)Arguments correspond to the fields above.
Related
References
- [1] D. Cajas. Entropy Pooling with CVaR and EVaR Views. Available at SSRN 7120258 (2026).
PortfolioOptimisers.GridEntropicValueatRiskViewConstraint — Type
struct GridEntropicValueatRiskViewConstraint{__T_x, __T_z, __T_alpha, __T_rhs, __T_M} <: AbstractEntropyPoolingTailViewCarries the grid of dual variables that an upper-bound or equality entropic value-at-risk view selects one point of.
A lower-bound grid view is a set of rows on the posterior probabilities alone, so it goes into the constraint dictionary and never reaches this carrier. An equality view emits both: the rows go into the dictionary and the selector block comes here.
Fields
x: Loss series of the asset the view names (-returns).
z: Grid of entropic value-at-risk dual variables.
alpha: Significance level of the view.
rhs: Target value of the view.
M: Big-M constant of the grid entropic value-at-risk formulation.
Constructors
GridEntropicValueatRiskViewConstraint(x, z, alpha, rhs, M)Arguments correspond to the fields above.
Related
References
- [1] D. Cajas. Entropy Pooling with CVaR and EVaR Views. Available at SSRN 7120258 (2026).
PortfolioOptimisers.ConicRelativisticValueatRiskViewConstraint — Type
struct ConicRelativisticValueatRiskViewConstraint{__T_x, __T_coef, __T_alpha, __T_kappa, __T_rhs} <: AbstractEntropyPoolingTailViewCarries the loss series and coefficient of every asset, the significance level, the deformation parameter and the target of a conic relativistic value-at-risk view.
The view parser produces one of these per view that takes the conic formulation. add_ep_tail_view! then writes the power cones that are the dual representation of RLVaR from it, one pair per observation per asset. Every coefficient is positive: a view whose coefficients carry both signs takes another formulation.
Fields
x: Per asset the view names, its loss series (-returns).
coef: Per asset, the coefficient the view gives its risk measure.
alpha: Significance level of the view.
kappa: Deformation parameter of the view.
rhs: Target value of the view.
Constructors
ConicRelativisticValueatRiskViewConstraint(x, coef, alpha, kappa, rhs)Arguments correspond to the fields above.
Related
References
- [2] D. Cajas. Entropy Pooling with Relativistic Value at Risk Views. Available at SSRN 7329718 (2026).
PortfolioOptimisers.GridRelativisticValueatRiskViewConstraint — Type
struct GridRelativisticValueatRiskViewConstraint{__T_x, __T_t, __T_z, __T_alpha, __T_kappa, __T_rhs, __T_M} <: AbstractEntropyPoolingTailViewCarries the grid of primal points that an upper-bound or equality relativistic value-at-risk view selects one point of.
A lower-bound grid view is a set of rows on the posterior probabilities alone, so it goes into the constraint dictionary and never reaches this carrier. An equality view emits both: the rows go into the dictionary and the selector block comes here.
Fields
x: Loss series of the asset the view names (-returns).
t: Shift variable that minimises the objective at each point ofz, one entry per grid point. It is read under the probabilities the grid is centred on, which are the prior's only where the centre is the prior's.
z: Grid of relativistic value-at-risk dual variables.
alpha: Significance level of the view.
kappa: Deformation parameter of the view.
rhs: Target value of the view.
M: Big-M constant of the grid relativistic value-at-risk formulation.
Constructors
GridRelativisticValueatRiskViewConstraint(x, t, z, alpha, kappa, rhs, M)Arguments correspond to the fields above.
Related
References
- [2] D. Cajas. Entropy Pooling with Relativistic Value at Risk Views. Available at SSRN 7329718 (2026).
PortfolioOptimisers.SequentialConditionalValueatRiskViewConstraint — Type
struct SequentialConditionalValueatRiskViewConstraint{__T_xd, __T_cd, __T_xp, __T_cp, __T_c, __T_b, __T_alpha, __T_rhs, __T_iters, __T_tol} <: AbstractSequentialTailViewConstraintCarries the two sides of a sequential conditional value-at-risk view, its surrogate row and its stopping rule.
The view parser produces one of these per view that takes SequentialConditionalValueatRiskView, with the surrogate row read at the prior. ep_refine_tail_view then re-reads the row at each posterior entropy_pooling produces.
Fields
xd: Per asset on the dual side of the view, its loss series (-returns). Once the view is oriented as a lower bound these are the assets with a positive coefficient, and each takes the exact dual block of its measure.
cd: Per asset on the dual side of the view, the coefficient the view gives its risk measure. Positive.
xp: Per asset on the primal side of the view, its loss series (-returns). Once the view is oriented as a lower bound these are the assets with a negative coefficient, and each takes a linear upper bound read from its primal representation.
cp: Per asset on the primal side of the view, the coefficient the view gives its risk measure. Negative.
c: Coefficients of the surrogate row, one per observation. They are the coefficient-weighted sum of the linear upper bounds of the primal side, read at the last posterior.
b: Constant of the surrogate row.
alpha: Significance level of the view.
rhs: Target value of the view.
iters: Largest number of re-solves after the first solve. Each re-solve reads the multipliers of the primal representation at the last posterior, which tightens the surrogate row. Zero keeps the first posterior, on which the view holds but the row is slack.
tol: Relative gap between the surrogate row and the risk measures it bounds at which the re-solves stop. It is read against the larger of the view's target and the largest loss the view names.
Constructors
SequentialConditionalValueatRiskViewConstraint(xd, cd, xp, cp, c, b, alpha, rhs, iters, tol)Arguments correspond to the fields above.
Related
AbstractSequentialTailViewConstraintSequentialConditionalValueatRiskViewadd_ep_tail_view!ep_refine_tail_view
References
- [1] D. Cajas. Entropy Pooling with CVaR and EVaR Views. Available at SSRN 7120258 (2026).
PortfolioOptimisers.SequentialEntropicValueatRiskViewConstraint — Type
struct SequentialEntropicValueatRiskViewConstraint{__T_xd, __T_cd, __T_xp, __T_cp, __T_c, __T_b, __T_alpha, __T_rhs, __T_iters, __T_tol, __T_args, __T_kwargs, __T_zlo_frac} <: AbstractSequentialTailViewConstraintCarries the two sides of a sequential entropic value-at-risk view, its surrogate row, its stopping rule, and the settings of the search for the dual variable.
The view parser produces one of these per view that takes SequentialEntropicValueatRiskView, with the surrogate row read at the prior. ep_refine_tail_view then re-reads the row at each posterior entropy_pooling produces, which runs ep_evar once per asset of the primal side under args, kwargs and zlo_frac.
Fields
xd: Per asset on the dual side of the view, its loss series (-returns). Once the view is oriented as a lower bound these are the assets with a positive coefficient, and each takes the exact dual block of its measure.
cd: Per asset on the dual side of the view, the coefficient the view gives its risk measure. Positive.
xp: Per asset on the primal side of the view, its loss series (-returns). Once the view is oriented as a lower bound these are the assets with a negative coefficient, and each takes a linear upper bound read from its primal representation.
cp: Per asset on the primal side of the view, the coefficient the view gives its risk measure. Negative.
c: Coefficients of the surrogate row, one per observation. They are the coefficient-weighted sum of the linear upper bounds of the primal side, read at the last posterior.
b: Constant of the surrogate row.
alpha: Significance level of the view.
rhs: Target value of the view.
iters: Largest number of re-solves after the first solve. Each re-solve reads the multipliers of the primal representation at the last posterior, which tightens the surrogate row. Zero keeps the first posterior, on which the view holds but the row is slack.
tol: Relative gap between the surrogate row and the risk measures it bounds at which the re-solves stop. It is read against the larger of the view's target and the largest loss the view names.
args: Additional positional arguments passed to the optimisation function. They reach the search ofep_evareach re-read runs.
kwargs: Additional keyword arguments passed to the optimisation function. They reach the same searchargsdoes.
zlo_frac: Lower end of the bracket of the dual variable, as a fraction of the upper end, ornothingto take the spanep_evarstates. The upper end is a proof, so it is not a knob and only the lower one is.
Constructors
SequentialEntropicValueatRiskViewConstraint(xd, cd, xp, cp, c, b, alpha, rhs, iters, tol, args, kwargs, zlo_frac)Arguments correspond to the fields above.
Related
AbstractSequentialTailViewConstraintSequentialEntropicValueatRiskViewadd_ep_tail_view!ep_refine_tail_viewep_evar
References
- [1] D. Cajas. Entropy Pooling with CVaR and EVaR Views. Available at SSRN 7120258 (2026).
PortfolioOptimisers.SequentialRelativisticValueatRiskViewConstraint — Type
struct SequentialRelativisticValueatRiskViewConstraint{__T_xd, __T_cd, __T_xp, __T_cp, __T_c, __T_b, __T_alpha, __T_kappa, __T_rhs, __T_iters, __T_tol, __T_args, __T_kwargs, __T_bracket} <: AbstractSequentialTailViewConstraintCarries the two sides of a sequential relativistic value-at-risk view, its surrogate row, its stopping rule, and the settings of the search for the primal pair.
The view parser produces one of these per view that takes SequentialRelativisticValueatRiskView, with the surrogate row read at the prior. ep_refine_tail_view then re-reads the row at each posterior entropy_pooling produces, which runs ep_rlvar once per asset of the primal side under args, kwargs and bracket.
Fields
xd: Per asset on the dual side of the view, its loss series (-returns). Once the view is oriented as a lower bound these are the assets with a positive coefficient, and each takes the exact dual block of its measure.
cd: Per asset on the dual side of the view, the coefficient the view gives its risk measure. Positive.
xp: Per asset on the primal side of the view, its loss series (-returns). Once the view is oriented as a lower bound these are the assets with a negative coefficient, and each takes a linear upper bound read from its primal representation.
cp: Per asset on the primal side of the view, the coefficient the view gives its risk measure. Negative.
c: Coefficients of the surrogate row, one per observation. They are the coefficient-weighted sum of the linear upper bounds of the primal side, read at the last posterior.
b: Constant of the surrogate row.
alpha: Significance level of the view.
kappa: Deformation parameter of the view.
rhs: Target value of the view.
iters: Largest number of re-solves after the first solve. Each re-solve reads the multipliers of the primal representation at the last posterior, which tightens the surrogate row. Zero keeps the first posterior, on which the view holds but the row is slack.
tol: Relative gap between the surrogate row and the risk measures it bounds at which the re-solves stop. It is read against the larger of the view's target and the largest loss the view names.
args: Additional positional arguments passed to the optimisation function. They reach the searches ofep_rlvareach re-read runs.
kwargs: Additional keyword arguments passed to the optimisation function. They reach the same searchesargsdoes.
bracket: Spans the two scalar searches of this estimator run over, ornothingto take the span each search states.
Constructors
SequentialRelativisticValueatRiskViewConstraint(xd, cd, xp, cp, c, b, alpha, kappa, rhs, iters, tol, args, kwargs, bracket)Arguments correspond to the fields above.
Related
AbstractSequentialTailViewConstraintSequentialRelativisticValueatRiskViewadd_ep_tail_view!ep_refine_tail_viewep_rlvar
References
- [2] D. Cajas. Entropy Pooling with Relativistic Value at Risk Views. Available at SSRN 7329718 (2026).
PortfolioOptimisers.ep_tail_dual_block! — Function
ep_tail_dual_block!(model::JuMP.Model, pw, tv::AbstractEntropyPoolingTailView, x::VecNum,
sc1::Number)Add the dual block of one asset's risk measure to an entropy pooling JuMP model, and return the expression that attains the measure.
The dual representation of each measure is a maximum of $\boldsymbol{\nu}^{\intercal} \boldsymbol{x}$ over a set of weights that depends on the posterior probabilities. ep_tail_dual_block! registers that set, and hands the linear expression back so the caller can bound it, on its own or in a coefficient-weighted sum over several assets. The carrier tv names the measure and carries its level, and the method is shared by the fixed carrier of the measure and its sequential one.
JuMP formulation
Variables
pw: $\boldsymbol{p}$: $T \times 1$ posterior probabilities of the observations, summing to one. They are the unknown of the entropy pooling problem. It is read from the caller, and every entry below is registered against it.nu: $\boldsymbol{\nu}$: $T \times 1$ vector of weights that attains the risk measure, the variable of its dual representation. The conditional value-at-risk method bounds it below by zero, and the two other methods bound it to $[0, 1]$.tau,varsigma: $\boldsymbol{\tau}$ and $\boldsymbol{\varsigma}$, $T \times 1$ each and bounded below by zero, created by the relativistic value-at-risk method. The cones and the budget already imply both bounds, and stating them is what turns aSLOW_PROGRESSreport into anOPTIMALone.
Expressions
- The method returns $\sum_{j=1}^{T} \nu_{j} x_{j}$, registered under no name.
Constraints
Every row is registered under no name. The conditional value-at-risk method, for LinearConditionalValueatRiskViewConstraint and SequentialConditionalValueatRiskViewConstraint, registers two:
- $s_{c1} \left(\nu_{j} - \dfrac{p_{j}}{\alpha}\right) \leq 0$, $\forall\, j = 1,\ldots,T$.
- $s_{c1} \left(\sum_{j=1}^{T} \nu_{j} - 1\right) = 0$.
The entropic value-at-risk method, for ConicEntropicValueatRiskViewConstraint and SequentialEntropicValueatRiskViewConstraint, registers two:
- $s_{c1} \left(\sum_{j=1}^{T} \nu_{j} - 1\right) = 0$.
- $\left(s_{c1} \ln\left(\dfrac{1}{\alpha}\right),\, s_{c1} \boldsymbol{p},\, s_{c1} \boldsymbol{\nu}\right) \in \mathcal{K}_{\mathrm{re}}(2T+1)$.
The relativistic value-at-risk method, for ConicRelativisticValueatRiskViewConstraint and SequentialRelativisticValueatRiskViewConstraint, registers four:
- $s_{c1} \left(\sum_{j=1}^{T} \nu_{j} - 1\right) = 0$.
- $s_{c1} \left(\sum_{j=1}^{T} \dfrac{\tau_{j} - \varsigma_{j}}{2\kappa} - \ln_{\kappa}\left(\dfrac{1}{\alpha T}\right)\right) \leq 0$.
- $\left(s_{c1} \tau_{j},\, s_{c1} T p_{j},\, s_{c1} \nu_{j}\right) \in \mathcal{K}_{\mathrm{pow}}\left(\dfrac{1}{1+\kappa}\right)$, $\forall\, j = 1,\ldots,T$.
- $\left(s_{c1} \nu_{j},\, s_{c1} T p_{j},\, s_{c1} \varsigma_{j}\right) \in \mathcal{K}_{\mathrm{pow}}(1-\kappa)$, $\forall\, j = 1,\ldots,T$.
Where:
- $s_{c1}$: Constraint scale of the entropy pooling optimiser. It multiplies both sides of a row, so a positive value leaves the feasible set unchanged.
- $\boldsymbol{p}$: $T \times 1$ posterior probabilities of the observations, summing to one. They are the unknown of the entropy pooling problem.
- $\boldsymbol{\nu}$: $T \times 1$ vector of weights that attains the risk measure, the variable of its dual representation.
- $\boldsymbol{x}$: $T \times 1$ loss series of one asset, the negated returns, whose $j$-th entry is $x_{j}$.
- $\alpha$: Significance level (left tail probability), $\alpha \in (0, 1)$.
- $\kappa$: Kaniadakis deformation parameter, $\kappa \in (0, 1)$.
- $T$: Number of observations.
- $\ln_{\kappa}(u) = \dfrac{u^{\kappa} - u^{-\kappa}}{2 \kappa}$: Kaniadakis logarithm.
- $\boldsymbol{\tau}$, $\boldsymbol{\varsigma}$: $T \times 1$ vectors that carry the Kaniadakis entropy budget of $\boldsymbol{\nu}$.
- $\mathcal{K}_{\mathrm{re}}(1 + 2T) = \{(u,\, \boldsymbol{v},\, \boldsymbol{s}) : u \geq \sum_{j=1}^{T} s_{j} \ln(s_{j} / v_{j})\}$: Relative entropy cone.
- $\mathcal{K}_{\mathrm{pow}}(\pi) = \{(a, b, c) : a^{\pi} b^{1-\pi} \geq |c|,\, a \geq 0,\, b \geq 0\}$: Power cone.
Relaxation
The encoding is not exact: the entries below bound the quantity instead of reproducing it, and the bound is tight only under the condition stated here.
The block is exact: the set it registers is the dual description of the measure, so the largest value the returned expression takes is the measure of the asset under pw.
Arguments
model: Entropy pooling JuMP model.pw: Vector of posterior probability variables.tv: Tail view constraint. It names the measure and carries its level, and its deformation parameter for the relativistic method.x: Loss series of the asset.sc1: Constraint scaling factor.
Returns
expr::JuMP.AffExpr: The expression $\sum_{j=1}^{T} \nu_{j} x_{j}$.
Related
add_ep_tail_view!LinearConditionalValueatRiskViewConstraintConicEntropicValueatRiskViewConstraintConicRelativisticValueatRiskViewConstraintAbstractSequentialTailViewConstraint
References
PortfolioOptimisers.ep_var_multiplier — Function
ep_var_multiplier(x::VecNum, w::VecNum, alpha::Number)Find the value at risk of a loss series under observation probabilities, as the minimiser of the primal of the conditional value at risk.
Mathematical definition
The conditional value at risk is the minimum over $\eta$ of $\eta + \dfrac{1}{\alpha} \sum_{j=1}^{T} w_{j} (x_{j} - \eta)^{+}$, a convex piecewise-linear function whose kinks sit at the losses. Its minimiser is the loss at which the tail mass first reaches $\alpha$:
\[\eta^{\star} = x_{(s)}\,, \quad s = \min\left\{k : \sum_{i=1}^{k} w_{(i)} \geq \alpha\right\}\,,\]
with the losses sorted in descending order, $x_{(1)} \geq x_{(2)} \geq \ldots$.
Where:
- $\boldsymbol{x}$: $T \times 1$ loss series of one asset, the negated returns, whose $j$-th entry is $x_{j}$.
- $\boldsymbol{w}$: $T \times 1$ observation probabilities, summing to one. In a view they are the posterior probabilities the model solves for.
- $\alpha$: Significance level (left tail probability), $\alpha \in (0, 1)$.
- $T$: Number of observations.
Arguments
x: Loss series (-returns).w: Observation probabilities. Normalised to sum to one.alpha: Significance level.
Returns
eta::Number: The value at risk, one of the losses ofx.
Related
PortfolioOptimisers.ep_tail_surrogate_row — Function
ep_tail_surrogate_row(tv::AbstractSequentialTailViewConstraint, x::VecNum, w::VecNum)Read the linear upper bound of one asset's risk measure at a posterior.
Each sequential formulation bounds the measure of an asset on its primal side by an affine function of the posterior probabilities, $r_{0} + \boldsymbol{r}^{\intercal} \boldsymbol{p}$, that is tight at the probabilities w it is read at. ep_tail_surrogate_row returns that function, so the value $r_{0} + \boldsymbol{r}^{\intercal} \boldsymbol{w}$ is the measure of the asset under w.
Mathematical definition
The conditional value-at-risk method reads the primal at the value at risk $\eta$ of ep_var_multiplier:
\[r_{0} = \eta\,, \quad r_{j} = \dfrac{(x_{j} - \eta)^{+}}{\alpha}\,.\]
The entropic value-at-risk method reads the dual variable $z$ and the value of ep_evar, and takes the tangent of the concave primal at w:
\[r_{0} = \mathrm{EVaR}_{\alpha}(X) - z\,, \quad r_{j} = \dfrac{z e^{x_{j}/z}}{\sum_{k=1}^{T} w_{k} e^{x_{k}/z}}\,.\]
The relativistic value-at-risk method reads the pair $(t, z)$ of ep_rlvar, at which the primal is linear in the probabilities:
\[r_{0} = t + z \ln_{\kappa}\left(\dfrac{1}{\alpha T}\right)\,, \quad r_{j} = T \varphi_{\kappa}(t - x_{j},\, z)\,.\]
Where:
- $\boldsymbol{x}$: $T \times 1$ loss series of one asset, the negated returns, whose $j$-th entry is $x_{j}$.
- $\boldsymbol{w}$: $T \times 1$ observation probabilities, summing to one. In a view they are the posterior probabilities the model solves for.
- $\alpha$: Significance level (left tail probability), $\alpha \in (0, 1)$.
- $\kappa$: Kaniadakis deformation parameter, $\kappa \in (0, 1)$.
- $T$: Number of observations.
- $\ln_{\kappa}(u) = \dfrac{u^{\kappa} - u^{-\kappa}}{2 \kappa}$: Kaniadakis logarithm.
- $\varphi_{\kappa}(u, z)$: Smallest sum the pair of power cones of one observation allows.
- $\mathrm{EVaR}_{\alpha}(X)$: Entropic value at risk of the loss series $\boldsymbol{x}$ at level $\alpha$.
- $\eta$: Value at risk of the loss series under $\boldsymbol{w}$.
- $z$: Dual variable that attains the measure under $\boldsymbol{w}$.
- $t$: Shift that attains the relativistic value at risk under $\boldsymbol{w}$.
Arguments
tv: Sequential tail view constraint. It names the measure, and carries its level and the settings of its search.x: Loss series of the asset (-returns).w: Observation probabilities the bound is read at, summing to one.
Returns
r::VecNum: Coefficients of the bound, one per observation.r0::Number: Constant of the bound.
Related
References
PortfolioOptimisers.ep_refine_tail_view — Method
ep_refine_tail_view(tv::AbstractEntropyPoolingTailView, w::VecNum)Re-read a tail view carrier at a posterior, and say whether its rows were already tight there.
A carrier whose rows are fixed at construction is returned unchanged, and is always tight. A sequential carrier re-reads the multipliers of its primal side at w, which is what tightens its surrogate row between two solves of entropy_pooling; its method lives beside it in src/10_Prior/06_EntropyPooling/03_EntropyPoolingPrior.jl.
Arguments
tv: Tail view constraint.w: Posterior probabilities of the last solve.
Returns
tv::AbstractEntropyPoolingTailView: The carrier to solve with next.tight::Bool: Whether the rowstvheld before the call were tight atw, within the tolerance the carrier holds.
Related
PortfolioOptimisers.ep_evar — Function
ep_evar(x::VecNum, w::VecNum, alpha::Number; args::Tuple = (),
kwargs::NamedTuple = (;), zlo_frac::Option{<:Number} = nothing)Compute the sample entropic value at risk of a loss series and the dual variable that attains it.
ep_evar minimises the scalar convex objective of the sample EVaR formula with Optim.jl. It is used by the entropy pooling view machinery, which needs both the value (to compare a view against its prior) and the minimiser (to centre the grid of GridEntropicValueatRiskView).
Mathematical definition
\[\mathrm{EVaR}_{\alpha}(X) = \min_{z > 0} \; z \ln\left(\dfrac{\sum_{j=1}^{T} w_{j} \exp(x_{j}/z)}{\alpha}\right)\,.\]
Algorithm
- Normalise the observation probabilities in the logarithmic domain, giving
lw. - Bracket the dual variable. The upper end
hiis(maximum(x) - dot(w, x)) / log(inv(alpha)), replaced byepsof its own type where that is not positive, and the lower end ishi * zlo_frac. - Minimise the objective over the bracket with
Optim.jl. Each evaluation goes throughLogExpFunctions.logsumexp, so a smallzdoes not overflow. - Return the minimum as
evar, and the minimiser asz.
Arguments
x: Loss series (-returns).w: Observation probabilities. Normalised to sum to one.alpha: Significance level.args: Additional positional arguments passed to the optimisation function. Left empty it takesOptim.Brent(), which is whatOptim.optimizeselects for a bracketed scalar minimisation.kwargs: Additional keyword arguments passed to the optimisation function.zlo_frac: Lower end of the bracket of the dual variable, as a fraction of the upper end.nothingtakessqrt(eps(T))for the element typeT, which the caller cannot state because the type follows from the data. The upper end is(maximum(x) - dot(w, x)) / log(inv(alpha)), above which the objective already exceedsmaximum(x), which bounds the EVaR from above. That is a proof, so the upper end is not a knob and only the lower one is.
Validation
0 < zlo_frac < 1.- The search converges. It is a bracketed scalar minimisation of a convex function, so it fails only under
argsorkwargsthat stop it early.
Returns
res::@NamedTuple{evar::Number, z::Number}: The value and the dual variable that attains it.
The incremental fit
This prior has no exact incremental recursion, so it takes the online step by refitting from a sample buffer: Online seeds cache, partial_fit! appends each observation to it verbatim, and the one-argument prior runs this estimator's own batch verb over the rows the buffer kept. The answer is therefore exactly a batch fit over those rows, and a max_history on the wrapper windows the whole fit.
cache travels the three propagation channels as every partial-fit state does: factory carries it unchanged, port_opt_view slices it to the selected assets, and obs_weights_view drops it, because no slice of a state exists on the observation axis. It is not rendered, because a running buffer is not the configuration a reader looks the type up for.
Related
References
- [1] D. Cajas. Entropy Pooling with CVaR and EVaR Views. Available at SSRN 7120258 (2026).
PortfolioOptimisers.ep_evar_grid_row — Function
ep_evar_grid_row(x::VecNum, ebar::Number, z::Number)Build one scaled row of the grid formulation of an entropic value-at-risk view.
ep_evar_grid_row returns the coefficients of exp((x - ebar) / z) divided by their largest entry, together with the reciprocal of that entry, which the right hand side must be multiplied by. Scaling the row keeps the coefficients in (0, 1] however small z is, which is what lets the big-M constant of GridEntropicValueatRiskView be a plain number rather than a function of the data.
Algorithm
- Exponentiate the shifted loss series, giving
c, the unscaled coefficientsexp((x - ebar) / z). - Read the largest entry of
cintosc. - Return
cdivided bysc, andisc, the reciprocal ofsc.
Arguments
x: Loss series (-returns).ebar: Target entropic value-at-risk.z: Grid point of the entropic value-at-risk dual variable.
Returns
c::VecNum: Scaled coefficients.isc::Number: Scaling factor to apply to the right hand side.
Related
PortfolioOptimisers.ep_rlvar_tail — Function
ep_rlvar_tail(u::Number, z::Number, kappa::Number)Evaluate the smallest tail penalty the pair of power cones of one observation allows.
The primal programme of the relativistic value at risk carries two power cones and two non-negative variables per observation. Their sum is minimised out in closed form, which is what turns a point of the primal programme into a row that is linear in the posterior probabilities.
Mathematical definition
\[\begin{align} \varphi_{\kappa}(u, z) &= \dfrac{\kappa}{1+\kappa} \left(\dfrac{2\kappa}{(1+\kappa) z}\right)^{\frac{1}{\kappa}} \left(\dfrac{\sigma - u}{2}\right)^{\frac{1+\kappa}{\kappa}} + \kappa (1-\kappa)^{\frac{1-\kappa}{\kappa}} \left(\dfrac{z}{2\kappa}\right)^{\frac{1}{\kappa}} \left(\dfrac{\sigma + u}{2}\right)^{-\frac{1-\kappa}{\kappa}}\,,\\ \sigma &= \sqrt{u^{2} + \dfrac{(1 - \kappa^{2}) z^{2}}{\kappa^{2}}}\,. \end{align}\]
Where:
- $\varphi_{\kappa}(u, z)$: Smallest sum the pair of power cones of one observation allows.
- $u$: Shifted loss of one observation, $t - x_{j}$.
- $z > 0$: Dual variable of the primal programme.
- $\kappa$: Kaniadakis deformation parameter, $\kappa \in (0, 1)$.
- $\sigma$: Positive root of the stationarity condition of $\varphi_{\kappa}$.
Arguments
u: Shifted return of the observation,t - xfor a loss seriesx.z: Dual variable of the primal programme.kappa: Deformation parameter, in(0, 1).
Returns
phi::Number: Smallest sum of the two tail variables of the observation.
Related
References
- [2] D. Cajas. Entropy Pooling with Relativistic Value at Risk Views. Available at SSRN 7329718 (2026).
PortfolioOptimisers.ep_rlvar_shift — Function
ep_rlvar_shift(x::VecNum, w::VecNum, kappa::Number, lnk::Number, z::Number;
args::Tuple = (), kwargs::NamedTuple = (;),
bracket::Option{<:RelativisticValueatRiskViewBracket} = nothing)Minimise the primal objective of the relativistic value at risk over its shift variable, at a fixed dual variable.
Mathematical definition
\[\begin{align} \underset{t}{\min} &\; t + z \ln_{\kappa}\left(\dfrac{1}{\alpha T}\right) + T \sum_{j=1}^{T} w_{j} \varphi_{\kappa}(t - x_{j},\, z)\,. \end{align}\]
Where:
- $t$: Shift variable of the primal programme.
- $z > 0$: Dual variable of the primal programme.
- $\ln_{\kappa}(u) = \dfrac{u^{\kappa} - u^{-\kappa}}{2 \kappa}$: Kaniadakis logarithm.
- $\alpha$: Significance level (left tail probability), $\alpha \in (0, 1)$.
- $T$: Number of observations.
- $\boldsymbol{w}$: $T \times 1$ observation probabilities, summing to one. In a view they are the posterior probabilities the model solves for.
- $\varphi_{\kappa}(u, z)$: Smallest sum the pair of power cones of one observation allows.
- $\boldsymbol{x}$: $T \times 1$ loss series of one asset, the negated returns, whose $j$-th entry is $x_{j}$.
- $\kappa$: Kaniadakis deformation parameter, $\kappa \in (0, 1)$.
Arguments
x: Loss series (-returns).w: Observation probabilities, summing to one.kappa: Deformation parameter, in(0, 1).lnk: Kaniadakis logarithm ofinv(alpha * T), fromkappa_log.z: Dual variable of the primal programme.args: Additional positional arguments passed to the optimisation function. Left empty it takesOptim.Brent(), which is whatOptim.optimizeselects for a bracketed scalar minimisation.kwargs: Additional keyword arguments passed to the optimisation function.bracket: Spans of the searches of a relativistic value-at-risk view, ornothingto take the oneRelativisticValueatRiskViewBracketstates. This function readstspanalone. It is a margin, not a proof, so widen it where the minimising shift lands on an end of the bracket.ep_rlvarreads the other two fields.
Validation
- The search converges. It is a bracketed scalar minimisation of a convex function, so it fails only under
argsorkwargsthat stop it early. A minimiser that lands on an end of the bracket does not fail it:Optimreports that end as converged.
Returns
res::@NamedTuple{risk::Number, t::Number}: The value at the minimising shift, and that shift.
Algorithm
- Bracket the shift by the loss range widened by
tspanof its spans on each side. The minimising shift sits near the largest loss, so the bracket holds it with a wide margin. - Minimise the objective over the bracket with
Optim.jl.
Related
References
- [2] D. Cajas. Entropy Pooling with Relativistic Value at Risk Views. Available at SSRN 7329718 (2026).
PortfolioOptimisers.ep_rlvar — Function
ep_rlvar(x::VecNum, w::VecNum, alpha::Number, kappa::Number; args::Tuple = (),
kwargs::NamedTuple = (;), bracket::Option{<:RelativisticValueatRiskViewBracket} = nothing)Compute the sample relativistic value at risk of a loss series and the primal point that attains it.
ep_rlvar minimises the two-variable primal objective of the sample RLVaR, whose per-observation power cones ep_rlvar_tail has already minimised out. It is used by the entropy pooling view machinery, which needs both the value (to compare a view against its prior) and the minimiser (to centre the grid of GridRelativisticValueatRiskView).
Mathematical definition
\[\begin{align} \mathrm{RLVaR}_{\alpha,\kappa}(X) &= \underset{t,\, z > 0}{\min} \; t + z \ln_{\kappa}\left(\dfrac{1}{\alpha T}\right) + T \sum_{j=1}^{T} w_{j} \varphi_{\kappa}(t - x_{j},\, z)\,. \end{align}\]
Where:
- $\mathrm{RLVaR}_{\alpha,\kappa}(X)$: Relativistic value at risk of the loss series $\boldsymbol{x}$ at level $\alpha$ and deformation $\kappa$.
- $t$: Shift variable of the primal programme.
- $z > 0$: Dual variable of the primal programme.
- $\ln_{\kappa}(u) = \dfrac{u^{\kappa} - u^{-\kappa}}{2 \kappa}$: Kaniadakis logarithm.
- $\alpha$: Significance level (left tail probability), $\alpha \in (0, 1)$.
- $T$: Number of observations.
- $\boldsymbol{w}$: $T \times 1$ observation probabilities, summing to one. In a view they are the posterior probabilities the model solves for.
- $\varphi_{\kappa}(u, z)$: Smallest sum the pair of power cones of one observation allows.
- $\boldsymbol{x}$: $T \times 1$ loss series of one asset, the negated returns, whose $j$-th entry is $x_{j}$.
- $\kappa$: Kaniadakis deformation parameter, $\kappa \in (0, 1)$.
Arguments
x: Loss series (-returns).w: Observation probabilities. Normalised to sum to one.alpha: Significance level.kappa: Deformation parameter, in(0, 1).args: Additional positional arguments passed to the optimisation function. It reaches both searches. Left empty it takesOptim.Brent(), which is whatOptim.optimizeselects for a bracketed scalar minimisation.kwargs: Additional keyword arguments passed to the optimisation function. They reach both searches.bracket: Spans of the searches, ornothingto take the oneRelativisticValueatRiskViewBracketstates. This function readslog_zloandlog_zhi, the ends of the bracket of the logarithm of the dual variable, as offsets from the logarithm of the loss range. They are a margin, not a proof, so widen one where the minimising dual variable lands on an end of the bracket.ep_rlvar_shiftreadstspan.
Validation
- Both searches converge. Each is a bracketed scalar minimisation of a convex function, so one fails only under
argsorkwargsthat stop it early. A minimiser that lands on an end of a bracket does not fail it:Optimreports that end as converged.
Returns
res::@NamedTuple{rlvar::Number, t::Number, z::Number}: The value and the primal pair that attains it.
Algorithm
- Minimise over the logarithm of the dual variable with
Optim.jl, over a bracket running fromexp(log_zlo)toexp(log_zhi)times the loss range, which is about2e-9to about2e4under the default bracket. The objective is convex in the pair, so the partial minimum over the shift is convex in the dual variable, and the logarithm is increasing, so the outer minimisation sees a unimodal function. - Minimise over the shift at each candidate dual variable with
ep_rlvar_shift. - Re-run the inner minimisation at the minimising dual variable, so the shift returned is the one that attains the value.
Related
ep_rlvar_tailep_rlvar_shiftConicRelativisticValueatRiskViewGridRelativisticValueatRiskViewRelativisticValueatRiskRelativisticValueatRiskView
References
- [2] D. Cajas. Entropy Pooling with Relativistic Value at Risk Views. Available at SSRN 7329718 (2026).
PortfolioOptimisers.ep_rlvar_grid_row — Function
ep_rlvar_grid_row(x::VecNum, vbar::Number, t::Number, z::Number, alpha::Number,
kappa::Number)Build one scaled row of the grid formulation of a relativistic value-at-risk view.
ep_rlvar_grid_row returns the coefficients T * phi(t - x, z) divided by their largest entry, together with the target of the row divided by that same entry. Scaling the row keeps the coefficients in (0, 1] however small z is, which is what lets the big-M constant of GridRelativisticValueatRiskView be a plain number rather than a function of the data.
Arguments
x: Loss series (-returns).vbar: Target relativistic value at risk.t: Shift variable of the grid point.z: Dual variable of the grid point.alpha: Significance level.kappa: Deformation parameter, in(0, 1).
Returns
c::VecNum: Scaled coefficients.b::Number: Scaled target the row is compared against.
Related
References
- [2] D. Cajas. Entropy Pooling with Relativistic Value at Risk Views. Available at SSRN 7329718 (2026).
PortfolioOptimisers.ep_row_tilt — Function
ep_row_tilt(w::VecNum, c::VecNum, b::Number; iters::Integer = 200)Tilt a probability vector so that one linear row holds with equality, at the smallest relative entropy.
The row of a grid point is linear in the posterior probabilities, so the posterior that makes it tight and stays closest to the prior is an exponential tilt of the prior along the row's coefficients. It is the entropy pooling answer to that single row, and it needs no solver.
Mathematical definition
\[\begin{align} q_{j}(\theta) &= \dfrac{w_{j} e^{-\theta c_{j}}}{\sum_{i=1}^{T} w_{i} e^{-\theta c_{i}}}\,,\\ \sum_{j=1}^{T} q_{j}(\theta) c_{j} &= b\,. \end{align}\]
The row's value under the tilt falls strictly as $\theta$ rises, from $\max_{j} c_{j}$ to $\min_{j} c_{j}$, so the tilt exists exactly when $b$ sits strictly inside that range.
Arguments
w: Prior probabilities, summing to one.c: Coefficients of the row.b: Value the row is to take.iters::Integer = 200: Largest number of bisection steps. The bisection stops on its own when the midpoint stops moving, which forFloat64happens near step 64, so this binds only a type of higher precision.
Validation
iters >= 1.
Returns
q::Option{VecNum}: The tilted probabilities, ornothingwhenbsits outside the range ofcand no probability vector attains it.
Algorithm
- Return
nothingwhenbsits outside the open range ofc. - Bracket the root by doubling the tilt away from zero until the row's value crosses
b. - Bisect the bracket to the resolution of the floating-point type, or for
iterssteps, whichever comes first.
Related
References
- [2] D. Cajas. Entropy Pooling with Relativistic Value at Risk Views. Available at SSRN 7329718 (2026).
PortfolioOptimisers.ep_evar_anchor — Function
ep_evar_anchor(x::VecNum, w::VecNum, alpha::Number, rhs::Number, z::Number;
iters::Integer = 50, tol::Number = 1e-10, tilt_iters::Integer = 200,
args::Tuple = (), kwargs::NamedTuple = (;),
zlo_frac::Option{<:Number} = nothing)Find the dual variable of the entropic value at risk that a posterior meeting an upper-bound view attains.
A grid point states the view as one row, and a posterior that makes the row tight reaches the target only where that point is the point the posterior itself attains. ep_evar_anchor solves for the dual variable that satisfies both conditions at once, which is the point the grid of GridEntropicValueatRiskView is centred on. It calls no solver.
Arguments
x: Loss series (-returns).w: Prior probabilities, summing to one.alpha: Significance level.rhs: Target entropic value at risk.z: Dual variable the iteration starts from.iters::Integer = 50: Largest number of steps the iteration takes.tol::Number = 1e-10: Relative distance from the target at which the iteration stops.tilt_iters::Integer = 200: Largest number of bisection steps the tilt of one row takes (seeep_row_tilt).args: Additional positional arguments passed to the optimisation function.kwargs: Additional keyword arguments passed to the optimisation function.zlo_frac: Lower end of the bracket of the dual variable, as a fraction of the upper end, forwarded toep_evar.
Returns
res::Option{@NamedTuple{z::Number, w::VecNum}}: The dual variable and the posterior that attains it, ornothingwhen the iteration does not reach the target.
Algorithm
- Build the row of the current dual variable with
ep_evar_grid_row. Returnnothingwhen it is not finite. - Tilt the prior so the row is tight with
ep_row_tilt. Returnnothingwhen no probability vector makes it tight. - Recompute the dual variable as the minimiser at the tilted probabilities with
ep_evar. - Stop when the entropic value at risk of the tilted probabilities is within
tolof the target, and return the dual variable and those probabilities. - Return
nothingafteriterssteps without that.
Related
References
- [1] D. Cajas. Entropy Pooling with CVaR and EVaR Views. Available at SSRN 7120258 (2026).
PortfolioOptimisers.ep_evar_grid — Function
ep_evar_grid(x::VecNum, w::VecNum, alpha::Number, op::Symbol, rhs::Number,
zstar::Number, pct::Number, K::Integer; iters::Integer = 50,
tol::Number = 1e-10, tilt_iters::Integer = 200, args::Tuple = (),
kwargs::NamedTuple = (;), zlo_frac::Option{<:Number} = nothing)Build the grid of dual variables an entropic value-at-risk view is written on.
A view that carries an upper-bound half is centred on the dual variable ep_evar_anchor finds. A lower-bound view, and a view whose anchor does not converge, is centred on the prior's dual variable instead. The grid of GridRelativisticValueatRiskView also translates its shift, and an EVaR grid needs no counterpart of that: the shift of the primal programme of EVaR is closed form in the target and the dual variable, and the row exp((x - rhs) / z) of ep_evar_grid_row already carries it.
Arguments
x: Loss series (-returns).w: Prior probabilities, summing to one.alpha: Significance level.op: Comparison operator of the view.rhs: Target entropic value at risk.zstar: Dual variable that attains the prior EVaR of the asset.pct: Half-width of the grid, as a fraction of the dual variable it is centred on.K: Number of grid points.iters::Integer = 50: Largest number of steps the anchor takes.tol::Number = 1e-10: Relative distance from the target at which the anchor stops.tilt_iters::Integer = 200: Largest number of bisection steps the tilt of one row takes (seeep_row_tilt).args: Additional positional arguments passed to the optimisation function.kwargs: Additional keyword arguments passed to the optimisation function.zlo_frac: Lower end of the bracket of the dual variable, as a fraction of the upper end, forwarded toep_evar.
Returns
z::VecNum: Dual variable of each grid point.
Algorithm
- Take the prior's dual variable as the centre.
- Where the view carries an upper-bound half, replace it with the dual variable of
ep_evar_anchor. Keep the prior's where the anchor does not converge. - Span the dual variable from
zc * (1 - pct)tozc * (1 + pct)inKpoints.Kis odd, so the centre is a point of the grid, and a grid of one point is the centre alone.
Related
References
- [1] D. Cajas. Entropy Pooling with CVaR and EVaR Views. Available at SSRN 7120258 (2026).
PortfolioOptimisers.ep_rlvar_anchor — Function
ep_rlvar_anchor(x::VecNum, w::VecNum, alpha::Number, kappa::Number, rhs::Number,
t::Number, z::Number; iters::Integer = 50, tol::Number = 1e-10,
tilt_iters::Integer = 200, args::Tuple = (),
kwargs::NamedTuple = (;),
bracket::Option{<:RelativisticValueatRiskViewBracket} = nothing)Find the primal point of the relativistic value at risk that a posterior meeting an upper-bound view attains.
A grid point states the view as one row, and a posterior that makes the row tight reaches the target only where that point is the point the posterior itself attains. ep_rlvar_anchor solves for the pair that satisfies both conditions at once, which is the pair the grid of GridRelativisticValueatRiskView is centred on. It calls no solver.
Arguments
x: Loss series (-returns).w: Prior probabilities, summing to one.alpha: Significance level.kappa: Deformation parameter, in(0, 1).rhs: Target relativistic value at risk.t: Shift variable the iteration starts from.z: Dual variable the iteration starts from.iters::Integer = 50: Largest number of steps the iteration takes.tol::Number = 1e-10: Relative distance from the target at which the iteration stops.tilt_iters::Integer = 200: Largest number of bisection steps the tilt of one row takes (seeep_row_tilt).args: Additional positional arguments passed to the optimisation function.kwargs: Additional keyword arguments passed to the optimisation function.bracket: Spans of the searches, forwarded toep_rlvarandep_rlvar_shift.
Returns
res::Option{@NamedTuple{t::Number, z::Number, w::VecNum}}: The pair and the posterior that attains it, ornothingwhen the iteration does not reach the target.
Algorithm
- Build the row of the current pair with
ep_rlvar_grid_row. Returnnothingwhen it is not finite. - Tilt the prior so the row is tight with
ep_row_tilt. Returnnothingwhen no probability vector makes it tight. - Recompute the pair as the minimiser at the tilted probabilities with
ep_rlvar. - Stop when the relativistic value at risk of the tilted probabilities is within
tolof the target, and return the pair and those probabilities. - Return
nothingafteriterssteps without that.
Related
References
- [2] D. Cajas. Entropy Pooling with Relativistic Value at Risk Views. Available at SSRN 7329718 (2026).
PortfolioOptimisers.ep_rlvar_grid — Function
ep_rlvar_grid(x::VecNum, w::VecNum, alpha::Number, kappa::Number, op::Symbol,
rhs::Number, zstar::Number, pv::Number, pct::Number, K::Integer;
iters::Integer = 50, tol::Number = 1e-10, tilt_iters::Integer = 200,
args::Tuple = (), kwargs::NamedTuple = (;),
bracket::Option{<:RelativisticValueatRiskViewBracket} = nothing)Build the grid of primal points a relativistic value-at-risk view is written on.
A view that carries an upper-bound half is centred on the pair ep_rlvar_anchor finds, and every shift is the one that minimises at the posterior that pair belongs to. A lower-bound view, and a view whose anchor does not converge, is centred on the prior's dual variable instead, and every shift is the one that minimises under the prior probabilities, less the distance from the prior value to the target. The relativistic value at risk and the shift that attains it are both translation-equivariant, so a posterior that moves the value to the target behaves, to first order, like translating every loss by that distance.
Arguments
x: Loss series (-returns).w: Prior probabilities, summing to one.alpha: Significance level.kappa: Deformation parameter, in(0, 1).op: Comparison operator of the view.rhs: Target relativistic value at risk.zstar: Dual variable that attains the prior RLVaR of the asset.pv: Prior RLVaR of the asset.pct: Half-width of the grid, as a fraction of the dual variable it is centred on.K: Number of grid points.iters::Integer = 50: Largest number of steps the anchor takes.tol::Number = 1e-10: Relative distance from the target at which the anchor stops.tilt_iters::Integer = 200: Largest number of bisection steps the tilt of one row takes (seeep_row_tilt).args: Additional positional arguments passed to the optimisation function.kwargs: Additional keyword arguments passed to the optimisation function.bracket: Spans of the searches, forwarded toep_rlvarandep_rlvar_shift.
Returns
t::VecNum: Shift variable of each grid point.z::VecNum: Dual variable of each grid point.
Algorithm
- Take the prior's pair as the centre, and the distance from the prior value to the target as the translation each shift carries.
- Where the view carries an upper-bound half, replace both with the pair and the posterior of
ep_rlvar_anchor, and drop the translation. Keep the prior's pair when the anchor does not converge. - Span the dual variable from
zc * (1 - pct)tozc * (1 + pct)inKpoints.Kis odd, so the centre is a point of the grid, and a grid of one point is the centre alone. - Minimise the objective over the shift at each point with
ep_rlvar_shift, and subtract the translation.
Related
References
- [2] D. Cajas. Entropy Pooling with Relativistic Value at Risk Views. Available at SSRN 7329718 (2026).
PortfolioOptimisers.ep_view_terms — Function
ep_view_terms(res::ParsingResult, sets::UniverseSets, X::MatNum; strict::Bool = false)Resolve one parsed tail view into the assets it names, their coefficients, its operator and its target.
ep_view_terms routes a ParsingResult through get_linear_constraints, which resolves the variable names against the universe and reports the ones it cannot place, then undoes the sign flip that entry point applies to a >= equation so the operator survives. The linear view machinery never needs the operator back, because a row of A x <= b carries it; a tail view does, because each operator picks a different formulation.
Algorithm
- Resolve the view against the universe with
get_linear_constraints, givinglc. Returnnothingwhere it places no name of the view. - Read the sign
sgnand the inequality flag of the view's operator withcomparison_sign_ineq_flag, and pick from them the operatoropthe view carries and the blockblkit landed in. - Scale the row
Aand the targetrhsbysgn, which undoes the flipget_linear_constraintsapplies to a>=equation. - Return the indices of the non-zero entries of
A, the coefficients at those indices,opandrhs.
Arguments
res: Parsed view constraint.sets: Asset set mapping asset names to indices.X: Asset returns matrix, read for its element type.strict: Iftrue, throws error for missing assets; otherwise, issue warnings.
Returns
nothing: If no name in the view could be placed in the universe.terms::@NamedTuple{idx::VecInt, coef::VecNum, op::Symbol, rhs::Number}: The assets the view names, their coefficients, its operator (:eq,:geqor:leq) and its target.
Related
PortfolioOptimisers.ep_normalise_view_term — Function
ep_normalise_view_term(coef::Number, op::Symbol, rhs::Number)Divide a single-asset tail view by its coefficient.
Returns the operator and target of the equivalent view whose coefficient is one, flipping the operator when the coefficient is negative.
Algorithm
- Divide the target by the coefficient, giving
rhs. - Where the coefficient is negative, exchange
:geqand:leq, givingop. An equality is unchanged, because dividing both sides by a negative number preserves it.
Arguments
coef: Coefficient the view gives the asset's risk measure.op: Comparison operator of the view.rhs: Target value of the view.
Returns
op::Symbol: Operator of the normalised view.rhs::Number: Target of the normalised view.
Related
PortfolioOptimisers.ep_view_formulations — Function
ep_view_formulations(alg, N::Integer, key::Symbol)Spread the tail view formulation setting of an entropy pooling prior over its views.
A single formulation applies to every view, a vector supplies one per view, and nothing leaves the choice to the view.
Arguments
alg: Formulation setting.N: Number of views.key: Field name, used in the error message.
Validation
- If
algis a vector,length(alg) == N.
Returns
algs::AbstractVector: One entry per view.
Related
PortfolioOptimisers.ep_sbar — Function
ep_sbar(sbar, T::Integer, alpha::Number, w::VecNum, ord::VecInt)Resolve the number of largest losses the integer conditional value-at-risk formulation considers.
Algorithm
- An
Integersbaris a count. Return it, capped atT. - Any other number is a fraction of
T. Returnceil(Int, sbar * T), never below one and capped atT. nothingtakes the rule of thumb of [1]. Walk the losses from the largest down, accumulating the prior probabilities, and stop at the positionsat which they first reachalpha.- Return twice
s, never belowceil(Int, 2 * alpha * T), never below one and capped atT. A view above the prior CVaR moves mass into the tail and needs about the positions; a view below it moves mass out and needs more.
Arguments
sbar: Setting held byIntegerConditionalValueatRiskView. AnIntegeris a count, a fraction in(0, 1)is a fraction ofT, andnothingapplies the rule of thumb of [1].T: Number of observations.alpha: Significance level of the view.w: Prior probability weights.ord: Indices of the losses in ascending order, so the largest loss is last.
Returns
sbar::Int: Number of largest losses, in1:T.
Related
References
- [1] D. Cajas. Entropy Pooling with CVaR and EVaR Views. Available at SSRN 7120258 (2026).
PortfolioOptimisers.ep_assert_reachable_view — Function
ep_assert_reachable_view(op::Symbol, rhs::Number, x::AbstractVector{<:VecNum},
coef::VecNum, eqn::AbstractString, name::AbstractString)Reject a tail view no reweighting of the sample can reach.
A tail risk measure of a reweighted sample lies between the smallest and the largest loss the sample holds, so a coefficient-weighted sum of measures lies between the sums of those bounds, and a view outside that band is infeasible however the probabilities move. The band is exact for one asset, and an outer bound for several: a reweighting that puts every asset at its worst loss at once need not exist.
Algorithm
- Read
hi, the sum over the assets of the coefficient times the largest loss where the coefficient is positive, and times the smallest loss where it is negative. Readlothe other way round. - Where
opasks the statistic to reach or exceedrhs, raise unlessrhssits belowhi. - Where
opasks the statistic to reach or fall belowrhs, raise unlessrhssits abovelo.
Arguments
op: Comparison operator of the view.rhs: Target value of the view.x: Per asset the view names, its loss series.coef: Per asset, the coefficient the view gives its risk measure.eqn: Equation of the view, used in the error message.name: Name of the view family, used in the error message.
Validation
- If
opis:geqor:eq,rhs < hi. - If
opis:leqor:eq,rhs > lo.
Returns
nothing.
Related
PortfolioOptimisers.ep_cvar_formulation — Function
ep_cvar_formulation(alg::Option{<:AbstractConditionalValueatRiskViewFormulation},
mixed::Bool, op::Symbol, rhs::Number, pv::Number)Pick the formulation of one conditional value-at-risk view.
A stated formulation is returned unchanged. nothing takes LinearConditionalValueatRiskView wherever it expresses the view exactly, which is every view whose lower level set is convex, and IntegerConditionalValueatRiskView otherwise: a view whose coefficients carry both signs, an upper bound, and an equality below the prior value of the left hand side.
The branch each input takes:
alg | mixed | op | rhs against pv | Branch |
|---|---|---|---|---|
| stated | any | any | any | alg, unchanged |
nothing | false | :geq | any | LinearConditionalValueatRiskView |
nothing | false | :eq | rhs >= pv | LinearConditionalValueatRiskView |
nothing | false | :eq | rhs < pv | IntegerConditionalValueatRiskView |
nothing | false | :leq | any | IntegerConditionalValueatRiskView |
nothing | true | any | any | IntegerConditionalValueatRiskView |
SequentialConditionalValueatRiskView is never the default. It writes every view the integer formulation does with no integer variable, but its posterior is a local minimiser of the divergence, and nothing stands for the exact formulation.
Arguments
alg: Stated formulation, ornothing.mixed: Whether the coefficients of the view carry both signs.op: Comparison operator of the view.rhs: Target value of the view.pv: Prior value of the view's left hand side.
Returns
alg::AbstractConditionalValueatRiskViewFormulation: The formulation to use.
Related
PortfolioOptimisers.ep_evar_formulation — Function
ep_evar_formulation(alg::Option{<:AbstractEntropicValueatRiskViewFormulation}, mixed::Bool,
op::Symbol, rhs::Number, pv::Number)Pick the formulation of one entropic value-at-risk view.
A stated formulation is returned unchanged. nothing takes ConicEntropicValueatRiskView wherever it expresses the view exactly, which is every view whose lower level set is convex, and GridEntropicValueatRiskView for an upper bound and an equality below the prior value. A view whose coefficients carry both signs has no grid to select from, because the grid is one asset's, so it takes SequentialEntropicValueatRiskView, the one formulation that expresses it.
The branch each input takes:
alg | mixed | op | rhs against pv | Branch |
|---|---|---|---|---|
| stated | any | any | any | alg, unchanged |
nothing | false | :geq | any | ConicEntropicValueatRiskView |
nothing | false | :eq | rhs >= pv | ConicEntropicValueatRiskView |
nothing | false | :eq | rhs < pv | GridEntropicValueatRiskView |
nothing | false | :leq | any | GridEntropicValueatRiskView |
nothing | true | any | any | SequentialEntropicValueatRiskView |
Arguments
alg: Stated formulation, ornothing.mixed: Whether the coefficients of the view carry both signs.op: Comparison operator of the view.rhs: Target value of the view.pv: Prior value of the view's left hand side.
Returns
alg::AbstractEntropicValueatRiskViewFormulation: The formulation to use.
Related
PortfolioOptimisers.ep_rlvar_formulation — Function
ep_rlvar_formulation(alg::Option{<:AbstractRelativisticValueatRiskViewFormulation},
mixed::Bool, op::Symbol, rhs::Number, pv::Number)Pick the formulation of one relativistic value-at-risk view.
A stated formulation is returned unchanged. nothing takes ConicRelativisticValueatRiskView wherever it expresses the view exactly, which is every view whose lower level set is convex, and GridRelativisticValueatRiskView for an upper bound and an equality below the prior value. A view whose coefficients carry both signs has no grid to select from, because the grid is one asset's, so it takes SequentialRelativisticValueatRiskView, the one formulation that expresses it.
The branch each input takes:
alg | mixed | op | rhs against pv | Branch |
|---|---|---|---|---|
| stated | any | any | any | alg, unchanged |
nothing | false | :geq | any | ConicRelativisticValueatRiskView |
nothing | false | :eq | rhs >= pv | ConicRelativisticValueatRiskView |
nothing | false | :eq | rhs < pv | GridRelativisticValueatRiskView |
nothing | false | :leq | any | GridRelativisticValueatRiskView |
nothing | true | any | any | SequentialRelativisticValueatRiskView |
Arguments
alg: Stated formulation, ornothing.mixed: Whether the coefficients of the view carry both signs.op: Comparison operator of the view.rhs: Target value of the view.pv: Prior value of the view's left hand side.
Returns
alg::AbstractRelativisticValueatRiskViewFormulation: The formulation to use.
Related
PortfolioOptimisers.ep_sequential_sides — Function
ep_sequential_sides(x::AbstractVector{<:VecNum}, coef::VecNum, op::Symbol, rhs::Number,
pv::Number)Orient a tail view as a lower bound, and split its assets into the dual side and the primal side of a sequential formulation.
Algorithm
- Orient the view. An upper bound, and an equality whose target sits at or below the prior value of the left hand side, are negated on both sides, so the view reads
>=. A lower bound, and an equality the prior sits below, are kept. An equality is therefore written as the bound the prior violates, which the entropy minimiser makes tight. - Put every asset whose oriented coefficient is positive on the dual side, whose measure is concave in the probabilities and takes its exact dual block. Put every other asset on the primal side, whose measure takes a linear upper bound.
Arguments
x: Per asset the view names, its loss series.coef: Per asset, the coefficient the view gives its risk measure.op: Comparison operator of the view.rhs: Target value of the view.pv: Prior value of the view's left hand side.
Returns
xd::AbstractVector{<:VecNum}: Loss series of the assets on the dual side.cd::VecNum: Their oriented coefficients, positive.xp::AbstractVector{<:VecNum}: Loss series of the assets on the primal side.cp::VecNum: Their oriented coefficients, negative.rhs::Number: Target of the oriented view.
Related
PortfolioOptimisers.ep_sequential_start — Method
ep_sequential_start(tv::AbstractSequentialTailViewConstraint, w::VecNum)Read the first surrogate row of a sequential tail view at probabilities under which the row can meet the view.
A linear upper bound is tight where it is read, but it can fall only as far as its smallest value over the simplex, and a target further below the prior than that leaves the first solve with no feasible point. The relativistic measure is the one this bites: its bound at the prior's pair has a floor at the shift plus the deformed logarithm, and only the tail term above it can move. ep_sequential_start walks the multipliers toward the target with a chain of exponential tilts before any solver runs, which is what the anchors of GridEntropicValueatRiskView and GridRelativisticValueatRiskView do to centre their grids. It calls no solver.
Algorithm
- Normalise
wto sum to one, and read the row at it withep_refine_tail_view. Return the carrier where its primal side is empty, because the view is then convex and the row is empty. - Read
need, the value the row must reach: the target, less the row's constant, less the coefficient-weighted sum of the measures of the dual side under the current probabilities, each read throughep_tail_surrogate_row. - Return the carrier where the largest coefficient of the row is at least
need. A probability vector then meets the row, and the solve can start. - Otherwise tilt the probabilities with
ep_row_tiltso the row reaches nine tenths of the way from its current value to its largest coefficient, re-read the row there, and return to step 2. Take at mostiterssteps, and return the last carrier where the tilt does not exist.
Arguments
tv: Sequential tail view constraint, with any row.w: Prior probability weights.
Returns
tv::AbstractSequentialTailViewConstraint: The carrier with its first row.
Related
PortfolioOptimisers.ep_add_cvar_view! — Function
ep_add_cvar_view!(tvs::AbstractVector, alg::AbstractConditionalValueatRiskViewFormulation,
x::AbstractVector{<:VecNum}, coef::VecNum, op::Symbol, rhs::Number,
alpha::Number, w::VecNum, pv::Number, eqn::AbstractString)Lower one conditional value-at-risk view into the tail view constraint its formulation needs.
Algorithm
LinearConditionalValueatRiskViewchecks the three preconditions below, then appends oneLinearConditionalValueatRiskViewConstraintcarryingx,coef,alphaandrhs.IntegerConditionalValueatRiskViewsorts the loss series of each asset the view names, giving the ascending ordero, and resolves the lengthsbof that asset's tail window withep_sbar.- It keeps the last
sbpositions ofoasord[k], and the losses at those positions asxw[k]. - It appends one
IntegerConditionalValueatRiskViewConstraintcarrying those windows,coef,alpha,opandrhs. SequentialConditionalValueatRiskVieworients the view and splits its assets withep_sequential_sides, builds aSequentialConditionalValueatRiskViewConstraintwith an empty surrogate row, reads its first row from the priorwwithep_sequential_start, and appends it.
Arguments
tvs: Tail view constraints, appended to.alg: Formulation of the view.x: Per asset the view names, its loss series.coef: Per asset, the coefficient the view gives its CVaR.op: Comparison operator of the view.rhs: Target value of the view.alpha: Significance level of the view.w: Prior probability weights.pv: Prior value of the view's left hand side.eqn: Equation of the view, used in the error messages.
Validation
LinearConditionalValueatRiskViewneeds coefficients of one sign, an operator other than<=, and, for an equality, a target at or above the prior value of the left hand side.
Returns
nothing: The function mutatestvsin-place.
Related
PortfolioOptimisers.ep_add_evar_view! — Function
ep_add_evar_view!(epc::AbstractDict, tvs::AbstractVector,
alg::AbstractEntropicValueatRiskViewFormulation,
x::AbstractVector{<:VecNum}, coef::VecNum, alpha::Number, op::Symbol,
rhs::Number, w::VecNum, zstar::VecNum, pv::Number, eqn::AbstractString;
args::Tuple = (), kwargs::NamedTuple = (;),
zlo_frac::Option{<:Number} = nothing)Lower one entropic value-at-risk view into the constraints its formulation needs.
ConicEntropicValueatRiskView and SequentialEntropicValueatRiskView produce one tail view constraint each. GridEntropicValueatRiskView produces linear rows on the posterior probabilities for the lower-bound half of the view, and a tail view constraint for the upper-bound half, so an equality view produces both.
Algorithm
ConicEntropicValueatRiskViewchecks the three preconditions below, then appends oneConicEntropicValueatRiskViewConstraintcarryingx,coef,alphaandrhs.GridEntropicValueatRiskViewchecks that the view names one asset, and normaliseswto sum to one, givingwi.- It builds the grid
zof dual variables withep_evar_grid. - It keeps the points whose row is finite, giving
keep, and raises wherekeepis empty. - For the lower-bound half of the view, it builds the row of each kept point with
ep_evar_grid_row, and adds it toepcunder:ineqwithadd_ep_constraint!, negated so the row reads as the<=sense that key states. - For the upper-bound half of the view, it appends one
GridEntropicValueatRiskViewConstraintcarryingx, the kept grid,alpha,rhsand the big-M constantM. SequentialEntropicValueatRiskVieworients the view and splits its assets withep_sequential_sides, builds aSequentialEntropicValueatRiskViewConstraintwith an empty surrogate row, reads its first row from the priorwwithep_sequential_start, and appends it.
Arguments
epc: Dictionary of entropy pooling constraints, mapping keys to(lhs, rhs)pairs.tvs: Tail view constraints, appended to.alg: Formulation of the view. A grid formulation is also where the number of steps and the tolerance of the anchor live, and a sequential one where the number of re-solves and their tolerance live.x: Per asset the view names, its loss series.coef: Per asset, the coefficient the view gives its EVaR.alpha: Significance level of the view.op: Comparison operator of the view.rhs: Target value of the view.w: Prior probability weights. They start the search for the dual variable the grid is centred on, and they are where the first surrogate row of a sequential view is read.zstar: Per asset, the dual variable that attains its prior EVaR.pv: Prior value of the view's left hand side.eqn: Equation of the view, used in the error messages.args: Additional positional arguments passed to the optimisation function.kwargs: Additional keyword arguments passed to the optimisation function.zlo_frac: Lower end of the bracket of the dual variable, as a fraction of the upper end, forwarded toep_evar.
Validation
ConicEntropicValueatRiskViewneeds coefficients of one sign, an operator other than<=, and, for an equality, a target at or above the prior value of the left hand side.GridEntropicValueatRiskViewneeds one asset, and at least one grid point whose row is finite.ep_evar_grid_rowoverflows at a dual variable near zero. The grid sits there whenpctapproaches one, and wholly there whenalpha * Tfalls below one, becauseep_evar's minimiser is then at the end of its bracket. The points it overflows at are dropped, and a grid that keeps none of them raises.
Returns
nothing: The function mutatesepcandtvsin-place.
Related
PortfolioOptimisers.ep_add_grid_tail_view! — Function
ep_add_grid_tail_view!(epc::AbstractDict, grid::AbstractVector, op::Symbol, row, msg)Keep the finite points of a tail view grid, and add the rows of its lower-bound half.
ep_add_grid_tail_view! is the scaffold shared by GridEntropicValueatRiskView and GridRelativisticValueatRiskView. Both build a grid of points, drop the points whose row is not finite, and add one linear row per kept point. They differ in what a point is and in how its row is built, and both reach the scaffold through row.
A point whose row is not finite is not a grid point, because a non-finite coefficient reaches the solver as NaN * x[j]. The caller's msg names the setting that put the whole grid there.
Algorithm
- Build the row of every point with
row, and keep the points whose coefficients and whose right-hand side are all finite. - Raise with
msgwhere no point is kept. - Where the view carries a lower-bound half, add the row of each kept point to
epcunder:ineqwithadd_ep_constraint!, negated so the row reads as the<=sense that key states. - Return the kept points, which the caller carries into the tail view constraint of the upper-bound half.
Arguments
epc: Dictionary of entropy pooling constraints, mapping keys to(lhs, rhs)pairs.grid: Points of the grid.op: Comparison operator of the view.row: Function taking one point to the coefficients and the right-hand side of its row.msg: Function of no arguments giving the message of the error raised where no point is kept. It is called only where the grid keeps no point.
Validation
- At least one point of the grid has a finite row. A grid that keeps no point raises an
ArgumentErrorcarryingmsg().
Returns
grid::AbstractVector: Points of the grid whose row is finite.
Related
PortfolioOptimisers.ep_add_rlvar_view! — Function
ep_add_rlvar_view!(epc::AbstractDict, tvs::AbstractVector,
alg::AbstractRelativisticValueatRiskViewFormulation,
x::AbstractVector{<:VecNum}, coef::VecNum, alpha::Number,
kappa::Number, op::Symbol, rhs::Number, w::VecNum, zstar::VecNum,
pv::Number, eqn::AbstractString; args::Tuple = (),
kwargs::NamedTuple = (;),
bracket::Option{<:RelativisticValueatRiskViewBracket} = nothing)Lower one relativistic value-at-risk view into the constraints its formulation needs.
ConicRelativisticValueatRiskView and SequentialRelativisticValueatRiskView produce one tail view constraint each. GridRelativisticValueatRiskView produces linear rows on the posterior probabilities for the lower-bound half of the view, and a tail view constraint for the upper-bound half, so an equality view produces both.
Algorithm
ConicRelativisticValueatRiskViewchecks the three preconditions below, then appends oneConicRelativisticValueatRiskViewConstraintcarryingx,coef,alpha,kappaandrhs.GridRelativisticValueatRiskViewchecks that the view names one asset, and normaliseswto sum to one, givingwi.- It builds the grid
t,zof primal points withep_rlvar_grid. - It keeps the points whose row is finite, giving
keep, and raises wherekeepis empty. - For the lower-bound half of the view, it builds the row of each kept point with
ep_rlvar_grid_row, and adds it toepcunder:ineqwithadd_ep_constraint!, negated so the row reads as the<=sense that key states. - For the upper-bound half of the view, it appends one
GridRelativisticValueatRiskViewConstraintcarryingx, the kept grid,alpha,kappa,rhsand the big-M constantM. SequentialRelativisticValueatRiskVieworients the view and splits its assets withep_sequential_sides, builds aSequentialRelativisticValueatRiskViewConstraintwith an empty surrogate row, reads its first row from the priorwwithep_sequential_start, and appends it.
Arguments
epc: Dictionary of entropy pooling constraints, mapping keys to(lhs, rhs)pairs.tvs: Tail view constraints, appended to.alg: Formulation of the view. A grid formulation is also where the number of steps and the tolerance of the anchor live, and a sequential one where the number of re-solves and their tolerance live.x: Per asset the view names, its loss series.coef: Per asset, the coefficient the view gives its RLVaR.alpha: Significance level of the view.kappa: Deformation parameter of the view.op: Comparison operator of the view.rhs: Target value of the view.w: Prior probability weights. They start the search for the point the grid is centred on, and they pin the shift of each grid point where that search does not converge. They are also where the first surrogate row of a sequential view is read.zstar: Per asset, the dual variable that attains its prior RLVaR.pv: Prior value of the view's left hand side. Withrhsit fixes the translation a grid centred on the prior carries.eqn: Equation of the view, used in the error messages.args: Additional positional arguments passed to the optimisation function.kwargs: Additional keyword arguments passed to the optimisation function.bracket: Spans of the searches, forwarded toep_rlvarandep_rlvar_shift.
Validation
ConicRelativisticValueatRiskViewneeds coefficients of one sign, an operator other than<=, and, for an equality, a target at or above the prior value of the left hand side.GridRelativisticValueatRiskViewneeds one asset, and at least one grid point whose row is finite.ep_rlvar_tailoverflows at a dual variable near zero, which is where the grid sits whenkappaapproaches one; the points it overflows at are dropped, and a grid that keeps none of them raises.
Returns
nothing: The function mutatesepcandtvsin-place.
Related
PortfolioOptimisers.ep_tail_view_prior_args — Function
ep_tail_view_prior_args(tail_views::ConditionalValueatRiskView, w::VecNum)
ep_tail_view_prior_args(tail_views::EntropicValueatRiskView, w::VecNum)
ep_tail_view_prior_args(tail_views::RelativisticValueatRiskView, w::VecNum)Give the trailing arguments a prior(...) reference of this tail view resolves under.
ep_tail_view_prior_args is one of the two kernels ep_tail_views! takes a measure from. It names the statistic get_pr_value reads, and it carries the level, the prior probabilities, and whatever settings the search for that statistic needs. replace_prior_views forwards the tuple unchanged, so a measure is added by adding a method here rather than by copying the lowering.
Arguments
tail_views: Tail view group whose settings the tuple carries.w: Prior probability weights.
Returns
args::Tuple: Trailing arguments ofreplace_prior_views, starting with the tag of the statistic.
Related
PortfolioOptimisers.ep_normalise_tail_view — Function
ep_normalise_tail_view(terms::NamedTuple, X::MatNum, eqn::AbstractString,
name::AbstractString)Normalise the coefficients of a tail view, read the loss series it is stated on, and say whether its coefficients carry both signs.
The steps below are shared by every tail view. A view of one asset is divided by its coefficient, so its target is the measure itself. A view of several assets whose coefficients share one sign is multiplied by that sign, so every coefficient is positive and the view is a positive combination of measures, whose lower level set is convex. A view whose coefficients carry both signs is a relative view, and is left as stated.
Algorithm
- Read
mixed, whether the coefficients carry both signs. - Where the view names one asset, divide it by that asset's coefficient with
ep_normalise_view_term, which flips the operator where the coefficient is negative, and set the coefficient to one. - Where it names several assets and
mixedis false, multiply both sides by the sign of the first coefficient through the same function, so every coefficient is positive and the operator flips where the sign is negative. - Read the loss series of each asset,
x, as its negated returns column. - Reject a target no reweighting of the sample reaches with
ep_assert_reachable_view.
Arguments
terms: Resolved terms of the view, asep_view_termsreturns them.X: Matrix of asset returns.eqn: Equation of the view, used in the error messages.name: Name of the risk measure, used in the error messages.
Returns
x::AbstractVector{<:VecNum}: Per asset the view names, its loss series.coef::VecNum: Per asset, its normalised coefficient.op::Symbol: Operator of the normalised view.rhs::Number: Target of the normalised view.mixed::Bool: Whether the coefficients carry both signs.
Related
PortfolioOptimisers.ep_add_tail_view! — Function
ep_add_tail_view!(epc::AbstractDict, tvs::AbstractVector,
tail_views::ConditionalValueatRiskView, alg, X::MatNum,
terms::NamedTuple, eqn::AbstractString, w::VecNum)
ep_add_tail_view!(epc::AbstractDict, tvs::AbstractVector,
tail_views::EntropicValueatRiskView, alg, X::MatNum,
terms::NamedTuple, eqn::AbstractString, w::VecNum)
ep_add_tail_view!(epc::AbstractDict, tvs::AbstractVector,
tail_views::RelativisticValueatRiskView, alg, X::MatNum,
terms::NamedTuple, eqn::AbstractString, w::VecNum)Lower one resolved tail view into the constraints its measure and its formulation need.
ep_add_tail_view! is the second of the two kernels ep_tail_views! takes a measure from. ep_tail_views! parses the group, expands its groups, and resolves its prior references and its terms; this verb carries everything past that point, which is everything the measures do not share. A measure is added by adding a method here and to ep_tail_view_prior_args.
Every measure admits a view over several assets. Normalise it with ep_normalise_tail_view, which also says whether the coefficients carry both signs, and read pv, the prior value of the left hand side, as the coefficient-weighted sum of the per-asset measures under w. Then pick the formulation and lower the view:
- A
ConditionalValueatRiskViewreads each asset's prior CVaR throughConditionalValueatRisk, picks the formulation withep_cvar_formulation, and appends withep_add_cvar_view!. - An
EntropicValueatRiskViewreads each asset's prior EVaR and the dual variable that attains it withep_evar, picks the formulation withep_evar_formulation, and appends withep_add_evar_view!. - A
RelativisticValueatRiskViewreads each asset's prior RLVaR and the primal pair that attains it withep_rlvar, picks the formulation withep_rlvar_formulation, and appends withep_add_rlvar_view!.
Arguments
epc: Dictionary of entropy pooling constraints, mapping keys to(lhs, rhs)pairs.tvs: Tail view constraints, appended to.tail_views: Tail view group the view belongs to. It carries the level, the formulation setting, and the settings of the searches.alg: Formulation of this view, asep_view_formulationsspread it.X: Matrix of asset returns.terms: Resolved terms of the view, asep_view_termsreturns them.eqn: Equation of the view, used in the error messages.w: Prior probability weights.
Returns
nothing: The function mutatesepcandtvsin-place.
Related
ep_tail_views!ep_tail_view_prior_argsep_normalise_tail_viewep_add_cvar_view!ep_add_evar_view!ep_add_rlvar_view!EntropyPoolingPrior
References
PortfolioOptimisers.ep_tail_views! — Function
ep_tail_views!(tail_views::Nothing, args...; kwargs...)No-op pass-through for tail view constraints when none are specified.
Arguments
tail_views::Nothing: Indicates that no tail view constraints are specified.args...: Additional positional arguments (ignored).kwargs...: Additional keyword arguments (ignored).
Returns
nothing.
Related
ep_tail_views!(tail_views::AbstractVector{<:AbstractEntropyPoolingTailViewEstimator},
args...; kwargs...)Lower each group of tail views under its own settings.
Every AbstractEntropyPoolingTailViewEstimator in the vector is lowered in turn, so the groups accumulate into the same constraint set and one entropy pooling solve answers all of them.
Algorithm
- Lower each group of
tail_viewsin turn, forwardingargs...andkwargs...to each call. - Return
nothing. Each call has already written its constraints intoepcandtvs.
Arguments
tail_views: Groups of tail views.args...: Additional positional arguments forwarded toep_tail_views!.kwargs...: Additional keyword arguments forwarded toep_tail_views!.
Returns
nothing: The function mutatesepcandtvsin-place.
Related
ep_tail_views!(tail_views::AbstractEntropyPoolingTailViewEstimator, epc::AbstractDict,
tvs::AbstractVector, pr::AbstractPriorResult, sets::UniverseSets,
w::VecNum; strict::Bool = false)Parse a group of tail views and lower them into entropy pooling constraints.
ep_tail_views! is the one lowering of the tail view family. It parses the view equations of a LinearConstraintEstimator, replaces prior references with their values, resolves the asset names against the universe, picks a formulation for each view, and appends the constraints that formulation needs. Unlike the recursive algorithm of MeucciEntropyPoolingPrior, nothing is solved here: the views become part of the one entropy pooling problem entropy_pooling solves.
It accepts ==, >= and <=. A group name expands to its members, each carrying the coefficient the group carried, so a view on a group constrains the sum of the members' risk measures and not their average. A view whose coefficients share one sign is a positive combination of measures, and its lower-bound form is convex. A view whose coefficients carry both signs is a relative view, and is not.
The two kernels below carry everything that differs between the conditional, the entropic and the relativistic measure, so a fourth measure supplies two methods rather than a fourth copy of this verb:
ep_tail_view_prior_argsnames the statistic aprior(...)reference resolves to, and the settings its search takes.ep_add_tail_view!checks the shape of the view, reads its prior value, picks its formulation, and appends its constraints.
Algorithm
- Parse the view equations of
tail_views.views.val, giving oneParsingResultper view. - Replace every group name by the assets it spans, giving one term per member.
- Replace every
prior(...)reference by the prior value of the measure, throughreplace_prior_viewsunder the tupleep_tail_view_prior_argsgives. - Spread the formulation setting over the views with
ep_view_formulations, givingalgs. - For each view in turn, resolve its terms with
ep_view_terms, and drop the view where no name of it is placed in the universe. - Lower the view with
ep_add_tail_view!.
Arguments
tail_views: Tail view constraints.epc: Dictionary of entropy pooling constraints, mapping keys to(lhs, rhs)pairs.tvs: Tail view constraints, appended to.pr: Prior result containing asset return information.sets: Asset set mapping asset names to indices.w: Prior probability weights.strict: Iftrue, throws error for missing assets; otherwise, issue warnings.
Returns
nothing: The function mutatesepcandtvsin-place.
Related
ep_tail_view_prior_argsep_add_tail_view!ConditionalValueatRiskViewEntropicValueatRiskViewRelativisticValueatRiskViewEntropyPoolingPrior
References
PortfolioOptimisers.add_ep_tail_view! — Function
add_ep_tail_view!(model::JuMP.Model, pw, tv::AbstractEntropyPoolingTailView,
sc1::Number)Add the variables and constraints of one tail view to an entropy pooling JuMP model.
add_ep_tail_view! is the one seam through which a conditional, entropic or relativistic value-at-risk view reaches the model. Each formulation has its own method, dispatched on the constraint carrier the view parser produced. The three dual carriers share one method, and the three sequential carriers share another: both write one dual block per asset with ep_tail_dual_block!, and differ in the row that bounds the sum.
JuMP formulation
The section covers the five methods, and every entry each of them registers. Each entry is anonymous: one model carries one block per view, so a name would collide on the second view of a family, and nothing reads these entries back by name.
Variables
pw: $\boldsymbol{p}$: $T \times 1$ posterior probabilities of the observations, summing to one. They are the unknown of the entropy pooling problem. It is read from the caller, and every entry below is registered against it.nu,tau,varsigma: created once per asset of the view byep_tail_dual_block!, for the dual carriers and for the dual side of the sequential ones. Its# JuMP formulationnames them.y,q: $\boldsymbol{y}$ and $\boldsymbol{q}$, $\bar{s} \times 1$ each, created once per asset by theIntegerConditionalValueatRiskViewConstraintmethod.yis binary, andqis bounded below by zero.y: $\boldsymbol{y}$, $K \times 1$ and binary, created by theGridEntropicValueatRiskViewConstraintandGridRelativisticValueatRiskViewConstraintmethods. It selects the grid point the view is met at.
Expressions
- $\varepsilon$: Left hand side of the view, built once per method and registered under no name. It is the coefficient-weighted sum of the per-asset expressions
ep_tail_dual_block!returns for the dual carriers, of the per-asset tail sums for the integer carrier, and of the dual-side expressions plus the surrogate row $b + \boldsymbol{c}^{\intercal} \boldsymbol{p}$ for the sequential carriers.
Constraints
The method of the three dual carriers, LinearConditionalValueatRiskViewConstraint, ConicEntropicValueatRiskViewConstraint and ConicRelativisticValueatRiskViewConstraint, registers one block of ep_tail_dual_block! per asset the view names, and one row:
- $s_{c1} \left(\bar{c} - \sum_{i} \gamma_{i} \sum_{j=1}^{T} \nu_{i,\,j} x_{i,\,j}\right) \leq 0$.
The method of the three sequential carriers, SequentialConditionalValueatRiskViewConstraint, SequentialEntropicValueatRiskViewConstraint and SequentialRelativisticValueatRiskViewConstraint, registers one block of ep_tail_dual_block! per asset of the dual side, and one row over both sides, divided by the largest coefficient of the surrogate row where that exceeds one, so the row's coefficients sit in $[-1, 1]$ however small the dual variable of a relativistic measure is:
- $s_{c1} \left(\bar{c} - \sum_{i \in \mathcal{P}} \gamma_{i} \sum_{j=1}^{T} \nu_{i,\,j} x_{i,\,j} - b - \sum_{j=1}^{T} c_{j} p_{j}\right) \Big/ \max\left(1, \lVert \boldsymbol{c} \rVert_{\infty}\right) \leq 0$.
The IntegerConditionalValueatRiskViewConstraint method registers five rows per asset the view names, over that asset's window of the $\bar{s}$ largest losses:
- $s_{c1} \left(q_{j} - y_{j}\right) \leq 0$, $\forall\, j = 1,\ldots,\bar{s}$.
- $s_{c1} \left(q_{j} - p_{[j]}\right) \leq 0$, $\forall\, j = 1,\ldots,\bar{s}$.
- $s_{c1} \left(p_{[j]} - (1 - y_{j}) - q_{j}\right) \leq 0$, $\forall\, j = 1,\ldots,\bar{s}$.
- $s_{c1} \left(y_{j} - y_{j+1}\right) \leq 0$, $\forall\, j = 1,\ldots,\bar{s}-1$.
- $s_{c1} \left(\sum_{j=1}^{\bar{s}} q_{j} - \alpha\right) = 0$.
and one further row on $\varepsilon = \sum_{i} \dfrac{\gamma_{i}}{\alpha} \sum_{j=1}^{\bar{s}} q_{i,\,j} x_{i,\,[j]}$, the view's operator picking which of the three:
- $s_{c1} \left(\varepsilon - \bar{c}\right) = 0$ under
:eq. - $s_{c1} \left(\bar{c} - \varepsilon\right) \leq 0$ under
:geq. - $s_{c1} \left(\varepsilon - \bar{c}\right) \leq 0$ under
:leq.
The GridEntropicValueatRiskViewConstraint method registers two rows:
- $s_{c1} \left(\sum_{k=1}^{K} y_{k} - 1\right) = 0$.
- $s_{c1} \left(\sum_{j=1}^{T} c_{k,\,j} p_{j} - \alpha \iota_{k} - M (1 - y_{k})\right) \leq 0$, $\forall\, k = 1,\ldots,K$.
The GridRelativisticValueatRiskViewConstraint method registers two rows:
- $s_{c1} \left(\sum_{k=1}^{K} y_{k} - 1\right) = 0$.
- $s_{c1} \left(\sum_{j=1}^{T} c_{k,\,j} p_{j} - b_{k} - M (1 - y_{k})\right) \leq 0$, $\forall\, k = 1,\ldots,K$.
Where:
- $s_{c1}$: Constraint scale of the entropy pooling optimiser. It multiplies both sides of a row, so a positive value leaves the feasible set unchanged.
- $\boldsymbol{p}$: $T \times 1$ posterior probabilities of the observations, summing to one. They are the unknown of the entropy pooling problem.
- $\alpha$: Significance level (left tail probability), $\alpha \in (0, 1)$.
- $T$: Number of observations.
- $\bar{c}$: Target conditional value at risk of the view.
- $x_{i,\,j}$: Loss of asset $i$ at observation $j$, the negated return.
- $\boldsymbol{\nu}_{i}$: $T \times 1$ vector of weights that attains the measure of asset $i$, from its block of
ep_tail_dual_block!. - $\bar{c}$: Target of the view, whichever measure it is stated on. A sequential carrier holds the view oriented as a lower bound, so its target carries the sign of that orientation.
- $\bar{s}$: Length of one asset's window of largest losses, from
ep_sbar. - $x_{[j]}$, $p_{[j]}$: Loss and posterior probability of the observation in position $j$ of that window, which is sorted ascending.
- $\gamma_{i}$: Coefficient the view gives asset $i$.
- $\mathcal{P}$: Assets on the dual side of a sequential carrier.
- $b$, $\boldsymbol{c}$: Surrogate row a sequential carrier holds, from
ep_tail_surrogate_row. - $\boldsymbol{y}$: Binary vector. It marks the tail of one asset's window in the integer conditional value-at-risk method, and selects one grid point in the two grid methods.
- $\boldsymbol{q}$: $\bar{s} \times 1$ vector that carries the product $q_{j} = p_{[j]} y_{j}$.
- $\varepsilon$: Left hand side of an integer conditional value-at-risk view, the coefficient-weighted sum of the per-asset posterior CVaRs.
- $K$: Number of grid points the carrier holds.
- $c_{k,\,j}$: Scaled coefficient of observation $j$ at grid point $k$, from
ep_evar_grid_roworep_rlvar_grid_row. - $\iota_{k}$, $b_{k}$: Scaled target of grid point $k$, from those same two functions.
- $M$: Big-M constant the grid carrier holds.
Relaxation
The encoding is not exact: the entries below bound the quantity instead of reproducing it, and the bound is tight only under the condition stated here.
The two grid methods and the sequential method bound the statistic. The dual method and the integer method are exact.
The sequential method is a restriction of the view, tightened by re-solves.
Direction. The surrogate row bounds each measure of the primal side from above, and each of them carries a negative coefficient, so the row's value sits at or below the view's left hand side. A posterior that meets the row meets the view.
Quantity. The coefficient-weighted sum of the posterior measures the view names, a statistic of
pw.Tightness. The row is tight at the posterior it was read at.
entropy_poolingre-reads it at each posterior withep_refine_tail_viewand solves again, until the slack is within the carrier'stolor itsitersre-solves are spent, so the view is met to that tolerance at the fixed point and over-met before it.Direction. Every grid point is a feasible point of the primal programme of the statistic, so its row bounds the statistic from above. The block asks one grid point to hold, so the posterior statistic lies at or below the target. The encoding is a restriction: it can only be tighter than the view asks, and the view is never violated.
Quantity. The posterior entropic value at risk under the
GridEntropicValueatRiskViewConstraintmethod, and the posterior relativistic value at risk under theGridRelativisticValueatRiskViewConstraintmethod. Both are statistics ofpw.Tightness. The bound is tight where the grid holds the point the posterior itself attains.
ep_evar_anchorandep_rlvar_anchorput the centre of the grid on that point. Where the anchor does not converge the grid falls back to the prior's point, and the posterior statistic can land strictly below the target. Widenpctor raiseKthere.
$M$ releases the rows of the grid points the selector does not pick. A row's coefficients sit in $(0, 1]$ and $\boldsymbol{p}$ sums to one, so the left hand side never exceeds one and the default $M$ of both carriers clears it. An $M$ below that bound restricts the model further, in the same direction.
The other half of a grid view is a relaxation, and it does not reach this function. A lower-bound view asks at $K$ points a condition that must hold everywhere, so the posterior statistic holds at the grid points and can fall short between them. ep_add_evar_view! and ep_add_rlvar_view! file those rows into the entropy pooling constraint dictionary rather than into the model.
Arguments
model: Entropy pooling JuMP model.pw: Vector of posterior probability variables.tv: Tail view constraint.sc1: Constraint scaling factor.
Returns
nothing: The function mutatesmodelin-place.
Related
AbstractEntropyPoolingTailViewep_tail_dual_block!LinearConditionalValueatRiskViewConstraintIntegerConditionalValueatRiskViewConstraintConicEntropicValueatRiskViewConstraintGridEntropicValueatRiskViewConstraintConicRelativisticValueatRiskViewConstraintGridRelativisticValueatRiskViewConstraintAbstractSequentialTailViewConstraintentropy_poolingEntropyPoolingPrior
References
PortfolioOptimisers.show_fields — Method
show_fields(_::EntropyPoolingPrior) -> NTuple{15, Symbol}
Renders every field of a EntropyPoolingPrior except cache.
The state a cache holds is the running detail of an incremental fit, not the configuration a reader looks the type up for, and it prints under the estimator at every site that renders one. Set set_show_nothing_fields!(:EntropyPoolingPrior, true) to render it.
Arguments
::EntropyPoolingPrior: Prior estimator, read for its type alone.
Returns
fields::Tuple: The field names to render, which is(:pe, :mu_views, :var_views, :cvar_views, :evar_views, :rlvar_views, :sigma_views, :sk_views, :kt_views, :cov_views, :rho_views, :sets, :opt, :w, :alg).
Related
PortfolioOptimisers.ep_prior — Function
ep_prior(alg::StagedEP, pe::EntropyPoolingPrior, X::MatNum, F::Option{<:MatNum},
pnl::Option{<:AssetPanel} = nothing; strict::Bool = false, kwargs...)Compute entropy pooling prior moments with tail views, enforcing the views in stages.
ep_prior accumulates the views of each stage into one constraint set and solves once per stage, so a stage's views hold alongside every view of the stages before it. The mean of an asset a later stage constrains is pinned to the value the earlier stage produced, so a higher moment view does not silently move it.
Algorithm
- Fit the wrapped prior estimator, giving
pr. The fit states the observation axis:Tissize(pr.X, 1), which a nested prior that drops rows makes smaller thansize(X, 1). - Read the prior probabilities
w0on that axis withep_prior_probabilities. They arepe.wwhere the caller set one,pr.wwhere the fit answered one, and the uniform1/Totherwise. A caller'spe.wreaches the wrapped estimator throughfactory, andpris refitted under it. - Stage one holds the mean, value at risk, conditional, entropic and relativistic value at risk views. Accumulate them into the constraint dictionary
epcand the tail view vectortvs. Where either is non-empty, solve fromw0withentropy_pooling, givingw1, and refitpratw1. - Stage two holds the variance and covariance views, with the mean of every asset they name pinned by
fix_mu!. Whereepcortvsis non-empty, solve fromw0underH1_EntropyPooling, or from the previousw1underH2_EntropyPooling, and refitprat the neww1. - Stage three holds the skewness, kurtosis and correlation views, with the mean and the variance of every asset they name pinned by
fix_mu!andfix_sigma!. Under the same emptiness test, solve from the same start step 4 takes, and refitprat the neww1. - Compute
ens, the effective number of scenarios ofw1, andkld, the divergence ofw1fromw0. - Return a
LowOrderPriorcarrying the refit moments,w1,ensandkld. The feature matrix and the factor block come fromprunchanged.
Every row of every family can drop under strict = false, and a stage then states no view. The emptiness test is on the rows the stages hold, not on the fields the caller set, so such a fit answers the prior: w1 is w0, kld is zero, and no refit runs.
Arguments
alg: Staged entropy pooling algorithm.::H1_EntropyPooling: Each stage re-solves from the original prior weights.::H2_EntropyPooling: Each stage re-solves from the previous stage's weights.
pe: Entropy pooling prior estimator.X: Asset returns matrix, already oriented.F: Optional factor returns matrix, already oriented.pnl: OptionalAssetPanel, the panel the carrier held. A wrapping prior forwards it unchanged, so that it can compose an estimator that is fitted on a panel. An estimator that reads no panel ignores it.strict: Iftrue, throws error for missing assets; otherwise, issue warnings.kwargs...: Additional keyword arguments forwarded to the wrapped prior estimator.
Returns
pr::LowOrderPrior: Prior result carrying the posterior probability weights.
Related
PortfolioOptimisers.ep_prior — Function
ep_prior(alg::H0_EntropyPooling, pe::EntropyPoolingPrior, X::MatNum,
F::Option{<:MatNum}, pnl::Option{<:AssetPanel} = nothing;
strict::Bool = false, kwargs...)Compute entropy pooling prior moments with tail views, enforcing every view in one optimisation.
ep_prior builds every view constraint against the same prior and solves once. It is faster than the staged algorithms and pins nothing, so a higher moment view is free to move a lower moment.
Algorithm
- Fit the wrapped prior estimator, giving
pr. The fit states the observation axis:Tissize(pr.X, 1), which a nested prior that drops rows makes smaller thansize(X, 1). - Read the prior probabilities
w0on that axis withep_prior_probabilities. They arepe.wwhere the caller set one,pr.wwhere the fit answered one, and the uniform1/Totherwise. A caller'spe.wreaches the wrapped estimator throughfactory, andpris refitted under it. - Build every view against that one
pr: the mean, value at risk, conditional, entropic and relativistic value at risk, variance, covariance, skewness, kurtosis and correlation views. Each row that is linear in the posterior probabilities reaches the constraint dictionaryepc, and each tail view that needs auxiliary variables reaches the tail view vectortvs. No asset's mean or variance is pinned. - Where
epcortvsis non-empty, solve once fromw0withentropy_pooling, givingw1, and refitpratw1. Every row of every family can drop understrict = false, and the view set then states nothing:w1isw0,kldis zero, and no refit runs. - Compute
ens, the effective number of scenarios ofw1, andkld, the divergence ofw1fromw0. - Return a
LowOrderPriorcarrying the refit moments,w1,ensandkld. The feature matrix and the factor block come fromprunchanged.
Arguments
alg: Single-shot entropy pooling algorithm.pe: Entropy pooling prior estimator.X: Asset returns matrix, already oriented.F: Optional factor returns matrix, already oriented.pnl: OptionalAssetPanel, the panel the carrier held. A wrapping prior forwards it unchanged, so that it can compose an estimator that is fitted on a panel. An estimator that reads no panel ignores it.strict: Iftrue, throws error for missing assets; otherwise, issue warnings.kwargs...: Additional keyword arguments forwarded to the wrapped prior estimator.
Returns
pr::LowOrderPrior: Prior result carrying the posterior probability weights.
Related
References
- [1]
- D. Cajas. Entropy Pooling with CVaR and EVaR Views. Available at SSRN 7120258 (2026).
- [2]
- D. Cajas. Entropy Pooling with Relativistic Value at Risk Views. Available at SSRN 7329718 (2026).