Composite price-level statistics

This page has more statistics for PriceLevelExpectedReturns, from later papers on online portfolio selection. They are a truncated exponential moving average, a double estimate with Gaussian weights, and a statistic that switches per asset between three others on the sign of a trend test. There is also a radial-basis mix of several trend forecasts, centred on the trend with the best worst-case return over the last window periods. The last is the three-state price prediction of kernel trend pattern tracking, which keeps its previous prediction and fits its first state with an elastic-net regression.

PortfolioOptimisers.TruncatedExponentialMovingAverage — Type
struct TruncatedExponentialMovingAverage{T1<:Real, T2<:Integer} <: AbstractPriceLevelStatistic

Takes an exponential average of the last window price levels, truncated and not normalised, which is the forecast of a rising asset in the trend promote price tracing of Dai, Liang, Dai, Huang and Adnan (2022).

The paper prints this forecast as a sum of five terms (eq. 7 and Algorithm 1). Its first term reads the level of the next period, $\boldsymbol{p}_{t+1}$, which is not known at period $t$. If that term means $\boldsymbol{p}_{t-4}$, the oldest level gets the largest weight. The library keeps the paper's five coefficients and gives the largest one to the current level, as an exponential moving average does. Algorithm 1 of the paper sets alpha = 0.5, and its experiments use window = 5. These are the defaults.

Mathematical definition

\[\begin{align} \hat{\boldsymbol{x}}_{t+1} &= \alpha \sum_{k = 0}^{w - 1} (1 - \alpha)^{k}\, \boldsymbol{p}_{t - k} \oslash \boldsymbol{p}_{t}\,. \end{align}\]

Where:

  • $\hat{\boldsymbol{x}}_{t+1}$: Price Relative Forecast for period $t + 1$, made after the row of period $t$.
  • $\alpha$: Smoothing weight on the current level, in $(0, 1]$. A smaller weight gives a longer memory.
  • $\boldsymbol{p}_t$: Price level vector of period $t$, one entry per asset.
  • $w$: Price-level window, the number of price levels a statistic reads, the current one included.

The weights fall with age and sum to $1 - (1 - \alpha)^{w}$, not to one. On a flat path the forecast is therefore below one at every $\alpha$ below one, and at the defaults the weights sum to 0.96875. At $\alpha = 1$ the forecast is one in every asset.

Fields

  • alpha: The smoothing weight on the current level, 0 < alpha <= 1.
  • window: The number of price levels the statistic reads, the current one included; window - 1 returns reconstruct them.

Constructors

TruncatedExponentialMovingAverage(; alpha::Real = 0.5, window::Integer = 5) -> TruncatedExponentialMovingAverage

Keywords correspond to the struct's fields.

Validation

  • 0 < alpha <= 1. A DomainError is thrown otherwise.
  • window >= 2. A DomainError is thrown otherwise.

Examples

julia> TruncatedExponentialMovingAverage()TruncatedExponentialMovingAverage   alpha ┼ Float64: 0.5  window ┴ Int64: 5

Related

References

  • [57] H.-L. Dai, C.-X. Liang, H.-M. Dai, C.-Y. Huang and R. M. Adnan. An online portfolio strategy based on trend promote price tracing ensemble learning algorithm. Knowledge-Based Systems 239, 107957 (2022). Equation (7) and Algorithm 1.
source
PortfolioOptimisers.GaussianWeightedDoubleEstimate — Type
struct GaussianWeightedDoubleEstimate{T1<:Real, T2<:Real} <: AbstractPriceLevelStatistic

Averages two Gaussian-weighted estimates of the next price level, which is the forecast of the Gaussian weighting reversion of Cai and Ye (2019).

The first estimate weights the last $l$ levels with the left half of a Gaussian. The second estimate is the same weighted mean, with the current level replaced by the first estimate of the previous period. The weights fall with age, and the window $l$ is the number of levels whose weight is at least the cutoff. At the paper's tau = 2.8 and cutoff = 0.005, which are the defaults, $l = 9$. The previous estimate is a function of the levels $\boldsymbol{p}_{t-l}, \ldots, \boldsymbol{p}_{t-1}$, so the statistic carries no state and reads $l$ returns. Over fewer levels, each estimate reads the levels it has.

Mathematical definition

\[\begin{align} g_k &= \exp\left(-\frac{k^2}{2 \tau^2}\right)\,,\quad k = 1, \ldots, l\,,\quad l = \left\lfloor \sqrt{-2 \tau^2 \ln \epsilon_w} \right\rfloor\,,\\ \hat{\boldsymbol{p}}^{(1)}_{t} &= \frac{\sum_{k = 1}^{l} g_k\, \boldsymbol{p}_{t - k + 1}}{\sum_{k = 1}^{l} g_k}\,,\\ \hat{\boldsymbol{p}}^{(2)}_{t} &= \frac{g_1\, \hat{\boldsymbol{p}}^{(1)}_{t - 1} + \sum_{k = 2}^{l} g_k\, \boldsymbol{p}_{t - k + 1}}{\sum_{k = 1}^{l} g_k}\,,\\ \hat{\boldsymbol{x}}_{t+1} &= \tfrac{1}{2}\left(\hat{\boldsymbol{p}}^{(1)}_{t} + \hat{\boldsymbol{p}}^{(2)}_{t}\right) \oslash \boldsymbol{p}_{t}\,. \end{align}\]

Where:

  • $g_k$: Gaussian weight of the level $k - 1$ periods before the current one.
  • $\tau$: Width of the Gaussian, in periods.
  • $\epsilon_w$: Cutoff, the smallest weight that a level in the window takes.
  • $l$: Gaussian window, the number of levels that each estimate reads.
  • $\hat{\boldsymbol{p}}^{(1)}_{t}$, $\hat{\boldsymbol{p}}^{(2)}_{t}$: First and second estimates of the next level, made at period $t$.
  • $\boldsymbol{p}_t$: Price level vector of period $t$, one entry per asset.
  • $\hat{\boldsymbol{x}}_{t+1}$: Price Relative Forecast for period $t + 1$, made after the row of period $t$.

Fields

  • tau: The width of the Gaussian, in periods.
  • cutoff: The weight below which a level leaves the window.

Constructors

GaussianWeightedDoubleEstimate(; tau::Real = 2.8, cutoff::Real = 0.005) -> GaussianWeightedDoubleEstimate

Keywords correspond to the struct's fields.

Validation

  • tau > 0. A DomainError is thrown otherwise.
  • 0 < cutoff < 1. A DomainError is thrown otherwise.
  • -2 tau^2 log(cutoff) >= 1, so that the window holds at least one level. A DomainError is thrown otherwise.

Examples

julia> GaussianWeightedDoubleEstimate()GaussianWeightedDoubleEstimate     tau ┼ Float64: 2.8  cutoff ┴ Float64: 0.005

Related

References

  • [58] X. Cai and Z. Ye. Gaussian weighting reversion strategy for accurate online portfolio selection. IEEE Transactions on Signal Processing 67, 5558–5570 (2019). Equations (2) to (6).
source
PortfolioOptimisers.AbstractTrendTest — Type
abstract type AbstractTrendTest <: AbstractAlgorithm

Abstract supertype for the per-asset trend tests that a TrendSwitch switches on.

A test returns one sign per asset: +1 for a rising asset, 0 for a flat one and -1 for a falling one. Over fewer than two levels no trend exists, and the tests of the library return zero in every asset.

Interfaces

To implement a new trend test, subtype AbstractTrendTest with its parameters as part of the struct, and implement the following methods:

  • trend_sign(test::AbstractTrendTest, P::AbstractMatrix) -> AbstractVector: The trend sign of each asset over the levels P, levels × assets, whose last row is the current level.
  • window_rows(test::AbstractTrendTest) -> Integer: The number of return rows that the test reads. The default reads test.window - 1, for a test over window levels.

Related

source
PortfolioOptimisers.PairwiseSlopeSum — Type
struct PairwiseSlopeSum{T1<:Integer} <: AbstractTrendTest

Takes the sign of the sum of the slopes between every pair of the last window levels, per asset, which is the trend test of the trend promote price tracing of Dai, Liang, Dai, Huang and Adnan (2022).

At window = 5 the sum runs over ten pairs. The paper's text counts these ten pairs, and its eq. (7) sums them. Its slope formula, eq. (6), writes only the four slopes from the current level, and the sign of those four can differ from the sign of the ten. The test has no threshold, so an asset is flat only when the sum is exactly zero, as it is on a constant window.

Mathematical definition

\[\begin{align} s_{i} &= \operatorname{sign} \sum_{t - w < a < b \leq t} \frac{p_{b, i} - p_{a, i}}{b - a}\,. \end{align}\]

Where:

  • $s_i$: Trend sign of asset $i$, $+1$ for a rising asset, $0$ for a flat one and $-1$ for a falling one.
  • $p_{t,i}$: Price level of asset $i$ at period $t$, the entry $i$ of $\boldsymbol{p}_t$.
  • $t$: Period index, counted from one.
  • $w$: Price-level window, the number of price levels a statistic reads, the current one included.

Fields

  • window: The number of price levels the statistic reads, the current one included; window - 1 returns reconstruct them.

Constructors

PairwiseSlopeSum(; window::Integer = 5) -> PairwiseSlopeSum

Keywords correspond to the struct's fields.

Validation

  • window >= 2. A DomainError is thrown otherwise.

Examples

julia> PairwiseSlopeSum()PairwiseSlopeSum  window ┴ Int64: 5

Related

References

  • [57] H.-L. Dai, C.-X. Liang, H.-M. Dai, C.-Y. Huang and R. M. Adnan. An online portfolio strategy based on trend promote price tracing ensemble learning algorithm. Knowledge-Based Systems 239, 107957 (2022). Equations (6) and (7).
source
PortfolioOptimisers.RegressionSlope — Type
struct RegressionSlope{T1<:Integer, T2<:Real, T3<:Real} <: AbstractTrendTest

Compares the ridge-regularised slope of a straight line through the last window levels with a threshold, per asset, which is the trend test of the local adaptive learning of Guan and An (2019).

The line has a free intercept, and the ridge weight penalises the slope alone, as in eq. (4) of the paper. The paper states no ridge weight, and lambda = 0 is plain least squares. Its experiments use window = 5 and threshold = 0.1, the defaults. An asset is rising when its slope is above the threshold, flat when the slope equals it, and falling when the slope is below it. So an asset with a small positive slope is falling. Local adaptive learning reads the same statistic on the flat and the falling branch, so this does not change the paper's rule.

The test takes the slope on the reconstructed path, whose last level is one. The threshold is therefore in units of the current price per period, and the paper's 0.1 means the same for every asset. The paper regresses on its own price series and states no normalisation, so there the threshold scales with the level of each asset.

Mathematical definition

\[\begin{align} a_{i} &= \frac{\sum_{\tau = 1}^{w} (\tau - \bar{\tau})(p_{t - w + \tau, i} - \bar{p}_{i})}{\sum_{\tau = 1}^{w} (\tau - \bar{\tau})^2 + \lambda}\,,\\ s_{i} &= \operatorname{sign}(a_{i} - \eta)\,. \end{align}\]

Where:

  • $a_i$: Ridge slope of asset $i$, in levels per period.
  • $\tau$: Position of a level in the window, one for the oldest.
  • $\bar{\tau} = (w + 1) / 2$: Mean position.
  • $\bar{p}_{i}$: Mean level of asset $i$ over the window.
  • $\lambda$: Ridge weight on the slope.
  • $\eta$: Threshold on the slope.
  • $s_i$: Trend sign of asset $i$, $+1$ for a rising asset, $0$ for a flat one and $-1$ for a falling one.
  • $p_{t,i}$: Price level of asset $i$ at period $t$, the entry $i$ of $\boldsymbol{p}_t$.
  • $t$: Period index, counted from one.
  • $w$: Price-level window, the number of price levels a statistic reads, the current one included.

Fields

  • window: The number of price levels the statistic reads, the current one included; window - 1 returns reconstruct them.
  • threshold: The slope above which an asset is rising.
  • lambda: The ridge weight on the slope, 0 for plain least squares.

Constructors

RegressionSlope(; window::Integer = 5, threshold::Real = 0.1, lambda::Real = 0) -> RegressionSlope

Keywords correspond to the struct's fields.

Validation

  • window >= 2. A DomainError is thrown otherwise.
  • lambda >= 0. A DomainError is thrown otherwise.

Examples

julia> RegressionSlope()RegressionSlope     window ┼ Int64: 5  threshold ┼ Float64: 0.1     lambda ┴ Int64: 0

Related

References

  • [59] H. Guan and Z. An. A local adaptive learning system for online portfolio selection. Knowledge-Based Systems 186, 104958 (2019). Equations (3) and (4).
source
PortfolioOptimisers.trend_sign — Function
trend_sign(test::PairwiseSlopeSum, P::AbstractMatrix)
trend_sign(test::RegressionSlope, P::AbstractMatrix)

Returns the trend sign of each asset over the levels P: +1 for a rising asset, 0 for a flat one and -1 for a falling one.

The pairwise test takes the sign of the sum of its slopes, and the regression test takes the sign of its slope minus its threshold. Each test states its sign in its own # Mathematical definition. Over fewer than two levels both tests return zero in every asset.

Arguments

  • test: The trend test.
  • P: The levels of the test's window, levels × assets, whose last row is the current level.

Returns

  • s::Vector: The sign per asset, in the element type of the levels or a wider one.

Related

source
PortfolioOptimisers.TrendSwitch — Type
struct TrendSwitch{T1<:AbstractTrendTest, T2<:AbstractPriceLevelStatistic, T3<:AbstractPriceLevelStatistic, T4<:AbstractPriceLevelStatistic} <: AbstractPriceLevelStatistic

Switches per asset between three statistics on the sign of a trend test, one statistic for a rising asset, one for a flat asset and one for a falling asset.

The trend promote price tracing of Dai, Liang, Dai, Huang and Adnan (2022) switches on the PairwiseSlopeSum. It takes the TruncatedExponentialMovingAverage of a rising asset, the current price of a flat one and the WindowPeak of a falling one. The local adaptive learning of Guan and An (2019) switches on the RegressionSlope. It takes the WindowPeak above the threshold and the ExponentialMovingAverage otherwise, so its flat and falling branches hold the same statistic.

The composite holds the largest window of its test and its branches, and it reads each of them over its own window. A folding branch reads every level. The composite then holds every row, and the branch runs the paper's recursion over the full history.

Mathematical definition

\[\begin{align} \hat{x}_{t+1, i} &= \begin{cases} u_{i} / p_{t, i} & s_{i} = +1\,,\\ f_{i} / p_{t, i} & s_{i} = 0\,,\\ d_{i} / p_{t, i} & s_{i} = -1\,. \end{cases} \end{align}\]

Where:

  • $\hat{\boldsymbol{x}}_{t+1}$: Price Relative Forecast for period $t + 1$, made after the row of period $t$. Its entry $i$ is $\hat{x}_{t+1, i}$.
  • $s_i$: Trend sign of asset $i$, $+1$ for a rising asset, $0$ for a flat one and $-1$ for a falling one. The test of the switch gives it.
  • $u_i$, $f_i$, $d_i$: Statistics of asset $i$ under the rising, the flat and the falling branch, each over its own window.
  • $p_{t,i}$: Price level of asset $i$ at period $t$, the entry $i$ of $\boldsymbol{p}_t$.

Fields

  • test: The per-asset trend test.
  • rising: The statistic of a rising asset.
  • flat: The statistic of a flat asset.
  • falling: The statistic of a falling asset.

Constructors

TrendSwitch(;    test::AbstractTrendTest = PairwiseSlopeSum(),    rising::AbstractPriceLevelStatistic = TruncatedExponentialMovingAverage(),    flat::AbstractPriceLevelStatistic = LaggedPrice(; lag = 0),    falling::AbstractPriceLevelStatistic = WindowPeak()) -> TrendSwitch

Keywords correspond to the struct's fields.

Examples

julia> TrendSwitch()TrendSwitch     test ┼ PairwiseSlopeSum          │   window ┴ Int64: 5   rising ┼ TruncatedExponentialMovingAverage          │    alpha ┼ Float64: 0.5          │   window ┴ Int64: 5     flat ┼ LaggedPrice          │   lag ┴ Int64: 0  falling ┼ WindowPeak          │   window ┴ Int64: 5

Related

References

  • [57] H.-L. Dai, C.-X. Liang, H.-M. Dai, C.-Y. Huang and R. M. Adnan. An online portfolio strategy based on trend promote price tracing ensemble learning algorithm. Knowledge-Based Systems 239, 107957 (2022). Equation (7).
  • [59] H. Guan and Z. An. A local adaptive learning system for online portfolio selection. Knowledge-Based Systems 186, 104958 (2019). Equations (5) and (6).
source
PortfolioOptimisers.CompositeTrend — Type
struct CompositeTrend{T1<:(AbstractVector{<:AbstractPriceLevelStatistic}), T2<:Integer, T3<:Real} <: AbstractPriceLevelStatistic

Mixes several trend forecasts with radial basis weights, centred on the trend whose simplex-projected forecast had the best worst return over the last window periods, which is the forecast of the adaptive input and composite trend representation of Lai, Dai, Ren and Huang (2018).

The paper does not normalise its weights, so the centre takes weight one and every other trend takes less. The composite divides by the sum of the weights, so that it is a forecast on its own. The tracking step of AdaptiveInputCompositeTrend scales its centred direction to a fixed length, as eq. (15) and Algorithm 1 of the paper do, so the division does not change the step. Eq. (16) of the paper calls that scaling a projection onto a ball, which would keep the length of a shorter vector. The library follows eq. (15).

The back-test reads the trend forecasts of the last window periods, so the composite reads window - 1 rows more than its widest trend. Over the first rows it back-tests the periods that it has, and without a period to back-test it centres on the first trend. The paper states no rule for these rows. The paper's trends are the simple moving average, the exponential moving average and the window peak, over window = 5 levels, with sigma2 = 0.0025. These are the defaults. The paper states no smoothing weight for the exponential moving average, and the default of ExponentialMovingAverage stands.

Mathematical definition

\[\begin{align} \tilde{\boldsymbol{x}}_{l, t+1} &= \mathrm{Proj}_{\Delta_N}(\hat{\boldsymbol{x}}_{l, t+1})\,,\\ R_{l, t - k} &= \langle \tilde{\boldsymbol{x}}_{l, t - k}, \boldsymbol{x}_{t - k} \rangle\,,\quad k = 0, \ldots, w - 1\,,\\ \ast &= \underset{l}{\arg\max} \min_{k} R_{l, t - k}\,,\\ \varphi_{l} &= \exp\left(-\frac{\lVert \tilde{\boldsymbol{x}}_{\ast, t+1} - \tilde{\boldsymbol{x}}_{l, t+1} \rVert^2}{2 \sigma^2}\right)\,,\\ \hat{\boldsymbol{x}}_{t+1} &= \frac{\sum_{l} \varphi_{l}\, \hat{\boldsymbol{x}}_{l, t+1}}{\sum_{l} \varphi_{l}}\,. \end{align}\]

Where:

  • $\hat{\boldsymbol{x}}_{l, t+1}$: Price Relative Forecast of trend $l$ for period $t + 1$, made after the row of period $t$.
  • $\tilde{\boldsymbol{x}}_{l, t+1}$: Trend portfolio of trend $l$ for period $t + 1$.
  • $\mathrm{Proj}_{\Delta_N}$: Euclidean projection onto $\Delta_N$, which project_simplex computes.
  • $\Delta_N$: Probability simplex over the $N$ assets.
  • $R_{l, t - k}$: Return of the trend portfolio of trend $l$ over period $t - k$.
  • $w$: Back-test window, the number of periods over which the back-test scores the trend portfolios.
  • $\ast$: Centre, the trend with the largest worst return over the back-test window.
  • $\varphi_{l}$: Radial basis weight of trend $l$, one at the centre.
  • $\sigma^2$: Squared width of the radial basis function.
  • $\boldsymbol{x}_t$: Price relative vector of period $t$, each asset's price over its price one period earlier.
  • $\hat{\boldsymbol{x}}_{t+1}$: Price Relative Forecast for period $t + 1$, made after the row of period $t$.

The composite is a weighted mean of the trend forecasts, so it lies between the smallest and the largest of them in every asset.

Fields

  • trends: The trend statistics that the composite mixes, one forecast each.
  • window: The number of periods over which the back-test scores the trend portfolios to choose the centre.
  • sigma2: The squared width of the radial basis function over the trend portfolios.

Constructors

CompositeTrend(;    trends::AbstractVector{<:AbstractPriceLevelStatistic} = [MovingAverage(), ExponentialMovingAverage(), WindowPeak()],    window::Integer = 5,    sigma2::Real = 0.0025) -> CompositeTrend

Keywords correspond to the struct's fields.

Validation

  • trends is non-empty. An IsEmptyError is thrown otherwise.
  • window >= 2. A DomainError is thrown otherwise.
  • sigma2 > 0. A DomainError is thrown otherwise.

Examples

julia> CompositeTrend()CompositeTrend  trends ┼ 3-element Vector{PortfolioOptimisers.AbstractPriceLevelStatistic}         │ MovingAverage ⋯         │ ExponentialMovingAverage ⋯         │ WindowPeak ⋯  window ┼ Int64: 5  sigma2 ┴ Float64: 0.0025

Related

References

  • [60] Z.-R. Lai, D.-Q. Dai, C.-X. Ren and K.-K. Huang. Radial basis functions with adaptive input and composite trend representation for portfolio selection. IEEE Transactions on Neural Networks and Learning Systems 29, 6214–6226 (2018). Equations (9) to (12) and (15).
source
PortfolioOptimisers.member_statistic — Function
member_statistic(
    alg::AbstractPriceLevelStatistic,
    P::AbstractMatrix,
    u::Integer
) -> Any

Returns the statistic of a member of a composite over the member's own window of the levels that end at row u.

Algorithm

  1. Read need, the number of return rows that the member reads, from window_rows.
  2. Take lo, the first row of the member's window. It is the later of u - need and the first row of P, or the first row when need is nothing.
  3. Return the member's statistic over the rows lo to u of P.

Arguments

  • alg: The member statistic.
  • P: The levels the composite holds.
  • u: The row of P the member's window ends at.

Returns

  • stat::Vector: The member's statistic per asset, in units of the levels.

Related

source
PortfolioOptimisers.ElasticNetPath — Type
struct ElasticNetPath{T1<:Real, T2<:Real, T3<:Integer, T4<:Real} <: AbstractAlgorithm

Reads the elastic-net regularisation path of Friedman, Hastie and Tibshirani (2010) at its middle point, which gives the regression of the initial state of KernelTrendPattern on the levels of its window.

The objective is eq. (15) of the kernel trend pattern paper of Lai, Yang, Wu and Fang (2018), the elastic net of Zou and Hastie (2005). That paper takes "the middle one in the regularization path" and states no grid. The path paper runs its path over 100 strengths on a log scale, down to a floor of $10^{-3}$ times the largest strength (section 2.5). Such a grid has no single middle point. The library takes the geometric middle of the path, which lies between the 50th and the 51st point of that grid. The model of the kernel paper has no intercept, so the regression fits none and does not standardise the columns. The glmnet package does both by default, and its objective is the one below divided by twice the number of observations, so it holds the same path. theta = 0.99 is the kernel paper's value. It is almost the lasso, and it keeps the objective strictly convex.

The columns are the levels of consecutive periods, so they are almost collinear, and the coordinate sweeps converge slowly. Each sweep therefore ends with an exact solve on the sign pattern that it leaves, see elastic_net_path. The sweeps must still find the sign pattern of the optimum. On the 4 × 5 window of the test fixture they find it after between 2000 and 5000 sweeps, and a cap of 1000 stops more than 0.5 from the optimum in one coefficient. When the sweeps stop at tol or at iters before that, the result is the last sweep, which is not the optimum.

Mathematical definition

\[\begin{align} \hat{\boldsymbol{z}}(\gamma) &= \underset{\boldsymbol{z}}{\arg\min} \lVert \boldsymbol{y} - \mathbf{P} \boldsymbol{z} \rVert^2 + \gamma \left( 2 \vartheta \lVert \boldsymbol{z} \rVert_1 + (1 - \vartheta) \lVert \boldsymbol{z} \rVert^2 \right)\,,\\ \gamma_{\max} &= \max_{k} \frac{\lvert \mathbf{P}_k^\intercal \boldsymbol{y} \rvert}{\vartheta}\,,\\ \hat{\boldsymbol{z}} &= \hat{\boldsymbol{z}}\left(\gamma_{\max} \sqrt{\rho}\right)\,. \end{align}\]

Where:

  • $\boldsymbol{y}$: Response of the elastic net, one entry per observation.
  • $\mathbf{P}$: Regressors of the elastic net, one row per observation and one column per regressor. Column $k$ is $\mathbf{P}_k$.
  • $\boldsymbol{z}$: Coefficients of the elastic net, one per column of $\mathbf{P}$. Coefficient $k$ is $z_k$.
  • $\gamma$: Regularisation strength of the elastic net.
  • $\vartheta$: Share of the $L_1$ penalty in the elastic net, the theta field of ElasticNetPath.
  • $\gamma_{\max}$: Smallest strength at which every coefficient is zero.
  • $\rho$: Floor of the path as a fraction of $\gamma_{\max}$, the ratio field.
  • $\hat{\boldsymbol{z}}$: Coefficients at the middle point of the path.

Every coefficient is zero at and above $\gamma_{\max}$. The path runs from $\gamma_{\max}$ down to $\rho\, \gamma_{\max}$ on a log scale, so its geometric middle is $\gamma_{\max} \sqrt{\rho}$.

Fields

  • theta: The share of the $L_1$ penalty, 1 for the lasso.
  • ratio: The floor of the path as a fraction of the strength above which every coefficient is zero.
  • iters: Maximum number of coordinate-descent sweeps. Each sweep ends with the exact solve on its sign pattern.
  • tol: Tolerance on the largest change of a coefficient over one sweep. The sweeps stop below it when no exact solve has given the optimum.

Constructors

ElasticNetPath(; theta::Real = 0.99, ratio::Real = 1e-3, iters::Integer = 10_000, tol::Real = 1e-10) -> ElasticNetPath

Keywords correspond to the struct's fields.

Validation

  • 0 < theta <= 1. A DomainError is thrown otherwise: at theta = 0 the penalty is a ridge alone, which has no strength above which every coefficient is zero.
  • 0 < ratio < 1. A DomainError is thrown otherwise.
  • iters >= 1. A DomainError is thrown otherwise.
  • tol > 0. A DomainError is thrown otherwise.

Examples

julia> ElasticNetPath()ElasticNetPath  theta ┼ Float64: 0.99  ratio ┼ Float64: 0.001  iters ┼ Int64: 10000    tol ┴ Float64: 1.0e-10

Related

References

  • [61] J. Friedman, T. Hastie and R. Tibshirani. Regularization paths for generalized linear models via coordinate descent. Journal of Statistical Software 33, 1–22 (2010). Section 2.5.
  • [62] H. Zou and T. Hastie. Regularization and variable selection via the elastic net. Journal of the Royal Statistical Society: Series B (Statistical Methodology) 67, 301–320 (2005).
  • [63] Z.-R. Lai, P.-Y. Yang, X. Wu and L. Fang. A kernel-based trend pattern tracking system for portfolio optimization. Data Mining and Knowledge Discovery 32, 1708–1734 (2018). Equation (15).
source
PortfolioOptimisers.KernelTrendPattern — Type
struct KernelTrendPattern{T1<:Integer, T2<:Real, T3<:ElasticNetPath} <: AbstractPriceLevelStatistic

Predicts the next price level in three states, which is the forecast of the kernel-based trend pattern tracking of Lai, Yang, Wu and Fang (2018).

It is a folding statistic with a memory. It carries its previous prediction and the last 2 window price relatives. The initial state mixes the window peak with the previous prediction. The intermediate state is the regression of that mix on the recent levels, with negative values clipped to zero as the text of the paper states. The final state moves from the intermediate state toward the peak by a reverting strength, which is long-term through the trend-reverting fraction and short-term through the reciprocal of the last price relative. The defaults window = 5 and nu = 0.5 are the paper's.

Over the first rows the window and the memory hold the levels that exist, as Algorithm 1 of the paper states. The paper states no rule for fewer than three levels or for the first prediction. The library sets the trend-reverting fraction to zero below three levels, and it seeds the first prediction at the current price.

The regression pools the assets as its observations, so the fit changes when the levels of one asset are scaled. The library reads it on the reconstructed path, whose last level is one for every asset, so the assets enter in the same units. The data sets of the paper hold price relatives, and the paper does not state the anchor of the prices that it rebuilds from them. Under any other anchor, an asset with higher levels than the others weighs more in the fit.

Under an active mask the fit takes the active assets alone, because partial_fit! folds the Coverage Universe of the row and holds the other assets. The memory of an asset that the mask turns off stays flat over the inactive rows. When the asset relists, the memory holds its relisting level repeated. The window peak is then the peak of the levels that the asset has, which is the truncation of the paper, and the fit reads a flat column for the asset until the memory fills again.

Mathematical definition

\[\begin{align} \tilde{\boldsymbol{p}}_{t+1} &= \max_{0 \leq k < w} \boldsymbol{p}_{t-k}\,,\\ \boldsymbol{y}_{t+1} &= \nu \tilde{\boldsymbol{p}}_{t+1} + (1 - \nu)\, \hat{\boldsymbol{p}}_{t}\,,\\ \hat{\boldsymbol{y}}_{t+1} &= \max\left(\mathbf{P}_{t} \hat{\boldsymbol{z}}_{t}, 0\right)\,,\quad \mathbf{P}_{t} = [\boldsymbol{p}_{t-w+1}, \ldots, \boldsymbol{p}_{t}]\,,\\ \lambda_{t+1} &= \frac{1}{(L - 2) N} \sum_{i = 1}^{N} \sum_{k = t - L + 3}^{t} \mathbb{1}\left[ (p_{k, i} - p_{k-1, i})(p_{k-2, i} - p_{k-1, i}) > 0 \right]\,,\\ \boldsymbol{c} &= \min\left( \frac{\lambda_{t+1}}{2} \boldsymbol{1} \oslash \boldsymbol{x}_{t}, \boldsymbol{1} \right)\,,\\ \hat{\boldsymbol{p}}_{t+1} &= \boldsymbol{c} \odot \tilde{\boldsymbol{p}}_{t+1} + (\boldsymbol{1} - \boldsymbol{c}) \odot \hat{\boldsymbol{y}}_{t+1}\,,\\ \hat{\boldsymbol{x}}_{t+1} &= \hat{\boldsymbol{p}}_{t+1} \oslash \boldsymbol{p}_{t}\,. \end{align}\]

Where:

  • $\tilde{\boldsymbol{p}}_{t+1}$: Window peak, the highest level of each asset in the window.
  • $\hat{\boldsymbol{p}}_{t}$: Prediction of the level of period $t$, made at period $t - 1$.
  • $\nu$: Weight of the window peak in the initial state.
  • $\boldsymbol{y}_{t+1}$, $\hat{\boldsymbol{y}}_{t+1}$: Initial and intermediate states.
  • $\mathbf{P}_{t}$: Window of levels, one row per asset and one column per level.
  • $\hat{\boldsymbol{z}}_{t}$: Coefficients of the elastic net of $\boldsymbol{y}_{t+1}$ on the columns of $\mathbf{P}_{t}$, at the middle point of the path of ElasticNetPath. The assets are the observations.
  • $\lambda_{t+1}$: Trend-reverting fraction, the share of the interior levels of the memory at which the path of an asset turns.
  • $L$: Number of levels that the memory reaches, at most $2w + 1$.
  • $\boldsymbol{c}$: Reverting strength, one entry per asset.
  • $\boldsymbol{p}_t$: Price level vector of period $t$, one entry per asset.
  • $p_{t,i}$: Price level of asset $i$ at period $t$, the entry $i$ of $\boldsymbol{p}_t$.
  • $\boldsymbol{x}_t$: Price relative vector of period $t$, each asset's price over its price one period earlier.
  • $\hat{\boldsymbol{x}}_{t+1}$: Price Relative Forecast for period $t + 1$, made after the row of period $t$.
  • $w$: Price-level window, the number of price levels a statistic reads, the current one included.
  • $N$: Number of assets.

A level turns when its two neighbours are both above it or both below it. The fraction is in $[0, 1]$, so $\boldsymbol{c}$ is at most one half when no asset fell in the last period.

Algorithm

For each row, the fold runs these steps.

  1. Rebuild P, the levels of the memory, from the relatives that the memory holds, with the current level at one.
  2. Take Pw, the last window levels of P, and ptilde, their peak per asset.
  3. Bring the carried prediction into the units of the current level, which gives prev. Before the first row, the carried value is the cold seed, so prev is one.
  4. Mix ptilde and prev with the weight nu, which gives the initial state y.
  5. Regress y on the columns of the transpose of Pw with elastic_net_path, and clip the fit at zero, which gives yhat.
  6. Compute the reverting strength c from trend_reverting_fraction over P and the relative x of the row.
  7. Return the final state, the mix of ptilde and yhat with the weights c.

Fields

  • window: The number of price levels the statistic reads, the current one included; window - 1 returns reconstruct them.
  • nu: The weight of the window peak in the initial state. The previous prediction takes the rest.
  • path: The elastic-net path of the intermediate state.

Constructors

KernelTrendPattern(; window::Integer = 5, nu::Real = 0.5, path::ElasticNetPath = ElasticNetPath()) -> KernelTrendPattern

Keywords correspond to the struct's fields. The statistic folds with a memory of 2 window relatives, so the head holds no rows for it.

Validation

  • window >= 2. A DomainError is thrown otherwise.
  • 0 <= nu <= 1. A DomainError is thrown otherwise.

Examples

julia> KernelTrendPattern()KernelTrendPattern  window ┼ Int64: 5      nu ┼ Float64: 0.5    path ┼ ElasticNetPath         │   theta ┼ Float64: 0.99         │   ratio ┼ Float64: 0.001         │   iters ┼ Int64: 10000         │     tol ┴ Float64: 1.0e-10

Related

References

  • [63] Z.-R. Lai, P.-Y. Yang, X. Wu and L. Fang. A kernel-based trend pattern tracking system for portfolio optimization. Data Mining and Knowledge Discovery 32, 1708–1734 (2018). Equations (11) to (16) and (26) to (31), Algorithm 1.
source

References

[57]
H.-L. Dai, C.-X. Liang, H.-M. Dai, C.-Y. Huang and R. M. Adnan. An online portfolio strategy based on trend promote price tracing ensemble learning algorithm. Knowledge-Based Systems 239, 107957 (2022).
[58]
X. Cai and Z. Ye. Gaussian weighting reversion strategy for accurate online portfolio selection. IEEE Transactions on Signal Processing 67, 5558–5570 (2019).
[59]
H. Guan and Z. An. A local adaptive learning system for online portfolio selection. Knowledge-Based Systems 186, 104958 (2019).
[60]
Z.-R. Lai, D.-Q. Dai, C.-X. Ren and K.-K. Huang. Radial basis functions with adaptive input and composite trend representation for portfolio selection. IEEE Transactions on Neural Networks and Learning Systems 29, 6214–6226 (2018).
[61]
J. Friedman, T. Hastie and R. Tibshirani. Regularization paths for generalized linear models via coordinate descent. Journal of Statistical Software 33, 1–22 (2010).
[62]
H. Zou and T. Hastie. Regularization and variable selection via the elastic net. Journal of the Royal Statistical Society: Series B (Statistical Methodology) 67, 301–320 (2005).
[63]
Z.-R. Lai, P.-Y. Yang, X. Wu and L. Fang. A kernel-based trend pattern tracking system for portfolio optimization. Data Mining and Knowledge Discovery 32, 1708–1734 (2018).