golang高性能限价订单簿撮合引擎插件库orderbook的使用
Golang高性能限价订单簿撮合引擎插件库orderbook的使用
Go orderbook
改进的用Go(Golang)编写的撮合引擎
特性
- 标准的价格-时间优先级
- 支持市价单和限价单
- 支持订单取消
- 高性能(每秒超过30万笔交易)
- 最优内存使用
- JSON序列化和反序列化
- 计算指定数量的市场价格
使用
要开始使用orderbook,你需要创建一个对象:
import (
"fmt"
ob "github.com/muzykantov/orderbook"
)
func main() {
orderBook := ob.NewOrderBook()
fmt.Println(orderBook)
}
然后你可以使用以下主要功能:
func (ob *OrderBook) ProcessLimitOrder(side Side, orderID string, quantity, price decimal.Decimal) (done []*Order, partial *Order, err error) { ... }
func (ob *OrderBook) ProcessMarketOrder(side Side, quantity decimal.Decimal) (done []*Order, partial *Order, quantityLeft decimal.Decimal, err error) { .. }
func (ob *OrderBook) CancelOrder(orderID string) *Order { ... }
关于主要功能
ProcessLimitOrder
// ProcessLimitOrder 将新订单放入订单簿
// 参数:
// side - 你想做什么(ob.Sell 或 ob.Buy)
// orderID - 深度中的唯一订单ID
// quantity - 你想卖出或买入的数量
// price - 不超过这个价格(或不低于这个价格)
// * 要创建新的十进制数,你应该使用decimal.New()函数
// 返回:
// error - 如果数量(或价格)小于或等于0,则不为nil。或者如果给定ID的订单已存在
// done - 如果你的订单完成了另一个订单,这个订单将被添加到"done"切片中。如果你的订单也完成了,它也会被放到这个数组中
// partial - 如果你的订单已完成但顶部订单未完全完成,则不为nil。或者如果你的订单部分完成并放入订单簿而没有全部数量 - partial将包含你的订单与剩余数量
// partialQuantityProcessed - 如果partial订单不为nil,这个结果包含从partial订单处理的量
func (ob *OrderBook) ProcessLimitOrder(side Side, orderID string, quantity, price decimal.Decimal) (done []*Order, partial *Order, err error) { ... }
例如:
ProcessLimitOrder(ob.Sell, "uinqueID", decimal.New(55, 0), decimal.New(100, 0))
asks: 110 -> 5 110 -> 5
100 -> 1 100 -> 56
-------------- -> --------------
bids: 90 -> 5 90 -> 5
80 -> 1 80 -> 1
done - nil
partial - nil
ProcessMarketOrder
// ProcessMarketOrder 立即以市场价格从订单簿中获取指定数量
// 参数:
// side - 你想做什么(ob.Sell 或 ob.Buy)
// quantity - 你想卖出或买入的数量
// * 要创建新的十进制数,你应该使用decimal.New()函数
// 返回:
// error - 如果价格小于或等于0,则不为nil
// done - 如果你的市价单完成了其他订单,这个订单将被添加到"done"切片中
// partial - 如果你的订单已完成但顶部订单未完全完成,则不为nil
// partialQuantityProcessed - 如果partial订单不为nil,这个结果包含从partial订单处理的量
// quantityLeft - 如果没有足够的订单来处理所有数量,则大于零
func (ob *OrderBook) ProcessMarketOrder(side Side, quantity decimal.Decimal) (done []*Order, partial *Order, quantityLeft decimal.Decimal, err error) { .. }
例如:
ProcessMarketOrder(ob.Sell, decimal.New(6, 0))
asks: 110 -> 5 110 -> 5
100 -> 1 100 -> 1
-------------- -> --------------
bids: 90 -> 5 80 -> 1
80 -> 2
done - 2 (or more orders)
partial - 1 order with price 80
quantityLeft - 0
CancelOrder
// CancelOrder 从订单簿中移除给定ID的订单
func (ob *OrderBook) CancelOrder(orderID string) *Order { ... }
例如:
CancelOrder("myUinqueID-Sell-1-with-100")
asks: 110 -> 5
100 -> 1 110 -> 5
-------------- -> --------------
bids: 90 -> 5 90 -> 5
80 -> 1 80 -> 1
done - 2 (or more orders)
partial - nil
quantityLeft - 4
完整示例
package main
import (
"fmt"
ob "github.com/muzykantov/orderbook"
"github.com/shopspring/decimal"
)
func main() {
// 创建新的订单簿
orderBook := ob.NewOrderBook()
// 添加限价买单
done, partial, err := orderBook.ProcessLimitOrder(
ob.Buy,
"buy-order-1",
decimal.New(10, 0), // 数量 10
decimal.New(100, 0), // 价格 100
)
if err != nil {
fmt.Println("Error placing buy order:", err)
return
}
fmt.Printf("Buy order placed. Done: %v, Partial: %v\n", done, partial)
// 添加限价卖单
done, partial, err = orderBook.ProcessLimitOrder(
ob.Sell,
"sell-order-1",
decimal.New(5, 0), // 数量 5
decimal.New(105, 0), // 价格 105
)
if err != nil {
fmt.Println("Error placing sell order:", err)
return
}
fmt.Printf("Sell order placed. Done: %v, Partial: %v\n", done, partial)
// 执行市价买单
done, partial, left, err := orderBook.ProcessMarketOrder(
ob.Buy,
decimal.New(7, 0), // 数量 7
)
if err != nil {
fmt.Println("Error processing market order:", err)
return
}
fmt.Printf("Market buy order processed. Done: %v, Partial: %v, Left: %v\n", done, partial, left)
// 取消订单
cancelled := orderBook.CancelOrder("sell-order-1")
fmt.Printf("Cancelled order: %v\n", cancelled)
}
许可证
MIT许可证
更多关于golang高性能限价订单簿撮合引擎插件库orderbook的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang高性能限价订单簿撮合引擎插件库orderbook的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang高性能限价订单簿撮合引擎插件库orderbook使用指南
概述
orderbook是一个用于构建高性能交易撮合引擎的Golang库,它实现了限价订单簿(Order Book)的核心功能,包括订单匹配、深度行情生成等。下面我将详细介绍如何使用这个库。
安装
go get github.com/i25959341/orderbook
基本使用
1. 创建订单簿
package main
import (
"fmt"
"github.com/i25959341/orderbook"
)
func main() {
// 创建一个新的订单簿
ob := orderbook.NewOrderBook()
// 设置订单簿ID (可选)
ob.SetID("BTC_USDT")
}
2. 添加订单
// 添加买单
bidOrder := orderbook.NewOrder(
"order1", // 订单ID
orderbook.Bid, // 方向 (Bid=买单, Ask=卖单)
10000.0, // 价格
1.0, // 数量
time.Now(), // 时间戳
)
// 添加卖单
askOrder := orderbook.NewOrder(
"order2",
orderbook.Ask,
10050.0,
2.0,
time.Now(),
)
// 将订单添加到订单簿
ob.Process(bidOrder)
ob.Process(askOrder)
3. 撮合订单
// 创建一个市价单尝试撮合
marketOrder := orderbook.NewOrder(
"order3",
orderbook.Ask, // 假设这是一个市价卖单
0, // 市价单价格为0
0.5, // 数量
time.Now(),
)
// 处理订单并返回撮合结果
trades := ob.Process(marketOrder)
// 打印撮合结果
for _, trade := range trades {
fmt.Printf("撮合成功: %s 成交价 %.2f 数量 %.4f\n",
trade.TakerOrderID, trade.Price, trade.Amount)
}
高级功能
1. 获取市场深度
// 获取前5档买盘深度
bids := ob.GetBids(5)
for _, level := range bids {
fmt.Printf("买盘: 价格 %.2f 总量 %.4f\n", level.Price, level.Amount)
}
// 获取前5档卖盘深度
asks := ob.GetAsks(5)
for _, level := range asks {
fmt.Printf("卖盘: 价格 %.2f 总量 %.4f\n", level.Price, level.Amount)
}
2. 取消订单
// 取消订单
cancelOrder := orderbook.NewOrder(
"order1", // 要取消的订单ID
orderbook.Bid, // 必须与原始订单方向一致
10000.0, // 必须与原始订单价格一致
0, // 数量设为0表示取消
time.Now(),
)
ob.Process(cancelOrder)
3. 批量处理订单
// 创建批量订单
orders := []*orderbook.Order{
orderbook.NewOrder("order4", orderbook.Bid, 9990.0, 0.3, time.Now()),
orderbook.NewOrder("order5", orderbook.Ask, 10010.0, 0.4, time.Now()),
orderbook.NewOrder("order6", orderbook.Bid, 9995.0, 0.5, time.Now()),
}
// 批量处理
for _, order := range orders {
trades := ob.Process(order)
// 处理撮合结果...
}
性能优化技巧
- 对象复用:在高频场景下,可以复用Order对象减少GC压力
var orderPool = sync.Pool{
New: func() interface{} {
return &orderbook.Order{}
},
}
// 获取订单对象
order := orderPool.Get().(*orderbook.Order)
order.ID = "order7"
order.Side = orderbook.Bid
order.Price = 10000.0
order.Amount = 1.0
order.Time = time.Now()
// 使用后放回池中
orderPool.Put(order)
-
批量处理:尽可能批量处理订单减少锁竞争
-
避免频繁打印:在生产环境减少日志输出
注意事项
- 订单ID必须唯一
- 市价单的价格应设为0
- 取消订单时数量和方向必须与原始订单一致
- 时间戳用于确定订单优先级(价格相同时)
完整示例
package main
import (
"fmt"
"time"
"github.com/i25959341/orderbook"
)
func main() {
// 1. 创建订单簿
ob := orderbook.NewOrderBook()
ob.SetID("BTC_USDT")
// 2. 添加初始订单
ob.Process(orderbook.NewOrder("bid1", orderbook.Bid, 10000.0, 1.0, time.Now()))
ob.Process(orderbook.NewOrder("ask1", orderbook.Ask, 10050.0, 2.0, time.Now()))
// 3. 获取市场深度
fmt.Println("初始市场深度:")
printDepth(ob, 3)
// 4. 撮合新订单
fmt.Println("\n处理新订单...")
trades := ob.Process(orderbook.NewOrder("bid2", orderbook.Bid, 10050.0, 1.5, time.Now()))
// 5. 打印撮合结果
for _, trade := range trades {
fmt.Printf("撮合: %s ↔ %s @ %.2f x %.4f\n",
trade.MakerOrderID, trade.TakerOrderID, trade.Price, trade.Amount)
}
// 6. 更新后的市场深度
fmt.Println("\n更新后市场深度:")
printDepth(ob, 3)
}
func printDepth(ob *orderbook.OrderBook, depth int) {
fmt.Println("买盘:")
for _, bid := range ob.GetBids(depth) {
fmt.Printf(" %.2f\t%.4f\n", bid.Price, bid.Amount)
}
fmt.Println("卖盘:")
for _, ask := range ob.GetAsks(depth) {
fmt.Printf(" %.2f\t%.4f\n", ask.Price, ask.Amount)
}
}
这个库非常适合构建加密货币交易所、股票交易系统等需要高性能订单撮合的场景。通过合理使用可以轻松处理每秒数万笔订单的撮合需求。