[R-SIG-Finance] [PortfolioAnalytics] optimize.portfolio.rebalancing with changing stock universe

Brian G. Peterson br|@n @end|ng |rom br@verock@com
Sun Aug 4 23:09:08 CEST 2019


Joshua,

The problem of assets becoming available or unavailable through time
has been one we've been aware of for a long time.

Ross' solution of building a custom loop certainly works, as you can
call optimize.portfolio in your own loop and change either the 'assets'
slot in the portfolio specification or the constraints matrix,
constraining some assets to 0 position.

We've been discussing this as one open package TODO with our 2019 GSoC
Student, Shawn Feng of the University of Illinois, and are hoping that
we may have a solution in the package code this month for a more
general solution.

We have identified a couple of possible general solutions.  All revolve
around making some aspect of the portfolios specification into a time
series.  Either the 'assets' slot in the portfolio spec could specify
valid assets as a time series rather than the named vector that it is
right now, the 'box_constraint' could take a time series and e.g. take
NA as a constrain for unavailable assets, or the 'position_limit'
constraint could be specified as a time series.

My suspicion is that either changing the assets slot over time or
allowing NA's in the box constraints are the most feasible solution,
but we don't have any code to back that hypothesis up yet.

As you point out indirectly, different analysts will have different
goals for how to include or exclude specific assets at a particular
point in time, so I think we will need to just support a time series
methodology for defining the universe and then lett the user define
their universe using their own criteria (e.g. your Amihud criteria).

Unfortunately, we don't have working general code to solve this feature
request just yet.  Until then (hopefully soon), I'm afraid you'll need
to adjust things manually and call 'optimize.portfolio' multiple times,
on dates of your choosing.

As for your desire to check multiple different benchmark portfolios,
see help and examples for 'combine.portfolios' and
'combine.optimizations' to create an output object of type  'opt.list'.
Most of the summary, print, plot, etc functions should handle these
combined optimizations and give you reasonable output already. 

Regards,

Brian


On Sun, 2019-08-04 at 21:56 +0200, Joshua Knipe wrote:
> I am using the PortfolioAnalytics package to run a multi-period
> optimisation on a stock universe of just over 100 stocks but I'm
> running
> into some issues. I would like to exclude certain stocks at each
> rebalancing date but have not been able to get it working thus far.
> 
> 
> <a href="
> http://r.789695.n4.nabble.com/optimize-portfolio-rebalancing-with-changing-dynamic-stock-universe-PortfolioAnalytics-td4753227.html
> ">
> http://r.789695.n4.nabble.com/optimize-portfolio-rebalancing-with-changing-dynamic-stock-universe-PortfolioAnalytics-td4753227.html
> </a>
> 
> This thread has a very similar issue and Ross Bennett (the creator of
> this awesome package) mentions writing ones own rebalancing loop in
> order to achieve an evolving universe of stocks. This sounds like the
> solution but I am not sure how to implement that unfortunately.
> 
> 
> I have calculated a measure of illiquidity for each stock (the
> Amihud'sILLIQ value specifically) and have these in a separate file
> which I am reading into R. The measures are weekly in order to match
> the data I am using for the returns of the stocks. I have calculated
> a vector of the median value of this measure for each week i.e. 160
> medians for 160 weeks.
> 
> 
> What I would like to do is exclude all the stocks which have a Amihud
> value above this median from the rebalancing for that period i.e.
> make sure they have 0 weighting if they are not liquid enough.
> 
> I tried it initially with a penalty function which would just sum the
> weights * Amihud values and then scale that value, but this has the
> undesired effect of also penalising stocks below but close to the
> median
> value.
> 
> 
> My end goal is to get the returns of certain portfolio strategies
> (e.g. mean-var, min-var, equal weight etc) on this data set and then
> compare how the returns change when these "illiquid stocks" are
> excluded at each rebalancing period.
> 
> 
> Any advice would be seriously appreciated! :)
> 
> 
> <b>Data</b>
> 
> 
> The Amihud values are in the following format (which is the same
> format as
> the price data):
> 
> 
> Date.               Stock 1.             Stock
> 2.                Stock 3.
>           Stock 4.           etc
> 
> 2009-06-05.    1.057348e-06.    5.263602e-07   2.054617e-
> 11.   6.470526e-11
> 
> 2009-06-12.    1.057346e-06.    5.123452e-07   2.311231e-
> 11.   6.381738e-11
> 
> 2009-06-19.    1.034941e-06.    5.219238e-07   2.192929e-
> 11.   6.238939e-11
> 
> 
> <b>Code</b>
> 
> An extract of the code I have thus far:
> 
> 
> sjPrices =
> as.data.frame(read_excel("ALSI_Cleaned_Weekly_Prices.xlsx",
> sheet = 1, col_names = T,
> 
>                                             na = "", skip = 0))
> 
> weeklyAmihud = as.data.frame(read_excel("weeklyAmihud.xlsx", sheet =
> 1,
> col_names = T,
> 
>                                               na = "", skip = 0))
> 
> 
> #create vector of medians (uses function from matrixStats package)
> 
> mid <- rowMedians(as.matrix(weeklyAmihud[, -1]))
> 
> 
> dates = as_date(sjPrices[,1])
> 
> 
> # remove the first column (of dates)
> 
> sjPrices <- sjPrices[, -1]
> 
> weeklyAmihud <- weeklyAmihud[, -1]
> 
> 
> #create xts objects
> 
> sjPrices <- xts(sjPrices, order.by=dates)
> 
> weeklyAmihud <- xts(weeklyAmihud, order.by=dates)
> 
> 
> sjReturns <- ROC(sjPrices)
> 
> 
> #remove first row (0 returns)
> 
> sjReturns <- sjReturns[-1,]
> 
> 
> #this function does penalise the very illiquid stocks but has other
> undesired side-effects
> 
> AMIHUD <- function(sjReturns, weights, wAmihud){
> 
>   return(sum(weights*wAmihud)*100)
> 
> }
> 
> 
> portf <- portfolio.spec(colnames(sjReturns))
> 
> 
> portf <- add.constraint(portf,type = "weight_sum", min_sum = 0.99,
> max_sum
> = 1.01)
> 
> portf <- add.constraint(portf, type="long_only")
> 
> 
> portf <- add.objective(portf, type = "risk", name = "StdDev")
> 
> portf <- add.objective(portf, type="risk", name="AMIHUD",
> 
>                        arguments=list(wAmihud=weeklyAmihud))
> 
> 
> opt_rebal <- optimize.portfolio.rebalancing(sjReturns,
> 
>                                             portf,
> 
>                                             optimize_method="DEoptim"
> ,
> 
>                                             rebalance_on="quarters",
> 
>                                             training_period=52,
> 
>                                             rolling_window=52,
> 
>                                             trace=TRUE, traceDE=5,
> search_size=2000)
> 
> 	[[alternative HTML version deleted]]
> 
> _______________________________________________
> R-SIG-Finance using 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.
-- 
Brian G. Peterson
ph: +1.773.459.4973
im: bgpbraverock



More information about the R-SIG-Finance mailing list