I previously wrote a note on calculating the optimal amount to leverage your portfolio to maximize compound growth using your trading strategy's historical returns.


I tried to extend it to use the actual data rather than a histogram approximation. So I just ran it with all the historical returns (not binned) assigning uniform probability to each historical return observation. It gave nearly the same results as the histogram approximation, but it was more accurate in cases where the binning had been done heavy-handedly. To figure out why this was the case, I looked back at the expected log growth formula, sum(p_i*ln(1+f*r_i)). From that it became obvious, as perhaps it should have been from the start, that just using point masses was fine. If you have multiple events with the same return you can add the probabilities if you like by expanding the sum and refactoring terms.

So now in my Kelly fraction computing code the histogram approximation (empirical density optimization) is optional.

I also improved the optimization routine so that it no longer uses brute force. The details are not important, but the basic idea is that now it does hill-climbing, and uses information about the steepness of the optimization surface at each point to jump faster.

Thirdly, I added a bit to simulate the effect of adding a stop-loss. It aggregates the probabilities of all the returns which were below the stop at the stop percentage itself. That's how it works. Easily abusable, but possibly an interesting way of bending the empirical distribution. It assumes your stop is based on a percent rather than dollar loss amount, etc.

Here is the code. First copy the kelly, empirical_distribution, and expectation functions into the command line. Then run the example code in the comment at the top. The example illustrates a nice advantage of this method of optimizing leverage rather than the analytic way which assumes Gaussian returns. You'll need the widely used numpy, matplotlib, and scipy libraries, which I believe give you access to pylab as well. If not you need that too. Notice that you can suppress the extra output by changing the disp=1 and full_output=1 arguments to 0 in scipy.optimize.fmin_cg.

The one issue it has is that sometimes the optimal leverage will be at a point that would make one of the (1+f*r_i) quantities in the sum above less than 0, which then causes the log(1+f*r_i) to be undefined, so the whole sum (i.e. objective function) is undefined, and it breaks the optimizer (it will just hang forever as far as I can tell). For example in the case of a Gaussian with mean 0.05, sd 0.10, the optimal leverage will be .05/(.1^2)=5, but of course the return values that have been observed could be, say -25% (i.e the support of the Gaussian is over (-inf,inf)), so 5x leverage pushes it under -100% and causes the undefined error. I'm not sure how to correctly handle this, or what the right answer really is.

The next step is to add a parameter that allows you to include transaction costs and releveraging frequency in the optimization since higher transaction costs result in a lower optimal leverage. This is because if you use leverage then any change in your holding's prices will require you to releverage. For example: you have 3.0 leverage and $100 in your own cash ie a $300 portfolio. Then the price goes up 100%. You now have a $600 portfolio, but $400 is your cash now. So your leverage is only 1.5. Assuming the Kelly fraction is 3.0, you need to buy more shares, which incurs a cost. Etc. The difficulty in computing effects like these on the optimal leverage are what causes people to fall back on heuristics like half-Kelly (well, that and black swan events).

I'd like to hear anything you know about this topic if you have anything to share.

9 comments:

Joshua Ulrich said...

To solve Ralph Vince's LSP optimization in the LSPM R package, I've found the differential evolution algorithm to be fast and robust. Here's a Python implementation.

Best,
Josh

Gabriele (Italy) said...

Dear Max,

As usual, I am stunned by how smart you are!

Even though I do not understand enough about programming to give any advice in that direction, I thought about the problem with the argument of the logarithm turning negative, thus causing an undefined logarithm.

Here is how I would handle the issue:

Keep in mind the use of logarithmic returns is an effective mathematical way of modeling return (from the famous properties of logarithms) BUT they often are just approximations of the real "core" returns: the more you go away from log(1)=0, the more the approximation has errors.

Thus here is my suggestion: why not using the "core"/"original" returns (in the formula r_i )?

The formula to optimize would then be: sum( p_i*(f*r_i).

The downside is that you loose the beautiful properties of logarithms. The upside (does this word even exist in English???) is that a negative return (greater than 100%) becomes "handable". It will just reduce the mean.

I don't know if this might help and please do not hesitate to tell me if I just said nonsense. Let me know if my contribution is of any help and again my very best compliments!

shabbychef said...

max;

the cheezy-peazy way around some of these issues is to maximize the conditional expected [utility of] the log returns at a given leverage. by 'conditional', I mean you omit the 5% tails (and artificially mark as -inf a prospective value of leverage where the bottom 2.5% goes negative). by 'utility of', I mean that you apply a concave utility function to the logreturns e.g. to penalize downside more than you reward upside. the latter modification usually pulls in the target leverages from insane candyland (~100x leverage) to something you can sell to your risk manager (~2x leverage).

Max Dama said...

Thanks Shabby Chef-

That's exactly the kind of answer I was looking for, although not the answer I want. If your PM wants to use a certain amount of leverage, he/she should just do that without deluding him/herself with a model.

The tail adjustment might help, but it won't fix the problem in all cases. And the tail risks are the ones you're really trying to base your risk calculations on.

Gabriele,

Thanks. I'm not sure how that would effect the optimality properties of the formula, although it can only make it less optimal. And it's not really logarithmic returns we're looking at here, it's Shannon's measure of 'information'.

There is likely a solution that doesn't break the theoretical reasons for using it in the first place. I'd like to find that.

Regards,
Max

shabbychef said...

max;

There is some problem with the claim that "the tail risks are the ones you're really trying to base your risk calculations on." Under any model of the market, there is a slim, but nonzero change, that you could lose all (minus an epsilon) the value in your longs, and go arbitrarily underwater on your shorts. If you must constrain yourself to the domain of the log function, you can never short or use leverage, which is admirable, but perhaps not realistic. Moreover, estimation of e.g. the tail parameter of a power law is notoriously difficult: even with millions of observations, the best known statistical techniques can fail miserably.

Max Dama said...

Shabby Chef,

If you calculate the Kelly formula assuming Gaussian returns, which has domain (-inf,inf), it gives the result f* = mean/variance, not 0. The derivations have used too much stochastic calculus for me so I haven't figured out where my formula is breaking down and how to avoid that to get the true answer.

I agree about the tail risks are the hardest to estimate of course. Perhaps there is a better way than chopping them off?

Regards,
Max

julien said...

Be careful with your stop loss:
the way you do assumes that only bad trades will trigger the stop loss. What if a trade started bad and ended up good. If you use a stop loss this trade will be stopped as well.

So using stop loss aggregates the losses that were bigger than the stop loss to the stop loss level but also aggregates some of the profits to the stop loss level.

A quick example: say you bet in one direction for a given (say 1 day), you get for pnl say a centered gaussian distribution (0 mean)- a dumb trading strategy not working). Using a stop loss at -1 cts does not transform that dumb strategy into a money making machine because you will see that 100% of your trade go into the stop loss, not only the losing ones.

Max Dama said...

Julien,

I agree 100%, that's why I said "Easily abusable". I just thought it might spark others' ideas.

Regards,
Max

Ralph Vince said...

Max,

Interesting posting. I've rather arrived at the conclusion that we're in an era polluted by the LTCM event still. We know we're working with tails which, in most cases, unless truncated go to infinity.I think we get hung up on this notion though, at quite a cost. The longer I trade, the greater the possibility of that even way out on the tails, which I have not budgeted for, will occur. But I am only trading for a finite a window, a horizon, and it is over that window that I seek optimality of my criteria (whatever that may be, in the instant case, geometric growth maximization though I would not use the formula you present here for reasons unrelated to the topic at hand). In attempting to account for the relentless tails of the distributions we are working with in most cases, we are attempting to budget for all possible outcomes -- to be optimal over all possible outcomes. I don't think that's necessary, or even wise. I think we can quite realistically (given the finite window we will be implementing over) truncate the tails at whatever point we wish, bearing in mind that where we truncate them means that we are seeking optimality only in x% of the cases. That tiny, 1-x probability, we know exists, but we whistle past it, fingers and toes crossed -- and are, in effect, optimal x% of the effect, optimal then with the exception of those very far-out occurrences we have not incorporated. There is a probability that when I step outside of my door this morning I will be smote to smithereens by a minuscule meteorite. If I were to live to be millions of years old, I might be concerned. Given the window I live in, it's not reason enough to not go out of the house. Everyone knows the tails are there in most cases, and as for deviations from the shape of the Normal curve, we can account for that. So I don't find these arguments obturating enough that we don't model around them.