-
Notifications
You must be signed in to change notification settings - Fork 15
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
Create Input for Adjusting Isolated Position's Margin #326
Merged
jaredvu
merged 27 commits into
main
from
jared/tra-183-create-input-for-adjusting-position-margin
May 8, 2024
Merged
Changes from 21 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
cb128db
draft new Input
jaredvu a78ece2
Merge branch 'main' into jared/tra-183-create-input-for-adjusting-pos…
jaredvu 4a4c397
Merge branch 'main' into jared/tra-183-create-input-for-adjusting-pos…
jaredvu 4d3c22a
Merge branch 'main' into jared/tra-183-create-input-for-adjusting-pos…
jaredvu bc3c4f2
adjustIsolatedMarginInput: state, tests, calculators
jaredvu 7dd42c9
Merge branch 'main' into jared/tra-183-create-input-for-adjusting-pos…
jaredvu 84201d3
update documentation and nit
jaredvu 37dbcdf
update summary
jaredvu d961cc9
Merge branch 'main' into jared/tra-183-create-input-for-adjusting-pos…
jaredvu d1f2736
spotlessApply
jaredvu 2296a58
remove newline
jaredvu 04f755c
Merge branch 'main' into jared/tra-183-create-input-for-adjusting-pos…
jaredvu 3c1c059
bump version
jaredvu dc966b4
linter get what linter wants
jaredvu 157d951
Merge branch 'main' into jared/tra-183-create-input-for-adjusting-pos…
jaredvu 59ec66f
detekt rule
jaredvu a7efaba
fix validation
jaredvu eeb7829
Merge branch 'main' into jared/tra-183-create-input-for-adjusting-pos…
jaredvu b4a693c
force enum usage instead of converting to string
jaredvu 527b5eb
spotlessApply
jaredvu b25c10b
string -> enum
jaredvu 875771a
kotlin enum feedback
jaredvu 45171ec
built-in kotlin enum for input field
jaredvu 360b43d
bump verison, update test
jaredvu 09442d9
Merge branch 'main' into jared/tra-183-create-input-for-adjusting-pos…
jaredvu 92b79b6
Update accessors due to built-in enum change
jaredvu a0a969f
update docs
jaredvu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# AdjustIsolatedMarginInput | ||
|
||
data class TriggerOrdersInput( | ||
 val type: String?, // "ADD" or "REMOVE" | ||
 val amount: Double?, | ||
 val childSubaccountNumber: Int?, | ||
) | ||
|
||
## type | ||
|
||
ADD - Add margin to the child's isolated margin account from the parent's cross margin account | ||
REMOVE - Remove margin from the child's isolated margin account to the parent's cross margin account | ||
|
||
## amount | ||
|
||
Amount of USDC to remove or add | ||
|
||
## childSubaccountNumber | ||
|
||
Subaccount number for the child whose margin is to be adjusted | ||
|
136 changes: 136 additions & 0 deletions
136
src/commonMain/kotlin/exchange.dydx.abacus/calculator/AdjustIsolatedMarginInputCalculator.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
package exchange.dydx.abacus.calculator | ||
|
||
import exchange.dydx.abacus.output.input.IsolatedMarginAdjustmentType | ||
import exchange.dydx.abacus.protocols.ParserProtocol | ||
import exchange.dydx.abacus.utils.Numeric | ||
import exchange.dydx.abacus.utils.mutable | ||
import exchange.dydx.abacus.utils.safeSet | ||
|
||
@Suppress("UNCHECKED_CAST") | ||
internal class AdjustIsolatedMarginInputCalculator(val parser: ParserProtocol) { | ||
private val subaccountTransformer = SubaccountTransformer() | ||
|
||
internal fun calculate( | ||
state: Map<String, Any>, | ||
parentSubaccountNumber: Int?, | ||
): Map<String, Any> { | ||
val wallet = parser.asNativeMap(state["wallet"]) | ||
val isolatedMarginAdjustment = parser.asNativeMap(state["adjustIsolatedMargin"]) | ||
val childSubaccountNumber = parser.asInt(isolatedMarginAdjustment?.get("childSubaccountNumber")) | ||
val type = parser.asString(isolatedMarginAdjustment?.get("type"))?.let { | ||
IsolatedMarginAdjustmentType.invoke(it) | ||
} ?: IsolatedMarginAdjustmentType.Add | ||
|
||
return if (wallet != null && isolatedMarginAdjustment != null && type != null) { | ||
val modified = state.mutable() | ||
val parentTransferDelta = getModifiedTransferDelta(isolatedMarginAdjustment, true) | ||
val childTransferDelta = getModifiedTransferDelta(isolatedMarginAdjustment, false) | ||
|
||
val walletPostParentSubaccountTransfer = | ||
subaccountTransformer.applyIsolatedMarginAdjustmentToWallet( | ||
wallet, | ||
subaccountNumber = parentSubaccountNumber, | ||
parentTransferDelta, | ||
parser, | ||
"postOrder", | ||
) | ||
|
||
val walletPostChildSubaccountTransfer = | ||
subaccountTransformer.applyIsolatedMarginAdjustmentToWallet( | ||
wallet = walletPostParentSubaccountTransfer, | ||
subaccountNumber = childSubaccountNumber, | ||
childTransferDelta, | ||
parser, | ||
"postOrder", | ||
) | ||
|
||
val modifiedParentSubaccount = parser.asNativeMap(parser.value(walletPostChildSubaccountTransfer, "accounts.subaccounts.$parentSubaccountNumber")) | ||
val modifiedChildSubaccount = parser.asNativeMap(parser.value(walletPostChildSubaccountTransfer, "accounts.subaccounts.$childSubaccountNumber")) | ||
val modifiedIsolatedMarginAdjustment = finalize(isolatedMarginAdjustment, modifiedParentSubaccount, modifiedChildSubaccount, type) | ||
|
||
modified["adjustIsolatedMargin"] = modifiedIsolatedMarginAdjustment | ||
modified["wallet"] = walletPostChildSubaccountTransfer | ||
modified | ||
} else { | ||
state | ||
} | ||
} | ||
|
||
private fun getModifiedTransferDelta( | ||
isolatedMarginAdjustment: Map<String, Any>, | ||
isParentSubaccount: Boolean, | ||
): Map<String, Double> { | ||
val type = parser.asString(isolatedMarginAdjustment["type"])?.let { | ||
IsolatedMarginAdjustmentType.invoke(it) | ||
} ?: IsolatedMarginAdjustmentType.Add | ||
val amount = parser.asDouble(isolatedMarginAdjustment["amount"]) | ||
|
||
when (type) { | ||
IsolatedMarginAdjustmentType.Add -> { | ||
val multiplier = | ||
if (isParentSubaccount) Numeric.double.NEGATIVE else Numeric.double.POSITIVE | ||
val usdcSize = (amount ?: Numeric.double.ZERO) * multiplier | ||
|
||
return mapOf( | ||
"usdcSize" to usdcSize, | ||
) | ||
} | ||
|
||
IsolatedMarginAdjustmentType.Remove -> { | ||
val multiplier = | ||
if (isParentSubaccount) Numeric.double.POSITIVE else Numeric.double.NEGATIVE | ||
val usdcSize = (amount ?: Numeric.double.ZERO) * multiplier | ||
|
||
return mapOf( | ||
"usdcSize" to usdcSize, | ||
) | ||
} | ||
} | ||
} | ||
|
||
private fun summaryForType( | ||
parentSubaccount: Map<String, Any>?, | ||
childSubaccount: Map<String, Any>?, | ||
type: IsolatedMarginAdjustmentType, | ||
): Map<String, Any> { | ||
val summary = mutableMapOf<String, Any>() | ||
val crossCollateral = parser.asDouble(parser.value(parentSubaccount, "freeCollateral.postOrder")) | ||
val crossMarginUsage = parser.asDouble(parser.value(parentSubaccount, "marginUsage.postOrder")) | ||
val openPositions = parser.asNativeMap(childSubaccount?.get("openPositions")) | ||
val marketId = openPositions?.keys?.firstOrNull() | ||
val positionMargin = parser.asDouble(parser.value(childSubaccount, "freeCollateral.postOrder")) | ||
val positionLeverage = parser.asDouble(parser.value(childSubaccount, "openPositions.$marketId.leverage.postOrder")) | ||
val liquidationPrice = parser.asDouble(parser.value(childSubaccount, "openPositions.$marketId.liquidationPrice.postOrder")) | ||
|
||
when (type) { | ||
IsolatedMarginAdjustmentType.Add -> { | ||
summary.safeSet("crossFreeCollateral", crossCollateral) | ||
summary.safeSet("crossMarginUsage", crossMarginUsage) | ||
summary.safeSet("positionMargin", positionMargin) | ||
summary.safeSet("positionLeverage", positionLeverage) | ||
summary.safeSet("liquidationPrice", liquidationPrice) | ||
} | ||
|
||
IsolatedMarginAdjustmentType.Remove -> { | ||
summary.safeSet("crossFreeCollateral", crossCollateral) | ||
summary.safeSet("crossMarginUsage", crossMarginUsage) | ||
summary.safeSet("positionMargin", positionMargin) | ||
summary.safeSet("positionLeverage", positionLeverage) | ||
summary.safeSet("liquidationPrice", liquidationPrice) | ||
} | ||
} | ||
|
||
return summary | ||
} | ||
|
||
private fun finalize( | ||
isolatedMarginAdjustment: Map<String, Any>, | ||
parentSubaccount: Map<String, Any>?, | ||
childSubaccount: Map<String, Any>?, | ||
type: IsolatedMarginAdjustmentType, | ||
): Map<String, Any> { | ||
val modified = isolatedMarginAdjustment.mutable() | ||
modified.safeSet("summary", summaryForType(parentSubaccount, childSubaccount, type)) | ||
return modified | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can use static imports for
Add
andRemove
specifically to make the code easier to read below.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
qq: wdym by easier to read? The import would be easier to read?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
like at usage sites you now get:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow that's pretty cool! I don't have a preference on either though. With the static import I think we would lose some readability unless you double check the enum, and what happens if there are multiple enums with the same
.name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah up to you, i don't feel strongly.
re multiple enums: you have to explicitly say what type you're casting the value to, so that ends up not being an issue. ex: