从订单示例构建订单

时间:2012-03-29 17:38:11

标签: algorithm algorithmic-trading

我正在寻找从订单构建订单的代码

例如,如果订单是

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

然后agregated orderbook应该是:

side | price | quantity
buy    100     11001
buy    101     10 

在计划生命周期内,会添加,修改或删除订单。在每次订单更新时,我需要快速更新OrderBook。

我确定这是非常常见的任务,因此互联网上应该有很多实现。

感谢您的任何推荐,我正在寻找c#实现,但如果需要,我可以用其他语言重写它。

upd 其实我应该重新解释一下我的问题。最初订单是空的。然后我收到事件:添加订单,更改订单数量或取消订单。我应该从这条消息中重新计算orderBook。但现在我很清楚它应该是多么简单。添加订单时,我只需在此价格水平上添加数量。当订单数量发生变化时,我只需要添加"更改"当订单被取消时,我只需要从相应的价格水平中删除相应的数量。唯一的问题是我应该在哪里存储"最后的订单数量"总共有很多订单(数十亿),但是没有很多活动订单(不超过10万),而且我需要获得的每个活动订单都是#34;最后数量" by orderId ...当然我可以使用字典,但这可能太慢了。我想要更快的东西。但我不能使用5亿个数组。

4 个答案:

答案 0 :(得分:2)

以下是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的结果是
orderbook result in LINQPad

答案 1 :(得分:1)

您需要按priceside进行分组,然后为每个组选择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));

答案 2 :(得分: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,从已更改的订单中添加值。

答案 3 :(得分:0)

  

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

任何解决方案都涉及树或哈希表。所以你最好使用你的语言的标准字典实现。

现在,不要猜测任何有关性能的事情,特别是在实现有效的方法之前。然后进行配置文件,如果您使用的特定字典实现被证明会影响性能,那么使用实际代码询问一个特定问题,我们将很乐意尝试和改进。