Über das Projekt
Drei Reihen auf derselben Kapitalbasis
Der Backtester zeigt, wie sich dasselbe Startkapital in S&P 500, Bitcoin und Gold entwickelt hätte. Besucher wählen Zeitraum, Kapital und Anlageklassen. Die Seite berechnet Endwert, Rendite, CAGR und maximalen Drawdown 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
- Gemeinsamer Vergleich: Alle ausgewählten Reihen starten mit demselben Kapital und am selben Datum.
- Flexible Zeiträume: Eine Woche bis zehn Jahre, Maximalzeitraum und eigene Start- und Enddaten.
- Vier Diagramme: Drei Einzelverläufe zeigen die jeweiligen Werte; der Gesamtchart zeigt normierte Portfoliowerte.
- Logarithmische Skala: Alle Y-Achsen bleiben positiv und bilden relative Veränderungen über lange Zeiträume lesbar ab.
- Kennzahlen: Endwert, Gewinn oder Verlust, Gesamtrendite, CAGR und maximaler Drawdown.
- Echte Datenstände: Tooltips und Tabellen nennen den letzten tatsächlich beobachteten Handelstag.
- Fehlende Markttage: Wochenenden und Feiertage werden nur im berechneten Chart fortgeführt, nicht in der Rohdatentabelle.
- Fehlertoleranz: Ein Providerfehler löscht keine Historie. Besucher sehen weiter die zuletzt gespeicherten Werte.
Datenpipeline
Vom Rohdatensatz zum Tageswert
Bitcoin
Das Importprogramm verdichtet mehr als sieben Millionen BTC/USD-Minutenzeilen auf den letzten gültigen Wert jedes UTC-Tages. Historische EZB-Kurse rechnen die Reihe in Euro um. CoinGecko liefert die laufenden BTC/EUR-Werte.
S&P 500
Die FRED-Preisindexreihe wird bereinigt und mit dem historischen USD/EUR-Referenzkurs der EZB umgerechnet. Sie enthält keine Dividenden und wird deshalb ausdrücklich als Preisindex dokumentiert.
Gold über GLD
Die gelieferte Reihe wurde gegen das offizielle GLD-Archiv geprüft. 130 fehlende Handelstage stammen aus demselben Archiv. Auch hier erfolgt die EUR-Umrechnung für jeden historischen Tag.
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: Fünf Tabellen speichern Quellen, Anlageklassen, Beobachtungen, Sync-Zustände und protokollierte Läufe. Indizes beschleunigen Bereichsabfragen und die Suche nach fälligen Jobs.
Frontend: Vanilla JavaScript verwaltet URL-Zustand, Formulare, API-Aufrufe und Fehlermeldungen. Chart.js liegt lokal auf dem Server. Die Seite enthält Live-Regionen und textliche Chart-Zusammenfassungen für Screenreader.
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 Preisindex, GLD-Schlusskurs, BTC-Referenzwert und normiertes Portfolio sauber getrennt. Historische USD-Werte rechne ich mit dem Wechselkurs des jeweiligen Tages um.
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, Forward-Fill, 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 nächste technische Aufgabe ist klar: S&P 500 und GLD brauchen laufende Quellen, die exakt an die importierte Methodik anschließen. Bis dahin bleiben Historie und täglicher Bitcoin-Betrieb sauber getrennt.