9 个版本 (破坏性更新)
0.7.0 | 2020 年 10 月 26 日 |
---|---|
0.6.1 | 2020 年 10 月 22 日 |
0.5.0 | 2020 年 10 月 10 日 |
0.4.0 | 2020 年 10 月 10 日 |
0.1.0 | 2020 年 9 月 20 日 |
#822 在 数据结构
每月 41 次下载
315KB
2.5K SLoC
包含 (ELF 可执行文件/库, 6KB) quantcup/engine.o
快速入门
要使用 Lobster,创建一个具有默认参数的订单簿实例,并发送订单进行执行
use lobster::{FillMetadata, OrderBook, OrderEvent, OrderType, Side};
let mut ob = OrderBook::default();
let event = ob.execute(OrderType::Market { id: 0, qty: 1, side: Side::Bid });
assert_eq!(event, OrderEvent::Unfilled { id: 0 });
let event = ob.execute(OrderType::Limit { id: 1, price: 120, qty: 3, side: Side::Ask });
assert_eq!(event, OrderEvent::Placed { id: 1 });
let event = ob.execute(OrderType::Market { id: 2, qty: 4, side: Side::Bid });
assert_eq!(
event,
OrderEvent::PartiallyFilled {
id: 2,
filled_qty: 3,
fills: vec![
FillMetadata {
order_1: 2,
order_2: 1,
qty: 3,
price: 120,
taker_side: Side::Bid,
total_fill: true,
}
],
},
);
Lobster 仅处理整数价格点和数量。价格和数量表示为无符号 64 位整数。如果交易工具支持分数价格和数量,则转换需要由用户处理。目前,Lobster 不支持负价格。
更多信息可以在 文档 中找到。
Quantcup
目前获胜的 quantcup 提交比 Lobster 快 10-11 倍。虽然 Lobster 可以显著改进,但一些设计选择不可避免地使其变慢。以下是非详尽的列表
-
Quantcup 解决方案将所有可能的价格点存储在内存中,而 Lobster 使用两个 BTreeMap 结构,按需存储价格点。在栈上使用连续数据结构存储所有价格点的性能提升巨大,但这并不太实用:数组通过价格索引,因此可以非常大(想象一下为外汇市场实现一个具有所有非分数价格点的订单簿);实际上,可以在任何价格下进行限价订单,在大多数市场中没有上限,因此静态数组解决方案不可行。
-
Quantcup 解决方案在取消订单时不会更新最大出价/最小要价值。因此,如果取消了对最佳出价/要价的订单,该解决方案将是不正确的。公平地说,这是一个非常容易修复的问题,但在基准测试中获胜的解决方案中没有这样做。
-
Quantcup 解决方案不接受外部订单 ID;相反,它提供静态数组中的整数索引作为它们。这具有明显的实际后果:订单簿可以处理的最大开放订单数量是在编译时选择的。此外,如果发送者在执行订单之前不知道订单 ID,则很难向正确的发送者广播事件。Lobster 支持无符号 128 位整数作为订单 ID,因此可以包含 v4 UUID。
待办事项
- 删除
OrderBook::update_min_ask
和OrderBook::update_max_bid
,仅在需要时更新最小卖价/最大买价值。目前这些方法在每次订单执行时都会被调用。 - 尝试用来自
qp_trie
的 Trie 替换BTreeMap
。