Online selection rules: the forecast-reading arm

These rules read a forecast of the next price relatives, which the expected returns estimator in their me field makes. ForecastReversion is the passive-aggressive reversion step, with an optional diagonal scale. Six constructors build it with the forecast of their paper: MovingAverageReversion, ExponentialMovingAverageReversion, RobustMedianReversion, ReweightedPriceRelativeTracking, GaussianWeightingReversion and LocalAdaptiveLearning.

ForecastTracking is the tracking step of fixed length, and three constructors build it: PeakPriceTracking, AdaptiveInputCompositeTrend and TrendPromotePriceTracking. KernelTrendTracking scales the tracking step with a kernel, and KernelTrendPatternTracking builds it. TransactionCostOptimisation takes a step that accounts for transaction costs and leaves small trades at zero. ShortTermSparsePortfolio is the sparse portfolio, which uses one of three algorithms to find the point it projects.

A forecast with an exact update stores its state with the state of the rule. Any other forecast refits on the rows that OnlinePortfolioSelection stores.

PortfolioOptimisers.ForecastReversion — Type
struct ForecastReversion{T1<:AbstractExpectedReturnsEstimator, T2<:Real, T3<:(Union{Nothing, var"#s7440"} where var"#s7440"<:AbstractPriceLevelStatistic), T4<:EuclideanProjection} <: AbstractOnlinePortfolioSelectionAlgorithm

Moves the allocation by the least amount that gives a forecast return of at least eps, then projects.

Five papers share this passive-aggressive step: the moving average reversion of Li and Hoi (2012), the robust median reversion of Huang, Zhou, Li, Hoi and Zhou (2016), the reweighted price relative tracking of Lai, Yang, Fang and Wu (2020), the Gaussian weighting reversion of Cai and Ye (2019) and the local adaptive learning of Guan and An (2019). The papers differ only in the statistic on the me slot. MovingAverageReversion, ExponentialMovingAverageReversion, RobustMedianReversion, ReweightedPriceRelativeTracking, GaussianWeightingReversion and LocalAdaptiveLearning fill the slot with the statistic of each paper.

Any expected-returns estimator can sit on the slot, for example a mean of past returns, a shrunk mean, or the mean of a Prior through PriorExpectedReturns. forecast_relative advances it. The rule fits a forecaster that does not fold again on every row that the head holds, because rows_needed returns nothing for it. So each step costs one fit over the whole prefix.

The rule bets on the reversion that the forecast encodes. It gains on a market that reverts and loses on a market that trends.

Mathematical definition

\[\begin{align} \lambda_t &= \max\left(0, \frac{\epsilon - \langle \boldsymbol{w}_t, \hat{\boldsymbol{x}}_{t+1} \rangle}{\lVert \tilde{\boldsymbol{x}}_{t+1} \rVert^2}\right)\,, \\ \boldsymbol{w}_{t+1} &= \mathrm{Proj}_{\mathcal{W}}\left( \boldsymbol{w}_t + \lambda_t \mathbf{D}_{t+1} \tilde{\boldsymbol{x}}_{t+1} \right)\,. \end{align}\]

Where:

  • $\hat{\boldsymbol{x}}_{t+1}$: Price Relative Forecast for period $t + 1$, made after the row of period $t$.
  • $\tilde{\boldsymbol{x}}_{t+1} = \hat{\boldsymbol{x}}_{t+1} - \bar{x}_{t+1} \boldsymbol{1}$: Centred Price Relative Forecast, with $\bar{x}_{t+1}$ the mean of the entries of $\hat{\boldsymbol{x}}_{t+1}$. Its entries sum to zero.
  • $\boldsymbol{w}_t$: Iterate of the rule at period $t$, the allocation its update reads.
  • $t$: Period index, counted from one.
  • $\epsilon$: Target of the forecast return $\langle \boldsymbol{w}, \hat{\boldsymbol{x}}_{t+1} \rangle$, the eps field.
  • $\lambda_t$: Step multiplier, zero when $\tilde{\boldsymbol{x}}_{t+1} = \boldsymbol{0}$.
  • $\mathbf{D}_{t+1}$: Diagonal preconditioner. It is the identity when scale is nothing, and otherwise the diagonal matrix of the Price Relative Forecast of the scale statistic.
  • $\mathrm{Proj}_{\mathcal{W}}$: Euclidean projection onto the Allocation Set $\mathcal{W}$.

Without a preconditioner, the vector inside the projection solves the programme that the papers state, $\underset{\boldsymbol{w}}{\min} \; \tfrac{1}{2} \lVert \boldsymbol{w} - \boldsymbol{w}_t \rVert^2$ subject to $\langle \boldsymbol{w}, \hat{\boldsymbol{x}}_{t+1} \rangle \geq \epsilon$ and $\boldsymbol{1}^\intercal \boldsymbol{w} = 1$. The projection then restores the bounds. The reweighted price relative tracking keeps the same $\lambda_t$ with the preconditioner. In general its vector then leaves the budget hyperplane and misses the target $\epsilon$, and the projection restores the budget.

The sign of the step is opposite to the sign of PassiveAggressiveMeanReversion, because $\hat{\boldsymbol{x}}_{t+1}$ forecasts the next price relative, where that rule reads the last one.

Algorithm

online_update! runs these steps at the row x of the period, from the allocation w.

  1. Advance the forecaster with forecast_relative, which gives the carrier st and the forecast xhat.
  2. Centre the forecast, which gives dev, and take its squared norm denom.
  3. Form the multiplier lam: zero when denom is zero, and $\lambda_t$ otherwise.
  4. Form the diagonal D of the preconditioner with scale_relative, or nothing.
  5. Form the raw step q = w .+ lam .* dev, or q = w .+ lam .* D .* dev with a preconditioner.
  6. Project q onto the set with project, with the price_adjusted_allocation of w after the row. Return st and the new allocation.

Fields

  • me: The forecaster whose mean is the Price Relative Forecast, x̂ = 1 .+ mu: folded on the Rule State where it has an exact fold, and refit over the rows the head holds otherwise.
  • eps: Target of the forecast return. A larger target gives a longer step.
  • scale: The statistic whose Price Relative Forecast preconditions the step, or nothing for the identity.
  • proj: The Projection Geometry the rule projects its raw step onto the Allocation Set in; the slot's type bound names the geometries the rule's theorem covers.

Constructors

ForecastReversion(;    me::Union{<:AbstractExpectedReturnsEstimator, <:Online} = PriceLevelExpectedReturns(),    eps::Real = 10,    scale::Option{<:AbstractPriceLevelStatistic} = nothing,    proj::EuclideanProjection = EuclideanProjection()) -> ForecastReversion

Keywords correspond to the struct's fields. The rule needs the larger of the rows that the forecaster reads and the rows that the scale reads, so the head holds the rows of both. A forecaster that folds reads the current row alone.

Validation

  • eps > 0. A DomainError is thrown otherwise.
  • me is not an Online wrapper, and holds none. An ArgumentError is thrown otherwise, and it names the wrapper.

Examples

julia> ForecastReversion()ForecastReversion     me ┼ PriceLevelExpectedReturns        │   alg ┼ MovingAverage        │       │   window ┴ Int64: 5    eps ┼ Int64: 10  scale ┼ nothing   proj ┴ EuclideanProjection()

Related

References

  • [48] B. Li and S. C. H. Hoi. On-line portfolio selection with moving average reversion. In: Proceedings of the 29th International Conference on Machine Learning (2012).
  • [50] D. Huang, J. Zhou, B. Li, S. C. H. Hoi and S. Zhou. Robust median reversion strategy for online portfolio selection. IEEE Transactions on Knowledge and Data Engineering 28, 2480–2493 (2016).
  • [56] Z.-R. Lai, P.-Y. Yang, L. Fang and X. Wu. Reweighted price relative tracking system for automatic portfolio optimization. IEEE Transactions on Systems, Man, and Cybernetics: Systems 50, 4349–4361 (2020).
  • [54] B. Li, J. Luo and H. Xu. A portfolio selection strategy based on the peak price involving randomness. IEEE Access 11, 52066–52074 (2023).
  • [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).
source
PortfolioOptimisers.MovingAverageReversion — Function
MovingAverageReversion(; window::Integer = 5, eps::Real = 10, proj::EuclideanProjection = EuclideanProjection())

Builds the on-line moving average reversion of Li and Hoi (2012), OLMAR.

It is a ForecastReversion whose forecast is the MovingAverage of the last window price levels over the last price. The defaults window = 5 and eps = 10 are the paper's. window is the horizon of the reversion, and a search over "alg.me.alg.window" tunes it.

The algorithm of the 2012 paper takes eps > 1 and window >= 3, and the algorithm of Li, Hoi, Sahoo and Liu (2015) takes window >= 2. At two levels the average is the mean of the current price and the previous price. The step is defined for any positive eps, so the constructor admits eps > 0 and window >= 2. With eps <= 1 the step moves only when the forecast return of the held allocation is below eps, which is a forecast loss.

Examples

julia> MovingAverageReversion(; window = 3)ForecastReversion     me ┼ PriceLevelExpectedReturns        │   alg ┼ MovingAverage        │       │   window ┴ Int64: 3    eps ┼ Int64: 10  scale ┼ nothing   proj ┴ EuclideanProjection()

Related

References

  • [48] B. Li and S. C. H. Hoi. On-line portfolio selection with moving average reversion. In: Proceedings of the 29th International Conference on Machine Learning (2012).
  • [49] B. Li, S. C. H. Hoi, D. Sahoo and Z.-Y. Liu. Moving average reversion strategy for on-line portfolio selection. Artificial Intelligence 222, 104–123 (2015).
source
PortfolioOptimisers.ExponentialMovingAverageReversion — Function
ExponentialMovingAverageReversion(; alpha::Real = 0.5, eps::Real = 10, proj::EuclideanProjection = EuclideanProjection())

Builds the second form of the on-line moving average reversion of Li, Hoi, Sahoo and Liu (2015), OLMAR-2.

It is a ForecastReversion whose forecast is the ExponentialMovingAverage of the price levels over the last price. eps = 10 is the paper's. The paper gives no default alpha, and its sensitivity study scans alpha from 0 to 1. The library takes 0.5, the middle of that range.

The average starts at the first price, as the expansion of the paper does, so the forecast after one level is one. The statistic folds, so the rule carries one vector and the head holds only the current row.

Examples

julia> ExponentialMovingAverageReversion()ForecastReversion     me ┼ PriceLevelExpectedReturns        │   alg ┼ ExponentialMovingAverage        │       │   alpha ┴ Float64: 0.5    eps ┼ Int64: 10  scale ┼ nothing   proj ┴ EuclideanProjection()

Related

References

  • [49] B. Li, S. C. H. Hoi, D. Sahoo and Z.-Y. Liu. Moving average reversion strategy for on-line portfolio selection. Artificial Intelligence 222, 104–123 (2015).
source
PortfolioOptimisers.RobustMedianReversion — Function
RobustMedianReversion(; window::Integer = 5, eps::Real = 5, iters::Integer = 100, tol::Real = 1e-8, proj::EuclideanProjection = EuclideanProjection())

Builds the robust median reversion of Huang, Zhou, Li, Hoi and Zhou (2016), RMR.

It is a ForecastReversion whose forecast is the SpatialMedian of the last window price levels over the last price. The defaults window = 5 and eps = 5 are the paper's. One extreme price moves a mean without limit, and it moves a spatial median very little.

The library reads the median on the rebuilt price path, with the last level of each asset at one. Its iteration stops by a rule different from the rule of the paper. SpatialMedian states both differences.

Examples

julia> RobustMedianReversion(; window = 3)ForecastReversion     me ┼ PriceLevelExpectedReturns        │   alg ┼ SpatialMedian        │       │   window ┼ Int64: 3        │       │    iters ┼ Int64: 100        │       │      tol ┴ Float64: 1.0e-8    eps ┼ Int64: 5  scale ┼ nothing   proj ┴ EuclideanProjection()

Related

References

  • [50] D. Huang, J. Zhou, B. Li, S. C. H. Hoi and S. Zhou. Robust median reversion strategy for online portfolio selection. IEEE Transactions on Knowledge and Data Engineering 28, 2480–2493 (2016).
source
PortfolioOptimisers.ReweightedPriceRelativeTracking — Function
ReweightedPriceRelativeTracking(; window::Integer = 5, theta::Real = 0.8, eps::Real = 50, proj::EuclideanProjection = EuclideanProjection())

Builds the reweighted price relative tracking of Lai, Yang, Fang and Wu (2020), RPRT.

It is a ForecastReversion whose forecast is the ReweightedPriceRelative recursion. The MovingAverage forecast of the same window preconditions its step.

The paper is not open access. Li, Luo and Xu (2023, eqs. 8 to 11) restate its forecast and its step, and the MATLAB code that the authors publish runs the same recursion. The code seeds the forecast at one, and the restatement seeds it at the first price relative, which ReweightedPriceRelative follows. The defaults theta = 0.8, eps = 50 and window = 5 are the values of that code. In its first window periods the code preconditions with the last price relative, and the library uses the moving average of the levels that it has.

With eps = 50 the forecast return is below the target at every step, so the step always moves. The projected answer is then almost one-hot, as the answers of the tracking rules at their defaults are.

Examples

julia> ReweightedPriceRelativeTracking()ForecastReversion     me ┼ PriceLevelExpectedReturns        │   alg ┼ ReweightedPriceRelative        │       │   theta ┴ Float64: 0.8    eps ┼ Int64: 50  scale ┼ MovingAverage        │   window ┴ Int64: 5   proj ┴ EuclideanProjection()

Related

References

  • [56] Z.-R. Lai, P.-Y. Yang, L. Fang and X. Wu. Reweighted price relative tracking system for automatic portfolio optimization. IEEE Transactions on Systems, Man, and Cybernetics: Systems 50, 4349–4361 (2020).
  • [54] B. Li, J. Luo and H. Xu. A portfolio selection strategy based on the peak price involving randomness. IEEE Access 11, 52066–52074 (2023).
source
PortfolioOptimisers.GaussianWeightingReversion — Function
GaussianWeightingReversion(; tau::Real = 2.8, cutoff::Real = 0.005, eps::Real = 50, proj::EuclideanProjection = EuclideanProjection())

Builds the Gaussian weighting reversion of Cai and Ye (2019), GWR.

It is a ForecastReversion whose forecast is the GaussianWeightedDoubleEstimate over the last price. The defaults tau = 2.8, cutoff = 0.005 and eps = 50 are the paper's. The paper names the target $\delta$ and the cutoff $\epsilon$.

The adaptive variant of the paper, GWR-A, chooses tau online with a bandit over the reward. The library does not build it, because the family has no seam for a parameter that the reward chooses online.

Examples

julia> GaussianWeightingReversion()ForecastReversion     me ┼ PriceLevelExpectedReturns        │   alg ┼ GaussianWeightedDoubleEstimate        │       │      tau ┼ Float64: 2.8        │       │   cutoff ┴ Float64: 0.005    eps ┼ Int64: 50  scale ┼ nothing   proj ┴ EuclideanProjection()

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).
source
PortfolioOptimisers.LocalAdaptiveLearning — Function
LocalAdaptiveLearning(; window::Integer = 5, alpha::Real = 0.5, threshold::Real = 0.1, lambda::Real = 0, eps::Real = 10, proj::EuclideanProjection = EuclideanProjection())

Builds the local adaptive learning of Guan and An (2019), LOAD.

It is a ForecastReversion whose forecast is a TrendSwitch on the RegressionSlope. An asset whose slope exceeds threshold takes its WindowPeak, and every other asset takes its ExponentialMovingAverage. The defaults window = 5, alpha = 0.5 and threshold = 0.1 are the paper's.

The paper states neither the target eps nor the ridge weight lambda. The defaults are the eps = 10 of the moving average reversion and plain least squares. The paper fits the slope on the prices. The library fits it on the rebuilt price path, with the last level at one, so threshold compares with a slope in units of the current price. The exponential average reads the full history, as the recursion of the paper does, so the head holds every row for this rule.

Examples

julia> LocalAdaptiveLearning()ForecastReversion     me ┼ PriceLevelExpectedReturns        │   alg ┼ TrendSwitch        │       │      test ┼ RegressionSlope        │       │           │      window ┼ Int64: 5        │       │           │   threshold ┼ Float64: 0.1        │       │           │      lambda ┴ Int64: 0        │       │    rising ┼ WindowPeak        │       │           │   window ┴ Int64: 5        │       │      flat ┼ ExponentialMovingAverage        │       │           │   alpha ┴ Float64: 0.5        │       │   falling ┼ ExponentialMovingAverage        │       │           │   alpha ┴ Float64: 0.5    eps ┼ Int64: 10  scale ┼ nothing   proj ┴ EuclideanProjection()

Related

References

  • [59] H. Guan and Z. An. A local adaptive learning system for online portfolio selection. Knowledge-Based Systems 186, 104958 (2019).
source
PortfolioOptimisers.ForecastTracking — Type
struct ForecastTracking{T1<:AbstractExpectedReturnsEstimator, T2<:Real, T3<:EuclideanProjection} <: AbstractOnlinePortfolioSelectionAlgorithm

Moves the allocation a fixed distance eps along the centred Price Relative Forecast, then projects.

Three papers share this step: the peak price tracking of Lai, Dai, Ren and Huang (2018), the adaptive input and composite trend representation of the same authors (2018), and the trend promote price tracing of Dai, Liang, Dai, Huang and Adnan (2022). It is the mirror of ForecastReversion. eps is a step length and not a rate, so the forecast sets the direction alone.

Mathematical definition

\[\begin{align} \boldsymbol{w}_{t+1} &= \mathrm{Proj}_{\mathcal{W}}\left( \boldsymbol{w}_t + \epsilon\, \frac{\tilde{\boldsymbol{x}}_{t+1}}{\lVert \tilde{\boldsymbol{x}}_{t+1} \rVert} \right)\,. \end{align}\]

Where:

  • $\hat{\boldsymbol{x}}_{t+1}$: Price Relative Forecast for period $t + 1$, made after the row of period $t$.
  • $\tilde{\boldsymbol{x}}_{t+1} = \hat{\boldsymbol{x}}_{t+1} - \bar{x}_{t+1} \boldsymbol{1}$: Centred Price Relative Forecast, with $\bar{x}_{t+1}$ the mean of the entries of $\hat{\boldsymbol{x}}_{t+1}$. Its entries sum to zero.
  • $\boldsymbol{w}_t$: Iterate of the rule at period $t$, the allocation its update reads.
  • $t$: Period index, counted from one.
  • $\epsilon$: Euclidean length of the step, the eps field.
  • $\mathrm{Proj}_{\mathcal{W}}$: Euclidean projection onto the Allocation Set $\mathcal{W}$.

When $\tilde{\boldsymbol{x}}_{t+1} = \boldsymbol{0}$ the step is zero, and $\boldsymbol{w}_{t+1} = \mathrm{Proj}_{\mathcal{W}}(\boldsymbol{w}_t)$.

The vector inside the projection maximises $\langle \boldsymbol{w}, \hat{\boldsymbol{x}}_{t+1} \rangle$ over the ball $\lVert \boldsymbol{w} - \boldsymbol{w}_t \rVert \leq \epsilon$ in the budget hyperplane $\boldsymbol{1}^\intercal \boldsymbol{w} = 1$, which is the programme of the papers. The projection then restores the bounds, as it does after the reversion step.

On the simplex, the projection is one-hot on asset $i$ whenever $\epsilon (u_i - u_j) \geq 2$ for every other asset $j$, with $\boldsymbol{u} = \tilde{\boldsymbol{x}}_{t+1} / \lVert \tilde{\boldsymbol{x}}_{t+1} \rVert$. At $\epsilon = 100$ that gap is 0.02, so at the defaults of the papers the step puts all the wealth on the asset with the largest forecast, except when the forecasts of two assets are almost equal.

Algorithm

online_update! runs these steps at the row x of the period, from the allocation w.

  1. Advance the forecaster with forecast_relative, which gives the carrier st and the forecast xhat.
  2. Centre the forecast, which gives dev, and take its norm nrm.
  3. Form the raw step q, which is w when nrm is zero and w .+ eps .* dev ./ nrm otherwise.
  4. Project q onto the set with project, with the price_adjusted_allocation of w after the row. Return st and the new allocation.

Fields

  • me: The forecaster whose mean is the Price Relative Forecast, x̂ = 1 .+ mu: folded on the Rule State where it has an exact fold, and refit over the rows the head holds otherwise.
  • eps: Euclidean length of the step along the centred forecast.
  • proj: The Projection Geometry the rule projects its raw step onto the Allocation Set in; the slot's type bound names the geometries the rule's theorem covers.

Constructors

ForecastTracking(;    me::Union{<:AbstractExpectedReturnsEstimator, <:Online} = PriceLevelExpectedReturns(; alg = WindowPeak()),    eps::Real = 100,    proj::EuclideanProjection = EuclideanProjection()) -> ForecastTracking

Keywords correspond to the struct's fields. The rule needs the rows that me needs.

Validation

  • eps > 0. A DomainError is thrown otherwise.
  • me is not an Online wrapper, and holds none. An ArgumentError is thrown otherwise, and it names the wrapper.

Examples

julia> ForecastTracking()ForecastTracking    me ┼ PriceLevelExpectedReturns       │   alg ┼ WindowPeak       │       │   window ┴ Int64: 5   eps ┼ Int64: 100  proj ┴ EuclideanProjection()

Related

References

  • [52] Z.-R. Lai, D.-Q. Dai, C.-X. Ren and K.-K. Huang. A peak price tracking-based learning system for portfolio selection. IEEE Transactions on Neural Networks and Learning Systems 29, 2823–2832 (2018).
  • [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).
  • [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).
source
PortfolioOptimisers.PeakPriceTracking — Function
PeakPriceTracking(; window::Integer = 5, eps::Real = 100, proj::EuclideanProjection = EuclideanProjection())

Builds the peak price tracking of Lai, Dai, Ren and Huang (2018), PPT.

It is a ForecastTracking whose forecast is the WindowPeak of the last window price levels over the last price. The defaults window = 5 and eps = 100 are the paper's, and the MATLAB code that the authors publish uses the same step.

At eps = 100 the answer almost always puts all the wealth on the asset with the highest ratio of peak to last price. The sensitivity study of the paper (its Fig. 4) shows a flat wealth for eps >= 50, and this saturation is the cause.

Examples

julia> PeakPriceTracking()ForecastTracking    me ┼ PriceLevelExpectedReturns       │   alg ┼ WindowPeak       │       │   window ┴ Int64: 5   eps ┼ Int64: 100  proj ┴ EuclideanProjection()

Related

References

  • [52] Z.-R. Lai, D.-Q. Dai, C.-X. Ren and K.-K. Huang. A peak price tracking-based learning system for portfolio selection. IEEE Transactions on Neural Networks and Learning Systems 29, 2823–2832 (2018).
source
PortfolioOptimisers.AdaptiveInputCompositeTrend — Function
AdaptiveInputCompositeTrend(; window::Integer = 5, alpha::Real = 0.5, sigma2::Real = 0.0025, eps::Real = 1000, proj::EuclideanProjection = EuclideanProjection())

Builds the adaptive input and composite trend representation of Lai, Dai, Ren and Huang (2018), AICTR.

It is a ForecastTracking whose forecast is the CompositeTrend of the MovingAverage, the ExponentialMovingAverage and the WindowPeak over window levels. The defaults window = 5, sigma2 = 0.0025 and eps = 1000 are the paper's.

The paper gives no smoothing weight for its exponential average, so the library sets alpha = 0.5. The exponential average reads the full history, so the head holds every row for this rule.

Examples

julia> AdaptiveInputCompositeTrend()ForecastTracking    me ┼ PriceLevelExpectedReturns       │   alg ┼ CompositeTrend       │       │   trends ┼ 3-element Vector{PortfolioOptimisers.AbstractPriceLevelStatistic}       │       │          │ MovingAverage ⋯       │       │          │ ExponentialMovingAverage ⋯       │       │          │ WindowPeak ⋯       │       │   window ┼ Int64: 5       │       │   sigma2 ┴ Float64: 0.0025   eps ┼ Int64: 1000  proj ┴ EuclideanProjection()

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).
source
PortfolioOptimisers.TrendPromotePriceTracking — Function
TrendPromotePriceTracking(; window::Integer = 5, alpha::Real = 0.5, eps::Real = 100, proj::EuclideanProjection = EuclideanProjection())

Builds the trend promote price tracing of Dai, Liang, Dai, Huang and Adnan (2022), TPPT.

It is a ForecastTracking whose forecast is a TrendSwitch on the PairwiseSlopeSum. A rising asset takes its TruncatedExponentialMovingAverage, a flat asset takes its current price, and a falling asset takes its WindowPeak. The defaults window = 5, alpha = 0.5 and eps = 100 are the paper's.

The rising branch of the paper cannot be computed as printed, because it reads the price of the next period, which is the quantity that it forecasts. TruncatedExponentialMovingAverage states the reading that the library takes, so a parity test against the numbers of the paper is not possible.

Examples

julia> TrendPromotePriceTracking()ForecastTracking    me ┼ PriceLevelExpectedReturns       │   alg ┼ 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   eps ┼ Int64: 100  proj ┴ EuclideanProjection()

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).
source
PortfolioOptimisers.KernelTrendTracking — Type
struct KernelTrendTracking{T1<:AbstractExpectedReturnsEstimator, T2<:Real, T3<:Real, T4<:EuclideanProjection} <: AbstractOnlinePortfolioSelectionAlgorithm

Moves the allocation along the kernel-scaled centred Price Relative Forecast at a fixed rate eta, then projects.

This is the step of the kernel-based trend pattern tracking of Lai, Yang, Wu and Fang (2018). Unlike the step of ForecastTracking, it is not normalised, so eta is a rate on the centred forecast and not a step length. forecast_relative advances the forecaster on me, and KernelTrendPatternTracking fills that slot with the KernelTrendPattern of the paper.

Mathematical definition

\[\begin{align} \tilde{\boldsymbol{w}}_t &= \boldsymbol{w}_t - \bar{w}_t \boldsymbol{1}\,, \\ K_i &= \exp\left( -\lvert \tilde{w}_{t, i} - \tilde{x}_{t+1, i} \rvert^{1/q} \right)\,, \\ \boldsymbol{w}_{t+1} &= \mathrm{Proj}_{\mathcal{W}}\left( \boldsymbol{w}_t + \eta\, \mathbf{K} \tilde{\boldsymbol{x}}_{t+1} \right)\,. \end{align}\]

Where:

  • $\hat{\boldsymbol{x}}_{t+1}$: Price Relative Forecast for period $t + 1$, made after the row of period $t$.
  • $\tilde{\boldsymbol{x}}_{t+1} = \hat{\boldsymbol{x}}_{t+1} - \bar{x}_{t+1} \boldsymbol{1}$: Centred Price Relative Forecast, with $\bar{x}_{t+1}$ the mean of the entries of $\hat{\boldsymbol{x}}_{t+1}$. Its entries sum to zero. $\tilde{x}_{t+1, i}$ is the entry of asset $i$.
  • $\boldsymbol{w}_t$: Iterate of the rule at period $t$, the allocation its update reads.
  • $\tilde{\boldsymbol{w}}_t$: Centred iterate, with $\bar{w}_t$ the mean of the entries of $\boldsymbol{w}_t$.
  • $\mathbf{K}$: Diagonal kernel matrix with the entries $K_i$ in $(0, 1]$.
  • $q$: Shape of the kernel, the q field.
  • $\eta$: Rate of the step, the eta field.
  • $t$: Period index, counted from one.
  • $\mathrm{Proj}_{\mathcal{W}}$: Euclidean projection onto the Allocation Set $\mathcal{W}$.

When $\tilde{\boldsymbol{x}}_{t+1} = \boldsymbol{0}$ the step is zero, and $\boldsymbol{w}_{t+1} = \mathrm{Proj}_{\mathcal{W}}(\boldsymbol{w}_t)$.

The kernel is the similarity of the paper between the allocation and the forecast. $K_i$ is largest where the centred weight of asset $i$ already matches its centred forecast. The vector inside the projection maximises $\langle \boldsymbol{w}, \mathbf{K}^{-1} \tilde{\boldsymbol{x}}_{t+1} \rangle$ over the ellipsoid $(\boldsymbol{w} - \boldsymbol{w}_t)^\intercal \mathbf{K}^{-2} (\boldsymbol{w} - \boldsymbol{w}_t) \leq \eta^2 \lVert \tilde{\boldsymbol{x}}_{t+1} \rVert^2$, which is the programme of the paper at the radius that it sets. The radius grows with the forecast, so the normalisation of ForecastTracking cancels.

On the simplex, the projection is one-hot on asset $i$ whenever $\eta (K_i \tilde{x}_{t+1, i} - K_j \tilde{x}_{t+1, j}) \geq 2$ for every other asset $j$. At $\eta = 1000$ that gap is 0.002. Below that gap the answer can hold two assets. From a book on one asset, a gap of $1.5 / \eta$ gives the weights 0.75 and 0.25.

Algorithm

online_update! runs these steps at the row x of the period, from the allocation w.

  1. Advance the forecaster with forecast_relative, which gives the carrier st and the forecast xhat.
  2. Centre the forecast, which gives dev.
  3. When every entry of dev is zero, take the raw step q = w and go to step 5.
  4. Form the kernel K from the centred w and dev, and the raw step q = w .+ eta .* K .* dev.
  5. Project q onto the set with project, with the price_adjusted_allocation of w after the row. Return st and the new allocation.

Fields

  • me: The forecaster whose mean is the Price Relative Forecast, x̂ = 1 .+ mu: folded on the Rule State where it has an exact fold, and refit over the rows the head holds otherwise.
  • eta: Rate of the step on the centred forecast after the kernel scales it.
  • q: Shape of the kernel. The kernel raises the distance between the centred weight and the centred forecast of an asset to the power 1 / q, so a larger q gives a flatter similarity.
  • proj: The Projection Geometry the rule projects its raw step onto the Allocation Set in; the slot's type bound names the geometries the rule's theorem covers.

Constructors

KernelTrendTracking(;    me::Union{<:AbstractExpectedReturnsEstimator, <:Online} = PriceLevelExpectedReturns(; alg = KernelTrendPattern()),    eta::Real = 1000,    q::Real = 6,    proj::EuclideanProjection = EuclideanProjection()) -> KernelTrendTracking

Keywords correspond to the struct's fields, and the defaults eta = 1000 and q = 6 are the paper's. The rule needs the rows that me needs.

Validation

  • eta > 0. A DomainError is thrown otherwise.
  • q > 0. A DomainError is thrown otherwise.
  • me is not an Online wrapper, and holds none. An ArgumentError is thrown otherwise, and it names the wrapper.

Examples

julia> KernelTrendTracking()KernelTrendTracking    me ┼ PriceLevelExpectedReturns       │   alg ┼ 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   eta ┼ Int64: 1000     q ┼ Int64: 6  proj ┴ EuclideanProjection()

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).
source
PortfolioOptimisers.KernelTrendPatternTracking — Function
KernelTrendPatternTracking(; window::Integer = 5, nu::Real = 0.5, theta::Real = 0.99, iters::Integer = 10_000, tol::Real = 1e-10, q::Real = 6, eta::Real = 1000, proj::EuclideanProjection = EuclideanProjection())

Builds the kernel-based trend pattern tracking of Lai, Yang, Wu and Fang (2018), KTPT.

It is a KernelTrendTracking whose forecast is the KernelTrendPattern over window levels. nu mixes its initial state, and an ElasticNetPath at theta gives its intermediate state, with at most iters sweeps stopped at tol. The defaults window = 5, nu = 0.5, theta = 0.99, q = 6 and eta = 1000 are the paper's.

The paper reports that the wealth is robust to eta from 800 to 1300 and stable for q near 6. The statistic folds with a memory, so the head holds only the current row for this rule.

Examples

julia> KernelTrendPatternTracking(; window = 3)KernelTrendTracking    me ┼ PriceLevelExpectedReturns       │   alg ┼ KernelTrendPattern       │       │   window ┼ Int64: 3       │       │       nu ┼ Float64: 0.5       │       │     path ┼ ElasticNetPath       │       │          │   theta ┼ Float64: 0.99       │       │          │   ratio ┼ Float64: 0.001       │       │          │   iters ┼ Int64: 10000       │       │          │     tol ┴ Float64: 1.0e-10   eta ┼ Int64: 1000     q ┼ Int64: 6  proj ┴ EuclideanProjection()

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).
source
PortfolioOptimisers.TransactionCostOptimisation — Type
struct TransactionCostOptimisation{T1<:AbstractExpectedReturnsEstimator, T2<:Real, T3<:Real, T4<:EuclideanProjection} <: AbstractOnlinePortfolioSelectionAlgorithm

Takes one soft-thresholded, linearised step of the log forecast return from the Price-Adjusted Allocation (TCO).

This is the transaction cost optimisation of Li, Wang, Huang and Hoi (2018). The threshold is a multiple of the cost rate, and it leaves each small trade at zero. The first form of the paper reads the reciprocal of the last price relative, LaggedPrice at lag = 1, which is the default. The second form reads the moving average of the price levels over the last price. The paper does not give its window, and Moon (2019) uses five levels, the default of MovingAverage.

Mathematical definition

\[\begin{align} \boldsymbol{g} &= \frac{\hat{\boldsymbol{x}}_{t+1}}{\langle \hat{\boldsymbol{w}}_t, \hat{\boldsymbol{x}}_{t+1} \rangle}\,, \\ \boldsymbol{v} &= \eta \left( \boldsymbol{g} - \bar{g} \boldsymbol{1} \right)\,, \\ \boldsymbol{w}_{t+1} &= \mathrm{Proj}_{\mathcal{W}}\left( \hat{\boldsymbol{w}}_t + \operatorname{sign}(\boldsymbol{v}) \odot \max\left(\lvert \boldsymbol{v} \rvert - \eta \lambda,\, 0\right) \right)\,, \\ \lambda &= 10 \gamma\,. \end{align}\]

Where:

  • $\hat{\boldsymbol{x}}_{t+1}$: Price Relative Forecast for period $t + 1$, made after the row of period $t$.
  • $\hat{\boldsymbol{w}}_t = \boldsymbol{w}_t \odot \boldsymbol{x}_t / \langle \boldsymbol{w}_t, \boldsymbol{x}_t \rangle$: Price-Adjusted Allocation, the wealth held in each asset at the end of period $t$.
  • $\boldsymbol{g}$: Gradient of $\log \langle \boldsymbol{w}, \hat{\boldsymbol{x}}_{t+1} \rangle$ at $\hat{\boldsymbol{w}}_t$.
  • $\bar{g}$: Mean of the entries of $\boldsymbol{g}$.
  • $\boldsymbol{v}$: Centred step before the threshold.
  • $\eta$: Step size of the linearised step, the eta field.
  • $\lambda$: Weight of the $L_1$ penalty on the trade.
  • $\gamma$: Proportional transaction cost rate, the gamma field.
  • $t$: Period index, counted from one.
  • $\mathrm{Proj}_{\mathcal{W}}$: Euclidean projection onto the Allocation Set $\mathcal{W}$.

The paper states the programme $\underset{\boldsymbol{w}}{\min} \; -\log \langle \boldsymbol{w}, \hat{\boldsymbol{x}}_{t+1} \rangle + \lambda \lVert \boldsymbol{w} - \hat{\boldsymbol{w}}_t \rVert_1$ on the simplex. Its Proposition 4.2 linearises the log at $\hat{\boldsymbol{w}}_t$, adds the proximal term $\lVert \boldsymbol{w} - \hat{\boldsymbol{w}}_t \rVert^2 / (2 \eta)$, and takes $\bar{g}$ as the multiplier of the budget. The vector inside the projection is the exact minimiser of that proximal programme without the bounds, and the projection restores them. When $\eta \lambda$ exceeds every entry of $\lvert \boldsymbol{v} \rvert$, the rule holds $\hat{\boldsymbol{w}}_t$.

The proof of Proposition 4.2 renames the threshold $\eta \lambda$ as $\lambda$, and the experiments of the paper set that renamed threshold to $10 \gamma$. Moon (2019) records that the code of the authors applies the threshold $10 \eta \gamma$, and that the published results rest on it. The library takes that threshold, so $\lambda = 10 \gamma$ is the weight of the $L_1$ penalty.

Algorithm

online_update! runs these steps at the row x of the period, from the allocation w.

  1. Advance the forecaster with forecast_relative, which gives the carrier st and the forecast xhat.
  2. Form the Price-Adjusted Allocation what of w after the row, with price_adjusted_allocation.
  3. Form the gradient g at what.
  4. Form the centred step v.
  5. Form the threshold lam = 10 * eta * gamma, which is $\eta \lambda$.
  6. Form the raw step q by the soft threshold of v at lam, added to what.
  7. Project q onto the set with project, with what. Return st and the new allocation.

Fields

  • me: The forecaster whose mean is the Price Relative Forecast, x̂ = 1 .+ mu: folded on the Rule State where it has an exact fold, and refit over the rows the head holds otherwise.
  • eta: Step size of the linearised step. It also scales the soft threshold.
  • gamma: Proportional transaction cost rate. The soft threshold is 10 * eta * gamma.
  • proj: The Projection Geometry the rule projects its raw step onto the Allocation Set in; the slot's type bound names the geometries the rule's theorem covers.

Constructors

TransactionCostOptimisation(;    me::Union{<:AbstractExpectedReturnsEstimator, <:Online} = PriceLevelExpectedReturns(; alg = LaggedPrice()),    eta::Real = 10,    gamma::Real = 0.001,    proj::EuclideanProjection = EuclideanProjection()) -> TransactionCostOptimisation

Keywords correspond to the struct's fields. The rule needs the rows that me needs. eta = 10 is the paper's. gamma is the proportional cost rate that the trader pays, which the paper leaves to the market. The paper tests gamma = 0.0025 and gamma = 0.005.

Validation

  • eta > 0. A DomainError is thrown otherwise.
  • gamma >= 0. A DomainError is thrown otherwise.
  • me is not an Online wrapper, and holds none. An ArgumentError is thrown otherwise, and it names the wrapper.

Examples

julia> TransactionCostOptimisation()TransactionCostOptimisation     me ┼ PriceLevelExpectedReturns        │   alg ┼ LaggedPrice        │       │   lag ┴ Int64: 1    eta ┼ Int64: 10  gamma ┼ Float64: 0.001   proj ┴ EuclideanProjection()

Related

References

  • [55] B. Li, J. Wang, D. Huang and S. C. H. Hoi. Transaction cost optimization for online portfolio selection. Quantitative Finance 18, 1411–1424 (2018).
  • [188] S.-H. Moon. Empirical investigation of state-of-the-art mean reversion strategies for equity markets. arXiv preprint arXiv:1909.04327 (2019).
source
PortfolioOptimisers.ShortTermSparsePortfolio — Type
struct ShortTermSparsePortfolio{T1<:AbstractExpectedReturnsEstimator, T2<:AbstractSparsePortfolioAlgorithm, T3<:Real, T4<:EuclideanProjection} <: AbstractOnlinePortfolioSelectionAlgorithm

Solves a linear programme on the log of the forecast with an $L_1$ penalty, then projects the scaled solution (SSPO).

This is the short-term sparse portfolio optimisation of Lai, Yang, Fang and Wu (2018). The forecast is the window peak over the last price by default, so every entry of the forecast is at least one. alg finds the iterate, and the scale of the iterate before the projection makes the allocation sparse.

Mathematical definition

\[\begin{align} \boldsymbol{\phi} &= -\left(1.1 \log \hat{\boldsymbol{x}}_{t+1} + \boldsymbol{1}\right)\,, \\ &\underset{\boldsymbol{b}}{\min} \; \langle \boldsymbol{b}, \boldsymbol{\phi} \rangle + \lambda \lVert \boldsymbol{b} \rVert_1 \quad \text{s.t.} \quad \boldsymbol{1}^\intercal \boldsymbol{b} = 1\,, \\ &\underset{\boldsymbol{b}, \boldsymbol{g}}{\min} \; \langle \boldsymbol{b}, \boldsymbol{\phi} \rangle + \lambda \lVert \boldsymbol{g} \rVert_1 + \tfrac{\lambda}{2 \gamma} \lVert \boldsymbol{b} - \boldsymbol{g} \rVert^2 \quad \text{s.t.} \quad \boldsymbol{1}^\intercal \boldsymbol{b} = 1\,, \\ \boldsymbol{w}_{t+1} &= \mathrm{Proj}_{\mathcal{W}}\left(\zeta \boldsymbol{b}\right)\,. \end{align}\]

Where:

  • $\boldsymbol{\phi}$: Objective vector of the short-term sparse portfolio step, $-(1.1 \log \hat{\boldsymbol{x}} + \boldsymbol{1})$ for the Price Relative Forecast $\hat{\boldsymbol{x}}$. Its smallest entry is the largest forecast.
  • $\hat{\boldsymbol{x}}_{t+1}$: Price Relative Forecast for period $t + 1$, made after the row of period $t$.
  • $\boldsymbol{b}$: Unscaled target of the short-term sparse portfolio step, the vector whose scaled projection is the next allocation.
  • $\boldsymbol{g}$: Auxiliary vector that carries the $L_1$ penalty in place of the target.
  • $\lambda$: Penalty weight of the $L_1$ norm, positive.
  • $\gamma$: Soft-threshold width, positive.
  • $\zeta$: Scale of the iterate before the projection, the zeta field.
  • $t$: Period index, counted from one.
  • $\mathrm{Proj}_{\mathcal{W}}$: Euclidean projection onto the Allocation Set $\mathcal{W}$.

The first programme is the programme that the paper states. The paper solves it by an alternating direction iteration, which couples $\boldsymbol{b}$ to its soft threshold $\boldsymbol{g}$ by a quadratic term with no multiplier. So the fixed point of that iteration solves the second programme. alg chooses the iterate $\boldsymbol{b}$:

algThe iterateParametersCost of a step
L1Optimumthe optimum of the stated programmenone$O(N)$
HuberOptimumthe fixed point of the paper's iteration, in closed formlambda, gamma$O(N)$, or $O(N^2)$ when $N \gamma > 1$
AlternatingDirectionMethodthe paper's iteration at the paper's stoplambda, gamma, eta, iters, tolup to iters iterations of $O(N)$

The first programme puts the whole budget on the largest forecast. The fixed point gives every other asset at most $\gamma$. So its scaled projection also puts the whole budget on the largest forecast while $N \gamma \leq 1 - 1 / \zeta$, with $N$ the number of assets. At the paper's gamma = 0.01 and zeta = 500 that is up to 99 assets. With more assets, the projection of the fixed point can hold a few assets.

The iteration of the paper approaches the fixed point slowly. It stops when the budget residual is below its tolerance, which it can reach at a sign change of the residual while the iterate is still tenths away from the fixed point. So its projection is usually the projection of the fixed point, but not always. HuberOptimum is the default, because the method of the paper converges to its answer. Take L1Optimum for the programme that the paper states, and AlternatingDirectionMethod for the loop of the paper with its stop.

Both programmes have a minimum only when $\max \boldsymbol{\phi} - \min \boldsymbol{\phi} \leq 2 \lambda$. At $\lambda = 1/2$ that is $\max \hat{\boldsymbol{x}}_{t+1} / \min \hat{\boldsymbol{x}}_{t+1} \leq e^{1 / 1.1}$. Past that bound the objective decreases without limit as the budget moves to the largest forecast. L1Optimum and HuberOptimum take that limit, and the iteration of the paper returns its last iterate.

Algorithm

online_update! runs these steps at the row x of the period, from the allocation w.

  1. Advance the forecaster with forecast_relative, which gives the carrier st and the forecast xhat.
  2. Check that every entry of xhat is positive.
  3. Form the objective vector phi from xhat.
  4. Find the iterate b with sparse_portfolio_iterate, from phi and the seed w.
  5. Project zeta .* b onto the set with project, with the price_adjusted_allocation of w after the row. Return st and the new allocation.

Fields

  • me: The forecaster whose mean is the Price Relative Forecast, x̂ = 1 .+ mu: folded on the Rule State where it has an exact fold, and refit over the rows the head holds otherwise.
  • alg: Algorithm that finds the iterate.
  • zeta: Scale of the iterate before the projection.
  • proj: The Projection Geometry the rule projects its raw step onto the Allocation Set in; the slot's type bound names the geometries the rule's theorem covers.

Constructors

ShortTermSparsePortfolio(;    me::Union{<:AbstractExpectedReturnsEstimator, <:Online} = PriceLevelExpectedReturns(; alg = WindowPeak()),    alg::AbstractSparsePortfolioAlgorithm = HuberOptimum(),    zeta::Real = 500,    proj::EuclideanProjection = EuclideanProjection()) -> ShortTermSparsePortfolio

Keywords correspond to the struct's fields. The defaults of zeta and of the parameters of alg are the paper's. The rule needs the rows that me needs.

Validation

  • zeta > 0. A DomainError is thrown otherwise.
  • me is not an Online wrapper, and holds none. An ArgumentError is thrown otherwise, and it names the wrapper.
  • At the update, x̂ > 0 in every asset, so the log is defined. A DomainError is thrown otherwise.

Examples

julia> ShortTermSparsePortfolio()ShortTermSparsePortfolio    me ┼ PriceLevelExpectedReturns       │   alg ┼ WindowPeak       │       │   window ┴ Int64: 5   alg ┼ HuberOptimum       │   lambda ┼ Float64: 0.5       │    gamma ┴ Float64: 0.01  zeta ┼ Int64: 500  proj ┴ EuclideanProjection()

Related

References

  • [53] Z.-R. Lai, P.-Y. Yang, L. Fang and X. Wu. Short-term sparse portfolio optimization based on alternating direction method of multipliers. Journal of Machine Learning Research 19, 1–28 (2018).
source
PortfolioOptimisers.AbstractSparsePortfolioAlgorithm — Type
abstract type AbstractSparsePortfolioAlgorithm <: AbstractAlgorithm

Abstract supertype for the algorithms that find the iterate of a short-term sparse portfolio step.

The iterate is the vector $\boldsymbol{b}$ whose scaled projection is the next allocation. The members differ in the programme that they solve, and ShortTermSparsePortfolio compares them.

Interfaces

To implement a new algorithm, subtype AbstractSparsePortfolioAlgorithm with its parameters as the fields of the struct, and implement this method:

  • sparse_portfolio_iterate(alg::AbstractSparsePortfolioAlgorithm, phi::AbstractVector, w::AbstractVector) -> AbstractVector: Returns the iterate for the objective vector phi. The entries of the iterate sum to one. w is the held allocation, which an iteration reads as its seed.

Related

source
PortfolioOptimisers.ForecasterState — Type
struct ForecasterState{__T_me} <: AbstractPartialFitState

Holds the forecaster of a forecast-reading rule, with the Partial Fit State of the rows that it folded.

A rule seeds this carrier when its forecaster has an exact fold. SimpleExpectedReturns, ExpWeightedExpectedReturns, a PriceLevelExpectedReturns over a folding statistic and a PriorExpectedReturns over a prior that folds all have one. supports_partial_fit answers the question once, at the seed.

The rule folds the forecaster on every row and reads the forecast from its state, so the head holds one row for it. The fold reads that row as the head received it, with its gaps and its active mask, and not the finite price relative of the step. The rule fits a forecaster with no exact fold again on the rows that the head holds, and its carrier is then nothing.

Fields

  • me: The forecaster, which carries the state of the rows that it folded.

Related

source
PortfolioOptimisers.forecast_relative — Function
forecast_relative(me::AbstractExpectedReturnsEstimator, st::Nothing, x::AbstractVector, rows)
forecast_relative(me::AbstractExpectedReturnsEstimator, st::ForecasterState, x::AbstractVector, rows)

Advances the forecaster of a rule by the row x, and returns its Price Relative Forecast.

The fold arm folds a forecaster on a ForecasterState on the row, and reads the forecast from its state. The refit arm fits a forecaster with no carrier again on the rows that the head holds, which include the row. Outside the head, with no rows carrier, the fold arm folds the finite x .- 1, and the refit arm fits the row alone.

Both arms read the rows carrier of the head as the batch verb reads it, with the gaps and the active mask. The refit arm reduces to the Coverage Universe of the window. So a plain forecaster gives NaN, and the step holds the asset, when the asset has a gap anywhere in the window. A mask-aware forecaster gives the forecast from the rows that it has.

The fold arm folds the last row of the carrier, which is the current row as the head received it, under its active mask. The running statistic of a plain moment forecaster is then NaN from the first gap on, which is the Coverage Universe of the prefix. A mask-aware forecaster freezes, resets or admits the asset again by its own policy. A folding price-level statistic resets the asset that the mask turns off, and gives NaN until it has folded a level, so a relisted asset starts cold.

Mathematical definition

\[\begin{align} \hat{x}_{t+1, i} &= \begin{cases} 1 + \hat{\mu}_i & \text{if } \hat{\mu}_i \text{ is finite}\,, \\ 1 & \text{otherwise}\,. \end{cases} \end{align}\]

Where:

  • $\hat{\boldsymbol{x}}_{t+1}$: Price Relative Forecast for period $t + 1$, made after the row of period $t$.
  • $\hat{\mu}_i$: Expected return of asset $i$ that the forecaster estimates after the row of period $t$.
  • $t$: Period index, counted from one.

A forecast of one in every asset is flat, and the step of every rule holds on a flat forecast. The refit arm also gives a flat forecast while it has fewer rows than forecast_min_rows.

Algorithm

With no carrier, the refit arm:

  1. Take the returns X and the Asset Panel pnl with refit_rows.
  2. When X has fewer rows than forecast_min_rows, return nothing and a flat forecast. Stop.
  3. Estimate the expected returns with mean(me, X, pnl; dims = 1).
  4. Return nothing and one plus the expected returns, through flat_where_undefined.

With a ForecasterState, the fold arm:

  1. Fold the forecaster st.me with partial_fit!. With a rows carrier, fold the last row of rows.X under the mask of last_active_mask. Without one, fold x .- 1.
  2. Read the expected returns from the state of the folded forecaster.
  3. Return the new ForecasterState and one plus the expected returns, through flat_where_undefined.

Arguments

  • me: The forecaster on the slot of the rule.
  • st: The carrier of the rule, or nothing.
  • x: The price relative of the row.
  • rows: The rows carrier that the head holds through the row, a ReturnsResult, or nothing.

Returns

  • (st', x̂)::Tuple: The carrier after the row, and the forecast as a new vector.

Related

source

References

[48]
B. Li and S. C. Hoi. On-line portfolio selection with moving average reversion. In: Proceedings of the 29th International Conference on Machine Learning (2012).
[49]
B. Li, S. C. Hoi, D. Sahoo and Z.-Y. Liu. Moving average reversion strategy for on-line portfolio selection. Artificial Intelligence 222, 104–123 (2015).
[50]
D. Huang, J. Zhou, B. Li, S. C. Hoi and S. Zhou. Robust median reversion strategy for online portfolio selection. IEEE Transactions on Knowledge and Data Engineering 28, 2480–2493 (2016).
[52]
Z.-R. Lai, D.-Q. Dai, C.-X. Ren and K.-K. Huang. A peak price tracking-based learning system for portfolio selection. IEEE Transactions on Neural Networks and Learning Systems 29, 2823–2832 (2018).
[53]
Z.-R. Lai, P.-Y. Yang, L. Fang and X. Wu. Short-term sparse portfolio optimization based on alternating direction method of multipliers. Journal of Machine Learning Research 19, 1–28 (2018).
[54]
B. Li, J. Luo and H. Xu. A portfolio selection strategy based on the peak price involving randomness. IEEE Access 11, 52066–52074 (2023).
[55]
B. Li, J. Wang, D. Huang and S. C. Hoi. Transaction cost optimization for online portfolio selection. Quantitative Finance 18, 1411–1424 (2018).
[56]
Z.-R. Lai, P.-Y. Yang, L. Fang and X. Wu. Reweighted price relative tracking system for automatic portfolio optimization. IEEE Transactions on Systems, Man, and Cybernetics: Systems 50, 4349–4361 (2020).
[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).
[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).
[188]
S.-H. Moon. Empirical investigation of state-of-the-art mean reversion strategies for equity markets, arXiv preprint arXiv:1909.04327 (2019).