Entropy Pooling (a): private API

PortfolioOptimisers.AbstractSequentialTailViewConstraint — Type
abstract type AbstractSequentialTailViewConstraint <: AbstractEntropyPoolingTailView

Abstract 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

source
PortfolioOptimisers.LinearConditionalValueatRiskViewConstraint — Type
struct LinearConditionalValueatRiskViewConstraint{__T_x, __T_coef, __T_alpha, __T_rhs} <: AbstractEntropyPoolingTailView

Carries 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).
source
PortfolioOptimisers.IntegerConditionalValueatRiskViewConstraint — Type
struct IntegerConditionalValueatRiskViewConstraint{__T_ord, __T_x, __T_coef, __T_alpha, __T_op, __T_rhs} <: AbstractEntropyPoolingTailView

Carries 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, :geq and :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).
source
PortfolioOptimisers.ConicEntropicValueatRiskViewConstraint — Type
struct ConicEntropicValueatRiskViewConstraint{__T_x, __T_coef, __T_alpha, __T_rhs} <: AbstractEntropyPoolingTailView

Carries 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).
source
PortfolioOptimisers.GridEntropicValueatRiskViewConstraint — Type
struct GridEntropicValueatRiskViewConstraint{__T_x, __T_z, __T_alpha, __T_rhs, __T_M} <: AbstractEntropyPoolingTailView

Carries 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: Multiplier of the big-M constant of each row of the grid entropic value-at-risk formulation. The constant of a row is the smallest that releases it, so M >= 1, and M = 1 keeps every row as tight as the data allow.

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).
source
PortfolioOptimisers.ConicRelativisticValueatRiskViewConstraint — Type
struct ConicRelativisticValueatRiskViewConstraint{__T_x, __T_coef, __T_alpha, __T_kappa, __T_rhs} <: AbstractEntropyPoolingTailView

Carries 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).
source
PortfolioOptimisers.GridRelativisticValueatRiskViewConstraint — Type
struct GridRelativisticValueatRiskViewConstraint{__T_x, __T_t, __T_z, __T_alpha, __T_kappa, __T_rhs, __T_M} <: AbstractEntropyPoolingTailView

Carries 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 of z, 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: Multiplier of the big-M constant of each row of the grid relativistic value-at-risk formulation. The constant of a row is the smallest that releases it, so M >= 1, and M = 1 keeps every row as tight as the data allow.

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).
source
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} <: AbstractSequentialTailViewConstraint

Carries 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

References

  • [1] D. Cajas. Entropy Pooling with CVaR and EVaR Views. Available at SSRN 7120258 (2026).
source
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} <: AbstractSequentialTailViewConstraint

Carries 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 of ep_evar each re-read runs.
  • kwargs: Additional keyword arguments passed to the optimisation function. They reach the same search args does.
  • zlo_frac: Lower end of the bracket of the dual variable, as a fraction of the upper end, or nothing to take the span ep_evar states. 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

References

  • [1] D. Cajas. Entropy Pooling with CVaR and EVaR Views. Available at SSRN 7120258 (2026).
source
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} <: AbstractSequentialTailViewConstraint

Carries 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 of ep_rlvar each re-read runs.
  • kwargs: Additional keyword arguments passed to the optimisation function. They reach the same searches args does.
  • bracket: Spans the two scalar searches of this estimator run over, or nothing to 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

References

  • [2] D. Cajas. Entropy Pooling with Relativistic Value at Risk Views. Available at SSRN 7329718 (2026).
source
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 a SLOW_PROGRESS report into an OPTIMAL one.

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

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).
source
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 of x.

Related

source
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

  • [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).
source
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_a.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 rows tv held before the call were tight at w, within the tolerance the carrier holds. A tight row marks a fixed point of the sequence, which can be a local minimiser of the divergence and not the global one.

Related

source
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

  1. Normalise the observation probabilities in the logarithmic domain, giving lw.
  2. Bracket the dual variable. The upper end hi is (maximum(x) - dot(w, x)) / log(inv(alpha)), replaced by eps of its own type where that is not positive, and the lower end is hi * zlo_frac.
  3. Minimise the objective over the bracket with Optim.jl. Each evaluation goes through LogExpFunctions.logsumexp, so a small z does not overflow.
  4. Return the minimum as evar, and the minimiser as z.

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 takes Optim.Brent(), which is what Optim.optimize selects 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. nothing takes sqrt(eps(T)) for the element type T, 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 exceeds maximum(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 args or kwargs that 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).
source
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, so the row does not overflow before it is built. The bound alpha * isc then falls far below one at a small z, so an upper-bound row reaches the model divided by that bound too, by add_ep_tail_view!. A lower-bound row keeps the norm scale of ep_add_grid_tail_view!.

Algorithm

  1. Exponentiate the shifted loss series, giving c, the unscaled coefficients exp((x - ebar) / z).
  2. Read the largest entry of c into sc.
  3. Return c divided by sc, and isc, the reciprocal of sc.

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

source
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 - x for a loss series x.
  • 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).
source
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 of inv(alpha * T), from kappa_log.
  • z: Dual variable of the primal programme.
  • args: Additional positional arguments passed to the optimisation function. Left empty it takes Optim.Brent(), which is what Optim.optimize selects 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, or nothing to take the one RelativisticValueatRiskViewBracket states. This function reads tspan alone. It is a margin, not a proof, so widen it where the minimising shift lands on an end of the bracket. ep_rlvar reads the other two fields.

Validation

  • The search converges. It is a bracketed scalar minimisation of a convex function, so it fails only under args or kwargs that stop it early. A minimiser that lands on an end of the bracket does not fail it: Optim reports that end as converged.

Returns

  • res::@NamedTuple{risk::Number, t::Number}: The value at the minimising shift, and that shift.

Algorithm

  1. Bracket the shift by the loss range widened by tspan of its spans on each side. The minimising shift sits near the largest loss, so the bracket holds it with a wide margin.
  2. 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).
source
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 takes Optim.Brent(), which is what Optim.optimize selects for a bracketed scalar minimisation.
  • kwargs: Additional keyword arguments passed to the optimisation function. They reach both searches.
  • bracket: Spans of the searches, or nothing to take the one RelativisticValueatRiskViewBracket states. This function reads log_zlo and log_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_shift reads tspan.

Validation

  • Both searches converge. Each is a bracketed scalar minimisation of a convex function, so one fails only under args or kwargs that stop it early. A minimiser that lands on an end of a bracket does not fail it: Optim reports that end as converged.

Returns

  • res::@NamedTuple{rlvar::Number, t::Number, z::Number}: The value and the primal pair that attains it.

Algorithm

  1. Minimise over the logarithm of the dual variable with Optim.jl, over a bracket running from exp(log_zlo) to exp(log_zhi) times the loss range, which is about 2e-9 to about 2e4 under 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.
  2. Minimise over the shift at each candidate dual variable with ep_rlvar_shift.
  3. Re-run the inner minimisation at the minimising dual variable, so the shift returned is the one that attains the value.

Related

References

  • [2] D. Cajas. Entropy Pooling with Relativistic Value at Risk Views. Available at SSRN 7329718 (2026).
source
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, so the row does not overflow before it is built. The target then falls far below one at a small z, so an upper-bound row reaches the model divided by that target too, by add_ep_tail_view!. A lower-bound row keeps the norm scale of ep_add_grid_tail_view!.

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).
source
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}$ over the observations with $w_{j} > 0$, so the tilt exists exactly when $b$ sits strictly inside that range. A tilt cannot put mass on an observation of zero prior probability, so the coefficient of such an observation bounds nothing.

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 for Float64 happens near step 64, so this binds only a type of higher precision.

Validation

  • iters >= 1.

Returns

  • q::Option{VecNum}: The tilted probabilities, or nothing when b sits outside the range of c over the support of w and no tilt attains it, or when the tilted row is not finite.

Algorithm

  1. Return nothing when b sits outside the open range of c over the observations with w > 0.
  2. Bracket the root by doubling the tilt away from zero until the row's value crosses b.
  3. Bisect the bracket to the resolution of the floating-point type, or for iters steps, whichever comes first.
  4. Return nothing when the tilted weights sum to zero or to a value that is not a number, and the normalised weights otherwise.

Related

References

  • [2] D. Cajas. Entropy Pooling with Relativistic Value at Risk Views. Available at SSRN 7329718 (2026).
source
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 (see ep_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 to ep_evar.

Returns

  • res::Option{@NamedTuple{z::Number, w::VecNum}}: The dual variable and the posterior that attains it, or nothing when the iteration does not reach the target.

Algorithm

  1. Build the row of the current dual variable with ep_evar_grid_row. Return nothing when it is not finite.
  2. Tilt the prior so the row is tight with ep_row_tilt. Return nothing when no probability vector makes it tight.
  3. Recompute the dual variable as the minimiser at the tilted probabilities with ep_evar.
  4. Stop when the entropic value at risk of the tilted probabilities is within tol of the target, and return the dual variable and those probabilities.
  5. Return nothing after iters steps without that.

Related

References

  • [1] D. Cajas. Entropy Pooling with CVaR and EVaR Views. Available at SSRN 7120258 (2026).
source
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 (see ep_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 to ep_evar.

Returns

  • z::VecNum: Dual variable of each grid point.

Algorithm

  1. Take the prior's dual variable as the centre.
  2. 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.
  3. Span the dual variable from zc * (1 - pct) to zc * (1 + pct) in K points. K is 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).
source
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 (see ep_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 to ep_rlvar and ep_rlvar_shift.

Returns

  • res::Option{@NamedTuple{t::Number, z::Number, w::VecNum}}: The pair and the posterior that attains it, or nothing when the iteration does not reach the target.

Algorithm

  1. Build the row of the current pair with ep_rlvar_grid_row. Return nothing when it is not finite.
  2. Tilt the prior so the row is tight with ep_row_tilt. Return nothing when no probability vector makes it tight.
  3. Recompute the pair as the minimiser at the tilted probabilities with ep_rlvar.
  4. Stop when the relativistic value at risk of the tilted probabilities is within tol of the target, and return the pair and those probabilities.
  5. Return nothing after iters steps without that.

Related

References

  • [2] D. Cajas. Entropy Pooling with Relativistic Value at Risk Views. Available at SSRN 7329718 (2026).
source
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 (see ep_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 to ep_rlvar and ep_rlvar_shift.

Returns

  • t::VecNum: Shift variable of each grid point.
  • z::VecNum: Dual variable of each grid point.

Algorithm

  1. Take the prior's pair as the centre, and the distance from the prior value to the target as the translation each shift carries.
  2. 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.
  3. Span the dual variable from zc * (1 - pct) to zc * (1 + pct) in K points. K is odd, so the centre is a point of the grid, and a grid of one point is the centre alone.
  4. 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).
source
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

  1. Normalise w to sum to one, and read the row at it with ep_refine_tail_view. Return the carrier where its primal side is empty, because the view is then convex and the row is empty.
  2. 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 through ep_tail_surrogate_row.
  3. 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.
  4. Otherwise tilt the probabilities with ep_row_tilt so 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 most iters steps, 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

source
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 by ep_tail_dual_block!, for the dual carriers and for the dual side of the sequential ones. Its # JuMP formulation names them.
  • y, q: $\boldsymbol{y}$ and $\boldsymbol{q}$, $\bar{s} \times 1$ each, created once per asset by the IntegerConditionalValueatRiskViewConstraint method. y is binary, and q is bounded below by zero.
  • y: $\boldsymbol{y}$, $K \times 1$ and binary, created by the GridEntropicValueatRiskViewConstraint and GridRelativisticValueatRiskViewConstraint methods. 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-1}) - q_{j}\right) \leq 0$, $\forall\, j = 2,\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 and GridRelativisticValueatRiskViewConstraint methods register two rows each, over the row of each grid point divided by its bound:

  • $s_{c1} \left(\sum_{k=1}^{K} y_{k} - 1\right) = 0$.
  • $s_{c1} \left(\sum_{j=1}^{T} \dfrac{c_{k,\,j}}{b_{k}} p_{j} - 1 - M M_{k} (1 - y_{k})\right) \leq 0$, $\forall\, k = 1,\ldots,K$, with $M_{k} = \max_{j} c_{k,\,j} / b_{k} - 1$.

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 tail mass of each observation of the window: $p_{[j]}$ above the lowest marked observation, a part of $p_{[j]}$ at it, and zero below it.
  • $\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_row or ep_rlvar_grid_row.
  • $b_{k}$: Scaled bound of grid point $k$, from those same two functions. It is $\alpha$ times the reciprocal that ep_evar_grid_row returns, and the target that ep_rlvar_grid_row returns.
  • $M_{k}$: Smallest big-M constant that releases the row of grid point $k$.
  • $M$: Big-M multiplier 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 is exact. The integer method is exact over the posteriors whose tail of mass $\alpha$ lies inside the window of $\bar{s}$ largest losses, which is every posterior when $\bar{s} = T$.

The sequential method is a restriction of the view, tightened by re-solves.

  1. 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.

  2. Quantity. The coefficient-weighted sum of the posterior measures the view names, a statistic of pw.

  3. Tightness. The row is tight at the posterior it was read at. entropy_pooling re-reads it at each posterior with ep_refine_tail_view and solves again, until the slack is within the carrier's tol or its iters re-solves are spent, so the view is met to that tolerance at the fixed point and over-met before it.

  4. 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.

  5. Quantity. The posterior entropic value at risk under the GridEntropicValueatRiskViewConstraint method, and the posterior relativistic value at risk under the GridRelativisticValueatRiskViewConstraint method. Both are statistics of pw.

  6. Tightness. The bound is tight where the grid holds the point the posterior itself attains. ep_evar_anchor and ep_rlvar_anchor put 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. Widen pct or raise K there.

A row reads against one because its bound $b_{k}$ falls far below a solver's feasibility tolerance where the dual variable is small. Read at that scale, the whole row is inside the tolerance, the solver takes it as met by any posterior, and the selector can pick that grid point with the view unmet.

$M M_{k}$ releases the rows of the grid points the selector does not pick. $\boldsymbol{p}$ sums to one, so the left hand side of row $k$ never exceeds $\max_{j} c_{k,\,j} / b_{k}$, and $M_{k}$ is the smallest constant that clears it. An $M$ below one would cut off a posterior the view admits, so $M \geq 1$. An $M$ above one gives the released rows headroom for a posterior that sums to one only to the solver's tolerance, but it also widens the slack that the tolerance on integrality opens on the selected row, so the default is $M = 1$.

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 mutates model in-place.

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).
source

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).