Skip to content

Commit

Permalink
chore(default-target-leverage): update default target leverage to 2x (#…
Browse files Browse the repository at this point in the history
…748)

Co-authored-by: Rui <[email protected]>
  • Loading branch information
jaredvu and ruixhuang authored Nov 15, 2024
1 parent a642a3f commit e4bcbb8
Show file tree
Hide file tree
Showing 11 changed files with 39 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import exchange.dydx.abacus.state.internalstate.InternalMarketState
import exchange.dydx.abacus.state.internalstate.InternalPerpetualPosition
import exchange.dydx.abacus.state.internalstate.InternalSubaccountState
import exchange.dydx.abacus.state.internalstate.InternalTradeInputState
import exchange.dydx.abacus.utils.DEFAULT_TARGET_LEVERAGE
import exchange.dydx.abacus.utils.IList
import exchange.dydx.abacus.utils.Logger
import exchange.dydx.abacus.utils.MAX_LEVERAGE_BUFFER_PERCENT
Expand Down Expand Up @@ -702,7 +703,7 @@ internal object MarginCalculator {
val oraclePrice = market?.perpetualMarket?.oraclePrice ?: return null
val price = trade.summary?.price ?: return null
val maxMarketLeverage = market.perpetualMarket?.configs?.maxMarketLeverage ?: return null
val targetLeverage = trade.targetLeverage ?: maxMarketLeverage
val targetLeverage = trade.targetLeverage ?: min(DEFAULT_TARGET_LEVERAGE, maxMarketLeverage)
val positionSizeDifference = getPositionSizeDifference(subaccount, trade) ?: return null

return calculateIsolatedMarginTransferAmountFromValues(
Expand Down Expand Up @@ -732,7 +733,7 @@ internal object MarginCalculator {
val effectiveImf = parser.asDouble(parser.value(market, "configs.effectiveInitialMarginFraction")) ?: Numeric.double.ZERO
val maxMarketLeverage = getMaxMarketLeverageDeprecated(effectiveImf = effectiveImf, imf = initialMarginFraction)

val targetLeverage = parser.asDouble(trade["targetLeverage"]) ?: maxMarketLeverage
val targetLeverage = parser.asDouble(trade["targetLeverage"]) ?: min(DEFAULT_TARGET_LEVERAGE, maxMarketLeverage)
val positionSizeDifference = getPositionSizeDifferenceDeprecated(parser, subaccount, trade) ?: return null

return calculateIsolatedMarginTransferAmountFromValues(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package exchange.dydx.abacus.calculator

import exchange.dydx.abacus.utils.DEFAULT_TARGET_LEVERAGE
import exchange.dydx.abacus.utils.Numeric
import exchange.dydx.abacus.utils.Parser
import exchange.dydx.abacus.utils.mutable
import kotlin.math.min

object MarginModeCalculator {

Expand Down Expand Up @@ -49,7 +51,7 @@ object MarginModeCalculator {
subaccountNumber,
)
val existingPositionLeverage = parser.asDouble(parser.value(existingPosition, "leverage.current"))
modified["targetLeverage"] = existingPositionLeverage ?: maxMarketLeverage
modified["targetLeverage"] = existingPositionLeverage ?: min(DEFAULT_TARGET_LEVERAGE, maxMarketLeverage)
}
} else {
val marketMarginMode = MarginCalculator.findMarketMarginModeDeprecated(
Expand All @@ -60,7 +62,7 @@ object MarginModeCalculator {
"ISOLATED" -> {
modified["marginMode"] = marketMarginMode
if (parser.asDouble(tradeInput["targetLeverage"]) == null) {
modified["targetLeverage"] = maxMarketLeverage
modified["targetLeverage"] = min(DEFAULT_TARGET_LEVERAGE, maxMarketLeverage)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import exchange.dydx.abacus.output.input.MarginMode
import exchange.dydx.abacus.state.internalstate.InternalAccountState
import exchange.dydx.abacus.state.internalstate.InternalMarketState
import exchange.dydx.abacus.state.internalstate.InternalTradeInputState
import exchange.dydx.abacus.utils.DEFAULT_TARGET_LEVERAGE
import exchange.dydx.abacus.utils.Numeric
import kotlin.math.min

internal class TradeInputMarginModeCalculator {
fun updateTradeInputMarginMode(
Expand All @@ -33,7 +35,7 @@ internal class TradeInputMarginModeCalculator {
subaccountNumber = subaccountNumber,
)
val existingPositionLeverage = existingPosition?.calculated?.get(CalculationPeriod.current)?.leverage
tradeInput.targetLeverage = if (existingPositionLeverage != null && existingPositionLeverage > Numeric.double.ZERO) existingPositionLeverage else maxMarketLeverage
tradeInput.targetLeverage = if (existingPositionLeverage != null && existingPositionLeverage > Numeric.double.ZERO) existingPositionLeverage else min(DEFAULT_TARGET_LEVERAGE, maxMarketLeverage)
}
} else {
val marketMarginMode = MarginCalculator.findMarketMarginMode(
Expand All @@ -42,7 +44,7 @@ internal class TradeInputMarginModeCalculator {
when (marketMarginMode) {
MarginMode.Isolated -> {
tradeInput.marginMode = marketMarginMode
tradeInput.targetLeverage = tradeInput.targetLeverage ?: maxMarketLeverage
tradeInput.targetLeverage = tradeInput.targetLeverage ?: min(DEFAULT_TARGET_LEVERAGE, maxMarketLeverage)
}

MarginMode.Cross -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -675,14 +675,15 @@ internal class TradeInputMarketOrderCalculator() {
tradeLeverage: Double,
isTradeSameSide: Boolean,
): Double {
if (freeCollateral <= Numeric.double.ZERO || tradeLeverage <= Numeric.double.ZERO) {
val tradeLeverageAbs = tradeLeverage.abs()
if (freeCollateral <= Numeric.double.ZERO || tradeLeverageAbs == Numeric.double.ZERO) {
return Numeric.double.ZERO
}
return if (isTradeSameSide) {
(usdcSize / tradeLeverage) / freeCollateral
(usdcSize / tradeLeverageAbs) / freeCollateral
} else {
val existingBalance = positionSize.abs() / tradeLeverage
(usdcSize / tradeLeverage - existingBalance) / (freeCollateral + existingBalance)
val existingBalance = positionSize.abs() / tradeLeverageAbs
(usdcSize / tradeLeverageAbs - existingBalance) / (freeCollateral + existingBalance)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ import exchange.dydx.abacus.state.internalstate.InternalWalletState
import exchange.dydx.abacus.state.internalstate.safeCreate
import exchange.dydx.abacus.state.manager.StatsigConfig
import exchange.dydx.abacus.state.model.ClosePositionInputField
import exchange.dydx.abacus.utils.DEFAULT_TARGET_LEVERAGE
import exchange.dydx.abacus.utils.Numeric
import kollections.iListOf
import kotlin.math.min

internal interface ClosePositionInputProcessorProtocol {
fun closePosition(
Expand Down Expand Up @@ -107,7 +109,7 @@ internal class ClosePositionInputProcessor(
val maxMarketLeverage = market?.perpetualMarket?.configs?.maxMarketLeverage ?: Numeric.double.ONE

val currentPositionLeverage = position.calculated[CalculationPeriod.current]?.leverage?.abs()
trade.targetLeverage = if (currentPositionLeverage != null && currentPositionLeverage > Numeric.double.ZERO) currentPositionLeverage else maxMarketLeverage
trade.targetLeverage = if (currentPositionLeverage != null && currentPositionLeverage > Numeric.double.ZERO) currentPositionLeverage else min(DEFAULT_TARGET_LEVERAGE, maxMarketLeverage)

// default full close
trade.sizePercent = 1.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ import exchange.dydx.abacus.state.internalstate.InternalTradeInputState
import exchange.dydx.abacus.state.internalstate.InternalWalletState
import exchange.dydx.abacus.state.internalstate.safeCreate
import exchange.dydx.abacus.state.model.TradeInputField
import exchange.dydx.abacus.utils.DEFAULT_TARGET_LEVERAGE
import exchange.dydx.abacus.utils.Numeric
import kollections.iListOf
import kotlin.math.min

internal interface TradeInputProcessorProtocol {
fun tradeInMarket(
Expand Down Expand Up @@ -262,7 +264,7 @@ internal class TradeInputProcessor(
val market = marketSummaryState.markets[trade.marketId]
val maxMarketLeverage = market?.perpetualMarket?.configs?.maxMarketLeverage
?: Numeric.double.ONE
trade.targetLeverage = maxMarketLeverage
trade.targetLeverage = min(DEFAULT_TARGET_LEVERAGE, maxMarketLeverage)
}

val changedSubaccountNumbers =
Expand Down Expand Up @@ -335,15 +337,15 @@ internal class TradeInputProcessor(
} else if (existingOrder != null) {
trade.marginMode =
if (existingOrder.subaccountNumber == subaccountNumber) MarginMode.Cross else MarginMode.Isolated
trade.targetLeverage = maxMarketLeverage
trade.targetLeverage = min(DEFAULT_TARGET_LEVERAGE, maxMarketLeverage)
} else {
val marketType = marketState?.perpetualMarket?.configs?.perpetualMarketType
trade.marginMode = when (marketType) {
PerpetualMarketType.CROSS -> MarginMode.Cross
PerpetualMarketType.ISOLATED -> MarginMode.Isolated
else -> null
}
trade.targetLeverage = maxMarketLeverage
trade.targetLeverage = min(DEFAULT_TARGET_LEVERAGE, maxMarketLeverage)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import exchange.dydx.abacus.responses.cannotModify
import exchange.dydx.abacus.state.changes.Changes
import exchange.dydx.abacus.state.changes.StateChanges
import exchange.dydx.abacus.state.manager.StatsigConfig
import exchange.dydx.abacus.utils.DEFAULT_TARGET_LEVERAGE
import exchange.dydx.abacus.utils.Numeric
import exchange.dydx.abacus.utils.mutable
import exchange.dydx.abacus.utils.mutableMapOf
import exchange.dydx.abacus.utils.safeSet
import kollections.JsExport
import kollections.iListOf
import kotlinx.serialization.Serializable
import kotlin.math.min

@JsExport
@Serializable
Expand Down Expand Up @@ -114,8 +116,9 @@ fun TradingStateMachine.closePosition(
} else {
Numeric.double.ONE
}

val currentPositionLeverage = parser.asDouble(parser.value(position, "leverage.current"))?.abs()
trade["targetLeverage"] = if (currentPositionLeverage != null && currentPositionLeverage > 0) currentPositionLeverage else maxMarketLeverage
trade["targetLeverage"] = if (currentPositionLeverage != null && currentPositionLeverage > 0) currentPositionLeverage else min(DEFAULT_TARGET_LEVERAGE, maxMarketLeverage)

// default full close
trade.safeSet("size.percent", 1.0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import exchange.dydx.abacus.responses.StateResponse
import exchange.dydx.abacus.responses.cannotModify
import exchange.dydx.abacus.state.changes.Changes
import exchange.dydx.abacus.state.changes.StateChanges
import exchange.dydx.abacus.utils.DEFAULT_TARGET_LEVERAGE
import exchange.dydx.abacus.utils.Numeric
import exchange.dydx.abacus.utils.mutable
import exchange.dydx.abacus.utils.mutableMapOf
import exchange.dydx.abacus.utils.safeSet
import kollections.JsExport
import kollections.iListOf
import kotlinx.serialization.Serializable
import kotlin.math.min

@JsExport
@Serializable
Expand Down Expand Up @@ -170,11 +172,11 @@ internal fun TradingStateMachine.tradeInMarket(
} else if (existingOrder != null) {
val orderMarginMode = if ((parser.asInt(parser.value(existingOrder, "subaccountNumber")) ?: subaccountNumber) == subaccountNumber) MarginMode.Cross.rawValue else MarginMode.Isolated.rawValue
it.safeSet("marginMode", orderMarginMode)
it.safeSet("targetLeverage", maxMarketLeverage)
it.safeSet("targetLeverage", min(DEFAULT_TARGET_LEVERAGE, maxMarketLeverage))
} else {
val marketType = parser.asString(parser.value(marketsSummary, "markets.$marketId.configs.perpetualMarketType"))
it.safeSet("marginMode", MarginMode.invoke(marketType)?.rawValue)
it.safeSet("targetLeverage", maxMarketLeverage)
it.safeSet("targetLeverage", min(DEFAULT_TARGET_LEVERAGE, maxMarketLeverage))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ internal const val MAX_FREE_COLLATERAL_BUFFER_PERCENT = 0.95
// Isolated Margin Constants
internal const val MAX_LEVERAGE_BUFFER_PERCENT = 0.98
internal const val MARGIN_COLLATERALIZATION_CHECK_BUFFER = 0.01;
internal const val DEFAULT_TARGET_LEVERAGE = 2.0;

// Order flags
internal const val SHORT_TERM_ORDER_FLAGS = 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ class IsolatedMarginModeTests : V4BaseTests(true) {
assertEquals("NEAR-USD", trade.marketId)
assertEquals(MarginMode.Cross, trade.marginMode)
assertEquals(true, trade.options.needsMarginMode)
assertEquals(10.0, trade.targetLeverage)
assertEquals(2.0, trade.targetLeverage)
} else {
test(
{
Expand All @@ -225,7 +225,7 @@ class IsolatedMarginModeTests : V4BaseTests(true) {
"trade": {
"marketId": "NEAR-USD",
"marginMode": "CROSS",
"targetLeverage": 10.0,
"targetLeverage": 5.0,
"options": {
"needsMarginMode": true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,10 @@ open class V4TradeInputTests : V4BaseTests() {
perp.trade("380", TradeInputField.usdcSize, 0)
}, null)

test({
perp.trade("20", TradeInputField.targetLeverage, 0)
}, null)

if (perp.staticTyping) {
perp.trade("1500", TradeInputField.limitPrice, 0)

Expand Down

0 comments on commit e4bcbb8

Please sign in to comment.