optimize.portfolio.rebalancing with changing/dynamic stock universe [PortfolioAnalytics]
Hi Simon, A changing universe is not directly supported in PortfolioAnalytics, but it can absolutely be done. Eric Berger mentioned several of the key concerns with return histories of different lengths and an evolving universe of assets. The optimize.portfolio.rebalancing function is effectively a wrapper around optimize.portfolio. A solution to your problem with a dynamic universe is to write your own rebalancing loop. At each iteration, you can define the assets in the portfolio specification and the returns to use for that iteration. This has come up before and I would like to add it to PortfolioAnalytics, but it has not risen to the top of my priority list. Feel free to open a feature request on https://github.com/braverock/PortfolioAnalytics. Also, patches always welcome. Hope that helps. Best, Ross
On Fri, Oct 19, 2018 at 4:48 AM Eric Berger <ericjberger at gmail.com> wrote:
I see a few problems with your approach 1. Providing incorrect returns data for stocks when they are NOT in the index won't work because you need the historical co-movements of the stock with the rest of the investable universe. e.g. for Sharpe-Ratio (Mean-Variance) optimization, if the stock first entered the index on July 1, you will need accurate returns data for at least the size of the window used to compute a covariance for July 1 - e.g. if a 12-month window then for the full year prior to the first entry into the index. 2. If your optimization problem allows negative weights (i.e. short positions), then clearly using extreme negative returns for a stock will identify it as a good candidate for inclusion on the short side. Possible approach: Major index membership changes relatively infrequently. e.g. the S&P500 membership is reconstituted annually. If your 1/0 data shows that changes are infrequent you might be able to simply perform several runs with each run having a "constant" investable universe for the rebalancing dates for that run. Then stitch together the results from the different runs. Another approach: Contact the authors of the package to see if they have suggestions. You are raising a standard concern and they may have addressed it or have thought about how to deal with it. Regards, Eric On Fri, Oct 19, 2018 at 12:14 AM Simon Hovmark <simonhovmark at gmail.com> wrote:
I am using the PortfolioAnalytics package to run a multi-period optimization on a quite large stock universe (14 European indicies ~ 800 stocks) but I?ve run into a problem. All examples and vignettes using the package has a fixed stock universe over the backtest period (like EDHEC) while I?ve a dynamic universe. For example, stock XYZ might have been in
an
index from may, 2002 to October 2007 and after that excluded from the index. However, the optimizer is only allowed to include stock XYZ in the optimization if it was part of an index at the rebalance date. From my understanding, it is not possible to set up a custom constraint (like it is with objectives) to say that, stock XYZ should only be
included
in the optimization rebalancing if the rebalancing date is between may, 2002 to October 2007. Does anybody have an idea how to solve this? Data I?ve a dataset (daily data) with a 1 if the stocks were in their respective index at the date and a 0 if they were not (see last
sentence).
Alternatively, I also have a list like the below with the precise dates: Name Entry Exit SBMO-NL 2003-03-03 2015-03-20 SMBO-NL 2016-03-21 2018-03-16 TA-NL 2008-03-26 2008-06-27 TLNL-NL 2000-12-29 2002-03-01 TLNL-NL 2004-03-02 2005-10-10 My returns series have the returns for the stocks for the complete
listing
period (not dependent on the stock being in an index or not). My current (very very ugly) work-around was to multiply the 1/0 matrix and the
return
matrix, so I only had returns for the periods when the stocks where in an index, and then replace all 0/NAs with -100. This -100 would penalize stocks outside of an index to such a degree, that it would not be
included
in the index. However, this is ugly and incorrect plus it does not work.
Code
This is not my exact code but see this as an example of a simple
optimization:
returns <- read_excel("R", sheet = 1, col_names = TRUE)
returns <- xts(returns[,-1], order.by = as.Date(paste(returns$Dato,
format = "%Y.%m.%d")))
returns <- Return.calculate(returns, method = "log")
returns <- returns[-1,]
fund.names <- colnames(returns)
tranch1 <- portfolio.spec(assets = fund.names)
# Constraints
tranch1 <- add.constraint(portfolio = tranch1, type = "leverage")
tranch1 <- add.constraint(portfolio = tranch1, type = "long_only")
# Objective
tranch1 <- add.objective(portfolio=tranch1, type="return", name="mean")
tranch1 <- add.objective(portfolio=tranch1, type="risk", name="StdDev")
tranch1_opt <- optimize.portfolio.rebalancing(R=returns,
portfolio=tranch1,
optimize_method="DEoptim",
#momentFUN = tranch1_boudt,
#momentargs=ac.moments,
rebalance_on = ?year?,
training_period = 26,
rolling_window = 26,
trace=TRUE, traceDE=5,
search_size=2000)
Here is some data from my sample (dput):
structure(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46.276, 46.327, 46.122, 46.924,
46.071, 46.856, 47.351, 45.645, 46.003, 47.436, 48.358, 49.501,
49.364, 49.433, 48.597, 48.204, 47.061, 47.266, 47.436, 49.211,
50.729, 51.514, 51.19, 49.996, 51.156, 51.856, 51.412, 52.385,
55.797, 55.371, 54.176, 53.784, 52.896, 53.511, 54.603, 55.115,
54.654, 52.658, 52.692, 54.603, 54.569, 56.258, 54.944, 54.654,
54.552, 54.603, 53.954, 53.852, 54.262, 54.262, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 123.067, 122.712, 123.422, 127.323, 127.855, 128.032,
124.84, 117.215, 121.826, 120.939, 117.747, 122.358, 119.875,
114.91, 115.619, 113.846, 116.328, 118.634, 119.698, 120.407,
119.166, 118.811, 120.584, 120.584, 120.584, 119.875, 119.166,
120.584, 123.422, 121.294, 119.52, 123.244, 122.89, 125.018,
126.082, 125.55, 126.082, 126.259, 125.55, 126.614, 126.082,
130.692, 132.288, 132.465, 134.061, 131.047, 131.401, 133.884,
134.771, 141.155, 38.773, 39.16, 39.419, 41.067, 40.356, 41.131,
41.099, 39.548, 40.453, 40.13, 39.419, 42.327, 42.392, 43.425,
43.684, 44.976, 44.944, 44.976, 44.136, 44.362, 43.813, 43.878,
43.942, 44.298, 44.912, 45.881, 45.235, 45.558, 47.658, 47.173,
45.59, 46.786, 47.335, 47.561, 47.27, 48.337, 47.82, 46.883,
45.396, 47.432, 47.917, 48.434, 48.66, 48.983, 48.983, 48.627,
49.015, 50.728, 51.697, 51.859), .Dim = c(50L, 5L), .Dimnames = list(
NULL, c("BAER-CH-B4R2R5", "BALN-CH-7124594", "CFR-CH-BCRWZ1",
"CIBN-CH-5196744", "CLN-CH-7113990")), index = structure(c(883353600,
883440000, 883526400, 883699200, 883958400, 884131200, 884217600,
884304000, 884563200, 884649600, 884736000, 884822400, 884908800,
885168000, 885254400, 885340800, 885427200, 885513600, 885772800,
885859200, 885945600, 886032000, 886118400, 886377600, 886464000,
886550400, 886636800, 886723200, 886982400, 887068800, 887155200,
887241600, 887328000, 887587200, 887673600, 887760000, 887846400,
887932800, 888192000, 888278400, 888364800, 888451200, 888537600,
888796800, 888883200, 888969600, 889056000, 889142400, 889401600,
889488000), tzone = "UTC", tclass = c("POSIXct", "POSIXt")), class =
c("xts",
"zoo"), .indexCLASS = c("POSIXct", "POSIXt"), tclass = c("POSIXct",
"POSIXt"), .indexTZ = "UTC", tzone = "UTC?)
As an alternative, I have also uploaded a full index here (
https://ufile.io/0cxn6 <https://ufile.io/0cxn6>) where the first sheet
is
the 1/0 matrix, the second the full return matrix and the third is the
1/0
matrix times the full return matrix.
[[alternative HTML version deleted]]
_______________________________________________ R-SIG-Finance at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-sig-finance -- Subscriber-posting only. If you want to post, subscribe first. -- Also note that this is not the r-help list where general R questions should go.
[[alternative HTML version deleted]]
_______________________________________________ R-SIG-Finance at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-sig-finance -- Subscriber-posting only. If you want to post, subscribe first. -- Also note that this is not the r-help list where general R questions should go.