Skip to content

Commit

Permalink
Orderbook fixes/optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
ruixhuang committed Aug 31, 2024
1 parent 8e4d1d7 commit b3aefd0
Show file tree
Hide file tree
Showing 11 changed files with 635 additions and 148 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,42 @@ internal class OrderbookCalculator(

buildGroupingLookup(tickSize)
val groupingTickSize = getGroupingTickSizeDecimals(tickSize, groupingMultiplier)
val asks = createGroup(rawOrderbook.asks, groupingTickSize)
val bids = createGroup(rawOrderbook.bids, groupingTickSize)
val asks = if (groupingMultiplier != 1) {
createGroup(rawOrderbook.asks, groupingTickSize)
} else {
var asksDepth = 0.0
var depthSizeCost = 0.0
rawOrderbook.asks?.map {
asksDepth += it.size
val sizeCost = it.size * it.price
depthSizeCost += sizeCost
OrderbookLine(
size = it.size,
price = it.price,
depth = asksDepth,
sizeCost = sizeCost,
depthCost = depthSizeCost,
)
}
}
val bids = if (groupingMultiplier != 1) {
createGroup(rawOrderbook.bids, groupingTickSize)
} else {
var bidsDepth = 0.0
var depthSizeCost = 0.0
rawOrderbook.bids?.map {
bidsDepth += it.size
val sizeCost = it.size * it.price
depthSizeCost += sizeCost
OrderbookLine(
size = it.size,
price = it.price,
depth = bidsDepth,
sizeCost = sizeCost,
depthCost = depthSizeCost,
)
}
}

val firstAskPrice = asks?.firstOrNull()?.price
val firstBidPrice = bids?.firstOrNull()?.price
Expand Down Expand Up @@ -131,7 +165,7 @@ internal class OrderbookCalculator(
val result = mutableListOf<OrderbookLine>()

// properties of the current group
var curFloored = Rounder.round(firstPrice, grouping);
var curFloored = Rounder.quickRound2(firstPrice, grouping);
var groupMin = if (curFloored != firstPrice) curFloored else (if (shouldFloor) curFloored else curFloored - grouping)
var groupMax = groupMin + grouping
var size = Numeric.double.ZERO
Expand Down Expand Up @@ -161,7 +195,7 @@ internal class OrderbookCalculator(
depthCost = depthCost,
),
)
curFloored = Rounder.round(linePrice, grouping);
curFloored = Rounder.quickRound2(linePrice, grouping);
groupMin = if (curFloored != linePrice) curFloored else (if (shouldFloor) curFloored else curFloored - grouping)
groupMax = groupMin + grouping

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ internal class OrderbookProcessor(
rawOrderbook = existing.rawOrderbook,
)
existing.groupedOrderbook = calculator.calculate(
rawOrderbook = existing.rawOrderbook,
rawOrderbook = existing.consolidatedOrderbook,
tickSize = tickSize ?: defaultTickSize,
groupingMultiplier = groupingMultiplier,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal fun TradingStateMachine.receivedMarkets(
val marketsPayload = parser.asTypedStringMap<IndexerCompositeMarketObject>(markets)
marketsProcessor.processSubscribed(internalState.marketsSummary, marketsPayload)
}
// TODO remove deprecated

marketsSummary = marketsProcessor.subscribedDeprecated(marketsSummary, payload)
marketsSummary = marketsCalculator.calculate(parser.asMap(marketsSummary), assets, null)
val subaccountNumbers = MarginCalculator.getChangedSubaccountNumbersDeprecated(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,11 @@ internal fun TradingStateMachine.receivedOrderbook(
tickSize = market?.perpetualMarket?.configs?.tickSize,
content = orderbookPayload,
)
} else {
this.marketsSummary =
marketsProcessor.receivedOrderbookDeprecated(marketsSummary, marketId, payload)
}

// TODO: Remove after TradeCalculator is converted to static typing
this.marketsSummary =
marketsProcessor.receivedOrderbookDeprecated(marketsSummary, marketId, payload)

return StateChanges(
iListOf(Changes.orderbook, Changes.input),
iListOf(marketId),
Expand Down Expand Up @@ -69,13 +68,14 @@ internal fun TradingStateMachine.receivedBatchOrderbookChanges(
marketId = marketId,
content = orderbookUpdatePayload,
)
} else {
this.marketsSummary = marketsProcessor.receivedBatchOrderbookChangesDeprecated(
marketsSummary,
marketId,
payload,
)
}
// TODO: Remove after TradeCalculator is converted to static typing
this.marketsSummary = marketsProcessor.receivedBatchOrderbookChangesDeprecated(
marketsSummary,
marketId,
payload,
)

return StateChanges(
iListOf(Changes.orderbook, Changes.input),
iListOf(marketId),
Expand All @@ -96,12 +96,12 @@ internal fun TradingStateMachine.setOrderbookGrouping(
marketId = marketId,
groupingMultiplier = groupingMultiplier,
)
} else {
this.groupingMultiplier = groupingMultiplier
this.marketsSummary =
marketsProcessor.groupOrderbookDeprecated(marketsSummary, marketId)
}

// TODO: Remove after TradeCalculator is converted to static typing
this.groupingMultiplier = groupingMultiplier
this.marketsSummary = marketsProcessor.groupOrderbookDeprecated(marketsSummary, marketId)

val changes =
StateChanges(
iListOf(Changes.orderbook),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@ internal fun TradingStateMachine.onChainRewardsParams(payload: String): StateCha
if (staticTyping) {
val rewardParamsObject = parser.asTypedObject<OnChainRewardsParamsResponse>(payload)
internalState.rewardsParams = rewardsProcessor.process(rewardParamsObject)
} else {
val json = parser.decodeJsonObject(payload)
val params = parser.asMap(json?.get("params"))
rewardsParams =
if (params != null) {
rewardsProcessor.received(parser.asMap(rewardsParams), params)
} else {
null
}
}
val json = parser.decodeJsonObject(payload)
val params = parser.asMap(json?.get("params"))
rewardsParams =
if (params != null) {
rewardsProcessor.received(parser.asMap(rewardsParams), params)
} else {
null
}
return StateChanges(iListOf())
}

Expand All @@ -33,23 +34,24 @@ internal fun TradingStateMachine.onChainRewardTokenPrice(payload: String): State
eixsting = internalState.rewardsParams,
payload = tokenPriceResponse,
)
}
val json = try {
Json.parseToJsonElement(payload).jsonObject.toMap()
} catch (exception: SerializationException) {
Logger.e {
"Failed to deserialize onChainRewardTokenPrice: $payload \n" +
"Exception: $exception"
}
null
}
val map = parser.asMap(json)
val price = parser.asMap(map?.get("marketPrice"))
rewardsParams =
if (price != null) {
rewardsProcessor.receivedTokenPrice(parser.asMap(rewardsParams), price)
} else {
} else {
val json = try {
Json.parseToJsonElement(payload).jsonObject.toMap()
} catch (exception: SerializationException) {
Logger.e {
"Failed to deserialize onChainRewardTokenPrice: $payload \n" +
"Exception: $exception"
}
null
}
val map = parser.asMap(json)
val price = parser.asMap(map?.get("marketPrice"))
rewardsParams =
if (price != null) {
rewardsProcessor.receivedTokenPrice(parser.asMap(rewardsParams), price)
} else {
null
}
}
return StateChanges(iListOf())
}
15 changes: 15 additions & 0 deletions src/commonMain/kotlin/exchange.dydx.abacus/utils/Rounder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,21 @@ class Rounder {
}
}

fun quickRound2(number: Double, stepSize: Double, roundingMode: RoundingMode = RoundingMode.TOWARDS_ZERO): Double {
if (stepSize > 0) {
val factor = stepSize
when (roundingMode) {
RoundingMode.TOWARDS_ZERO -> {
val sign = if (number < 0) -1 else 1
return kotlin.math.floor(number.abs() / factor) * factor * sign
}
RoundingMode.NEAREST -> return kotlin.math.round(number / factor) * factor
}
} else {
return number
}
}

fun round(number: Double, stepSize: Double, roundingMode: RoundingMode = RoundingMode.TOWARDS_ZERO): Double {
val roundedDecimal = roundDecimal(
number.toBigDecimal(null, Numeric.decimal.mode),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,17 @@ import kotlin.test.assertTrue
class V3MarketsDelayedTests : V3BaseTests() {
@Test
fun testOrderbookFirst() {
test(
{
loadOrderbook()
},
"""
if (perp.staticTyping) {
loadOrderbook()

val market = perp.internalState.marketsSummary.markets.get("ETH-USD")
assertTrue { market?.groupedOrderbook != null }
} else {
test(
{
loadOrderbook()
},
"""
{
"markets": {
"markets": {
Expand All @@ -24,11 +30,12 @@ class V3MarketsDelayedTests : V3BaseTests() {
}
}
}
""".trimIndent(),
{
assertNull(perp.state?.marketsSummary)
},
)
""".trimIndent(),
{
assertNull(perp.state?.marketsSummary)
},
)
}

if (perp.staticTyping) {
perp.loadTrades(mock)
Expand Down Expand Up @@ -58,11 +65,16 @@ class V3MarketsDelayedTests : V3BaseTests() {
)
}

test(
{
loadMarkets()
},
"""
if (perp.staticTyping) {
loadMarkets()
val market = perp.internalState.marketsSummary.markets.get("ETH-USD")
assertTrue { market?.groupedOrderbook != null }
} else {
test(
{
loadMarkets()
},
"""
{
"markets": {
"markets": {
Expand All @@ -73,11 +85,12 @@ class V3MarketsDelayedTests : V3BaseTests() {
}
}
}
""".trimIndent(),
{
assertNotNull(perp.state?.marketsSummary)
},
)
""".trimIndent(),
{
assertNotNull(perp.state?.marketsSummary)
},
)
}
}

@Test
Expand Down
Loading

0 comments on commit b3aefd0

Please sign in to comment.