Skip to content

Commit

Permalink
Merge pull request #584 from binance-chain/hotfix/allocate_residual
Browse files Browse the repository at this point in the history
[R4R] fixes for match engine
  • Loading branch information
rickyyangz authored May 28, 2019
2 parents 91044e2 + dcddd0e commit 3705968
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 47 deletions.
80 changes: 40 additions & 40 deletions plugins/dex/matcheng/match.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,56 +211,56 @@ func getTradePrice(overlapped *[]OverLappedLevel, maxExec *LevelIndex,
// It would try best to evenly allocate toAlloc among orders in proportion of order qty meanwhile by whole lot
// Due to lotsize change, it is possible the order would not be allocated with a full lot.
func allocateResidual(toAlloc *int64, orders []OrderPart, lotSize int64) bool {
if len(orders) == 1 {
n := len(orders)
if n == 1 {
qty := utils.MinInt(*toAlloc, orders[0].nxtTrade)
orders[0].nxtTrade = qty
*toAlloc -= qty
return true
}

t := sumOrdersTotalLeft(orders, false)
residual := *toAlloc

if compareBuy(t, residual) > 0 { // not enough to allocate
// It is assumed here toAlloc is lot size rounded, so that the below code
// should leave nothing not allocated
nLot := residual / lotSize
k := len(orders)
i := 0
for i = 0; i < k; i++ {
a := calcNumOfLot(nLot, orders[i].nxtTrade, t) * lotSize // this is supposed to be the main portion
if compareBuy(a, residual) >= 0 {
orders[i].nxtTrade = residual
residual = 0
break
} else {
orders[i].nxtTrade = a
residual -= a
}
}
for j := i % k; j < k; j++ {
if residual > lotSize { // remainder distribution, every one can only get 1 lot or zero
orders[j].nxtTrade += lotSize
residual -= lotSize
if j == k-1 { //restart from the beginning
i = 0
}
} else { // residual may has odd lot remainder
orders[j].nxtTrade += residual
residual = 0
break
}
}
*toAlloc = residual
//assert *toAlloc == 0
if compareBuy(*toAlloc, 0) != 0 {
return false
}
return true
} else { // t <= *toAlloc
if compareBuy(*toAlloc, t) >= 0 {
// no need to change order.nxtTrade
*toAlloc -= t
return true
}

// lot size should never be negative, this is only for some test case use.
if lotSize <= 0 {
return false
}

residual := *toAlloc
// It is assumed here toAlloc is lot size rounded, so that the below code
// should leave nothing not allocated
nLot := residual / lotSize
for i := range orders {
nxtTrade := lotSize * calcNumOfLot(nLot, orders[i].nxtTrade, t)
// here we already have (here all `residual` refer to the original residual):
// 1. residual < totalQty
// 2. n >= 2, i.e: order.nxtTrade < totalQty
// so we can easily prove:
// 1. nxtTrade < residual
// 2. sum(nxtTrade) <= residual
// 3. nxtTrade < order.nxtTrade
orders[i].nxtTrade = nxtTrade
residual -= nxtTrade
}

for i := 0; residual > 0; i = (i + 1) % n {
order := &orders[i]
toAdd := utils.MinInt(order.LeavesQty()-order.nxtTrade, utils.MinInt(residual, lotSize))
residual -= toAdd
order.nxtTrade += toAdd
}

*toAlloc = residual
//assert *toAlloc == 0
if compareBuy(*toAlloc, 0) != 0 {
return false
}
return true
}

// totalLot * orderLeft / totalLeft, orderLeft <= totalLeft
Expand Down
14 changes: 7 additions & 7 deletions plugins/dex/matcheng/match_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -618,16 +618,16 @@ func Test_allocateResidual(t *testing.T) {
assert.Equal(int64(0), toAlloc)

orders = []OrderPart{
OrderPart{"1", 100, 900, 0, 900},
OrderPart{"2", 100, 900, 0, 900},
OrderPart{"3", 100, 900, 0, 900},
OrderPart{"1", 100, 1, 0, 1},
OrderPart{"2", 100, 10, 0, 10},
OrderPart{"3", 100, 6, 0, 6},
}
toAlloc = 700
toAlloc = 15
assert.True(allocateResidual(&toAlloc, orders, 5))
assert.Equal(int64(235), orders[0].nxtTrade)
assert.Equal(int64(235), orders[1].nxtTrade)
assert.Equal(int64(1), orders[0].nxtTrade)
assert.Equal(int64(9), orders[1].nxtTrade)
assert.Equal("2", orders[1].Id)
assert.Equal(int64(230), orders[2].nxtTrade)
assert.Equal(int64(5), orders[2].nxtTrade)
assert.Equal("3", orders[2].Id)
assert.Equal(int64(0), toAlloc)
}
Expand Down

0 comments on commit 3705968

Please sign in to comment.