Dass einige Webservices für Aktienkurse den Dienst quittierten, ärgert Finanzjongleur Mike Schilli. Um seine angelegten Dollars weiter im Blick zu haben, zapft er die Schnittstellen zu Kursangeboten an.
Für Nutzer von APIs, die Aktienkurse einholen, hängt der Brotkorb seit Neuestem höher als gewohnt. Erst stellte Google seinen Webservice [2] für Echtzeit-Börsendaten ein (Abbildung 1), dann zog Yahoo den Stecker. Mit dem Ende der undokumentierten, aber weiträumig genutzten Aktienkurs-Schnittstelle im CSV-Format [3], riss Yahoo einige Open-Source-Projekte wie das Perl-CPAN-Modul Yahoo::Finance oder das Python-Paket »yahoo-finance« und darauf aufbauende Börsen-Applikationen mit in den Abgrund.
Auf den Github-Seiten raufen sich die User nun unter den Issues-Reitern die Haare und ringen die Hände in Hoffnung auf Ersatz für die gewohnten kostenlosen Echtzeit- oder zumindest zeitverzögerten Börsenkursdaten.
Umsonst ist billig genug
Gegen ein happiges monatliches Entgelt finden sich natürlich Dutzende professionelle Anbieter von Börsendaten wie Bloomberg, doch kostenlose Kurse bieten nur wenige Unternehmen an, oft auch nur gegen Registrierung und nach der Herausgabe eines dann bei jedem Request beizulegenden API-Key. Es ist wohl nur eine Frage der Zeit, bis auch die heute vorgestellte freie Quelle versiegen wird, doch auch in Zukunft werden sich immer wieder Möglichkeiten auftun, die Daten ohne Gebühr einzusammeln.
Entwickler sollten sich also darauf einstellen, dass sich das Daten-Backend einer Applikation kurzfristig ändern kann. Dank Design mit schöner Abstraktion der Kursquelle sollte dies jedoch nach einem simplen Upgrade der genutzten Quote-Bibliothek für Applikationen erledigt sein, und die Karawane durstiger Kamele, die an der alten Oase nur noch ausgedörrte Wasserlöcher findet, zieht zu erquickenderen Zielen weiter.
Listing 1 nutzt eine nach wie vor offene Yahoo-Quelle zum Einholen der aktuellen Marktpreise von Aktien an den Haupthandelsplätzen der Welt. Den Tageswert der Amazon-Aktie an der New Yorker Börse fördert das Ticker-Symbol »amzn« in Dollars zutage, wer stattdessen den Kurs von Amazon an der deutschen Xetra-Börse in Euro erkunden möchte, gibt »amz.de« an.
Listing 1
myquote.py
01 #!/usr/bin/env python 02 import requests 03 import json 04 05 def quote(symbol): 06 r = requests.get( 07 'https://query1.finance.yahoo.com'+ 08 '/v7/finance/quote?symbols=%s' 09 % symbol) 10 data = json.loads(r.text) 11 return (data['quoteResponse'] 12 ['result'][0] 13 ['regularMarketPrice'])
Dazu erwartet die Funktion »quote()« das Ticker-Symbol und setzt einen Request an das Web-API ab, das eine in Json kodierte Datenstruktur zurückliefert. Unter dem Schlüssel »regularMarketPrice« steht dort der Zahlenwert für den Preis in der am Handelsplatz üblichen Währung.
Inventur im Geldspeicher
Banken und Plattformen für den Aktienhandel rechnen für ihre Kunden natürlich aus, wie hoch der Nettowert des Depots gerade ist. Auch Google und Yahoo bieten Portfolios an, die sich aber ebenfalls gerade im Wandel befinden [3], scheinbar wollen beide neue Wege zum großen Geld beschreiten.
Der Vorteil eines selbst gestrickten Skripts ist, dass es kontoübergreifend alle Habseligkeiten addiert. Hierzu muss der User zwar selbstständig eine Yaml-Datei mit den Posten im Portfolio wie in Listing 1 auf dem neuesten Stand halten. Der Ansatz wahrt aber die Privatsphäre des Anlegers zuverlässiger als Applikationen von Drittanbietern, die private Vermögensverhältnisse nichts angehen.
Listing 2 zeigt zwei fiktive Konten, eines bei der Deutschen Bank und eines bei der Sparkasse. Dort liegen 100 Amazon-und 50 Google-Aktien, letztere laufen ja unter dem Namen “Alphabet”, und das Ticker-Symbol der Firma an der Frankfurter Börse ist »abea.f«. Beide Konten verfügen außerdem über eine »Cash« genannte Bargeld-Position. Beim Zusammenzählen addiert das Skript »mymoney.py« in Listing 3 Letztere eins zu eins auf, während es bei den Aktien-Posten den aktuellen Tageswert ermittelt und mit der im Depot liegenden Anzahl multipliziert.
Listing 2
portfolio.yaml
01 - account: Deutsche Bank 02 holdings: 03 - type: stock 04 ticker: amz.de 05 shares: 100 06 - type: cash 07 amount: 5170.99 08 09 - account: Sparkasse 10 holdings: 11 - type: stock 12 ticker: abea.f 13 shares: 50 14 - type: cash 15 amount: 1234.56
Listing 3 zieht in Zeile 3 das »PyYaml«-Modul hinein, das der Admin vorher mit »pip install –user pyyaml« installiert hat. Es bietet die Methode »load()«, die Zeile 8 nutzt, um die Kontodaten aus der Portfolio-Datei aus Listing 1 einzulesen. Zeile 30 iteriert über die dort gefundenen Konten, Zeile 32 über die dort jeweils gehorteten Posten. In der abgedruckten Version unterstützt das Skript Bargeld (»cash«) und Aktien ( »stock«), ließe sich aber bei Bedarf leicht um Pfandbriefe, Optionen, oder Posten in ausländischen Währungen erweitern, deren Kurs das Skript dann zur Laufzeit einholt. Zur Wert-Ermittlung eines Bargeldpostens dient die Funktion »cash_dump()« ab Zeile 18, die lediglich ein Tupel mit dem Namen »Cash« und dem Betrag zurückgibt.
Zur Wertbestimmung eines Aktienpostens nutzt Listing 3 das Modul »myquote.py« aus Listing 1 und ruft dessen Funktion »quote()« mit dem Tickersymbol als Parameter auf. Den zurückkommenden Tageswert multipliziert es mit der Anzahl der im Depot liegenden Aktien und gibt ihn mitsamt einem Tabellenschlüssel als Tupel ans Hauptprogramm zurück. Letzteres braucht nur noch die Einzelposten über alle Konten zu addieren und den Gesamt-Nettowert des Users auszugeben (Abbildung 2).
Runden, aber richtig
Computer sind ja bekanntlich grottenschlecht beim Addieren von Fließkommazahlen. Wer »1.23« und »4.56« zusammenzählt, bekommt unter Umständen ein Ergebnis, das vom erwarteten Wert »5.79« abweicht, weil der Prozessor intern »1.23« nicht genau als 1 und 23 Hundertstel darstellt, sondern im Binärformat approximiert. Vor einiger Zeit hat sich diese Kolumne dem Thema gewidmet, dass selbst Ebay nicht richtig rechnen kann und sich die monatliche Abrechnung regelmäßig um ein paar Pfennige verhaut [4].
Listing 3
mymoney.py
01 #!/usr/bin/env python
02 import requests
03 import yaml
04 import myquote
05
06 def pf_read(filename):
07 with open(filename, 'r') as stream:
08 return yaml.load(stream)
09
10 def amount_fmt(amount):
11 return "%10.2f" % amount
12
13 def stock_dump(ticker, shares):
14 price=myquote.quote(ticker)
15 return("%d x %s" % (shares, ticker),
16 price*shares)
17
18 def cash_dump(amount):
19 return "Cash", amount
20
21 def pos_dump(pos):
22 if pos['type'] == 'stock':
23 return stock_dump(pos['ticker'],
24 pos['shares'])
25 elif pos['type'] == 'cash':
26 return cash_dump(pos['amount'])
27
28 total=0
29
30 for account in pf_read("portfolio.yaml"):
31 print(account['account'])
32 for pos in account['holdings']:
33 (name, amount) = pos_dump(pos)
34 total += int(amount*100)
35 print("%15s: %s" %
36 (name, amount_fmt(amount)))
37
38 print("\n%15s: %s" %
39 ("Total", amount_fmt(total/100.0)))
Beim Rechnen mit Geldbeträgen ist es schlauer, statt mit Euro in Cents zu rechnen. Krumme Beträge also einfach mit 100 multiplizieren und als gerundete Integer addieren und beim Anzeigen des Ergebnisses dann vor die letzten zwei Ziffern ein Komma reinhauen – Listing 3 tut genau dies.
Online PLUS
Im Screencast demonstriert Michael Schilli das Beispiel: https://www.linux-magazin.de/Ausgaben/2018/02/plus
Zukunft vorhersagen
Mit den relativ einfach verfügbaren Tageskursdaten bekannter Aktien könnte man freilich auf den Gedanken verfallen, ein AI-Netzwerk mit historischen Kursdaten zu füttern und künftige Kurssprünge vorauszusagen, um dann mit diesem Wissen gewappnet dick einzukaufen und gehörig abzukassieren. Dagegen sprechen die schon nicht mehr ganz frischen, aber zeitlosen Argumente aus dem Bestseller “A Random Walk down Wall Street” [5], die belegen, dass es in diesem Fall Hunderte Marktteilnehmer mit ähnlichen Ideen gibt, die solche Wurmlöcher im Zeitgefüge, wenn es sie tatsächlich gäbe, schnell schließen würden, weil sie zur gleichen Zeit um etwaige Preissprünge wüssten und den Gewinn schon lange eingesackt hätten.
Und dies bevor ein Einzelner überhaupt eine Chance auf den Pott hätte. Das ganze Weltbörsenkasino ist eben ein einziger “Random Walk” [6], weil unvorhersehbar. Oder sollte man es lieber mit Monaco Franze halten, bei dem eben immer “a bisserl was” geht? Hauptsache ist: Kurs halten.
Infos
- Listings zu diesem Artikel: https://www.linux-magazin.de/static/listings/magazin/2018/02/snapshot/
- “Google Finance as you know it is going away”: https://www.marketwatch.com/story/google-finance-as-you-know-it-is-going-away-here-is-what-will-remain-2017-09-27
- “Has Yahoo finance web service disappeared?”: https://stackoverflow.com/questions/38355075
- Michael Schilli, “Ladenhüter”: Linux-Magazin 06/16, S. 86, https://www.linux-magazin.de/Ausgaben/2016/06/Perl-Snapshot
- “A Random Walk down Wall Street: The Time-tested Strategy for Successful Investing”, 2016: https://www.amazon.com/Random-Walk-down-Wall-Street/dp/0393352242
- “Random Walk”, Wikipedia: https://de.wikipedia.org/wiki/Random_Walk










Auch verzögerte Kursdaten sind an den meisten Börsenplätzen Lizenzgebühren pflichtig. Die kostenfreien Dienste dürften daher, spätestens wenn die Börsenplatzbetreiber dahinter kommen, das Abgreifen der Daten verhindern.
Wir bemühen uns eine gute Lösung zu vernünftigen Preisen zu liefern und bieten unsere API jetzt auch für Privatnutzer an. Kostenfrei können wir leider nicht liefern aber es kostet auch keine tausende von Euro mehr. Das sind absurde Preise, die die großen Anbieter fordern. Einfach mal reinschauen: https://leeway.tech/data-api.