From cfa864908e6ff19e02492d6b3863ed7ffb7ae1af Mon Sep 17 00:00:00 2001 From: John Huang Date: Tue, 28 May 2024 11:05:29 -0700 Subject: [PATCH 1/3] TRA-312 Moved marginMode checking to TradeInputCalculator --- .../calculator/TradeInputCalculator.kt | 54 ++++++++++++++++++- .../model/TradingStateMachine+TradeInput.kt | 43 +++------------ v4_abacus.podspec | 2 +- 3 files changed, 62 insertions(+), 37 deletions(-) diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/calculator/TradeInputCalculator.kt b/src/commonMain/kotlin/exchange.dydx.abacus/calculator/TradeInputCalculator.kt index 0ae7ef493..f229a76ce 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/calculator/TradeInputCalculator.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/calculator/TradeInputCalculator.kt @@ -69,7 +69,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 @@ -134,6 +139,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() diff --git a/v4_abacus.podspec b/v4_abacus.podspec index 319a1788b..e2d734d8b 100644 --- a/v4_abacus.podspec +++ b/v4_abacus.podspec @@ -11,7 +11,7 @@ Pod::Spec.new do |spec| - if false + if !Dir.exist?('build/cocoapods/framework/Abacus.framework') || Dir.empty?('build/cocoapods/framework/Abacus.framework') raise " Kotlin framework 'Abacus' doesn't exist yet, so a proper Xcode project can't be generated. From f8103408d8c782ec036aacbef3c9fa720b724246 Mon Sep 17 00:00:00 2001 From: John Huang Date: Tue, 28 May 2024 11:06:55 -0700 Subject: [PATCH 2/3] Update version --- build.gradle.kts | 2 +- .../calculator/TradeInputCalculator.kt | 82 +++++++++---------- v4_abacus.podspec | 4 +- 3 files changed, 44 insertions(+), 44 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index b49e59a7f..00084403b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -51,7 +51,7 @@ allprojects { } group = "exchange.dydx.abacus" -version = "1.7.33" +version = "1.7.34" 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 f229a76ce..b8fc25285 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/calculator/TradeInputCalculator.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/calculator/TradeInputCalculator.kt @@ -824,7 +824,7 @@ internal class TradeInputCalculator( @Suppress("LocalVariableName", "PropertyName") val X = ((LV * AE) - (SZ * OR)) / - (OR + (OS * LV * MP * FR) - (LV * (OR - MP))) + (OR + (OS * LV * MP * FR) - (LV * (OR - MP))) val desiredSize = X.abs() if (desiredSize < entrySize) { val rounded = this.rounded(sizeTotal, desiredSize, stepSize) @@ -1069,10 +1069,10 @@ internal class TradeInputCalculator( return mapOf( "field" to "stopLoss", "type" to - listOf( - priceField(), - reduceOnlyField(), - ).filterNotNull(), + listOf( + priceField(), + reduceOnlyField(), + ).filterNotNull(), ) } @@ -1080,10 +1080,10 @@ internal class TradeInputCalculator( return mapOf( "field" to "takeProfit", "type" to - listOf( - priceField(), - reduceOnlyField(), - ).filterNotNull(), + listOf( + priceField(), + reduceOnlyField(), + ).filterNotNull(), ) } @@ -1141,19 +1141,19 @@ internal class TradeInputCalculator( "field" to "execution", "type" to "string", "options" to - if (includesDefaultAndPostOnly) { - listOf( - executionDefault, - executionIOC, - executionFOK, - executionPostOnly, - ) - } else { - listOf( - executionIOC, - executionFOK, - ) - }, + if (includesDefaultAndPostOnly) { + listOf( + executionDefault, + executionIOC, + executionFOK, + executionPostOnly, + ) + } else { + listOf( + executionIOC, + executionFOK, + ) + }, ) } @@ -1462,10 +1462,10 @@ internal class TradeInputCalculator( ) { val feeMultiplier = feeMultiplierPpm / QUANTUM_MULTIPLIER return feeMultiplier * (fee - maxMakerRebate * notional) / ( - tokenPrice * 10.0.pow( - tokenPriceExponent, - ) - ) + tokenPrice * 10.0.pow( + tokenPriceExponent, + ) + ) } return null } @@ -1536,11 +1536,11 @@ internal class TradeInputCalculator( val total = if (usdcSize != null) { ( - usdcSize * multiplier + ( - fee - ?: Numeric.double.ZERO - ) * Numeric.double.NEGATIVE - ) + usdcSize * multiplier + ( + fee + ?: Numeric.double.ZERO + ) * Numeric.double.NEGATIVE + ) } else { null } @@ -1669,11 +1669,11 @@ internal class TradeInputCalculator( val total = if (usdcSize != null) { ( - usdcSize * multiplier + ( - fee - ?: Numeric.double.ZERO - ) * Numeric.double.NEGATIVE - ) + usdcSize * multiplier + ( + fee + ?: Numeric.double.ZERO + ) * Numeric.double.NEGATIVE + ) } else { null } @@ -1726,11 +1726,11 @@ internal class TradeInputCalculator( val total = if (usdcSize != null) { ( - usdcSize * multiplier + ( - fee - ?: Numeric.double.ZERO - ) * Numeric.double.NEGATIVE - ) + usdcSize * multiplier + ( + fee + ?: Numeric.double.ZERO + ) * Numeric.double.NEGATIVE + ) } else { null } diff --git a/v4_abacus.podspec b/v4_abacus.podspec index e2d734d8b..2e668c1f2 100644 --- a/v4_abacus.podspec +++ b/v4_abacus.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = 'v4_abacus' - spec.version = '1.7.33' + spec.version = '1.7.34' spec.homepage = 'https://github.com/dydxprotocol/v4-abacus' spec.source = { :http=> ''} spec.authors = '' @@ -11,7 +11,7 @@ Pod::Spec.new do |spec| - if !Dir.exist?('build/cocoapods/framework/Abacus.framework') || Dir.empty?('build/cocoapods/framework/Abacus.framework') + if false raise " Kotlin framework 'Abacus' doesn't exist yet, so a proper Xcode project can't be generated. From 01fbde20769c4a1a1dd3a368d1e3c6924d4185ab Mon Sep 17 00:00:00 2001 From: mobile-build-bot-git Date: Mon, 3 Jun 2024 21:39:35 +0000 Subject: [PATCH 3/3] Bump version --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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()