-5

注文からオーダーブックを構築するコードを探しています

たとえば、注文が

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

集約されたオーダーブックは次のようになります。

side | price | quantity
buy    100     11001
buy    101     10 

プログラムの存続期間中に、注文が追加、変更、または削除されます。注文を更新するたびに、OrderBook をすばやく更新する必要があります。

これは非常に一般的なタスクであると確信しているため、インターネットにはすでに多くの実装があるはずです。

参考にしていただきありがとうございます。C# の実装を探していますが、必要に応じて別の言語から書き直すことができます。

更新実際には、質問を言い換える必要があります。最初のオーダーブックは空です。次に、注文の追加、注文数量の変更、注文のキャンセルなどのイベントを受け取ります。このメッセージから orderBook を再計算する必要があります。しかし今、それがどれほどシンプルであるべきかが明らかになりました。注文が追加されると、この価格レベルで数量を追加するだけです。注文数量が変更された場合は、「変更」を追加するだけでよく、注文がキャンセルされた場合は、対応する価格レベルから対応する数量を削除する必要があります。唯一の問題は、「最終注文数量」をどこに保存すればよいかということです。全体として多くの注文 (数十万件) がありますが、アクティブな注文 (100 000 以下) は多くなく、アクティブな注文ごとに必要です。 orderId で「最後の数量」を取得... もちろん辞書を使用できますが、おそらく遅すぎるでしょう。もっと速いものが欲しい。

4

4 に答える 4

3

これが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...

LINQPad の結果は
LINQPad でのオーダーブックの結果

于 2012-03-29T18:24:53.353 に答える
1

もちろん辞書を使うこともできますが、おそらく遅すぎるでしょう

どのソリューションにも、ツリーまたはハッシュテーブルが含まれます。したがって、言語の標準的な辞書実装を使用する方がよいでしょう。

特に、機能するものを実装する前は、パフォーマンスについて何も推測しないでください。次にプロファイリングし、使用している特定の辞書の実装がパフォーマンスに影響を与えることが証明されている場合は、実際のコードで具体的な質問をしてください。喜んで改善を試みます。

于 2012-03-29T19:25:49.450 に答える
1

priceでグループ化し、各グループsideの合計を選択する必要があります。quantityメディア (データベース、メモリ内のオブジェクトなど) を指定していないため、特定の実装を実際に提供することはできません。

編集:明らかにこれらはメモリ内のオブジェクトです。その場合、LINQはあなたの友達です:

var results = orders.OrderBy(order => new{order.side, order.price})
.Select(group => new{ group.Key.side, group.Key.price, group.Sum(order => order.quantity));
于 2012-03-29T17:43:17.320 に答える
0

実行できるクエリの使用

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

ここで、:your_price と :your_side は変更された注文の値です。
すべてのテーブルをクリアして最初から埋めることができればより良いです:

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

最初の例では、注文の数量のみが変更可能であると仮定しました。ただし、他の値を変更できる場合は機能しません。
2 番目の例はコストがかかるため、注文が頻繁に変更されない場合にのみ使用してください。
最後に: 注文が頻繁に変化し、すべての値が変わる可能性がある場合:

  1. OrderBook を更新して、変更する必要がある注文から値を削除します (したがって、更新する前に)
  2. OrderBook を更新して、変更された注文の値を追加します。
于 2012-03-29T17:42:58.373 に答える