Erste öffentliche Fassung: Math Model Generator & Solver

Übersetzt natürlichsprachige Optimierungsaufgaben (Deutsch) per LLM in
eine geprüfte Modellspezifikation, erzeugt Solver-Code und führt ihn in
einer bubblewrap-Sandbox aus. Deterministische Prüfungen ohne LLM,
Report als Markdown/HTML, Benchmark mit 19 verifizierten Fällen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-09-17 11:42:58 +02:00
commit b74445b8d6
3 changed files with 7655 additions and 0 deletions

View file

@ -0,0 +1,43 @@
Problem: Komplexes Portfolio-Management:
Ein Investor möchte sein Geld 100000 Euro auf mindestens 5 und maximal 10 verschiedene Aktien aufteilen.
Er möchte den erwarteten Nutzen maximieren und gleichzeitig das Risiko (die Varianz) minimieren.
Maximieren Sie den Nutzen (Rendite abzüglich des Risikos und der Fixkosten)!
Unter folgenden Nebenbedingungen:
- 1. Kardinalitätsbedingungen: Er darf maximal in 10 verschiedene Aktien inverstieren, um Transaktionskosten zu sparen.
- 2. Er muss mindestens in 5 verschiedene Aktien investieren, um das Risiko zu verteilen.
- 3. Mindest- und Höchstgrenzen: Wenn er in eine Aktie investiert, dann müssen es mindestens 5 % und maximal 30 % des Gesamtkapitals sein.
- 4. Transaktionskosten: Beim Kauf fallen Transaktionskosten an: Mindestens 5 Euro und maximal 50 Euro, sonst den Prozentsatz aus der Tabelle vom Kaufpreis der Aktien.
- 5. Das gesamte Geld muss bis auf einen kleinen Restbetrag investiert werden.
- 6. Aktien lassen sich nicht stückeln; 0.5 Aktien kann man nicht kaufen.
Wir setzen folgende Rahmenbedingungen fest:
Maximale Anzahl Aktien im Portfolio: 10
Mindestgewichtung pro gewählte Aktie: 0.05 (Fünf Prozent)
Maximalgewichtung pro gewählte Aktie: 0.30 (Dreißig Prozent)
Risikoaversations-Faktor: 1.0
Hier sind die erwarteten Renditen und die variablen Transaktionskosten und die eigene Varianz (Risiko) für die 10 Aktien:
Aktie | Preis | Erwartete Rendite | Transaktionskosten | Varianz (Risiko)
--------|-------|---------------|---------------|--------------------------------
A01 | 12.47 | 6,9 % | 0,68 % | 2,04 %
A02 | 28.91 | 14,4 % | 0,74 % | 1,63 %
A03 | 6.38 | 11,5 % | 0,39 % | 3,62 %
A04 | 19.75 | 9,8 % | 0,27 % | 3,01 %
A05 | 24.06 | 4,0 % | 0,34 % | 3,30 %
A06 | 15.22 | 4,0 % | 0,46 % | 3,33 %
A07 | 29.44 | 2,8 % | 0,69 % | 3,24 %
A08 | 8.63 | 13,3 % | 0,72 % | 1,97 %
A09 | 21.18 | 9,8 % | 0,20 % | 3,26 %
A10 | 10.95 | 11,2 % | 0,51 % | 2,52 %

View file

@ -0,0 +1,87 @@
**Fallstudie: Kardinalitätsbeschränkte Portfolio-Optimierung (MIQP)**
### 1. Problemstellung und Kontext
Aus einem Universum von $N = 100$ US-Aktien (S&P 100) soll ein Teilportfolio aus exakt $k = 20$ Titeln zusammengestellt werden. Ziel ist es, drei konkurrierende Eigenschaften in Einklang zu bringen:
1. **Entwicklungspotenzial maximieren:** Hohe historische oder geschätzte Überrendite $\mu$.
2. **Risiko minimieren:** Geringe Portfoliovarianz $w^T \Sigma w$.
3. **Diversifikation maximieren:** Minimierung der durchschnittlichen paarweisen Korrelation zwischen den ausgewählten Werten.
---
### 2. Datengrundlage & Vorbereitung via Yahoo Finance
* **Aktienuniversum:** Die 100 Konstituenten des S&P 100 (Index-Kürzel: `^OEX`).
* **Datenquelle:** Yahoo Finance (über die Python-Bibliothek `yfinance`).
* **Erhebungszeitraum:** Tägliche bereinigte Schlusskurse (`Adj Close`) über einen Zeithorizont von 3 Jahren (z. B. 01.01.2023 bis 31.12.2025).
* **Berechnungsgrundlagen:**
* Tägliche logarithmische Renditen: $r_{i,t} = \ln(P_{i,t} / P_{i,t-1})$
* Annualisierter Renditevektor: $\boldsymbol{\mu} \in \mathbb{R}^{100}$ mit $\mu_i = 252 \cdot \bar{r}_i$
* Annualisierte Kovarianzmatrix: $\boldsymbol{\Sigma} \in \mathbb{R}^{100 \times 100}$ mit $\boldsymbol{\Sigma} = 252 \cdot \operatorname{Cov}(r)$
* Korrelationsmatrix: $\mathbf{R} \in [-1, 1]^{100 \times 100}$ mit $\rho_{ij} = \frac{\sigma_{ij}}{\sigma_i \sigma_j}$
---
### 3. Mathematische Modellierung
Das Problem wird als **Mixed-Integer Quadratic Program (MIQP)** formuliert.
#### Variablen
* $z_i \in \{0, 1\}$: Binäre Selektionsvariable ($z_i = 1$, wenn Aktie $i$ ins Portfolio aufgenommen wird; $0$ sonst).
* $w_i \ge 0$: Kapitalgewichtung der Aktie $i$ im Portfolio ($w \in \mathbb{R}^{100}$).
#### Zielfunktion
Maximierung der risikoadjustierten Rendite abzüglich der durchschnittlichen Korrelation der selektierten Titel (über die Risiko-Aversionsparameter $\lambda_1 > 0$ und $\lambda_2 > 0$):
$$\max_{w, z} \quad \sum_{i=1}^{100} w_i \mu_i - \lambda_1 \sum_{i=1}^{100} \sum_{j=1}^{100} w_i w_j \sigma_{ij} - \lambda_2 \sum_{i=1}^{100} \sum_{j=1}^{100} z_i z_j \rho_{ij}$$
*(Hinweis: Der Korrelationsterm bestraft hohe paarweise Korrelationen direkt auf Selektionsebene).*
#### Nebenbedingungen
* **Kardinalitätsbedingung:** Exakt 20 Titel werden gewählt:
$$\sum_{i=1}^{100} z_i = 20$$
* **Vollinvestition (Budgetbedingung):**
$$\sum_{i=1}^{100} w_i = 1$$
* **Kein Leerverkauf & Allokationsgrenzen (Big-M-Kopplung):**
Jeder ausgewählte Wert muss ein Mindestgewicht von $1\%$ und darf maximal $10\%$ des Portfolios ausmachen:
$$0{,}01 \cdot z_i \le w_i \le 0{,}10 \cdot z_i \quad \forall i \in \{1, \dots, 100\}$$
* **Definitionsbereiche:**
$$z_i \in \{0, 1\}, \quad w_i \ge 0 \quad \forall i \in \{1, \dots, 100\}$$
---
### 4. Arbeitsaufträge
* **Teil 1: Pipeline & Kennzahlen (Python)**
Schreiben Sie ein Skript, das die Tickerliste des S&P 100 lädt, bereinigt (Ausschluss von Titeln mit unvollständigen Datenreihen) und den Vektor $\boldsymbol{\mu}$, die Matrix $\boldsymbol{\Sigma}$ sowie $\mathbf{R}$ berechnet.
* **Teil 2: Optimierung & Lösung**
Implementieren Sie das MIQP in Python (z. B. mit `cvxpy`, `Gurobi` oder `SCIP`). Testen Sie drei Konfigurationen:
1. Reine Varianzminimierung ($\lambda_1 = 1$, $\lambda_2 = 0$, $\mu$-Zielschranke).
2. Reine Korrelationsminimierung ($\lambda_1 = 0$, $\lambda_2 = 1$).
3. Ausgewogene Skalarisierung ($\lambda_1 = 0{,}5$, $\lambda_2 = 0{,}5$).
* **Teil 3: Evaluation**
Vergleichen Sie die Performance der resultierenden 20-Aktien-Portfolios gegen eine gleichgewichtete Benchmark ($1/100$ aller S&P 100 Titel) anhand von Out-of-Sample-Daten (z. B. Folgequartal):
* Realisierte Volatilität
* Sharpe Ratio
* Maximale Drawdowns

16
aufgaben/nur_formeln.md Normal file
View file

@ -0,0 +1,16 @@
min z = 17*x1 + 23*x2 + 31*x3 + 19*x4 + 29*x5
s.t.
6*x1 + 4*x2 + 8*x3 + 5*x4 + 7*x5 >= 120
3*x1 + 9*x2 + 2*x3 + 6*x4 + 4*x5 >= 105
8*x1 + 5*x2 + 7*x3 + 3*x4 + 9*x5 >= 135
2*x1 + 7*x2 + 6*x3 + 8*x4 + 5*x5 >= 110
5*x1 + 3*x2 + 4*x3 + 6*x4 + 2*x5 <= 100
4*x1 + 6*x2 + 3*x3 + 2*x4 + 5*x5 <= 90
7*x1 + 2*x2 + 5*x3 + 4*x4 + 3*x5 <= 95
x1 + x2 + x3 + x4 + x5 <= 28
x1, x2, x3, x4, x5 in Z_{\ge 0}