Über das Projekt
Anlageklassen auf derselben Kapitalbasis
Der Backtester zeigt, wie sich dasselbe Startkapital in Aktienindizes, Bitcoin, Gold, Immobilien, Anleihen, Rohstoffen und Geldmarkt entwickelt hätte. Besucher wählen Zeitraum, Kapital und Vergleichsreihen. Die Seite berechnet Endwert, Rendite, CAGR, Drawdown und weitere Risikokennzahlen aus den gespeicherten Beobachtungen.
Die Browserseite ruft keine Finanzanbieter auf. PHP lädt die Werte aus MySQL, berechnet die Vergleichsreihen und liefert ein festes JSON-Format. Dadurch bleiben API-Keys, Rohantworten und Providerlogik auf dem Server.
Funktionen
Was der Backtester berechnet
- Marktübersicht: Die Tabelle lässt sich nach Rendite und den übrigen Kennzahlen sortieren. Nicht verfügbare Werte bleiben am Ende.
- Flexible Zeiträume: Eine Woche bis zehn Jahre, Maximalzeitraum, eigene Start- und Enddaten sowie ein verschiebbarer Zeitraumregler.
- Einzel- und Gesamtansicht: Jede Anlageklasse besitzt einen eigenen Verlauf. Im Gesamtchart steht beim Darüberfahren die renditestärkste Linie oben.
- Logarithmische Skala: Alle Y-Achsen bleiben positiv und bilden relative Veränderungen über lange Zeiträume lesbar ab.
- Erträge und Kosten: Dividenden fließen in die Gesamtrendite ein. Netto-Mietcashflow bleibt auf die Immobilien-Einzelverläufe begrenzt. Der TER-Schalter blendet dort erst bei Aktivierung die Eingabefelder ein.
- Steuern und reale Rendite: Der Vergleich startet nominal und ohne Steuermodell. In den Einstellungen lassen sich deutsche, europäische oder US-Inflation, eine eigene Jahresrate und die Steuerberechnung gezielt zuschalten.
- Echte Datenstände: Tooltips und Tabellen nennen den letzten tatsächlich beobachteten Handelstag.
- Fehlertoleranz: Ein Providerfehler löscht keine Historie. Besucher sehen weiter die zuletzt gespeicherten Werte.
Datenpipeline
Wie die Daten in den Backtester kommen
Indizes, Bitcoin, Gold und Fonds
CoinGecko liefert Bitcoin in Euro, FRED den S&P 500 und GoldAPI den Goldpreis. MSCI World, DAX, EURO STOXX 50 sowie die Fonds-Proxys für globale Anleihen und Rohstoffe laufen über getrennte Yahoo-Parser. USD- und GBP-Werte werden mit dem passenden EZB-Referenzkurs in Euro umgerechnet.
Immobilien, Geldmarkt und Inflation
US-Immobilienpreise kommen von der FHFA über FRED, deutsche Immobilienpreise und europäische Inflation von Eurostat. Die EZB stellt den zusammengesetzten €STR-Index bereit, die New York Fed den SOFR-Index und das BLS den US-Verbraucherpreisindex.
Dividenden und neue Veröffentlichungen
Die S&P-500-Dividendenrendite wird monatlich aus der freigegebenen Multpl-Tabelle übernommen. Hinterlegte Jahreswerte ergänzen MSCI World, DAX und EURO STOXX 50. Jeder Lauf prüft nur den passenden Rückblick, damit verspätete Veröffentlichungen und Revisionen ankommen, ohne die importierte Historie auszutauschen.
Technik
Aufbau und Betrieb
Backend: Provideradapter liefern ein gemeinsames Beobachtungsformat. Ein Validierungsdienst prüft Datum, Währung, positive Werte und Duplikate. Repositories kapseln Datenbankabfragen; Services übernehmen Synchronisierung und Berechnung.
Datenbank: Getrennte Tabellen speichern Quellen, Anlageklassen, Beobachtungen, Dividendenwerte, Sync-Zustände und protokollierte Läufe. Indizes beschleunigen Bereichsabfragen und die Suche nach fälligen Jobs.
Frontend: Vanilla JavaScript verwaltet Zeitraumregler, Renditesortierung, Vergleichsreihen und die Schalter für Inflation, TER und Steuern. Optionale Modelle bleiben nach einem neuen Seitenaufruf aus. Chart.js liegt lokal auf dem Server; Live-Regionen und textliche Chart-Zusammenfassungen ergänzen die Diagramme.
Betrieb: STRATO stellt PHP 8.3 und MySQL 8.0 bereit. FileZilla überträgt Dateien, SSH startet Tests und Importe. Ein externer HTTPS-Zeitplaner ruft den täglichen Update-Endpunkt mit einem geheimen Header auf.
Eingesetzte Skills
Was ich umgesetzt habe
Anforderungsanalyse
Ich habe die Spezifikation in konkrete Aufgaben für Daten, API, Oberfläche, Sicherheit und Betrieb zerlegt. Funktionen ohne fertige Berechnung habe ich bewusst deaktiviert.
Datenengineering
Ich habe Minuten-, Tages-, Börsen- und Wechselkursdaten über Datum, Zeitzone und Revision zusammengeführt. Die fertigen CSV-Dateien habe ich mit Prüfsummen abgesichert.
Finanzmethodik
Ich habe Preisentwicklung, Dividenden und Mietcashflow getrennt gerechnet. Inflation, TER und Steuern greifen nur nach einer bewussten Auswahl; Fremdwährungswerte nutzen den Referenzkurs des jeweiligen Tages.
PHP und APIs
Ich habe das PHP-Backend in Provider, Domänenobjekte, Repositories und Services aufgeteilt. Die öffentlichen Endpunkte prüfen alle Eingaben und liefern ein einheitliches JSON-Format.
MySQL
Ich habe das MySQL-Schema mit idempotenten Upserts, Quellrevisionen, Datumsindizes, Sync-Cursor und auslaufenden Locks aufgebaut.
Debugging
Ich habe beim Debugging die STRATO-CGI-Abweichungen, einen PDO-Parameterfehler, einen falsch eingetragenen CoinGecko-Key und unklare HTTP-Fehler behoben.
Tests
Ich habe Tests für Rendite, CAGR, Drawdown, Dividenden, Mietcashflow, Inflation, TER, Steuern, Parser, CSV-Import, Request-Sicherheit, Backoff, Locks und logarithmische Charts geschrieben.
Deployment
Ich habe die Anwendung ohne Buildsystem auf Shared Hosting bereitgestellt. Uploads, Datenbankimporte, Servertests und tägliche Aktualisierungen laufen über SFTP, SSH, phpMyAdmin und einen externen Cron-Dienst.
Problemlösung
Fehler, die in der Entwicklung sichtbar wurden
- MySQL ohne aktive Datenbank: Der Schemaimport lief nach der bewussten Auswahl der Zieldatenbank durch.
- STRATO-CGI statt klassischer CLI: Testausgabe und Argumentparser funktionieren ohne `STDERR`, `php -r` und `-f` vor den Skriptargumenten.
- PDO-Parameterfehler: Der Sync verwendet keine mehrfach gebundenen benannten Parameter mehr.
- Fehlende Goldtage: Das offizielle GLD-Archiv ergänzte 130 Handelstage ohne Wechsel der Datenreihe.
- Kein Hosting-Cronjob: Ein externer Dienst ruft den geschützten HTTPS-Endpunkt täglich auf.
Rückblick
Was ich bei diesem Projekt gelernt habe
Ein Finanzchart ist erst der letzte Schritt. Der größere Teil der Arbeit steckt in Quellenwahl, Tagesbildung, historischer Währungsumrechnung, Datenrechten und einem Import, der bei Wiederholungen keine Werte beschädigt.
Shared Hosting setzt eigene Grenzen. PHP verhält sich dort nicht immer wie eine lokale CLI, und ein fehlender Hosting-Cronjob braucht einen sicheren Ersatz. Die Anwendung musste unter diesen Bedingungen testbar und wartbar bleiben.
Die laufenden Quellen schließen an die importierte Historie an und dürfen vorhandene Daten nicht überschreiben. Tägliche, monatliche und quartalsweise Reihen folgen deshalb getrennten Prüfintervallen.