Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/tra 312 update margin mode when data comes in #389

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ allprojects {
}

group = "exchange.dydx.abacus"
version = "1.7.49"
version = "1.7.50"

repositories {
google()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -135,6 +140,53 @@ internal class TradeInputCalculator(
}
}

private fun updateTradeInputFromMarket(
markets: Map<String, Any>?,
account: Map<String, Any>?,
tradeInput: Map<String, Any>?,
subaccountNumber: Int,
): MutableMap<String, Any>? {
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<String, Any>,
market: Map<String, Any>?,
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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<String, Any>()
val changes =
StateChanges(
iListOf(Changes.input),
Expand All @@ -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,
)
}
Expand All @@ -115,31 +112,6 @@ internal fun TradingStateMachine.tradeInMarket(
}
}

internal fun TradingStateMachine.updateTradeInputFromMarket(
trade: Map<String, Any>,
subaccountNumber: Int,
): MutableMap<String, Any> {
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,
Expand All @@ -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<String, Any>()
Expand Down
Loading