diff --git a/build.gradle.kts b/build.gradle.kts index c41a5ad02..b6727b914 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -51,7 +51,7 @@ allprojects { } group = "exchange.dydx.abacus" -version = "1.7.49" +version = "1.7.50" repositories { google() diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/calculator/TradeInputCalculator.kt b/src/commonMain/kotlin/exchange.dydx.abacus/calculator/TradeInputCalculator.kt index b6c95caf3..723f793ce 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/calculator/TradeInputCalculator.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/calculator/TradeInputCalculator.kt @@ -70,7 +70,12 @@ internal class TradeInputCalculator( val user = parser.asNativeMap(state["user"]) ?: mapOf() val markets = parser.asNativeMap(state["markets"]) val rewardsParams = parser.asNativeMap(state["rewardsParams"]) - val trade = parser.asNativeMap(state["trade"]) + val trade = updateTradeInputFromMarket( + markets, + account, + parser.asNativeMap(state["trade"]), + subaccountNumber ?: 0, + ) val marketId = parser.asString(trade?.get("marketId")) val type = parser.asString(trade?.get("type")) val market = if (marketId != null) parser.asNativeMap(markets?.get(marketId)) else null @@ -135,6 +140,53 @@ internal class TradeInputCalculator( } } + private fun updateTradeInputFromMarket( + markets: Map?, + account: Map?, + tradeInput: Map?, + subaccountNumber: Int, + ): MutableMap? { + val modified = tradeInput?.mutable() ?: return null + val marketId = parser.asString(tradeInput["marketId"]) + val existingMarginMode = + MarginModeCalculator.findExistingMarginMode( + parser, + account, + marketId, + subaccountNumber, + ) + // If there is an existing position or order, we have to use the same margin mode + if (existingMarginMode != null) { + modified["marginMode"] = existingMarginMode + if ( + existingMarginMode == "ISOLATED" && + parser.asDouble(tradeInput["targetLeverage"]) == null + ) { + modified["targetLeverage"] = 1.0 + } + } else { + val marketMarginMode = MarginModeCalculator.findMarketMarginMode( + parser, + parser.asMap(markets?.get(marketId)), + ) + when (marketMarginMode) { + "ISOLATED" -> { + modified["marginMode"] = marketMarginMode + if (parser.asDouble(tradeInput["targetLeverage"]) == null) { + modified["targetLeverage"] = 1.0 + } + } + + "CROSS" -> { + if (modified["marginMode"] == null) { + modified["marginMode"] = marketMarginMode + } + } + } + } + return modified + } + private fun calculateNonMarketTrade( trade: Map, market: Map?, diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine+TradeInput.kt b/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine+TradeInput.kt index 7f8463b3d..897075f06 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine+TradeInput.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/state/model/TradingStateMachine+TradeInput.kt @@ -1,6 +1,5 @@ package exchange.dydx.abacus.state.model -import exchange.dydx.abacus.calculator.MarginModeCalculator import exchange.dydx.abacus.calculator.TradeCalculation import exchange.dydx.abacus.calculator.TradeInputCalculator import exchange.dydx.abacus.responses.ParsingError @@ -65,8 +64,7 @@ internal fun TradingStateMachine.tradeInMarket( return StateResponse(state, StateChanges(iListOf()), null) } else { input["current"] = "trade" - input["trade"] = - updateTradeInputFromMarket(parser.asNativeMap(input["trade"])!!, subaccountNumber) + input["trade"] = parser.asNativeMap(input["trade"]) ?: mutableMapOf() val changes = StateChanges( iListOf(Changes.input), @@ -88,13 +86,12 @@ internal fun TradingStateMachine.tradeInMarket( // If we changed market, we should also reset the price and size modified.safeSet("size", null) modified.safeSet("price", null) - updateTradeInputFromMarket(modified, subaccountNumber) + modified.safeSet("marginMode", null) + modified.safeSet("targetLeverage", null) + modified } else { - updateTradeInputFromMarket( - initiateTrade( - marketId, - subaccountNumber, - ), + initiateTrade( + marketId, subaccountNumber, ) } @@ -115,31 +112,6 @@ internal fun TradingStateMachine.tradeInMarket( } } -internal fun TradingStateMachine.updateTradeInputFromMarket( - trade: Map, - subaccountNumber: Int, -): MutableMap { - val modified = trade.mutable() - val account = this.account - val marketId = parser.asString(trade["marketId"]) - val existingMarginMode = - MarginModeCalculator.findExistingMarginMode( - parser, - account, - marketId, - subaccountNumber, - ) ?: MarginModeCalculator.findMarketMarginMode( - parser, - parser.asMap(parser.value(marketsSummary, "markets.$marketId")), - ) - // If there is an existing position or order, we have to use the same margin mode - modified["marginMode"] = existingMarginMode - if (existingMarginMode == "ISOLATED" && parser.asDouble(trade["targetLeverage"]) == null) { - modified["targetLeverage"] = 1.0 - } - return modified -} - internal fun TradingStateMachine.initiateTrade( marketId: String?, subaccountNumber: Int, @@ -148,7 +120,8 @@ internal fun TradingStateMachine.initiateTrade( trade["type"] = "LIMIT" trade["side"] = "BUY" trade["marketId"] = marketId ?: "ETH-USD" - trade["marginMode"] = "CROSS" + + trade.safeSet("marginMode", null) val calculator = TradeInputCalculator(parser, TradeCalculation.trade, featureFlags) val params = mutableMapOf()