tag:blogger.com,1999:blog-77240852810401698362024-03-05T21:32:46.635-08:00logopt: a journey in R, Python, finance and open sourceOrvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.comBlogger18125tag:blogger.com,1999:blog-7724085281040169836.post-37009644021570124572017-05-02T20:35:00.001-07:002017-05-02T20:35:21.012-07:00<style type="text/css">
.highlight{background: #f8f8f8; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .1em;padding:0em .5em;border-radius: 4px;}
.k{color: #338822; font-weight: bold;}
.kn{color: #338822; font-weight: bold;}
.mi{color: #000000;}
.o{color: #000000;}
.ow{color: #BA22FF; font-weight: bold;}
.nb{color: #338822;}
.n{color: #000000;}
.s{color: #cc2222;}
.se{color: #cc2222; font-weight: bold;}
.si{color: #C06688; font-weight: bold;}
.nn{color: #4D00FF; font-weight: bold;}
</style>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="A-R-named-list-is-not-a-python-dictionary">A R named list is not a python dictionary<a class="anchor-link" href="#A-R-named-list-is-not-a-python-dictionary">¶</a></h1><p>In the previous post, mpiktas posted a comment that included this question "Isn't Python dictionary a named list in R?". The short answer is no, but the reason why is worth some more explanation.</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>At first sight, a named list does look a little bit as a python dictionary, it allows to retrieve values inside a list using names (i.e. strings) instead of by numerical index. The code below is also a good example on how it is possible to mix R and python code inside a Jupyter notebook</p>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [1]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="o">%</span><span class="k">load_ext</span> rpy2.ipython
</pre></div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [2]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="o">%</span><span class="k">R</span> RL <- list('one'=1, 'two'=2, 'three'=3) ; RL[['one']]
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="prompt output_prompt">Out[2]:</div>
<div class="output_text output_subarea output_execute_result">
<pre>array([ 1.])</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [3]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">PD</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'one'</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">'two'</span><span class="p">:</span><span class="mi">2</span><span class="p">,</span> <span class="s1">'three'</span><span class="p">:</span> <span class="mi">3</span><span class="p">}</span> <span class="p">;</span> <span class="n">PD</span><span class="p">[</span><span class="s1">'one'</span><span class="p">]</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="prompt output_prompt">Out[3]:</div>
<div class="output_text output_subarea output_execute_result">
<pre>1</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>But a dictionary in python can do more, the keys can be any immutable type, so you can use numbers and tuples for keys, even in one dictionary</p>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [4]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">PD</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'one'</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">:</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="s1">'three'</span><span class="p">)</span> <span class="p">:</span> <span class="mi">3</span> <span class="p">}</span> <span class="p">;</span> <span class="n">PD</span><span class="p">[(</span><span class="mi">3</span><span class="p">,</span><span class="s1">'three'</span><span class="p">)]</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="prompt output_prompt">Out[4]:</div>
<div class="output_text output_subarea output_execute_result">
<pre>3</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>And you can add by name into an existing dictionary.</p>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [5]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">PD</span><span class="p">[</span><span class="s1">'four'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">4</span> <span class="p">;</span> <span class="n">PD</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="prompt output_prompt">Out[5]:</div>
<div class="output_text output_subarea output_execute_result">
<pre>{'one': 1, 2: 2, (3, 'three'): 3, 'four': 4}</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>You need a two step approach in R, or at least I don't know a single step approach to add a named element</p>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [6]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="o">%</span><span class="k">R</span> RL[4] <- 4 ; names(RL)[4] <- 'four' ; names(RL)
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="prompt output_prompt">Out[6]:</div>
<div class="output_text output_subarea output_execute_result">
<pre>array(['one', 'two', 'three', 'four'],
dtype='<U5')</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>But there is a more fundamental difference, the python dictionary uses a hash table implementation so that access to a key is independent of the size of the dictionary, while the named list in R seems to use a sorted table of names. This makes access by names (very) slow compared to access by index in R. Here is an example, that also shows how to mix intelligently R and python.</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>The code builds (large) equivalent structures, and a random subset is defined using R (easier in R) and passed to the python code. Then we measure the access time using different approaches. In python, we use both a list and a dictionary.</p>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [7]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="kn">import</span> <span class="nn">time</span>
<span class="kn">import</span> <span class="nn">pandas</span>
<span class="n">nBits</span> <span class="o">=</span> <span class="p">[</span><span class="mi">18</span><span class="p">,</span><span class="mi">19</span><span class="p">,</span><span class="mi">20</span><span class="p">,</span><span class="mi">21</span><span class="p">]</span>
<span class="n">columns</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"Size"</span><span class="p">,</span> <span class="s2">"Python dict by key"</span><span class="p">,</span> <span class="s2">"Python list by index"</span><span class="p">,</span> <span class="s2">"R list by index"</span><span class="p">,</span> <span class="s2">"R list by key"</span><span class="p">]</span>
<span class="n">results</span> <span class="o">=</span> <span class="n">pandas</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="n">columns</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="n">nBits</span><span class="p">)</span>
<span class="n">nSamples</span> <span class="o">=</span> <span class="mi">1000</span>
<span class="k">for</span> <span class="n">nBit</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">18</span><span class="p">,</span><span class="mi">19</span><span class="p">,</span><span class="mi">20</span><span class="p">,</span><span class="mi">21</span><span class="p">]:</span>
<span class="n">n</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="o"><<</span><span class="n">nBit</span><span class="p">)</span>
<span class="n">results</span><span class="p">[</span><span class="s2">"Size"</span><span class="p">][</span><span class="n">nBit</span><span class="p">]</span> <span class="o">=</span> <span class="n">n</span>
<span class="o">%</span><span class="k">R</span> -i nSamples -o samples -i n samples <- sample(1:(n-1), nSamples, replace = FALSE)
<span class="o">%</span><span class="k">R</span> -o keys keys <- as.character(samples)
<span class="n">keys</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">keys</span><span class="p">)</span>
<span class="n">PL</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">))</span>
<span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
<span class="n">S</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">([</span><span class="n">PL</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">samples</span> <span class="p">])</span>
<span class="n">stop</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
<span class="n">results</span><span class="p">[</span><span class="s2">"Python list by index"</span><span class="p">][</span><span class="n">nBit</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">stop</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">/</span> <span class="n">nSamples</span> <span class="o">*</span> <span class="mf">1e6</span>
<span class="n">PD</span> <span class="o">=</span> <span class="p">{</span> <span class="nb">str</span><span class="p">(</span><span class="n">x</span><span class="p">):</span><span class="n">x</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">PL</span><span class="p">}</span>
<span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
<span class="n">S</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">([</span><span class="n">PD</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">keys</span><span class="p">])</span>
<span class="n">stop</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
<span class="n">results</span><span class="p">[</span><span class="s2">"Python dict by key"</span><span class="p">][</span><span class="n">nBit</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">stop</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">/</span> <span class="n">nSamples</span> <span class="o">*</span> <span class="mf">1e6</span>
<span class="o">%</span><span class="k">R</span> -i n -o RL RL <- as.list(1:n)
<span class="o">%</span><span class="k">R</span> start <- Sys.time() ; S <- 0 ; for (i in samples) { S <- S + RL[[i]] } ; stop <- Sys.time()
<span class="o">%</span><span class="k">R</span> -o idelay idelay <- stop - start
<span class="o">%</span><span class="k">R</span> names(RL) <- as.character(RL)
<span class="o">%</span><span class="k">R</span> start <- Sys.time() ; S <- 0 ; for (k in keys ) { S <- S + RL[[k]] } ; stop <- Sys.time()
<span class="o">%</span><span class="k">R</span> -o kdelay kdelay <- stop - start
<span class="n">results</span><span class="p">[</span><span class="s2">"R list by index"</span><span class="p">][</span><span class="n">nBit</span><span class="p">]</span> <span class="o">=</span> <span class="n">idelay</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">/</span> <span class="n">nSamples</span> <span class="o">*</span> <span class="mf">1e6</span>
<span class="n">results</span><span class="p">[</span><span class="s2">"R list by key"</span><span class="p">][</span><span class="n">nBit</span><span class="p">]</span> <span class="o">=</span> <span class="n">kdelay</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">/</span> <span class="n">nSamples</span> <span class="o">*</span> <span class="mf">1e6</span>
<span class="n">results</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="prompt output_prompt">Out[7]:</div>
<div class="output_html rendered_html output_subarea output_execute_result">
<div>
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>Size</th>
<th>Python dict by key</th>
<th>Python list by index</th>
<th>R list by index</th>
<th>R list by key</th>
</tr>
</thead>
<tbody>
<tr>
<th>18</th>
<td>262144</td>
<td>0.447617</td>
<td>0.257533</td>
<td>0.998974</td>
<td>1298</td>
</tr>
<tr>
<th>19</th>
<td>524288</td>
<td>0.659162</td>
<td>0.341844</td>
<td>2.00105</td>
<td>3028.03</td>
</tr>
<tr>
<th>20</th>
<td>1048576</td>
<td>0.758547</td>
<td>0.357429</td>
<td>8.03399</td>
<td>6471.99</td>
</tr>
<tr>
<th>21</th>
<td>2097152</td>
<td>0.857677</td>
<td>0.415936</td>
<td>1.02687</td>
<td>13096</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>The results have sometimes outliers, but the main result is that access by key in R is both slow and increasing with the list size.</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>There is more to say, in particular there <em>are</em> data structures in R that are based on hash tables, but they remain less flexible than a python dictionary. I am not the first person making this type of analysis, you can check e.g.</p>
<ul>
<li><a href="http://jeffreyhorner.tumblr.com/post/114524915928/hash-table-performance-in-r-part-i">http://jeffreyhorner.tumblr.com/post/114524915928/hash-table-performance-in-r-part-i</a> and sequels</li>
<li><a href="https://opendatagroup.wordpress.com/2009/07/26/hash-package-for-r/">https://opendatagroup.wordpress.com/2009/07/26/hash-package-for-r/</a> introducing <a href="https://cran.r-project.org/web/packages/hash/">https://cran.r-project.org/web/packages/hash/</a> </li>
</ul>
</div>
</div>
</div>
Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com4tag:blogger.com,1999:blog-7724085281040169836.post-13929833565669967852017-03-05T19:03:00.000-08:002017-03-05T19:03:11.964-08:00Python and R for code developmentThe previous post glossed about why I now prefer Python to write code,
including for a module like logopt. This post explains in more details
some specific differences where I prefer one of these two languages:<br />
<ul>
<li>0-based indexing in python versus 1-based indexing in R. This may seem a small difference but for me, 0-based indexing is more natural and results in less off by one errors. No less than Dijkstra opines with me on <a href="https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html">0-based indexing</a>.</li>
<li>= versus <- for assignment. I like R approach here, and I would like to see more languages doing the same. I still sometimes end up using = where I wanted ==. If only R would allow <- in call arguments. </li>
<li>CRAN versus pypi</li>
<ul>
<li>CRAN is much better for the user, the <a href="https://cran.r-project.org/web/views/">CRAN Task Views</a> is a gold mine, and in general CRAN is a better repository, with higher quality packages.</li>
<li>But publishing one CRAN is simply daunting, and the reason logopt remained in R-Forge only. The manual explaining <a href="https://cran.r-project.org/doc/manuals/r-release/R-exts.pdf">how to write extensions</a> is 178 pages long.</li>
</ul>
<li>Python has better data structures, especially the Python dictionary is something I miss whenever I write in R. Python has no native dataframe, but this is easily taken care of by importing pandas.</li>
<li>Object orientation is conceptually clean and almost easy to use in Python, less so in R.</li>
<li>Plotting is better in R. There are some effort to make Python better in that area, especially for ease of use. Matplotlib is powerful but difficult to master.</li>
<li>lm is a gem in R, the simplicity with which you can express the expressions you want to model is incredible</li>
</ul>
All in all, I prefer coding in Python. This is a personal opinion of course, and R remains important because of some packages, but for more general purpose tasks, Python is simpler to use, and that translates in being more productive. Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com13tag:blogger.com,1999:blog-7724085281040169836.post-71266791560212166042017-02-20T13:43:00.002-08:002017-02-20T14:07:20.495-08:00Rebooting with Python and JupyterThis blog has been inactive for a long time for essentially two reasons:<br />
<br />
<ul>
<li>I was not very happy with the quality of the results</li>
<ul>
<li>The source code was not showing very nicely</li>
<li>It was difficult to get a nice display, including for pictures and mathematical expressions</li>
</ul>
<li>I started to use Python almost exclusively</li>
<ul>
<li>R is a nice language, but it is not a general purpose language, some tasks are hard in R compared to Python</li>
<li>At the other hand, Python has steadily improved in the area of data processing, with pandas providing something equivalent to the R dataframe</li>
</ul>
</ul>
But now, there is a good way to solve both problems, <a href="http://jupyter.org/">Jupyter</a> notebooks combined with the ability to directly include HTML in a post. So it is time for a reboot.<br />
<br />
Jupyter was originally know as iPython but has evolved to support many programming languages, including R. This allows now to develop a notebook, possibly based on multiple languages, then convert it for posting, while keeping the original notebook available for people that wants a more interactive experience. The development process is much simpler that way that it used to be for earlier posts.<br />
<br />
As an example, the rest of this post is this <a href="https://github.com/mdelvaux/logopt/blob/master/blog/RebootJupyterPython/R_and_python.ipynb">notebook</a> converted to HTML. Note that the notebook contains both R and Python code interacting in an almost seamless way. How to achieve that result will be explained in later posts.
<br /> <br />
<style type="text/css">
.highlight{background: #f8f8f8; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .1em;padding:0em .5em;border-radius: 4px;}
.k{color: #338822; font-weight: bold;}
.kn{color: #338822; font-weight: bold;}
.mi{color: #000000;}
.o{color: #000000;}
.ow{color: #BA22FF; font-weight: bold;}
.nb{color: #338822;}
.n{color: #000000;}
.s{color: #cc2222;}
.se{color: #cc2222; font-weight: bold;}
.si{color: #C06688; font-weight: bold;}
.nn{color: #4D00FF; font-weight: bold;}
</style>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [1]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="o">%</span><span class="k">load_ext</span> rpy2.ipython
</pre></div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [2]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="o">%%</span>R <span class="o">-</span>o x <span class="o">-</span>o xik <span class="o">-</span>o n <span class="o">-</span>o pik
<span class="c1"># figure 8.1 of Cover "Universal Portfolios"</span>
<span class="kn">library</span><span class="p">(</span>logopt<span class="p">)</span>
data<span class="p">(</span>nyse.cover.1962.1984<span class="p">)</span>
n <span class="o"><-</span> nyse.cover.1962.1984
x <span class="o"><-</span> coredata<span class="p">(</span>nyse.cover.1962.1984<span class="p">)</span>
xik <span class="o"><-</span> x<span class="p">[,</span><span class="kt">c</span><span class="p">(</span><span class="s">"iroqu"</span><span class="p">,</span><span class="s">"kinar"</span><span class="p">)]</span>
nDays <span class="o"><-</span> <span class="kp">dim</span><span class="p">(</span>xik<span class="p">)[</span><span class="m">1</span><span class="p">]</span>
Days <span class="o"><-</span> <span class="m">1</span><span class="o">:</span>nDays
pik <span class="o"><-</span> <span class="kp">apply</span><span class="p">(</span>xik<span class="p">,</span><span class="m">2</span><span class="p">,</span><span class="kp">cumprod</span><span class="p">)</span>
plot<span class="p">(</span>Days<span class="p">,</span> pik<span class="p">[,</span><span class="s">"iroqu"</span><span class="p">],</span> col<span class="o">=</span><span class="s">"blue"</span><span class="p">,</span> type<span class="o">=</span><span class="s">"l"</span><span class="p">,</span>
ylim<span class="o">=</span><span class="kp">range</span><span class="p">(</span>pik<span class="p">),</span> main <span class="o">=</span> <span class="s">'"iroqu" and "kinar"'</span><span class="p">,</span> ylab<span class="o">=</span><span class="s">""</span><span class="p">)</span>
lines<span class="p">(</span>Days<span class="p">,</span> pik<span class="p">[,</span><span class="s">"kinar"</span><span class="p">],</span> col<span class="o">=</span><span class="s">"red"</span><span class="p">)</span>
grid<span class="p">()</span>
legend<span class="p">(</span><span class="s">"topright"</span><span class="p">,</span><span class="kt">c</span><span class="p">(</span><span class="s">'"iroqu"'</span><span class="p">,</span><span class="s">'"kinar"'</span><span class="p">),</span>
col<span class="o">=</span><span class="kt">c</span><span class="p">(</span><span class="s">"blue"</span><span class="p">,</span><span class="s">"red"</span><span class="p">),</span>lty<span class="o">=</span><span class="kt">c</span><span class="p">(</span><span class="m">1</span><span class="p">,</span><span class="m">1</span><span class="p">))</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt"></div>
<div class="output_png output_subarea ">
<img src="data:image/png;base64,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
cCFg4Pp/bLcaP5+bf1sAAAAASUVORK5CYII=
"
>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [3]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
<span class="kn">import</span> <span class="nn">matplotlib</span> <span class="k">as</span> <span class="nn">mpl</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="nn">plt</span>
<span class="n">plt</span><span class="o">.</span><span class="n">ion</span><span class="p">()</span>
<span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">6</span><span class="p">,</span><span class="mi">4</span><span class="p">))</span>
<span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">pik</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">grid</span><span class="p">()</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area"><div class="prompt"></div>
<div class="output_subarea output_stream output_stdout output_text">
<pre>[[ 1.01515 1.02765 1.04183 ..., 1.00578 0.99697 0.99752]
[ 1.01493 1.04036 0.98905 ..., 1.00958 0.99088 1.00248]
[ 1. 0.97629 0.97786 ..., 1. 1.02761 0.99752]
...,
[ 0.99029 0.9966 0.99605 ..., 0.99216 1.00461 0.99273]
[ 0.99265 1.00683 1. ..., 0.99209 1.02752 1.00366]
[ 0.99753 1.00339 1.01984 ..., 1.01195 1. 0.99635]]
<class 'numpy.ndarray'>
</pre>
</div>
</div>
<div class="output_area"><div class="prompt"></div>
<div class="output_png output_subarea ">
<img src="data:image/png;base64,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
"
>
</div>
</div>
</div>
</div>
</div>
Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com0tag:blogger.com,1999:blog-7724085281040169836.post-56013115881649464652012-11-22T16:11:00.000-08:002012-11-22T16:11:45.040-08:00Escaping the simplex, part 1Before tackling the main subject, two quick notes:<br />
<br />
<ul>
<li>I did not post for quite a while in part because I followed the Coursera online course <a href="https://www.coursera.org/course/compfinance">Introduction to Computational Finance and Financial Econometrics</a>. It was a nice refresher, extremely well presented, and including some R. This did consume enough time to make posting cumbersome though.</li>
<li>I started using <a href="http://www.rstudio.com/">R studio</a>, and I am quite happy with it under Windows. This has also impacted my code, as R studio automatically stacks your plots.</li>
</ul>
The main topic of this post is to motivate an escape from the simplex, i.e. allow for weights either larger than 1 or smaller than 0. Generally, this implies going short on one asset deemed less favorable and shift the short proceed to a deemed more favorable asset.<br />
<div>
<br /></div>
<div>
The main reason to do so is that the Best Constant Rebalanced Portfolio (BCRP) may lie outside. This is a well known feature in the more traditional mean-variance analysis, where the constrained portfolio is sparser than the unconstrained one. We have a similar effect for the BCRP, the constrained optimization results in a sparse portfolio, i.e. many weights are (close to) zero.</div>
<div>
<br /></div>
<div>
We can illustrate this by calculating the weights of the constrained BCRP. The BCRP function in logopt is currently only supporting optimization on the simplex, and we can reuse the code originally presented in <a href="http://optimallog.blogspot.com/2012/08/universal-portfolio-part-10.html">Universal portfolio, part 10</a> to accumulate the portfolio weights for BCRP across multiple combinations of the reference data. This shows that the proportion of (close to) zero weights is high.</div>
<div>
<br /></div>
<div>
The code below as is runs for about 7 hours because of the large number of combinations, you can reduce the size of the problem if wanted by editing TupleSizes.<br />
<br />
Note that in the past Syntax Highlighter had problems with R-bloggers, you might need to go to the original page to view the code.</div>
<div>
<br /></div>
<pre class="brush: r"># assume the use of RStudio (no explicit management of graphic devices)
library(logopt)
data(nyse.cover.1962.1984)
x <- coredata(nyse.cover.1962.1984)
nStocks <- dim(x)[2]
EvaluateOnAllTuples <- function(ListName, TupleSizes, fFinalWealth, ...) {
if (exists(ListName) == FALSE) {
LocalList <- list()
for (i in 1:length(TupleSizes)) {
TupleSize <- TupleSizes[i]
ws <- combn(x=(1:nStocks), m=(TupleSize), FUN=fFinalWealth, simplify=TRUE, ...)
LocalList[[i]] <- ws
}
assign(ListName, LocalList, pos=parent.frame())
}
}
TupleSizes <- c(2,3,4,5)
# evaluate the sorted coefficients for best CRP
SortedOptB <- function(cols, ...) {
x <- list(...)[[1]] ;
x <- x[,cols]
b <- bcrp.optim(x)
return(sort(b))
}
TupleSizes <- c(2,3,4,5)
EvaluateOnAllTuples("lSortedOptBSmall", TupleSizes, SortedOptB, x)
TupleSizes <- c(nStocks-3,nStocks-2,nStocks-1,nStocks)
EvaluateOnAllTuples("lSortedOptBLarge", TupleSizes, SortedOptB, x)
Colors <- c("red", "green", "blue", "brown", "cyan", "darkred","darkgreen")
for (iL in 1:length(lSortedOptBSmall)) {
nCoeff <- nrow(lSortedOptBSmall[[iL]])
E <- ecdf(lSortedOptBSmall[[iL]][1,])
Title <- sprintf("Cumulative PDF for all sorted weights for BCRP of %d assets", nCoeff)
plot(E, col=Colors[1], xlim=c(0,1), pch=".", main = Title, xlab = "relative weight")
cat(sprintf("Combinations of %d assets\n", nCoeff))
for (iB in 1:nCoeff) {
E <- ecdf(lSortedOptBSmall[[iL]][iB,])
lines(E, col=Colors[iB], pch=".")
if (iB < nCoeff) {
cat(sprintf("Percent of portfolio with %d weight(s) smaller than 0.001: %f\n", iB, E(0.001) ))
}
}
}
SmallOf2 <- lSortedOptBSmall[[1]][1,]
hist(SmallOf2,n=25,probability=TRUE, main="Histogram of smallest weight for two assets",
xlab="Smallest coefficient")
lines(density(SmallOf2, bw=0.02),col="blue")
# for the large ones, we show only the largest coefficients and show them in
# opposite order to find how many coefficients are not always insiginifcant
for (iL in 1:length(lSortedOptBLarge)) {
nCoeff <- nrow(lSortedOptBLarge[[iL]])
E <- ecdf(lSortedOptBLarge[[iL]][nCoeff,])
Title <- sprintf("Cumulative PDF for largest sorted weights for BCRP of %d assets", nCoeff)
plot(E, col=Colors[1], xlim=c(0,1), pch=".", main = Title, xlab = "relative weight")
cat(sprintf("Combinations of %d assets\n", nCoeff))
for (iB in 1:nCoeff) {
iCoeff <- nCoeff-iB+1
E <- ecdf(lSortedOptBLarge[[iL]][iCoeff,])
if (E(0.001) < 0.9999) {
lines(E, col=Colors[iB], pch=".")
cat(sprintf("Percent of portfolio with %d weight(s) smaller than 0.001: %f\n", iCoeff, E(0.001) ))
}
}
}
</pre>
<br />
Only a subset of the results are shown below, first the cumulative probability function for the weights of the coefficients for all combinations of 5 assets. The graph shows that the smallest coefficient is almost always 0 and the second coefficient is also very small all of the time. The textual output shows that the second coefficient is insignificant 91% of the time or equivalently 91% of the best portfolio only uses 3 of the 5 possible assets.<br />
<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">Combinations of 5 assets</span><br />
<span style="font-family: Courier New, Courier, monospace;">Percent of portfolio with 1 weight(s) smaller than 0.001: 0.996499</span><br />
<span style="font-family: Courier New, Courier, monospace;">Percent of portfolio with 2 weight(s) smaller than 0.001: 0.914086</span><br />
<span style="font-family: Courier New, Courier, monospace;">Percent of portfolio with 3 weight(s) smaller than 0.001: 0.499448</span><br />
<span style="font-family: Courier New, Courier, monospace;">Percent of portfolio with 4 weight(s) smaller than 0.001: 0.067975</span><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPTsK8-bgrT-yfZ2pzmaP7j6pOO6VBbmywFScMx_B1TmCWzGVQdTRjWeh6Oiwf_q1NMBUAKzbA6qqaEYEp6b1seYrjyoaSIq5N2w-7hZEnpnLw1YRduP9Z0PqsKrpkWeb8_7TaSVLNJ6Y/s1600/ecdf_weights_for_5_assets.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="522" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPTsK8-bgrT-yfZ2pzmaP7j6pOO6VBbmywFScMx_B1TmCWzGVQdTRjWeh6Oiwf_q1NMBUAKzbA6qqaEYEp6b1seYrjyoaSIq5N2w-7hZEnpnLw1YRduP9Z0PqsKrpkWeb8_7TaSVLNJ6Y/s640/ecdf_weights_for_5_assets.png" width="640" /></a></div>
<br />
The density for the two asset case shows clearly that there is a high peak at zero.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj15ZeKjCJRrb6b5z8Ms-cZt55FRR4lWopzsdzyHcX6EN9W_SpNWd0wtFVJweLaAY8ahahIfwuWDOujx4m3u3jX-4d1gegryyTEeOgTA3vlaymG7YeHDaJmzsqjzZMi_JZ3uVqEJJnNgNA/s1600/pdf_2_asset.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="522" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj15ZeKjCJRrb6b5z8Ms-cZt55FRR4lWopzsdzyHcX6EN9W_SpNWd0wtFVJweLaAY8ahahIfwuWDOujx4m3u3jX-4d1gegryyTEeOgTA3vlaymG7YeHDaJmzsqjzZMi_JZ3uVqEJJnNgNA/s640/pdf_2_asset.png" width="640" /></a></div>
<br />
Finally the textual output and the ECDF shows that for 33 possible assets, only up to 7 are present in the BCRP<br />
<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">Combinations of 33 assets</span><br />
<span style="font-family: Courier New, Courier, monospace;">Percent of portfolio with 33 weight(s) smaller than 0.001: 0.000000</span><br />
<span style="font-family: Courier New, Courier, monospace;">Percent of portfolio with 32 weight(s) smaller than 0.001: 0.000000</span><br />
<span style="font-family: Courier New, Courier, monospace;">Percent of portfolio with 31 weight(s) smaller than 0.001: 0.000000</span><br />
<span style="font-family: Courier New, Courier, monospace;">Percent of portfolio with 30 weight(s) smaller than 0.001: 0.000000</span><br />
<span style="font-family: Courier New, Courier, monospace;">Percent of portfolio with 29 weight(s) smaller than 0.001: 0.065126</span><br />
<span style="font-family: Courier New, Courier, monospace;">Percent of portfolio with 28 weight(s) smaller than 0.001: 0.707843</span><br />
<span style="font-family: Courier New, Courier, monospace;">Percent of portfolio with 27 weight(s) smaller than 0.001: 0.947059</span><br />
<div>
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XlHwkf3TYm04W-QAg1F7P1VWMmfqsS8JilNHXB3lAD1hRWnYQrC2msclrnzoVBa4HxbX8hUujFCmc_7xWQGMbHJXiyuxtyKO_tfU791zVvtiWjFvgjmTHnOo3EyCG24-UCALdfLs3Gg/s1600/ecdf_33_assets.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="522" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XlHwkf3TYm04W-QAg1F7P1VWMmfqsS8JilNHXB3lAD1hRWnYQrC2msclrnzoVBa4HxbX8hUujFCmc_7xWQGMbHJXiyuxtyKO_tfU791zVvtiWjFvgjmTHnOo3EyCG24-UCALdfLs3Gg/s640/ecdf_33_assets.png" width="640" /></a></div>
All this points to the fact that most of the weights of the BCRP end up on the boundary of the simplex, and that removing that specific constraint would get an even better solution, at least in term of terminal wealth. We'll investigate further this in future posts.Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com1tag:blogger.com,1999:blog-7724085281040169836.post-29308983022757196972012-09-23T19:56:00.000-07:002012-09-24T20:37:46.979-07:00Universal portfolio, part 11First an apology, the links to the Universal Portfolio paper have stopped working. This is because the personal webpage of Thomas Cover at Stanford has been taken down, but fortunately the content moved elsewhere. The new link is <a href="http://www-isl.stanford.edu/~cover/papers/paper93.pdf">Universal Portfolio</a> and hopefully this one will be stable.<br />
<br />
Note that there are many available copies on the web but most (like <a href="http://stuff.mit.edu/afs/athena/course/6/6.962/www/www_fall_2001/shaas/universal_portfolios.pdf">this one</a>) are for something that seems to be a slighly reworked version dated October 23 1996. The text appears mostly identical to the published version, but it does not include the figures.<br />
<br />
In the rest of this post, I discuss the data used by Cover. That data is included in <span style="font-family: Courier New, Courier, monospace;">logopt</span> as <span style="font-family: Courier New, Courier, monospace;">nyse.cover.1962.1984</span>. It contains the relative prices for 36 NYSE stocks between 1962 and 1984.<br />
<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">> range(index(nyse.cover.1962.1984))</span><br />
<span style="font-family: Courier New, Courier, monospace;">[1] "1962-07-03" "1984-12-31"</span><br />
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">> colnames(nyse.cover.1962.1984)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> [1] "ahp" "alcoa" "amerb" "arco" "coke" "comme" "dow" "dupont" "espey" "exxon" "fisch" "ford" "ge" "gm" "gte" "gulf" "hp" </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">[18] "ibm" "inger" "iroqu" "jnj" "kimbc" "kinar" "kodak" "luken" "meico" "merck" "mmm" "mobil" "morris" "pandg" "pills" "schlum" "sears" </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">[35] "sherw" "tex" </span></div>
</div>
<div>
<br /></div>
<div>
The names are not stickers, some guessing and with some help from an <a href="http://www.cais.ntu.edu.sg/~libin/portfolios/NYSE_O_Dataset.html">other person using the series</a> gives the table below (and if anybody knows about the one without expansion yet. please post a comment).<br />
<br />
<table border="1">
<tbody>
<tr>
<th>Abbreviation</th>
<th>Company name</th>
<th>Current ticker</th>
</tr>
<tr>
<td>ahp</td>
<td>?</td>
<td>?</td>
</tr>
<tr>
<td>alcoa</td>
<td>Alcoa</td>
<td>AA</td>
</tr>
<tr>
<td>amerb</td>
<td>American Brands<br />
aka Fortune Brands</td>
<td>-</td>
</tr>
<tr>
<td>arco</td>
<td>?</td>
<td>?</td>
</tr>
<tr>
<td>coke</td>
<td>Coca-Cola</td>
<td>KO</td>
</tr>
<tr>
<td>comme</td>
<td>Commercial Metals</td>
<td>CMC</td>
</tr>
<tr>
<td>dow</td>
<td>Dow Chemicals</td>
<td>DOW</td>
</tr>
<tr>
<td>dupont</td>
<td>DuPont</td>
<td>DD</td>
</tr>
<tr>
<td>espey</td>
<td>Espey Manufacturing</td>
<td>ESP</td>
</tr>
<tr>
<td>exxon</td>
<td>Exxon Mobil</td>
<td>XOM</td>
</tr>
<tr>
<td>coke</td>
<td>Coca-Cola</td>
<td>KO</td>
</tr>
<tr>
<td>fisch</td>
<td>Fischbach Corp</td>
<td>-</td>
</tr>
<tr>
<td>ford</td>
<td>Ford</td>
<td>F</td>
</tr>
<tr>
<td>ge</td>
<td>General Electric</td>
<td>GE</td>
</tr>
<tr>
<td>gm</td>
<td>General Motors</td>
<td>GM*</td>
</tr>
<tr>
<td>gte</td>
<td>GTE Corporation</td>
<td>-</td>
</tr>
<tr>
<td>gulf</td>
<td>Gulf Oil (now Chevron)</td>
<td>CVX</td>
</tr>
<tr>
<td>hp</td>
<td>Hewlett-Packard</td>
<td>HPQ</td>
</tr>
<tr>
<td>ibm</td>
<td>IBM</td>
<td>IBM</td>
</tr>
<tr>
<td>inger</td>
<td>Ingersoll-Rand</td>
<td>IR</td>
</tr>
<tr>
<td>iroq</td>
<td>Iroquois Brands</td>
<td>-</td>
</tr>
<tr>
<td>jnj</td>
<td>Johnson & Johnson</td>
<td>JNJ</td>
</tr>
<tr>
<td>kimbc</td>
<td>Kimberly-Clark</td>
<td>KMB</td>
</tr>
<tr>
<td>kinar</td>
<td>Kinark?</td>
<td>-</td>
</tr>
<tr>
<td>kodak</td>
<td>Eastman Kodak</td>
<td>EKDKQ</td>
</tr>
<tr>
<td>luken</td>
<td>Lukens?</td>
<td>-</td>
</tr>
<tr>
<td>meico</td>
<td>?</td>
<td>?</td>
</tr>
<tr>
<td>merck</td>
<td>Merck</td>
<td>MRK</td>
</tr>
<tr>
<td>mmm</td>
<td>3M</td>
<td>MMM</td>
</tr>
<tr>
<td>mobil</td>
<td>Exxon Mobil</td>
<td>XOM</td>
</tr>
<tr>
<td>morris</td>
<td>Philip Morris</td>
<td>PM</td>
</tr>
<tr>
<td>pandg</td>
<td>Procter & Gamble</td>
<td>PG</td>
</tr>
<tr>
<td>pills</td>
<td>Pillsbury, now part of General Mills</td>
<td>-</td>
</tr>
<tr>
<td>schlum</td>
<td>Schlumberger</td>
<td>SLB</td>
</tr>
<tr>
<td>sears</td>
<td>Sears Holdings</td>
<td>SHLD</td>
</tr>
<tr>
<td>sherw</td>
<td>Sherwin-Williams</td>
<td>SHW</td>
</tr>
<tr>
<td>tex</td>
<td>Texaco, now Chevron</td>
<td>CVX</td>
</tr>
</tbody></table>
<br />
There is a lot of diversity across the different stocks, we saw that in two ways:<br />
<br />
<ul>
<li>by showing the global time evolution of all stocks in time</li>
<li>by showing the growth rate at two times separated by N market days (shown as a price relative between the two dates).</li>
</ul>
<br />
<pre class="brush: r"># Some statistics on the NYSE series
library(logopt)
x <- coredata(nyse.cover.1962.1984)
w <- logopt:::x2w(x)
nDays <- dim(x)[1]
nStocks <- dim(x)[2]
Days <- 1:nDays
iWin <- 1 ; plot(1:10)
Time <- index(nyse.cover.1962.1984)
# for each stock calculate:
# - min, max
# - average geometric return
MaxFinal <- max(w[nDays,])
MinFinal <- min(w[nDays,])
MaxAll <- max(w)
MinAll <- min(w)
if(length(dev.list()) < iWin) { x11() } ; iWin <- iWin + 1 ; dev.set(iWin) ;
plot(Time, w[,1], col="gray", ylim=range(w), log="y", type="l")
for (i in 1:nStocks) {
lines(Time, w[,i], col="gray")
if (w[nDays,i] == MaxFinal) { cat(sprintf("Stock with best final value: %s finishing at %.2f\n", colnames(w)[i], MaxFinal)) ; iMax <- i }
if (w[nDays,i] == MinFinal) { cat(sprintf("Stock with worst final value: %s finishing at %.2f\n", colnames(w)[i], MinFinal)) ; iMin <- i }
if (max(w[,i]) == MaxAll) { cat(sprintf("Stock with best peak value: %s at %.2f\n", colnames(w)[i], MaxAll)) }
if (min(w[,i]) == MinAll) { cat(sprintf("Stock with worst valley value: %s at %.2f\n", colnames(w)[i], MinAll)) }
}
lines(Time, w[,iMax], col="green")
lines(Time, w[,iMin], col="red")
lines(Time, apply(w,1,mean), col="blue")
grid()
# do a summary across n quotes
nDelta <- 1200
wD <- w[(nDelta+1):nDays,] / w[1:(nDays-nDelta),]
Time <- Time[1:(nDays-nDelta)]
MaxDAll <- max(wD)
MinDAll <- min(wD)
if(length(dev.list()) < iWin) { x11() } ; iWin <- iWin + 1 ; dev.set(iWin) ;
plot(Time, wD[,1], col="gray", ylim=range(wD), log ="y", type="l")
for (i in 1:nStocks) {
lines(Time, wD[,i], col="gray")
if (max(wD[,i]) == MaxDAll) { cat(sprintf("Stock with best gain on %s days: %s at %.2f\n", nDelta, colnames(w)[i], MaxDAll)) }
if (min(wD[,i]) == MinDAll) { cat(sprintf("Stock with worst lost on %s days: %s at %.2f\n", nDelta, colnames(w)[i], MinDAll)) }
}
lines(Time, apply(wD,1,mean), col="blue")
grid()
</pre>
<br />
This gives the following textual answer and graphs. Note that there are many alternate ways to present this information, in particular the package<a href="http://cran.r-project.org/web/packages/PerformanceAnalytics/index.html"> PerformanceAnalytics</a>.<br />
<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">Stock with worst final value: dupont finishing at 3.07</span><br />
<span style="font-family: Courier New, Courier, monospace;">Stock with worst valley value: meico at 0.26</span><br />
<span style="font-family: Courier New, Courier, monospace;">Stock with best final value: morris finishing at 54.14</span><br />
<span style="font-family: Courier New, Courier, monospace;">Stock with best peak value: schlum at 90.12</span><br />
<span style="font-family: Courier New, Courier, monospace;">Stock with best gain on 1200 days: espey at 15.84</span><br />
<span style="font-family: Courier New, Courier, monospace;">Stock with worst lost on 1200 days: meico at 0.07</span><br />
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEit2O0LP_3lHpFFt5PM7qPH-WYPSw-VB3u9StTnJ2Ej4azdYQOr3-A3R9e9oCxGixAYnIvWaGTbEN8LXjTvqux9IHREGsZB9zZNjkyZxoO91VeTCQXB0wpojLVAqKljxILd3AQibxrCJfY/s1600/TimeEvolutionAll.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="634" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEit2O0LP_3lHpFFt5PM7qPH-WYPSw-VB3u9StTnJ2Ej4azdYQOr3-A3R9e9oCxGixAYnIvWaGTbEN8LXjTvqux9IHREGsZB9zZNjkyZxoO91VeTCQXB0wpojLVAqKljxILd3AQibxrCJfY/s640/TimeEvolutionAll.png" width="640" /></a></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJt3o7EtWMj3A0NhuFXvPdE_ZMC14eafGR56s5iGBG_tIrnh_IZFU3AsBB2d1fgJuCcf3jNt_juxziFDRHkOxXpFaK4TqphmkRzoOJqJ5NGl0_13PVVK93SPbNhKzIEPJ7S3uaM4M36H4/s1600/GrowthRateAll.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="634" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJt3o7EtWMj3A0NhuFXvPdE_ZMC14eafGR56s5iGBG_tIrnh_IZFU3AsBB2d1fgJuCcf3jNt_juxziFDRHkOxXpFaK4TqphmkRzoOJqJ5NGl0_13PVVK93SPbNhKzIEPJ7S3uaM4M36H4/s640/GrowthRateAll.png" width="640" /></a></div>
<div>
<br /></div>
<div>
This sequence forms a nice reference covering a long period of time, and has been used in many studies of portfolio selection algorithms. But the series has a number of serious problems:</div>
<div>
<ul>
<li>Survivorship bias</li>
<li>The time range corresponds to a time where quotes were not yet decimal.</li>
</ul>
</div>
</div>
Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com2tag:blogger.com,1999:blog-7724085281040169836.post-35788089065187935442012-08-10T21:05:00.000-07:002012-08-12T18:43:50.231-07:00Universal portfolio, part 10<a href="http://optimallog.blogspot.com/2012/07/universal-portfolio-part-9.html">Part 9</a> compared the wealth of Universal against other portfolio selection algorithms by using the experimental cumulative distribution function of the relative wealth. This leads to a very compact representation, but it completely hides the absolute level evolution as the number of stocks in a portfolio increases.<br />
<br />
The code below uses a slightly different approach, it uses a scatterplot where the final absolute wealth of two different algorithms are used for the x and y axes. The main diagonal corresponds to both algorithms having an equal final wealth. To provide more information, side graphs with the marginal probability of final wealth are included.<br />
<br />
Finally, an other reference is added, the best CRP, using the optimization code in package <span style="font-family: Courier New, Courier, monospace;">logopt</span>.<br />
<br />
As in part 9, the code recalculates the value of Universal final wealth across all 4-tuples and thus takes one day to run if you did not have yet the results in your environment, be warned.
Also, the code presentation uses <a href="http://alexgorbatchev.com/SyntaxHighlighter/">Syntax Highlighter</a>, I am still experimenting with the best way to present R code.<br />
<br />
<br />
<pre class="brush: r"># Performance of Universal compared to some references
library(logopt)
x <- coredata(nyse.cover.1962.1984)
w <- logopt:::x2w(x)
nDays <- dim(x)[1]
nStocks <- dim(x)[2]
Days <- 1:nDays
iWin <- 1 ; plot(1:10)
TupleSizes <- c(2,3,4)
EvaluateOnAllTuples <- function(ListName, TupleSizes, fFinalWealth, ...) {
if (exists(ListName) == FALSE) {
LocalList <- list()
for (i in 1:length(TupleSizes)) {
TupleSize <- TupleSizes[i]
ws <- combn(x=(1:nStocks), m=(TupleSize), FUN=fFinalWealth, simplify=TRUE, ...)
LocalList[[i]] <- ws
}
assign(ListName, LocalList, pos=parent.frame())
}
}
UniversalFinalWealth <- function(cols, ...) {
x <- list(...)[[1]] ; n <- list(...)[[2]]
uc <- universal.cover(x[,cols], 20)
return(uc[length(uc)])
}
EvaluateOnAllTuples("lUniversalFinalWealth", TupleSizes, UniversalFinalWealth, x, 20)
BestStockFinalWealth <- function(cols, ...) {
w <- list(...)[[1]]
return(max(w[nDays,cols]))
}
EvaluateOnAllTuples("lBestStockFinalWealth", TupleSizes, BestStockFinalWealth, w)
UcrpFinalWealth <- function(cols, ...) {
x <- list(...)[[1]]
ucrp <- crp(x[,cols])
return(ucrp[length(ucrp)])
}
EvaluateOnAllTuples("lUcrpFinalWealth", TupleSizes, UcrpFinalWealth, x)
BhFinalWealth <- function(cols, ...) {
x <- list(...)[[1]]
ubh <- bh(x[,cols])
return(ubh[length(ubh)])
}
EvaluateOnAllTuples("lBhFinalWealth", TupleSizes, BhFinalWealth, x)
BestCrpFinalWealth <- function(cols, ...) {
x <- list(...)[[1]]
bopt <- bcrp.optim(x[,cols])
bcrp <- crp(x[,cols],bopt)
return(bcrp[length(bcrp)])
}
EvaluateOnAllTuples("lBestCrpFinalWealth", TupleSizes, BestCrpFinalWealth, x)
Colors <- c("blue","green","red")
CompareFinalAbsoluteWealth <- function( L0, L1, MainString, TupleSizes=TupleSizes, clip=0.01,
Colors=c("blue","green","red"), PlotChar = 19, PlotSize = 0.5,
XLabel="Universal wealth", YLabel="Other wealth") {
nLines <- min(length(L0),length(L1))
if (clip > 0) { MaxUp <- quantile(c(L0[[nLines]], L1[[nLines]]), 1-clip) }
else { MaxUp <- max(L0, L1) }
XLims = c(0, MaxUp)
layout( matrix( c(0,2,2,1,3,3,1,3,3),ncol=3) )
d.x <- density(L0[[1]])
plot(d.x$x, d.x$y, xlim=XLims, type='l', col=Colors[1], main="Density on x axis", xlab="", ylab="")
grid()
for (i in 1:nLines) {
d.x <- density(L0[[i]])
lines(d.x$x, d.x$y, type='l', col=Colors[i])
abline(v=mean(L0[[i]]), col=Colors[i])
}
d.y <- density(L1[[1]])
plot(d.y$y, d.y$x, ylim=XLims, xlim=rev(range(d.y$y)), type='l', col=Colors[1], , main="Density on y axis", xlab="", ylab="")
grid()
for (i in 1:nLines) {
d.y <- density(L1[[i]])
lines(d.y$y, d.y$x, type='l', col=Colors[i])
abline(h=mean(L1[[i]]), col=Colors[i])
}
plot(L0[[nLines]], L1[[nLines]], col=Colors[nLines], pch=PlotChar, cex=PlotSize,
xlab=XLabel, ylab=YLabel, xlim= XLims, ylim= XLims, type="p", main=MainString)
for (j in 1:nLines) {
i <- nLines - j + 1
points(L0[[i]], L1[[i]], col=Colors[i], pch=PlotChar, cex=PlotSize)
rug(L0[[i]], col=Colors[i],ticksize=0.01*i)
rug(L1[[i]], col=Colors[i],ticksize=0.01*i, side=2)
}
abline(0,1,col="lightgray",lwd=2)
legend("topright", legend=c("2 stocks","3 stocks","4 stocks"), pch=PlotChar, col=Colors, bg="white")
grid()
}
if(length(dev.list()) < iWin) { x11() } ; iWin <- iWin + 1 ; dev.set(iWin) ;
CompareFinalAbsoluteWealth(lUniversalFinalWealth, lBestStockFinalWealth, "Universal relative to best stock final wealth", TupleSizes)
if(length(dev.list()) < iWin) { x11() } ; iWin <- iWin + 1 ; dev.set(iWin) ;
CompareFinalAbsoluteWealth(lUniversalFinalWealth, lBhFinalWealth, "Universal relative to uniform buy and hold final wealth", TupleSizes)
if(length(dev.list()) < iWin) { x11() } ; iWin <- iWin + 1 ; dev.set(iWin) ;
CompareFinalAbsoluteWealth(lUniversalFinalWealth, lUcrpFinalWealth, "Universal relative to uniform CRP final wealth", TupleSizes)
if(length(dev.list()) < iWin) { x11() } ; iWin <- iWin + 1 ; dev.set(iWin) ;
CompareFinalAbsoluteWealth(lUniversalFinalWealth, lBestCrpFinalWealth, "Universal relative to best CRP final wealth", TupleSizes)
# a function to compare the ECDF of two lists of final wealths
CompareFinalRelativeWealth <- function( L0, L1, MainString, TupleSizes=TupleSizes,
Colors=c("blue","green","red"), PlotChar = ".",
XLabel="Ratio of final wealths", YLabel="Cumulative probability") {
nLines <- min(length(L0),length(L1))
LR <- list() ; XLims = c()
for(i in 1:nLines) { LR[[i]] <- L0[[i]]/L1[[i]] ; XLims <- range(XLims, LR[[i]]) }
plot(ecdf(L0[[1]]/L1[[1]]), pch=PlotChar, col=Colors[1], main=MainString,
xlab=XLabel, ylab=YLabel, xlim= XLims)
abline(v=1,col="gray",lwd=2)
for (i in 1:nLines) {
lines(ecdf(L0[[i]]/L1[[i]]), pch=PlotChar, col=Colors[i])
}
legend("bottomright", legend=c("2 stocks","3 stocks","4 stocks"), fill=Colors)
grid()
# show best relative wealth and its composition
for (i in 1:length(TupleSizes)) {
TupleSize <- TupleSizes[i]
BestTuple <- which.max(LR[[i]])
BestStocks <- combn(1:nStocks, TupleSize)[,BestTuple]
cat(sprintf("Max final relative wealth %.4f for stocks: ", LR[[i]][BestTuple]))
cat(colnames(x)[BestStocks]) ; cat("\n")
}
}
if(length(dev.list()) < iWin) { x11() } ; iWin <- iWin + 1 ; dev.set(iWin) ;
CompareFinalRelativeWealth(lUniversalFinalWealth, lBestCrpFinalWealth, "Universal relative to best CRP final wealth", TupleSizes)
</pre>
<br />
The first graph compares Universal to the best stock in the portfolio. It also shows that the density function is not an ideal solution when the set of possible outcomes is discrete. The ecdf function would be a better choice in this case. The plot is also slightly misleading when compared to the equivalent plot of relative wealth in part 9. The problem is that points overlap and so the 2D density cannot be assessed except for the set of blue points.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0p5BrWLrTAaQQEBvbszpvqoNzY3H42GHPVGVcEJQdtfoL9WYp3P7_ui-kHY3mO6NCDSrqHgt_vB1fIMpQADJKNKtzomME_a45-sfoMomKz7G2BpBHD5dZjyb3ajaScp4kU-DT3zl6B-4/s1600/Wealth234OverBestScatter.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="620" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0p5BrWLrTAaQQEBvbszpvqoNzY3H42GHPVGVcEJQdtfoL9WYp3P7_ui-kHY3mO6NCDSrqHgt_vB1fIMpQADJKNKtzomME_a45-sfoMomKz7G2BpBHD5dZjyb3ajaScp4kU-DT3zl6B-4/s640/Wealth234OverBestScatter.png" width="640" /></a></div>
<br />
The next graph shows a comparison of Universal and Uniform CRP. The graph works reasonably well in this case because both axes have smooth marginal distributions. As for the corresponding graph of relative wealth, we can clearly see that UCRP is simply better, but now we can also see that this is especially true for the best performing portfolios.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjB4t0viBOjiWF5Lh252_M5JOtG-cnJhtXFtbaK-qPpy0wPzh2uMlUbVVPAV4bDSx-y5CxzMEPkqN5XXfq6vNaD1MMe2PL8hcdmU9wXLhAfFvwJFVgcNyRnNE-Bhxn-GpWUtifuwoyy46Y/s1600/Wealth234OverUcrpScatter.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="626" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjB4t0viBOjiWF5Lh252_M5JOtG-cnJhtXFtbaK-qPpy0wPzh2uMlUbVVPAV4bDSx-y5CxzMEPkqN5XXfq6vNaD1MMe2PL8hcdmU9wXLhAfFvwJFVgcNyRnNE-Bhxn-GpWUtifuwoyy46Y/s640/Wealth234OverUcrpScatter.png" width="640" /></a></div>
The comparison between Universal and Uniform Buy and Hold below also works well. And this time also we can see that the ratio gets better for better performing portfolios, but now with Universal the better algorithm<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3FpOaa-yk6nVjqkDeXmCTW-DoMz3LHSJa6Zg3BfSOjLmX3fQVkPpSQSwmFOyqV47UbVah2cpJ8-y4LXB1nbe71SzcIGFbR2jEznjd53czCQCBZt0ovemqJ0RFKaVkCsJbZJVZbH8uzM4/s1600/Wealth234OverBhScatter.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="626" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3FpOaa-yk6nVjqkDeXmCTW-DoMz3LHSJa6Zg3BfSOjLmX3fQVkPpSQSwmFOyqV47UbVah2cpJ8-y4LXB1nbe71SzcIGFbR2jEznjd53czCQCBZt0ovemqJ0RFKaVkCsJbZJVZbH8uzM4/s640/Wealth234OverBhScatter.png" width="640" /></a></div>
<br />
Finally the comparison between the Best CRP (in hindsight) and Universal shows that BCRP is always better. Because the probability density function of the best CRP is less smooth, the comparison is not perfect, but it seems that the ratio degrades as the number of stocks in the portfolio increases. This is expected given that the performance bound of Universal decreases as the number of stocks increase.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0BrA-6GeyKeYlowC0JI1-5pDTjAPnJKuqzSF9USrldwhyAXsN1b8Xo7Md9NI22uFy_emSvPEchKkwjQWHuIZSVhDbAIEE7kODSOP3vTd8C9cGwjT1v_5RiB5_6rh9_R9TdQnD0SRKcds/s1600/Wealth234OverBcrpScatter.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="630" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0BrA-6GeyKeYlowC0JI1-5pDTjAPnJKuqzSF9USrldwhyAXsN1b8Xo7Md9NI22uFy_emSvPEchKkwjQWHuIZSVhDbAIEE7kODSOP3vTd8C9cGwjT1v_5RiB5_6rh9_R9TdQnD0SRKcds/s640/Wealth234OverBcrpScatter.png" width="640" /></a></div>
<br />
Plotting the ECDF of the relative wealth shows this effect much more vividly, clearly illustrating the advantage of looking at the same data in different fashions.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghH2Va0Cu9517tu9uem_wHIVWlOD6EY3Ym7_Io_Kh3-ewWDkwpLWBBDhNeZIwG9T5zuVULFQwkiyVoHfRlD1upn9-TRw84nk9g4z8z4szM0j9ad6RehRYIe85DcTRx9GGduIQKFt7ZxP0/s1600/Wealth234OverBcrpEcdf.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="460" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghH2Va0Cu9517tu9uem_wHIVWlOD6EY3Ym7_Io_Kh3-ewWDkwpLWBBDhNeZIwG9T5zuVULFQwkiyVoHfRlD1upn9-TRw84nk9g4z8z4szM0j9ad6RehRYIe85DcTRx9GGduIQKFt7ZxP0/s640/Wealth234OverBcrpEcdf.png" width="640" /></a></div>
<br />
<br />Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com3tag:blogger.com,1999:blog-7724085281040169836.post-4000583494624394112012-07-25T21:45:00.001-07:002012-07-25T21:45:27.100-07:00Universal portfolio, part 9<a href="http://optimallog.blogspot.com/2012/07/universal-portfolio-part-8.html">Part 8</a> was discussing the distribution of the absolute wealth of the Universal Portfolio across all possible tuples of length 2, 3 and 4.<br />
<br />
However, comparing the absolute wealth against some reference, especially against simple portfolio selection algorithm provides a better view of the exact performance of the Universal algorithm. Because we want to compute and compute multiple references, the code uses functions to be more generic. The code remains terse (88 lines, including comments) and could be even terser.<br />
<br />
Writing the code in this fashion shows again the strength of R, some specific aspects used here:<br />
<br />
<ul>
<li>Passing functions as parameters of other functions</li>
<li>Using frames to access information outside the function scope, including assigning new values.</li>
<li>Use of ... to write variadic functions (I am still learning that, the current code works but is not elegant)</li>
<li>Use of ::: to access non exported functions from a package</li>
</ul>
<div>
The code recalculates the value of Universal final wealth across all 4-tuples and thus takes one day to run, be warned.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<script src="https://gist.github.com/3180110.js?file=part9.R">
</script>
<br />
<br />
The first graph shows the final wealth of Universal versus the final wealth of the best stock in the tuple. Contrary to the absolute wealth, the relative wealth decreases as the number of stocks in the tuple increases and is also generally significantly less than 1. The red curve shows that for about 70% of the 4-tuples, Universal final wealth is below the wealth of the best stock in the tuple.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGJpwzfOs418mpacoOxv8360GffVKpfRSloud9yyC0kGQo0Cah4i0FkOi0ENqOq9eDs3FeuhdAXfizQqGaXTLqTfgebl9rp2xIxmjV0mroOQha8C-VmlqIOu5IrwOTPDanNEckCgdjjZE/s1600/Wealth234OverBestEcdf.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="432" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGJpwzfOs418mpacoOxv8360GffVKpfRSloud9yyC0kGQo0Cah4i0FkOi0ENqOq9eDs3FeuhdAXfizQqGaXTLqTfgebl9rp2xIxmjV0mroOQha8C-VmlqIOu5IrwOTPDanNEckCgdjjZE/s640/Wealth234OverBestEcdf.png" width="640" /></a></div>
<br />
Obviously, it is impossible to know in advance which stock will have the best final wealth, so the comparison is slightly unfair. The next two comparisons however are against two of the simplest causal selection algorithms:<br />
<br />
<ul>
<li>Equally weighted buy and hold, UBH for short, U for uniform</li>
<li>Equally weighted Constant Rebalanced Portfolio, usually UCRP for Uniform CRP. This one is interesting as Universal itself is based on a weighted combination of all CRP.</li>
</ul>
<div>
As BH is by construction worse than the best stock, we expect BH to fare better and indeed it does. First Universal is generally better than BH, and second the relative performance increases as the number of stocks in the tuple increase. In general, Universal is much better than UBH. The cumulative distribution does still shows a rather long and thin tail.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizvuOZVQ8vWGmSfyvntq-WrTteG_hd6yI98M8eOkVSS2-ehmS9cK8ytJURgiRUx1rJ93QfmujJPvBapS2KmYVJUC3ovCY0QgulXEGZllkSyOJDVcRsJv6k5IInoEnvwlqZoaJwTh1ebHI/s1600/Wealth234OverBhEcdf.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="434" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizvuOZVQ8vWGmSfyvntq-WrTteG_hd6yI98M8eOkVSS2-ehmS9cK8ytJURgiRUx1rJ93QfmujJPvBapS2KmYVJUC3ovCY0QgulXEGZllkSyOJDVcRsJv6k5IInoEnvwlqZoaJwTh1ebHI/s640/Wealth234OverBhEcdf.png" width="640" /></a></div>
<div>
<br /></div>
<div>
Unfortunately this does not carry to UCRP, UCRP happens to be a very good performer, and a very tough reference to beat for any portfolio selection algorithm.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_Fs8tj6qlhKuebPGqX34vaSVeMNvfhogs_mD3sUQtXKFZJ42HK6xO_waSw92NmWIhtO59r1ytcRAtVwl1SK2NKPYbiRP-aE5KJbOTf_4s40cLNa9VHqiJa6sST6J_b2nc4CFpbZ4R_zI/s1600/Wealth234OverUcrpEcdf.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="440" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_Fs8tj6qlhKuebPGqX34vaSVeMNvfhogs_mD3sUQtXKFZJ42HK6xO_waSw92NmWIhtO59r1ytcRAtVwl1SK2NKPYbiRP-aE5KJbOTf_4s40cLNa9VHqiJa6sST6J_b2nc4CFpbZ4R_zI/s640/Wealth234OverUcrpEcdf.png" width="640" /></a></div>
<div>
<br /></div>
<div>
Against UCRP:</div>
<div>
<ul>
<li>Universal generally loses to UCRP (around 90% of the time) and sometimes pretty badly</li>
<li>Increasing the tuple size increases the relative performance when UCRP is better than Universal and decreases the performance when the opposite is true.</li>
</ul>
<div>
Interestingly, the textual output shows that the composition of the best absolute or relative Universal portfolios differ significantly for the comparison against UCRP.</div>
</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max final wealth 78.4742 for stocks: comme kinar</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max final wealth 111.6039 for stocks: comme kinar meico</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max final wealth 138.5075 for stocks: comme espey kinar meico</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max final relative wealth 4.3379 for stocks: iroqu kinar</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max final relative wealth 5.6186 for stocks: espey iroqu kinar</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max final relative wealth 5.2758 for stocks: coke espey iroqu kinar</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max final relative wealth 5.9302 for stocks: iroqu kinar</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max final relative wealth 8.6374 for stocks: espey iroqu kinar</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max final relative wealth 8.8390 for stocks: espey iroqu kinar meico</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max final relative wealth 1.3043 for stocks: dupont morris</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max final relative wealth 1.1980 for stocks: dupont morris sears</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max final relative wealth 1.1330 for stocks: dupont morris schlum sears</span></div>
</div>Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com0tag:blogger.com,1999:blog-7724085281040169836.post-6055468621770729192012-07-18T21:52:00.000-07:002012-07-18T21:52:43.097-07:00Universal portfolio, part 8We extend the analysis of <a href="http://optimallog.blogspot.com/2012/07/universal-portfolio-part-7.html">part 7</a> by calculating the final wealth for all tuples of 3 and 4 stocks, this is a simple extension but it also shows the most important problem of the Universal portfolio algorithm, its exponential complexity in the number of stocks.<br />
<br />
The first part shows the cumulative distribution of the absolute final wealth for all possible tuples of 2, 3 and 4 stocks. The results are qualitatively the same as before, a thin tail of good results. It also a shows increase in absolute wealth as the number of stocks increase.<br />
<br />
The code remains quite compact, R is simply wonderful for this type of analysis.<br />
<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">library(logopt)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">x <- coredata(nyse.cover.1962.1984)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">w <- logopt:::x2w(x)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">nDays <- dim(x)[1]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">nStocks <- dim(x)[2] </span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Days <- 1:nDays</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">iWin <- 1 ; plot(1:10)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">FinalWealth <- function(cols) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>xij <- x[,cols]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>uc <- universal.cover(xij, 20)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>return(uc[length(uc)])</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">}</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">TupleSizes <- c(2,3,4)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><b><span style="color: #cc0000;">if (exists("lws") == FALSE)</span></b> {<span class="Apple-tab-span" style="white-space: pre;"> </span></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>lws <- list()</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>for (i in 1:length(TupleSizes)) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>TupleSize <- TupleSizes[i]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>ws <- combn(1:nStocks, TupleSize, FinalWealth)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>lines(ecdf(ws), pch=".", col=Colors[i])</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>lws[[i]] <- ws</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">}</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"># show the ecdf </span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">if(length(dev.list()) < iWin) { x11() } ; iWin <- iWin + 1 ; dev.set(iWin) ;</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">plot(ecdf(lws[[3]]), pch=".", col="red", main="Cumulative probability of final wealth",</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>xlab="Final wealth", ylab="Cumulative probability")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">lines(ecdf(lws[[2]]), pch=".", col="green")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">lines(ecdf(lws[[1]]), pch=".", col="blue")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">legend("bottomright", legend=c("2 stocks","3 stocks","4 stocks"), fill=c("blue","green","red"))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">grid()</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"># show best absolute wealth and its composition</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">for (i in 1:length(TupleSizes)) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>TupleSize <- TupleSizes[i]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>BestTuple <- which.max(lws[[i]])</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>BestStocks <- combn(1:nStocks, TupleSize)[,BestTuple]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat(sprintf("Max final wealth %.4f for stocks: ", lws[[i]][BestTuple]))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat(colnames(x)[BestStocks]) ; cat("\n")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">}</span><br />
<br />
<br />
This gives the following output and graph<br />
<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max final wealth 78.4742 for stocks: comme kinar</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max final wealth 111.6039 for stocks: comme kinar meico</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max final wealth 138.5075 for stocks: comme espey kinar meico</span><br />
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCopY55VWba319MuqIi-qEcT5E4-S9_sTBqJmhpzmmRjprY0XASxzWJX2utm-LrYnEzP4WVRzHws-9rUf5x11o3LTQ3YaaYR_aNT7sl6dK3mZ8u7HMYBbXg2GTsNf1kC_7loUAWVfvqYE/s1600/Wealth234Ecdf.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="528" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCopY55VWba319MuqIi-qEcT5E4-S9_sTBqJmhpzmmRjprY0XASxzWJX2utm-LrYnEzP4WVRzHws-9rUf5x11o3LTQ3YaaYR_aNT7sl6dK3mZ8u7HMYBbXg2GTsNf1kC_7loUAWVfvqYE/s640/Wealth234Ecdf.png" width="640" /></a></div>
<div>
<br /></div>
<br />
<span style="background-color: white;">The highlighted line of code is there for a reason, calculating the final wealth for all 4-tuples takes about one full day on my machine. So the code is only run once, then the magic of automatically saving the environment takes care of avoiding recalculating the result.</span><br />
<span style="background-color: white;"><br /></span><br />
<span style="background-color: white;">But why is the running time so long? The main problem of the Universal Portfolio algorithm is that it needs to evaluate an integral on the simplex, and the <a href="http://en.wikipedia.org/wiki/Curse_of_dimensionality">curse of dimensionality</a> rears its ugly head. The general approach for a numerical integration in n dimensions is exponential in the number of dimensions. Furthermore we calculate the wealth for all possible n-tuples and this increases also exponentially in n when n is much smaller than the total number of stocks concerned.</span><br />
<span style="background-color: white;"><br /></span><br />
<span style="background-color: white;">As usual R code can provide a more vivid representation, the following code generates a plot showing the complexity evolution as the number of stocks increase for 36 stocks and a grid spacing of 0.05. The code also produces a table for small the small values of n. The code uses the ::: operator, it was new to me and allows to call package functions that are not part of the exposed interface.</span><br />
<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">library(logopt)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">x <- coredata(nyse.cover.1962.1984)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">nStocks <- dim(x)[2] </span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Sizes <- 1:nStocks</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">nCs <- 0 * Sizes </span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">nSs <- 0 * Sizes</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">for (i in 1:length(Sizes)) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>n <- Sizes[i]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>nCs[i] <- choose(nStocks, n) </span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>nSs[i] <- logopt:::count.grid.points(n, 20)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">}</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">plot(nCs * nSs, type="l", col="blue", log="y",ylim=range(nCs,nSs,nCs*nSs))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">lines(nCs, col="red")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">lines(nSs, col="green")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">grid()</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">cat(sprintf("n C(36,n) S(n,20) C(36,n)*S(n,20) Ratios to previous value\n"))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">for(i in 2:6) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>n <- Sizes[i]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat(sprintf("%d %10d %10d %15.0f",n,nCs[i],nSs[i], nCs[i] * nSs[i]))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>if(i > 2) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat(sprintf("%7.1f %7.1f %7.1f", nCs[i]/nCs[i-1], nSs[i]/nSs[i-1],</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> (nCs[i] * nSs[i]) / (nCs[i-1] * nSs[i-1])))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat("\n")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">}</span><br />
<div>
<br /></div>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">n C(36,n) S(n,20) C(36,n)*S(n,20) Ratios to previous value</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">2 630 21 13230</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">3 7140 231 1649340 11.3 11.0 124.7</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">4 58905 1771 104320755 8.2 7.7 63.2</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">5 376992 10626 4005916992 6.4 6.0 38.4</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">6 1947792 53130 103486188960 5.2 5.0 25.8</span></div>
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg85B3jWLr6I8zu8OScgjTZbCeqrMKubQRBc4tLpQTQUG-2hAtyfO5Gv8vazRJZpuh7Oiav7vipAuLLNfWG9N8rPw-haV3kZHT6kdh9bpcUdJHjwxWTCtiSX5dcaV72s-DbEBNsKzkLre0/s1600/SampleComplexity.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="540" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg85B3jWLr6I8zu8OScgjTZbCeqrMKubQRBc4tLpQTQUG-2hAtyfO5Gv8vazRJZpuh7Oiav7vipAuLLNfWG9N8rPw-haV3kZHT6kdh9bpcUdJHjwxWTCtiSX5dcaV72s-DbEBNsKzkLre0/s640/SampleComplexity.png" width="640" /></a></div>
<div>
The exponential complexity makes the Universal Porfolio algorithm impractical for large portfolio, a serious limitation. Some authors have devised more efficient approaches, that either try to approximate Universal Portfolio at reduced complexity or are inspired by the ideas of Universal but with less complexity and general either no bounds or worse bounds.</div>
<br />
<span style="background-color: white;"><br /></span>Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com0tag:blogger.com,1999:blog-7724085281040169836.post-34486699293052291532012-07-07T20:44:00.001-07:002012-07-18T21:52:34.092-07:00Universal portfolio, part 7After reproducing all original figures and tables from <a href="http://www.stanford.edu/~cover/papers/paper93.pdf">Universal Portfolios</a>, R coupled with modern processors allows to perform some more analysis.<br />
<br />
First we calculate the final wealth of the universal portfolio for all possible pairs of stocks, and show the corresponding cumulative probability function, and which pair is the best. This shows how concise R code can be.<br />
<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">library(logopt)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">x <- coredata(nyse.cover.1962.1984)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">w <- logopt:::x2w(x)<span style="background-color: white;"> </span></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">nDays <- dim(x)[1]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">nStocks <- dim(x)[2] </span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Days <- 1:nDays</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">FinalWealth <- function(cols) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>xij <- x[,cols]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>uc <- universal.cover(xij, 20)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>return(uc[length(uc)])</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">}</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">ws <- combn(1:nStocks, 2, FinalWealth)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">plot(ecdf(ws),col="blue",pch=19,cex=0.5)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">grid()</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"># show the best pair</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">BestIdx <- combn(1:nStocks,2)[,which.max(ws)]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">cat(sprintf("Max final wealth: %.4f for pair (%s,%s)\n", max(ws), colnames(x)[BestIdx[1]], colnames(x)[BestIdx[2]]))</span><br />
<div>
<br /></div>
<div>
The result is the figure below, plus this line</div>
<div>
<br /></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max final wealth: 78.4742 for pair (comme,kinar)</span></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw3vz3U9cM0ZSTSVe6ud_arqQLvFxJkVz2xtTN6lXKApKhEXtNC8E-kmMOgZVY10NVFPYpQFMKf3EmrtQCVpqdggiuKULAGqpHcxtHfQ4KtrVBhMDDYiVpxrFu9-hyr0pfaj4XGB5613Y/s1600/WealthEcdf.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="486" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw3vz3U9cM0ZSTSVe6ud_arqQLvFxJkVz2xtTN6lXKApKhEXtNC8E-kmMOgZVY10NVFPYpQFMKf3EmrtQCVpqdggiuKULAGqpHcxtHfQ4KtrVBhMDDYiVpxrFu9-hyr0pfaj4XGB5613Y/s640/WealthEcdf.png" width="640" /></a></div>
<div>
There are two interesting observations to make:</div>
<div>
<ul>
<li>There is a long, thin tail. In other words, there are some pairs giving good results, but they are relatively rare.</li>
<li>The best pair happens to be one of the examples in Cover's article, probably not a coincidence.</li>
</ul>
An even better metric is the ratio between the final wealth and the wealth of the best stock in the pair. It is expected that the universal portfolio gets better performance when the underlying stocks perform better. The code below is very similar to the code above, but calculating the ratio of wealth as a final step. It needs the same prolog as above (not shown).</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">WealthRatio <- function(cols) {</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>xij <- x[,cols]</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>uc <- universal.cover(xij, 20)</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>return(uc[length(uc)]/max(w[length(uc),cols]))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">}</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">wrs <- combn(1:nStocks, 2, WealthRatio)</span></div>
<div>
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;">plot(ecdf(wrs),col="blue",pch=19,cex=0.5)</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">grid()</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
# show the best and worst pairs</div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">BestIdx <- combn(1:nStocks,2)[,which.max(wrs)]</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">cat(sprintf("Max increase from best stock: %.4f for pair (%s,%s)\n", max(wrs), colnames(x)[BestIdx[1]], colnames(x)[BestIdx[2]]))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">WorstIdx <- combn(1:nStocks,2)[,which.min(wrs)]</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">cat(sprintf("Min ratio from best stock: %.4f for pair (%s,%s)\n", min(wrs), colnames(x)[WorstIdx[1]], colnames(x)[WorstIdx[2]]))</span></div>
<div>
<br /></div>
</div>
<div>
<div>
The result is the figure below, plus these lines</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Max increase from best stock: 4.3379 for pair (iroqu,kinar)</span></div>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Min ratio from best stock: 0.3773 for pair (dupont,morris)</span></div>
</div>
</div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEo3rEE5Htq8bTtdl0Uph4-12qEk8UyyEquSEYnBKShFf1GK4ZLViyR-nPAjRX3IoExNDBKrACtfhVUDT77egCJ4qLQt4uIovzuBeQLz6E-UfMisRh0iZq0zyHLZXHXRqKePLhcXxx46o/s1600/WealthOverBestEcdf.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="486" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEo3rEE5Htq8bTtdl0Uph4-12qEk8UyyEquSEYnBKShFf1GK4ZLViyR-nPAjRX3IoExNDBKrACtfhVUDT77egCJ4qLQt4uIovzuBeQLz6E-UfMisRh0iZq0zyHLZXHXRqKePLhcXxx46o/s640/WealthOverBestEcdf.png" width="640" /></a></div>
<div>
<div>
And we can do similar observations:</div>
<div>
<ul>
<li>There is a long, thin tail, even thinner than for the wealth itself. In other words, there are some pairs giving good results, but they are relatively rare.</li>
<li>In the majority of the case (about 60%), the wealth of universal portfolio is below the wealth of the best stock in the pair, sometimes significantly so.</li>
<li>The best pair happens to be another one of the examples in Cover's article, probably not a coincidence either.</li>
</ul>
<div>
The general feeling is that universal portfolio is a valid approach, but maybe not as performing as could be deduced from the original article that cherry picked the examples.</div>
</div>
</div>Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com0tag:blogger.com,1999:blog-7724085281040169836.post-87264124241290936722012-06-30T14:03:00.000-07:002012-06-30T14:03:17.810-07:00R is funAs mentioned in <span style="background-color: white;"><a href="http://optimallog.blogspot.com/2012/06/universal-portfolio-part-6.html">Universal portfolio, part 6</a>, the wealth reported in Table 8.4 of</span><span style="color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 14px; line-height: 17px;"> </span><a href="http://www.stanford.edu/~cover/papers/paper93.pdf" style="color: #888888; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 14px; line-height: 17px; text-decoration: none;">Universal Portfolios</a> could not be reproduced. An other observation is that the random weight vectors reported in Table 8.4 are shown in descending lexicographic order, except for the last one, suggesting possibly that there is an error in the original table.<br />
<br />
R code allows to perform a simple experiment, take subsets of the full set of weights and check if we can reproduce the reported wealth. Explicitly we'll try all subsets that exclude from 1 to 7 values in the original set. This shows the expressive power of R, and how fast modern computers operate. The whole search only takes a few line of codes and execute very fast even if this entails computing the mean of 280,599 different subsets.<br />
<br />
As it turns out, <b>two</b> different subsets with 18 elements match the reported wealth, a surprising result. No other subsets match. The code below must be appended after the code used in <a href="http://optimallog.blogspot.com/2012/06/universal-portfolio-part-6.html">Universal portfolio, part 6</a>.<br />
<br />
<br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;"># remove selected entries to try to get the published value of 98.4240</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;"># R is fun and modern computers are fast</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;">BestAppr <- 0</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;">nPruned <- 0</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;">nC <- length(crps)</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;">cat("\n")</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;">for (m in seq(nC-1, nC-7)) {</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>CrpPruned <- combn(crps, m, mean)</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;"> nPruned <- nPruned + length(CrpPruned)</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>Best <- min(abs(CrpPruned - 98.4240))</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat(sprintf("Min delta from Cover with %d samples is %.4f\n", m, Best))</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;">}</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;">cat(sprintf("\n%d different subsets tried\n", nPruned))</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;">cat("\n Subsets matching the wealth reported in Table 8.4\n")</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;"># so at least one subset of 18 samples match the published value, show them</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;">Indices <- combn(1:22,18)</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;">for (i in 1:(dim(Indices)[2])) {</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>PrunedMean <- mean(crps[Indices[,i]])</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>if (abs(PrunedMean - 98.4240) < 0.0001) {</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat(Indices[,i])</span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat(sprintf(" %.5f\n",PrunedMean)) </span><br />
<span style="background-color: white;"><span class="Apple-tab-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small; white-space: pre;"> </span><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">}</span></span><br />
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;">}</span><br />
<div>
<br /></div>
<div>
This gives the following output</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Min delta from Cover with 21 samples is 2.3056</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Min delta from Cover with 20 samples is 0.0398</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Min delta from Cover with 19 samples is 0.0116</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Min delta from Cover with 18 samples is 0.0000</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Min delta from Cover with 17 samples is 0.0003</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Min delta from Cover with 16 samples is 0.0008</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Min delta from Cover with 15 samples is 0.0002</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">280599 different subsets tried</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Subsets matching the wealth reported in Table 8.4</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">1 2 3 4 5 6 9 10 11 12 13 14 15 17 19 20 21 22 98.42403</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">1 2 3 4 5 6 9 11 12 13 14 15 17 18 19 20 21 22 98.42403</span></div>
</div>
<div>
<br /></div>Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com0tag:blogger.com,1999:blog-7724085281040169836.post-67004848447700394082012-06-10T20:35:00.002-07:002012-06-11T20:26:51.955-07:00Universal portfolio, part 6The final table in <a href="http://www.stanford.edu/~cover/papers/paper93.pdf">Universal Portfolios</a> introduces leverage. It indirectly also shows the dangers of rebalancing on margin, while Kin Ark increases 4.2 times, at 50% margin it goes to nothing.<br />
<div>
<br /></div>
<div>
The code below reproduces Table 8.4, again as plain text only. For unknown reason, the wealth of the universal portfolio cannot be reproduced, while all other values do match.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"># table 8.4 of Cover "Universal Portfolios"</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">library(logopt)</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">x <- nyse.cover.1962.1984</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">xck <- x[,c("comme","kinar")]</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">nDays <- dim(xck)[1]</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Days <- 1:nDays</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"># calculate the margined sequence</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">r <- 0.000233 # seems to be r <- ((1+0.06) ^ (1/250)) - 1 rounded</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">yck <- (2 * xck) - 1 - r</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">xyck <- cbind(xck[,1], yck[,1], xck[,2], yck[,2])</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">mck <- cumprod(xyck)[nDays]</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">cat(sprintf("Commercial metals %.4f\n", mck[1,1]))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">cat(sprintf("Commercial metals on margin %.4f\n", mck[1,2]))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">cat(sprintf("Kin Ark %.4f\n", mck[1,3]))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">cat(sprintf("Kin Ark on margin %.4f\n", mck[1,4]))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">cat(sprintf("r = %.6f/day = 6%%/year\n",r))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"># same "random" b as in Cover</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- c(0.8, 0.2, 0.0, 0.0) </span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.8, 0.1, 0.0, 0.1))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.6, 0.1, 0.1, 0.2))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.6, 0.0, 0.4, 0.0))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.5, 0.0, 0.2, 0.3))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.4, 0.0, 0.4, 0.2))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.3, 0.5, 0.1, 0.1))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.3, 0.4, 0.1, 0.2))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.3, 0.2, 0.2, 0.3))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.3, 0.1, 0.2, 0.4))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.3, 0.0, 0.1, 0.6))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.2, 0.7, 0.0, 0.1))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.2, 0.2, 0.3, 0.3))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.1, 0.8, 0.1, 0.0))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.1, 0.5, 0.2, 0.2))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.1, 0.4, 0.2, 0.3))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.1, 0.3, 0.1, 0.5))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.1, 0.2, 0.4, 0.3))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.1, 0.1, 0.2, 0.6))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.0, 0.5, 0.4, 0.1))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.0, 0.4, 0.2, 0.4))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b <- rbind(b, c(0.2, 0.5, 0.1, 0.2))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">BestValue <- 0</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">crps <- b[,1] * 0</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">for (i in 1:length(crps)) {</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> <span class="Apple-tab-span" style="white-space: pre;"> </span>crps[i] <- crp(xyck, b[i,])[nDays]</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>if(crps[i] > BestValue) {</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>BestValue <- crps[i]</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>BestB <- b[i,]</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">}</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">cat(sprintf("Sn* = %.4f bn* =(%.1f, %.1f, %.1f, %.1f)\n",</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> BestValue, BestB[1], BestB[2], BestB[3], BestB[4]))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">cat(sprintf("Best constituent stock %.4f\n",max(mck)))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">cat(sprintf("Wealth achieved by universal portfolio Sn^ = %.4f\n", mean(crps)))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">cat(sprintf("\n b Sn(b)\n\n"))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">for (i in 1:length(crps)) {</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> <span class="Apple-tab-span" style="white-space: pre;"> </span>cat(sprintf("(%.1f, %.1f, %.1f %.1f) %8.4f\n",b[i,1], b[i,2], b[i,3], b[i,4], crps[i]))</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">}</span></div>
</div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: inherit;">Giving the following output</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Commercial metals 52.0203</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Commercial metals on margin 19.7335</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Kin Ark 4.1276</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Kin Ark on margin 0.0000</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">r = 0.000233/day = 6%/year</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Sn* = 262.4021 bn* =(0.2, 0.5, 0.1, 0.2)</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Best constituent stock 52.0203</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Wealth achieved by universal portfolio Sn^ = 108.0784</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> b Sn(b)</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.8, 0.2, 0.0 0.0) 57.0535</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.8, 0.1, 0.0 0.1) 148.9951</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.6, 0.1, 0.1 0.2) 207.1143</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.6, 0.0, 0.4 0.0) 140.7803</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.5, 0.0, 0.2 0.3) 60.8358</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.4, 0.0, 0.4 0.2) 47.6074</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.3, 0.5, 0.1 0.1) 212.8928</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.3, 0.4, 0.1 0.2) 261.0452</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.3, 0.2, 0.2 0.3) 89.0330</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.3, 0.1, 0.2 0.4) 19.4840</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.3, 0.0, 0.1 0.6) 0.7700</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.2, 0.7, 0.0 0.1) 121.0142</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.2, 0.2, 0.3 0.3) 45.2562</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.1, 0.8, 0.1 0.0) 67.5882</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.1, 0.5, 0.2 0.2) 233.6328</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.1, 0.4, 0.2 0.3) 112.6695</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.1, 0.3, 0.1 0.5) 12.7702</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.1, 0.2, 0.4 0.3) 19.4840</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.1, 0.1, 0.2 0.6) 0.2354</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.0, 0.5, 0.4 0.1) 225.2524</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.0, 0.4, 0.2 0.4) 31.8076</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">(0.2, 0.5, 0.1 0.2) 262.4021</span></div>
</div>
<div>
<br /></div>Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com0tag:blogger.com,1999:blog-7724085281040169836.post-78656469446645339242012-06-09T20:29:00.003-07:002012-06-11T20:26:42.532-07:00Universal portfolio, part 5The first three tables in <a href="http://www.stanford.edu/~cover/papers/paper93.pdf">Universal Portfolios</a> presents the same information in numerical form as some of the plots. The following code generates all three tables by defining a function then calling it with suitable parameters. The output is text only, so does not match the typography of the original.<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"># tables 8.1, 8.2 and 8.3 of Cover "Universal Portfolios"</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">require(logopt)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">x <- nyse.cover.1962.1984</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">ShowTable <- function(a,b) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat(sprintf("%s versus %s\n", a, b))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat(sprintf("------------------\n"))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat(sprintf("b Sn(b)\n"))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat(sprintf("------------------\n"))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>xab <- x[,c(a,b)]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>nDays <- dim(xab)[1]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>Days <- 1:nDays</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>alphas <- seq(0,1,by=0.05)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>crps <- alphas</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>for (i in 1:length(crps)) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> <span class="Apple-tab-span" style="white-space: pre;"> </span>crps[i] <- crp(xab, c(1-alphas[i], alphas[i]))[nDays]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> <span class="Apple-tab-span" style="white-space: pre;"> </span>cat(sprintf("%.2f %9.4f\n",1-alphas[i], crps[i]))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat(sprintf("------------------\n"))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat(sprintf("Target wealth: Sn* = %.4f\n",max(crps)))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat(sprintf("Best rebalanced portfolio: bn* = %4.2f\n",1-alphas[which.max(crps)]))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat(sprintf("Best constituent stock: %.4f\n", max(c(crps[1], crps[length(crps)]))))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cat(sprintf("Universal wealth: Sn^ = %.4f\n\n\n\n", mean(crps)))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">}</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">ShowTable("iroqu","kinar")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">ShowTable("comme","kinar")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">ShowTable("comme","meico")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">iroqu versus kinar</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">------------------</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b Sn(b)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">------------------</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">1.00 8.9151</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.95 13.7712</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.90 20.2276</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.85 28.2560</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.80 37.5429</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.75 47.4513</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.70 57.0581</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.65 65.2793</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.60 71.0652</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.55 73.6190</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.50 72.5766</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.45 68.0915</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.40 60.7981</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.35 51.6645</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.30 41.7831</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.25 32.1593</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.20 23.5559</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.15 16.4196</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.10 10.8910</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.05 6.8737</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.00 4.1276</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">------------------</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Target wealth: Sn* = 73.6190</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Best rebalanced portfolio: bn* = 0.55</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Best constituent stock: 8.9151</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Universal wealth: Sn^ = 38.6727</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">comme versus kinar</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">------------------</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b Sn(b)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">------------------</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">1.00 52.0203</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.95 68.2890</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.90 85.9255</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.85 103.6415</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.80 119.8472</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.75 132.8752</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.70 141.2588</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.65 144.0035</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.60 140.7803</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.55 131.9910</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.50 118.6854</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.45 102.3564</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.40 84.6655</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.35 67.1703</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.30 51.1127</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.25 37.3042</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.20 26.1131</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.15 17.5315</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.10 11.2883</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.05 6.9704</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.00 4.1276</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">------------------</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Target wealth: Sn* = 144.0035</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Best rebalanced portfolio: bn* = 0.65</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Best constituent stock: 52.0203</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Universal wealth: Sn^ = 78.4742</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">comme versus meico</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">------------------</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b Sn(b)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">------------------</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">1.00 52.0203</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.95 61.0165</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.90 70.0625</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.85 78.7602</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.80 86.6815</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.75 93.4026</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.70 98.5414</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.65 101.7927</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.60 102.9589</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.55 101.9691</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.50 98.8869</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.45 93.9033</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.40 87.3172</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.35 79.5057</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.30 70.8890</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.25 61.8932</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.20 52.9162</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.15 44.3012</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.10 36.3178</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.05 29.1538</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0.00 22.9160</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">------------------</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Target wealth: Sn* = 102.9589</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Best rebalanced portfolio: bn* = 0.60</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Best constituent stock: 52.0203</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Universal wealth: Sn^ = 72.6289</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<br />
<br />
The final table is more complex to reproduce and also more interesting, we'll tackle it in a next post.Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com0tag:blogger.com,1999:blog-7724085281040169836.post-83642357801272722972012-06-07T21:28:00.001-07:002012-06-11T20:26:33.108-07:00Universal portfolio, part 4The graph for figure 8.4 requires to be somehow careful about correctly lagging the CRP value when calculating the weights.<br />
<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"># fig 8.4 of Cover "Universal Portfolios"</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">require(logopt)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">x <- <b><span style="color: #6aa84f;">nyse.cover.1962.1984</span></b></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">xik <- x[,c("iroqu","kinar")]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">nDays <- dim(xik)[1]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Days <- 1:nDays</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">pik <- cumprod(xik)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">alphas <- seq(0,1,by=0.05)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">bk <- xik[,1] * 0</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">w <- xik[,1] * 0</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">for (i in 1:length(crps)) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> # we calculate bk by weighting the b by the realized wealth lagged one</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> weight <- lag(<b><span style="color: #6aa84f;">crp</span></b>(xik, c(alphas[i], 1-alphas[i])), 1)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> bk <- bk + alphas[i] * weight</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> w <- w + weight</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">}</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">bk <- bk / w</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">bk[1] <- 0.5</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">plot(Days, bk, col="blue", type="l", ylim = range(0.25, range(bk)), </span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> main = 'Mix of "iroqu" and "kinar" in Universal Portfolio', </span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> ylab='Fraction of "iroqu"')</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">grid()</span><br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF_hyDJknvDNfd1KQTk1hldiEa5AzesCxi0ZcR4fERPNumTEKIDaxVitWSPJD6rbrSPgH8VZ4FWiUkSgjyDNSNVvcD9EwvthrIt5R38JMwDnPZNS5w-zkfClNF5rOCIIFy6UWeT11uDuI/s1600/fig8.4.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="478" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF_hyDJknvDNfd1KQTk1hldiEa5AzesCxi0ZcR4fERPNumTEKIDaxVitWSPJD6rbrSPgH8VZ4FWiUkSgjyDNSNVvcD9EwvthrIt5R38JMwDnPZNS5w-zkfClNF5rOCIIFy6UWeT11uDuI/s640/fig8.4.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: small;">The porfolio </span><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"></math><span style="font-size: small;">
</span><mrow><span style="font-size: small;">
</span><msub><span style="font-size: small;">
<mrow>
<mover accent="true">
<mtext>b</mtext>
<mo>^</mo>
</mover>
</mrow>
<mi>k</mi></span>
</msub>
</mrow>
</td></tr>
</tbody></table>
Figure 8.5, 8.6 and 8.7 share the same format, so we define a function to draw them.<br />
<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"># fig 8.5, 8.6 and 8.7 of Cover "Universal Portfolios"</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">require(logopt)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">x <- <b><span style="color: #6aa84f;">nyse.cover.1962.1984</span></b></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">show_pair <- function (x,a,b) { </span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> xab <- x[,c(a,b)]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> nDays <- dim(xab)[1]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> Days <- 1:nDays</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> pab <- cumprod(xab)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> layout(matrix(c(1,3,4,2), 2, 2, byrow = TRUE))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> main_text <- sprintf("\"%s\" and \"%s\"",a,b)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> plot(Days, pab[,a], col="blue", type="l", ylim=range(pck), </span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> main = main_text, ylab="")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> lines(Days, pab[,b], col="red")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> grid() </span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> legend("topleft",c(sprintf("\"%s\"",a),</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> sprintf("\"%s\"",b)),col=c("blue","red"),lty=c(1,1))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> alphas <- seq(0,1,by=0.05)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> crps <- alphas</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> for (i in 1:length(crps)) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> crps[i] <- <b><span style="color: #6aa84f;">crp</span></b>(xab, c(alphas[i], 1-alphas[i]))[nDays]</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> main_text <- sprintf("20 Year Return vs. mix of \"%s\" and \"%s\"",a,b)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> xlab_text <- sprintf("Fraction of \"%s\" in Portfolio", a)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> plot(alphas, crps, col="blue", type="l", ylab="", </span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> main=main_text, xlab=xlab_text)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> points(alphas, crps, pch=19, cex=0.5, col="red")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> abline(h=mean(crps), col="green")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> text(0.4,mean(crps)*1.05,labels="Return from Universal Portfolio")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> grid()</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> universal <- xab[,1] * 0</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> for (i in 1:length(crps)) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> universal <- universal + <b><span style="color: #6aa84f;">crp</span></b>(xab, c(alphas[i], 1-alphas[i]))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> universal <- universal / length(alphas)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> main_text <- sprintf("Universal Portfolio with \"%s\" and \"%s\"",a,b)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> plot(Days, pab[,a], col="blue", type="l", ylim=range(pab, universal), </span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> main = main_text, ylab="")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> lines(Days, pab[,b], col="red")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> lines(Days, universal, col="green",)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> legend("topleft",c(sprintf("\"%s\"",a), sprintf("\"%s\"",b),'"unversal"'),</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> col=c("blue","red","green"),lty=c(1,1,1))</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> grid()</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> bk <- xab[,1] * 0</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> w <- xab[,1] * 0</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> for (i in 1:length(crps)) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> # we calculate bk by weighting the b by the realized wealth lagged one</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> weight <- lag(<b><span style="color: #6aa84f;">crp</span></b>(xab, c(alphas[i], 1-alphas[i])), 1)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> bk <- bk + alphas[i] * weight</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> w <- w + weight</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> bk <- bk / w</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> bk[1] <- 0.5</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> main_text <- sprintf("Mix of \"%s\" and \"%s\" in Universal Portfolio",a,b)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> ylab_text <- sprintf("Fraction of \"%s\"", a)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> plot(Days, bk, col="blue", type="l", ylim = range(range(bk)), </span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> main=main_text, ylab=ylab_text)</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> grid()</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">}</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"># fig 8.5</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">show_pair(x,"comme","kinar")</span><br />
<br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3GHdKXcJSc37emorFNQYd9k8KuoOsRObeH-g5fDa7BQHfbsKsVgLZK49EhsDja_rwf47KLkfJuMzyQd5d24uFIubpVxHLCMXVwdnwrgtBo__aEV8eszJALCOGK9uFS_9gacwlaJhaxAQ/s1600/fig8.5.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3GHdKXcJSc37emorFNQYd9k8KuoOsRObeH-g5fDa7BQHfbsKsVgLZK49EhsDja_rwf47KLkfJuMzyQd5d24uFIubpVxHLCMXVwdnwrgtBo__aEV8eszJALCOGK9uFS_9gacwlaJhaxAQ/s640/fig8.5.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: small;">Commercial Metals and Kin Ark</span></td></tr>
</tbody></table>
<div style="font-family: 'Courier New', Courier, monospace; font-size: small;">
# fig 8.6</div>
<div style="font-family: 'Courier New', Courier, monospace; font-size: small;">
show_pair(x,"comme","kinar")</div>
<div style="font-family: 'Courier New', Courier, monospace; font-size: small;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeeIt8vIQuzneIqp2RD9osO2k28V_hv2NfH2mXWn8MpgSrNLALllCSPJ5CBPcJGwFpJHEe4K1mQKuqc81y7GR4Z4AFY2MwxBFWKeGkFKSAZ3vTY-cuKq6WmL-tQMRiedebhUVKHF92sSo/s1600/fig8.6.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="410" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeeIt8vIQuzneIqp2RD9osO2k28V_hv2NfH2mXWn8MpgSrNLALllCSPJ5CBPcJGwFpJHEe4K1mQKuqc81y7GR4Z4AFY2MwxBFWKeGkFKSAZ3vTY-cuKq6WmL-tQMRiedebhUVKHF92sSo/s640/fig8.6.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: small;">Commercial Metals and Mei Corp.</span></td></tr>
</tbody></table>
<div style="font-family: 'Courier New', Courier, monospace; font-size: small;">
<br /></div>
<br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"># fig 8.7</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">show_pair(x,"coke","ibm")</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivuzEqsBqzWd4J5hsBFpNw8FL4FGEhgwYz2or9UOh5YozzYN2pNMAnkfwinpu9PhknQDP2a2QTBDpow4ZIB-_5u50hTtV-e8awQleP75F6aaQpIKnzru2T1DcP0eoDxTPw-uQctVST8wM/s1600/fig8.7.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="410" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivuzEqsBqzWd4J5hsBFpNw8FL4FGEhgwYz2or9UOh5YozzYN2pNMAnkfwinpu9PhknQDP2a2QTBDpow4ZIB-_5u50hTtV-e8awQleP75F6aaQpIKnzru2T1DcP0eoDxTPw-uQctVST8wM/s640/fig8.7.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: small;">IBM and Coca-Cola</span></td></tr>
</tbody></table>
<span style="font-size: x-small;">All original figures are now reproduced.</span><br />
<div style="font-family: 'Courier New', Courier, monospace; font-size: small;">
<br /></div>
<br />Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com1tag:blogger.com,1999:blog-7724085281040169836.post-41046543419239114042012-06-03T20:54:00.000-07:002012-07-25T20:18:27.341-07:00Universal portfolio, part 3After the theoretical analysis, section 8 of <a href="http://www.stanford.edu/~cover/papers/paper93.pdf" style="background-color: white; color: #888888; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px; text-decoration: none;">Universal Portfolios</a> provides examples. We now use <span style="background-color: white; color: #222222; font-family: 'Courier New', Courier, monospace; font-size: 14px; line-height: 17px;"><a href="http://r-forge.r-project.org/projects/logopt/" style="color: #888888; text-decoration: none;">logopt</a></span><span style="background-color: white; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 14px; line-height: 17px;"> </span>and <span style="font-family: 'Courier New', Courier, monospace;">R</span> to reproduce them, the first three in this post.<br />
<br />
The examples of <a href="http://www.stanford.edu/~cover/papers/paper93.pdf" style="background-color: white; color: #888888; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px; text-decoration: none;">Universal Portfolios</a> use a long time series of relative stock prices on the NYSE originally accumulated by Cover himself. This series has been reused by many authors to allow for comparisons of algorithms, and the series is available in <span style="font-family: 'Courier New', Courier, monospace;">logopt</span> itself (originally downloaded from this <a href="http://www.cs.bme.hu/~oti/portfolio/data.htmlhttp://www.cs.bme.hu/~oti/portfolio/data.html">website</a>).<br />
<br />
The two first figures introduce two specific stocks (8.1), then a series of CRP and Universal Portfolio for these two stocks (8.2). Each figure is drawn using a standalone snippet of code.<br />
<br />
<script src="https://gist.github.com/3174443.js?file=fig8.1.R">
</script>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIwNtxC5SzXnfonuJRl2HrVUGKZu31wahH19ywSVvTpDJGHa7Rv0JIb2deRnN-2Bjc9L2MOffBhl7YDU7jdLSNp5LNDOi7y3OvluUx9tRw4nkEqSUzqj9c6mxLy_MlQs6J6xLVjyzFgPo/s1600/fig8.1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="476" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIwNtxC5SzXnfonuJRl2HrVUGKZu31wahH19ywSVvTpDJGHa7Rv0JIb2deRnN-2Bjc9L2MOffBhl7YDU7jdLSNp5LNDOi7y3OvluUx9tRw4nkEqSUzqj9c6mxLy_MlQs6J6xLVjyzFgPo/s640/fig8.1.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: small;">Performance of Iroquois brands and Kin Ark</span></td></tr>
</tbody></table>
<br />
<script src="https://gist.github.com/3179984.js?file=fig8.2.R">
</script>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnIxiIMgZEnKMUehOKJ8ufwX5rkoSyYclXCoxoxrNcLa5HK7aCDrOgP9jBXf_xWkQQBJPucxHU0NDelnY_39PNBHsS_l60y_3l9iz8jt10_yQQcPaHP96AMItVhMYHVaQHm7RZgYCAFCk/s1600/fig8.2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="478" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnIxiIMgZEnKMUehOKJ8ufwX5rkoSyYclXCoxoxrNcLa5HK7aCDrOgP9jBXf_xWkQQBJPucxHU0NDelnY_39PNBHsS_l60y_3l9iz8jt10_yQQcPaHP96AMItVhMYHVaQHm7RZgYCAFCk/s640/fig8.2.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: small;">Performance of rebalanced portfolio</span>
</td></tr>
</tbody></table>
<br />
<script src="https://gist.github.com/3179999.js?file=fig8.3.R"></script>
<br />
<br />
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYTGP2Pml8hojDdbQXVQdKjODly60eovA1cDdxqmPhsDbPlDD9LHM2IZ0rNTy7DmxgeLTdwerdT_YAH4acNxK7iUj0H_mG75TkjHhYQPchfD-yBxclS8X1pMTItDZyp3hfRieDskdeM3w/s1600/fig8.3.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="476" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYTGP2Pml8hojDdbQXVQdKjODly60eovA1cDdxqmPhsDbPlDD9LHM2IZ0rNTy7DmxgeLTdwerdT_YAH4acNxK7iUj0H_mG75TkjHhYQPchfD-yBxclS8X1pMTItDZyp3hfRieDskdeM3w/s640/fig8.3.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: small;">Performance of universal portfolio</span></td></tr>
</tbody></table>
<div>
Updated on 2012/07/25 to correct code errors and use <a href="https://gist.github.com/">github:gist</a> as repository for the code examples.</div>
<br />Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com3tag:blogger.com,1999:blog-7724085281040169836.post-81309133028357533902012-06-02T20:12:00.000-07:002012-06-02T20:12:50.154-07:00Universal portfolio, part 2<a href="http://www.stanford.edu/~cover/papers/paper93.pdf" style="background-color: white; color: #888888; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px; text-decoration: none;">Universal Portfolios</a> has a classical structure: introduction of the problem, defining then proving a proposition, provide some illustration on real data, conclusion.<br />
<br />
The introduction first defines a reference portfolio, the best constant rebalanced portfolio (BCRP). The BCRP is found after all prices are known, so it is a rather tough reference to meet. In particular, by definition, Cover shows that the BRCP:<br />
<br />
<ul>
<li>exceeds the best stock (proposition 2.1 in the article)</li>
<li>exceeds the value line (proposition 2.2)</li>
<li>exceeds the arithmetic mean (proposition 2.3) </li>
</ul>
And still Cover then proves that a specific portofolio selection algorithm, called Universal Portfolio (UP) can asymptotically match the growth rate of the BCRP. This comes by showing that the ratio between BCRP and UP goes asymptotically to zero but slower than as an exponential, and thus the ratio of the growth rates tends to 1. The exact expression (6.1 in the article) for the ratio is<br />
<br />
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML">
<mrow>
<mstyle mathsize="16pt">
<mfrac>
<mrow>
<mover accent="true">
<mrow>
<msub>
<mi>S</mi>
<mi>n</mi>
</msub>
</mrow>
<mo>^</mo>
</mover>
</mrow>
<mrow>
<msubsup>
<mi>S</mi>
<mi>n</mi>
<mtext>*</mtext>
</msubsup>
</mrow>
</mfrac>
<mo>∼</mo>
<msup>
<mrow>
<mo>(</mo>
<msqrt>
<mfrac>
<mrow>
<mtext>2</mtext>
<mi>Π</mi>
</mrow>
<mrow>
<mi>n</mi>
</mrow>
</mfrac>
</msqrt>
<mo>)</mo>
</mrow>
<mrow>
<mi>m</mi>
<mo>-</mo>
<mn>1</mn>
</mrow>
</msup>
<mfrac>
<mrow>
<mfenced close=")" open="(" separators=",">
<mrow>
<mi>m</mi>
<mo>-</mo>
<mn>1</mn>
</mrow>
</mfenced>
</mrow>
<mrow>
<msup>
<mrow>
<mfenced close="|" open="|" separators=",">
<mrow>
<msup>
<mi>J</mi>
<mtext>*</mtext>
</msup>
</mrow>
</mfenced>
</mrow>
<mtext>1/2</mtext>
</msup>
</mrow>
</mfrac>
</mstyle>
</mrow>
</math>
<br />
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML">
<mrow>
<mover accent="true">
<mrow>
<msub>
<mi>S</mi>
<mi>n</mi>
</msub>
</mrow>
<mo>^</mo>
</mover>
</mrow>
</math> is the value of the Universal Portfolio after <i>n</i> periods
<br />
<math display="inline">
<mrow>
<mrow>
<msubsup>
<mi>S</mi>
<mi>n</mi>
<mtext>*</mtext>
</msubsup>
</mrow>
</mrow>
</math>
is the value of the BCRP after <i>n</i> periods<br />
<i>m</i> is the number of stocks considered<br />
<math display="inline">
<mrow>
<mfenced close="|" open="|" separators=",">
<mrow>
<msup>
<mi>J</mi>
<mtext>*</mtext>
</msup>
</mrow>
</mfenced>
</mrow>
</math> is a measure of "curvature" of the time series of price relatives<br />
The important aspect is that the ratio is not an exponential function of <i>n</i> and so the difference in growth rates between the two portfolios is asymptotically 0.
<br />
<br />
Unfortunately, the Universal Portfolio is a little bit disappointing, it effectively splits the initial investment across <b>all</b> possible CRP, so that it is sure to hit the best one. This is only done on paper, there is only one real portfolio but its composition is matched to the combination of all possible CRP at any moment in time. This happens to be difficult to do (exponential in the number of stocks for the obvious approach), with a number of simpler approximations available.<br />
<br />
<a href="http://www.stanford.edu/~cover/papers/paper93.pdf" style="background-color: white; color: #888888; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px; text-decoration: none;">Universal Portfolios</a> then uses a long sequence of historical prices to show real applications. This will be the subject of the next post in this series.<br />
<br />Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com0tag:blogger.com,1999:blog-7724085281040169836.post-25217272759427886182012-05-30T21:47:00.000-07:002012-05-30T21:47:45.136-07:00Correcting the package on R-forgeWriting a blog did help, it forced me to look at R-forge and discover that <span style="font-family: 'Courier New', Courier, monospace;">logopt</span> was not building correctly. After installing back all necessary tools, I have (almost) recreated the original environment and was able to solve the problem, committing the first change in a long time. Hopefully R-forge will have a valid build tomorrow.<br />
<br />
One of the reasons I stopped working on <span style="font-family: 'Courier New', Courier, monospace;">logopt</span> was a disk crash, in which I lost some files used in building the package. Obviously the source files committed on the server were safe (an other reason to open source your code), but I lost some local files used to build the vignette and currently I cannot build the vignette anymore, even if I recovered the source code. This will be one pending task after finishing the planned sequence of write-ups on <a href="http://www.stanford.edu/~cover/papers/paper93.pdf" style="background-color: white; color: #33aaff; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px;">Universal Portfolios</a>.Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com0tag:blogger.com,1999:blog-7724085281040169836.post-71640558234428819542012-05-27T21:23:00.002-07:002012-05-30T21:50:33.453-07:00Universal portfolio, part 1<a href="http://www.stanford.edu/~cover/">Thomas M. Cover</a> was a well known Stanford professor working in the field of information theory. He studied portfolio theory from an information theory standpoint, in a tradition started by <a href="http://home.williampoundstone.net/Kelly/Kelly.html">John L. Kelly, Jr</a> in
<a href="http://www.racing.saratoga.ny.us/kelly.pdf">A New Interpretation of Information Rate</a>, <em> Bell System Technical Journal</em> 35: 917–926, 1956. A large number of his portfolio theory articles are available <a href="http://www.stanford.edu/~cover/portfolio-theory.html">on line</a>.<br />
<br />
<a href="http://www.stanford.edu/~cover/papers/paper93.pdf">Universal Portfolios. </a><em>Mathematical Finance</em>, 1(1): 1-29, January 1991 is the most interesting for me:<br />
<br />
<ul>
<li>It is highly didactic and relatively easy to understand.</li>
<li>It includes a number of interesting graphs, contrary to many articles that restrict themselves to numeric tables.</li>
<li>It presents a portfolio approach that is guaranteed to work "reasonably well" under all conditions.</li>
</ul>
What not to like? Reading this article led to some R code that eventually became the seed for <span style="font-family: 'Courier New', Courier, monospace;"><a href="http://r-forge.r-project.org/projects/logopt/">logopt</a></span>.<br />
<br />
But what does "reasonably well"? In Cover own words<br />
<blockquote class="tr_bq">
We exhibit an algorithm for portfolio selection that asymptotically outperforms the best stock in the market.</blockquote>
This seems sensational, and is also slightly misleading as I'll discuss later on.<br />
<br /><br />
<h2>
Constant rebalanced portfolio (CRP)</h2>
<div>
In Cover's words again,</div>
<blockquote class="tr_bq">
"Universal Portfolios," Cover [1991] introduces a portfolio that does as well to first order in the exponent as the best constant rebalanced portfolio</blockquote>
<div>
A constant rebalanced portfolio buys and sells shares so that the ratio of each stock in the portfolio is a constant. Intrinsically this corresponds to sell winners to buy losers. The evolution of the value of a constant rebalanced portfolio is easy to describe mathematically, and this is why Cover is able to derive a portfolio selection algorithm that is guaranteed to track (in a mathematical sense) the best possible constant rebalanced portfolio.</div>
<br />Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com0tag:blogger.com,1999:blog-7724085281040169836.post-84903114890497779892012-05-26T21:45:00.001-07:002012-05-27T20:21:01.586-07:00<span style="font-family: 'Courier New', Courier, monospace;"><a href="http://r-forge.r-project.org/projects/logopt/">logopt</a></span> is a R package that I have neglected for too long a time for a variety of reasons. Logopt comes from log optimal portfolio, a part of the more general portfolio theory. This blog is an attempt at reviving it through an increase in exposure, with these goals:<br />
<br />
<ul>
<li>Clean up the existing code and discuss its implementation</li>
<li>Present applications of the code, generally by recreating the results of academic articles</li>
<li>Write new code</li>
</ul>
The base idea will be "<a href="http://lifehacker.com/281626/jerry-seinfelds-productivity-secret">don't break the chain</a>", post and commit code on a regular base, in small chunks. The first set of posts will discuss the initial motivation for logopt. a seminal article by Thomas M. Cover. <a href="http://www.stanford.edu/~cover/papers/paper93.pdf">Universal Portfolios. </a><em>Mathematical Finance</em>, 1(1): 1-29, January 1991.Orvalhttp://www.blogger.com/profile/11226733156943501535noreply@blogger.com0