2012-03-29 12 views
-5

Ich bin für Code suchen, dieKonstrukt Orderbuch von Aufträgen Beispiel

Zum Beispiel Orderbuch von Aufträgen konstruiert, wenn Aufträge sollte

side | price | quantity 
buy 100  1 
buy 101  10 
buy 100  1000 
buy 100  10000 

dann agregated Orderbuch sein:

side | price | quantity 
buy 100  11001 
buy 101  10 

Während des Programms lebenslange Aufträge werden hinzugefügt, geändert oder gelöscht. Bei jedem Bestellupdate muss ich OrderBook schnell aktualisieren.

Ich bin mir sicher, das ist sehr häufig Aufgabe, so sollte es eine Menge Implementierungen im Internet bereits sein.

Vielen Dank für alle Referenzen, ich bin auf der Suche nach C# Implementierung, aber ich kann es aus einer anderen Sprache neu schreiben, wenn nötig.

upd Eigentlich sollte ich meine Frage neu formulieren. Anfangs ist das Orderbuch leer. Dann erhalte ich Ereignisse: Bestellung hinzufügen, Bestellmenge ändern oder Bestellung stornieren. Ich sollte OrderBook von diesen Nachrichten neu berechnen. Aber jetzt wird mir klar, wie einfach es sein sollte. Wenn die Bestellung hinzugefügt wird, füge ich nur die Menge zu diesem Preis hinzu. Wenn Auftragsmenge geändert wird, muss ich nur "Änderung" addieren und wenn Auftrag annulliert wird, muss ich nur entsprechende Quantität vom entsprechenden Preisniveau entfernen. Die einzige Frage ist, wo sollte ich "letzte Bestellmenge" speichern. Insgesamt gibt es viele Bestellungen (Dutzende von Millionen), aber es gibt nicht viele aktive Bestellungen (nicht mehr als 100 000) und für jede aktive Bestellung muss ich erhalte "last quantity" by orderId ... Natürlich kann ich das Wörterbuch benutzen, aber das wäre wahrscheinlich zu langsam. Ich will etwas schneller. Aber ich kann nicht 50 000 000 Elemente Array verwenden.

+0

"Es sollte bereits viele Implementierungen im Internet geben". Ich bezweifle das. Es kann jedoch kommerzielle Implementierungen solcher Sachen geben. –

+0

Oh, und bitte sehen Sie http://mattgememm.com/2008/12/08/what-have-you-tried/ für das nächste Mal –

+0

ich denke, ociweb Liquibook ist die beliebteste Open-Source-Implementierung von Orderbook – javapowered

Antwort

0

eine Abfrage können Sie in

UPDATE OrderBook 
SET quantity = (
    SELECT SUM(quantity) FROM orders 
    WHERE price = :your_price 
     AND side = :your_side) p 
WHERE price = :your_price 
    AND side = :your_side 

wo tun: your_price und: your_side sind Werte von modifizierten Reihenfolge.
besser, wenn Sie alle Tabelle beseitigen können und es von Anfang füllen:

TRUNCATE TABLE OrderBook; 
INSERT INTO OrderBook 
SELECT side, price, SUM(quantity) 
FROM orders 
GROUP BY side, price 

In meinem ersten Beispiel, das ich diese Menge in Ihrer Bestellung ändern kann nur dann ausgegangen; Aber wenn sich andere Werte ändern können, kann es nicht funktionieren.
Zweites Beispiel ist teuer, also verwenden Sie es nur, wenn sich Ihre Bestellung nicht oft ändert.
Endlich: wenn Ihre Aufträge variieren oft und jeder Wert kann man ändern könnte:

  1. aktualisieren Orderbuch Werte aus, um zu entfernen, die geändert werden sollte (so, bevor es aktualisiert wird)
  2. aktualisieren Orderbuchwerte aus, um das Hinzufügen das hat wurde geändert.
+0

Es macht mehr Sinn, es nur eine Sicht basierend auf der Gruppe nach Abfrage zu machen. Lassen Sie die Datenbank das Zwischenspeichern übernehmen und den Cache verwalten. – Servy

+0

Entschuldigung, ich habe die Beschreibung aktualisiert. Ich muss keine aktuellen Bestellungen in das Orderbuch "übertragen". Ich muss das während der Laufzeit der Anwendung auf jedem "Auftrag Update-Ereignis" – javapowered

0

Sie müssen Gruppe der price und side und dann die Summe von quantity für jede Gruppe auswählen. Da Sie kein Medium (Datenbank, Objekte im Speicher usw.) angegeben haben, können wir Ihnen keine spezifische Implementierung geben.

Edit: offenbar sind dieses Objekt im Speicher, in welchem ​​Fall LINQ ist dein Freund:

var results = orders.OrderBy(order => new{order.side, order.price}) 
.Select(group => new{ group.Key.side, group.Key.price, group.Sum(order => order.quantity)); 
+0

Ich brauche C# Implementierung, natürlich habe ich Aufträge im Speicher :) – javapowered

2

Hier ist der Code in LINQPad


var orders = new [] { 
    new {Side = "Buy", Price = 100, Quantity = 1 }, 
    new {Side = "Buy", Price = 101, Quantity = 10 }, 
    new {Side = "Buy", Price = 100, Quantity = 1000 }, 
    new {Side = "Buy", Price = 100, Quantity = 10000 }, 
    new {Side = "Sell", Price = 100, Quantity = 10000 } 
}; 

var orderboook 
    = from o in (   
        from order in orders 
        group order by order.Side into sideGroup 
        select new { 
         Side = sideGroup.Key, 
         SideGroup = 
          from s in sideGroup 
          group s by s.Price into g 
          select new { 
           Side = sideGroup.Key, 
           Price = g.Key, 
           Quantity = g.Sum(s => s.Quantity) 
          } 
        } 
       ) 
    from g in o.SideGroup 
    select g; 

orderboook.Dump(); // .Dump() is LINQPad helper method... 

Das Ergebnis in LINQPad getestet ist
orderbook result in LINQPad

+0

+1 für mich auf LINQPad :) – reagan

0

Natürlich kann ich dictio verwenden nary, aber das wäre zu langsam wahrscheinlich

Jede Lösung wird entweder einen Baum oder eine Hashtabelle beinhalten. Daher ist es wahrscheinlich besser, die Standard-Wörterbuchimplementierung Ihrer Sprache zu verwenden.

Jetzt raten Sie nichts über die Leistung, besonders bevor Sie etwas implementiert haben, das funktioniert. Dann, Profil, und wenn die bestimmte Wörterbuchimplementierung, die Sie verwenden, nachweislich die Leistung beeinträchtigt, dann stellen Sie eine spezifische Frage mit tatsächlichem Code, den wir gerne versuchen zu verbessern.

+0

Ich denke, Sie richtig. Wissend, dass 95% der aktiven Aufträge "sehr nahe beieinander" sind, dh ihre ID ist mit 100 000 Intervall Ich kann wahrscheinlich versuchen, Array für diesen Teil zu verwenden und Wörterbuch für den Rest 5% der Aufträge zu verwenden, und ich muss Verschiebt Befehle dynamisch von Array zu Dictionary. Aber das hört sich so kompliziert an, dass ich 'Dictionary' lieber als erste Aufnahme benutze und es bei Bedarf profiliere. – javapowered

+0

@javapowered: Das Sprichwort sagt:" Mach die einfachste Sache, die möglicherweise funktionieren kann "(und aus Erfahrung ist dies eine goldene Regel) in irgendeiner Form des [algorithmischen] Handels). –

+0

@javapowered: Auch hier ist Leistung relativ. Ich nehme an, Ihr Interesse wird mehr auf Verbindungslatenz als auf billiges Zeug wie das Speichern von Sachen in einem Wörterbuch gerichtet sein. Die einzige beste Verbesserung, die Geld für HFT kaufen kann, ist Colocation. –