| Type: | Package |
| Title: | Time-Varying Minimum Variance Portfolio |
| Version: | 1.0.5 |
| Date: | 2025-06-27 |
| Description: | Provides the estimation of a time-dependent covariance matrix of returns with the intended use for portfolio optimization. The package offers methods for determining the optimal number of factors to be used in the covariance estimation, a hypothesis test of time-varying covariance, and user-friendly functions for portfolio optimization and rolling window evaluation. The local PCA method, method for determining the number of factors, and associated hypothesis test are based on Su and Wang (2017) <doi:10.1016/j.jeconom.2016.12.004>. The approach to time-varying portfolio optimization follows Fan et al. (2024) <doi:10.1016/j.jeconom.2022.08.007>. The regularisation applied to the residual covariance matrix adopts the technique introduced by Chen et al. (2019) <doi:10.1016/j.jeconom.2019.04.025>. |
| License: | MIT + file LICENSE |
| URL: | https://github.com/erilill/TV-MVP |
| BugReports: | https://github.com/erilill/TV-MVP/issues |
| Encoding: | UTF-8 |
| Depends: | R (≥ 3.6.0) |
| Imports: | R6, cli, prettyunits, dplyr, ggplot2, tidyr |
| Suggests: | knitr, rmarkdown, testthat (≥ 3.0.0) |
| RoxygenNote: | 7.3.2 |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| NeedsCompilation: | no |
| Packaged: | 2025-06-27 15:24:41 UTC; erikl_xzy542i |
| Author: | Erik Lillrank |
| Maintainer: | Erik Lillrank <erik.lillrank@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2025-06-27 15:50:06 UTC |
TVMVP: Time-Varying Minimum Variance Portfolio Optimization
Description
The TVMVP package provides tools for estimating time-dependent covariance matrices using kernel-weighted principal component analysis. These estimates can then be used for portfolio optimization in a dynamic setting.
Details
The method involves five steps: (1) determining the number of factors, (2) estimating kernel-weighted PCA, (3) regularizing the idiosyncratic error covariance, (4) estimating the total covariance matrix, and (5) computing optimal portfolio weights.
An optional step includes a hypothesis test to check whether the covariance matrix is time-invariant.
The local PCA method, method for determining the number of factors, and associated hypothesis test are based on Su and Wang (2017). The approach to time-varying portfolio optimization follows Fan et al. (2024). The regularisation applied to the residual covariance matrix adopts the technique introduced by Chen et al. (2019).
The methodology implemented in this package closely follows Fan et al. (2024).The original authors provide a Matlab implementation at https://github.com/RuikeWu/TV-MVP.
The default kernel function in the package is the Epanechnikov kernel. Otherkernel functions can also be used, however these are not implemented in thepackage. In order to do this, write an R function with an integrablekernel function and use this as input in the functions with argumentkernel_func. It should be constructed ascustom_kernel <- function(u){...}.
Similarly, the bandwidth function which is implemented in the package is the Silverman's rule of thumb. For most functions, simply setbandwidthto your preferred bandwidth, however forexpanding_tvmvp,only Silverman's is implemented in this version of the package.
Authors and Maintainer
Authors: Erik Lillrank and Yukai Yang
Maintainer: Erik Lillrank
Department of Statistics, Uppsala University
erik.lillrank@gmail.com,yukai.yang@statistik.uu.se
Functions
determine_factorsSelects the optimal number of factors via an information criterion.
hyptestHypothesis test for time-invariant covariance matrices. Bootstrap p-values supported.
predict_portfolioOptimizes portfolio weights for out-of-sample prediction of portfolio performance.
expanding_tvmvpEvaluates MVP performance in a expanding window framework.
time_varying_covEstimates the time-varying covariance matrix.
silvermanSilverman's rule of thumb bandwidth formula.
Class
TVMVPTime Varying Minimum Variance Portfolio (TVMVP) Class.
References
Lillrank, E. (2025).A Time-Varying Factor Approach to Covariance Estimation
Su, L., & Wang, X. (2017). On time-varying factor models: Estimation and testing. Journal of Econometrics, 198(1), 84–101.
Fan, Q., Wu, R., Yang, Y., & Zhong, W. (2024). Time-varying minimum variance portfolio. Journal of Econometrics, 239(2), 105339.
Chen, J., Li, D., & Linton, O. (2019). A new semiparametric estimation approach for large dynamic covariance matrices with multiple conditioning variables. Journal of Econometrics, 212(1), 155–176.
Author(s)
Maintainer: Erik Lillrankerik.lillrank@gmail.com (ORCID)
Authors:
Yukai Yangyukai.yang@statistik.uu.se (ORCID)
See Also
Useful links:
Time Varying Minimum Variance Portfolio (TVMVP) Class
Description
This class implements a time-varying minimum variance portfolio using locallysmoothed principal component analysis (PCA) to estimate the time-dependentcovariance matrix.
This class provides a flexible interface to:
Set return data (
$set_data())Determine optimal number of factors (
$determine_factors())Conduct test of constant factor loadings (
$hyptest())Time-dependent covariance estimation (
$time_varying_cov())Portfolio optimization (
$predict_portfolio())Expanding window evaluation (
$expanding_tvmvp())Extract cached results (
$get_optimal_m(),$get_IC_values(),$get_bootstrap())
Looking for package description? SeeTVMVP-package.
Usage
# Initial object of class TVMVPtv <- TVMVP$new()# Set datatv$set_data(returns) # Returns must be T times p matrix# Determine number of factorstv$determine_factors(max_m=10)# Test for constant loadingstv$hyptest()# Estimate time-dependent covariance matrixcov <- tv$time_varying_cov()# Evaluate TVMVP performance on historical datamvp_results <- tv$expanding_tvmvp( initial_window = 60, rebal_period = 5, max_factors = 10, return_type = "daily") # Make out-of-sample prediction and compute weightspredictions <- tv$predict_portfolio(horizon=5, min_return = 0.01, max_SR = TRUE)# Extract weightspredictions$getWeights("MVP")#'
Arguments
- data
T × p(time periods by assets) matrix of returns.- bandwidth
Numerical. Bandwidth parameter used for local smoothing in the local PCA
- max_m
Integer. Maximum number of factors to be tested when determining the optimal number of factors.
- optimal_m
The optimal number of factors to use in covariance estimation.
Methods
$new(data = NULL)Initialize object of class TVMVP. Optionally pass returns matrix.
$set_data(data)Set the data. Must be
T × p(time periods by assets) matrix.$get_data()Get the data.
$set()Manually set arguments of the object.
$determine_factors()Determines optimal number of factors based on BIC-type information criterion.
$get_optimal_m{}Prints optimal number of factors,
optimal_m.$get_IC_values()Prints IC-values for the different number of factors tested using
determine_factors.$hyptest()Hypothesis test of constant loadings.
$get_bootstrap()Prints bootstrap test statistics from the hypothesis test.
$predict_portfolio()Optimizes portfolio weights for out-of-sample prediction of portfolio performance.
$expanding_tvmvp()Evaluates MVP performance in a expanding window framework.
$time_varying_cov()Estimates the time-varying covariance matrix.
$silverman()Silverman's rule of thumb bandwidth formula.
Adaptive Selection of the Shrinkage Parameter\rho for POET
Description
This function selects an optimal shrinkage parameter\rho for the residual covarianceestimation procedure. It does so by dividing the data into groups and comparing a shrunk covariancematrix (computed on one subsample) to a benchmark covariance (computed on another subsample) usingthe Frobenius norm. The candidate\rho that minimizes the total squared Frobenius norm differenceis selected.
Usage
adaptive_poet_rho( R, M0 = 10, rho_grid = seq(0.001, 2, length.out = 20), epsilon2 = 1e-06)Arguments
R | A numeric matrix of data (e.g., residuals) with dimensions |
M0 | Integer. The number of observations to leave out between two subsamples when forming groups.Default is 10. |
rho_grid | A numeric vector of candidate shrinkage parameters |
epsilon2 | A small positive tuning parameter used as an adjustment in the selection of |
Details
The function proceeds as follows:
The total number of observations
Tis halved to defineT_1andT_2. Specifically:T_1 = \left\lfloor \frac{T}{2} \times \left(1 - \frac{1}{\log(T)}\right) \right\rfloorT_2 = \left\lfloor \frac{T}{2} \right\rfloor - T_1The sample is divided into
\left\lfloor T/(2M_0) \right\rfloorgroups (withM_0observations left out in between).For each group, two subsamples are defined:
Subsample 1: the first
T_1observations of the group.Subsample 2: the last
T_2observations of the group, after skippingM_0observations following subsample 1.
For each group and a given candidate
\rhoinrho_grid, the covariance matrixS_1is computed from subsample 1, and then shrunk using soft-thresholding:S_{1,\text{shrunk}} = \text{soft\_threshold}\left(S_1, \rho \times \text{mean}\left(|S_1|_{\text{off-diag}}\right)\right)The total squared Frobenius norm between
S_{1,\text{shrunk}}and the covariance matrixS_2(from subsample 2) is computed across all groups.The function scans
rho_gridto find the\rhominimizing total error. Additionally, it computes\rho_1as\epsilon_2plus the smallest\rhofor which the smallest eigenvalue of the shrunk covariance is positive.
Value
A list containing:
best_rho: The selected optimal shrinkage parameter\hat{\rho}that minimizes the totalsquared Frobenius norm difference.rho_1: The lower bound for\rhoderived from the minimum eigenvalue criteria (adjusted byepsilon2).min_Fnorm: The minimum total squared Frobenius norm difference achieved.
Boundary Kernel Function
Description
This function computes boundary kernel weights for a given time periodt within a datasetof sizeT. It adjusts the kernel weights near the boundaries to account for edge effects,ensuring that the weights sum to one.
Usage
boundary_kernel(t, r, iT, h, kernel_func)Arguments
t | An integer specifying the current time period for which the kernel weights are computed. |
r | An integer representing the reference time period. |
iT | An integer indicating the total number of time periods in the dataset. |
h | A numeric value representing the bandwidth parameter for the kernel function. |
kernel_func | A function representing the kernel used for weighting. |
Details
The boundary kernel function adjusts kernel weights near the start and end of the dataset to mitigateedge effects commonly encountered in kernel-based methods. The function performs the following steps:
Scales the difference between the current time
tand reference timerby theproduct of total time periodsTand bandwidthh.Applies the kernel function to the scaled difference and adjusts by the bandwidth.
Determines if the current time period is within the lower or upper boundary regions based on
T_h = \lfloor T \times h \rfloor.Computes the integral of the kernel function over the adjusted limits to ensure the weightssum to one in boundary regions.
Value
A numeric scalar representing the boundary-adjusted kernel weight for the given time period.
Function to compute expected returns using a simple model selection approach
Description
Function to compute expected returns using a simple model selection approach
Usage
comp_expected_returns(returns, horizon)Arguments
returns | T times p matrix of returns |
horizon | Length of forecasting horizon |
ComputeB_{pT} Statistic for Covariance Time-Variation Hypothesis Testing
Description
This function calculates theB_{pT} statistic, which is part of the hypothesistesting procedure to determine whether the covariance matrix of asset returns is time-varying.It incorporates kernel-weighted local and global factor interactions along with residuals.
Usage
compute_B_pT(local_factors, global_factors, residuals, h, iT, ip, kernel_func)Arguments
local_factors | A list where each element is a numeric matrix representing thelocal factor scores for a specific time period. Each matrix should have |
global_factors | A numeric matrix of global factor scores with |
residuals | A numeric matrix of residuals with |
h | A numeric value indicating the bandwidth parameter for the kernel function. |
iT | An integer specifying the number of time periods. |
ip | An integer specifying the number of assets. |
kernel_func | A function representing the kernel used for weighting. Typically, anEpanechnikov kernel or another boundary kernel function. |
Details
The function performs the following steps:
Computes the sum of squared residuals for each time period
s.Constructs the kernel matrix
K[s,t]by applying theboundary_kernelfunction to each pair of time periods(s,t).Calculates the local dot-product matrix
L[s,t]as the dot product betweenthe local factors at timesandt.Computes the global dot-product matrix
G[s,t]as the dot product betweenthe global factors at timesandt.Computes the element-wise squared difference between
K * LandG,multiplies it by the residuals, and sums over alls,t.Scales the aggregated value by
\frac{\sqrt{h}}{T^2 \sqrt{p}}to obtainB_{pT}.
Value
A numeric scalarB_{pT} representing the computed statistic based onkernel-weighted factor interactions and residuals.
ComputeM_{\hat{}} Statistic for Covariance Time-Variation Hypothesis Testing
Description
This function calculates theM_{\hat{}} statistic, which measures the average squareddiscrepancy between local and global factor models across all assets and time periods.It quantifies the difference between locally estimated factors/loadings and their globalcounterparts.
Usage
compute_M_hat( local_factors, global_factors, local_loadings, global_loadings, iT, ip, m)Arguments
local_factors | A list where each element is a numeric matrix representing thelocal factor scores for a specific time period. Each matrix should have |
global_factors | A numeric matrix of global factor scores with |
local_loadings | A list where each element is a numeric matrix representing thelocal factor loadings for a specific time period. Each matrix should have |
global_loadings | A numeric matrix of global factor loadings with |
iT | An integer specifying the number of time periods. |
ip | An integer specifying the number of assets. |
m | An integer specifying the number of factors. |
Details
The function performs the following steps:
Initializes the
M_{\hat{}}statistic to zero.If the number of factors
mis equal to one, it ensures thatglobal_loadingsandglobal_factorsare treated as matrices.Iterates over each asset
i = 1toNand each time periodt = 1toT.For each asset and time period, computes:
common_H1: The dot product of the local loadings and local factors.common_H0: The dot product of the global loadings and global factors.The squared difference
(common\_H1 - common\_H0)^2and adds it toM_{\hat{}}.
After all iterations, normalizes
M_{\hat{}}by dividing by the product ofNandT.
Value
A numeric scalarM_{\hat{}} representing the average squared discrepancybetween local and global factor models across all assets and time periods.
ComputeV_{pT} Statistic for Covariance Time-Variation Hypothesis Testing
Description
This function calculates theV_{pT} statistic, which is part of the hypothesistesting procedure to determine whether the covariance matrix of asset returns is time-varying.It incorporates kernel-weighted factor interactions and residual correlations.
Usage
compute_V_pT(local_factors, residuals, h, iT, ip, kernel_func)Arguments
local_factors | A list where each element is a numeric matrix representing thelocal factor scores for a specific time period. Each matrix should have |
residuals | A numeric matrix of residuals with |
h | A numeric value indicating the bandwidth parameter for the kernel function. |
iT | An integer specifying the number of time periods. |
ip | An integer specifying the number of assets. |
kernel_func | A function representing the kernel used for weighting. Typically, anEpanechnikov kernel or another boundary kernel function. |
Details
The function performs the following steps:
Iterates over each pair of time periods
(s, r)wheres < r.Computes the two-fold convolution kernel value
\bar{K}_{sr}using thetwo_fold_convolution_kernelfunction.Calculates the squared dot product of local factors weighted by the factor covariancematrix.
Computes the squared dot product of residuals between time periods
sandr.Aggregates these values across all relevant time period pairs and scales by
\frac{2}{T^2 × p × h}to obtainV_{pT}.
Value
A numeric scalarV_{pT} representing the computed statistic based onkernel-weighted factor interactions and residual correlations.
Compute Sigma_0 p.93 Su and Wang (2017).
Description
Compute Sigma_0 p.93 Su and Wang (2017).
Usage
compute_sigma_0(res_set, iT, ip)Arguments
res_set | Residuals. |
iT | Number of time periods. |
ip | Number of assets. |
Value
Sigma_0 from page 93 in Su and Wang (2017).
Determine the Optimal Number of Factors via an Information Criterion
Description
This function selects the optimal number of factors for a local principal componentanalysis (PCA) model of asset returns. It computes an BIC-type information criterion (IC) for each candidatenumber of factors, based on the sum of squared residuals (SSR) from the PCA reconstruction and apenalty term that increases with the number of factors. The optimal number of factors is chosen as theone that minimizes the IC. The procedure is available either as a stand-alonefunction or as a method in the 'TVMVP' R6 class.
Usage
determine_factors(returns, max_m, bandwidth = silverman(returns))Arguments
returns | A numeric matrix of asset returns with dimensions |
max_m | Integer. The maximum number of factors to consider. |
bandwidth | Numeric. Kernel bandwidth for local PCA. Default is Silverman's rule of thumb. |
Details
Two usage styles:
# Function interfacedetermine_factors(returns, max_m = 5)# R6 method interfacetv <- TVMVP$new()tv$set_data(returns)tv$determine_factors(max_m = 5)tv$get_optimal_m()tv$get_IC_values()
When using the method form, if 'max_m' or 'bandwidth' are omitted,they default to values stored in the object. Results are cached andretrievable via class methods.
For each candidate number of factorsm (from 1 tomax_m), the function:
Performs a local PCA on the returns at each time point
r = 1,\dots,Tusingmfactors.Computes a reconstruction of the returns and the corresponding residuals:
\text{Residual}_r = R_r - F_r \Lambda_r,where
R_ris the return at timer, andF_rand\Lambda_rare the local factors and loadings, respectively.Computes the average sum of squared residuals (SSR) as:
V(m) = \frac{1}{pT} \sum_{r=1}^{T} \| \text{Residual}_r \|^2.Adds a penalty term that increases with
R:\text{Penalty}(m) = m × \frac{(p + T × \text{bandwidth})}{(pT × \text{bandwidth})} \log\left(\frac{pT × \text{bandwidth}}{(p + T × \text{bandwidth})}\right).The information criterion is defined as:
\text{IC}(m) = \log\big(V(m)\big) + \text{Penalty}(m).
The optimal number of factors is then chosen as the value ofm that minimizes\text{IC}(m).
Value
A list with:
optimal_m: Integer. The optimal number of factors.IC_values: Numeric vector of IC values for each candidatem.
References
Su, L., & Wang, X. (2017). On time-varying factor models: Estimation and testing. Journal of Econometrics, 198(1), 84–101.
Examples
set.seed(123)returns <- matrix(rnorm(100 * 30), nrow = 100, ncol = 30)# Function usageresult <- determine_factors(returns, max_m = 5)print(result$optimal_m)print(result$IC_values)# R6 usagetv <- TVMVP$new()tv$set_data(returns)tv$determine_factors(max_m = 5)tv$get_optimal_m()tv$get_IC_values()Epanechnikov Kernel Function
Description
This function computes the value of the Epanechnikov kernel for a given inputu.The Epanechnikov kernel is a popular choice in kernel density estimation due to its optimalproperties in minimizing mean integrated squared error.
Usage
epanechnikov_kernel(u)Arguments
u | A numeric vector of points at which the kernel is evaluated. |
Details
The Epanechnikov kernel is defined as:
K(u) = \begin{cases}\frac{3}{4}(1 - u^2) & \text{if } |u| \leq 1, \\0 & \text{otherwise}.\end{cases}
This function applies the above formula to each element of the input vectoru.
Value
A numeric vector of kernel values corresponding to each inputu.
Examples
# Define a range of u valuesu_values <- seq(-1.5, 1.5, by = 0.1)# Compute Epanechnikov kernel valueskernel_values <- epanechnikov_kernel(u_values)Estimate Local Covariance
Description
This internal function computes a time-varying covariance matrix estimate for a givenwindow of asset returns by combining factor-based and sparse residual covariance estimation.It uses results from a local PCA to form residuals and then applies an adaptive thresholdingprocedure (viaadaptive_poet_rho()) to shrink the residual covariance.
Usage
estimate_residual_cov_poet_local( localPCA_results, returns, M0 = 10, rho_grid = seq(0.005, 2, length.out = 30), floor_value = 1e-12, epsilon2 = 1e-06)Arguments
localPCA_results | A list containing the results from local PCA, with components:
|
returns | A numeric matrix of asset returns with dimensions |
M0 | Integer. The number of observations to leave out between the two sub-samples in the adaptive thresholding procedure. Default is 10. |
rho_grid | A numeric vector of candidate shrinkage parameters |
floor_value | A small positive number specifying the lower bound for eigenvalues in the final positive semidefinite repair. Default is |
epsilon2 | A small positive tuning parameter for the adaptive thresholding. Default is |
Details
The function follows these steps:
**Local Residuals:**Extract the local loadings
\Lambda_tfrom the last element oflocalPCA_results\$loadingsandfactors\hat{F}fromlocalPCA_results\$f_hat. Letw_tdenote the corresponding kernel weights.The local residuals are computed as:U_{\text{local}} = R - F \Lambda_t,where
Ris the returns matrix.**Adaptive Thresholding:**The function calls
adaptive_poet_rho()onU_{\text{local}}to select an optimal shrinkage parameter\hat{\rho}_t.**Residual Covariance Estimation:**The raw residual covariance is computed as:
S_{u,\text{raw}} = \frac{1}{T} U_{\text{local}}^\top U_{\text{local}},and a threshold is set as:
\text{threshold} = \hat{\rho}_t × \text{mean}(|S_{u,\text{raw}}|),where the mean is taken over the off-diagonal elements.Soft-thresholding is then applied to obtain the shrunk residual covariance matrix
\hat{S}_u.**Total Covariance Estimation:**The final covariance matrix is constructed by combining the factor component with the shrunk residual covariance:
\Sigma_R(t) = \Lambda_t \left(\frac{F^\top F}{T}\right) \Lambda_t^\top + \hat{S}_u.**PSD Repair:**A final positive semidefinite repair is performed by flooring eigenvalues at
floor_valueand symmetrizing the matrix.
Value
A list containing:
best_rho: The selected shrinkage parameter\hat{\rho}_tfor the local residual covariance.residual_cov: The shrunk residual covariance matrix\hat{\Sigma}_e(T).total_cov: The final estimated time-varying covariance matrix\Sigma_R(t).loadings: The local factor loadings\Lambda_tfrom the local PCA.naive_resid_cov: The raw (unshrunk) residual covariance matrix.
#' Expanding Window Time-Varying Minimum Variance Portfolio Optimization
Description
This function performs time-varying minimum variance portfolio (TV-MVP) optimization usingtime-varying covariance estimation based on Local Principal Component Analysis (Local PCA). Theoptimization is performed over a Expanding window, with periodic rebalancing.The procedure is available either as a stand-alone function or as a method inthe 'TVMVP' R6 class.
Usage
expanding_tvmvp( obj, initial_window, rebal_period, max_factors, return_type = "daily", kernel_func = epanechnikov_kernel, rf = NULL, M0 = 10, rho_grid = seq(0.005, 2, length.out = 30), floor_value = 1e-12, epsilon2 = 1e-06)Arguments
obj | An object of class TVMVP with the data. |
initial_window | An integer specifying the number of periods used in the initial estimation window. |
rebal_period | An integer specifying the number of periods between portfolio rebalancing (e.g., weekly, monthly). |
max_factors | An integer indicating the maximum number of latent factors to consider in the factor model. |
return_type | A string indicating the return frequency. Options: '"daily"', '"weekly"', or '"monthly"'. Used for annualization of evaluation metrics. |
kernel_func | A kernel function to be used in the local PCA procedure. Default is 'epanechnikov_kernel'. |
rf | A numeric vector or single value representing the risk-free rate. If 'NULL', it defaults to zero. |
M0 | An integer specifying the number of observations to leave out between the two sub-samples for the adaptive thresholding of the residual covariance estimation. |
rho_grid | A numeric sequence specifying the grid of rho values for threshold selection in covariance shrinkage. Default is 'seq(0.005, 2, length.out = 30)'. |
floor_value | A small positive value to ensure numerical stability in the covariance matrix. Default is '1e-12'. |
epsilon2 | A small positive value used in the adaptive thresholding of the residual covariance estimation. Default is '1e-6'. |
Details
Two usage styles:#'
# Function interfaceresults <- expanding_tvmvp( obj = tv, initial_window = 50, rebal_period = 20, max_factors = 3, return_type = "daily", rf = NULL)# R6 method interfacetv <- TVMVP$new()tv$set_data(returns)results <- tv$expanding_tvmvp( initial_window = 50, rebal_period = 20, max_factors = 3, return_type = "daily", rf = NULL)
The function implements a Expanding time-varying PCA approach to estimate latent factor structuresand uses a sparse residual covariance estimation method to improve covariance matrix estimation.The covariance matrix is used to determine the global minimum variance portfolio (MVP), which isrebalanced periodically according to the specified 'rebal_period'. The number of factors isdetermined by a BIC-type information criterion using the function 'determine_factors', updatedyearly. The bandwidth is determined by Silverman's rule of thumb, updated each rebalancing period.
If 'rf' is 'NULL', the risk-free rate is assumed to be zero.
Value
An R6 object of classExpandingWindow with the following accessible elements:
summaryA data frame of summary statistics for the TV-MVP and equal-weight portfolios, including cumulative excess return (CER), mean excess returns (MER), Sharpe ratio (SR), and standard deviation (SD) (raw and annualized).
TVMVPA list containing rebalancing dates, estimated portfolio weights, and excess returns for the TV-MVP strategy.
EqualA list with similar structure for the equal-weight portfolio.
References
Lillrank, E. (2025).A Time-Varying Factor Approach to Covariance Estimation
Fan, Q., Wu, R., Yang, Y., & Zhong, W. (2024). Time-varying minimum variance portfolio. Journal of Econometrics, 239(2), 105339.
Examples
# Generate random returns for 20 assets over 100 periodsset.seed(123)returns <- matrix(rnorm(20*100), nrow = 100, ncol = 20)# Initialize objecttv <- TVMVP$new()tv$set_data(returns)# Run Expanding TV-MVP optimizationresults <- expanding_tvmvp( obj = tv, initial_window = 50, rebal_period = 20, max_factors = 3, return_type = "daily", kernel_func = epanechnikov_kernel, rf = NULL)# R6 method interfaceresults <- tv$expanding_tvmvp( initial_window = 50, rebal_period = 20, max_factors = 3, return_type = "daily", rf = NULL)# Print summaryprint(results)# Plot cumulative log excess returnsplot(results)the function will return the size of objand it is smart in the sense that it will choose the suitable unit
Description
the function will return the size of objand it is smart in the sense that it will choose the suitable unit
Usage
get_object_size(obj)Arguments
obj | Object |
Test for Time-Varying Covariance via Local PCA and Bootstrap
Description
This function performs a hypothesis test for time-varying covariance in asset returns based on Su and Wang (2017).It first standardizes the input returns and then computes a time-varying covariance estimatorusing a local principal component analysis (Local PCA) approach. The test statisticJ_{pT}is computed and its significance is assessed using a bootstrap procedure. The procedure is available either as a stand-alonefunction or as a method in the 'TVMVP' R6 class.
Usage
hyptest(returns, m, B = 200, kernel_func = epanechnikov_kernel)Arguments
returns | A numeric matrix of asset returns with dimensions |
m | Integer. The number of factors to extract in the local PCA. See |
B | Integer. The number of bootstrap replications to perform. Default is 200 |
kernel_func | Function. A kernel function for weighting observations in the local PCA. Default is |
Details
Two usage styles:
# Function interfacehyptest(returns, m=2)# R6 method interfacetv <- TVMVP$new()tv$set_data(returns)tv$determine_factors(max_m=5)tv$hyptest()tvtv$get_bootstrap() # prints bootstrap test statistics
When using the method form, if 'm' are omitted,they default to values stored in the object. Results are cached andretrievable via class methods.
The function follows the steps below:
Standardizes the returns.
Computes the optimal bandwidth using the Silverman rule.
Performs a local PCA on the standardized returns to extract local factors and loadings.
Computes a global factor model via singular value decomposition (SVD) to obtain global factors.
Calculates residuals by comparing the local PCA reconstruction to the standardized returns.
Computes a test statistic
J_{pT}based on a function of the residuals and covariance estimates as:\hat{J}_{pT} = \frac{T p^{1/2} h^{1/2} \hat{M} - \hat{\mathbb{B}}_{pT}}{\sqrt{\hat{\mathbb{V}}_{pT}}},where:
\hat{M} = \frac{1}{pT} \sum_{i=1}^p \sum_{t=1}^T \left(\hat{\lambda}_{it}' \hat{F}_t - \tilde{\lambda}_{i0}' \tilde{F}_t\right),\hat{\mathbb{B}}_{pT} = \frac{h^{1/2}}{T^2 p^{1/2}} \sum_{i=1}^p \sum_{t=1}^T \sum_{s=1}^T \left(k_{h,st} \hat{F}_s' \hat{F}_t - \tilde{F}_s' \tilde{F}_t\right)^2 \hat{e}_{is}^2,and
\hat{\mathbb{V}}_{pT} = \frac{2}{p h T^2} \sum_{1\leq s \neq r \leq T} \bar{k}_{sr}^2 \left(\hat{F}_s' \hat{\Sigma}_F \hat{F}_r \right)^2 \left(\hat{e}_r' \hat{e}_s \right)^2.A bootstrap procedure is then used to compute the distribution of
J_{pT}and derive a p-value.
The function prints a message indicating the strength of evidence for time-varying covariance based on the p-value.
Value
A list containing:
J_NT | The test statistic |
p_value | The bootstrap p-value, indicating the significance of time variation in covariance. |
J_pT_bootstrap | A numeric vector of bootstrap test statistics from each replication. |
References
Su, L., & Wang, X. (2017). On time-varying factor models: Estimation and testing. Journal of Econometrics, 198(1), 84–101
Examples
# Simulate some random returns (e.g., 100 periods, 30 assets)set.seed(123)returns <- matrix(rnorm(100*30, mean = 0, sd = 0.02), nrow = 100, ncol = 30)# Test for time-varying covariance using 3 factors and 10 bootstrap replicationstest_result <- hyptest(returns, m = 3, B = 10, kernel_func = epanechnikov_kernel)# Print test statistic and p-valueprint(test_result$J_NT)print(test_result$p_value)# Or use R6 method interfacetv <- TVMVP$new()tv$set_data(returns)tv$determine_factors(max_m=5)tv$hyptest(iB = 10, kernel_func = epanechnikov_kernel)tvtv$get_bootstrap() # prints bootstrap test statisticsPerform Local PCA Over Time
Description
This function performs a local principal component analysis (PCA) on asset returns for each time period, aggregating the results over time. It calls an internal functionlocal_pca() at each time index to extract local factors, loadings, and one-step-ahead factor estimates, and stores these results in lists. It uses previously computed factors to align the sign of the new factors.
Usage
localPCA(returns, bandwidth, m, kernel_func = epanechnikov_kernel)Arguments
returns | A numeric matrix of asset returns with dimensions |
bandwidth | Numeric. The bandwidth parameter used in the kernel weighting for the local PCA. |
m | Integer. The number of factors to extract. |
kernel_func | Function. The kernel function used for weighting observations. Default is |
Details
The function processes the input returns overT time periods by iteratively calling thelocal_pca() function. For each timet_i:
Kernel weights are computed using the specified
kernel_funcandbandwidth.The returns are weighted by the square root of these kernel weights.
An eigen decomposition is performed on the weighted returns' covariance matrix to extract the top
meigenvectors, which are scaled by sqrt(T) to form the local factors.The signs of the new factors are aligned with those of the previous factors.
The factor loadings are computed by projecting the weighted returns onto the local factors, normalized by
T.A second pass computes a one-step-ahead factor estimate for the current time period.
Value
A list with the following components:
factors: A list of lengthT, where each element is aT × mmatrix of local factors.loadings: A list of lengthT, where each element is ap × mmatrix of factor loadings.m: The number of factors extracted.weights: A list of lengthT, where each element is a vector of kernel weights used at that time point.f_hat: AT × mmatrix of one-step-ahead factor estimates.
References
Su, L., & Wang, X. (2017). On time-varying factor models: Estimation and testing. Journal of Econometrics, 198(1), 84–101.
Perform Local Principal Component Analysis
Description
This function performs a local principal component analysis (PCA) on asset returns,weighted by a specified kernel function. It extracts local factors and loadings from the weightedreturns and computes a factor estimate. Optionally, previously estimated factors canbe provided to align the new factors' directions.
Usage
local_pca(returns, r, bandwidth, m, kernel_func, prev_F = NULL)Arguments
returns | A numeric matrix of asset returns with dimensions |
r | Integer. The current time index at which to perform the local PCA. |
bandwidth | Numeric. The bandwidth used in the kernel weighting. |
m | Integer. The number of factors to extract. |
kernel_func | Function. The kernel function used for weighting observations (e.g., |
prev_F | Optional. A numeric matrix of previously estimated factors (with dimensions |
Details
The function operates in the following steps:
**Kernel Weight Computation:** For each time point
t = 1, \dots, T, the kernel weight is computed usingboundary_kernel(r, t, T, bandwidth, kernel_func). The weighted returns are given byX_r = \text{returns} \circ \sqrt{k_h},where
\circdenotes element-wise multiplication andk_his the vector of kernel weights.**Eigen Decomposition:** The function computes the eigen decomposition of the matrix
X_r X_r^\topand orders the eigenvalues indescending order. The topmeigenvectors are scaled by\sqrt{T}to form the local factors:\hat{F}_r = \sqrt{T} \, \text{eigvecs}_{1:m}.**Direction Alignment:** If previous factors (
prev_F) are provided, the function aligns the signs of the new factors with the previous ones by checking the correlation and flipping the sign if the correlation is negative.**Loadings Computation:** The loadings are computed by projecting the weighted returns onto the factors:
\Lambda_r = \frac{1}{T} X_r^\top \hat{F}_r,where the result is transposed to yield a
p × mmatrix.**One-Step-Ahead Factor Estimation:** A second pass computes the factor estimate for the current time index
rby solving\hat{F}_r = \left(\Lambda_r^\top \Lambda_r\right)^{-1} \Lambda_r^\top R_r,where
R_ris the return vector at timer.
Value
A list with the following components:
factors: AT × mmatrix of local factors estimated from the weighted returns.f_hat: A1 × mvector containing the factor estimate for timer.loadings: Ap × mmatrix of factor loadings.w_r: A numeric vector of kernel weights used in the computation.
Predict Optimal Portfolio Weights Using Time-Varying Covariance Estimation
Description
This function estimates optimal portfolio weights using a time-varying covariance matrixderived from Local Principal Component Analysis (Local PCA). The procedure is available either as a stand-alonefunction or as a method in the 'TVMVP' R6 class. It computes the following portfolios:
Global Minimum Variance Portfolio (MVP)
Maximum Sharpe Ratio Portfolio (if
max_SR = TRUE)Return-Constrained Minimum Variance Portfolio (if
min_returnis provided)
Usage
predict_portfolio( obj, horizon = 1, max_factors = 3, kernel_func = epanechnikov_kernel, min_return = NULL, max_SR = NULL, rf = NULL)Arguments
obj | An object of class TVMVP with the data. |
horizon | Integer. Investment horizon over which expected return and risk are computed. Default is 1. |
max_factors | Integer. The number of latent factors to consider in the Local PCA model. Default is 3. |
kernel_func | Function. Kernel used for weighting observations in Local PCA. Default is |
min_return | Optional numeric. If provided, the function computes a Return-Constrained Portfolio that targets this minimum return. |
max_SR | Logical. If TRUE, the Maximum Sharpe Ratio Portfolio is also computed. Default is |
rf | Numeric. Log risk-free rate. If |
Details
Two usage styles:
#'
# R6 method interfacetv <- TVMVP$new()tv$set_data(returns)tv$determine_factors(max_m=5)prediction <- tv$predict_portfolio(horizon = 1, min_return = 0.01, max_SR = TRUE)#' # Function interfaceprediction <- predict_portfolio(obj, horizon = 5, m = 2, min_return = 0.01, max_SR=TRUE)
The methods can then be used onprediction to retrieve the weights.
The function estimates a time-varying covariance matrix using Local PCA:
\hat{\Sigma}_{r,t}=\hat{\Lambda}_t \hat{\Sigma}_F \hat{\Lambda}_t' + \tilde{\Sigma}_e
Where\hat{\Lambda}_t is the factor loadings at time t,\hat{\Sigma}_F is the factor covariance matrix, and\tilde{\Sigma}_e is regularized covariance matrix of the idiosyncratic errors.
It forecasts asset-level expected returns using a simple ARIMA model selection procedure and uses these in portfolio optimization.Optimization strategies include:
Global minimum variance (analytical)
Maximum Sharpe ratio (if
max_SR = TRUE)Minimum variance with expected return constraint (if
min_returnis provided)
Value
An object of classPortfolioPredictions (an R6 object) with:
summaryA data frame of evaluation metrics (expected return, risk, Sharpe ratio) for all computed portfolios.
MVPA list containing the weights, expected return, risk, and Sharpe ratio for the Global Minimum Variance Portfolio.
max_SR(Optional) A list with metrics for the Maximum Sharpe Ratio Portfolio.
MVPConstrained(Optional) A list with metrics for the Return-Constrained Portfolio.
Methods
The returned object includes:
$print(): Nicely prints summary and portfolio access information.$getWeights(method = c("MVP", "max_SR", "MVPConstrained")): Retrieves the weights for the selected portfolio.
References
Lillrank, E. (2025).A Time-Varying Factor Approach to Covariance Estimation
Fan, Q., Wu, R., Yang, Y., & Zhong, W. (2024). Time-varying minimum variance portfolio. Journal of Econometrics, 239(2), 105339.
Examples
set.seed(123)returns <- matrix(rnorm(200 * 20, mean = 0, sd = 0.02), ncol = 20)# Initialize objecttv <- TVMVP$new()tv$set_data(returns)# Optimize weights and predict returnsresult <- predict_portfolio( tv, horizon = 5, m = 3, min_return = 0.02, max_SR = TRUE)# Print the portfolio performance summaryprint(result)# Access MVP weightsresult$getWeights("MVP")# Access Max Sharpe weights (if computed)result$getWeights("max_SR")# Or use R6 method interfacetv$determine_factors(max_m=5)prediction <- tv$predict_portfolio(horizon = 1, min_return)predictionprediction$getWeights("MVPConstrained")Estimate Residuals from Factor Model
Description
This function estimates the residuals of asset returns after removing the effectof factor-driven returns.
Usage
residuals(factors, loadings_list, returns)Arguments
factors | A matrix containing the step-ahead-factors of from the |
loadings_list | A list where each element is a matrix of loadings correspondingto the factors for each time period. |
returns | A matrix of asset returns with rows representing time periods andcolumns representing assets. |
Details
For each time periodt, the function models the asset returns as:
R_t = F_t \Lambda_t + \epsilon_t
whereR_t is the vector of asset returns,F_t is the t'th row of the factor matrix,\Lambda_t is the loadings matrix, and\epsilon_t represents the residuals.
The residuals are computed as the difference between actual returns and the modeledreturns.
Value
A matrix of residuals where each row corresponds to a time period and eachcolumn corresponds to an asset.
Compute Bandwidth Parameter Using Silverman's Rule of Thumb
Description
This function calculates the bandwidth parameter for kernel functions using Silverman's rule of thumb,which is commonly used in kernel density estimation to determine an appropriate bandwidth. The procedure is available either as a stand-alone function or as a method in the 'TVMVP' R6 class.
Usage
silverman(returns)Arguments
returns | A numeric matrix of asset returns with |
Details
Silverman's rule of thumb for bandwidth selection is given by:
bandwidth = \frac{2.35}{\sqrt{12}} \times T^{-0.2} \times p^{-0.1}
whereT is the number of time periods andp is the number of assets.
Two usage styles:
# Function interfacebw <- silverman(returns)# R6 method interfacetv <- TVMVP$new()tv$set_data(returns)tv$silverman()
Value
A numeric value representing the computed bandwidth parameter based on Silverman's rule.
Examples
# Simulate data for 50 assets over 200 time periodsset.seed(123)T <- 200p <- 50returns <- matrix(rnorm(T * p, mean = 0.001, sd = 0.02), ncol = p)# Compute bandwidth using Silverman's rule of thumbbw <- silverman(returns)print(bw)tv <- TVMVP$new()tv$set_data(returns)tv$silverman()Compute the Square Root of a Matrix
Description
Computes the square root of a symmetric matrix via eigen decomposition.Negative eigenvalues are handled by taking the square root of their absolute values.
Usage
sqrt_matrix(Amat)Arguments
Amat | A numeric symmetric matrix. |
Value
A matrix that is the square root ofAmat.
Estimate Time-Varying Covariance Matrix Using Local PCA
Description
This function estimates a time-varying covariance matrix using local principal componentanalysis and the soft thresholding for residual shrinkage. By default, only the totalcovariance matrix is returned. Optionally, the user can retrieve all intermediatecomponents of the estimation process. The procedure is available either as astand-alone function or as a method in the 'TVMVP' R6 class.
Usage
time_varying_cov( obj, max_factors = 3, kernel_func = epanechnikov_kernel, M0 = 10, rho_grid = seq(0.005, 2, length.out = 30), floor_value = 1e-12, epsilon2 = 1e-06, full_output = FALSE)Arguments
obj | An object of class TVMVP with the data. |
max_factors | The number of factors to use in local PCA. |
kernel_func | The kernel function to use (default is |
M0 | Integer. The number of observations to leave out between the two sub-samples in the adaptive thresholding procedure. Default is 10. |
rho_grid | A numeric vector of candidate shrinkage parameters |
floor_value | A small positive number specifying the lower bound for eigenvalues in the final positive semidefinite repair. Default is |
epsilon2 | A small positive tuning parameter for the adaptive thresholding. Default is |
full_output | Logical; if |
Details
The function estimates a time-varying covariance matrix using Local PCA:
\hat{\Sigma}_{r,t}=\hat{\Lambda}_t \hat{\Sigma}_F \hat{\Lambda}_t' + \tilde{\Sigma}_e
Where\hat{\Lambda}_t is the factor loadings at time t,\hat{\Sigma}_F is the factor covariance matrix, and\tilde{\Sigma}_e is regularized covariance matrix of the idiosyncratic errors.
Two usage styles:
# Function interfacetv <- TVMVP$new()tv$set_data(returns)cov <- time_varying_cov(tv, m = 5)# R6 method interfacetv$determine_factors(max_m = 5)cov <- tv$time_varying_cov()
Value
By default, a covariance matrix. Iffull_output = TRUE, a list containing:
total_cov– the estimated covariance matrix,residual_cov– the residual (idiosyncratic) covariance,loadings– estimated factor loadings,best_rho– optimal shrinkage parameter,naive_resid_cov– residual covariance before shrinkage
References
Lillrank, E. (2025).A Time-Varying Factor Approach to Covariance Estimation
Chen, J., Li, D., & Linton, O. (2019). A new semiparametric estimation approach for large dynamic covariance matrices with multiple conditioning variables. Journal of Econometrics, 212(1), 155–176.
Fan, Q., Wu, R., Yang, Y., & Zhong, W. (2024). Time-varying minimum variance portfolio. Journal of Econometrics, 239(2), 105339.
Examples
set.seed(123)returns <- matrix(rnorm(100 * 30), nrow = 100, ncol = 30)# Initialize objecttv <- TVMVP$new()tv$set_data(returns)# Using function interfacetime_varying_cov(obj = tv, m = 3)# Or using R6 methodtv$time_varying_cov(m=3)Two-Fold Convolution Kernel Function
Description
This function computes the two-fold convolution of a given kernel function with itself.The convolution is evaluated over a range of inputsu and is set to zero outsidethe interval \([-2, 2]\).
Usage
two_fold_convolution_kernel(u, kernel_func)Arguments
u | A numeric vector of points at which the two-fold convolution kernel is evaluated. |
kernel_func | A function representing the kernel to be convolved. |
Details
The two-fold convolution kernel is defined as:
K^{(2)}(u) = \int_{-1}^{1} K(v) \cdot K(u - v) \, dv
whereK is the original kernel function. The function evaluates this convolution for eachinputu within the interval \([-2, 2]\) and sets it to zero outside this range.
Value
A numeric vector of two-fold convolution kernel values corresponding to each inputu.