Very simple long-only

Task

Generate a set of long-only portfolios with some simple constraints.

Preparation

  • vector of asset prices
  • Portfolio Probe

You need the prices at which assets trade.

You also need to have the Portfolio Probe package loaded into your R session:

require(PortfolioProbe)

If you don’t have Portfolio Probe, see “Demo or Buy”.

Doing the example

  • pprobeData package

You need to have the package loaded into your R session:

require(pprobeData)

Doing it

prices

We start by naming the vector of prices that we want to use:

priceVector <- xassetPrices[251,]

These are the prices at the close of the last trading day of 2006.  The first few values are:

> head(priceVector)
 XA101  XA103  XA105  XA107  XA108  XA111 
 33.56  72.25  74.39 192.06   5.91  15.98

The requirement for the prices is that it be a vector of positive numbers with names (that are the asset identifiers).

generation

Now we want to generate 4 random portfolios with the constraints:

  • long-only
  • value is very close to $1,000,000
  • no more than 3 assets in the portfolio

We can get such portfolios with the command:

rploVerysimp <- random.portfolio(4, priceVector, 
   long.only=TRUE, gross=1e6, port.size=3)

print result

The result looks like:

> rploVerysimp
[[1]]
XA120 XA411 XA636 
 6610 37909 20590 

[[2]]
XA778 XA802 
20203  1404 

[[3]]
XA107 XA353 XA569 
 3051  5242   760 

[[4]]
XA250 XA448 
 6125 30789 

attr(,"call")
random.portfolio(number.rand = 4, prices = priceVector, long.only = TRUE, 
    gross = 1e+06, port.size = 3)
attr(,"timestamp")
[1] "Mon Sep 03 18:55:45 2012"
[2] "Mon Sep 03 18:55:45 2012"
attr(,"class")
[1] "randportBurSt"
seed attribute begins: 1 386950432 -1389227587 1974221297

Some information about the object is printed at the end which makes it look more complicated than it is.  Let’s focus on the first little bit:

[[1]]
XA120 XA411 XA636 
 6610 37909 20590 

[[2]]
XA778 XA802 
20203  1404

This is showing the first two random portfolios.  The first portfolio contains three assets.  It has 6610 shares of asset XA120, 37,909 shares of XA411 and 20,590 shares of XA636.  The second portfolio only contains two assets — that’s okay: the constraint was to have at most 3 assets, not exactly 3 assets (though we could have had that constraint).

If you do this command, you will get different portfolios because you will have a different random seed.

Explanation

The random.portfolio function is the (primary) function that generates random portfolios.

Its first argument is the number of random portfolios desired.

The second argument is the price vector.

The remaining arguments are all constraints.  For long-only portfolios, you must include ‘long.only=TRUE‘.

It is mandatory to constrain the value of portfolios.  In this case it suffices to state the maximum for the gross value.  (As we’ll see below this is really short-hand for slightly less than that maximum value.)

The final part of the call is ‘port.size=3‘.  This is what constrains the number of assets in the portfolio to be at most 3.

Further details

We can see what the values of the portfolios are:

> valuation(rploVerysimp, prices=priceVector, collapse=TRUE)
[1] 999960.9 999980.8 999991.8 999999.2

They are all slightly less than 1 million.  We can’t expect the value to be exactly 1 million, but it is easy to get close.  The meaning of “close” depends on the unit prices of the assets.  (But the default range for gross does not look at the prices — it is merely a fraction of the maximum.)

To change this example into something that you really want to do, you just need to put in the constraints appropriate for your problem.

Troubleshooting

  • All of the prices need to be in the same currency.  You have to check that — the code has no way of knowing.
  • It will still work if the object given as the prices is a one-column or one-row matrix.  But it will complain about other matrices:
> random.portfolio(4, xassetPrices[250:251,], long.only=TRUE, gross=1e6, port.size=3)
Error in trade.optimizer.pre(prices = prices, variance = variance, expected.return = expected.return,  : 
  'prices' expected to be a numeric vector with names, not a matrix

See also

Navigate