Beste Programmiersprache für algorithmische Handelssysteme
Veröffentlicht am
Eine der häufigsten Fragen, die ich in der QS-Mailbox erhalte, lautet: "Was ist die beste Programmiersprache für den algorithmischen Handel?". Die kurze Antwort lautet, dass es keine "beste" Sprache gibt. Strategieparameter, Leistung, Modularität, Entwicklung, Ausfallsicherheit und Kosten müssen alle berücksichtigt werden. In diesem Artikel werden die notwendigen Komponenten einer algorithmischen Handelssystemarchitektur umrissen und es wird erläutert, wie sich Entscheidungen bezüglich der Implementierung auf die Wahl der Sprache auswirken.
Zunächst werden die wichtigsten Komponenten eines algorithmischen Handelssystems betrachtet, wie die Research-Tools, der Portfolio-Optimierer, der Risikomanager und die Ausführungsmaschine. Anschließend werden verschiedene Handelsstrategien und ihre Auswirkungen auf die Gestaltung des Systems untersucht. Dabei werden insbesondere die Häufigkeit des Handels und das voraussichtliche Handelsvolumen erörtert.
Sobald die Handelsstrategie ausgewählt wurde, muss das gesamte System konzipiert werden. Dazu gehören die Wahl der Hardware, des/der Betriebssystems/Betriebssysteme und die Ausfallsicherheit des Systems bei seltenen, potenziell katastrophalen Ereignissen. Bei den Überlegungen zur Architektur muss auch die Leistung berücksichtigt werden - sowohl bei den Recherchetools als auch bei der Live-Ausführungsumgebung.
Was soll das Handelssystem leisten?
Bevor man sich für die "beste" Sprache entscheidet, mit der ein automatisiertes Handelssystem geschrieben werden soll, müssen die Anforderungen definiert werden. Wird das System rein ausführungsbasiert sein? Wird das System ein Risikomanagement- oder Portfoliokonstruktionsmodul benötigen? Benötigt das System einen leistungsstarken Backtester? Für die meisten Strategien kann das Handelssystem in zwei Kategorien unterteilt werden: Research und Signalgenerierung.
Beim Research geht es um die Bewertung der Leistung einer Strategie anhand historischer Daten. Der Prozess der Evaluierung einer Handelsstrategie anhand früherer Marktdaten wird als Backtesting bezeichnet. Die Größe der Daten und die Komplexität des Algorithmus haben einen großen Einfluss auf die Rechenintensität des Backtesters. CPU-Geschwindigkeit und Gleichzeitigkeit sind oft die begrenzenden Faktoren bei der Optimierung der Ausführungsgeschwindigkeit von Untersuchungen.
Bei der Signalerzeugung geht es darum, eine Reihe von Handelssignalen aus einem Algorithmus zu generieren und diese Aufträge an den Markt zu senden, in der Regel über einen Makler. Für bestimmte Strategien ist ein hohes Maß an Leistung erforderlich. E/A-Probleme wie Netzwerkbandbreite und Latenz sind oft der begrenzende Faktor bei der Optimierung von Ausführungssystemen. Daher kann die Wahl der Sprachen für jede Komponente Ihres Gesamtsystems recht unterschiedlich ausfallen.
Art, Häufigkeit und Umfang der Strategie
Die Art der eingesetzten algorithmischen Strategie hat einen erheblichen Einfluss auf die Gestaltung des Systems. Zu berücksichtigen sind die gehandelten Märkte, die Konnektivität zu externen Datenanbietern, die Häufigkeit und das Volumen der Strategie, der Kompromiss zwischen einfacher Entwicklung und Leistungsoptimierung sowie die eventuell erforderliche kundenspezifische Hardware, einschließlich kundenspezifischer Server, GPUs oder FPGAs.
Die Technologieauswahl für eine Niedrigfrequenz-Strategie für US-Aktien wird sich erheblich von der einer Hochfrequenz-Strategie für statistische Arbitrage auf dem Futures-Markt unterscheiden. Vor der Wahl der Sprache müssen viele Datenanbieter bewertet werden, die für die jeweilige Strategie in Frage kommen.
Zu berücksichtigen sind dabei die Konnektivität mit dem Anbieter, die Struktur der APIs, die Aktualität der Daten, die Speicheranforderungen und die Ausfallsicherheit, falls ein Anbieter offline geht. Es ist auch ratsam, einen schnellen Zugang zu mehreren Anbietern zu haben! Die verschiedenen Instrumente haben alle ihre eigenen Eigenheiten bei der Speicherung, z. B. mehrere Tickersymbole bei Aktien und Verfallsdaten bei Futures (ganz zu schweigen von den spezifischen OTC-Daten). Dies muss bei der Konzeption der Plattform berücksichtigt werden.
Die Häufigkeit der Strategien wird wahrscheinlich einer der wichtigsten Faktoren für die Definition des Technologie-Stacks sein. Strategien, die Daten häufiger als im Minutentakt oder im Sekundentakt verwenden, erfordern erhebliche Überlegungen hinsichtlich der Leistung.
Bei einer Strategie, die mehr als einen Sekundentakt (d. h. Tickdaten) verwendet, ist ein leistungsorientiertes Design die wichtigste Anforderung. Bei Hochfrequenzstrategien muss eine erhebliche Menge an Marktdaten gespeichert und ausgewertet werden. Software wie HDF5 oder kdb+ werden üblicherweise für diese Aufgaben eingesetzt.
Um die umfangreichen Datenmengen zu verarbeiten, die für HFT-Anwendungen benötigt werden, muss ein umfassend optimiertes Backtester- und Ausführungssystem eingesetzt werden. C/C++ (möglicherweise mit etwas Assembler) ist wahrscheinlich die am besten geeignete Sprache. Ultrahochfrequenz-Strategien werden mit ziemlicher Sicherheit kundenspezifische Hardware wie FPGAs, Börsen-Ko-Location und Kernal-/Netzwerk-Schnittstellen-Tuning erfordern.
Forschungssysteme
Forschungssysteme beinhalten in der Regel eine Mischung aus interaktiver Entwicklung und automatisierter Skripterstellung. Erstere findet häufig in einer IDE wie Visual Studio, MatLab oder R Studio statt. Letzteres beinhaltet umfangreiche numerische Berechnungen über zahlreiche Parameter und Datenpunkte. Dies führt dazu, dass eine Sprache gewählt werden muss, die eine unkomplizierte Umgebung zum Testen des Codes bietet, aber auch ausreichend leistungsfähig ist, um Strategien über mehrere Parameterdimensionen hinweg zu bewerten.
Typische IDEs in diesem Bereich sind Microsoft Visual C++/C#, das umfangreiche Debugging-Werkzeuge, Code-Vervollständigungsfunktionen (über "Intellisense") und einfache Übersichten über den gesamten Projektstapel (über das Datenbank-ORM LINQ) enthält; MatLab, das für umfangreiche numerische lineare Algebra und vektorisierte Operationen konzipiert ist, allerdings in einer interaktiven Konsolenform; R Studio, das die Konsole der statistischen Sprache R in eine vollwertige IDE verpackt; Eclipse IDE für Linux Java und C++; und semi-proprietäre IDEs wie die Anaconda Distribution, die die Spyder IDE für Python enthält. Diese Distribution enthält Datenanalysebibliotheken wie NumPy, SciPy, scikit-learn und pandas in einer einzigen interaktiven (Konsolen-)Umgebung.
Für das numerische Backtesting sind alle oben genannten Sprachen geeignet, obwohl es nicht notwendig ist, eine GUI/IDE zu verwenden, da der Code "im Hintergrund" ausgeführt wird. Die wichtigste Überlegung in dieser Phase ist die Ausführungsgeschwindigkeit. Eine kompilierte Sprache (wie C++) ist oft nützlich, wenn die Backtesting-Parameter sehr groß sind. Denken Sie daran, dass Sie in diesem Fall mit solchen Systemen vorsichtig sein müssen!
Interpretierte Sprachen wie Python verwenden für den Backtesting-Schritt oft Hochleistungsbibliotheken wie NumPy/pandas, um mit kompilierten Pendants einigermaßen konkurrenzfähig zu bleiben. Letztendlich wird die für das Backtesting gewählte Sprache durch die spezifischen algorithmischen Anforderungen sowie durch die in der Sprache verfügbaren Bibliotheken bestimmt (mehr dazu weiter unten). Die für den Backtester und die Research-Umgebungen verwendete Sprache kann jedoch völlig unabhängig von den für die Portfoliokonstruktion, das Risikomanagement und die Ausführungskomponenten verwendeten Sprachen sein, wie wir noch sehen werden.
Portfoliokonstruktion und Risikomanagement
Die Komponenten der Portfoliokonstruktion und des Risikomanagements werden von algorithmischen Einzelhändlern oft übersehen. Dies ist fast immer ein Fehler. Diese Instrumente sind der Mechanismus, durch den das Kapital erhalten wird. Sie versuchen nicht nur, die Anzahl der "riskanten" Wetten zu verringern, sondern auch die Fluktuation bei den Geschäften selbst zu minimieren und so die Transaktionskosten zu senken.
Ausgefeilte Versionen dieser Komponenten können einen erheblichen Einfluss auf die Qualität und die Beständigkeit der Rentabilität haben. Es ist einfach, eine Reihe von Strategien zu entwickeln, da der Mechanismus für die Portfoliokonstruktion und der Risikomanager leicht geändert werden können, um mehrere Systeme zu verwalten. Daher sollten sie zu Beginn der Entwicklung eines algorithmischen Handelssystems als wesentliche Komponenten betrachtet werden.
Die Aufgabe des Portfoliokonstruktionssystems besteht darin, aus einer Reihe von gewünschten Handelsgeschäften eine Reihe von tatsächlichen Handelsgeschäften zu erstellen, die die Fluktuation minimieren, die Exposition gegenüber verschiedenen Faktoren (wie Sektoren, Anlageklassen, Volatilität usw.) aufrechterhalten und die Zuweisung von Kapital zu verschiedenen Strategien in einem Portfolio optimieren.
Die Portfoliokonstruktion reduziert sich häufig auf ein Problem der linearen Algebra (z. B. eine Matrixfaktorisierung), und daher hängt die Leistung in hohem Maße von der Effizienz der verfügbaren numerischen linearen Algebra-Implementierung ab. Zu den gängigen Bibliotheken gehören uBLAS, LAPACK und NAG für C++. MatLab verfügt ebenfalls über umfangreich optimierte Matrixoperationen. Python verwendet NumPy/SciPy für solche Berechnungen. Ein häufig umgeschichtetes Portfolio erfordert eine kompilierte (und gut optimierte!) Matrixbibliothek, um diesen Schritt auszuführen, damit das Handelssystem nicht in einen Engpass gerät.
Das Risikomanagement ist ein weiterer äußerst wichtiger Teil eines algorithmischen Handelssystems. Risiko kann in vielen Formen auftreten: Erhöhte Volatilität (obwohl dies für bestimmte Strategien als wünschenswert angesehen werden kann!), erhöhte Korrelationen zwischen Anlageklassen, Ausfall der Gegenpartei, Serverausfälle, "schwarze Schwäne" und unentdeckte Fehler im Handelscode, um nur einige zu nennen.
Die Komponenten des Risikomanagements versuchen, die Auswirkungen einer übermäßigen Volatilität und Korrelation zwischen den Anlageklassen und die sich daraus ergebenden Auswirkungen auf das Handelskapital zu antizipieren. Oft reduziert sich dies auf eine Reihe statistischer Berechnungen wie Monte-Carlo-"Stresstests". Dies ähnelt sehr stark dem Rechenbedarf einer Derivatpreisberechnungsmaschine und ist daher CPU-gebunden. Diese Simulationen sind hochgradig parallelisierbar (siehe unten), und bis zu einem gewissen Grad ist es möglich, "Hardware auf das Problem zu werfen".
Ausführungssysteme
Quelle : dollarsandsense.sg
Die Aufgabe des Ausführungssystems besteht darin, gefilterte Handelssignale von den Komponenten der Portfoliokonstruktion und des Risikomanagements zu empfangen und sie an einen Makler oder einen anderen Marktzugang weiterzuleiten. Für die Mehrzahl der algorithmischen Handelsstrategien für Privatkunden bedeutet dies eine API- oder FIX-Verbindung zu einem Broker wie Interactive Brokers. Zu den wichtigsten Überlegungen bei der Entscheidung für eine Sprache gehören die Qualität der API, die Verfügbarkeit von Sprach-Wrappern für eine API, die Ausführungshäufigkeit und die erwartete Slippage.
Die "Qualität" der API bezieht sich darauf, wie gut sie dokumentiert ist, welche Art von Leistung sie bietet, ob für den Zugriff eine eigenständige Software erforderlich ist oder ob ein Gateway ohne Benutzeroberfläche eingerichtet werden kann. Im Falle von Interactive Brokers muss das Trader WorkStation-Tool in einer GUI-Umgebung laufen, um auf die API zugreifen zu können. Ich musste einmal eine Ubuntu-Desktop-Edition auf einem Amazon-Cloud-Server installieren, um aus der Ferne auf Interactive Brokers zuzugreifen, und zwar genau aus diesem Grund!
Die meisten APIs bieten eine C++- und/oder Java-Schnittstelle. Normalerweise ist es Aufgabe der Community, sprachspezifische Wrapper für C#, Python, R, Excel und MatLab zu entwickeln. Beachten Sie, dass mit jedem zusätzlichen Plugin (insbesondere API-Wrappern) die Möglichkeit besteht, dass sich Fehler in das System einschleichen. Testen Sie solche Plugins immer und stellen Sie sicher, dass sie aktiv gewartet werden. Ein guter Indikator ist, wie viele neue Updates in den letzten Monaten an einer Codebasis vorgenommen wurden.
Die Ausführungshäufigkeit ist für den Ausführungsalgorithmus von größter Bedeutung. Beachten Sie, dass jede Minute Hunderte von Aufträgen gesendet werden können und die Leistung daher entscheidend ist. Ein schlecht funktionierendes Ausführungssystem führt zu Verlusten, die sich dramatisch auf die Rentabilität auswirken.
Statisch getypte Sprachen (siehe unten) wie C++/Java sind im Allgemeinen optimal für die Ausführung, aber es gibt einen Kompromiss in Bezug auf Entwicklungszeit, Tests und Wartungsfreundlichkeit. Dynamisch getippte Sprachen wie Python und Perl sind heute im Allgemeinen "schnell genug". Achten Sie immer darauf, dass die Komponenten modular aufgebaut sind (siehe unten), so dass sie bei der Skalierung des Systems "ausgetauscht" werden können.
Architektonische Planung und Entwicklungsprozess
Die Komponenten eines Handelssystems sowie die Anforderungen an die Häufigkeit und das Volumen wurden bereits erörtert, doch die Systeminfrastruktur wurde noch nicht behandelt. Wer als Einzelhändler tätig ist oder in einem kleinen Fonds arbeitet, wird wahrscheinlich "viele Hüte tragen" müssen. Man muss sich mit dem Alphamodell, dem Risikomanagement und den Ausführungsparametern sowie mit der endgültigen Implementierung des Systems befassen. Bevor auf die einzelnen Sprachen eingegangen wird, soll der Entwurf einer optimalen Systemarchitektur erörtert werden.
Trennung der Belange
Eine der wichtigsten Entscheidungen, die zu Beginn getroffen werden müssen, ist die Frage, wie die einzelnen Bereiche eines Handelssystems getrennt werden können. In der Softwareentwicklung bedeutet dies im Wesentlichen, wie die verschiedenen Aspekte des Handelssystems in separate modulare Komponenten aufgeteilt werden können.
Durch die Offenlegung von Schnittstellen an jeder der Komponenten ist es einfach, Teile des Systems gegen andere Versionen auszutauschen, die die Leistung, Zuverlässigkeit oder Wartung verbessern, ohne dass der Code für externe Abhängigkeiten geändert werden muss. Dies ist die "beste Praxis" für solche Systeme. Für Strategien mit niedrigeren Frequenzen sind solche Praktiken zu empfehlen. Für den Hochfrequenzhandel muss das Regelwerk unter Umständen ignoriert werden, um das System für noch mehr Leistung zu optimieren. Ein enger gekoppeltes System könnte wünschenswert sein.
Die Erstellung eines Komponentenplans für ein algorithmisches Handelssystem ist einen eigenen Artikel wert. Ein optimaler Ansatz besteht jedoch darin, sicherzustellen, dass es getrennte Komponenten für die historischen und Echtzeit-Marktdateneingaben, die Datenspeicherung, die Datenzugriffs-API, den Backtester, die Strategieparameter, die Portfoliokonstruktion, das Risikomanagement und die automatischen Ausführungssysteme gibt.
Wenn beispielsweise der verwendete Datenspeicher selbst bei erheblicher Optimierung nicht die gewünschte Leistung erbringt, kann er mit minimalen Änderungen an der Dateneingabe oder der Datenzugangs-API ausgetauscht werden. In Bezug auf den Backtester und die nachfolgenden Komponenten gibt es keinen Unterschied.
Ein weiterer Vorteil der getrennten Komponenten besteht darin, dass eine Vielzahl von Programmiersprachen im Gesamtsystem verwendet werden kann. Es besteht keine Notwendigkeit, sich auf eine einzige Sprache zu beschränken, wenn die Kommunikationsmethode der Komponenten sprachunabhängig ist. Dies ist der Fall, wenn sie über TCP/IP, ZeroMQ oder ein anderes sprachunabhängiges Protokoll kommunizieren.
Ein konkretes Beispiel ist ein Backtesting-System, das in C++ geschrieben wurde, um die "Number Crunching"-Leistung zu gewährleisten, während der Portfoliomanager und die Ausführungssysteme in Python mit SciPy und IBPy geschrieben wurden.
Überlegungen zur Leistung
Die Leistung ist für die meisten Handelsstrategien ein wichtiger Faktor. Bei Strategien mit höherer Frequenz ist sie der wichtigste Faktor. Der Begriff "Leistung" umfasst ein breites Spektrum von Aspekten wie die Ausführungsgeschwindigkeit von Algorithmen, Netzwerklatenz, Bandbreite, Daten-E/A, Parallelität/Parallelität und Skalierung. Jeder dieser Bereiche wird einzeln in umfangreichen Lehrbüchern behandelt, so dass dieser Artikel nur an der Oberfläche der einzelnen Themen kratzen wird. Architektur und Sprachwahl werden nun im Hinblick auf ihre Auswirkungen auf die Leistung diskutiert.
Die vorherrschende Weisheit, die von Donald Knuth, einem der Väter der Informatik, formuliert wurde, ist, dass "verfrühte Optimierung die Wurzel allen Übels ist". Dies ist fast immer der Fall - außer bei der Entwicklung eines Hochfrequenzhandelsalgorithmus! Für diejenigen, die sich für Strategien mit niedrigerer Frequenz interessieren, besteht ein gängiger Ansatz darin, ein System so einfach wie möglich aufzubauen und erst dann zu optimieren, wenn Engpässe auftreten.
Profiling-Tools werden eingesetzt, um festzustellen, wo Engpässe entstehen. Profile können für alle oben genannten Faktoren erstellt werden, entweder in einer MS Windows- oder Linux-Umgebung. Hierfür stehen zahlreiche Betriebssystem- und Sprachtools sowie Dienstprogramme von Drittanbietern zur Verfügung. Die Wahl der Sprache wird nun im Zusammenhang mit der Leistung erörtert.
C++, Java, Python, R und MatLab enthalten alle leistungsstarke Bibliotheken (entweder als Teil ihres Standards oder extern) für grundlegende Datenstrukturen und algorithmische Arbeiten. C++ wird mit der Standard Template Library ausgeliefert, während Python NumPy/SciPy enthält. Übliche mathematische Aufgaben sind in diesen Bibliotheken zu finden, und es ist selten von Vorteil, eine neue Implementierung zu schreiben.
Eine Ausnahme ist, wenn eine stark angepasste Hardware-Architektur erforderlich ist und ein Algorithmus ausgiebig von proprietären Erweiterungen Gebrauch macht (z. B. kundenspezifische Caches). Häufig wird jedoch durch die "Neuerfindung des Rades" Zeit verschwendet, die besser für die Entwicklung und Optimierung anderer Teile der Handelsinfrastruktur verwendet werden könnte. Entwicklungszeit ist äußerst kostbar, vor allem wenn es sich um einen einzelnen Entwickler handelt.
Latenz ist oft ein Problem des Ausführungssystems, da sich die Forschungswerkzeuge in der Regel auf demselben Rechner befinden. Bei ersteren kann die Latenz an mehreren Punkten entlang des Ausführungspfads auftreten. Datenbanken müssen konsultiert werden (Festplatten-/Netzwerklatenz), Signale müssen generiert werden (Betriebssystem, Kernel-Nachrichtenlatenz), Handelssignale müssen gesendet werden (NIC-Latenz) und Aufträge müssen verarbeitet werden (interne Latenz der Börsensysteme).
Für Operationen mit höherer Frequenz ist es erforderlich, sich eingehend mit der Optimierung des Kerns und der Netzwerkübertragung zu befassen. Dies ist ein tiefes Gebiet und würde den Rahmen dieses Artikels bei weitem sprengen, aber wenn Sie einen UHFT-Algorithmus wünschen, sollten Sie sich über die Tiefe des erforderlichen Wissens im Klaren sein!
Die Zwischenspeicherung von Daten ist ein sehr nützlicher Bestandteil des Instrumentariums eines Entwicklers für quantitativen Handel. Caching bezieht sich auf das Konzept der Speicherung von Daten, auf die häufig zugegriffen wird, in einer Art und Weise, die einen leistungsfähigeren Zugriff auf Kosten der potenziellen Vergänglichkeit der Daten ermöglicht. Ein gängiger Anwendungsfall in der Webentwicklung ist die Übernahme von Daten aus einer relationalen Datenbank auf der Festplatte in den Speicher. Nachfolgende Anfragen nach den Daten müssen nicht mehr auf die Datenbank zugreifen, was zu erheblichen Leistungssteigerungen führen kann.
Für Handelssituationen kann das Caching äußerst vorteilhaft sein. So kann z.B. der aktuelle Stand eines Strategieportfolios in einem Cache gespeichert werden, bis es neu gewichtet wird, so dass die Liste nicht bei jeder Schleife des Handelsalgorithmus neu erstellt werden muss. Eine solche Neugenerierung ist wahrscheinlich mit einem hohen CPU- oder Festplatten-E/A-Aufwand verbunden.
Die Zwischenspeicherung ist jedoch nicht unproblematisch. Die gleichzeitige Regeneration von Cache-Daten kann aufgrund der Volatilität des Cache-Speichers erhebliche Anforderungen an die Infrastruktur stellen. Ein weiteres Problem ist das Dog-Piling, bei dem mehrere Generationen einer neuen Cache-Kopie unter extrem hoher Last durchgeführt werden, was zu Kaskadenfehlern führt.
Die dynamische Speicherzuweisung ist ein teurer Vorgang bei der Softwareausführung. Daher ist es für leistungsfähigere Handelsanwendungen unerlässlich, dass sie genau wissen, wie der Speicher während des Programmablaufs zugewiesen und freigegeben wird. Neuere Sprachstandards wie Java, C# und Python führen alle eine automatische Garbage Collection durch, d. h. die Freigabe von dynamisch zugewiesenem Speicher, wenn Objekte aus dem Anwendungsbereich herausfallen.
Die Garbage Collection ist während der Entwicklung äußerst nützlich, da sie Fehler reduziert und die Lesbarkeit verbessert. Für bestimmte Hochfrequenz-Handelsstrategien ist sie jedoch oft suboptimal. Für diese Fälle wird oft eine benutzerdefinierte Garbage Collection gewünscht. In Java ist es beispielsweise möglich, durch die Abstimmung des Garbage Collectors und der Heap-Konfiguration eine hohe Leistung für HFT-Strategien zu erzielen.
C++ bietet keinen nativen Garbage Collector, so dass es notwendig ist, die gesamte Speicherzuweisung/-freigabe als Teil der Objektimplementierung zu behandeln. Obwohl dies potenziell fehleranfällig ist (was zu "Dangling Pointers" führen kann), ist es für bestimmte Anwendungen äußerst nützlich, eine feinkörnige Kontrolle darüber zu haben, wie Objekte auf dem Heap erscheinen. Bei der Auswahl einer Sprache sollte man sich vergewissern, wie der Garbage Collector funktioniert und ob er so modifiziert werden kann, dass er für einen bestimmten Anwendungsfall optimiert werden kann.
Viele Operationen in algorithmischen Handelssystemen sind für eine Parallelisierung geeignet. Dies bezieht sich auf das Konzept der gleichzeitigen, d. h. "parallelen" Ausführung mehrerer programmtechnischer Operationen. Sogenannte "peinlich parallele" Algorithmen umfassen Schritte, die völlig unabhängig von anderen Schritten berechnet werden können. Bestimmte statistische Operationen, wie z. B. Monte-Carlo-Simulationen, sind ein gutes Beispiel für peinlich parallele Algorithmen, da jede zufällige Ziehung und jede nachfolgende Pfadoperation ohne Kenntnis anderer Pfade berechnet werden kann.
Andere Algorithmen sind nur teilweise parallelisierbar. Strömungsdynamiksimulationen sind ein solches Beispiel, bei dem die Berechnungsdomäne zwar unterteilt werden kann, aber letztlich müssen diese Domänen miteinander kommunizieren, so dass die Operationen teilweise sequentiell sind. Parallelisierbare Algorithmen unterliegen dem Amdahl'schen Gesetz, das eine theoretische Obergrenze für die Leistungssteigerung eines parallelisierten Algorithmus bei getrennten Prozessen (z. B. auf einem CPU-Kern oder Thread) vorgibt.
Die Parallelisierung hat als Optimierungsmittel zunehmend an Bedeutung gewonnen, seit die Taktraten der Prozessoren stagnieren, da neuere Prozessoren viele Kerne enthalten, mit denen parallele Berechnungen durchgeführt werden können. Das Aufkommen von Grafikhardware für Verbraucher (vor allem für Videospiele) hat zur Entwicklung von Graphical Processing Units (GPUs) geführt, die Hunderte von "Kernen" für hochgradig gleichzeitige Operationen enthalten. Solche GPUs sind jetzt sehr erschwinglich. High-Level-Frameworks wie CUDA von Nvidia haben zu einer weit verbreiteten Anwendung in der Wissenschaft und im Finanzwesen geführt.
Solche GPU-Hardware ist im Allgemeinen nur für den Forschungsaspekt der quantitativen Finanzwirtschaft geeignet, während andere, spezialisiertere Hardware (einschließlich Field-Programmable Gate Arrays - FPGAs) für (U)HFT verwendet wird. Heutzutage unterstützen die meisten modernen Sprachen ein gewisses Maß an Gleichzeitigkeit/Multithreading. Somit ist es einfach, einen Backtester zu optimieren, da alle Berechnungen im Allgemeinen unabhängig voneinander sind.
Unter Skalierung versteht man in der Softwaretechnik und im Betrieb die Fähigkeit des Systems, stetig steigende Lasten in Form von mehr Anfragen, höherer Prozessorauslastung und mehr Speicherzuweisung zu bewältigen. Im algorithmischen Handel ist eine Strategie dann skalierbar, wenn sie größere Kapitalmengen aufnehmen und dennoch gleichbleibende Erträge erzielen kann. Der Stack der Handelstechnologie ist skalierbar, wenn er größere Handelsvolumina und höhere Latenzzeiten aushalten kann, ohne dass es zu Engpässen kommt.
Systeme müssen zwar skalierbar sein, aber es ist oft schwer vorherzusagen, wo ein Engpass auftreten wird. Rigorose Protokollierung, Tests, Profilerstellung und Überwachung tragen wesentlich dazu bei, dass ein System skaliert werden kann. Sprachen selbst werden oft als "nicht skalierbar" bezeichnet. Dies ist in der Regel das Ergebnis von Fehlinformationen und nicht von harten Fakten. Nicht die Sprache, sondern der gesamte Technologie-Stack sollte auf Skalierbarkeit geprüft werden. Natürlich sind bestimmte Sprachen in bestimmten Anwendungsfällen leistungsfähiger als andere, aber eine Sprache ist niemals in jeder Hinsicht "besser" als eine andere.
Eine Möglichkeit, die Skalierung zu steuern, ist die Trennung von Bereichen, wie oben erwähnt. Um darüber hinaus die Möglichkeit zu schaffen, "Spitzen" im System zu bewältigen (d. h. plötzliche Volatilität, die eine ganze Reihe von Geschäften auslöst), ist es sinnvoll, eine "Message-Queuing-Architektur" zu schaffen. Dies bedeutet einfach, dass zwischen den Komponenten ein Warteschlangensystem eingerichtet wird, so dass Aufträge "aufgestapelt" werden, wenn eine bestimmte Komponente nicht in der Lage ist, viele Anfragen zu bearbeiten.
Anstatt dass die Aufträge verloren gehen, werden sie einfach in einem Stapel aufbewahrt, bis die Nachricht bearbeitet ist. Dies ist besonders nützlich für die Übermittlung von Geschäften an eine Ausführungsmaschine. Wenn die Engine unter starken Latenzzeiten leidet, wird sie die Abschlüsse zurückhalten. Eine Warteschlange zwischen dem Handelssignalgenerator und der Ausführungs-API mildert dieses Problem auf Kosten potenzieller Handelsverschiebungen. Ein angesehener Open Source Message Queue Broker ist RabbitMQ.
Hardware und Betriebssysteme
Die Hardware, auf der Ihre Strategie ausgeführt wird, kann einen erheblichen Einfluss auf die Rentabilität Ihres Algorithmus haben. Dies ist auch kein Problem, das auf Hochfrequenzhändler beschränkt ist. Eine schlechte Wahl der Hardware und des Betriebssystems kann dazu führen, dass der Rechner im unpassendsten Moment abstürzt oder neu startet. Daher muss man sich überlegen, wo man seine Anwendung unterbringt. In der Regel hat man die Wahl zwischen einem persönlichen Desktop-Rechner, einem Remote-Server, einem "Cloud"-Anbieter oder einem an der Börse angesiedelten Server.
Desktop-Rechner sind einfach zu installieren und zu verwalten, insbesondere mit neueren benutzerfreundlichen Betriebssystemen wie Windows 7/8, Mac OSX und Ubuntu. Desktop-Systeme haben jedoch auch einige erhebliche Nachteile. Der wichtigste ist, dass die Versionen der Betriebssysteme, die für Desktop-Rechner entwickelt wurden, wahrscheinlich Neustarts/Patches erfordern (und das oft zu den ungünstigsten Zeiten!). Außerdem verbrauchen sie mehr Rechenressourcen, da sie eine grafische Benutzeroberfläche (GUI) benötigen.
Die Verwendung von Hardware in einer Heimumgebung (oder einem lokalen Büro) kann zu Problemen mit der Internetverbindung und der Stromversorgung führen. Der Hauptvorteil eines Desktop-Systems besteht darin, dass eine beträchtliche Rechenleistung für einen Bruchteil der Kosten eines dedizierten Servers (oder eines Cloud-basierten Systems) mit vergleichbarer Geschwindigkeit erworben werden kann.
Ein dedizierter Server oder eine Cloud-basierte Maschine ist zwar oft teurer als eine Desktop-Option, ermöglicht aber eine umfangreichere Redundanzinfrastruktur, wie z. B. automatische Datensicherungen, die Möglichkeit, die Betriebszeit einfacher zu gewährleisten, und eine Fernüberwachung. Sie sind schwieriger zu verwalten, da sie die Fähigkeit zur Fernanmeldung des Betriebssystems erfordern.
Unter Windows geschieht dies im Allgemeinen über das GUI Remote Desktop Protocol (RDP). In Unix-basierten Systemen wird die Befehlszeile Secure SHell (SSH) verwendet. Unix-basierte Serverinfrastrukturen sind fast immer kommandozeilenbasiert, was GUI-basierte Programmierwerkzeuge (wie MatLab oder Excel) sofort unbrauchbar macht.
Ein Co-Located Server, wie der Begriff auf den Kapitalmärkten verwendet wird, ist einfach ein dedizierter Server, der sich innerhalb einer Börse befindet, um die Latenzzeit des Handelsalgorithmus zu verringern. Dies ist für bestimmte Hochfrequenzhandelsstrategien, die auf eine geringe Latenzzeit angewiesen sind, um Alpha zu generieren, absolut notwendig.
Der letzte Aspekt bei der Wahl der Hardware und der Programmiersprache ist die Plattformunabhängigkeit. Muss der Code auf mehreren verschiedenen Betriebssystemen ausgeführt werden können? Ist der Code für eine bestimmte Prozessorarchitektur wie Intel x86/x64 ausgelegt oder kann er auch auf RISC-Prozessoren wie denen von ARM ausgeführt werden? Diese Fragen hängen in hohem Maße von der Häufigkeit und der Art der umzusetzenden Strategie ab.
Widerstandsfähigkeit und Tests
Quelle : youtube.com
Eine der besten Möglichkeiten, beim algorithmischen Handel viel Geld zu verlieren, besteht darin, ein System zu entwickeln, das nicht belastbar ist. Dies bezieht sich auf die Widerstandsfähigkeit des Systems bei seltenen Ereignissen wie Konkursen von Maklern, plötzlicher übermäßiger Volatilität, regionalem Ausfall eines Cloud-Server-Anbieters oder dem versehentlichen Löschen einer gesamten Handelsdatenbank. Jahrelange Gewinne können mit einer schlecht konzipierten Architektur innerhalb von Sekunden zunichte gemacht werden. Es ist absolut notwendig, Themen wie Fehlersuche, Testen, Protokollierung, Backups, Hochverfügbarkeit und Überwachung als Kernkomponenten Ihres Systems zu betrachten.
Es ist wahrscheinlich, dass bei jeder einigermaßen komplizierten benutzerdefinierten quantitativen Handelsanwendung mindestens 50 % der Entwicklungszeit auf Fehlersuche, Testen und Wartung entfallen.
Nahezu alle Programmiersprachen werden entweder mit einem Debugger ausgeliefert oder verfügen über bewährte Alternativen von Drittanbietern. Im Wesentlichen ermöglicht ein Debugger die Ausführung eines Programms mit dem Einfügen beliebiger Haltepunkte im Codepfad, die die Ausführung vorübergehend anhalten, um den Zustand des Systems zu untersuchen. Der Hauptvorteil des Debugging besteht darin, dass es möglich ist, das Verhalten des Codes vor einem bekannten Absturzpunkt zu untersuchen.
Debugging ist ein wesentlicher Bestandteil des Werkzeugkastens für die Analyse von Programmierfehlern. Sie werden jedoch eher in kompilierten Sprachen wie C++ oder Java verwendet, da interpretierte Sprachen wie Python aufgrund von weniger LOC und weniger ausführlichen Anweisungen oft einfacher zu debuggen sind. Trotz dieser Tendenz wird Python mit dem pdb ausgeliefert, einem hochentwickelten Debugging-Tool. Die Microsoft Visual C++ IDE verfügt über umfangreiche GUI-Debugging-Werkzeuge, während für Linux-C++-Programmierer, die auf der Kommandozeile arbeiten, der gdb-Debugger zur Verfügung steht.
Testen in der Softwareentwicklung bezieht sich auf den Prozess der Anwendung bekannter Parameter und Ergebnisse auf bestimmte Funktionen, Methoden und Objekte innerhalb einer Codebasis, um das Verhalten zu simulieren und mehrere Codepfade zu bewerten und so sicherzustellen, dass sich ein System so verhält, wie es sollte. Ein neueres Paradigma ist die testgetriebene Entwicklung (Test Driven Development, TDD), bei der der Testcode gegen eine bestimmte Schnittstelle ohne Implementierung entwickelt wird. Vor der Fertigstellung der eigentlichen Codebasis werden alle Tests fehlschlagen. Wenn der Code geschrieben wird, um die Lücken zu füllen, werden die Tests schließlich alle erfolgreich sein, und dann sollte die Entwicklung eingestellt werden.
TDD erfordert ein umfangreiches Design der Spezifikationen im Vorfeld sowie ein gesundes Maß an Disziplin, um erfolgreich durchgeführt werden zu können. In C++ bietet Boost einen Rahmen für Unit-Tests. In Java gibt es die JUnit-Bibliothek, die den gleichen Zweck erfüllt. Auch Python verfügt über das Modul unittest als Teil der Standardbibliothek. Viele andere Sprachen verfügen über Unit-Testing-Frameworks, und oft gibt es mehrere Optionen.
In einer Produktionsumgebung ist eine ausgefeilte Protokollierung unerlässlich. Logging bezieht sich auf den Prozess der Ausgabe von Meldungen mit verschiedenen Schweregraden über das Ausführungsverhalten eines Systems in eine flache Datei oder eine Datenbank. Protokolle sind eine "erste Angriffslinie" bei der Suche nach unerwartetem Programmlaufzeitverhalten. Leider werden die Unzulänglichkeiten eines Protokollierungssystems oft erst im Nachhinein entdeckt! Wie bei den weiter unten besprochenen Backups sollte ein Protokollierungssystem bereits VOR der Entwicklung eines Systems in Betracht gezogen werden.
Sowohl Microsoft Windows als auch Linux verfügen über umfangreiche Systemprotokollierungsfunktionen, und Programmiersprachen werden in der Regel mit Standardprotokollierungsbibliotheken ausgeliefert, die die meisten Anwendungsfälle abdecken. Es ist oft ratsam, die Logging-Informationen zu zentralisieren, um sie zu einem späteren Zeitpunkt zu analysieren, da sie oft zu Ideen zur Leistungsverbesserung oder Fehlerreduzierung führen können, was sich mit ziemlicher Sicherheit positiv auf Ihre Handelserträge auswirken wird.
Während die Protokollierung eines Systems Aufschluss darüber gibt, was in der Vergangenheit geschehen ist, gibt die Überwachung einer Anwendung Aufschluss darüber, was gerade geschieht. Alle Aspekte des Systems sollten bei der Überwachung berücksichtigt werden. Metriken auf Systemebene wie Festplattennutzung, verfügbarer Speicher, Netzwerkbandbreite und CPU-Nutzung liefern grundlegende Belastungsinformationen.
Handelskennzahlen wie abnormale Preise/Volumen, plötzliche schnelle Rückgänge und das Kontorisiko für verschiedene Sektoren/Märkte sollten ebenfalls kontinuierlich überwacht werden. Darüber hinaus sollte ein Schwellenwertsystem eingerichtet werden, das eine Benachrichtigung vorsieht, wenn bestimmte Metriken verletzt werden, wobei die Benachrichtigungsmethode (E-Mail, SMS, automatischer Telefonanruf) je nach Schweregrad der Metrik variiert.
Die Systemüberwachung ist oft die Domäne des Systemadministrators oder Betriebsleiters. Als Entwickler eines Einzelhandelsunternehmens müssen diese Metriken jedoch als Teil des Gesamtkonzepts festgelegt werden. Es gibt viele Lösungen für die Überwachung: proprietäre, gehostete und Open-Source-Lösungen, die eine umfassende Anpassung der Metriken für einen bestimmten Anwendungsfall ermöglichen.
Backups und hohe Verfügbarkeit sollten bei einem Handelssystem an erster Stelle stehen. Betrachten Sie die folgenden zwei Fragen: 1) Wenn eine gesamte Produktionsdatenbank mit Marktdaten und Handelshistorie gelöscht würde (ohne Backups), wie würde sich das auf den Recherche- und Ausführungsalgorithmus auswirken? 2) Wie würde sich ein längerer Ausfall des Handelssystems (mit offenen Positionen) auf den Kontostand und die laufende Rentabilität auswirken? Die Antworten auf diese beiden Fragen sind oft ernüchternd!
Es ist unbedingt erforderlich, ein System zur Sicherung der Daten und zum Testen der Wiederherstellung dieser Daten einzurichten. Viele Personen testen keine Wiederherstellungsstrategie. Wenn die Wiederherstellung nach einem Absturz nicht in einer sicheren Umgebung getestet wurde, welche Garantien gibt es dann, dass die Wiederherstellung im schlimmsten Fall verfügbar ist?
In ähnlicher Weise muss die Hochverfügbarkeit von Anfang an "eingebaut" werden. Redundante Infrastrukturen (auch wenn sie zusätzliche Kosten verursachen) müssen immer in Betracht gezogen werden, da die Kosten für Ausfallzeiten die laufenden Wartungskosten solcher Systeme wahrscheinlich bei weitem übersteigen. Ich werde nicht zu tief in dieses Thema eindringen, da es ein großer Bereich ist, aber stellen Sie sicher, dass es eine der ersten Überlegungen ist, die Sie für Ihr Handelssystem anstellen.
Auswahl einer Sprache
Die verschiedenen Faktoren, die bei der Entwicklung eines maßgeschneiderten, leistungsstarken algorithmischen Handelssystems eine Rolle spielen, wurden nun ausführlich beschrieben. In einem nächsten Schritt soll nun erörtert werden, wie Programmiersprachen im Allgemeinen kategorisiert werden.
Typensysteme
Bei der Auswahl einer Sprache für einen Trading Stack muss das Typsystem berücksichtigt werden. Die Sprachen, die für den algorithmischen Handel von Interesse sind, sind entweder statisch oder dynamisch typisiert. Bei einer statisch typisierten Sprache werden die Typen (z. B. Ganzzahlen, Gleitkommazahlen, benutzerdefinierte Klassen usw.) während des Kompilierungsprozesses überprüft. Zu diesen Sprachen gehören C++ und Java. Eine dynamisch typisierte Sprache führt den Großteil der Typüberprüfung zur Laufzeit durch. Zu diesen Sprachen gehören Python, Perl und JavaScript.
Für ein hochgradig numerisches System wie eine algorithmische Handelsmaschine kann die Typüberprüfung zur Kompilierungszeit äußerst vorteilhaft sein, da sie viele Fehler beseitigen kann, die sonst zu numerischen Fehlern führen würden. Allerdings fängt die Typüberprüfung nicht alles ab, und hier kommt die Ausnahmebehandlung ins Spiel, da unerwartete Operationen gehandhabt werden müssen. Dynamische" Sprachen (d.h. solche, die dynamisch typisiert sind) können oft zu Laufzeitfehlern führen, die andernfalls durch eine Typüberprüfung bei der Kompilierung abgefangen würden. Aus diesem Grund entstand das Konzept der TDD (siehe oben) und der Unit-Tests, die, wenn sie korrekt durchgeführt werden, oft mehr Sicherheit bieten als die Kompilierzeitprüfung allein.
Ein weiterer Vorteil statisch typisierter Sprachen besteht darin, dass der Compiler viele Optimierungen vornehmen kann, die einer dynamisch typisierten Sprache nicht zur Verfügung stehen, einfach weil der Typ (und damit der Speicherbedarf) zur Kompilierzeit bekannt ist. Tatsächlich rührt ein Teil der Ineffizienz vieler dynamisch typisierter Sprachen von der Tatsache her, dass bestimmte Objekte zur Laufzeit typgeprüft werden müssen, was mit Leistungseinbußen verbunden ist. Bibliotheken für dynamische Sprachen, wie z. B. NumPy/SciPy, mildern dieses Problem durch die Erzwingung eines Typs in Arrays.
Open Source oder proprietär?
Eine der wichtigsten Entscheidungen, die ein Entwickler von algorithmischen Handelssystemen treffen muss, ist die Frage, ob er proprietäre (kommerzielle) oder Open-Source-Technologien verwenden möchte. Beide Ansätze haben ihre Vor- und Nachteile. Es ist zu berücksichtigen, wie gut eine Sprache unterstützt wird, wie aktiv die Gemeinschaft rund um eine Sprache ist, wie einfach die Installation und Wartung ist, wie gut die Dokumentation ist und wie hoch die Lizenzierungs- und Wartungskosten sind.
Der .NET-Stack von Microsoft (einschließlich Visual C++ und Visual C#) und MatLab von MathWorks sind zwei der größeren proprietären Lösungen für die Entwicklung kundenspezifischer algorithmischer Handelssoftware. Beide Tools haben sich in der Finanzbranche bewährt, wobei erstere den vorherrschenden Software-Stack für die Handelsinfrastruktur im Investmentbanking bilden und letztere in großem Umfang für die quantitative Handelsforschung in Investmentfonds verwendet werden.
Sowohl Microsoft als auch MathWorks bieten eine umfangreiche und qualitativ hochwertige Dokumentation für ihre Produkte. Darüber hinaus sind die Communities rund um jedes Tool sehr groß und es gibt aktive Webforen für beide. Die .NET-Software ermöglicht eine kohärente Integration mit mehreren Sprachen wie C++, C# und VB. Für MatLab gibt es außerdem viele Plugins/Bibliotheken (einige kostenlos, andere kommerziell) für nahezu jeden Bereich der quantitativen Forschung.
Es gibt auch Nachteile. Bei beiden Programmen sind die Kosten für einen Einzelkämpfer nicht unerheblich (obwohl Microsoft die Einstiegsversion von Visual Studio kostenlos anbietet). Die Microsoft-Tools "spielen" gut miteinander, lassen sich aber weniger gut mit externem Code integrieren. Visual Studio muss außerdem auf Microsoft Windows ausgeführt werden, das wohl weit weniger leistungsfähig ist als ein entsprechender, optimal abgestimmter Linux-Server.
Außerdem fehlen MatLab einige wichtige Plugins, wie z. B. ein guter Wrapper für die API von Interactive Brokers, einem der wenigen Broker, die sich für den algorithmischen Hochleistungshandel eignen. Das Hauptproblem bei proprietären Produkten ist die mangelnde Verfügbarkeit des Quellcodes. Das bedeutet, dass diese beiden Tools weit weniger attraktiv sind, wenn wirklich Höchstleistung gefragt ist.
Open-Source-Tools sind schon seit einiger Zeit branchenüblich. Im Bereich der alternativen Anlagen werden Open-Source-Linux, MySQL/PostgreSQL, Python, R, C++ und Java in hohem Maße für die Produktion eingesetzt. Sie sind jedoch bei weitem nicht auf diesen Bereich beschränkt. Insbesondere Python und R enthalten eine Fülle umfangreicher numerischer Bibliotheken, mit denen sich nahezu jede erdenkliche Art von Datenanalyse durchführen lässt, und zwar oft mit Ausführungsgeschwindigkeiten, die mit kompilierten Sprachen vergleichbar sind, allerdings mit einigen Einschränkungen.
Der Hauptvorteil der Verwendung interpretierter Sprachen liegt in der kürzeren Entwicklungszeit. Python und R benötigen viel weniger Codezeilen (LOC), um eine ähnliche Funktionalität zu erreichen, was hauptsächlich auf die umfangreichen Bibliotheken zurückzuführen ist. Darüber hinaus ermöglichen sie oft eine interaktive konsolenbasierte Entwicklung, wodurch der iterative Entwicklungsprozess schnell verkürzt wird.
Da die Zeit eines Entwicklers extrem wertvoll ist und die Ausführungsgeschwindigkeit oft weniger (außer im HFT-Bereich), lohnt es sich, einen Open-Source-Technologiestack ausgiebig in Betracht zu ziehen. Python und R verfügen über bedeutende Entwicklergemeinschaften und werden aufgrund ihrer Popularität sehr gut unterstützt. Die Dokumentation ist hervorragend, und Bugs (zumindest bei den Kernbibliotheken) sind selten.
Open-Source-Tools leiden oft unter dem Fehlen eines speziellen kommerziellen Supportvertrags und laufen optimal auf Systemen mit weniger nachsichtigen Benutzeroberflächen. Ein typischer Linux-Server (z. B. Ubuntu) ist oft vollständig kommandozeilenorientiert. Darüber hinaus können Python und R bei bestimmten Ausführungsaufgaben langsam sein. Es gibt Mechanismen für die Integration mit C++, um die Ausführungsgeschwindigkeit zu verbessern, aber dies erfordert einige Erfahrung in der mehrsprachigen Programmierung.
Zwar ist auch proprietäre Software nicht vor Problemen mit Abhängigkeiten/Versionen gefeit, doch kommt es in solchen Umgebungen weitaus seltener vor, dass man mit falschen Bibliotheksversionen zu kämpfen hat. Open-Source-Betriebssysteme wie Linux können schwieriger zu verwalten sein.
Ich möchte hier meine persönliche Meinung kundtun und behaupten, dass ich alle meine Handelswerkzeuge mit Open-Source-Technologien entwickle. Ich verwende insbesondere: Ubuntu, MySQL, Python, C++ und R. Die Ausgereiftheit, die Größe der Community, die Möglichkeit, bei Problemen in die Tiefe zu gehen, und die niedrigeren Gesamtbetriebskosten (TCO) überwiegen bei weitem die Einfachheit proprietärer Benutzeroberflächen und einfacher Installationen. Abgesehen davon ist Microsoft Visual Studio (insbesondere für C++) eine fantastische integrierte Entwicklungsumgebung (IDE), die ich ebenfalls sehr empfehlen würde.
Enthaltene Batterien?
Quelle : tradeoptionswithme.com
Die Überschrift dieses Abschnitts bezieht sich auf die "out of the box"-Fähigkeiten der Sprache - welche Bibliotheken enthält sie und wie gut sind sie? Hier haben ausgereifte Sprachen einen Vorteil gegenüber neueren Varianten. C++, Java und Python verfügen alle über umfangreiche Bibliotheken für Netzwerkprogrammierung, HTTP, Betriebssysteminteraktion, grafische Benutzeroberflächen, reguläre Ausdrücke (regex), Iteration und grundlegende Algorithmen.
C++ ist berühmt für seine Standard Template Library (STL), die eine Fülle von leistungsstarken Datenstrukturen und Algorithmen "kostenlos" enthält. Python ist dafür bekannt, dass es mit fast allen anderen Systemen/Protokollen (insbesondere dem Web) kommunizieren kann, vor allem über seine eigene Standardbibliothek. R verfügt über eine Fülle statistischer und ökonometrischer Tools, während MatLab für numerische lineare Algebra-Codes (wie sie z. B. bei der Portfolio-Optimierung und der Preisgestaltung von Derivaten verwendet werden) extrem optimiert ist.
Außerhalb der Standardbibliotheken macht C++ Gebrauch von der Boost-Bibliothek, die die "fehlenden Teile" der Standardbibliothek ergänzt. Tatsächlich wurden viele Teile von Boost in den TR1-Standard aufgenommen und sind nun in der C++11-Spezifikation verfügbar, einschließlich nativer Unterstützung für Lambda-Ausdrücke und Nebenläufigkeit.
Python verfügt über die Hochleistungsbibliothek NumPy/SciPy/Pandas für die Datenanalyse, die sich in der algorithmischen Handelsforschung weithin durchgesetzt hat. Darüber hinaus gibt es leistungsstarke Plugins für den Zugriff auf die wichtigsten relationalen Datenbanken, wie MySQL++ (MySQL/C++), JDBC (Java/MatLab) und MySQLdb (MySQL/Python). Python kann über das RPy-Plugin sogar mit R kommunizieren!
Ein oft übersehener Aspekt eines Handelssystems in der anfänglichen Forschungs- und Entwurfsphase ist die Konnektivität mit einer Broker-API. Die meisten APIs unterstützen von Haus aus C++ und Java, aber einige unterstützen auch C# und Python, entweder direkt oder mit von der Community bereitgestelltem Wrapper-Code für die C++-APIs. Insbesondere Interactive Brokers können über das IBPy-Plugin angebunden werden. Wenn eine hohe Leistung erforderlich ist, unterstützen die Broker das FIX-Protokoll.
Schlussfolgerung
Wie jetzt deutlich wird, ist die Wahl der Programmiersprache(n) für ein algorithmisches Handelssystem nicht einfach und erfordert gründliche Überlegungen. Die wichtigsten Erwägungen sind Leistung, einfache Entwicklung, Ausfallsicherheit und Tests, Trennung von Belangen, Vertrautheit, Wartung, Verfügbarkeit von Quellcode, Lizenzkosten und Reife der Bibliotheken.
Der Vorteil einer getrennten Architektur besteht darin, dass Sprachen für verschiedene Aspekte eines Trading Stacks "eingesteckt" werden können, wenn sich die Anforderungen ändern. Ein Handelssystem ist ein sich ständig weiterentwickelndes Werkzeug, und es ist wahrscheinlich, dass sich die Wahl der Sprache mit ihm weiterentwickeln wird.