Norm error
PortfolioOptimisers.NormError — Type
abstract type NormError <: AbstractEstimatorAbstract supertype for all norm-based error algorithms.
All concrete and/or abstract types representing norm-based error algorithms (such as second-order cone or norm-one error) should be subtypes of NormError.
Interfaces
In order to implement a new norm-based error algorithm which will work seamlessly with the library, subtype NormError with all necessary parameters struct, and implement the following method:
norm_factor(f::NormError, T::Number) -> Number: Returns the divisor that scales the norm. TheT === nothingcase is already covered by a generic method that returns1.
The functor side is norm_error, and the model side is set_risk_constraints! for TrackingRiskMeasure and set_tracking_error_constraints! for TrackingError. All three must agree.
Related
PortfolioOptimisers.L2Norm — Type
struct L2Norm{__T_ddof} <: NormErrorSecond-order cone (SOC) norm-based error formulation.
L2Norm implements a norm-based error formulation using the Euclidean (L2) norm, scaled by the square root of the number of assets minus the degrees of freedom (ddof). This is commonly used for error constraints and objectives in portfolio optimisation.
Mathematical definition
\[\begin{align} \mathrm{TE}_{L_2}(\boldsymbol{a},\boldsymbol{b}) &= \frac{\lVert \boldsymbol{a} - \boldsymbol{b} \rVert_2}{\sqrt{T - d}}\,. \end{align}\]
Where:
- $\mathrm{TE}_{L_2}(\boldsymbol{a},\boldsymbol{b})$: L2-norm error.
- $\boldsymbol{a}$: Portfolio weight or return vector $T \times 1$.
- $\boldsymbol{b}$: Benchmark vector $T \times 1$.
- $T$: Number of observations.
- $d$: Degrees of freedom,
ddof. When $T$ is not provided the denominator is 1.
The source states the denominator as $\sqrt{T}$. The default ddof = 1 gives the sample denominator $\sqrt{T-1}$. Set ddof = 0 to recover the source.
Fields
ddof: Degrees-of-freedom correction.
Constructors
L2Norm(; ddof::Integer = 1) -> L2NormKeywords correspond to the struct's fields.
Validation
0 <= ddof.
Examples
julia> L2Norm()L2Norm ddof ┴ Int64: 1Related
References
- [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Section 9.2, Equation 9.16.
PortfolioOptimisers.SquaredL2Norm — Type
struct SquaredL2Norm{__T_ddof} <: NormErrorSecond-order cone (SOC) squared norm-based error formulation.
SquaredL2Norm implements a norm-based error formulation using the squared Euclidean (L2) norm, scaled by the number of assets minus the degrees of freedom (ddof). This is commonly used for norm error constraints and objectives in portfolio optimisation where squared error is preferred.
The value is the square of the L2Norm error, so a settings.ub on a TrackingRiskMeasure carries squared units. The JuMP model converts the bound with a square root, so the two encodings accept the same bound.
Mathematical definition
\[\begin{align} \mathrm{TE}_{L_2^2}(\boldsymbol{a},\boldsymbol{b}) &= \frac{\lVert \boldsymbol{a} - \boldsymbol{b} \rVert_2^2}{T - d}\,. \end{align}\]
Where:
- $\mathrm{TE}_{L_2^2}(\boldsymbol{a},\boldsymbol{b})$: Squared L2-norm error.
- $\boldsymbol{a}$: Portfolio weight or return vector $T \times 1$.
- $\boldsymbol{b}$: Benchmark vector $T \times 1$.
- $T$: Number of observations.
- $d$: Degrees of freedom,
ddof. When $T$ is not provided the denominator is 1.
Fields
ddof: Degrees-of-freedom correction.
Constructors
SquaredL2Norm(; ddof::Integer = 1,) -> SquaredL2NormKeywords correspond to the struct's fields.
Validation
0 <= ddof.
Examples
julia> SquaredL2Norm()SquaredL2Norm ddof ┴ Int64: 1Related
References
- [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Section 9.2, Equation 9.16.
PortfolioOptimisers.L1Norm — Type
struct L1Norm <: NormErrorNorm-one (NOC) error formulation.
L1Norm implements a norm-based error formulation using the L1 (norm-one) distance between portfolio and benchmark weights. This is commonly used for error constraints and objectives in portfolio optimisation where sparsity or absolute deviations are preferred.
Mathematical definition
\[\begin{align} \mathrm{TE}_{L_1}(\boldsymbol{a},\boldsymbol{b}) &= \frac{\lVert \boldsymbol{a} - \boldsymbol{b} \rVert_1}{T}\,. \end{align}\]
Where:
- $\mathrm{TE}_{L_1}(\boldsymbol{a},\boldsymbol{b})$: L1-norm error.
- $\boldsymbol{a}$: Portfolio weight or return vector $T \times 1$.
- $\boldsymbol{b}$: Benchmark vector $T \times 1$.
- $T$: Number of observations. When $T$ is not provided the denominator is 1.
Constructors
L1Norm() -> L1NormExamples
julia> L1Norm()L1Norm()Related
References
- [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Section 9.2, Equation 9.17.
PortfolioOptimisers.LpNorm — Type
struct LpNorm{__T_p, __T_ddof} <: NormErrorL-p norm error estimator.
LpNorm takes the Lp-norm of the difference between the portfolio and the benchmark returns, and divides it by $(T - d)^{1/p}$. It generalises L1Norm and L2Norm to a free norm order.
Mathematical definition
\[\begin{align} \mathrm{TE}_{L_p}(\boldsymbol{a},\boldsymbol{b}) &= \frac{\lVert \boldsymbol{a} - \boldsymbol{b} \rVert_p}{(T - d)^{1/p}}\,. \end{align}\]
Where:
- $\mathrm{TE}_{L_p}(\boldsymbol{a},\boldsymbol{b})$: Lp-norm error.
- $\boldsymbol{a}$: Portfolio weight or return vector $T \times 1$.
- $\boldsymbol{b}$: Benchmark vector $T \times 1$.
- $T$: Number of observations.
- $d$: Degrees of freedom,
ddof. When $T$ is not provided the denominator is 1. - $p$: Norm order.
Fields
p: Power or order parameter.
ddof: Degrees-of-freedom correction.
Constructors
LpNorm(; p::Number = 3, ddof::Integer = 0) -> LpNormKeywords correspond to the struct's fields.
Validation
0 <= ddof. The constructor does not boundp. The JuMP model does: bothset_risk_constraints!andset_tracking_error_constraints!need1 < pfor the power cone, and raise aDomainErrorotherwise. The functor accepts anypthatLinearAlgebra.normaccepts.
Examples
julia> LpNorm()LpNorm p ┼ Int64: 3 ddof ┴ Int64: 0Related
PortfolioOptimisers.LInfNorm — Type
struct LInfNorm{__T_ddof} <: NormErrorL-infinity norm (maximum absolute deviation) error estimator.
LInfNorm takes the largest absolute deviation between the portfolio and the benchmark returns, and divides it by $T - d$.
Mathematical definition
\[\begin{align} \mathrm{TE}_{L_\infty}(\boldsymbol{a},\boldsymbol{b}) &= \frac{\lVert \boldsymbol{a} - \boldsymbol{b} \rVert_\infty}{T - d}\,. \end{align}\]
Where:
- $\mathrm{TE}_{L_\infty}(\boldsymbol{a},\boldsymbol{b})$: L∞-norm error, the largest absolute deviation.
- $\boldsymbol{a}$: Portfolio weight or return vector $T \times 1$.
- $\boldsymbol{b}$: Benchmark vector $T \times 1$.
- $T$: Number of observations.
- $d$: Degrees of freedom,
ddof. When $T$ is not provided the denominator is 1.
Fields
ddof: Degrees-of-freedom correction.
Constructors
LInfNorm(; ddof::Integer = 0) -> LInfNormKeywords correspond to the struct's fields.
Validation
0 <= ddof.
Examples
julia> LInfNorm()LInfNorm ddof ┴ Int64: 0Related
PortfolioOptimisers.norm_factor — Function
norm_factor(f::Union{Nothing, <:NormError}, T::Option{<:Number})Compute the denominator that scales a norm in norm_error.
The factor is the single place where the optional observation count T is turned into a divisor. Each NormError declares its own factor, and the T === nothing case is a method, not a branch inside one. A branch is what let ifelse evaluate T - f.ddof on the nothing path.
Algorithm
The method Julia selects on the types of f and T is the algorithm. A T of nothing selects the method that returns 1, so the nothing case is a method and never a branch inside one.
f === nothinggivessqrt(T), the unweighted L2 factor.L2Normgivessqrt(T - f.ddof).SquaredL2NormgivesT - f.ddof.L1NormgivesT, because that norm carries no degrees of freedom.LpNormgives(T - f.ddof)^(1/f.p), taken withcbrtwhenf.pis3, the default.LInfNormgivesT - f.ddof.
Arguments
f: Norm-based error algorithm, aNormErrorsubtype.nothingmeans an unweighted L2 norm.T: Optional number of observations.
Returns
factor::Number: Divisor for the norm. It is1whenTisnothing.
Examples
julia> PortfolioOptimisers.norm_factor(L2Norm(), 4)1.7320508075688772julia> PortfolioOptimisers.norm_factor(LInfNorm(), nothing)1Related
References
- [5]
- D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025).