The Algo Base Class
Relevant source files
The following files were used as context for generating this wiki page:
The Algo class serves as the fundamental building block for all Online Portfolio Selection (OLPS) algorithms within the universal-portfolios library. Its primary purpose is to provide a unified interface for calculating portfolio weights at every timestep, allowing for the simulation and analysis of various trading strategies. The class handles the orchestration of sequential weight calculation, data conversion, and integration with result analysis tools.
By subclassing Algo, developers can implement specific financial theories—such as Modern Portfolio Theory (MPT) or Universal Portfolios (UP)—while leveraging a common infrastructure for backtesting. The base class manages the iteration over historical price data and produces an AlgoResult object, which encapsulates performance metrics like Sharpe ratio, drawdowns, and total wealth.
Sources: universal/algo.py:16-29, README.md:38-40
Core Architecture and Lifecycle
The Algo class operates through a lifecycle of initialization, weight generation (either sequentially or in bulk), and result aggregation. Subclasses typically override the step method for sequential logic or the weights method for optimized matrix calculations.
Lifecycle Flow
The following diagram illustrates the typical execution flow when calling the run method on an algorithm instance:
The algorithm processes price relatives (ratio of price $p_t / p_{t-1}$), log returns, or raw prices depending on its configuration.
Sources: universal/algo.py:81-120, universal/algo.py:171-200
Key Methods and Configuration
| Method / Property | Description |
|---|---|
init_weights(columns) | Sets initial portfolio weights (e.g., uniform or zeros). |
init_step(X) | Initializes persistent variables before the sequential loop starts. |
step(x, last_b, history) | Calculates new weights for the next period based on current returns and history. |
weights(X) | Orchestrates the sequential call to step for all timesteps. |
run(S) | Main entry point that converts absolute prices S and executes the algorithm. |
PRICE_TYPE | Class attribute determining input format: "ratio", "log", or "raw". |
Sources: universal/algo.py:38-79, universal/algo.py:126-140
Sequential Processing and History
The algorithm maintains a "no look-ahead" policy by default. The step method only receives information available up to time $t$ to calculate weights for $t+1$.
The step Method
This is the most critical extension point. It takes three parameters:
x: The most recent returns (price relatives).last_b: The portfolio weights used in the previous period.history: A DataFrame containing all returns up to the current moment.
def step(self, x, last_b, history=None):
# Example implementation in a subclass (CRP)
if self.b is None:
self.b = np.ones(len(x)) / len(x)
return self.b
Sources: universal/algo.py:59-69, universal/algos/crp.py:28-32
Minimum History and Frequency
The min_history parameter allows algorithms to skip weight updates until enough data is collected for parameter estimation (e.g., covariance matrices in MPT). The frequency parameter controls how often rebalancing occurs; for instance, a frequency of 5 trades every fifth period.
Sources: universal/algo.py:33-36, universal/algos/mpt.py:108-111
Integration with Result Analysis
Upon completion of a backtest, the run method returns an AlgoResult object. This class is responsible for calculating financial performance based on the weights generated by the Algo.
Result Generation Sequence
Implementation Examples
Constant Rebalanced Portfolio (CRP)
The CRP algorithm implements a static weight strategy. Its step method simply returns a fixed weight vector b, ignoring market fluctuations and history.
Sources: universal/algos/crp.py:15-32
Modern Portfolio Theory (MPT)
The MPT subclass demonstrates a complex use of the base class. It overrides init_step to calculate rolling covariance matrices and uses the step method to solve optimization problems (Sharpe ratio maximization or variance minimization) using history.
Sources: universal/algos/mpt.py:108-140
Universal Portfolios (UP)
The UP algorithm uses init_step to create a mesh of Constant Rebalanced Portfolios on a simplex. The step method then updates the wealth of each point in the mesh to determine the performance-weighted average portfolio.
Sources: universal/algos/up.py:38-54
Summary
The Algo base class provides a standardized framework for online portfolio selection. By abstracting the complexities of data iteration, price conversion, and performance reporting, it allows developers to focus on implementing specific strategy logic within the step method. Its integration with AlgoResult ensures that every strategy can be evaluated using a consistent set of metrics, facilitating objective comparison between different financial models.
Sources: universal/algo.py:16-29, universal/result.py:236-250