Very simple long-short

Task

Generate a set of 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 3 random portfolios with the constraints:

  • gross value very close to $1,000,000
  • net value between $5000 and $20,000
  • no more than 4 assets in the portfolio

We can get such portfolios with the command:

rplsVerysimp <- random.portfolio(3, priceVector, 
   gross=1e6, net=c(5000, 20000), port.size=4)

print result

The result looks like:

> rplsVerysimp
[[1]]
XA262 XA535 XA561 XA674 
-5390 -3849 -4675 16813 

[[2]]
 XA126  XA231  XA319  XA623 
  -129  -9451 -12744   5377 

[[3]]
XA228 XA373 XA781 XA986 
-4267     1  6924 -6811 

attr(,"call")
random.portfolio(number.rand = 3, prices = priceVector, gross = 1e+06, 
    net = c(5000, 20000), port.size = 4)
attr(,"timestamp")
[1] "Mon Sep 03 20:38:00 2012"
[2] "Mon Sep 03 20:38:00 2012"
attr(,"class")
[1] "randportBurSt"
seed attribute begins: 1 -959789278 1943820272 2019334722

Some information about the object is printed at the end which makes it look more complicated than it is.  But the first part shows three portfolios that each contain 4 assets.

The first portfolio is short 5390 shares of XA262, short 3849 shares of XA535 and short 4675 shares of XA561.  The only asset it is long in is XA674 of which it holds 16,813 shares.

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.

It is mandatory to constrain the value of portfolios.  There are other possibilities, but constraining the gross value and the net value is the most common approach for long-short portfolios.  Two numbers are given for the net value — this is the allowable range.  Only one number is given for the gross value.  However, this is really an interval as well — the value given is the upper bound and the lower bound is automatically generated to be a slightly smaller number.

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

Further details

We can see what the value of the portfolios is:

> valuation(rplsVerysimp, prices=priceVector, collapse=TRUE)
[1] 999916.5 999975.2 999943.6
> valuation(rplsVerysimp, prices=priceVector, type="net", collapse=TRUE)
[1] 9536.05 9717.85 6297.83

The gross values (the first command) 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.

All the net values are well within their allowed range.

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(3, xassetPrices[250:251,], gross=1e6, net=0)
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