-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

您需要按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 回答
1

当然我可以使用字典,但这可能太慢了

任何解决方案都将涉及树或哈希表。因此,您最好使用您的语言的标准字典实现。

现在,不要猜测任何关于性能的事情,尤其是在实现一些可行的东西之前。然后进行分析,如果您使用的特定字典实现被证明会影响性能,那么使用实际代码提出一个特定问题,我们将很乐意尝试和改进。

于 2012-03-29T19:25:49.450 回答
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

在我的第一个示例中,我假设您的订单中只有数量可以更改;但如果其他值可以改变,它就无法工作。
第二个例子很昂贵,所以只有在您的订单不经常更改时才使用它。
最后:如果您的订单经常变化并且每个值都可以更改,您可以:

  1. 更新 OrderBook 从订单中删除应该修改的值(所以在更新之前)
  2. 更新 OrderBook,从已更改的订单中添加值。
于 2012-03-29T17:42:58.373 回答