Sechster und siebter Fund: die letzten handgeschriebenen Nummern

Der Loesungsanhang trug 98 Marken der Bauart "**9.2 — Ansatz waehlen.**",
saemtlich aus Version 03, wo Unsicherheit Kapitel 9 war. Heute ist es
Kapitel 12, und die Aufgabe wird korrekt als "Aufgabe 12.2" gesetzt.

Das war keine Schoenheitsfrage: "Aufgabe 9.2" existiert wirklich - sie
gehoert zum Kapitel Metaheuristiken ("Zuggroesse und Temperatur"). Wer die
Loesung zu 9.2 nachschlug, landete beim falschen Thema. Beide bisherigen
Pruefungen liefen vorbei: Vor der Zahl steht kein Schluesselwort, und es ist
keine Tabellenzelle.

Zwei Messungen machten die Reparatur billig. In allen 15 nummerierten
Abschnitten gab es exakt so viele Loesungen wie Aufgaben, lueckenlos 1..n -
nur der Kapitelteil war falsch. Und die acht in Phase 3 ergaenzten Kapitel
machten es laengst richtig (**Titel.** ohne Nummer); der Anhang wurde also
nicht auf etwas Neues umgestellt, sondern auf das, was seine neueren Teile
schon taten.

nummeriere_marken() vergibt die Marken jetzt selbst. Der Praefix kommt NICHT
aus "# Anhang A:" - der Anhang ist eine Ueberschrift, seine Abschnitte
gehoeren aber zu 23 verschiedenen Kapiteln. Er kommt aus
{#sec:loesungen-X} -> {#kap:X}; diese Zuordnung gilt geprueft fuer alle 23.
Im Quelltext steht "**{loesung} — Titel.**".

Siebter Fund unterwegs: neun Verweise auf Denkfehler-Nummern. Saetze wie
"siehe Denkfehler 8.1" standen in alter Zaehlung - "8" war in Version 03 das
QP/NLP-Kapitel, heute ist es Graphen. Eine blosse Umnummerierung haette sie
stillschweigend woanders hin zeigen lassen; das Ziel wurde deshalb fuer jeden
einzelnen aus dem Zusammenhang bestimmt und auf {ref:sec:<kapitel>-denkfehler}
umgestellt. Einer steckte in einem Programm-Docstring und bekam nach Regel 12
den Kapitelnamen statt eines Verweises.

Eine bewusste Abweichung vom Plan: Der Denkfehler bekommt GAR KEINE Nummer.
Es gibt je Kapitel genau einen, die zweite Stelle waere immer .1, und er
steht ohnehin unter einer nummerierten Ueberschrift. Eine Nummer, die nie
variiert, holte nur die Fragilitaet zurueck, die hier beseitigt wird. Auch
das folgt den acht neuen Kapiteln, die ihren Denkfehler schon vorher nur mit
dem Titel des Raetsels ankuendigen.

--check bewacht jetzt alle Familien (Denkfehler N.M, Micro-Quiz N, **N.M —
im Anhang) und zaehlt zusaetzlich ab, dass jeder Loesungsabschnitt so viele
{loesung}-Marken hat wie sein Kapitel Aufgaben - das faengt eine vergessene
oder doppelte Loesung, was keine Textsuche leisten kann. Gegengetestet mit
vier kuenstlichen Fehlern auf einmal: alle vier gemeldet, nach dem Rueckbau
null.

Gegenprobe der Umstellung: Gesamtdokument vorher gesichert, nachher
verglichen. 168 geaenderte Zeilen, restlos einer Familie zuzuordnen - 118
Loesungsmarken (138 gesamt minus 20, die in den Kapiteln 1 bis 3 zufaellig
schon stimmten), 15 Anhang-Ueberschriften, 15 Kapitel-Callouts, 12
Micro-Quiz, 7 Zeilen mit Verweisen, 1 Docstring. Keine verschobene oder
inhaltlich veraenderte Zeile.

Ergebnis: 138 Aufgaben, 138 Loesungen, keine ohne Gegenstueck. Micro-Quiz
tragen die echten Kapitelnummern. 293 Abschnitte, 720 Querverweise, 327
Indexmarken, PDF unveraendert 725 Seiten, 33 pytest-Tests, 67 netzfreie
Programme fehlerfrei (die vier yfinance-Programme scheiterten am Rate-Limit
des Anbieters, nicht an dieser Aenderung).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
dschlueter 2026-09-08 09:52:41 +02:00
commit cc990c2998
45 changed files with 1056 additions and 876 deletions

View file

@ -720,7 +720,7 @@ prices.columns: [&#39;AAPL&#39;, &#39;AMZN&#39;, &#39;CVX&#39;, &#39;GS&#39;, &
<h2 id="sec:finanzdaten-denkfehler">18.8 Finde den Denkfehler</h2>
<div class="card card-denkfehler">
<blockquote>
<p><strong>🐛 Finde den Denkfehler 11.1: Das risikofreie Portfolio</strong></p>
<p><strong>🐛 Finde den Denkfehler: Das risikofreie Portfolio</strong></p>
<p>Ein Analyst stellt ein Portfolio aus <strong>30 Titeln</strong> zusammen. Für die Kovarianzmatrix nimmt er das letzte Quartal — bei Wochendaten sind das <strong>20 Beobachtungen</strong>. Dann minimiert er die Varianz.</p>
<p>Das Ergebnis begeistert ihn: Das Portfolio hat ein Risiko von <strong>0,000 %</strong>. Er hat ein risikofreies Aktienportfolio gefunden.</p>
<p><strong>Ihre Aufgabe:</strong> (a) Wie hoch ist der Rang einer Kovarianzmatrix, die aus <span class="math inline">T</span> Beobachtungen für <span class="math inline">N &gt; T</span> Anlagen geschätzt wurde — und was folgt daraus geometrisch? (b) Warum findet ausgerechnet ein <strong>Minimum</strong>-Varianz-Optimierer diese Stelle so zuverlässig? (c) Sehen Sie sich unten die Spalte „Hebel“ an. Was sagt ein Wert von 3,8 über das Portfolio aus? (d) Warum schlägt die simple Gleichgewichtung den Optimierer — und was folgt daraus für Ihre eigenen Modelle, auch außerhalb der Finanzwelt?</p>
@ -785,72 +785,73 @@ prices.columns: [&#39;AAPL&#39;, &#39;AMZN&#39;, &#39;CVX&#39;, &#39;GS&#39;, &
<span id="cb9-55"><a href="#cb9-55" aria-hidden="true" tabindex="-1"></a><span class="co"> exakt positiv semidefinit ist - rechne trotzdem.&#39; Das ist hier bewusst so</span></span>
<span id="cb9-56"><a href="#cb9-56" aria-hidden="true" tabindex="-1"></a><span class="co"> gewaehlt, denn genau diese Eigenschaft wollen wir vorfuehren. Im</span></span>
<span id="cb9-57"><a href="#cb9-57" aria-hidden="true" tabindex="-1"></a><span class="co"> Produktivbetrieb waere die DCP-Fehlermeldung das Warnsignal, dem man</span></span>
<span id="cb9-58"><a href="#cb9-58" aria-hidden="true" tabindex="-1"></a><span class="co"> nachgehen muss (siehe Denkfehler 8.1).</span></span>
<span id="cb9-59"><a href="#cb9-59" aria-hidden="true" tabindex="-1"></a><span class="co"> &quot;&quot;&quot;</span></span>
<span id="cb9-60"><a href="#cb9-60" aria-hidden="true" tabindex="-1"></a> gewichte <span class="op">=</span> cp.Variable(ANZAHL_ANLAGEN)</span>
<span id="cb9-61"><a href="#cb9-61" aria-hidden="true" tabindex="-1"></a> problem <span class="op">=</span> cp.Problem(cp.Minimize(cp.quad_form(gewichte, cp.psd_wrap(kovarianz))),</span>
<span id="cb9-62"><a href="#cb9-62" aria-hidden="true" tabindex="-1"></a> [cp.<span class="bu">sum</span>(gewichte) <span class="op">==</span> <span class="dv">1</span>])</span>
<span id="cb9-63"><a href="#cb9-63" aria-hidden="true" tabindex="-1"></a> problem.solve()</span>
<span id="cb9-64"><a href="#cb9-64" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> np.array(gewichte.value).ravel(), <span class="bu">max</span>(problem.value, <span class="fl">0.0</span>)</span>
<span id="cb9-65"><a href="#cb9-65" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-58"><a href="#cb9-58" aria-hidden="true" tabindex="-1"></a><span class="co"> nachgehen muss (siehe den Denkfehler im Kapitel Quadratische und</span></span>
<span id="cb9-59"><a href="#cb9-59" aria-hidden="true" tabindex="-1"></a><span class="co"> nichtlineare Optimierung).</span></span>
<span id="cb9-60"><a href="#cb9-60" aria-hidden="true" tabindex="-1"></a><span class="co"> &quot;&quot;&quot;</span></span>
<span id="cb9-61"><a href="#cb9-61" aria-hidden="true" tabindex="-1"></a> gewichte <span class="op">=</span> cp.Variable(ANZAHL_ANLAGEN)</span>
<span id="cb9-62"><a href="#cb9-62" aria-hidden="true" tabindex="-1"></a> problem <span class="op">=</span> cp.Problem(cp.Minimize(cp.quad_form(gewichte, cp.psd_wrap(kovarianz))),</span>
<span id="cb9-63"><a href="#cb9-63" aria-hidden="true" tabindex="-1"></a> [cp.<span class="bu">sum</span>(gewichte) <span class="op">==</span> <span class="dv">1</span>])</span>
<span id="cb9-64"><a href="#cb9-64" aria-hidden="true" tabindex="-1"></a> problem.solve()</span>
<span id="cb9-65"><a href="#cb9-65" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> np.array(gewichte.value).ravel(), <span class="bu">max</span>(problem.value, <span class="fl">0.0</span>)</span>
<span id="cb9-66"><a href="#cb9-66" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-67"><a href="#cb9-67" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&quot;__main__&quot;</span>:</span>
<span id="cb9-68"><a href="#cb9-68" aria-hidden="true" tabindex="-1"></a> schaetzzeitraum <span class="op">=</span> erzeuge_renditen(BEOBACHTUNGEN_SCHAETZUNG)</span>
<span id="cb9-69"><a href="#cb9-69" aria-hidden="true" tabindex="-1"></a> spaeterer_verlauf <span class="op">=</span> erzeuge_renditen(BEOBACHTUNGEN_TEST)</span>
<span id="cb9-70"><a href="#cb9-70" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-71"><a href="#cb9-71" aria-hidden="true" tabindex="-1"></a> stichprobe <span class="op">=</span> np.cov(schaetzzeitraum, rowvar<span class="op">=</span><span class="va">False</span>)</span>
<span id="cb9-72"><a href="#cb9-72" aria-hidden="true" tabindex="-1"></a> ledoit_wolf <span class="op">=</span> LedoitWolf().fit(schaetzzeitraum)</span>
<span id="cb9-73"><a href="#cb9-73" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-74"><a href="#cb9-74" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;=&quot;</span> <span class="op">*</span> <span class="dv">78</span>)</span>
<span id="cb9-75"><a href="#cb9-75" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot; DIE KOVARIANZ-FALLE&quot;</span>)</span>
<span id="cb9-76"><a href="#cb9-76" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;=&quot;</span> <span class="op">*</span> <span class="dv">78</span>)</span>
<span id="cb9-77"><a href="#cb9-77" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f&quot;</span><span class="sc">{</span>ANZAHL_ANLAGEN<span class="sc">}</span><span class="ss"> Anlagen, geschaetzt aus </span><span class="sc">{</span>BEOBACHTUNGEN_SCHAETZUNG<span class="sc">}</span><span class="ss"> &quot;</span></span>
<span id="cb9-78"><a href="#cb9-78" aria-hidden="true" tabindex="-1"></a> <span class="ss">f&quot;Beobachtungen.&quot;</span>)</span>
<span id="cb9-79"><a href="#cb9-79" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f&quot;Rang der Stichprobenmatrix: &quot;</span></span>
<span id="cb9-80"><a href="#cb9-80" aria-hidden="true" tabindex="-1"></a> <span class="ss">f&quot;</span><span class="sc">{</span>np<span class="sc">.</span>linalg<span class="sc">.</span>matrix_rank(stichprobe)<span class="sc">}</span><span class="ss"> - noetig waeren </span><span class="sc">{</span>ANZAHL_ANLAGEN<span class="sc">}</span><span class="ss">.&quot;</span>)</span>
<span id="cb9-81"><a href="#cb9-81" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f&quot;Kleinster Eigenwert: </span><span class="sc">{</span>np<span class="sc">.</span>linalg<span class="sc">.</span>eigvalsh(stichprobe)<span class="sc">.</span><span class="bu">min</span>()<span class="sc">:.2e}</span><span class="ss">&quot;</span>)</span>
<span id="cb9-82"><a href="#cb9-82" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>()</span>
<span id="cb9-83"><a href="#cb9-83" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;Es gibt also Richtungen, in denen diese Matrix EXAKT null Varianz&quot;</span>)</span>
<span id="cb9-84"><a href="#cb9-84" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;misst. Genau dort sucht ein Minimum-Varianz-Optimierer.&quot;</span>)</span>
<span id="cb9-85"><a href="#cb9-85" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>()</span>
<span id="cb9-86"><a href="#cb9-86" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-87"><a href="#cb9-87" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f&quot;</span><span class="sc">{</span><span class="st">&#39;Schaetzer&#39;</span><span class="sc">:&lt;26}</span><span class="ss"> </span><span class="sc">{</span><span class="st">&#39;Risiko im Zeitraum&#39;</span><span class="sc">:&gt;19}</span><span class="ss"> &quot;</span></span>
<span id="cb9-88"><a href="#cb9-88" aria-hidden="true" tabindex="-1"></a> <span class="ss">f&quot;</span><span class="sc">{</span><span class="st">&#39;Risiko spaeter&#39;</span><span class="sc">:&gt;16}</span><span class="ss"> </span><span class="sc">{</span><span class="st">&#39;Hebel&#39;</span><span class="sc">:&gt;7}</span><span class="ss">&quot;</span>)</span>
<span id="cb9-89"><a href="#cb9-89" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;-&quot;</span> <span class="op">*</span> <span class="dv">78</span>)</span>
<span id="cb9-90"><a href="#cb9-90" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-91"><a href="#cb9-91" aria-hidden="true" tabindex="-1"></a> ergebnisse <span class="op">=</span> {}</span>
<span id="cb9-92"><a href="#cb9-92" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> name, matrix <span class="kw">in</span> [</span>
<span id="cb9-93"><a href="#cb9-93" aria-hidden="true" tabindex="-1"></a> (<span class="st">&quot;Stichprobe (roh)&quot;</span>, stichprobe),</span>
<span id="cb9-94"><a href="#cb9-94" aria-hidden="true" tabindex="-1"></a> (<span class="ss">f&quot;Ledoit-Wolf (d=</span><span class="sc">{</span>ledoit_wolf<span class="sc">.</span>shrinkage_<span class="sc">:.2f}</span><span class="ss">)&quot;</span>, ledoit_wolf.covariance_)]:</span>
<span id="cb9-95"><a href="#cb9-95" aria-hidden="true" tabindex="-1"></a> gewichte, varianz_intern <span class="op">=</span> minimales_risiko(matrix)</span>
<span id="cb9-96"><a href="#cb9-96" aria-hidden="true" tabindex="-1"></a> risiko_spaeter <span class="op">=</span> <span class="bu">float</span>(np.std(spaeterer_verlauf <span class="op">@</span> gewichte))</span>
<span id="cb9-97"><a href="#cb9-97" aria-hidden="true" tabindex="-1"></a> hebel <span class="op">=</span> <span class="bu">float</span>(np.<span class="bu">abs</span>(gewichte).<span class="bu">sum</span>())</span>
<span id="cb9-98"><a href="#cb9-98" aria-hidden="true" tabindex="-1"></a> ergebnisse[name] <span class="op">=</span> (risiko_spaeter, gewichte)</span>
<span id="cb9-99"><a href="#cb9-99" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f&quot;</span><span class="sc">{</span>name<span class="sc">:&lt;26}</span><span class="ss"> </span><span class="sc">{</span>np<span class="sc">.</span>sqrt(varianz_intern) <span class="op">*</span> <span class="dv">100</span><span class="sc">:&gt;18.3f}</span><span class="ss"> % &quot;</span></span>
<span id="cb9-100"><a href="#cb9-100" aria-hidden="true" tabindex="-1"></a> <span class="ss">f&quot;</span><span class="sc">{</span>risiko_spaeter <span class="op">*</span> <span class="dv">100</span><span class="sc">:&gt;15.3f}</span><span class="ss"> % </span><span class="sc">{</span>hebel<span class="sc">:&gt;7.1f}</span><span class="ss">&quot;</span>)</span>
<span id="cb9-101"><a href="#cb9-101" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-102"><a href="#cb9-102" aria-hidden="true" tabindex="-1"></a> gleich <span class="op">=</span> np.full(ANZAHL_ANLAGEN, <span class="fl">1.0</span> <span class="op">/</span> ANZAHL_ANLAGEN)</span>
<span id="cb9-103"><a href="#cb9-103" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f&quot;</span><span class="sc">{</span><span class="st">&#39;Gleichgewichtung 1/N&#39;</span><span class="sc">:&lt;26}</span><span class="ss"> &quot;</span></span>
<span id="cb9-104"><a href="#cb9-104" aria-hidden="true" tabindex="-1"></a> <span class="ss">f&quot;</span><span class="sc">{</span><span class="bu">float</span>(np.std(schaetzzeitraum <span class="op">@</span> gleich)) <span class="op">*</span> <span class="dv">100</span><span class="sc">:&gt;18.3f}</span><span class="ss"> % &quot;</span></span>
<span id="cb9-105"><a href="#cb9-105" aria-hidden="true" tabindex="-1"></a> <span class="ss">f&quot;</span><span class="sc">{</span><span class="bu">float</span>(np.std(spaeterer_verlauf <span class="op">@</span> gleich)) <span class="op">*</span> <span class="dv">100</span><span class="sc">:&gt;15.3f}</span><span class="ss"> % </span><span class="sc">{</span><span class="fl">1.0</span><span class="sc">:&gt;7.1f}</span><span class="ss">&quot;</span>)</span>
<span id="cb9-106"><a href="#cb9-106" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;-&quot;</span> <span class="op">*</span> <span class="dv">78</span>)</span>
<span id="cb9-107"><a href="#cb9-107" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-108"><a href="#cb9-108" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;</span><span class="ch">\n</span><span class="st">Drei Beobachtungen:&quot;</span>)</span>
<span id="cb9-109"><a href="#cb9-109" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;1. Die rohe Schaetzung meldet 0,000 % Risiko - und liefert spaeter das&quot;</span>)</span>
<span id="cb9-110"><a href="#cb9-110" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot; SCHLECHTESTE Ergebnis der drei. Sie hat kein Portfolio optimiert,&quot;</span>)</span>
<span id="cb9-111"><a href="#cb9-111" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot; sondern eine Luecke in den eigenen Daten gefunden.&quot;</span>)</span>
<span id="cb9-112"><a href="#cb9-112" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;2. Die Gleichgewichtung, die gar nicht optimiert, schlaegt den rohen&quot;</span>)</span>
<span id="cb9-113"><a href="#cb9-113" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot; Optimierer deutlich. Das ist kein Zufallsbefund, sondern in der&quot;</span>)</span>
<span id="cb9-114"><a href="#cb9-114" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot; Literatur breit belegt.&quot;</span>)</span>
<span id="cb9-115"><a href="#cb9-115" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;3. Ledoit-Wolf ist im Schaetzzeitraum EHRLICHER (0,441 statt 0,000 %)&quot;</span>)</span>
<span id="cb9-116"><a href="#cb9-116" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot; und spaeter am besten. Der Hebel faellt von 3,8 auf 1,8 - das&quot;</span>)</span>
<span id="cb9-117"><a href="#cb9-117" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot; Portfolio wird auch praktisch handelbarer.&quot;</span>)</span>
<span id="cb9-118"><a href="#cb9-118" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>()</span>
<span id="cb9-119"><a href="#cb9-119" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;Merksatz: Ein Optimierer glaubt seinen Eingabedaten vollstaendig.&quot;</span>)</span>
<span id="cb9-120"><a href="#cb9-120" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;Je mehr Freiheit Sie ihm geben, desto gruendlicher findet er deren&quot;</span>)</span>
<span id="cb9-121"><a href="#cb9-121" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;Fehler. Das gilt fuer Kovarianzmatrizen wie fuer Lieferzeiten,&quot;</span>)</span>
<span id="cb9-122"><a href="#cb9-122" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;Ausfallraten und jede andere geschaetzte Groesse.&quot;</span>)</span>
<span id="cb9-123"><a href="#cb9-123" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;=&quot;</span> <span class="op">*</span> <span class="dv">78</span>)</span></code></pre></div>
<span id="cb9-67"><a href="#cb9-67" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-68"><a href="#cb9-68" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&quot;__main__&quot;</span>:</span>
<span id="cb9-69"><a href="#cb9-69" aria-hidden="true" tabindex="-1"></a> schaetzzeitraum <span class="op">=</span> erzeuge_renditen(BEOBACHTUNGEN_SCHAETZUNG)</span>
<span id="cb9-70"><a href="#cb9-70" aria-hidden="true" tabindex="-1"></a> spaeterer_verlauf <span class="op">=</span> erzeuge_renditen(BEOBACHTUNGEN_TEST)</span>
<span id="cb9-71"><a href="#cb9-71" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-72"><a href="#cb9-72" aria-hidden="true" tabindex="-1"></a> stichprobe <span class="op">=</span> np.cov(schaetzzeitraum, rowvar<span class="op">=</span><span class="va">False</span>)</span>
<span id="cb9-73"><a href="#cb9-73" aria-hidden="true" tabindex="-1"></a> ledoit_wolf <span class="op">=</span> LedoitWolf().fit(schaetzzeitraum)</span>
<span id="cb9-74"><a href="#cb9-74" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-75"><a href="#cb9-75" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;=&quot;</span> <span class="op">*</span> <span class="dv">78</span>)</span>
<span id="cb9-76"><a href="#cb9-76" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot; DIE KOVARIANZ-FALLE&quot;</span>)</span>
<span id="cb9-77"><a href="#cb9-77" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;=&quot;</span> <span class="op">*</span> <span class="dv">78</span>)</span>
<span id="cb9-78"><a href="#cb9-78" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f&quot;</span><span class="sc">{</span>ANZAHL_ANLAGEN<span class="sc">}</span><span class="ss"> Anlagen, geschaetzt aus </span><span class="sc">{</span>BEOBACHTUNGEN_SCHAETZUNG<span class="sc">}</span><span class="ss"> &quot;</span></span>
<span id="cb9-79"><a href="#cb9-79" aria-hidden="true" tabindex="-1"></a> <span class="ss">f&quot;Beobachtungen.&quot;</span>)</span>
<span id="cb9-80"><a href="#cb9-80" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f&quot;Rang der Stichprobenmatrix: &quot;</span></span>
<span id="cb9-81"><a href="#cb9-81" aria-hidden="true" tabindex="-1"></a> <span class="ss">f&quot;</span><span class="sc">{</span>np<span class="sc">.</span>linalg<span class="sc">.</span>matrix_rank(stichprobe)<span class="sc">}</span><span class="ss"> - noetig waeren </span><span class="sc">{</span>ANZAHL_ANLAGEN<span class="sc">}</span><span class="ss">.&quot;</span>)</span>
<span id="cb9-82"><a href="#cb9-82" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f&quot;Kleinster Eigenwert: </span><span class="sc">{</span>np<span class="sc">.</span>linalg<span class="sc">.</span>eigvalsh(stichprobe)<span class="sc">.</span><span class="bu">min</span>()<span class="sc">:.2e}</span><span class="ss">&quot;</span>)</span>
<span id="cb9-83"><a href="#cb9-83" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>()</span>
<span id="cb9-84"><a href="#cb9-84" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;Es gibt also Richtungen, in denen diese Matrix EXAKT null Varianz&quot;</span>)</span>
<span id="cb9-85"><a href="#cb9-85" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;misst. Genau dort sucht ein Minimum-Varianz-Optimierer.&quot;</span>)</span>
<span id="cb9-86"><a href="#cb9-86" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>()</span>
<span id="cb9-87"><a href="#cb9-87" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-88"><a href="#cb9-88" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f&quot;</span><span class="sc">{</span><span class="st">&#39;Schaetzer&#39;</span><span class="sc">:&lt;26}</span><span class="ss"> </span><span class="sc">{</span><span class="st">&#39;Risiko im Zeitraum&#39;</span><span class="sc">:&gt;19}</span><span class="ss"> &quot;</span></span>
<span id="cb9-89"><a href="#cb9-89" aria-hidden="true" tabindex="-1"></a> <span class="ss">f&quot;</span><span class="sc">{</span><span class="st">&#39;Risiko spaeter&#39;</span><span class="sc">:&gt;16}</span><span class="ss"> </span><span class="sc">{</span><span class="st">&#39;Hebel&#39;</span><span class="sc">:&gt;7}</span><span class="ss">&quot;</span>)</span>
<span id="cb9-90"><a href="#cb9-90" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;-&quot;</span> <span class="op">*</span> <span class="dv">78</span>)</span>
<span id="cb9-91"><a href="#cb9-91" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-92"><a href="#cb9-92" aria-hidden="true" tabindex="-1"></a> ergebnisse <span class="op">=</span> {}</span>
<span id="cb9-93"><a href="#cb9-93" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> name, matrix <span class="kw">in</span> [</span>
<span id="cb9-94"><a href="#cb9-94" aria-hidden="true" tabindex="-1"></a> (<span class="st">&quot;Stichprobe (roh)&quot;</span>, stichprobe),</span>
<span id="cb9-95"><a href="#cb9-95" aria-hidden="true" tabindex="-1"></a> (<span class="ss">f&quot;Ledoit-Wolf (d=</span><span class="sc">{</span>ledoit_wolf<span class="sc">.</span>shrinkage_<span class="sc">:.2f}</span><span class="ss">)&quot;</span>, ledoit_wolf.covariance_)]:</span>
<span id="cb9-96"><a href="#cb9-96" aria-hidden="true" tabindex="-1"></a> gewichte, varianz_intern <span class="op">=</span> minimales_risiko(matrix)</span>
<span id="cb9-97"><a href="#cb9-97" aria-hidden="true" tabindex="-1"></a> risiko_spaeter <span class="op">=</span> <span class="bu">float</span>(np.std(spaeterer_verlauf <span class="op">@</span> gewichte))</span>
<span id="cb9-98"><a href="#cb9-98" aria-hidden="true" tabindex="-1"></a> hebel <span class="op">=</span> <span class="bu">float</span>(np.<span class="bu">abs</span>(gewichte).<span class="bu">sum</span>())</span>
<span id="cb9-99"><a href="#cb9-99" aria-hidden="true" tabindex="-1"></a> ergebnisse[name] <span class="op">=</span> (risiko_spaeter, gewichte)</span>
<span id="cb9-100"><a href="#cb9-100" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f&quot;</span><span class="sc">{</span>name<span class="sc">:&lt;26}</span><span class="ss"> </span><span class="sc">{</span>np<span class="sc">.</span>sqrt(varianz_intern) <span class="op">*</span> <span class="dv">100</span><span class="sc">:&gt;18.3f}</span><span class="ss"> % &quot;</span></span>
<span id="cb9-101"><a href="#cb9-101" aria-hidden="true" tabindex="-1"></a> <span class="ss">f&quot;</span><span class="sc">{</span>risiko_spaeter <span class="op">*</span> <span class="dv">100</span><span class="sc">:&gt;15.3f}</span><span class="ss"> % </span><span class="sc">{</span>hebel<span class="sc">:&gt;7.1f}</span><span class="ss">&quot;</span>)</span>
<span id="cb9-102"><a href="#cb9-102" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-103"><a href="#cb9-103" aria-hidden="true" tabindex="-1"></a> gleich <span class="op">=</span> np.full(ANZAHL_ANLAGEN, <span class="fl">1.0</span> <span class="op">/</span> ANZAHL_ANLAGEN)</span>
<span id="cb9-104"><a href="#cb9-104" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f&quot;</span><span class="sc">{</span><span class="st">&#39;Gleichgewichtung 1/N&#39;</span><span class="sc">:&lt;26}</span><span class="ss"> &quot;</span></span>
<span id="cb9-105"><a href="#cb9-105" aria-hidden="true" tabindex="-1"></a> <span class="ss">f&quot;</span><span class="sc">{</span><span class="bu">float</span>(np.std(schaetzzeitraum <span class="op">@</span> gleich)) <span class="op">*</span> <span class="dv">100</span><span class="sc">:&gt;18.3f}</span><span class="ss"> % &quot;</span></span>
<span id="cb9-106"><a href="#cb9-106" aria-hidden="true" tabindex="-1"></a> <span class="ss">f&quot;</span><span class="sc">{</span><span class="bu">float</span>(np.std(spaeterer_verlauf <span class="op">@</span> gleich)) <span class="op">*</span> <span class="dv">100</span><span class="sc">:&gt;15.3f}</span><span class="ss"> % </span><span class="sc">{</span><span class="fl">1.0</span><span class="sc">:&gt;7.1f}</span><span class="ss">&quot;</span>)</span>
<span id="cb9-107"><a href="#cb9-107" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;-&quot;</span> <span class="op">*</span> <span class="dv">78</span>)</span>
<span id="cb9-108"><a href="#cb9-108" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-109"><a href="#cb9-109" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;</span><span class="ch">\n</span><span class="st">Drei Beobachtungen:&quot;</span>)</span>
<span id="cb9-110"><a href="#cb9-110" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;1. Die rohe Schaetzung meldet 0,000 % Risiko - und liefert spaeter das&quot;</span>)</span>
<span id="cb9-111"><a href="#cb9-111" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot; SCHLECHTESTE Ergebnis der drei. Sie hat kein Portfolio optimiert,&quot;</span>)</span>
<span id="cb9-112"><a href="#cb9-112" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot; sondern eine Luecke in den eigenen Daten gefunden.&quot;</span>)</span>
<span id="cb9-113"><a href="#cb9-113" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;2. Die Gleichgewichtung, die gar nicht optimiert, schlaegt den rohen&quot;</span>)</span>
<span id="cb9-114"><a href="#cb9-114" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot; Optimierer deutlich. Das ist kein Zufallsbefund, sondern in der&quot;</span>)</span>
<span id="cb9-115"><a href="#cb9-115" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot; Literatur breit belegt.&quot;</span>)</span>
<span id="cb9-116"><a href="#cb9-116" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;3. Ledoit-Wolf ist im Schaetzzeitraum EHRLICHER (0,441 statt 0,000 %)&quot;</span>)</span>
<span id="cb9-117"><a href="#cb9-117" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot; und spaeter am besten. Der Hebel faellt von 3,8 auf 1,8 - das&quot;</span>)</span>
<span id="cb9-118"><a href="#cb9-118" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot; Portfolio wird auch praktisch handelbarer.&quot;</span>)</span>
<span id="cb9-119"><a href="#cb9-119" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>()</span>
<span id="cb9-120"><a href="#cb9-120" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;Merksatz: Ein Optimierer glaubt seinen Eingabedaten vollstaendig.&quot;</span>)</span>
<span id="cb9-121"><a href="#cb9-121" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;Je mehr Freiheit Sie ihm geben, desto gruendlicher findet er deren&quot;</span>)</span>
<span id="cb9-122"><a href="#cb9-122" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;Fehler. Das gilt fuer Kovarianzmatrizen wie fuer Lieferzeiten,&quot;</span>)</span>
<span id="cb9-123"><a href="#cb9-123" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;Ausfallraten und jede andere geschaetzte Groesse.&quot;</span>)</span>
<span id="cb9-124"><a href="#cb9-124" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">&quot;=&quot;</span> <span class="op">*</span> <span class="dv">78</span>)</span></code></pre></div>
<p><strong>Erwartete Ausgabe:</strong></p>
<pre><code>==============================================================================
DIE KOVARIANZ-FALLE
@ -925,7 +926,7 @@ Ausfallraten und jede andere geschaetzte Groesse.
<h2 id="sec:finanzdaten-quiz">18.9 Micro-Quiz</h2>
<div class="card card-quiz">
<blockquote>
<p><strong>❓ Micro-Quiz 11: Drei Fragen zum Selbstcheck</strong></p>
<p><strong>❓ Micro-Quiz 18: Drei Fragen zum Selbstcheck</strong></p>
<p>Genau eine Antwort ist jeweils richtig. Auflösung in <a href="anhang-loesungen.html#quiz-loesung-finanzdaten">Anhang A</a>.</p>
<p><strong>1. Ein Kurs fällt um 50 % und steigt danach um 50 %. Wo steht er?</strong> (a) Wieder beim Ausgangswert — die Prozente heben sich auf. (b) Bei 75 % des Ausgangswerts. Diskrete Renditen verknüpfen sich multiplikativ, nicht additiv: <span class="math inline">1{,}0 \cdot 0{,}5 \cdot 1{,}5 = 0{,}75</span>. (c) Bei 25 % des Ausgangswerts.</p>
<p><strong>2. Wofür nimmt man logarithmische Renditen, wofür diskrete?</strong> (a) Logarithmische sind grundsätzlich genauer und daher immer vorzuziehen. (b) Logarithmische addieren sich über die <strong>Zeit</strong>, diskrete über die <strong>Anlagen</strong> eines Portfolios. Man wählt nach der Richtung, in der summiert wird. (c) Diskrete für kurze, logarithmische für lange Zeiträume.</p>