Skip to content

Commit

Permalink
Merge pull request #50 from crescent-network/cherry-pick/341
Browse files Browse the repository at this point in the history
refactor!: detailed configuration for order book responses #341
  • Loading branch information
crypin authored Jul 27, 2022
2 parents 89a6348 + fc7eaa5 commit 430c148
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 20 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ Ref: https://keepachangelog.com/en/1.0.0/

## [Unreleased]

## v2.1.1

### Improvements

* (x/liquidity) [\#50](https://github.com/crescent-network/crescent/pull/50) Enable detailed configuration for order book responses

## v2.1.0

### Client Breaking Changes
Expand Down
16 changes: 15 additions & 1 deletion x/liquidity/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,21 @@ func (k Querier) OrderBooks(c context.Context, req *types.QueryOrderBooksRequest
ov := ob.MakeView()
ov.Match()

pairs = append(pairs, types.MakeOrderBookPairResponse(pair.Id, ov, lowestPrice, highestPrice, int(tickPrec), int(req.NumTicks)))
pairs = append(
pairs, types.MakeOrderBookPairResponse(
pair.Id, ov, lowestPrice, highestPrice, int(tickPrec),
types.OrderBookConfig{
PriceUnitPower: 0,
MaxNumTicks: int(req.NumTicks),
},
types.OrderBookConfig{
PriceUnitPower: 1,
MaxNumTicks: int(req.NumTicks),
},
types.OrderBookConfig{
PriceUnitPower: 2,
MaxNumTicks: int(req.NumTicks),
}))
}

return &types.QueryOrderBooksResponse{
Expand Down
70 changes: 60 additions & 10 deletions x/liquidity/types/example_orderbook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ func ExampleMakeOrderBookPairResponse() {
tickPrec := 1
lowestPrice := utils.ParseDec("0")
highestPrice := utils.ParseDec("20")
resp := types.MakeOrderBookPairResponse(1, ov, lowestPrice, highestPrice, tickPrec, 20)
resp := types.MakeOrderBookPairResponse(1, ov, lowestPrice, highestPrice, tickPrec, types.OrderBookConfig{
PriceUnitPower: 0,
MaxNumTicks: 20,
})
types.PrintOrderBookResponse(resp.OrderBooks[0], resp.BasePrice)

// Output:
Expand Down Expand Up @@ -62,7 +65,10 @@ func ExampleMakeOrderBookPairResponse_pool() {
ov := ob.MakeView()
ov.Match()
tickPrec := 3
resp := types.MakeOrderBookPairResponse(1, ov, lowestPrice, highestPrice, tickPrec, 10)
resp := types.MakeOrderBookPairResponse(1, ov, lowestPrice, highestPrice, tickPrec, types.OrderBookConfig{
PriceUnitPower: 0,
MaxNumTicks: 10,
})
types.PrintOrderBookResponse(resp.OrderBooks[0], resp.BasePrice)

// Output:
Expand Down Expand Up @@ -113,7 +119,10 @@ func ExampleMakeOrderBookPairResponse_userOrder() {
ov := ob.MakeView()
ov.Match()
tickPrec := 3
resp := types.MakeOrderBookPairResponse(1, ov, lowestPrice, highestPrice, tickPrec, 10)
resp := types.MakeOrderBookPairResponse(1, ov, lowestPrice, highestPrice, tickPrec, types.OrderBookConfig{
PriceUnitPower: 0,
MaxNumTicks: 10,
})
basePrice, found := types.OrderBookBasePrice(ov, tickPrec)
if !found {
panic("base price not found")
Expand Down Expand Up @@ -159,7 +168,10 @@ func ExampleMakeOrderBookPairResponse_match() {
ov := ob.MakeView()
ov.Match()
tickPrec := 3
resp := types.MakeOrderBookPairResponse(1, ov, utils.ParseDec("0.9"), utils.ParseDec("1.1"), tickPrec, 10)
resp := types.MakeOrderBookPairResponse(1, ov, utils.ParseDec("0.9"), utils.ParseDec("1.1"), tickPrec, types.OrderBookConfig{
PriceUnitPower: 0,
MaxNumTicks: 10,
})
basePrice, found := types.OrderBookBasePrice(ov, tickPrec)
if !found {
panic("base price not found")
Expand Down Expand Up @@ -188,7 +200,10 @@ func ExampleMakeOrderBookPairResponse_zigzag() {
ov.Match()

basePrice, _ := types.OrderBookBasePrice(ov, 4)
resp := types.MakeOrderBookPairResponse(1, ov, utils.ParseDec("0.9"), utils.ParseDec("1.1"), 3, 20)
resp := types.MakeOrderBookPairResponse(1, ov, utils.ParseDec("0.9"), utils.ParseDec("1.1"), 3, types.OrderBookConfig{
PriceUnitPower: 0,
MaxNumTicks: 20,
})
types.PrintOrderBookResponse(resp.OrderBooks[0], basePrice)

// Output:
Expand Down Expand Up @@ -217,7 +232,10 @@ func ExampleMakeOrderBookPairResponse_edgecase1() {
ov.Match()

basePrice, _ := types.OrderBookBasePrice(ov, 4)
resp := types.MakeOrderBookPairResponse(1, ov, lowestPrice, highestPrice, 3, 10)
resp := types.MakeOrderBookPairResponse(1, ov, lowestPrice, highestPrice, 3, types.OrderBookConfig{
PriceUnitPower: 0,
MaxNumTicks: 10,
})
types.PrintOrderBookResponse(resp.OrderBooks[0], basePrice)

// Output:
Expand Down Expand Up @@ -260,7 +278,10 @@ func ExampleMakeOrderBookPairResponse_edgecase2() {
ov := ob.MakeView()
ov.Match()

resp := types.MakeOrderBookPairResponse(1, ov, utils.ParseDec("0.9"), utils.ParseDec("1.1"), 3, 10)
resp := types.MakeOrderBookPairResponse(1, ov, utils.ParseDec("0.9"), utils.ParseDec("1.1"), 3, types.OrderBookConfig{
PriceUnitPower: 0,
MaxNumTicks: 10,
})
types.PrintOrderBookResponse(resp.OrderBooks[0], resp.BasePrice)

// Output:
Expand All @@ -283,7 +304,10 @@ func ExampleMakeOrderBookPairResponse_edgecase3() {
ov := ob.MakeView()
ov.Match()

resp := types.MakeOrderBookPairResponse(1, ov, utils.ParseDec("0.9"), utils.ParseDec("1.1"), 3, 10)
resp := types.MakeOrderBookPairResponse(1, ov, utils.ParseDec("0.9"), utils.ParseDec("1.1"), 3, types.OrderBookConfig{
PriceUnitPower: 0,
MaxNumTicks: 10,
})
types.PrintOrderBookResponse(resp.OrderBooks[0], resp.BasePrice)

// Output:
Expand All @@ -307,7 +331,20 @@ func ExampleMakeOrderBookPairResponse_priceUnits1() {
ov := ob.MakeView()
ov.Match()

resp := types.MakeOrderBookPairResponse(1, ov, lowestPrice, highestPrice, 4, 10)
resp := types.MakeOrderBookPairResponse(1, ov, lowestPrice, highestPrice, 4,
types.OrderBookConfig{
PriceUnitPower: 0,
MaxNumTicks: 10,
},
types.OrderBookConfig{
PriceUnitPower: 1,
MaxNumTicks: 10,
},
types.OrderBookConfig{
PriceUnitPower: 2,
MaxNumTicks: 10,
},
)
types.PrintOrderBookResponse(resp.OrderBooks[0], resp.BasePrice)
types.PrintOrderBookResponse(resp.OrderBooks[1], resp.BasePrice)
types.PrintOrderBookResponse(resp.OrderBooks[2], resp.BasePrice)
Expand Down Expand Up @@ -401,7 +438,20 @@ func ExampleMakeOrderBookPairResponse_priceUnits2() {
ov := ob.MakeView()
ov.Match()

resp := types.MakeOrderBookPairResponse(1, ov, lowestPrice, highestPrice, 4, 10)
resp := types.MakeOrderBookPairResponse(1, ov, lowestPrice, highestPrice, 4,
types.OrderBookConfig{
PriceUnitPower: 0,
MaxNumTicks: 10,
},
types.OrderBookConfig{
PriceUnitPower: 1,
MaxNumTicks: 10,
},
types.OrderBookConfig{
PriceUnitPower: 2,
MaxNumTicks: 10,
},
)
types.PrintOrderBookResponse(resp.OrderBooks[0], resp.BasePrice)
types.PrintOrderBookResponse(resp.OrderBooks[1], resp.BasePrice)
types.PrintOrderBookResponse(resp.OrderBooks[2], resp.BasePrice)
Expand Down
26 changes: 19 additions & 7 deletions x/liquidity/types/orderbook.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package types

import (
"fmt"
"sort"

sdk "github.com/cosmos/cosmos-sdk/types"

Expand All @@ -24,7 +25,13 @@ func OrderBookBasePrice(ov amm.OrderView, tickPrec int) (sdk.Dec, bool) {
}
}

func MakeOrderBookPairResponse(pairId uint64, ov *amm.OrderBookView, lowestPrice, highestPrice sdk.Dec, tickPrec, numTicks int) OrderBookPairResponse {
// OrderBookConfig defines configuration parameter for an order book response.
type OrderBookConfig struct {
PriceUnitPower int
MaxNumTicks int
}

func MakeOrderBookPairResponse(pairId uint64, ov *amm.OrderBookView, lowestPrice, highestPrice sdk.Dec, tickPrec int, configs ...OrderBookConfig) OrderBookPairResponse {
resp := OrderBookPairResponse{
PairId: pairId,
}
Expand All @@ -35,19 +42,24 @@ func MakeOrderBookPairResponse(pairId uint64, ov *amm.OrderBookView, lowestPrice
resp.BasePrice = basePrice
ammTickPrec := amm.TickPrecision(tickPrec)

sort.Slice(configs, func(i, j int) bool {
return configs[i].PriceUnitPower < configs[j].PriceUnitPower
})
lowestPriceUnitMaxNumTicks := configs[0].MaxNumTicks

highestBuyPrice, foundHighestBuyPrice := ov.HighestBuyPrice()
lowestSellPrice, foundLowestSellPrice := ov.LowestSellPrice()

var smallestPriceUnit sdk.Dec
if foundLowestSellPrice {
currentPrice := lowestSellPrice
for i := 0; i < numTicks && currentPrice.LTE(highestPrice); {
for i := 0; i < lowestPriceUnitMaxNumTicks && currentPrice.LTE(highestPrice); {
amtInclusive := ov.SellAmountOver(currentPrice, true)
amtExclusive := ov.SellAmountOver(currentPrice, false)
amt := amtInclusive.Sub(amtExclusive)
if amt.IsPositive() {
i++
if i == numTicks {
if i == lowestPriceUnitMaxNumTicks {
break
}
}
Expand All @@ -61,9 +73,9 @@ func MakeOrderBookPairResponse(pairId uint64, ov *amm.OrderBookView, lowestPrice
smallestPriceUnit = ammTickPrec.TickGap(highestBuyPrice)
}

for i := 0; i < 3; i++ {
for _, config := range configs {
priceUnit := smallestPriceUnit
for j := 0; j < i; j++ {
for j := 0; j < config.PriceUnitPower; j++ {
priceUnit = priceUnit.MulInt64(10)
}
ob := OrderBookResponse{
Expand All @@ -75,7 +87,7 @@ func MakeOrderBookPairResponse(pairId uint64, ov *amm.OrderBookView, lowestPrice
startPrice := FitPriceToTickGap(lowestSellPrice, priceUnit, false)
currentPrice := startPrice
accAmt := sdk.ZeroInt()
for j := 0; j < numTicks && currentPrice.LTE(highestPrice); {
for j := 0; j < config.MaxNumTicks && currentPrice.LTE(highestPrice); {
amt := ov.SellAmountUnder(currentPrice, true).Sub(accAmt)
if amt.IsPositive() {
ob.Sells = append(ob.Sells, OrderBookTickResponse{
Expand All @@ -100,7 +112,7 @@ func MakeOrderBookPairResponse(pairId uint64, ov *amm.OrderBookView, lowestPrice
startPrice := FitPriceToTickGap(highestBuyPrice, priceUnit, true)
currentPrice := startPrice
accAmt := sdk.ZeroInt()
for j := 0; j < numTicks && currentPrice.GTE(lowestPrice) && !currentPrice.IsNegative(); {
for j := 0; j < config.MaxNumTicks && currentPrice.GTE(lowestPrice) && !currentPrice.IsNegative(); {
amt := ov.BuyAmountOver(currentPrice, true).Sub(accAmt)
if amt.IsPositive() {
ob.Buys = append(ob.Buys, OrderBookTickResponse{
Expand Down
20 changes: 18 additions & 2 deletions x/liquidity/types/orderbook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ func TestMakeOrderBookResponse(t *testing.T) {
panic("base price not found")
}

resp := types.MakeOrderBookPairResponse(1, ov, lowestPrice, highestPrice, 4, 20)
resp := types.MakeOrderBookPairResponse(1, ov, lowestPrice, highestPrice, 4, types.OrderBookConfig{
PriceUnitPower: 0,
MaxNumTicks: 20,
})
types.PrintOrderBookResponse(resp.OrderBooks[0], basePrice)
}

Expand Down Expand Up @@ -67,5 +70,18 @@ func makeOrderBookPairResponse(numOrders, numPools, numTicks, tickPrec int) type
ov := ob.MakeView()
ov.Match()

return types.MakeOrderBookPairResponse(1, ov, lowestPrice, highestPrice, 4, numTicks)
return types.MakeOrderBookPairResponse(1, ov, lowestPrice, highestPrice, 4,
types.OrderBookConfig{
PriceUnitPower: 0,
MaxNumTicks: numTicks,
},
types.OrderBookConfig{
PriceUnitPower: 1,
MaxNumTicks: numTicks,
},
types.OrderBookConfig{
PriceUnitPower: 2,
MaxNumTicks: numTicks,
},
)
}

0 comments on commit 430c148

Please sign in to comment.