Skip to content

Commit

Permalink
Merge branch 'main' into features/notification
Browse files Browse the repository at this point in the history
# Conflicts:
#	build.gradle.kts
#	integration/iOS/Pods/Pods.xcodeproj/project.pbxproj
#	src/commonMain/kotlin/exchange.dydx.abacus/state/manager/StateManagerAdaptor.kt
#	src/commonMain/kotlin/exchange.dydx.abacus/state/v2/supervisor/SubaccountSupervisor.kt
#	v4_abacus.podspec
  • Loading branch information
ruixhuang committed May 10, 2024
2 parents f242f5e + 8f8ac34 commit 724b069
Show file tree
Hide file tree
Showing 71 changed files with 17,127 additions and 392 deletions.
14 changes: 14 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks

default_install_hook_types:
[pre-push]

repos:
- repo: local
hooks:
- id: spotless-apply
name: spotless-apply
entry: ./run_spotless_apply.sh
language: script
stages: [pre-push]
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ Integration tests can be written to call Abacus from non-Kotlin code (i.e., Swif

> ./bump_version.sh
# Auto-lint

Enable pre-commit to auto-lint/auto-format your changes before git commit:

> brew install pre-commit
> pre-commit install
# How to use

```
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ allprojects {
}

group = "exchange.dydx.abacus"
version = "1.6.52"
version = "1.7.7"

repositories {
google()
Expand Down
3 changes: 3 additions & 0 deletions detekt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ naming:
# /exchange -> /dydx -> /abacus
# didn't seem worth the potential thrash in PRs to fix (feel free to fix if you feel differently)
active: false
MatchingDeclarationName:
# Affects a lot of the TradingStateMachine+_.kt files
active: false

complexity:
CognitiveComplexMethod:
Expand Down
28 changes: 27 additions & 1 deletion docs/API/Actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,4 +240,30 @@ Take profit order trigger price's percentage difference from the position's aver

### takeProfitUsdcDiff

Take profit order trigger price's usdc difference from the position's average entry price
Take profit order trigger price's usdc difference from the position's average entry price

# AdjustIsolatedMargin

fun adjustIsolatedMargin(data: String?, type: AdjustIsolatedMarginInputField?): AppStateResponse

The input state is in `response.state.input.adjustIsolatedMargin` as a [AdjustIsolatedMarginInput](../Input/AdjustIsolatedMarginInput.md).

### data

Data input in string format

## AdjustIsolatedMarginInputField

### Type

IsolatedMarginAdjustmentType
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
21 changes: 21 additions & 0 deletions docs/Input/AdjustIsolatedMarginInput.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# AdjustIsolatedMarginInput

data class AdjustIsolatedMarginInput(
 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

2 changes: 1 addition & 1 deletion integration/iOS/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
source 'https://github.com/CocoaPods/Specs.git'

def abacus_pods
pod 'abacus', :path => '~/v4-abacus'
pod 'abacus', :path => '../../v4-abacus'
#pod 'abacus', :git => 'https://github.com/dydxprotocol/v4-abacus.git'
end

Expand Down
4 changes: 2 additions & 2 deletions integration/iOS/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ EXTERNAL SOURCES:
:path: "~/v4-abacus"

SPEC CHECKSUMS:
abacus: 46f62be6dc9b3f888093eb2c9952d0267ab40670
abacus: a57d55b0ca0d3514389573a87c47507f88eb6b0a
CryptoSwift: 562f8eceb40e80796fffc668b0cad9313284cfa6

PODFILE CHECKSUM: 37d72c15b180e62a4c42b8fb41b4836c89aa63c9

COCOAPODS: 1.15.2
COCOAPODS: 1.12.1
1 change: 0 additions & 1 deletion integration/iOS/Pods/Local Podspecs/abacus.podspec.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions integration/iOS/Pods/Manifest.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

86 changes: 43 additions & 43 deletions integration/iOS/Pods/Pods.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions run_spotless_apply.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh

./gradlew spotlessApply

exit 0
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.valueOf(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.valueOf(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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,26 @@ internal class SubaccountTransformer {
}
}

internal fun applyIsolatedMarginAdjustmentToWallet(
wallet: Map<String, Any>,
subaccountNumber: Int?,
delta: Map<String, Double>,
parser: ParserProtocol,
period: String
): Map<String, Any> {
val key = "account.subaccounts.$subaccountNumber"
val subaccount = parser.asNativeMap(parser.value(wallet, key))

if (subaccount != null) {
val modifiedSubaccount = applyDeltaToSubaccount(subaccount, delta, parser, period)
val modifiedWallet = wallet.mutable()
modifiedWallet.safeSet(key, modifiedSubaccount)
return modifiedWallet
}

return wallet
}

internal fun applyTradeToSubaccount(
subaccount: Map<String, Any>?,
trade: Map<String, Any>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,7 @@ internal class TradeInputCalculator(
return parser.asDouble(parser.value(position, "maxLeverage.current"))
} else {
val initialMarginFraction =
parser.asDouble(parser.value(market, "configs.initialMarginFraction"))
parser.asDouble(parser.value(market, "configs.effectiveInitialMarginFraction"))
?: return null
return 1.0 / initialMarginFraction
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import exchange.dydx.abacus.utils.mutable
import exchange.dydx.abacus.utils.safeSet
import kotlin.math.abs

internal object TriggerOrdersConstants {
const val TRIGGER_ORDER_DEFAULT_DURATION_DAYS = 90.0
}

@Suppress("UNCHECKED_CAST")
internal class TriggerOrdersInputCalculator(val parser: ParserProtocol) {
internal fun calculate(
Expand Down
Loading

0 comments on commit 724b069

Please sign in to comment.