# Implementation of Kelly in multivariate case using modeled distributions

I am exploring how to determine an "optimal" portfolio in the context of real life data and systems. Specifically, I want to calculate a Kelly Optimal Portfolio (see this paper, especially section 8.4 for the multi-variate case). Calculating fractional allocations between strategies introduces questions the strength and stability of correlations between strategies.

[all code in mathematica]

I have two lists of daily log returns (truncated for illustration):

backret = {{0.0977634,-0.0247598,-0.00951279,.......,.412994,-0.421786,0,-0.0267264,0},{
-0.0450008,0.0460733,0.073524,0,-0.0794881,.....,.-0.0450008,0.0460733,0.073524,0,-0.0794881}}


I use the following function to calculate kelly fractions at regular windows using an unanchored lookback window:

thorpeMA[listOfReturnVectors_,riskFreeRateAnnualized_,windowsize_,stepsize_]:=
Module[{stratNumb,retLength,avgreturns,covm,fvector,riskfreevector,fres},
stratNumb = Length[listOfReturnVectors];
retLength=Length[Transpose[listOfReturnVectors]];
riskfreevector = Table[riskFreeRateAnnualized/Sqrt[360],{stratNumb}];
avgreturns=Partition[Flatten[Table[Last[MovingAverage[Take[Transpose[listOfReturnVectors],i],Min[i,windowsize]]],{i,stepsize, retLength,stepsize}]],stratNumb];
covm = Table[Covariance[Take[Transpose[listOfReturnVectors],{Max[1,i-windowsize],i}]],{i,stepsize,retLength,stepsize}];
fvector = Table[Inverse[covm[[i]]].Transpose[{avgreturns[[i]]-riskfreevector}],{i,1,Length[avgreturns]}];
fres = Partition[Flatten[fvector],stratNumb]]


This returns a list of fractions for each, which change through time:

(In practice, this calculation may needed added constraint of being >= 0 for any given strategy).

More out of curiosity than anything, I decided to explore similar calculations based on randomized (but similarly distributed) data, to see what changes and what stays the same.

eps =SmoothKernelDistribution[Transpose[backret]];
Plot3D[PDF[eps,{ x,y}], {x,-4,4},{y,-4,4} ,PlotRange->All,ImageSize->Large]


Now, the autocorrelation of each return stream is small:

AutocorrelationTest/@backret


{0.0679951,0.0303144}

However, the autocorrelation of randomly generated return streams from single-variate return stream distribution vary widely:

alph =KernelMixtureDistribution[mojr]
vauto=AutocorrelationTest/@Table[RandomVariate[alph, 10^5],200];
ListLinePlot[vauto, ImageSize->Large]


Now, I apply fraction-determining algorithm to several randomly generated return streams:

monte = Table[Transpose[RandomVariate[eps, 300]], 500];
monteF=thorpeMA[#, 0,200,30] & /@ monte;


I calculate the cumulative growth curve for each of these generated return streams and corresponding allocation fractions:

growthList[fstarvecs_,returnvecs_,stepsize_]:=Module[{fracpairs,returnmatch,growthstream,res},
fracpairs = Partition[Flatten[Table[Table[fstarvecs[[i]],stepsize],{i,Length[fstarvecs]}]],Length[returnvecs]];
returnmatch=Take[Transpose@returnvecs,Length@fracpairs];
growthstream  =Total[#]&/@(fracpairs*returnmatch);
res=FoldList[#1*(1+#2)&,1,growthstream]]


And plotting the results:

res=Table[growthList[monteF[[i]], monte[[i]],30],{i,Length[monteF]}];
ListLogPlot[Take[res,100], ImageSize->Full, Joined->True]


These results vary widely;

#[Last[Transpose[res]]]&/@{Mean, Min, Max,StandardDeviation}


{133362., -310297., 6.09435×10^7, 2.72618×10^6}

So after all this, I am left wondering if the random data is really doing anything; it seems to be randomizing the one of the key inputs to the allocation fraction, the correlation/covariance, and thus not really providing useful information. Examining the sampled distribution properties of the correlation across the random sample:

 Apply[#,{Correlation[#[[1]], #[[2]]] & /@ monte}] & /@ {Mean, Min, Max,StandardDeviation, Skewness}


{0.0265798,-0.123224,0.177558,0.0576346,0.0177617}

This compares closely to the data for the original distribution:

Correlation[backret[[1]],backret[[2]]]


0.028274

The mean correlation among random data of .0266 is small but (perhaps) not negligible. This is what I am questioning:

1. Is it possible that the correlation between the two original data distributions is being modeled somehow? How is this done?

2. Is using randomized return data in this way a useful exercise for portfolio optimization?

3. What are some approaches to modeling changing correlations throughout time?

I recognize this is a "messy" question. I have provided a lot of background to help describe what is motivating my questions. This is really more about implementation than it is concept; trying to make reasonable assumptions about real world application. I also realize that I may very well be barking up the wrong tree in this whole exercise; I am hoping that if I am, someone may be able to point out a better approach.

• Did anyone help you with this? – Ted Taylor of Life Aug 8 '16 at 9:46
• No, didn't get any feedback. I fear my question was to broad but also too detailed to engage people for specific answers. – pyrex Aug 9 '16 at 1:56
• Lol, have you tried cross validated or math? – Ted Taylor of Life Aug 23 '16 at 12:42
• I put it on twitter and Robert Frey responded. His response: It’s difficult to follow your code but it appears that you allow short positions in your non-cash portfolio. If so, you’ve lost ergodicity and did not implement Kelly. Kelly is not equivalent to a single-period, log utility optimum. – Paul Portesi Jun 16 '18 at 16:21