Task
Restrict amounts for individual assets in various ways.
Preparation
This presumes that you can do basic random portfolio generation. For example, that you have mastered “Very simple long-only”.
- Portfolio Probe
You 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
- The objects:
priceVector
,grossVal
,curPortfol
that are defined in several examples, such as in “Passive, no benchmark (minimum variance)” xaLWvar06
variance matrix from “Returns to variance matrix” example
Doing it
We will generate random portfolios that:
- limit maximum weight of assets
- limit the contribution to portfolio variance of assets
- limit minimum and maximum amount in a long-only portfolio
- limit amount traded by asset
Limit maximum weight of assets
We generate portfolios that restrict the maximum weight to 10%:
rpMaxWt <- random.portfolio(100, priceVector, existing=curPortfol, gross=grossVal, long.only=TRUE, max.weight=.1)
We can get the maximum weight in each portfolio and then do a summary of those numbers:
> summary(sapply(valuation(rpMaxWt, priceVector, + weight=TRUE), max)) Min. 1st Qu. Median Mean 3rd Qu. Max. 0.08140 0.09079 0.09527 0.09479 0.09830 0.10000
Limit the contribution to portfolio variance of assets
The constraint in the previous example — limiting maximum weight — is quite commonly done, but is not likely to be what people really want. Closer to what is wanted is to constrain the amount of risk that each asset brings to the portfolio.
Do that with:
rpRiskFrac <- random.portfolio(100, priceVector, variance=xaLWvar06, existing=curPortfol, gross=grossVal, long.only=TRUE, risk.fraction=.1)
There are two changes between this and the previous example: “max.weight
” is changed to “risk.fraction
“, and a variance matrix is given.
The summary of the maximum weights is:
> summary(sapply(valuation(rpRiskFrac, priceVector, + weight=TRUE), max)) Min. 1st Qu. Median Mean 3rd Qu. Max. 0.04648 0.07284 0.08416 0.09031 0.09394 0.17360
Since we are restricting risk rather than weight, the maximum weight can be bigger than 10%. Interestingly there are some portfolios with quite low maximum weight as well.
Limit minimum and maximum amount in a long-only portfolio
There is no “min.weight” argument to match the max.weight
argument. One way of getting a minimum weight constraint is to use the positions
argument.
To get a minimum weight of 5% and maximum weight of 20% for all assets, we can set up the positions
argument as:
posArg <- cbind(rep(.05, 10), .2) * grossVal
This argument expects its inputs in terms of money. The first few rows look like:
> head(posArg, 3) [,1] [,2] [1,] 151671.5 606686 [2,] 151671.5 606686 [3,] 151671.5 606686
Now we can generate the portfolios . Note that we are restricting the universe to only the first 10 assets (the ones that are in the existing portfolio):
rpMinMaxWt <- random.portfolio(100, head(priceVector, 10), existing=curPortfol, gross=grossVal, long.only=TRUE, positions=posArg)
The summary of minimum weights is:
> summary(sapply(valuation(rpMinMaxWt, priceVector, + weight=TRUE), min)) Min. 1st Qu. Median Mean 3rd Qu. Max. 0.05000 0.05001 0.05291 0.05391 0.05672 0.06965
Limit amount traded by asset
We can limit the number of units (that is, shares, contracts, …) that are traded by asset with the arguments lower.trade
and upper.trade
.
First we create a vector for the maximum number of shares we are willing to sell for each of the assets in the existing portfolio:
lowArg <- seq(-1500, by=100, length=10) names(lowArg) <- names(curPortfol)
This looks like:
XA101 XA103 XA105 XA107 XA108 XA111 XA113 XA115 -1500 -1400 -1300 -1200 -1100 -1000 -900 -800 XA120 XA126 -700 -600
In general the upper.trade
need not be related to the values in lower.trade
, but in the interests of simplicity we’ll make the trading limits symmetric:
rpLoHiTrade <- random.portfolio(100, priceVector, existing=curPortfol, gross=grossVal, long.only=TRUE, lower.trade=lowArg, upper.trade=-lowArg)
This restricts the trading of the ten assets named in lowArg
but not any of the other assets. Often all assets are restricted, but you can constrain or not constrain any assets as you please.
Explanation
Maximum weight
A blanket weight constraint as in the first example is almost surely better as a risk fraction constraint. However, there are maximum weight constraints that do make sense. For example, you may want to hold no more than x days of average volume of each asset. That can be stated as a maximum weight, but will be a different weight for each asset.
To give such a constraint, give a named vector to max.weight
. For example:
max.weight=c(XA101=.057, XA103=.015, XA120=.712)
This constrains the three assets named but does not constrain any others.
Risk fraction
The generalization of the max.weight
argument explained just above also works for risk.fraction
. It is possible to put a lower bound on the risk fractions as well (in the same spirit as the third example).
Minimum and maximum amount
The matrix that we gave to the positions
argument had all its rows the same. In order to give different amounts for different assets, the matrix needs row names that are the identifiers of the assets.
Lower and upper trade
The values in lower.trade
need to be negative or zero, and the values in upper.trade
need to be positive or zero.
Otherwise, they would be forcing a trade. You can force trades, but you need to use either the forced.trade
argument or the positions
argument.
Further details
The example with minimum weights was restricted to have only 10 assets in the universe because that form of constraint says that all assets should obey it. If instead you want a minimum weight given that the asset is in the portfolio at all, then that is a threshold constraint. Threshold constraints may be imposed either with the threshold
argument or with the positions
argument (using more columns).
For long-short portfolios, max.weight
constrains the absolute value of the weight. In this case weight is defined as the position value divided by the gross value of the portfolio.
Troubleshooting
- Be mindful that these arguments are mostly in different units from each other:
max.weight
: weightrisk.fraction
: fraction of variance (by default)positions
: monetary valuelower.trade
,upper.trade
: units (shares, contracts, …)threshold
: unitsforced.trade
: units
See also
Navigate
- Back to “Random Portfolio Generation”
- Back to the top level of “Portfolio Probe Cookbook”