Passive Aggressive Mean Reversion (PAMR & WMAMR)
Relevant source files
The following files were used as context for generating this wiki page:
Passive Aggressive Mean Reversion (PAMR) is an Online Portfolio Selection (OLPS) algorithm implemented within the universal-portfolios library. It belongs to the "Follow the Loser" category of strategies, which exploit the mean-reversion property of financial assets. The core logic of PAMR is to update portfolio weights such that the expected return on the current day's price relative stays below a certain threshold, while minimizing the deviation from the previous portfolio weights.
Weighted Moving Average Passive Aggressive (WMAMR) is an extension of PAMR. It combines the principles of Online Moving Average Reversion (OLMAR) and PAMR by using a moving average of past returns to predict the next period's price relative before applying the Passive-Aggressive update rules.
Sources: README.md:46-56, universal/algos/pamr.py:8-13, universal/algos/wmamr.py:10-15
Architecture and Class Hierarchy
The PAMR and WMAMR algorithms are implemented as classes inheriting from the base Algo class. WMAMR specifically inherits from PAMR, reusing its update logic while overriding the prediction step.
The diagram shows the inheritance structure where PAMR provides the fundamental update logic and WMAMR specializes it with a window-based prediction.
Sources: universal/algos/pamr.py:16, universal/algos/wmamr.py:19, universal/algos/olmar.py:11, universal/algos/rmr.py:22
PAMR Core Logic
PAMR operates by receiving a price relative vector $x$ and updating the portfolio weights $b$. The algorithm aims to satisfy the constraint $b \cdot x \leq \epsilon$, where $\epsilon$ is a mean reversion threshold.
Technical Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
eps | float | 0.5 | Mean reversion threshold. Recommended between 0.5 and 1.0. |
C | float | 500 | Aggressiveness control parameter for variants 1 and 2. |
variant | int | 0 | Selection of algorithmic variant (0, 1, or 2). |
Sources: universal/algos/pamr.py:25-33
Algorithmic Variants
The algorithm calculates a loss function $l_\epsilon = \max(0, b \cdot x - \epsilon)$ and a Lagrangian multiplier $\lambda$. The calculation of $\lambda$ depends on the chosen variant:
- Variant 0: $\lambda = \frac{l_\epsilon}{|x - \bar{x}|^2}$
- Variant 1: $\lambda = \min(C, \frac{l_\epsilon}{|x - \bar{x}|^2})$
- Variant 2: $\lambda = \frac{l_\epsilon}{|x - \bar{x}|^2 + \frac{1}{2C}}$
The updated weights are calculated as $b = b - \lambda(x - \bar{x})$, where $\bar{x}$ is the mean of the price relatives. Finally, the weights are projected back onto the simplex to ensure they are non-negative and sum to one.
Sources: universal/algos/pamr.py:59-81
WMAMR Implementation
WMAMR modifies the input to the PAMR update function. Instead of using the raw price relative of the current period, it calculates a weighted moving average of history to serve as a prediction.
Execution Flow
The flowchart illustrates how WMAMR intercepts the step process to inject a moving average prediction (xx = history[-self.window:].mean()) before utilizing the standard PAMR update formula.
Sources: universal/algos/wmamr.py:38-42
Configuration
WMAMR introduces a lookback window parameter:
window: Length of the moving average window (default: 5). Must be $\geq 1$.kwargs: Inheritseps,C, andvariantfrom PAMR.
Sources: universal/algos/wmamr.py:30-36
Mathematical Utilities and Projections
Both algorithms rely on universal.tools.simplex_proj to maintain valid portfolio weights. This utility ensures that the vector $b$ remains within the probability simplex ($b_i \geq 0$ and $\sum b_i = 1$).
def simplex_proj(y):
"""Projection of y onto simplex."""
m = len(y)
bget = False
s = sorted(y, reverse=True)
tmpsum = 0.0
# ... logic to find tmax ...
return np.maximum(y - tmax, 0.0)
Sources: universal/tools.py:328-345, universal/algos/pamr.py:81
Relation to Other Mean Reversion Algos
PAMR and WMAMR are part of a broader suite of mean reversion algorithms in the library:
- OLMAR: Uses a moving average prediction and a similar update rule but with a constraint $b \cdot \hat{x} \geq \epsilon$.
- RMR: Uses an L1-median estimator instead of a simple mean for robustness against outliers.
- CWMR: A confidence-weighted version that models portfolio weights as a Gaussian distribution.
Sources: universal/algos/olmar.py:46-56, universal/algos/rmr.py:17-21, universal/algos/cwmr.py:14-20
Summary
The PAMR and WMAMR modules provide robust implementations of Passive-Aggressive learning applied to portfolio selection. PAMR focuses on the immediate mean-reversion of price relatives through a constrained optimization problem. WMAMR enhances this by smoothing price signals through a moving average window, making it less sensitive to single-period noise and aligning it with trends observed in the OLMAR strategy. These algorithms are essential components of the "Follow the Loser" category within the universal-portfolios ecosystem.
Sources: universal/algos/pamr.py, universal/algos/wmamr.py, README.md:46-56