Skip to content

Commit

Permalink
Add order book function with single db call
Browse files Browse the repository at this point in the history
  • Loading branch information
tolyo committed Dec 10, 2023
1 parent ad3394c commit 3531706
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 0 deletions.
1 change: 1 addition & 0 deletions pkg/models/order_book.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package models
type PriceVolume struct {
Price float64
Volume float64
Side OrderSide
}

type OrderBook struct {
Expand Down
27 changes: 27 additions & 0 deletions pkg/services/order_book_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,30 @@ func GetVolumes(instrumentName models.InstrumentName, side models.OrderSide) []m
)
return res
}

func GetOrderBook(instrumentName models.InstrumentName) models.OrderBook {
res := db.QueryList[models.PriceVolume](`
SELECT price, volume, side
FROM price_level
WHERE price > 0
AND instrument_id = (SELECT id FROM instrument WHERE name = $1)
ORDER BY price ASC, side DESC
`, instrumentName)

orderBook := models.OrderBook{}
for _, entry := range res {
switch entry.Side {
case models.Sell:
orderBook.SellSide = append(orderBook.SellSide, models.PriceVolume{Price: entry.Price, Volume: entry.Volume})
case models.Buy:
orderBook.BuySide = append(orderBook.BuySide, models.PriceVolume{Price: entry.Price, Volume: entry.Volume})
}
}

// reverse array
for i, j := 0, len(orderBook.BuySide)-1; i < j; i, j = i+1, j-1 {
orderBook.BuySide[i], orderBook.BuySide[j] = orderBook.BuySide[j], orderBook.BuySide[i]
}

return orderBook
}
24 changes: 24 additions & 0 deletions pkg/services/order_book_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,27 @@ func (assert *ServiceTestSuite) TestGetVolumeBuySide() {
}, GetVolumes("BTC_EUR", models.Buy))

}

func (assert *ServiceTestSuite) TestGetOrderBook() {

res := GetOrderBook("BTC_EUR")
assert.Len(res.BuySide, 0)
assert.Len(res.BuySide, 0)

// when
ProcessTradeOrder(assert.tradingAccount1, "BTC_EUR", "LIMIT", models.Buy, 1.7, 10, "GTC")
ProcessTradeOrder(assert.tradingAccount1, "BTC_EUR", "LIMIT", models.Buy, 1.6, 10, "GTC")
ProcessTradeOrder(assert.tradingAccount1, "BTC_EUR", "LIMIT", models.Buy, 1.7, 10, "GTC")
ProcessTradeOrder(assert.tradingAccount1, "BTC_EUR", "LIMIT", models.Buy, 1.4, 10, "GTC")

// then should be sorted with most expensive orders first
assert.Equal(models.OrderBook{
BuySide: []models.PriceVolume{
{Price: 1.7, Volume: 20},
{Price: 1.6, Volume: 10},
{Price: 1.4, Volume: 10},
},
SellSide: nil,
}, GetOrderBook("BTC_EUR"))

}

0 comments on commit 3531706

Please sign in to comment.