diff --git a/docs/Input/TradeInput.md b/docs/Input/TradeInput.md index 6e67e361f..161dc297e 100644 --- a/docs/Input/TradeInput.md +++ b/docs/Input/TradeInput.md @@ -223,6 +223,7 @@ The orderbook entries taken by the market order data class TradeInputOptions(  val needsSize: Boolean,  val needsLeverage: Boolean, + val needsBalancePercent: Boolean,  val maxLeverage: Double?,  val needsLimitPrice: Boolean,  val needsTargetLeverage: Boolean, @@ -248,6 +249,10 @@ UX should ask user for size UX should ask user for leverage input +## needsBalancePercent + +UX should ask user for balance percent input + ## maxLeverage Max leverage for the leverage slider diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/calculator/TradeInputCalculator.kt b/src/commonMain/kotlin/exchange.dydx.abacus/calculator/TradeInputCalculator.kt index 920adb434..a60a90804 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/calculator/TradeInputCalculator.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/calculator/TradeInputCalculator.kt @@ -1066,6 +1066,7 @@ internal class TradeInputCalculator( return when (MarginMode.invoke(marginMode)) { MarginMode.Isolated -> listOf( sizeField(), + // balancePercentField(), TODO: enable in CT-1180 bracketsField(), marginModeField(market, account, subaccount), reduceOnlyField(), @@ -1073,6 +1074,7 @@ internal class TradeInputCalculator( else -> listOf( sizeField(), leverageField(), + balancePercentField(), bracketsField(), marginModeField(market, account, subaccount), reduceOnlyField(), @@ -1157,6 +1159,13 @@ internal class TradeInputCalculator( ) } + private fun balancePercentField(): Map { + return mapOf( + "field" to "size.balancePercent", + "type" to "double", + ) + } + private fun limitPriceField(): Map { return mapOf( "field" to "price.limitPrice", @@ -1346,6 +1355,7 @@ internal class TradeInputCalculator( val options = mutableMapOf( "needsSize" to false, "needsLeverage" to false, + "needsBalancePercent" to false, "needsTargetLeverage" to false, "needsTriggerPrice" to false, "needsLimitPrice" to false, @@ -1363,6 +1373,7 @@ internal class TradeInputCalculator( when (parser.asString(field["field"])) { "size.size" -> options["needsSize"] = true "size.leverage" -> options["needsLeverage"] = true + "size.balancePercent" -> options["needsBalancePercent"] = true "price.triggerPrice" -> options["needsTriggerPrice"] = true "price.limitPrice" -> options["needsLimitPrice"] = true "price.trailingPercent" -> options["needsTrailingPercent"] = true diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/calculator/V2/TradeInput/TradeInputOptionsCalculator.kt b/src/commonMain/kotlin/exchange.dydx.abacus/calculator/V2/TradeInput/TradeInputOptionsCalculator.kt index 4a0c793c2..48d5c01d5 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/calculator/V2/TradeInput/TradeInputOptionsCalculator.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/calculator/V2/TradeInput/TradeInputOptionsCalculator.kt @@ -81,6 +81,7 @@ internal class TradeInputOptionsCalculator( return when (trade.marginMode) { MarginMode.Isolated -> listOf( sizeField(), + // balancePercentField(), TODO: enable in CT-1180 bracketsField(), marginModeField(market, account, subaccount), reduceOnlyField(), @@ -89,6 +90,7 @@ internal class TradeInputOptionsCalculator( else -> listOf( sizeField(), leverageField(), + balancePercentField(), bracketsField(), marginModeField(market, account, subaccount), reduceOnlyField(), @@ -181,6 +183,7 @@ internal class TradeInputOptionsCalculator( when (parser.asString(field["field"])) { "size.size" -> options.needsSize = true "size.leverage" -> options.needsLeverage = true + "size.balancePercent" -> options.needsBalancePercent = true "price.triggerPrice" -> options.needsTriggerPrice = true "price.limitPrice" -> options.needsLimitPrice = true "price.trailingPercent" -> options.needsTrailingPercent = true @@ -404,6 +407,13 @@ internal class TradeInputOptionsCalculator( ) } + private fun balancePercentField(): Map { + return mapOf( + "field" to "size.balancePercent", + "type" to "double", + ) + } + private fun limitPriceField(): Map { return mapOf( "field" to "price.limitPrice", diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/output/input/TradeInput.kt b/src/commonMain/kotlin/exchange.dydx.abacus/output/input/TradeInput.kt index 8e07ca217..dbad270dc 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/output/input/TradeInput.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/output/input/TradeInput.kt @@ -70,6 +70,7 @@ data class TradeInputOptions( val needsMarginMode: Boolean, val needsSize: Boolean, val needsLeverage: Boolean, + val needsBalancePercent: Boolean, val maxLeverage: Double?, val needsLimitPrice: Boolean, val needsTargetLeverage: Boolean, @@ -184,6 +185,7 @@ data class TradeInputOptions( needsMarginMode = state.needsMarginMode, needsSize = state.needsSize, needsLeverage = state.needsLeverage, + needsBalancePercent = state.needsBalancePercent, maxLeverage = state.maxLeverage, needsLimitPrice = state.needsLimitPrice, needsTargetLeverage = state.needsTargetLeverage, @@ -215,6 +217,7 @@ data class TradeInputOptions( val needsMarginMode = parser.asBool(data["needsMarginMode"]) ?: true val needsSize = parser.asBool(data["needsSize"]) ?: false val needsLeverage = parser.asBool(data["needsLeverage"]) ?: false + val needsBalancePercent = parser.asBool(data["needsBalancePercent"]) ?: false val maxLeverage = parser.asDouble(data["maxLeverage"]) val needsLimitPrice = parser.asBool(data["needsLimitPrice"]) ?: false val needsTargetLeverage = parser.asBool(data["needsTargetLeverage"]) ?: false @@ -282,6 +285,7 @@ data class TradeInputOptions( existing?.needsMarginMode != needsMarginMode || existing.needsSize != needsSize || existing.needsLeverage != needsLeverage || + existing.needsBalancePercent != needsBalancePercent || existing.maxLeverage != maxLeverage || existing.needsLimitPrice != needsLimitPrice || existing.needsTargetLeverage != needsTargetLeverage || @@ -302,6 +306,7 @@ data class TradeInputOptions( needsMarginMode, needsSize, needsLeverage, + needsBalancePercent, maxLeverage, needsLimitPrice, needsTargetLeverage, diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/state/internalstate/InternalState.kt b/src/commonMain/kotlin/exchange.dydx.abacus/state/internalstate/InternalState.kt index bfb09deb1..cf75c6a2f 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/state/internalstate/InternalState.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/state/internalstate/InternalState.kt @@ -151,6 +151,7 @@ internal data class InternalTradeInputOptions( var needsMarginMode: Boolean = false, var needsSize: Boolean = false, var needsLeverage: Boolean = false, + var needsBalancePercent: Boolean = false, var maxLeverage: Double? = null, var needsLimitPrice: Boolean = false, var needsTargetLeverage: Boolean = false, diff --git a/src/commonTest/kotlin/exchange.dydx.abacus/payload/BaseTests.kt b/src/commonTest/kotlin/exchange.dydx.abacus/payload/BaseTests.kt index 62d881cc2..be04a4b04 100644 --- a/src/commonTest/kotlin/exchange.dydx.abacus/payload/BaseTests.kt +++ b/src/commonTest/kotlin/exchange.dydx.abacus/payload/BaseTests.kt @@ -733,6 +733,7 @@ open class BaseTests( assertEquals(data.needsMarginMode, obj.needsMarginMode, "$trace.needsMarginMode $doesntMatchText") assertEquals(data.needsSize, obj.needsSize, "$trace.needsSize $doesntMatchText") assertEquals(data.needsLeverage, obj.needsLeverage, "$trace.needsLeverage $doesntMatchText") + assertEquals(data.needsBalancePercent, obj.needsBalancePercent, "$trace.needsBalancePercent $doesntMatchText") assertEquals(data.needsBrackets, obj.needsBrackets, "$trace.needsBrackets $doesntMatchText") assertEquals(data.needsGoodUntil, obj.needsGoodUntil, "$trace.needsGoodUntil $doesntMatchText") assertEquals(data.needsLimitPrice, obj.needsLimitPrice, "$trace.needsLimitPrice $doesntMatchText") @@ -771,6 +772,11 @@ open class BaseTests( obj.needsLeverage, "$trace.needsLeverage $doesntMatchText", ) + assertEquals( + parser.asBool(data["needsBalancePercent"]) ?: false, + obj.needsBalancePercent, + "$trace.needsBalancePercent $doesntMatchText", + ) assertEquals( parser.asBool(data["needsBrackets"]) ?: false, obj.needsBrackets, diff --git a/src/commonTest/kotlin/exchange.dydx.abacus/payload/TradeInputOptionsTests.kt b/src/commonTest/kotlin/exchange.dydx.abacus/payload/TradeInputOptionsTests.kt index 02bfbf7b1..054542a73 100644 --- a/src/commonTest/kotlin/exchange.dydx.abacus/payload/TradeInputOptionsTests.kt +++ b/src/commonTest/kotlin/exchange.dydx.abacus/payload/TradeInputOptionsTests.kt @@ -126,6 +126,7 @@ class TradeInputOptionsTests : V4BaseTests() { val options = trade.options assertEquals(options.needsSize, true) assertEquals(options.needsLeverage, true) + assertEquals(options.needsBalancePercent, true) assertEquals(options.needsTriggerPrice, false) assertEquals(options.needsLimitPrice, false) assertEquals(options.needsTrailingPercent, false) @@ -145,6 +146,7 @@ class TradeInputOptionsTests : V4BaseTests() { "options": { "needsSize": true, "needsLeverage": true, + "needsBalancePercent": true, "needsTriggerPrice": false, "needsLimitPrice": false, "needsTrailingPercent": false, @@ -168,6 +170,7 @@ class TradeInputOptionsTests : V4BaseTests() { val options = trade.options assertEquals(options.needsSize, true) assertEquals(options.needsLeverage, false) + assertEquals(options.needsBalancePercent, false) assertEquals(options.needsTriggerPrice, false) assertEquals(options.needsLimitPrice, true) assertEquals(options.needsTrailingPercent, false) @@ -187,6 +190,7 @@ class TradeInputOptionsTests : V4BaseTests() { "options": { "needsSize": true, "needsLeverage": false, + "needsBalancePercent": false, "needsTriggerPrice": false, "needsLimitPrice": true, "needsTrailingPercent": false, @@ -210,6 +214,7 @@ class TradeInputOptionsTests : V4BaseTests() { val options = trade.options assertEquals(options.needsSize, true) assertEquals(options.needsLeverage, false) + assertEquals(options.needsBalancePercent, false) assertEquals(options.needsTriggerPrice, false) assertEquals(options.needsLimitPrice, true) assertEquals(options.needsTrailingPercent, false) @@ -229,6 +234,7 @@ class TradeInputOptionsTests : V4BaseTests() { "options": { "needsSize": true, "needsLeverage": false, + "needsBalancePercent": false, "needsTriggerPrice": false, "needsLimitPrice": true, "needsTrailingPercent": false, @@ -252,6 +258,7 @@ class TradeInputOptionsTests : V4BaseTests() { val options = trade.options assertEquals(options.needsSize, true) assertEquals(options.needsLeverage, false) + assertEquals(options.needsBalancePercent, false) assertEquals(options.needsTriggerPrice, false) assertEquals(options.needsLimitPrice, true) assertEquals(options.needsTrailingPercent, false) @@ -290,6 +297,7 @@ class TradeInputOptionsTests : V4BaseTests() { "options": { "needsSize": true, "needsLeverage": false, + "needsBalancePercent": false, "needsTriggerPrice": false, "needsLimitPrice": true, "needsTrailingPercent": false,