VonmoTrade-Experiment. Teil 3: Optionsscheinheft. Verarbeitung und Speicherung von Handelsinformationen


Im letzten Artikel des Zyklus haben wir die Arten von UmtauschauftrÀgen kennengelernt. Heute werden wir das Auftragsbuch, die Bearbeitung von AntrÀgen und Fragen im Zusammenhang mit der Organisation der Speicherung von Handelsinformationen analysieren.


Nachfrage und Angebot


Sicherlich erinnern Sie sich an das Gesetz von Angebot und Nachfrage im Verlauf der Wirtschaft, das die Mechanismen des Marktes fĂŒr Preisbildung zeigt:



Die gleiche Mechanik arbeitet am Austausch.


Das Orderbuch ist eine Liste, in die LimitauftrÀge von VerkÀufern und KÀufern eingetragen werden und die das aktuelle Interesse an einem bestimmten Finanzinstrument anzeigt.


Wenn Sie die vorherige Grafik in Bezug auf das Auftragsbuch konvertieren, erhalten Sie ungefÀhr Folgendes:



Hier sehen wir, dass der Marktpreis erhalten wird, wenn der maximale Nachfragepreis und der minimale Angebotspreis gleich sind. Spread ist der Unterschied in diesen Preisen. Dies ist ein wichtiger Indikator, da er mit der LiquiditĂ€t des Instruments zusammenhĂ€ngt. Je geringer der Spread, desto flĂŒssiger das Instrument. Um die LiquiditĂ€t im Rahmen des Börsenhandels zu gewĂ€hrleisten, wird der maximale Spread hĂ€ufig begrenzt, oberhalb dessen der Handel eingestellt werden kann.


Erstellung von Anwendungen


BerĂŒcksichtigen Sie den Lebensverlauf einer Bewerbung von der Zulassung ĂŒber den Umtausch bis zur ErfĂŒllung oder Stornierung. Der Einfachheit halber betrachten wir den Devisenmarkt. Ein spezieller Prozess ist fĂŒr die Logik der Auftragsabwicklung zustĂ€ndig, nennen wir ihn den Market Controller.


Also, der Teilnehmer erstellt eine Bewerbung, es kommt zur Vermittlung. Der Controller muss sicherstellen, dass der Teilnehmer ĂŒber genĂŒgend LiquiditĂ€t verfĂŒgt, um die angeforderte Auftragsart zu erstellen. Die Informationsquelle kann ein interner Buchhaltungsservice oder eine beliebige externe API sein.


FĂŒr die sofortige AusfĂŒhrung dieser Anwendung muss eine sogenannte Paired-Anwendung auf dem Markt vorhanden sein.


Wenn es eine Gegenreihenfolge des gefundenen Paares gibt, wird die kleinere Reihenfolge vollstĂ€ndig und die grĂ¶ĂŸere teilweise ausgefĂŒhrt. NatĂŒrlich, wenn die Handelsanweisungen der Anwendung eine teilweise AusfĂŒhrung zulassen. Fehlt eine Gegenbestellung, fĂ€llt eine neue Bestellung in das Auftragsbuch und nimmt ihren Platz in der Auftragsliste ihrer Art ein.


Da nur ausstehende Bestellungen in das Auftragsbuch aufgenommen werden, mĂŒssen Sie fĂŒr Bestellungen anderer Typen Ihre Listen auswĂ€hlen.


In allen Bestelllisten sollte die Einkaufsseite in absteigender Reihenfolge und die Verkaufsseite in aufsteigender Reihenfolge sortiert sein. Das erste Element der Liste der LimitauftrĂ€ge fĂŒr jede Seite bildet den jeweils besten Preis fĂŒr Angebot und Nachfrage.


Ein weiterer wichtiger Punkt ist die Reihenfolge der AusfĂŒhrung. Die Steuerung muss FIFO implementieren. Wenn daher die Preise der beiden Gebote ĂŒbereinstimmen, sollte das zuvor erstellte höher sein.


In der BenutzeroberflĂ€che sieht das Buch wie eine Tabelle aus, die aus einer Reihe von Preisstufen besteht, in denen LimitauftrĂ€ge sowohl fĂŒr den Kauf als auch fĂŒr den Verkauf angezeigt werden.



Zur zusÀtzlichen visuellen Unterscheidung haben Kauf- und Verkaufsanwendungen unterschiedliche Farben.


Level Aggregation


Buchtiefe - Die Anzahl der Preisstufen. Bei aktiven MĂ€rkten mit einer großen Anzahl von ausstehenden AuftrĂ€gen, die durch einen Mindestabstand voneinander getrennt sind, kann die Tiefe fĂŒr die Anzeige im Terminal des HĂ€ndlers sehr groß sein. Um das gesamte Buch zu bewerten, benötigen Sie ein Level-Gruppierungs-Tool.


Indem wir eine Dezimalstelle abschneiden und die Ebenen gruppieren, können wir ihre Anzahl bei jedem Schritt verringern.


AusfĂŒhrung und Stornierung von AntrĂ€gen


Nachdem der Auftrag im Buch ausgefĂŒhrt oder storniert wurde, muss der Controller das Buch aktualisieren, indem er diesen Auftrag löscht und alle an den Änderungen im Buch interessierten Personen benachrichtigt.


Handlerarchitektur und Skalierung


Angesichts der erforderlichen Leistung und ZuverlĂ€ssigkeit mĂŒssen AnsĂ€tze zur Skalierung von Anwendungen und Speichersystemen festgelegt werden.


In der Regel verwenden Börsen die vertikale Skalierung. Der Code zum Verarbeiten von Anwendungen und Benutzerkonten wird auf einem Computer innerhalb eines einzelnen Monolithen ausgefĂŒhrt. Ein solcher Ansatz zeigt eine gute Leistung, weist jedoch eine erhebliche EinschrĂ€nkung auf - in jedem Fall ist die vertikale Skalierung sowohl hinsichtlich der Prozessorleistung als auch der SpeicherkapazitĂ€t begrenzt.


Im Rahmen des Experiments entschied ich, dass die Marktbearbeitung horizontal skaliert werden sollte. Jedes einzelne Werkzeug wird nach einem eigenen Verfahren bearbeitet. Prozesse werden automatisch auf die Clusterknoten verteilt. Im Falle eines Ausfalls wird der Markt ohne Statusverlust auf einen anderen Knoten ĂŒbertragen.



Die Formel des Systems ist Ă€ußerst einfach: M Handler sind auf K Knoten des Clusters verteilt und verwenden L Datenspeicher.
Mit einem Àhnlichen Schema können Sie das System auf ungefÀhr 150 Knoten skalieren. Und jeder Markt-Controller kann ungefÀhr 30.000 RPS verarbeiten.


Da der Anwendungsfluss in allen MĂ€rkten unterschiedlich ist und von der BenutzeraktivitĂ€t abhĂ€ngt, können die MĂ€rkte in mehrere Gruppen unterteilt werden: kleine, mittlere und große. Jeder Knoten verfĂŒgt ĂŒber Einstellungen, mit denen Sie die Anzahl der MĂ€rkte begrenzen können, die er verarbeiten kann. Der Assistent verteilt MĂ€rkte desselben Typs automatisch und gleichmĂ€ĂŸig auf Clusterknoten. Bei einer Änderung der Clusterzusammensetzung werden die MĂ€rkte neu verteilt. Dadurch wird eine mehr oder weniger gleichmĂ€ĂŸige Lastverteilung auf das System erreicht.


Eine Beispielansicht von Knoten in der Exchange-Verwaltungsschnittstelle:



Datenspeicherung


Das Auftragsbuch Ă€ndert sich stĂ€ndig und muss im GedĂ€chtnis behalten werden. FĂŒr MVP habe ich Tarantool mit WAL als In-Memory-Speicher gewĂ€hlt. Alle historischen Daten werden in PostgreSQL aufgezeichnet.


Das Schema zum Speichern aktueller und historischer Daten sollte dem ausgewÀhlten Schema zum Skalieren des Codes der Handler entsprechen. Jeder Markt kann sein eigenes Postgres und Tarantool verwenden. Kombinieren Sie dazu das Paar aus postgresql und tarantool zu einer einzigen EntitÀt - einem Market Data Warehouse.


Beim Einrichten des Marktes hat der Administrator die Möglichkeit, Repositorys zu verwalten. Um die FlexibilitĂ€t aufrechtzuerhalten, geben wir anstelle des Zugriffs auf bestimmte postgresql- und tarantool-Instanzen eine eindeutige Verbindungspool-ID an. Die Schnittstelle dieser Pools wird von der Plattform unterstĂŒtzt. Somit sieht das Repository in der Admin-OberflĂ€che folgendermaßen aus:



Beim Einrichten eines Marktes muss der Administrator mindestens ein GeschĂ€ft fĂŒr jeden Markt angeben. Wenn Sie einige angeben, erhalten Sie einen Markt mit logischer Datenreplikation. Mit dieser Funktion können Sie die ZuverlĂ€ssigkeit und Leistung eines Speicherschemas konfigurieren.


Auftragsbuchdaten


Tarantool verwendet Speicherplatz, um gespeicherte Daten zu organisieren. Die Angabe der benötigten PlĂ€tze fĂŒr das Auftragsbuch lautet wie folgt:


book = { state = { name = 'book_state', id = 1, }, orders = { limit = { buy_orders = { name = 'limit_buy_orders', id = 10, }, sell_orders = { name = 'limit_sell_orders', id = 20, }, }, market = { buy_orders = { name = 'market_buy_orders', id = 30, }, sell_orders = { name = 'market_sell_orders', id = 40, }, }, ... }, orders_mapping = { name = 'orders_mapping', id = 50, }, } 

Da mehrere MĂ€rkte ihre Daten auf einer Tarantool-Instanz speichern können, fĂŒgen wir allen EntitĂ€ten eine Marktkennung hinzu. Die derzeitige Umsetzung des Buches basiert auf dem Prinzip des einmaligen ZĂ€hlens und des mehrmaligen Gebens. WĂ€hrend der Buchaktualisierung werden Gruppierungen automatisch nachgezĂ€hlt. Zum Beispiel fĂŒgen wir dem Markt eine Bestellung hinzu, die Genauigkeit der Preise betrĂ€gt 6, es gibt 6 mögliche Preisgruppen + eine Scheibe mit den ursprĂŒnglichen Bestelldaten, die aktualisiert werden mĂŒssen.


Es gibt eine Vielzahl von orders_mapping-AuftrĂ€gen fĂŒr die Ausgabe von Listen aktiver KundenauftrĂ€ge.


Dank des Tarantool-Datenmodells, das eine Kombination aus Indizes und verschiedenen Stichprobeniteratoren verwendet, benötigt der Lua-Code, der die Speicherung des Auftragsbuchs implementiert, nur 600 Zeilen (zusammen mit der Initialisierung).


Historische Daten


Marktdaten werden fĂŒr jeden Markt in separaten Tabellen gespeichert. Betrachten Sie eine Reihe von Basistabellen.


Verlauf abgeschlossener Bewerbungen


Verwenden Sie die Verlaufstabelle, um die Ergebnisse der Verarbeitung von Anwendungen zu speichern. Es enthĂ€lt vollstĂ€ndig ausgefĂŒllte AntrĂ€ge sowie stornierte, jedoch teilweise ausgefĂŒllte AntrĂ€ge.


 CREATE TABLE public.history ( id uuid NOT NULL, ts timestamp without time zone NOT NULL DEFAULT now(), owner character varying(75) COLLATE pg_catalog."default" NOT NULL, order_type integer NOT NULL, order_side integer NOT NULL, price numeric(64,32) NOT NULL, qty numeric(64,32) NOT NULL, commission numeric(64,32) NOT NULL, opts jsonb NOT NULL, CONSTRAINT history_pkey PRIMARY KEY (id, ts) ) 

Die Ausgabe fĂŒr Endnutzer basiert auf der Vorgeschichte ihrer Angebote.


Feed mit historischen Daten


Zu Analysezwecken sowie zur Bildung eines historischen Datenfeeds muss der Marktcontroller nach jeder Transaktion Informationen zu diesem Ereignis speichern. Verwenden Sie die Tick-Tabelle, um Ereignisse von MarktÀnderungen zu beheben:


 CREATE TABLE public.ticks ( ts timestamp without time zone NOT NULL, bid numeric(64,32) NOT NULL, ask numeric(64,32) NOT NULL, last numeric(64,32) NOT NULL, bid_vol numeric(64,32), ask_vol numeric(64,32), last_vol numeric(64,32), opts jsonb DEFAULT '{}'::jsonb, CONSTRAINT ticks_pk PRIMARY KEY (ts) ) 

Nach der Transaktion werden Preise und Marktvolumina gespeichert, und das Feld opts enthÀlt Serviceinformationen, z. B. eine Beschreibung der an der Transaktion beteiligten Bestellungen.


Diagrammdaten-Feed


Um Trading-Charts zu erstellen, reicht die Tick-Tabelle aus. Es enthĂ€lt den sogenannten Raw-Stream, aber postgresql verfĂŒgt ĂŒber leistungsstarke Analysefunktionen und ermöglicht es Ihnen, Daten nach Bedarf zu aggregieren.


Probleme beginnen, wenn zu viele Daten vorhanden sind und zu wenig Strom vorhanden ist. Erstellen Sie zum Lösen eine Tabelle mit vorberechneten Daten:


 CREATE TABLE public.df ( t timestamp without time zone NOT NULL, r df_resolution NOT NULL DEFAULT '1m'::df_resolution, o numeric(64,32), h numeric(64,32), l numeric(64,32), c numeric(64,32), v numeric(64,32), CONSTRAINT df_pk PRIMARY KEY (t, r) ) 

Wir werden im nĂ€chsten Artikel darĂŒber sprechen, wie man mit Zeitreihen in Postgresql arbeitet, Daten fĂŒr die df-Tabelle aufbereitet und wie man Diagramme erstellt.


Zusammenfassung


Wir haben die wichtigsten Punkte bei der Organisation des Auftragsbuchs und des Auftragsabwicklungsmechanismus herausgefunden und uns ein wenig mit der Arbeit mit Marktdaten befasst.


Das ausgewĂ€hlte Speicherschema ermöglicht es Ihnen, von einem GeschĂ€ft fĂŒr alle MĂ€rkte aus zu starten und die MĂ€rkte im Verlauf des Projekts auf verschiedene GeschĂ€fte zu verteilen, um sie so nah wie möglich an den Marktprozessoren zu platzieren.

Source: https://habr.com/ru/post/de482254/


All Articles