99 lines
No EOL
4.1 KiB
Text
99 lines
No EOL
4.1 KiB
Text
import "./decodeOrder.code"
|
||
import "./limitLessThanPrice.code"
|
||
|
||
def tupleForTokensWithValue(field value) -> (field[3]):
|
||
return [value, value, value]
|
||
|
||
def tupleForTokenPairsWithValue(field value) -> (field[9]):
|
||
return [value, value, value, value, value, value, value, value, value]
|
||
|
||
def findPairInTokenPairList(field[9] pairs, field sourceToken, field targetToken) -> (field):
|
||
return pairs[sourceToken * 3 + targetToken]
|
||
|
||
// add `volume` to element `token` in `volumeToken`
|
||
def addVolumesForOrder(field[3] volumeToken, field token, field volume) -> (field[3]):
|
||
for field i in 0..3 do
|
||
volumeToken[i] = volumeToken[i] + if token == i then volume else 0 fi
|
||
endfor
|
||
return volumeToken
|
||
|
||
def updateHighestTouchedOrder(field[9] highestTouchedOrder, field sourceToken, field targetToken, field limit, field volume) -> (field[9]):
|
||
|
||
field highest = findPairInTokenPairList(highestTouchedOrder, sourceToken, targetToken)
|
||
|
||
field shouldUpdate = if 0 < volume then 1 else 0 fi
|
||
shouldUpdate = if highest < limit then shouldUpdate else 0 fi
|
||
|
||
highestTouchedOrder[sourceToken * 3 + targetToken] = if shouldUpdate == 1 then limit else highestTouchedOrder[sourceToken * 3 + targetToken] fi
|
||
|
||
return highestTouchedOrder
|
||
|
||
def verifyCompletelyFulfilledIfLimitLowerHighestTouchedOrder(field[9] highestTouchedOrder, field sourceAmount, field sourceToken, field targetToken, field limit, field volume) -> (field):
|
||
|
||
field highest = findPairInTokenPairList(highestTouchedOrder, sourceToken, targetToken)
|
||
|
||
field valid = if limit < highest then 1 - (sourceAmount - volume) else 1 fi
|
||
return valid
|
||
|
||
def checkConstraints(field[3] amount, field[3] sourceToken, field[3] targetToken, field[3] limit, field[3] volume, field[3] priceToken) -> (field):
|
||
// volumes are not larger than in original offer
|
||
for field i in 0..3 do
|
||
1 == if amount[i] < volume[i] then 0 else 1 fi
|
||
endfor
|
||
|
||
field[3] sourceTokenPriceOrder = [0, 0, 0]
|
||
field[3] targetTokenPriceOrder = [0, 0, 0]
|
||
|
||
for field i in 0..3 do
|
||
sourceTokenPriceOrder[i] = priceToken[sourceToken[i]]
|
||
targetTokenPriceOrder[i] = priceToken[targetToken[i]]
|
||
endfor
|
||
|
||
// orders are only touched, if the limit price is below the calculated price:
|
||
for field i in 0..3 do
|
||
1 == if volume[i] == 0 then 1 else limitLessThanPrice(sourceTokenPriceOrder[i], targetTokenPriceOrder[i], limit[i]) fi
|
||
endfor
|
||
|
||
// the amount of sell volume for a token equals its buy volume:
|
||
buyVolumeToken = tupleForTokensWithValue(0)
|
||
sellVolumeToken = tupleForTokensWithValue(0)
|
||
|
||
for field i in 0..3 do
|
||
buyVolumeToken = addVolumesForOrder(buyVolumeToken, targetToken[i], volume[i] * sourceTokenPriceOrder[i])
|
||
sellVolumeToken = addVolumesForOrder(sellVolumeToken, sourceToken[i], volume[i] * sourceTokenPriceOrder[i])
|
||
endfor
|
||
|
||
buyVolumeToken == sellVolumeToken
|
||
|
||
// If an order σ ∈ Oi→j with a limit price p has a positive trading volume, then every order in Oi→j with a lower limit price should be completely fulfilled.
|
||
highestTouchedOrder = tupleForTokenPairsWithValue(0)
|
||
|
||
for field i in 0..3 do
|
||
highestTouchedOrder = updateHighestTouchedOrder(highestTouchedOrder, sourceToken[i], targetToken[i], limit[i], volume[i])
|
||
endfor
|
||
|
||
for field i in 0..3 do
|
||
1 == verifyCompletelyFulfilledIfLimitLowerHighestTouchedOrder(highestTouchedOrder, amount[i], sourceToken[i], targetToken[i], limit[i], volume[i])
|
||
endfor
|
||
|
||
return 1 // Could return total volume to maximize for
|
||
|
||
def main(private field[3] encodedOrder, private field[3] bitmapOrder, private field[3] volume, private field[3] priceToken) -> (field):
|
||
// Remove orders that are not double signed
|
||
encodedOrder = [if bitmapOrder[0] == 1 then encodedOrder[0] else 0 fi, if bitmapOrder[1] == 1 then encodedOrder[1] else 0 fi, if bitmapOrder[2] == 1 then encodedOrder[2] else 0 fi]
|
||
|
||
field[3] amount = [0, 0, 0]
|
||
field[3] sourceToken = [0, 0, 0]
|
||
field[3] targetToken = [0, 0, 0]
|
||
field[3] limit = [0, 0, 0]
|
||
|
||
// Decode orders
|
||
for field i in 0..3 do
|
||
a, s, t, l = decodeOrder(encodedOrder[i])
|
||
amount[i] = a
|
||
sourceToken[i] = s
|
||
targetToken[i] = t
|
||
limit[i] = l
|
||
endfor
|
||
|
||
return checkConstraints(amount, sourceToken, targetToken, limit, volume, priceToken) |