Capability catalogue

This page lists what PortfolioOptimisers.jl can do, grouped by the job that each type or function does. Each entry links to its docstring, on a public API page, or on a private API page for a name outside the public API.

The documentation build writes this page with docs/generatecapabilitycatalogue.jl. The grouping comes from docs/capability_catalogue.jl. The description of an entry is the first sentence of its docstring, unless the catalogue gives the entry its own label. The build fails when a type that you can choose, such as an estimator or an algorithm, has no entry here.

The type hierarchy lists the same types by their supertypes.

Core abstractions

Every component of the library is one of three kinds. An estimator is a configuration, which names a method and holds its hyperparameters. An algorithm selects a behaviour, and you pass it to an estimator. A result holds what a computation returns. You choose the estimators and the algorithms, and you get the results back.

Every estimator, algorithm and result is immutable, so the library passes a value it computes at run time down a composed estimator by rebuilding that estimator.

  • No-op factory function for constructing objects with a uniform interface. factory

Preprocessing

Preprocessing estimator that converts price-level data into returns-level data. PricesToReturns, fit_preprocessing, and apply_preprocessing

Price gap conventions

  • Fills the price gaps inside the listing of each asset with a stated convention, and changes no other price. PriceGapFill and PriceGapFillResult
  • States that a price did not move across a gap, so the fill holds the last observed price forward. CarriedPrice

Conventions for the return that ends a price gap

  • Books the whole move across a Held Gap on the observation that ends it, so the gap holds k non-finite returns. CatchUpGapReturn

Asset selection

Selection rules

  • RankRule with the tail sizes given as fractions of the asset universe. QuantileRule
  • Take best and/or worst assets from the tails of the score ordering, then keep or drop them. RankRule
  • Keep assets whose score falls strictly inside the band (lo, hi). ThresholdRule

The universe a price panel states

The position of a gap in a price column tells you whether the asset was in the universe. A run of gaps at the start means that the asset was not yet listed. A run at the end means that it was delisted. A gap between two prices is a suspension, and the asset stays listed through it. listing_span applies that rule to a table of prices, and universe_masks moves the answer onto the dates of the returns. The answer is the two masks an AssetPanel holds, one for the assets that are listed at each date and one for the listed assets whose return is also finite. If you have a listing calendar of your own, pass it at the same point, and it replaces the answer derived from the prices.

The ingestion layer

PriceIngestion assembles raw price series into the price table that the conversion to returns reads. It unifies the two conventions for an absent price, joins the factor and benchmark tables, and collapses the frequency. It runs once on the whole history, not as a Pipeline step, for two reasons. The join can add or drop dates, and the collapse renumbers the observations, but a cross-validation cuts its folds once, on the dates of the table. The rule for gaps above also needs the whole history, and a step sees only one window. The table it returns holds the listing span of each asset, the dates from its first price to its last. PricesToReturns moves that span onto the dates of the returns and gives the ReturnsResult an AssetPanel that states the universe. It does this for every table, a table with no gaps included. If a returns result holds no panel, you built it without the ingestion layer.

  • Estimator that assembles raw price series into the price carrier and its Listing Span, which the conversion then reads. PriceIngestion and price_ingestion

Build the AssetPanel a carrier holds, from the raw, blank-carrying form of each Panel Field. asset_panel, AssetPanel, panel_field, panel_feature_matrix, panel_dataframe, feature_matrix, feature_labels, and panel_input

Kinds of panel field, the named quantities such as a market capitalisation or a sector that a panel holds per asset

  • A Panel Field holding one number per asset, and per observation when it is time-varying. NumericPanelField
  • A Panel Field holding one category label per asset, and per observation when it is time-varying. CategoricalPanelField
  • A Panel Field whose trailing axis carries its own labels, and optionally its own groups. TensorPanelField

Inputs that build a panel field

  • Raw form of a Panel Field holding one numeric quantity per observation and asset. NumericPanelInput
  • Raw form of a Panel Field holding one category label per observation and asset. CategoricalPanelInput
  • Raw form of a Panel Field whose third axis carries its own labels, and optionally its own groups. TensorPanelInput

Blank-cell policies

  • Refuses a blank cell instead of resolving one. NoPanelFill
  • Resolves every blank cell to one constant. ConstantPanelFill
  • Resolves a blank cell to the nearest earlier observed value of the same asset. ForwardPanelFill
  • Resolves a blank cell to the nearest later observed value of the same asset. BackwardPanelFill

Cross-sectional transforms

A cross-sectional transform rescales the values of the assets at one observation against each other, through cross_sectional_transform. You pass the benchmark weights and the group labels to the call. cross_sectional_groups derives the group labels from a one-hot array or from a categorical panel field, such as a sector.

Outlier treatments

Scoring transforms

Matrix processing

  • Projects a matrix to the nearest positive definite matrix, typically used for co-moment matrices. Posdef, posdef!, and posdef

Configures and applies denoising algorithms to covariance or correlation matrices. Denoise, denoise!, and denoise

  • Denoises by setting the noise eigenvalues to zero. SpectralDenoise
  • Denoises by replacing the noise eigenvalues with their own mean. FixedDenoise
  • Denoises by shrinking the off-diagonal part of the noise block towards zero, keeping its diagonal whole. ShrunkDenoise

Regression models

A factor prior that regresses on a series of factor returns fits it with regression, which returns a Regression. ImpliedVolatilityRegression does not call it: it fits one of the regression targets below to each asset and predicts its realised volatility.

Regression targets

  • Fits each response by ordinary least squares through GLM.LinearModel. LinearModel
  • Fits each response by a generalised linear model through GLM.GeneralizedLinearModel. GeneralisedLinearModel

Regression types

Estimates a loadings matrix by selecting a factor subset per asset, one factor at a time. StepwiseRegression

Algorithms

  • Grows the factor set from empty, adding the factor that most improves the criterion. ForwardSelection
  • Shrinks the factor set from full, removing the factor whose removal most improves the criterion. BackwardElimination

Selection criteria

  • Selects factors by the statistical significance of their coefficients. PValue
  • :aic
  • :aicc
  • :bic
  • :r2
  • :adjr2

Estimates a loadings matrix by regressing each asset on the leading components of the factors. DimensionReductionRegression

  • Replaces the factors with the principal components of their standardised covariance. PCA
  • Replaces the factors with the latent components of a Gaussian latent-variable model. PPCA

Cross-sectional regression types

A cross-sectional regression fits one model per observation, across the assets. cross_sectional_regression runs it and returns a CrossSectionalRegression. cross_sectional_r2 and mean_cross_sectional_r2 score a fit.

Fits one weighted least squares per observation across the assets, in closed form. CrossSectionalLinearRegression, cross_sectional_regression, cross_sectional_r2, and mean_cross_sectional_r2

Rank deficiency policies

Cross-sectional regression weight policies

A weight policy sets the weight of each asset in the cross-sectional fit at one observation. A one-pass policy reads the cross-section alone. A two-pass policy also reads the residuals of a first fit.

Cross-sectional regression diagnostics

A diagnostic of the cross-sectional fit reads the exposure history, the factor returns and the residuals. It returns a series over the observations or one value per factor. You can pass the histories as bare arrays, already aligned for the lag. Every function except cs_gram also takes a CrossSectionalFactorModel. From the model, it lags the exposures and applies the factor family basis itself. The section on the factor family basis below says what that basis does.

Return the weighted Gram history of a cross-sectional regression, one slice per observation. cs_gram

  • Return the variance inflation factor of every factor, one row per observation. exposure_vif
  • Return the two-norm condition number of the Gram matrix of the cross-sectional design, one entry per observation. exposure_condition_number

Fit quality.

  • Return the weighted cross-sectional coefficient of determination, one entry per observation. cs_regression_r2
  • Return the cross-sectional coefficient of determination adjusted for the regressor count, one entry per observation. cs_regression_adjusted_r2
  • Return the Akaike information criterion of every cross-sectional fit, one entry per observation. cs_regression_aic
  • Return the Bayesian information criterion of every cross-sectional fit, one entry per observation. cs_regression_bic

Significance of a factor return.

Cross-sectional exposure diagnostics

A diagnostic of the exposure history reads the exposures as the AssetPanel holds them, with no lag and with one column per named factor. It returns a matrix over the factors, a series over the observations, or one value per factor. The input is bare arrays or a CrossSectionalFactorModel. With a model, the correlation, stability, dispersion and coverage functions derive the cross-sectional weights from an AbstractOrthogonalityMetric. The information coefficient uses the weights of the regression, and its reduced keyword maps the exposures through the factor family basis.

Redundancy and turnover of an exposure.

  • Return the time-averaged correlation between every pair of factor exposures. exposure_correlation
  • Return the stability of every factor exposure, one row per pair of observations. exposure_stability

Reach and spread of an exposure.

  • Return the weighted cross-sectional standard deviation of every factor exposure, one row per observation. exposure_dispersion
  • Return the coverage of every factor exposure, one entry per factor. exposure_coverage

Forecasting power of an exposure.

  • Return the information coefficient of every factor exposure, one row per pair of observations. exposure_ic
  • Return the summary of an information coefficient series, one entry per factor. exposure_ic_summary

Cross-sectional idiosyncratic diagnostics

A diagnostic of the idiosyncratic returns divides each residual of the fit by the volatility the fit predicted for it. It then reads the cross-section of those ratios one observation at a time. Each function takes the residuals and the predicted volatilities as two bare arrays. A CrossSectionalFactorModel holds both histories, and every function except standardised_idio_returns also accepts one. Neither history has one column per factor, so this group applies no lag and no factor family basis.

The standardised residuals from which every series of this group is computed.

Shape of the standardised cross-section.

  • Return the cross-sectional standard deviation of the standardised idiosyncratic returns, one entry per observation. idio_calibration
  • Return the share of assets whose standardised idiosyncratic return exceeds a threshold, one entry per observation. idio_tail_rate
  • Return the cross-sectional excess kurtosis of the standardised idiosyncratic returns, one entry per observation. idio_kurtosis
  • Return the cross-sectional skewness of the standardised idiosyncratic returns, one entry per observation. idio_skewness
  • Return the five time-aggregated numbers of the calibration of a cross-sectional fit. idio_calibration_summary

Ranking power of the predicted volatility.

  • Return the information coefficient of the predicted idiosyncratic volatility, one entry per pair of observations. idio_vol_ic
  • Return the rank correlation of the predicted idiosyncratic volatility against the next observation's standardised absolute idiosyncratic return, one entry per pair of observations. idio_vol_residual_dependence

Factor model summary

The summary puts the diagnostics above into one table, with one row per named factor, before the factor family basis drops any. For each column it calls one function of the regression group or of the exposure group, and it aggregates the series over the observations. If the model holds no exposure history, every column that reads the exposures is nothing.

Summarise every factor of a cross-sectional factor model as a FactorSummaryResult. factor_model_summary

Descriptors

A descriptor is a value per asset and observation that is computed from the panel fields of an AssetPanel, such as a momentum or a book-to-price ratio. descriptor computes it from a descriptor estimator. Each named descriptor below is a constructor function for one of the general estimators. It fixes the panel fields, the window or the half-life, and a keyword overrides each value it fixes.

Divides one Panel Field, or a combination of Panel Fields, by another at every observation. PanelFieldRatio

  • Book equity over market capitalisation, the value Descriptor. BookToPrice
  • Trailing operating cash flow over market capitalisation, a value Descriptor. CashFlowToPrice
  • Trailing sales over market capitalisation, a value Descriptor. SalesToPrice
  • Trailing net income over market capitalisation, the earnings yield Descriptor. EarningsToPrice
  • Forward earnings per share over the adjusted close, the forward earnings yield Descriptor. ForwardEarningsToPrice
  • Trailing EBITDA over enterprise value, an earnings yield Descriptor that is neutral to the capital structure. EbitdaToEnterpriseValue
  • Trailing common dividends over market capitalisation, the dividend yield Descriptor. DividendToPrice
  • Forward dividends per share over the adjusted close, the forward dividend yield Descriptor. ForwardDividendToPrice
  • Trailing dividends plus net buybacks over market capitalisation, the total payout Descriptor. ShareholderYield
  • Total debt over total book capital, the book leverage Descriptor. BookLeverage
  • Total debt over total market capital, the market leverage Descriptor. MarketLeverage
  • Total debt over total assets, a leverage Descriptor. DebtToAssets
  • Gross profit over total assets, the gross profitability Descriptor. GrossProfitability
  • Gross profit over sales, the gross margin Descriptor. GrossMargin
  • Trailing net income over total assets, the return on assets Descriptor. ReturnOnAssets
  • Trailing net income over book equity, the return on equity Descriptor. ReturnOnEquity
  • Trailing sales over total assets, the asset turnover Descriptor. AssetTurnover
  • Trailing operating cash flow over total assets, a profitability Descriptor. CashFlowToAssets
  • Trailing sales over enterprise value, a profitability Descriptor that is neutral to the capital structure. SalesToEnterpriseValue
  • Accruals over total assets, the earnings quality Descriptor. AccrualsCashFlow
  • Dispersion of the forward earnings estimates over the adjusted close, an earnings quality Descriptor. AnalystDispersionToPrice
  • Shares sold short over shares outstanding, the short interest Descriptor. ShortInterest

Takes the natural logarithm of one Panel Field at every observation. PanelFieldLog

  • Natural logarithm of the market capitalisation, the size Descriptor. LogMarketCap
  • Returns one numeric Panel Field unchanged, as a Descriptor. Passthrough

Growth of a non-negative Panel Field over a fixed lag, at every observation. GrowthRate

  • Growth of total assets over one year, the investment Descriptor. AssetsGrowthRate
  • Growth of trailing sales over one year, the growth Descriptor. SalesGrowthRate
  • Growth of the split-adjusted share count over one year, the net issuance Descriptor. IssuanceGrowthRate

Change of a Panel Field over a fixed lag, scaled by the current value of a second Panel Field. ChangeToScale

  • Change of trailing net income over one year, divided by the current market capitalisation. EarningsChangeToPrice

Change of the ratio of two Panel Fields over a fixed lag. ChangeInIntensity

Exponentially weighted mean of the log returns, at every observation, with an optional skip. EWMean

  • Exponentially weighted mean of the log returns of the past year, less the past month. EWMomentum

Exponentially weighted mean of a ratio of Panel Fields, at every observation. EWVolumeRatio

  • Exponentially weighted share turnover, the fraction of the shares outstanding that changes hands. EWShareTurnover
  • Exponentially weighted price impact, the absolute return earned per unit of traded amount. EWAmihudIlliquidity
  • Ratio of a Panel Field to the exponentially weighted mean of a second one, at every observation. DaysToCover

Exponentially weighted volatility of the returns, at every observation. EWVolatility

  • Exponentially weighted volatility of the returns that fall short of a minimum acceptable return. EWDownsideVolatility

Exponentially weighted volatility of the market-model residual, at every observation. EWResidualVolatility

  • Exponentially weighted volatility of the market-model residuals that fall short of a minimum acceptable return. EWResidualDownsideVolatility

Exponentially weighted beta of the returns against the market return, at every observation. EWBeta

  • Exponentially weighted sensitivity of an asset to the market portfolio. EWMarketBeta
  • Exponentially weighted sensitivity of the returns to a reference series, after the market is removed. EWMacroSensitivity
  • Exponentially weighted sensitivity of the returns to the falls of the market, at every observation. EWDownsideBeta

Sum of log returns over a fixed window that ends a fixed number of observations back, at every observation. RollingLogReturn

  • Sum of log returns over one year, ending one month back. RollingMomentum
  • Negated sum of log returns over one month, ending at the current observation. Reversal

Maximum return over a fixed trailing window, at every observation. RollingMax

Factor exposures

A factor exposure is the loading of one asset on one factor at one observation. factor_exposure computes it from an exposure estimator, which takes descriptors, one categorical panel field, the exposure of another factor, or only the active mask of the AssetPanel. An estimator for one factor returns an observations by assets matrix. The one-hot estimator returns one factor per level of its panel field.

  • A Factor Exposure that is a fixed weighted combination of Descriptors. CompositeExposure
  • A Factor Exposure derived from the Factor Exposure of another factor. DerivedExposure
  • A Factor Exposure that expands one categorical Panel Field into one factor per level. OneHotExposure
  • A Factor Exposure equal to one for every asset at every observation. ConstantExposure

Factor family basis

A factor family is a set of one-hot factors, such as the sectors, whose exposures are collinear with a global factor. One member of each family is therefore redundant, and the fit changes the basis before it runs. factor_family_basis drops one member of each family and returns the change of basis, which varies over time. After the fit, the factor returns of the smaller basis expand back to one return per named factor.

Return forecasts

A return forecast is a prediction of the idiosyncratic return of each asset over the next period. return_forecast computes one from a return forecast estimator, which reads the descriptor scores and a fitted factor model, or takes a vector you state. Every fitted estimator starts from descriptor_scores. It winsorises and standardises each descriptor, can neutralise it against named factor exposures, and standardises it again. The forecast unit says what the descriptors forecast, the idiosyncratic return or the idiosyncratic Sharpe ratio. The estimator converts either one to a return.

Forecast evaluation

forecast_evaluation pairs each return forecast with the return it forecast, out of sample, and returns one result. Every statistic below is a function of that result. It accepts bare matrices as well as a fitted return forecast, so it scores a forecast from outside the library in the same way as one the library made.

Pair a Return Forecast with the forward target it is answerable for, out of sample. forecast_evaluation

  • The out-of-sample pairing of a Return Forecast with what happened next. ForecastEvaluationResult
  • Return the history of a Return Forecast Estimator, refitting the member if it computes none. forecast_history

The statistics of an evaluation, each a function of its result.

  • Return the information coefficients of a Return Forecast, one row per evaluation date. forecast_ic
  • Return the summary of the two information coefficient series of an evaluation, by name. forecast_ic_summary
  • Return the share of the universe an evaluation scored, one entry per evaluation date. forecast_coverage
  • Score the long-short portfolio that a Return Forecast states by itself. forecast_portfolio
  • Score the top-minus-bottom spread of a Return Forecast, one column per quantile. forecast_quantile_spread
  • Return the contemporaneous correlation of a Return Forecast against every factor exposure, one row per observation. forecast_factor_correlation
  • Score whether the magnitude of a Return Forecast is right, and not only its order. forecast_calibration

The same statistics over a range of forward windows, with every row computed on the same dates.

  • Score a Return Forecast against cumulative forward windows, one row per holding period. forecast_holding_period
  • Score a Return Forecast against disjoint forward windows, one row per period out. forecast_decay

A summary table with one row per forecast, which compares the forecasts.

The quantity the forecast is scored against.

  • Scores a Return Forecast against the forward idiosyncratic return. IdiosyncraticTarget
  • Scores a Return Forecast against the forward asset return. AssetReturnTarget
  • Scores a Return Forecast against the forward mean of a named numeric Panel Field. PanelFieldTarget

Moment estimation

Expected returns

Overloads Statistics.mean.

Shrinks the sample expected returns toward a target chosen by the shrinkage algorithm. ShrunkExpectedReturns

Algorithms

Targets, which every algorithm above accepts

Forecasts the next return of each asset as the move from the last price level to a statistic of a window of price levels. PriceLevelExpectedReturns

  • Averages the last window price levels, which is the forecast of the moving-average reversion of Li and Hoi (2012). MovingAverage
  • Averages the price levels with weights that fall exponentially with age, which is the forecast of the second form of the moving-average reversion of Li, Hoi, Sahoo and Liu (2015). ExponentialMovingAverage
  • Takes the spatial ($L_1$) median of the last window price levels, which is the forecast of the robust median reversion of Huang, Zhou, Li, Hoi and Zhou (2016). SpatialMedian
  • Takes the highest of the last window price levels, which is the forecast of the peak price tracking of Lai, Dai, Ren and Huang (2018). WindowPeak
  • Takes the price level lag observations ago, which is the forecast of the first form of the transaction-cost optimisation of Li, Wang, Huang and Hoi (2018). LaggedPrice
  • Averages the price levels with a weight per asset that depends on the data, which is the reweighted price relative of Lai, Yang, Fang and Wu (2020). ReweightedPriceRelative
  • 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). TruncatedExponentialMovingAverage
  • Averages two Gaussian-weighted estimates of the next price level, which is the forecast of the Gaussian weighting reversion of Cai and Ye (2019). GaussianWeightedDoubleEstimate

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. TrendSwitch

  • 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). PairwiseSlopeSum
  • 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). RegressionSlope
  • 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). CompositeTrend

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). KernelTrendPattern

  • 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. ElasticNetPath
  • Reads the mean of a Prior as an expected-returns vector, so that any me slot can hold a prior estimator. PriorExpectedReturns

Variance and standard deviation

Overloads Statistics.var and Statistics.std.

  • Computes the marginal variance and standard deviation, optionally weighted and optionally bias-corrected. SimpleVariance
  • Variance estimator that restricts computation to a rolling or indexed observation window. WindowedVariance

Covariance and correlation

Overloads Statistics.cov and Statistics.cor.

  • Adapts any StatsBase.CovarianceEstimator to the library's calling convention, carrying its observation weights alongside it. GeneralCovariance

Estimates the covariance matrix of asset returns from a centring estimator, a covariance estimator, and a moment algorithm. Covariance

  • Keeps every deviation from the target, so the moment is two-sided. FullMoment
  • Clips every deviation above the target to zero, so the moment reads the downside alone. SemiMoment

Configures and applies Gerber covariance estimators. GerberCovariance

  • Normalises the net co-movement vote by the observations on which both assets crossed their threshold. Gerber0
  • Normalises the net co-movement vote by every observation on which at least one asset crossed its threshold. Gerber1
  • Normalises the raw net co-movement vote by the geometric mean of its own diagonal. Gerber2

Configures and applies Smyth-Broby covariance estimators. SmythBrobyCovariance

  • Divides the difference of the concordant and discordant Smyth-Broby contribution sums by their sum. SmythBroby0
  • Divides the difference of the concordant and discordant Smyth-Broby contribution sums by their sum plus the neutral sum. SmythBroby1
  • Normalises the net Smyth-Broby contribution of a pair by the geometric mean of its own diagonal. SmythBroby2
  • Weights each Smyth-Broby contribution sum by its own observation count, then divides the difference by the sum. SmythBrobyGerber0
  • Weights each Smyth-Broby contribution sum by its own count, then divides the difference by the sum plus the neutral term. SmythBrobyGerber1
  • Weights each Smyth-Broby contribution sum by its own count, then normalises the net score by the geometric mean of its own diagonal. SmythBrobyGerber2
  • Counts concordant and discordant observations, discards the contribution sums, and divides their difference by their sum. SmythBrobyCount0
  • Counts concordant, discordant and neutral observations, discards the contribution sums, and divides the net count by the total. SmythBrobyCount1
  • Counts concordant and discordant observations, discards the contribution sums, and normalises the net count by the geometric mean of its own diagonal. SmythBrobyCount2

Gerber information quality covariance GerberIQCovariance, with a choice of estimator for the variance, the demeaning, the decay over time, and the numerator and the denominator

  • Measures linear and non-linear codependence from doubly-centred pairwise distance matrices. DistanceCovariance
  • Measures co-movement in the lower tail: the share of an asset's worst returns that fall on the same dates as another's. LowerTailDependenceCovariance

Rank covariances

  • Measures monotonic association with Kendall's tau, counting concordant against discordant pairs. KendallCovariance
  • Measures monotonic association with Spearman's rho, the Pearson correlation of the rank-transformed returns. SpearmanCovariance
  • Estimates the covariance of a short window as a rank-one matrix along the principal direction of its price relatives. RankOneCovariance

Measures codependence with mutual information, which captures a non-linear relationship a correlation misses. MutualInfoCovariance

Abstract supertype for all histogram binning algorithms based on a bin width selection rule. BinWidthBins

  • Histogram binning algorithm using the Hacine-Gharbi–Ravier rule. HacineGharbiRavier
  • Predefined number of bins

Shrinks a covariance matrix towards a target along the geodesic of the positive definite matrices. GeodesicShrinkageCovariance

Shrinkage targets

  • Targets the identity matrix, which ignores the scale of the matrix being shrunk. IdentityTarget
  • Targets the identity matrix scaled by the average variance, the target with condition number one. ScaledIdentityTarget
  • Targets a matrix with the average variance on the diagonal and the average covariance everywhere else. CommonCovarianceTarget
  • Targets a matrix that keeps the variances and gives every pair of assets the average correlation. ConstantCorrelationTarget

Covariance estimator based on implied volatility scaling. ImpliedVolatility

  • Implied volatility algorithm that divides the latest implied volatility by a volatility risk premium adjustment. ImpliedVolatilityPremium
  • Implied volatility algorithm that predicts realised volatility via regression on implied volatility. ImpliedVolatilityRegression

Exponentially weighted covariance and variance

  • Estimates a covariance matrix by an exponentially weighted recursion that holds a correlation on a holiday and resets on an inactive period. ExpWeightedCovariance
  • Estimates per-asset variance by an exponentially weighted recursion that freezes on a holiday and resets on an inactive period. ExpWeightedVariance

Regime-adjusted covariance and variance

Regime adjustment methods

  • Regime adjustment method that scales variance by the ratio of the mean absolute deviation of standardised returns to the first-moment normalisation constant x. FirstMomentRegimeAdjusted
  • Regime adjustment method that scales variance exponentially with the smoothed log-deviation of standardised squared returns from its expected value under stationarity. LogRegimeAdjusted
  • Regime adjustment method that scales variance by the square root of the mean of the standardised squared returns. RootMeanSquaredAdjusted

Shrinkage targets

  • Targets the diagonal of a covariance matrix, in a regime adjustment and in a geodesic shrinkage. DiagonalTarget
  • Regime-adjustment target that uses a Mahalanobis-distance-based baseline covariance structure. MahalanobisTarget
  • Regime-adjustment target that uses a portfolio-weighted baseline covariance structure. PortfolioTarget

Demeaning

  • Centres the returns series using the (weighted) mean before computing the Median Absolute Deviation. MeanCentering
  • Centres the returns series using the (weighted) median before computing the Median Absolute Deviation. MedianCentering

Correlation smoothing

  • Greedy pairwise correlation pruning: drop assets until no surviving pair exceeds t. PairwiseCorrelation
  • Group assets by connected component of the over-threshold correlation graph, and keep the best-scoring member of each. CorrelationComponents

Coskewness

Implements coskewness.

Estimates the coskewness tensor of a returns matrix, together with its negative spectral skewness matrix. Coskewness

  • Keeps every deviation from the target, so the moment is two-sided. FullMoment
  • Clips every deviation above the target to zero, so the moment reads the downside alone. SemiMoment
  • Coskewness estimator that restricts computation to a rolling or indexed observation window. WindowedCoskewness

Cokurtosis

Implements cokurtosis.

Estimates the square cokurtosis matrix of a returns matrix. Cokurtosis

  • Keeps every deviation from the target, so the moment is two-sided. FullMoment
  • Clips every deviation above the target to zero, so the moment reads the downside alone. SemiMoment
  • Cokurtosis estimator that restricts computation to a rolling or indexed observation window. WindowedCokurtosis

Windowed moments

Every windowed estimator wraps a base moment estimator and recomputes it over a subset of the observations. An integer window selects the last window observations, a vector selects the observations at those indices, and the default nothing selects them all.

Incremental fit

Some statistics have an exact update, in which the new value follows from a running state and one new observation. An estimator of such a statistic folds each new observation into its state, and it returns the statistic from the state without reading the sample again. The state is in the estimator's cache field. The sample mean, the sample variance and the full-moment sample covariance have an exact update. So do the FullMoment forms of Coskewness and Cokurtosis. The SemiMoment forms do not, because they clip each observation against a centre, and a new observation moves the centre.

Two functions fold an observation into the state. Each family of estimators implements partial_fit! as its fastest exact update, and the call can change the estimator you pass in. partial_fit returns a new estimator and leaves the one you pass in unchanged.

  • Folds observations into an estimator's partial-fit state, and returns the estimator. partial_fit!
  • Folds observations into a copy of an estimator's partial-fit state, and returns the estimator that carries the copy. partial_fit

An estimator of a statistic with no exact update keeps the observations it has seen instead, and it runs the batch computation over them to return the statistic. Online gives the estimator that store of observations. It applies once, at the warm-up before the first fold, and no Online wrapper remains in the estimator after that. Its max_history sets the largest number of observations the store keeps, and so the window of the fit. A wrapped estimator returns the batch statistic over the last max_history observations, and the scenario risk measures such as the conditional value at risk use the same rows. The store replaces the exact update of a statistic that has one, so the cap applies to it too. An estimator you leave unwrapped uses its exact update and stays fitted over every observation so far.

  • Declares that an estimator takes the online step from a buffer of the observations it has seen. Online

Coverage policy

By default, a moment estimator fits on the assets whose return is finite, and which the active mask of the AssetPanel marks as listed, at every observation of its window. This set of assets is the coverage universe. The rule keeps or drops each asset whole, so over an expanding window it can never admit an asset that lists after the first observation. A CoveragePolicy in the estimator's cvg field replaces the rule with available-case estimation, for that estimator alone. The estimator fits each entry of the result on the observations at which every asset of that entry is finite and active, and each entry has its own number of observations. An asset enters the result where its share of observations reaches min_coverage. The cvg field is nothing by default, and the estimator then fits on the coverage universe and writes NaN for every other asset.

The policy's alg field says what happens to an asset after it is delisted, with one type per rule. If your rule is none of the three below, write a new subtype of the family and implement its two functions, fold_inactive! and admits.

Fits each cell of a moment on the observations that cell has, instead of on the Coverage Universe. CoveragePolicy

  • Keeps a delisted asset's history, and drops the asset from the frame the moment it goes inactive. DecayCoverage
  • Throws a delisted asset's history away, so that a relisting starts the asset cold. ResetCoverage
  • Holds a delisted asset in the frame for a stated number of observations, then drops it. ExpireCoverage

Distance matrices

Implements distance and cor_and_dist.

  • Pairs a distance algorithm with an optional integer power, and applies it to a correlation matrix or to the data. Distance
  • Measures how differently two assets relate to the whole universe, by applying a metric to a distance matrix. DistanceDistance

Each distance estimator takes one of the distance matrix algorithms below.

  • Turns a signed correlation into a distance by $\sqrt{(1 - \rho) / 2}$. SimpleDistance
  • Turns the magnitude of a correlation into a distance by $\sqrt{1 - \lvert\rho\rvert}$. SimpleAbsoluteDistance
  • Turns the magnitude of a correlation into an unbounded distance by $-\log\lvert\rho\rvert$. LogDistance
  • Turns a non-negative codependence into a distance by $\sqrt{1 - \rho}$, without halving. CorrelationDistance

Measures the information one asset loses about another, from the entropies of a joint histogram. VariationInfoDistance

Abstract supertype for all histogram binning algorithms based on a bin width selection rule. BinWidthBins

  • Histogram binning algorithm using the Hacine-Gharbi–Ravier rule. HacineGharbiRavier
  • Predefined number of bins
  • Selects the distance algorithm that matches the covariance estimator it is given. CanonicalDistance

Feature distances

A feature matrix describes the assets by their exposures, memberships, loadings or adjacencies, not by their returns. A feature distance turns it into a distance matrix directly, with no correlation matrix between the two.

Turns a feature matrix into a distance matrix, by applying a metric to the rows of that matrix. FeatureDistance

Stack the Panel Fields a Feature Selector names into the Feature Matrix a distance measures. feature_matrix and feature_labels

The library derives the feature matrix from an AssetPanel each time it needs it, and stores it nowhere. feature_matrix stacks the panel fields that a selector names. feature_labels gives one label per column. A vector of labels is also a selector, so if you pass it back, it rebuilds the matrix that the distance measured.

Estimators that build the AssetPanel a distance measures

The ape field says which AssetPanel the metric measures. With nothing, the metric reads the panel that the returns data holds. An estimator below builds a static panel when the metric runs. RegressionPanel builds it from the prior result of the subproblem that runs it, and PhylogenyPanel from the returns of that subproblem. A view of the assets therefore leaves the estimator unchanged, and each fold of a cross-validation refits it.

  • Builds an Asset Panel that holds the factor loadings of the wrapped prior. RegressionPanel

Builds an Asset Panel that holds a square proximity matrix, graded from a graph or a partition. PhylogenyPanel and phylogeny_features

It grades the neighbourhood of each asset in a graph into a square assets × assets block of proximities. The distance then measures how much two neighbourhoods overlap. It is the one estimator here whose last axis is the asset axis. Its source is always an estimator, so every fold and every subproblem refits the graph on its own assets.

Phylogeny feature algorithm that scores each pair of assets by a decay of their separation. Proximity

phylogeny_matrix clamps each entry to zero or one, and so loses the number of steps between two assets. A proximity keeps that number and scores each pair by its separation. The decay sets how the score falls as the separation grows, and the sep of the source sets where the score stops. These are two settings because an exponential decay never reaches zero. No decay that the library ships gives zero inside the budget, so a zero entry means only that the pair is out of reach.

Separations, the open AbstractSeparationAlgorithm family, which separation_matrix and separation_budget apply

A NetworkEstimator holds it in its sep field. It says how far apart two assets are, and also how far is too far, because the two numbers have the same unit. It is a field of the network estimator and not of the panel estimator, because every user of a network needs to know which pairs it relates, and the constraints never see the panel estimator.

  • Separation measured as the number of graph edges between two assets. HopCount
  • PathLength sums the distances along the shortest path instead of counting its edges, and states its budget in the units of the distance estimator. With dmax = nothing the budget is the observed diameter of the graph

Budget rules, a callable in place of the budget number, which resolve_separation evaluates when the data is known

You cannot always state a budget in advance, because a cross-validation fold and a subproblem of a meta optimiser each refit the graph. In place of a number, the n field of HopCount takes a HopCountAlgorithm, and the dmax field of PathLength takes a PathLengthAlgorithm. Each is a callable struct, and either field also accepts a plain Function. A rule for a hop count must return an Integer. The library checks this when it evaluates the rule, because the return type of a callable is not part of its signature. A rule changes which quantity stays fixed. A stated budget keeps the radius fixed, and a quantile rule keeps the number of related pairs fixed.

  • HopCountQuantile sets the hop budget at a quantile of the observed hop separations, rounded to a whole number of hops, so the share of related pairs is near the requested share and not equal to it
  • PathLengthQuantile does the same in the units of the distance, with no rounding, so it reaches the requested share of related pairs. This is how you ask for a number of related pairs between two hop counts

Separation decays, the open AbstractSeparationDecayAlgorithm family, which separation_decay applies

A decay takes a real separation, so one family works for a hop count and for any continuous separation. A decay f must meet three conditions. f(0) is positive and is the largest value, f never increases, and f is not negative inside the budget. The library never assumes that f reaches zero. A fallback method checks a new decay against these conditions, and the decays that the library ships skip that check.

  • Separation decay falling off linearly to the edge of the budget. LinearDecay
  • Separation decay falling off exponentially. ExponentialDecay
  • Separation decay falling off as a power of the separation. ReciprocalDecay
  • NoDecay gives the same score to every pair inside the budget. The budget still applies, and the result is the indicator of the neighbourhood

Collapsing a window of time-varying features

  • Discards the window and measures the last observation's feature matrix alone. LastObservation

Collapses the window to one assets × features matrix, then applies the metric once. AggregateFeatures and AggregateDistances

  • Aggregates along the observation axis with the possibly weighted arithmetic mean. MeanCollapse
  • Aggregates along the observation axis with the possibly weighted median, which resists an outlying observation. MedianCollapse
  • Concatenates the window into one long feature vector per asset, so nothing is averaged away. StackObservations

Similarity matrices

A similarity matrix algorithm turns a distance matrix into a similarity matrix and reads nothing else. distance_to_similarity applies it. FeatureDistance picks one from its metric through default_similarity. The triangulated maximally filtered graph (TMFG) that DBHT and LoGo use takes its own.

The TMFG cannot take a negative weight. It therefore accepts only an AbstractNonNegativeSimilarityMatrixAlgorithm, and it throws an error at construction for AngularSimilarity. Two of the algorithms it accepts need a condition on the distance matrix, which assert_similarity_domain checks. ComplementSimilarity needs D <= 1, and MaximumDistanceSimilarity needs a finite D.

Phylogeny

PortfolioOptimisers.jl uses the relationships between assets in three ways. They drive the clustering optimisers, they constrain the weights, and they measure how related the assets of a portfolio are.

Clustering

Phylogeny constraints and the clustering optimisers cluster the assets through ClustersEstimator, Clusters and clusterise. Most of the clustering algorithms come from Clustering.jl.

Decides how many clusters to cut a dendrogram or a partition into. OptimalNumberClusters and VectorToScalarMeasure

  • Picks the number of clusters at which the within-cluster dispersion curve bends most sharply. SecondOrderDifference
  • Picks the number of clusters whose assets sit best inside their own cluster. SilhouetteScore
  • Predefined number of clusters.
  • Cut a dendrogram at the number of clusters onc selects. optimal_number_clusters
  • Get the vector of cluster indices for each point. assignments

Hierarchical

  • Builds a dendrogram by merging the two nearest clusters until one remains. HClustAlgorithm

Direct Bubble Hierarchical Trees DBHT and Local Global sparsification of the covariance matrix LoGo, logo!, and logo

Root selection

  • Takes one clique of the planar hierarchy as its single root. UniqueRoot
  • Builds one root from the adjacency tree of every root candidate. EqualRoot

Non-hierarchical

The hierarchical clustering optimisers cannot use a non-hierarchical clustering algorithm. Phylogeny constraints and NestedClustered can.

  • Partitions assets into k groups by Lloyd's algorithm, with no dendrogram. KMeansAlgorithm

Networks

Adjacency matrices

An adjacency matrix records which assets are related, from a clustering or from a graph. phylogeny_matrix computes it, and a PhylogenyResult holds it.

Network adjacency NetworkEstimator, with a choice of tree algorithm, covariance estimator and distance estimator

Triangulated maximally filtered graph, with a choice of similarity matrix algorithm

The graph accepts any AbstractNonNegativeSimilarityMatrixAlgorithm: MaximumDistanceSimilarity, ExponentialSimilarity, GeneralExponentialSimilarity or ComplementSimilarity. It does not accept AngularSimilarity, which returns a negative weight for every negative correlation, because a TMFG cannot take a negative weight.

The sep separation, which says which pairs count as related

HopCount relates every pair of assets within n edges of each other. PathLength relates every pair whose shortest path is no longer than dmax. A hop count can only add whole neighbourhoods at a time, and a path length reaches the numbers of related pairs between them. It does not put the pairs in a different order, because the graph already selects its edges by distance. A path length refines a hop count and does not compete with it. PathLength() with no dmax uses the observed diameter of the graph, so it relates every pair that is connected at all. That is the other extreme from HopCount(), whose default relates only direct neighbours. SemiDefinitePhylogenyEstimator and IntegerPhylogenyEstimator take either one. NetworkClustersEstimator takes only a hop count, because it sums the powers of the adjacency matrix, one power per edge.

Centrality and phylogeny measures

Centrality estimator CentralityEstimator, with a choice of centrality measure and of adjacency matrix estimator, from a clustering or from a network

Where it can, the centrality reads a weighted network, with the weights in the polarity that centrality_polarity returns for the algorithm

  • DistancePolarity for the shortest-path algorithms, which are betweenness, closeness, radiality and stress
  • SimilarityPolarity for eigenvector centrality, which reads the weighted adjacency matrix itself
  • TopologyOnly in the ov field of any of the five algorithms that declare a polarity, which removes the weights and computes the centrality on the topology of the network alone

Five cases run on the unweighted graph, and none of them throws an error. The first is a source with no weights, which is a ClustersEstimator, a precomputed Clusters or a precomputed PhylogenyResult. The others are DegreeCentrality, Pagerank, KatzCentrality, and EigenvectorCentrality on a tree network. The polarity says which weights an algorithm gets, and it never decides whether the call succeeds. The sep of a NetworkEstimator has no effect on the weighted computations, which read the edges of the network and not the pairs that sep relates. At the default HopCount(; n = 1) the two sets of pairs are the same.

The override works in one direction. It removes the weights and never adds them, so no value forces a polarity onto an algorithm. Every source accepts it, because a partition, a precomputed PhylogenyResult and a tree network already give the answer on the topology alone. Only the five algorithms that declare a polarity have the field. DegreeCentrality(; ov = TopologyOnly()) throws a MethodError, because the other three already read the topology alone. Every centrality function takes ct as a positional argument, so an algorithm you configure works with all of them. A CentralityEstimator holds only pl and ct.

  • Fallback no-op for returning a validated centrality vector result as-is. centrality_vector
  • Compute the weighted average centrality for a network and centrality algorithm. average_centrality
  • Compute the asset phylogeny score for a set of weights and a phylogeny matrix. asset_phylogeny

Cluster trees

Hierarchical clustering makes a tree of ClusterNodes. to_tree builds the tree, and pre_order and is_leaf walk it.

Optimisation constraints

The traditional optimisers, which build a JuMP problem, take the constraints below. The naive and clustering optimisers take weight bounds only. The entropy pooling priors take views, which are constraints on the posterior. You can state each constraint by hand, or derive its values from data with a type such as AbstractEstimatorValueAlgorithm or UniformValues.

You can state a constraint through its estimator, or directly as its result type. An estimator can name assets and groups of assets in key-value pairs. UniverseSets declares those assets and groups, and the library maps the names onto the assets with name_to_val! and replace_group_by_assets.

Factor exposure constraints ExposureConstraintEstimator

It wraps a linear constraint, an estimator of one, or a vector of those, and declares the AbstractConstraintSpace its rows are written in. You can then state a mandate in factor names, such as "at most 30% momentum", and the library maps it onto the assets through the loadings of the prior. The mapping happens when the library builds the constraints. The optimiser receives an ordinary LinearConstraint on the assets, and every optimiser built on JuMPOptimiser supports it. The factor names resolve against the factor axis that a UniverseSets declares.

  • The factor basis: a constraint written in factor names, re-based through a regression's loadings. FactorSpace

Budget constraints BudgetEstimator and BudgetRange

  • Charges the portfolio budget for transaction costs that grow linearly with the traded volume. BudgetCosts
  • Charges the portfolio budget and the return for market impact costs that follow an empirical power law. BudgetMarketImpact

Constraint values AbstractEstimatorValueAlgorithm

Where a constraint takes one value per asset or group, these algorithms derive the values from data in place of values you state.

  • Fills every entry of a value vector with 1/N, where N is the number of assets in the universe. UniformValues
  • Return one value per asset of the universe, from a mapping of asset names and group names to values. estimator_to_val
  • Algorithm for reducing a vector of real values to its minimum. MinValue
  • Algorithm for reducing a vector of real values to its maximum. MaxValue
  • Algorithm for reducing a vector of real values to its optionally weighted mean. MeanValue
  • Algorithm for reducing a vector of real values to its optionally weighted median. MedianValue
  • Algorithm for reducing a vector of real values to its mode. ModeValue
  • Algorithm for reducing a vector of real values to its sum. SumValue
  • Algorithm for reducing a vector of real values to its product. ProdValue
  • Algorithm for reducing a vector of real values to its optionally weighted standard deviation. StdValue
  • Algorithm for reducing a vector of real values to its optionally weighted variance. VarValue
  • Algorithm for reducing a vector of real values to its optionally weighted mean divided by its optionally weighted standard deviation. StandardisedValue
  • States that no fold-less value exists. NoDefault

Varies one optimiser input across the folds of a cross-validation scheme. TimeDependent

A time-dependent input takes a different value in each fold of a cross-validation scheme, and has no effect outside one.

Prior statistics

Many optimisations and constraints use prior statistics, which prior computes.

Carries the returns, mean and covariance a low order prior estimator produced. LowOrderPrior

  • Empirical prior estimator for asset returns. EmpiricalPrior
  • Factor-based prior estimator for asset returns. FactorPrior
  • Forecasts the next price relative and its covariance by averaging many low-dimensional lagged regressions, weighted by their in-sample fit. LowDimensionEnsemblePrior

Estimates a point-in-time cross-sectional factor model from an Asset Panel, and lifts it onto the assets. CrossSectionalFactorPrior

It is the cross-sectional counterpart of FactorPrior. It reads a point-in-time AssetPanel in place of a series of factor returns, and builds one factor exposure per named factor. At each observation it regresses the returns of the assets on their lagged exposures, and it returns a CrossSectionalFactorModel in the rr field. It uses the descriptors, the factor exposures, the cross-sectional regression, its weight policy and the factor family basis from the sections above. You can read the factors it will produce before any fit. cross_sectional_factor_axis returns the name of each factor and its family, from the estimator and the AssetPanel. cross_sectional_factor_sets writes those factors, and one group per family, into a UniverseSets. A factor mandate in a pipeline step then needs no list of one-hot levels typed by hand.

Black-Litterman

Reweights the observations of a prior so that its moments and its tails meet a set of views. EntropyPoolingPrior

Entropy pooling reweights the observations so that the posterior satisfies the views you state and stays as close as possible to the prior. It takes views on the moments, and also on the conditional, entropic and relativistic value at risk. Each view is a constraint of the one entropy pooling problem.

View constraint algorithms

  • Enforces every view in a single entropy pooling optimisation. H0_EntropyPooling
  • Enforces the views in stages, and starts every stage from the prior probabilities. H1_EntropyPooling
  • Enforces the views in stages, and starts every stage from the previous stage's probabilities. H2_EntropyPooling

Tail view formulations

View groups

A significance level belongs to a view, not to the estimator that holds the view. Each type below pairs a group of view equations with its significance level, and a tail view also with its formulation. One estimator can therefore state views at several levels. For the same reason, a relativistic view group holds its own deformation parameter.

  • A group of value at risk views, with the significance level they are read under. ValueatRiskView
  • A group of conditional value at risk views, with the significance level and formulation they are read under. ConditionalValueatRiskView
  • A group of entropic value at risk views, with the significance level and formulation they are read under. EntropicValueatRiskView
  • A group of relativistic value at risk views, with the significance level, the deformation parameter and the formulation they are read under. RelativisticValueatRiskView
  • Spans of the two searches that read a relativistic value at risk. RelativisticValueatRiskViewBracket

Divergence formulations

  • Evaluates the entropy pooling objective through the exponential of the dual variables. ExpEntropyPooling
  • Evaluates the entropy pooling objective in log space. LogEntropyPooling

Optimisers

Reweights the observations of a prior so that its moments meet a set of views, and root-finds a CVaR view. MeucciEntropyPoolingPrior

It is the earlier entropy pooling estimator. It searches for a conditional value at risk target with the recursive algorithm of Meucci, Ardia and Keel. Its views on the conditional value at risk must be equalities, one asset per view, and it solves the whole problem again for each candidate value at risk.

View constraint algorithms

Opinion pooling prior estimator for asset returns. OpinionPoolingPrior

Carries the coskewness and cokurtosis a high order prior estimator produced, over the low order prior it wraps. HighOrderPrior

Uncertainty sets

An uncertainty set on the expected returns or on the covariance makes an optimisation less sensitive to noise and to errors in the estimates. Any optimisation that uses one of the two quantities accepts a set on it. ucs, mu_ucs and sigma_ucs build the sets.

The first two shapes of set are a box and an ellipsoid.

EllipsoidalUncertaintySet and EllipsoidalUncertaintySetAlgorithm, with a choice of algorithm for the scaling parameter, which k_ucs computes

  • Fits the ellipsoid radius k empirically, as the 1 - q quantile of the Mahalanobis distances of the sampled estimation errors. NormalKUncertaintyAlgorithm
  • Computes the ellipsoid radius k as sqrt((1 - q) / q), the closed form that holds for any distribution of the estimation errors. GeneralKUncertaintyAlgorithm
  • Computes the ellipsoid radius k as the square root of the 1 - q chi-squared quantile, the closed form that holds when the estimation errors are normal. ChiSqKUncertaintyAlgorithm
  • Predefined scaling parameter

A third shape holds the worst-case variance of a covariance set as a quadratic penalty on the weights, so the optimisation stays a second-order cone programme and needs no semidefinite constraint.

  • Holds a worst-case variance penalty as a radius, a diagonal metric square root and a basis of the directions the penalty spares. CompactCovarianceUncertaintySet

A fourth shape is the image of a norm ball under a geometry map of any rank, for the expected returns or for the covariance. A set that is flat in the directions a factor model does not span then needs no full-rank shape matrix. An ellipsoid you already built converts to it with one Cholesky factorisation.

Several estimators build the sets. The next two build a box, an ellipsoid or a norm ball.

  • Fits a box or an ellipsoidal uncertainty set from the sampling laws that normal returns imply: the mean is normal and the covariance is Wishart. NormalUncertaintySet

Block bootstrap of the returns with the arch package, ARCHUncertaintySet

The next estimator builds a box only.

  • Fits a box uncertainty set by widening the prior statistics by a fixed fraction of their own absolute value. DeltaUncertaintySet

The library states a quintile portfolio as an uncertainty set on the characteristic vector, not as an optimiser of its own.

Fits an $\ell_1$ uncertainty set on the characteristic vector, mean-only and with a calibrated radius. CharacteristicUncertaintySet

One estimator reads no returns at all. It receives the fitted prior of its optimisation, and it limits both of its sets to the directions that the factor model of the prior does not span.

Fits both uncertainty sets from the factor model of the optimisation's own prior, confined to the directions the factors do not span. OrthogonalUncertaintySet

Orthogonality metrics, the cross-sectional weights under which the span of the factors is computed

Scalings of the set on the expected returns, in the directions the factors do not span

  • Gives every direction of the Orthogonal Subspace the same uncertainty, the default. IdentityScaling
  • Sizes each direction of the Orthogonal Subspace by the idiosyncratic covariance projected onto it. IdiosyncraticVarianceScaling

Rules that compute the radius of the covariance set from the sample and the factors, in place of a number you state

  • Sizes the compact radius from a chi-squared upper confidence bound on each idiosyncratic variance. ResidualInflation
  • Sizes the compact radius so that the penalty at a reference portfolio equals a stated fraction of its nominal variance. VarianceFraction

Axis tags of the ellipsoid and the norm ball

Turnover

The turnover is the absolute difference, asset by asset, between the current weights and a vector of benchmark weights. You can use it as a constraint, as the base of a fee, or as a risk measure. turnover_constraints, TurnoverEstimator and Turnover implement it.

Fees

Every optimisation except BudgetedHindsightPath can include fees, the naive ones too. A finite allocation takes them in its input, FiniteAllocationInput. calc_fees and calc_asset_fees compute the fees of a portfolio and of each asset, which you can subtract from the expected returns. The proportional and turnover rates apply in every period, and the two fixed amounts apply one time for the whole holding period. calc_total_fees and calc_total_asset_fees therefore give the cost over a horizon you state.

Names the per-asset fee rates, for fees_constraints to align to a universe. FeesEstimator and Fees

  • Proportional long
  • Proportional short
  • Fixed long
  • Fixed short
  • Turnover
  • Spreads the one-off terms of a fee, the fixed charges fl, fs and flq, evenly over a holding period. AmortisedFees
  • Charges the one-off terms of a fee, the fixed charges fl, fs and flq, on the first observation of a return series. FirstObservationFees

Portfolio returns and drawdowns

Many risk measures and analyses need the returns, the cumulative returns and the drawdowns of a portfolio, in total and per asset. calc_net_returns, calc_net_asset_returns, cumulative_returns and drawdowns compute them. calc_turnover computes the trading that a path of weights needs, which is the value of the quantity that Turnover bounds.

You can also score a window on the weights a fund holds, which move with the returns of their assets while no trade happens. The series is then the wealth ratio of those drifted holdings.

The realised series of a fold can also charge the two fixed fees on a schedule of its own. The scheme states that schedule in its fa field. It replaces the schedule of the fee itself, and it has no effect on the fit.

  • Grows each position at its own asset return and holds no trade in between, so the weights drift and the series is the wealth ratio of the drifted holdings. SelfFinancingDrift

Tracking

A tracking constraint keeps a portfolio close to a benchmark, which can be an index, an indicator or another portfolio.

Compute the benchmark portfolio returns for a weights-based tracking algorithm. tracking_benchmark and TrackingError

  • Carries the benchmark return series itself, for a benchmark whose weights are unknown. ReturnsTracking
  • Builds the benchmark return series by holding a fixed weight vector, net of its own fees. WeightsTracking

norm_error computes the error with one of the norms below.

Norm tracking algorithms

  • Norm-one (NOC) error formulation. L1Norm
  • Second-order cone (SOC) norm-based error formulation. L2Norm
  • Second-order cone (SOC) squared norm-based error formulation. SquaredL2Norm
  • L-p norm error estimator. LpNorm
  • L-infinity norm (maximum absolute deviation) error estimator. LInfNorm

The distance can also be a difference of risk, measured against a WeightsTracking benchmark, in place of a norm of the difference of returns. Two methods compute it.

Bounds how far the risk of a portfolio can move from the risk of a benchmark portfolio. RiskTrackingError

Risk measures

The sections below group the risk measures by the optimisations that accept them.

The fields of a risk measure that come from the prior, mu, sigma, kt and sk, take either the value or the estimator that computes it, a DeferredQuantity. The optimisation evaluates the estimator on its own prior, so the value is refitted in each cross-validation fold and in each subset of a meta optimiser. A matrix you pass in stays the same. A measure with two or more such fields can instead name one prior estimator in pe, and one fit then fills every field you leave empty.

Calibration

A tail probability and a deformation parameter also take a rule in place of the number. The field fixes the quantity and the end of the distribution, so you write only the rule. The optimisation evaluates the rule on its own prior, as it does a deferred estimator. The type of each field accepts the one family of rules that computes its quantity. It takes a callable estimator of that family, a plain function of (key, pr, w, slv, ctx), or the number. Five rules ship. Two compute a significance level, and three compute a deformation parameter. Forty fields over twenty-seven risk measures and weight builders take a rule, and they are every alpha and beta and every kappa, kappa_a and kappa_b. The two inner integration bounds of the tail Gini family, alpha_i and beta_i, are starting points and not quantities to estimate. They keep their numbers, and each fold checks the bound 0 < alpha_i < alpha < 1 against the calibrated alpha.

A significance rule reads the length of the sample. Where the count it states is a count of observations, it reads the effective weights of the observations. A deformation rule reads the probability of its own end of the distribution, which it gets in the CalibrationContext that the owner of the field builds. One deformation rule spends a stated entropy budget on the length of the sample. The other two estimate the tail index of the sample and return its reciprocal. One of them standardises each column and returns a value per end, so a skewed sample gives two numbers. The other whitens each observation with the covariance matrix and returns one number for both ends.

A rule that reads the shape of a series needs to know which series. A drawdown measure is computed on the drawdown series of the portfolio, not on its returns, and the key of the field does not say which. The measure therefore states its series in the CalibrationContext, beside the significance level. The two tail rules then read the drawdown series of each column in place of the column itself. The pooled rule pools those series. The radial rule whitens their rows with the covariance matrix of the same drawdown series, because a prior result holds no moment of the drawdowns. If you run a rule by hand, build the context with a series, such as AbsoluteDrawdownSeries(), as the measure would.

  • Computes a significance level from a count of observations, so that the tail keeps the same number of scenarios whatever the sample length becomes. ScenarioCount
  • Computes a significance level that shrinks with the square root of the sample length. RateSignificance
  • Computes the Kaniadakis deformation parameter that makes a relativistic measure spend a stated entropy budget. EntropyBudget
  • Computes the Kaniadakis deformation parameter whose tail decays at the rate the sample's own tail decays at. HillTailDecay
  • Computes the Kaniadakis deformation parameter whose tail decays at the rate the sample's radial series decays at. RadialTailDecay
  • Names the returns themselves, the columns of pr.X unchanged. ReturnsSeries
  • Names the absolute drawdown series of a column, which absolute_drawdown_vec builds. AbsoluteDrawdownSeries
  • Names the relative drawdown series of a column, which relative_drawdown_vec builds. RelativeDrawdownSeries

An ambiguity radius also takes a rule. A radius applies to no end of the distribution, so one type bound serves every radius field. The fields are the four regularisation coefficients of JuMPOptimiser and the radii of the distributionally robust risk measures. Four rules ship, and all four compute a radius. Two shrink the ball at the rate of the square root of the sample length. The third shrinks it at a rate that the number of assets sets, which is much slower over a wide universe.

  • Computes an ambiguity radius from the concentration of measure, so that the ball shrinks as the sample grows. ConcentrationRadius
  • Computes an ambiguity radius that shrinks with the square root of the sample length. RateRadius
  • Computes an ambiguity radius that shrinks at the dimensional rate a Wasserstein ball earns, not at the square-root rate. DimensionalRateRadius

Those three return the same number for every field, but the eight radius fields do not all measure distance in one norm. The fourth rule reads the key of the field, picks the ground metric that the field names, and returns the sampling error of the empirical measure in that metric. As a result, the l1 and linf coefficients of one optimiser get two different values.

  • Computes an ambiguity radius in the ground metric that the slot it stands in names, so that two slots of two different norms get two different numbers. DualNormRadius

The tail weight of an Esfahani-Kuhn loss has a family of its own. One rule ships for it, and it sets the tail term of the loss to a stated multiple of its mean term. A tail weight you state has no unit, but its effect depends on the scale of the sample, so one number gives a different trade-off at each sampling frequency. The rule reads the probability of its own field, which it gets in the same context.

  • Computes the Esfahani-Kuhn tail weight that prices the tail term of the loss at a stated multiple of its mean term. TailTermParity

A norm ceiling is a different quantity from a radius and has a family of its own. Neither family is accepted in the field of the other. A radius is the coefficient of a norm penalty in the objective. A ceiling bounds that norm in a constraint. The bound sets a floor on the effective number of assets. The three norm-constraint fields of JuMPOptimiser, l2c, lpc and linfc, take one. One rule ships. It keeps a stated fraction of the assets effective, so the floor changes with the assets of the prior. The order of the norm belongs to the constraint and not to the rule, so each constraint gives the rule its own order before the field is evaluated.

  • Computes a norm ceiling that holds a stated fraction of the universe effective, so that the floor refits whenever the universe changes. EffectiveAssetFloor

Risk measures for traditional optimisation

Each is a subtype of RiskMeasure. Every JuMP optimisation estimator that takes a risk measure accepts it, and so do hierarchical risk parity and hierarchical equal risk contribution.

Measures the portfolio variance, the quadratic form of the weights in a covariance matrix. Variance

Traditional optimisations also support:

  • Risk contribution

Formulations

  • Encodes the second moment as an explicit quadratic form in the risk expression. QuadRiskExpr
  • Encodes the second moment as the square of a second-order cone variable. SquaredSOCRiskExpr
  • Measures the portfolio standard deviation, the square root of the variance. StandardDeviation
  • Uncertainty set variance UncertaintySetVariance, which is the variance outside traditional optimisation

Represents a low-order moment risk measure. LowOrderMoment

Represents a second moment (variance or standard deviation) risk measure algorithm. SecondMoment

Second squared moments

  • Keeps every deviation from the target, so the moment is two-sided. FullMoment
  • Clips every deviation above the target to zero, so the moment reads the downside alone. SemiMoment

Traditional optimisation formulations

  • Encodes the second moment as an explicit quadratic form in the risk expression. QuadRiskExpr
  • Encodes the second moment as the square of a second-order cone variable. SquaredSOCRiskExpr
  • Encodes the second moment as a variable that a rotated second-order cone bounds. RSOCRiskExpr

Encodes the square root of the second moment as a second-order cone variable. SOCRiskExpr

  • Keeps every deviation from the target, so the moment is two-sided. FullMoment
  • Clips every deviation above the target to zero, so the moment reads the downside alone. SemiMoment

Represents the square root kurtosis risk measure. Kurtosis

  • Actual kurtosis

Traditional optimisers take the full or the semi kurtosis through the kt field, and the alg1 field sets which of these moments the risk computation from returns uses

  • Keeps every deviation from the target, so the moment is two-sided. FullMoment
  • Clips every deviation above the target to zero, so the moment reads the downside alone. SemiMoment

Traditional optimisation formulations

  • Encodes the second moment as an explicit quadratic form in the risk expression. QuadRiskExpr
  • Encodes the second moment as the square of a second-order cone variable. SquaredSOCRiskExpr
  • Encodes the second moment as a variable that a rotated second-order cone bounds. RSOCRiskExpr

Encodes the square root of the second moment as a second-order cone variable. SOCRiskExpr

  • Keeps every deviation from the target, so the moment is two-sided. FullMoment
  • Clips every deviation above the target to zero, so the moment reads the downside alone. SemiMoment

Represents the Negative Skewness risk measure. NegativeSkewness

Squared negative skewness

Traditional optimisers take the full or the semi skewness through the sk and V fields, and the moment algorithm of the coskewness estimator that fills them sets which one

  • Keeps every deviation from the target, so the moment is two-sided. FullMoment
  • Clips every deviation above the target to zero, so the moment reads the downside alone. SemiMoment

Traditional optimisation formulations

  • Encodes the second moment as an explicit quadratic form in the risk expression. QuadRiskExpr
  • Encodes the second moment as the square of a second-order cone variable. SquaredSOCRiskExpr
  • Encodes the square root of the second moment as a second-order cone variable. SOCRiskExpr
  • Composite risk measure combining variance, skewness, and kurtosis into a single expression. VarianceSkewKurtosis

Measures the Value-at-Risk (VaR), the loss that the portfolio exceeds with probability alpha. ValueatRisk

Traditional optimisation formulations

  • Computes the Value-at-Risk as the empirical quantile of the sample, through a mixed-integer programme. MIPValueatRisk
  • Computes the Value-at-Risk as a quantile of a parametric distribution, from the mean and the covariance of the asset returns. DistributionValueatRisk

Measures the Value-at-Risk Range, the spread between the loss quantile at alpha and the gain quantile at beta. ValueatRiskRange

Traditional optimisation formulations

  • Computes the Value-at-Risk as the empirical quantile of the sample, through a mixed-integer programme. MIPValueatRisk
  • Computes the Value-at-Risk as a quantile of a parametric distribution, from the mean and the covariance of the asset returns. DistributionValueatRisk

Ordered Weights Array

Risk measures

Traditional optimisation formulations

Callable weights, which the w field of an ordered weights array measure takes in place of a vector

Array functions

Linear moments (L-moments)

  • Compute the linear moment weights for the linear moments convex risk measure (CRM). owa_l_moment

Compute Ordered Weights Array (OWA) linear moment convex risk measure (CRM) weights using various estimation methods. owa_l_moment_crm

L-moment combination formulations

Represents the Maximum Entropy algorithm for Ordered Weights Array (OWA) estimation. MaximumEntropy

  • Represents the Minimum Squared Distance algorithm for Ordered Weights Array (OWA) estimation. MinimumSquaredDistance
  • Represents the Minimum Sum of Squares algorithm for Ordered Weights Array (OWA) estimation. MinimumSumSquares

Represents the Brownian Distance Variance (BDVar) risk measure. BrownianDistanceVariance

Traditional optimisation formulations

Distance matrix constraint formulations

Risk formulation

  • Encodes the second moment as an explicit quadratic form in the risk expression. QuadRiskExpr
  • Encodes the second moment as a variable that a rotated second-order cone bounds. RSOCRiskExpr

Measures the tracking error, a scaled norm of the gap between the net portfolio returns and a benchmark return series. TrackingRiskMeasure

  • Norm-one (NOC) error formulation. L1Norm
  • Second-order cone (SOC) norm-based error formulation. L2Norm
  • Second-order cone (SOC) squared norm-based error formulation. SquaredL2Norm
  • L-p norm error estimator. LpNorm
  • L-infinity norm (maximum absolute deviation) error estimator. LInfNorm

Risk tracking risk measure

  • Represents the Power Norm Value-at-Risk (PNVaR) risk measure. PowerNormValueatRisk
  • Represents the Power Norm Value-at-Risk Range (PNVaRRange) risk measure. PowerNormValueatRiskRange
  • Represents the Power Norm Drawdown-at-Risk (PNDaR) risk measure. PowerNormDrawdownatRisk
  • Represents a generic Value-at-Risk range risk measure that combines any pair of XatRisk-type measures applied to the loss and gain sides of the return distribution. GenericValueatRiskRange
  • Measures how far the risk of a portfolio is from the risk of a benchmark portfolio, under any risk measure. RiskTrackingRiskMeasure
  • Risk measure that contributes no risk. NoRisk

Risk measure settings

Every risk measure except RiskRatio holds a settings object in its settings field. A RiskMeasureSettings says whether the measure enters the objective, which upper bound constrains it, and its scale. A HierarchicalRiskMeasureSettings states only the scale. A MaxRiskMeasureSettings, which Skewness holds, states a lower bound in place of the upper one.

Risk measures for hierarchical optimisation

Each is a subtype of HierarchicalRiskMeasure, and only the hierarchical optimisation estimators accept it.

Represents a high-order moment risk measure. HighOrderMoment

Represents the unstandardised fourth moment (kurtosis or semi-kurtosis) risk measure algorithm. FourthMoment

  • Keeps every deviation from the target, so the moment is two-sided. FullMoment
  • Clips every deviation above the target to zero, so the moment reads the downside alone. SemiMoment

Represents a standardised high-order moment risk measure algorithm. StandardisedHighOrderMoment and FourthMoment

  • Keeps every deviation from the target, so the moment is two-sided. FullMoment
  • Clips every deviation above the target to zero, so the moment reads the downside alone. SemiMoment
  • Measures the Relative Drawdown-at-Risk, the compounded drawdown that the portfolio exceeds with probability alpha. RelativeDrawdownatRisk
  • Measures the Relative Conditional Drawdown-at-Risk, the average of the worst alpha fraction of the compounded drawdowns. RelativeConditionalDrawdownatRisk
  • Represents the Relative Entropic Drawdown-at-Risk (Relative EDaR) risk measure for hierarchical optimisation. RelativeEntropicDrawdownatRisk
  • Measures the Relative Relativistic Drawdown-at-Risk, the Relativistic Value-at-Risk of the compounded drawdown series, for hierarchical optimisation. RelativeRelativisticDrawdownatRisk
  • Represents the Relative Average Drawdown risk measure for hierarchical optimisation. RelativeAverageDrawdown
  • Represents the Relative Ulcer Index risk measure for hierarchical optimisation. RelativeUlcerIndex
  • Represents the Relative Maximum Drawdown risk measure for hierarchical optimisation. RelativeMaximumDrawdown
  • Represents the Relative Power Norm Drawdown-at-Risk (Relative PNDaR) risk measure for hierarchical optimisation. RelativePowerNormDrawdownatRisk
  • Represents a risk ratio risk measure for hierarchical portfolio optimisation. RiskRatio
  • Represents the Equal Risk Measure for hierarchical portfolio optimisation. EqualRisk
  • Represents the Median Absolute Deviation (MAD) risk measure for hierarchical portfolio optimisation. MedianAbsoluteDeviation

Non-optimisation risk measures

These risk measures can return a negative value, so no optimisation accepts them on their own. You can use them as performance metrics. Skewness enters an optimisation only as the skewness term of VarianceSkewKurtosis.

Performance metrics

Every function here that takes a risk measure also takes a vector of them. The sca keyword takes a Scalariser, which combines the vector into one number. All four scalarisers work here, MinScalariser included, because these functions combine numbers and build no model expression. A function that also reads a return takes one return term or a vector of them, and sums them at the weights of the terms. No scalariser applies to the returns. A result holds the risk measure and the scalariser of its optimisation, so expected_risk(res.r, res.w, res.pr; sca = res.sca) gives the optimised value and you name neither one.

  • Compute the expected value of a risk measure. expected_risk
  • Compute the effective number of assets of a portfolio, the inverse of the Herfindahl-Hirschman index of its weights. number_effective_assets

Risk contribution

  • Compute the contribution of each asset to the risk of a portfolio with a finite difference. risk_contribution
  • Compute the gradient of a risk measure with respect to the weights, with one entry for each asset. risk_gradient
  • Compute the contribution of each risk factor, and of the directions that no factor spans, to the risk of a portfolio. factor_risk_contribution

Factor attribution

factor_attribution splits the volatility and the mean return of a portfolio into four components, the systematic part, the idiosyncratic part, the part that the model does not explain, and the total, and returns one FactorAttributionResult. The result also breaks the portfolio down by factor, by factor family when the model names families, and by asset when you pass assets = true. The predicted methods read the moments that the optimiser used. The realised methods read a series of net returns, and each has a rolling version.

  • Decompose a portfolio's volatility and mean return over the factors of a factor model. factor_attribution and FactorAttributionResult
  • One row of a factor attribution: the volatility, the volatility contribution, the variance share, the mean return contribution and the correlation of one component of the portfolio return. AttributionComponent
  • The factor axis or the family axis of a factor attribution, one entry per row of the axis. AttributionBreakdown
  • The asset axis of a factor attribution, one entry per asset. AssetAttributionBreakdown
  • The asset-by-factor contributions of a factor attribution, two matrices of assets by factors. AssetFactorContribution

Compute the expected portfolio return using the specified return estimator. expected_return

Portfolio optimisation

optimise runs an optimisation. It takes an optimisation estimator and returns a result.

Naive

These return a NaiveOptimisationResult.

Naive optimisation features

Weight finalisers

  • Iteratively projects weights into the feasible region defined by weight bounds. IterativeWeightFinaliser
  • Moves weights into their bounds by the exact Euclidean projection, which needs no solver. EuclideanWeightFinaliser
  • Moves long-only weights into their bounds by the exact entropic projection, which needs no solver and keeps the ratios of the free weights. EntropicWeightFinaliser

Uses a JuMP optimisation model to enforce weight bounds. JuMPWeightFinaliser

Online portfolio selection

Online portfolio selection updates the weights after each new price relative, which is the price of each asset divided by its price one period before. Most of its rules need no solver. You choose a rule and hold it in OnlinePortfolioSelection. A batch fit runs the rule over every row of the window in order, from the start weights, and returns the weights for the next period. An online fit returns the weights the rule reached after its last update.

  • Updates its allocation from each realised price relative through the Online Selection Rule on alg. OnlinePortfolioSelection

Benchmark rules

  • Lets the allocation drift with the market and never trades it, the buy-and-hold benchmark of the online selection papers (BAH). BuyAndHold
  • Rebalances to the same allocation w after every price move, the constant rebalanced portfolio (CRP). ConstantRebalancedPortfolio

Follow-the-winner rules

Takes one mirror-descent step on the period's gradient, then projects the result back onto the Allocation Set. MirrorDescent

  • Steps to the Newton point of the log wealth of the past periods, the online Newton step (ONS) of Agarwal, Hazan, Kale and Schapire (2006). NewtonStep
  • Steps each asset at its own rate, set by the gradient mass that the asset has accrued (AdaGrad). AdaptiveSubgradient

Plays two half-steps of a first-order rule each period, the second along a hint for the gradient of the next period (OMD). OptimisticStep

  • Takes the last gradient as the hint of the optimistic step. LastGradient
  • Takes the running mean of the past gradients as the hint of the optimistic step. MeanGradient
  • Forms the hint of the optimistic step from a Price Relative Forecast. ForecastGradient
  • Moves the allocation a share eta of the way to the wealth held at the end of the period. ExpectationMaximisation
  • Builds Cover's (1991) universal portfolio as an expert mixture over n_experts constant rebalanced portfolios sampled from a Dirichlet prior on the simplex (UP). UniversalPortfolio
  • Builds the mixture of exponentiated-gradient experts under the weak aggregating algorithm, with a uniform prior. AggregatingExponentialGradient

Learning-rate schedules

  • Shrinks the learning rate with the square root of the period count, and needs no horizon. InverseSquareRootRate
  • Runs the rule in stages of growing length, and restarts it at the Start Allocation after the last period of each stage. DoublingTrickRate
  • Reads the learning rate from the running excess of each period's best asset over the played allocation. SelfConfidentRate
  • Sets the learning rate of an optimistic step from the hint residuals that the step has accrued. HintResidualRate
  • Chooses the learning rate of each period from a set of rates, by the recent wealth of one exponentiated-gradient run per rate. WindowedBestRate

Gradient transforms

  • Leaves the gradient unchanged, so the mirror step reads the period's gradient as it is. PlainGradient
  • Replaces the gradient with its exponential moving average, which gives the step a momentum. GradientMomentum
  • Divides the gradient by the root of a moving average of its square, per asset. RootMeanSquareGradient
  • Divides the moving average of the gradient by the root of the moving average of its square, per asset. AdaptiveMomentGradient

Follow-the-loser rules

Moves the allocation the least distance that brings the last period's gross return down to eps, the passive aggressive mean reversion (PAMR) of Li, Zhao, Hoi and Gopalkrishnan (2012). PassiveAggressiveMeanReversion

  • Takes the full step that brings the hinge loss of the period to zero, the step-length rule of PAMR. NoSlack
  • Caps the step of NoSlack at the aggressiveness C, the step-length rule of PAMR-1. LinearSlack
  • Softens the step of NoSlack by adding 1 / (2C) to its denominator, the step-length rule of PAMR-2. QuadraticSlack

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

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

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

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

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

  • Puts the whole budget on the asset with the largest Price Relative Forecast, and splits it in equal parts between tied assets. L1Optimum
  • Finds the fixed point of the alternating direction iteration of the short-term sparse portfolio in closed form. HuberOptimum
  • Runs the alternating direction iteration of the short-term sparse portfolio, and stops where the paper stops it. AlternatingDirectionMethod

Moves a Gaussian belief over the weights by the least relative entropy that puts the last return below eps with confidence. ConfidenceWeightedMeanReversion

  • Selects the confidence constraint that reads the variance of the belief along the price relative. VarianceUpdate
  • Selects the confidence constraint that reads the standard deviation of the belief along the price relative. StandardDeviationUpdate
  • Moves wealth from an asset that grew more to one whose log returns follow its own one window later. AntiCorrelation

Pattern-matching and solved rules

Re-solves an optimisation estimator on a sample of past periods at every step, the follow-the-leader rule. FollowTheLeader

  • Selects every period so far, the sample of follow the leader. Prefix
  • Selects the last W periods, the sample of the successive variable rebalanced portfolio. LastRows
  • Selects the periods whose preceding window falls in the same histogram cell as the latest window (BH). HistogramMatch
  • Selects the periods whose preceding window lies within radius of the latest window (BK). KernelMatch
  • Selects the periods whose preceding windows are the neighbours nearest to the latest window (BNN). NearestNeighbourMatch
  • Selects the periods whose preceding window correlates with the latest window at rho or more (CORN). CorrelationMatch
  • Selects the periods whose preceding window falls in the same cluster as the latest window (KMNLOG). ClusterMatch
  • Builds the short-term portfolio optimisation with loss control of Lai, Tan, Wu and Fang (2020) (SPOLC). ShortTermLossControlPortfolio
  • Builds the online low-dimension ensemble method of Xi, Li, Song and Ning (2023) (OLDEM). LowDimensionEnsemblePortfolio
  • The constraint that keeps each re-solve inside the allocation set, which is the set that every weight vector of the online estimator must lie in, AllocationSetConstraint

Meta-learning rules

Mixes the allocations of several expert rules, with weights that a second rule moves on the experts' returns. ExpertMixture

Weightings over the experts

  • Multiplies each weight by its price relative raised to the rate eta, then normalises the result. AggregatingAlgorithm
  • Holds the $k$ wealthiest assets, or experts, each weighted by its wealth. TopK
  • Weights each asset, or expert, by its prior times its wealth raised to a power that shrinks with the period. WeakAggregatingAlgorithm
  • Moves each weight to the other entries with probability $\gamma$ after the wealth step, the switching weighting of Singer (1997) (SP). SwitchingWeighting
  • Mixes copies of one rule started at different periods, with a fixed share for the newest copy (FLH). FollowTheLeadingHistory

Projection geometries

  • Projects the raw step onto the Allocation Set in squared Euclidean distance. EuclideanProjection
  • Projects the raw step onto the Allocation Set in relative entropy. EntropicProjection
  • Projects the raw step onto the Allocation Set in the Bregman divergence of the Tsallis potential of power alpha. TsallisProjection
  • Projects the raw step onto the Allocation Set in the Itakura–Saito divergence, the Bregman divergence of the Burg entropy. LogBarrierProjection
  • Projects the raw step onto the Allocation Set in the norm of the rule's Gram matrix. GramProjection

Allocation sets

  • Limits the allocation to the budget and to per-asset weight bounds, with closed-form projections and no solver. BoundedAllocationSet
  • Constrains an online allocation with every constraint kind of a JuMP optimiser, and projects onto the set with a solver. ProgrammeAllocationSet

Traditional

These optimisations build a JuMP problem through JuMPOptimiser, which holds every constraint they support.

Objective function optimisations

These optimisations take one of the objective functions below.

  • Configures one solver backend, its attributes, and the statuses its solutions must reach. Solver
  • Main JuMP-based portfolio optimiser configuration. JuMPOptimiser

Objective functions

Mean-Risk portfolio optimiser. MeanRisk and NearOptimalCentering

Sweeps the efficient frontier by solving the model once at each of N evenly spaced bound values. Frontier

  • Return based
  • Risk based

Bound spacing FrontierBoundEstimator

  • Passes bound values through unchanged (identity transformation). LinearBound
  • Applies a square-root transformation to bound values before enforcing them. SquareRootBound
  • Applies a squaring transformation to bound values before enforcing them. SquaredBound

Optimisation estimators

Near Optimal Centering formulations NearOptimalCentering

Risk budgeting optimisations

These optimisations find the weights at which each asset, or each factor, contributes the share of risk that a risk budget vector states.

Budget targets

Formulations

Optimisation estimators

Relaxed Risk Budgeting RelaxedRiskBudgeting returns a RelaxedRiskBudgetingResult

Traditional optimisation features

Budget

Directionality

  • Long
  • Short

Type

  • Exact
  • Bounds the sum of the portfolio weights inside a closed interval, rather than pinning it to one value. BudgetRange

Resolves a minimum-holding threshold written in asset or group names against a universe. ThresholdEstimator and Threshold

Directionality

  • Long
  • Short

Type

Cardinality

Portfolio returns

  • One return term, or a vector of them, summed at their weights into the return expression of the model
  • Carries one return term's own weight in the return sum, its own lower bound, and the two charges netted out of it. JuMPReturnsSettings

Arithmetic ArithmeticReturn

Risk vector scalarisation

  • Adds the scaled risk measures together. SumScalariser
  • Reports the largest of the scaled risk measures, so the aggregate is the worst of them. MaxScalariser
  • Smooths the maximum of the scaled risk measures, so every measure keeps a share of the aggregate. LogSumExpScalariser
  • Custom constraint
  • Number of effective assets

Regularisation penalty

Weight-norm constraints

A regularisation penalty puts a norm of the weights in the objective. These constraints bound the norm instead.

  • L2 (l2c)
  • Lp (lpc)
  • L-Inf (linfc)

Clustering optimisation

Clustering optimisations split the assets into clusters from their relationships, and optimise the clusters in a hierarchy or one at a time.

  • Holds the prior, the clustering, the bounds and the fees that a hierarchical optimiser shares with its siblings. HierarchicalOptimiser

Hierarchical clustering optimisation

These optimisations split the assets into a hierarchy of clusters, compute the risk of each cluster, and combine the clusters by the hierarchy.

Each result holds the risk measures and the scalarisers of its optimisation, after the optimisation resolved them. It holds its other fields in an embedded HierarchicalResult, which you reach as res.hr, or one field at a time as res.w, res.pr and so on.

Hierarchical clustering optimisation features

Risk vector scalarisation

  • The clustering optimisers accept every scalariser. A JuMP optimiser accepts every scalariser except MinScalariser.
  • Adds the scaled risk measures together. SumScalariser
  • Reports the largest of the scaled risk measures, so the aggregate is the worst of them. MaxScalariser
  • Smooths the maximum of the scaled risk measures, so every measure keeps a share of the aggregate. LogSumExpScalariser
  • Reports the smallest of the scaled risk measures, so the aggregate is the mildest of them. MinScalariser

Weight finalisers

  • Iteratively projects weights into the feasible region defined by weight bounds. IterativeWeightFinaliser
  • Moves weights into their bounds by the exact Euclidean projection, which needs no solver. EuclideanWeightFinaliser
  • Moves long-only weights into their bounds by the exact entropic projection, which needs no solver and keeps the ratios of the free weights. EntropicWeightFinaliser

Uses a JuMP optimisation model to enforce weight bounds. JuMPWeightFinaliser

Schur complementary optimisation

Schur complementary hierarchical risk parity interpolates between hierarchical risk parity and mean-variance optimisation through one parameter, gamma. At gamma = 0 it is hierarchical risk parity, and a larger gamma moves it towards mean variance. It adjusts the weights of each group of assets with the Schur complement of the covariance matrix, which puts back the covariance between the groups that hierarchical risk parity ignores.

Collects the risk measure, the interpolation parameter $\gamma$ and the two algorithms of one Schur complement bundle. SchurComplementParams

Schur complementary optimisation features

Weight finalisers

  • Iteratively projects weights into the feasible region defined by weight bounds. IterativeWeightFinaliser
  • Moves weights into their bounds by the exact Euclidean projection, which needs no solver. EuclideanWeightFinaliser
  • Moves long-only weights into their bounds by the exact entropic projection, which needs no solver and keeps the ratios of the free weights. EntropicWeightFinaliser

Uses a JuMP optimisation model to enforce weight bounds. JuMPWeightFinaliser

Nested clusters optimisation

Nested clustered optimisation splits the N assets into C clusters and optimises each cluster as a portfolio of its own. The inner weights go into an N × C matrix. Each column is one cluster, and it holds the weights of one synthetic asset. An asset has a non-zero weight only in the column of its own cluster. Each row of the matrix then holds one non-zero value, and each column holds as many non-zero values as its cluster has assets.

There are two ways to get the returns of the synthetic assets:

  1. Multiply the T × N matrix of asset returns by the N × C matrix of weights. The product is a T × C matrix of returns, where T is the number of observations.
  2. Run a cross-validation prediction for each cluster, which gives one vector of returns per cluster. Put the vectors side by side in a Y × C matrix, where Y ≤ T because the cross-validation can leave out part of the history.

The outer estimator optimises the synthetic assets on that matrix of returns, which gives a C × 1 vector of weights, one per cluster. The weights of the assets are the product of the N × C matrix and that C × 1 vector, an N × 1 vector.

Nested clusters optimisation features

Weight finalisers

  • Iteratively projects weights into the feasible region defined by weight bounds. IterativeWeightFinaliser
  • Moves weights into their bounds by the exact Euclidean projection, which needs no solver. EuclideanWeightFinaliser
  • Moves long-only weights into their bounds by the exact entropic projection, which needs no solver and keeps the ratios of the free weights. EntropicWeightFinaliser

Uses a JuMP optimisation model to enforce weight bounds. JuMPWeightFinaliser

  • Cross validation predictor for the outer estimator

Ensemble optimisation

Stacking works like nested clustered optimisation, but it does not split the assets. You give it a list of inner estimators, and each one optimises every asset. Each column of the N × C matrix then holds the weights of one inner estimator, so the matrix has no fixed pattern of zeros. The rest of the procedure is the same.

Ensemble optimisation features

Weight finalisers

  • Iteratively projects weights into the feasible region defined by weight bounds. IterativeWeightFinaliser
  • Moves weights into their bounds by the exact Euclidean projection, which needs no solver. EuclideanWeightFinaliser
  • Moves long-only weights into their bounds by the exact entropic projection, which needs no solver and keeps the ratios of the free weights. EntropicWeightFinaliser

Uses a JuMP optimisation model to enforce weight bounds. JuMPWeightFinaliser

  • Cross validation predictor for the outer estimator

Subset resampling optimisation

Subset resampling draws random subsets of the assets, as MultipleRandomised cross-validation does, and optimises each subset with the optimiser you give it. The weight of each asset is its mean weight over all subsets, with a weight of zero in each subset that does not hold it.

Subset resampling optimisation features

Weight finalisers

  • Iteratively projects weights into the feasible region defined by weight bounds. IterativeWeightFinaliser
  • Moves weights into their bounds by the exact Euclidean projection, which needs no solver. EuclideanWeightFinaliser
  • Moves long-only weights into their bounds by the exact entropic projection, which needs no solver and keeps the ratios of the free weights. EntropicWeightFinaliser

Uses a JuMP optimisation model to enforce weight bounds. JuMPWeightFinaliser

Finite allocation optimisation

A finite allocation turns the weights of another optimisation into whole numbers of shares, at the latest prices, with a stated amount of cash. Its answer is the allocation closest to those weights that the cash can buy, not an optimum of its own.

Discrete Allocation portfolio optimiser. DiscreteAllocation

Weight finalisers

  • Iteratively projects weights into the feasible region defined by weight bounds. IterativeWeightFinaliser
  • Moves weights into their bounds by the exact Euclidean projection, which needs no solver. EuclideanWeightFinaliser
  • Moves long-only weights into their bounds by the exact entropic projection, which needs no solver and keeps the ratios of the free weights. EntropicWeightFinaliser

Uses a JuMP optimisation model to enforce weight bounds. JuMPWeightFinaliser

Holds the target weights, prices and cash that a finite allocation reads. FiniteAllocationInput

Collateral algorithms

  • Pays for the long side of a finite allocation with the proceeds of its short sales. ProceedsCollateral
  • Caps the money that a finite allocation ties up at a collateral amount. CashCollateral

Cross validation

Split str into an array of substrings on occurrences of the delimiter(s) dlm. split and fit_and_predict

Walk forward WalkForwardEstimator returns a WalkForwardResult

  • Implements index-based walk-forward cross-validation for time series, supporting purging and flexible train/test windowing. IndexWalkForward and DateWalkForward
  • Hindsight split HindsightSplit trains each fold on its own test row, with the rows up to and including it or with that row alone. An estimator run through it is therefore a hindsight comparator for each row, an estimator fit on the row it is scored on
  • Online walk-forward OnlineIndexWalkForward, OnlineDateWalkForward and OnlineHindsightSplit wrap a scheme in Online. Each fold then updates one estimator with its new observations in place of a refit, and passes the estimator on to the next fold
  • Resume Resume continues an online walk-forward from its result over the longer history, and vcat joins the two results

A scheme scores each fold under an evaluation convention. SelfFinancingDrift scores the series of a fold on the weights the fund holds, not on the weights the optimiser chose, and the fold then holds a HeldWeightsResult. A walk-forward can also pass those held weights to the next fold.

  • Thread the weights a fold held after its last observation into the fold that follows it. DriftedWeights
  • Records what a fold actually held, so a reader can recover the weight path of that fold. HeldWeightsResult

Score every candidate of the grid of gscv on every fold of gscv.cv, and return the winner. search_cross_validation

Scoring a parameter set CrossValidationSearchScorer

Covariance forecast evaluation

covariance_forecast_evaluation scores the forecast of a covariance estimator, or of a prior, against the returns realised after it. It steps through a walk-forward. With a scheme that refits, each step refits the estimator, and with an online walk-forward, each step updates it. The evaluation centres the test rows on the location that the estimator forecasts, and it keeps the diagnostics of each step. The summary, the comparison and the re-projection are then functions of one result.

Evaluate a covariance forecast out of sample over a walk-forward, in batch or online. covariance_forecast_evaluation

The quantity the forecast is judged against.

  • Judges a covariance forecast against the realised covariance of the returns that follow it. RealisedCovariance
  • Judges a covariance forecast against the outer product of the return earned over the horizon. HorizonReturn

The functions of the result.

Log-wealth regret

log_wealth_regret reads two prediction results scored over the same rows. It returns the difference in log terminal wealth between a comparator and a strategy, the difference row by row, and a Newey-West test that the two have the same expected log growth. The comparator is any prediction result over the rows. It can be the same estimator run causally. It can also be a hindsight comparator, fit on the rows it is scored on and predicted in sample. Through a HindsightSplit the comparator changes from row to row, which gives the dynamic regret, and the result reports the path length of the comparator beside the regret. BudgetedHindsightPath is the best sequence of comparators whose path length stays within a budget. Its fit solves one programme over the whole panel, and its prediction result has one fold per row. Pass it as the comparator to read the regret at a given budget.

Pipeline

A Pipeline holds a whole workflow as one estimator. It is an ordered list of steps that run from left to right over a PipelineContext. The preprocessing, the priors and the optimiser then form one estimator, which you can cross-validate or tune as a unit.

Plotting

The plotting functions draw a portfolio, its history, its risk and the diagnostics of the models behind it. They are in a package extension, which loads when you load StatsPlots and GraphRecipes.

Simple or compound cumulative returns.

Portfolio composition.

  • Plot the composition of a portfolio as a bar chart of its asset weights. plot_composition

Several portfolios.

Risk contribution.

  • Plot the dendrogram of a hierarchical clustering, with one shaded region per cluster. plot_dendrogram
  • Plot the similarity matrix of a clustering as a heatmap in the order of the clustering, with a dendrogram on two sides and a box round each cluster. plot_clusters
  • Plot the cumulative returns of a portfolio above its drawdown, in two panels that share the time axis. plot_drawdowns
  • Plot the maximum drawdown of the portfolio over a rolling window, in percent, against the last date of each window. plot_rolling_drawdowns
  • Plot the histogram of the returns of a portfolio, with a vertical line for each of several statistics and an optional fitted Normal density. plot_histogram
  • Plot a scatter of two or three measures over a collection of portfolios, coloured by a fourth. plot_measures
  • Plot a risk or return measure of the portfolio returns over a rolling window, against the last date of each window. plot_rolling_measure
  • Plot a collection of portfolios as a line ordered by risk, coloured by a score, to trace an efficient frontier. plot_efficient_frontier
  • Plot the distribution of the weight of each asset over the folds of a path or the members of a population, as one box per asset. plot_weight_stability
  • Plot the turnover of a sequence of portfolios, the $L_1$ change of the weights from one portfolio to the next. plot_turnover
  • Plot the cumulative returns of a portfolio beside those of one or more benchmarks. plot_benchmark

Moments and priors

  • Plot the expected return of each asset as a bar chart. plot_mu
  • Plot the volatility of each asset, the square root of the diagonal of the covariance, as a bar chart. plot_sigma
  • Plot a correlation matrix as a heatmap, with no clustering and no dendrogram. plot_correlation
  • Plot the coskewness matrix, $N \times N^2$, of a HighOrderPrior as a heatmap on a diverging colour scale centred at zero. plot_coskewness
  • Plot the eigenvalues of the cokurtosis matrix, $N^2 \times N^2$, of a HighOrderPrior as a bar chart sorted from the largest, or the matrix itself as a heatmap. plot_cokurtosis
  • Plot the eigenvalues of a covariance or correlation matrix as a bar chart, sorted from the largest. plot_eigenspectrum
  • Plot a prior result as three panels side by side: the expected returns, the volatilities and the correlation. plot_prior

Factor models

Cross-sectional regression diagnostics

Cross-sectional exposure diagnostics

Cross-sectional idiosyncratic diagnostics

  • Plot the cross-sectional standard deviation of the standardised idiosyncratic returns against the observation axis. plot_idio_calibration
  • Plot the share of assets whose standardised idiosyncratic return exceeds a threshold, against the observation axis. plot_idio_tail_rate
  • Plot the cross-sectional excess kurtosis of the standardised idiosyncratic returns against the observation axis. plot_idio_kurtosis
  • Plot the cross-sectional skewness of the standardised idiosyncratic returns against the observation axis. plot_idio_skewness
  • Plot the information coefficient of the predicted idiosyncratic volatility against the observation axis. plot_idio_vol_ic
  • Plot the residual dependence of the standardised idiosyncratic returns on the predicted volatility, against the observation axis. plot_idio_vol_residual_dependence

Factor model summary and factor forecasts

Forecast evaluation

Phylogeny

  • Plot the network of the assets as a graph, with GraphRecipes.graphplot. plot_network
  • Plot the centrality score of each asset as a bar chart, sorted from the largest. plot_centrality

Cross validation

  • Plot the score of each fold or population member as a bar chart. plot_cv_scores
  • Plot a walk-forward path as four panels in a 2 × 2 layout: its fold compositions, its cumulative returns, its turnover and the stability of its weights. plot_cv_dashboard

Factor attribution

Dashboards

  • Plot one optimisation result as four panels in a 2 × 2 layout: its composition, its cumulative returns, its risk contributions and its drawdown. plot_portfolio_dashboard
  • Plot the performance statistics of a portfolio as a bar chart of eleven bars, blue at a value of zero or more and red below it. plot_performance_summary