Algorithm 从orders示例构造orderbook

Algorithm 从orders示例构造orderbook,algorithm,algorithmic-trading,Algorithm,Algorithmic Trading,我正在寻找从订单构造orderbook的代码 例如,如果订单是 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的代码

例如,如果订单是

side | price | quantity
buy   100      1
buy   101      10
buy   100      1000
buy   100      10000
那么,拒绝的订单应为:

side | price | quantity
buy    100     11001
buy    101     10 
在程序生命周期内,添加、修改或删除订单。每次订单更新时,我都需要快速更新订单簿


我相信这是一项非常常见的任务,所以在互联网上应该已经有很多实现了

谢谢你的任何参考资料,我正在寻找c实现,但如果需要,我可以用另一种语言重写它


事实上,我应该重新表述我的问题。最初,订单簿是空的。然后我收到事件:添加订单、更改订单数量或取消订单。我应该根据此邮件重新计算订单。但现在我明白了,这应该是多么简单。当订单增加时,我只是在这个价格水平上增加数量。当订单数量更改时,我只需要添加更改,当订单取消时,我只需要从相应的价格级别删除相应的数量。唯一的问题是我应该在哪里存储最后的订单数量总共有很多订单数千万,但没有很多活动订单不超过100000,对于每个活动订单,我需要通过orderId获取最后的数量。。。我当然会用字典,但那可能太慢了。我想要快一点的。但是我不能使用50000个条目数组。

使用查询可以

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
其中:您的_价格和:您的_方是修改订单的值。 如果您可以清除所有表格并从头开始填充,则效果更佳:

TRUNCATE TABLE OrderBook;
INSERT INTO OrderBook
SELECT side, price, SUM(quantity)
FROM orders
GROUP BY side, price
在我的第一个例子中,我假设在你的订单中只有数量可以改变;但如果其他值可以改变,它就无法工作。 第二个例子很昂贵,所以只有在订单不经常更改的情况下才使用它。 最后:如果您的订单经常变化,并且每个值都可能发生变化,您可以:

更新订单簿从订单中删除应在更新前进行修改的值 更新订单簿,添加已更改订单的值。 您需要按价格和边进行分组,然后选择每组的数量总和。由于您尚未指定任何媒体数据库、内存中的对象等,因此我们无法真正为您提供具体的实现

编辑:显然这些是内存中的对象,在这种情况下,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));

下面是在中测试的代码

LINQPad中的结果是

我当然会用字典,但那可能太慢了

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


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

将其作为基于分组查询的视图更为合理。让DB处理缓存和维护缓存。抱歉,我已更新了说明。我不需要将当前订单转移到订单簿。我需要在应用程序生命周期内,在每次订单更新时都这样做,即使我需要c实现,当然我在内存中也有订单:在Internet上应该已经有很多实现了。我对此表示怀疑。不过,这类东西可能存在商业实现。哦,下次请看,我认为ociweb Liquibook是OrderBook最流行的开源实现,我想你是对的。知道95%的活动订单彼此非常接近,即他们的id在100000间隔内,我可能会尝试使用数组来表示这一部分,并使用字典来表示其余5%的订单,我需要将订单从一个数组移动到另一个字典。但这听起来太复杂了,所以我最好先用字典作为第一枪,如果有必要的话,再分析一下needed@javapowered:俗话说得好,做最简单的事情,而且根据经验,这是任何形式的[算法]交易的黄金法则。@javapowered:此外,这里的表现是相对的。我想你更关心的是连接延迟,而不是像在字典里存储东西这样的便宜东西。金钱能为HFT买到的最好的改进就是托管。我已经配置好了。这是HFT中必须具备的:不幸的是,由于quickfast,我已经失去了150µs,我不想因为我自己的代码而失去更多。+1用于将我指向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...