As pointed out in a previous blog post, the Kelly Criterion is an interesting option to decide on position sizing in portfolio selection. While the previous post looked at single stocks, I will today show how to optimize position sizes for a portfolio with multiple stocks.
At the core of my portfolio optimization is this function:


The function has three parameters. shares
is the vector of shares (position size for each stock) that is going to be estimated by optimization. dpf
is a matrix where each stock is a column and each line contains the daily stock price movements like e.g.: diff(stock)/lag(stock)
. The maxshare
option can be used to restrict the position size of a single stock to a maximum.
exp_returns < dpf%*%shares
calculates the daily (or weekly) portfolio returns. obj
is the Kelly Criterion. The higher the volatility, the larger values obj
will take. We are going to minimize the function so low values, i.e. low volatility is preferred. The next line is a trick to restrict the optimizer to values that sum to 1 (100%). If the sum of all position sizes is 1, weight.penalty
is 0 (the minimum possible value). Would the sum deviate from 1, the weight.penalty
would quickly increase. The second penalty term is similar. If a position is sized above the maximum allowed share, the penalty scores. Finally the function returns a value which the optimizer will try to minimize.
Now to feed stock data into this function I wrote a wrapper function that prepares the matrix of returns and calls optim()
.


Most of the function is commented between the lines. I introduced two options: daily
and short
. The default values are, that short positions are not allowed and the returns are calculated on a weekly, not daily basis. One thing thats important for me is, that I dont use the stock returns as they are but I center them around the mean return that I expect. If I would not do this, the algorithm would always pick the historically best performing stock(s). However past performance is not a good predictor of future performance and one has to do his homework and build own (and realistic) expectations.
To test the function I select some random stocks (not a recommendation to trade these stocks).


This tells the following story: Assuming all stocks have the same expected yearly return of 3%, the long term growth rate of wealth (Kelly Criterion) is achieved by investing in the stock with a lowest volatility (here GIS). At the same time this is a hint, that the assumption that all returns are to be expected as equal is too strong. One could now play with the function to find out how high the expected return of a risky stock has to be, to be included into an existing portfolio.
I personally use this tool as a rough orientation, how stocks from my watchlist would contribute to the riskreturnprofile of my portfolio. I usually use the maxshare
option and rather “flat” and moderate return expectations, because the Kelly Criterion highly favors stocks with better return expectations. E.g. if I add 1% additional expected return for GOOG, the numbers change drastically:


If find the tool to be useful because it keeps me from overbetting on very volatile stocks and gives hints, if and when risky stocks are worth to bet on.
There are a few additional points worth mentioning:
opt_portfolio_wrapper()
gives the shares to achieve the Kellyoptimal portfolio selection, it does not tell, how much one should bet on the whole portfolio. Approximately this be calculated by dividing the expected portfolio return by the annualized variance. One could also adapt the kelly()
function from the previous blog post to get a number that incorporates the fact, that the return distribution is fattailed and nonnormal.from
option for getSymbols()
if the historic returns should be restricted to a certain rangeDerived by John L. Kelly (1956) the criterion recommends a certain fraction of a bankroll to be put on a bet with positive expectations. Kelly showed that $$\frac{p \cdot (b+1)  1}{b}$$ optimizes the growth rate of wealth if the game to bet on is repeated for many times, where p is the probability to win the bet and b is the net odds, i.e. what you would get back in excess of amount wagered. For example if you are offered to get your wager tripled for a correct coin flip guess, the Kelly criterion would advice you to bet $$\frac{0.5 * (2+1)  1}{2} = 0.25$$.
While the concept is popular in the betting universe and sometimes in options trading, it seems not to be a common concept in portfolio selection. However, the concept is rather easy to transfer into portfolio selection as all it does is optimizing the long term growth rate. What we would like to find is the fraction that optimizes the following function:


x
is a vector of expected future returns of a stock (which we yet have to conceptualize) and f
is the fraction to be calculated. First of all we need to make assumptions about our expected return. As an example lets assume we expect 3% annualized return for a stock (e.g. because that is approximately in line with economic growth expectations). Second we need to make assumptions about the underlying risk/volatility. I derive the risk from the history of returns. At this point I often get criticized from the value investors camp because it has a flavor of efficient market hypothesis, beta, BlackScholes, capital asset pricing model (CAPM), LTCM crash, etc.
Here is my few arguments why basing future risk on past risk seems legit to me:
By looking at the sum_logx
function, one can see that the Kelly criterion relaxes the strong assumptions that are implicit in the CAPM (normally distributed independent returns, constant correlation between assets) because it recognizes each data point “as is”, and NOT averaging out outliers by calculating a standard deviation. Therefore, more realistically, the Kelly criterion is capable of covering a huge part of the fat tails of the return distribution.
I use the Amazon stock as a mere example. This is not a recommendation to trade the stock.


Using the very early days of Amazon is probably not representative for the future risk, as Amazon matured. However the time span should ideally include all aspects of economic cycles, so I used about 10 years, including the financial crisis 2008.
Now I calculate weekly and monthly returns based on the adjusted closing price.


Now to incorporate my expected return I center the time series around that value. One might argue about the procedure but I find it more plausible than e.g. putting past returns into my models (as some people do) since past returns are not a predictor of future returns. So this is my best guestimate.


With this I basically keep the empiric distribution of returns to represent risk and input my personal expectation.
Then I optimize the function sumlog_x
using the defined vectors of expected returns for both, weekly and monthly returns.


This comes up with numbers around 20% of bankroll. Keep in mind however, that this relies on the assumptions, that the expected return is 3% and the return distribution of the next year is expected to be of the same source as was the return distribution in the last decade. Furthermore it is important, that overbetting does more harm than underbetting. Therefore many people recommend betting “half Kelly” to be rather on the save side that is slightly underperforming than on the risky side, that waits for the big wave to be wiped out.
Now what if I wanted an even more conservative estimate? Lets assume I expect the risk of bankruptcy for the next twelve month to be 0.4% higher than it is reflected by the market. I went for this very simple solution:


For each of the 10 years, I include one (~0.4%) total loss (1). In my opinion it is always advisable to think about total loss probability because listed stocks are per definition the ones that are not (yet) bankrupt (survivorship bias). The empiric distribution (my approach) has much fatter tails than the normal distribution (conventional approach) but it does not cover the events that did not take place so far.


As can be seen, the Kelly criterion is rather optimistic in general but very sensitive to total losses. I use the procedure as a tool to get a first impression of a stock I am thinking to invest in. However there is more to be looked at, e.g. the diversification benefit of the stock within an existing portfolio. I will cover this topic  how to optimize the Kelly criterion for a portfolio of multiple stocks  in a subsequent post.
For convenience here is the code of the function I use:


As mentioned above, stock returns are not normally distributed, therefore the CAPM compared to advise from the Kelly criterion tends to “overbet”.


Plotting the empiric quantiles vs. the theoretical quantiles we see that returns outside of the range of two standard deviations left and right is much more frequent than the normal distribution would suggest. This combined with high leverage was the central reason for the collapse of LTCM.
]]>After the basic setup, i.e.
raspiconfig
aptget install R
, which installed R 3.1.1I started to install the R packages usually needed for my cronjob tasks (mostly webscraping). I ran into problems with the rvest
package because several packages could not be installed. Maybe there is a more efficient way but I did the following steps:
To install xml and related R packages (rvest), I needed the libxml2 on the system although aptget had it, so I manually installed it:


I also needed pythondev to make libxml2 compile.


Then built libxml2:


I also had problems with the curl Package. Installation suggested to install libcurl4openssldev therefore:


Last problem was the openssl package. Again, I followed the suggestions from the failed Rpackage installation and installed libssldev:


After that, rvest
installed nicely. However, it took quite a while for the Pi to install all dependencies.
A simple Task, my Raspberry Pi is doing for me is sending a frost warning to my email if at 6 pm the weather forecast for the night goes below 3 °C. For this I got an API Key at openweathermap.org. Mind, that openweathermap.org does not like frequent requests (less than 1 per 10 minutes). At the beginning I got blocked.
You can then request some JSON for your city ID using your APPID (API Key):


Then tidy and extract the values needed. Temperatures are in degrees kelvin so we need to convert to celsius. The date I transform to POSIX.


Now for the part sending a mail:


Finally we have to tell the Raspberry Pi to schedule the script to run daily at early evening. Save the .R file and add it to your crontab:


The first time you use crontab you are asked to choose an editor. Easiest (at least for me) to use is nano.
Add the following line:


Which will add the script to your cronjobs scheduling it at 18:00 every day and month.
]]>