Skip to content

Commit

Permalink
handle short position case for displaying liquidation price, live-upd…
Browse files Browse the repository at this point in the history
…ate position row items (#205)

* handle short position case for displaying liquidation price

* remove viewmodel caching
  • Loading branch information
mike-dydx committed Aug 21, 2024
1 parent 95d734f commit 6207dc0
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 48 deletions.
6 changes: 5 additions & 1 deletion docs/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ _Provide a clear and concise description of the fix(es) or change(s) you made. I

| Before | After |
|--------|-------|
| <img src=""> | <img src=""> |
| <img src=""> | <img src="" width=60%> |
| <img src=""> | <img src="" width=60%> |
| <img src=""> | <img src="" width=60%> |
| <img src=""> | <img src="" width=60%> |
| <img src=""> | <img src="" width=60%> |
| <video src=""> | <video src=""> |


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ protocol dydxPortfolioPositionsViewPresenterProtocol: HostedViewPresenterProtoco
}

class dydxPortfolioPositionsViewPresenter: HostedViewPresenter<dydxPortfolioPositionsViewModel>, dydxPortfolioPositionsViewPresenterProtocol {
private var positionsCache = [String: dydxPortfolioPositionItemViewModel]()
private var pendingPositionsCache = [String: dydxPortfolioPendingPositionsItemViewModel]()

init(viewModel: dydxPortfolioPositionsViewModel?) {
super.init()

Expand Down Expand Up @@ -57,25 +54,19 @@ class dydxPortfolioPositionsViewPresenter: HostedViewPresenter<dydxPortfolioPosi

private func updatePositions(positions: [SubaccountPosition], marketMap: [String: PerpetualMarket], assetMap: [String: Asset]) {
let items: [dydxPortfolioPositionItemViewModel] = positions.compactMap { position -> dydxPortfolioPositionItemViewModel? in
let item = Self.createPositionViewModelItem(position: position,
Self.createPositionViewModelItem(position: position,
marketMap: marketMap,
assetMap: assetMap,
positionsCache: positionsCache)
positionsCache[position.assetId] = item
return item
assetMap: assetMap)
}

self.viewModel?.positionItems = items
}

private func updatePendingPositions(pendingPositions: [SubaccountPendingPosition], marketMap: [String: PerpetualMarket], assetMap: [String: Asset]) {
let items: [dydxPortfolioPendingPositionsItemViewModel] = pendingPositions.compactMap { pendingPosition -> dydxPortfolioPendingPositionsItemViewModel? in
let item = Self.createPendingPositionsViewModelItem(pendingPosition: pendingPosition,
Self.createPendingPositionsViewModelItem(pendingPosition: pendingPosition,
marketMap: marketMap,
assetMap: assetMap,
pendingPositionsCache: pendingPositionsCache)
pendingPositionsCache[pendingPosition.assetId] = item
return item
assetMap: assetMap)
}

self.viewModel?.pendingPositionItems = items
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,19 @@ private class dydxAdjustMarginInputViewPresenter: HostedViewPresenter<dydxAdjust
AbacusStateManager.shared.adjustIsolatedMargin(input: childSubaccountNumber, type: .childsubaccountnumber)

Publishers
.CombineLatest3(
.CombineLatest4(
AbacusStateManager.shared.state.market(of: marketId).compactMap { $0 },
AbacusStateManager.shared.state.assetMap,
AbacusStateManager.shared.state.adjustIsolatedMarginInput.compactMap { $0 }
AbacusStateManager.shared.state.adjustIsolatedMarginInput.compactMap { $0 },
AbacusStateManager.shared.state.selectedSubaccountPositions.compactMap { $0.first(where: { $0.id == marketId }) }
)
.sink { [weak self] market, assetMap, input in
.sink { [weak self] market, assetMap, input, position in
self?.updateState(market: market, assetMap: assetMap)
self?.updateFields(input: input)
self?.updateForMarginDirection(input: input)
self?.updatePrePostValues(input: input, market: market)
self?.updateLiquidationPrice(input: input, market: market)
guard let side = position.side.current else { return }
self?.updateLiquidationPrice(input: input, side: side, market: market)
}
.store(in: &subscriptions)
}
Expand Down Expand Up @@ -267,24 +269,32 @@ private class dydxAdjustMarginInputViewPresenter: HostedViewPresenter<dydxAdjust
}
}

private func updateLiquidationPrice(input: AdjustIsolatedMarginInput, market: PerpetualMarket) {
private func updateLiquidationPrice(input: AdjustIsolatedMarginInput, side: Abacus.PositionSide, market: PerpetualMarket) {
if let displayTickSizeDecimals = market.configs?.displayTickSizeDecimals?.intValue {
let curLiquidationPrice = input.summary?.liquidationPrice ?? 0
let postLiquidationPrice = input.summary?.liquidationPriceUpdated ?? 0
let curLiquidationPrice = input.summary?.liquidationPrice
let postLiquidationPrice = input.summary?.liquidationPriceUpdated
let currentLeverage = input.summary?.positionLeverage?.doubleValue ?? 0
let postLeverage = input.summary?.positionLeverageUpdated?.doubleValue ?? 0

viewModel?.liquidationPrice = dydxAdjustMarginLiquidationPriceViewModel()

if input.summary?.positionLeverageUpdated == nil {
let hasNoInput = input.summary?.positionLeverageUpdated == nil

if hasNoInput {
// no input, no change, update accordingly
viewModel?.liquidationPrice?.direction = .none
if currentLeverage <= 1 {
if currentLeverage <= 1 && side == Abacus.PositionSide.long_ {
viewModel?.liquidationPrice?.before = DataLocalizer.shared?.localize(path: "APP.GENERAL.NONE", params: nil)
} else {
viewModel?.liquidationPrice?.before = dydxFormatter.shared.dollar(number: curLiquidationPrice, digits: displayTickSizeDecimals)
}
viewModel?.liquidationPrice?.after = nil
} else if side == Abacus.PositionSide.short_ {
// else there is input, handle short positions which always have a liquidation price
viewModel?.liquidationPrice?.before = dydxFormatter.shared.dollar(number: curLiquidationPrice, digits: displayTickSizeDecimals)
viewModel?.liquidationPrice?.after = dydxFormatter.shared.dollar(number: postLiquidationPrice, digits: displayTickSizeDecimals)
} else {
// else there is input, handle long positions which sometimes have a liquidation price
switch (currentLeverage <= 1, postLeverage <= 1) {
case (true, true):
viewModel?.liquidationPrice?.before = DataLocalizer.shared?.localize(path: "APP.GENERAL.NONE", params: nil)
Expand All @@ -299,17 +309,17 @@ private class dydxAdjustMarginInputViewPresenter: HostedViewPresenter<dydxAdjust
viewModel?.liquidationPrice?.before = dydxFormatter.shared.dollar(number: curLiquidationPrice, digits: displayTickSizeDecimals)
viewModel?.liquidationPrice?.after = dydxFormatter.shared.dollar(number: postLiquidationPrice, digits: displayTickSizeDecimals)
}
}

switch input.type {
case .add:
// liquidation price is moving further from oracle price with less leverage
viewModel?.liquidationPrice?.direction = currentLeverage <= 1 && postLeverage <= 1 ? .none : .safer
case .remove:
// liquidation price is moving closer to oracle price with more leverage
viewModel?.liquidationPrice?.direction = currentLeverage <= 1 && postLeverage <= 1 ? .none : .riskier
default:
viewModel?.liquidationPrice?.direction = .none
}
switch input.type {
case .add:
// liquidation price is moving further from oracle price with less leverage
viewModel?.liquidationPrice?.direction = hasNoInput ? .none : .safer
case .remove:
// liquidation price is moving closer to oracle price with more leverage
viewModel?.liquidationPrice?.direction = hasNoInput ? .none : .riskier
default:
viewModel?.liquidationPrice?.direction = .none
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,21 @@ public class dydxPortfolioPositionItemViewModel: PlatformViewModel {
self.handler = Handler(onTapAction: onTapAction, onMarginEditAction: onMarginEditAction)
}

public var size: String?
public var token: TokenTextViewModel?
public var sideText = SideTextViewModel()
public var leverage: String?
public var leverageIcon: LeverageRiskModel?
public var indexPrice: String?
public var entryPrice: String?
public var unrealizedPnl: SignedAmountViewModel?
public var unrealizedPnlPercent: String = ""
public var marginValue: String = "--"
public var marginMode: String = "--"
public var isMarginAdjustable: Bool = false
public var logoUrl: URL?
public var gradientType: GradientType
public var handler: Handler?
@Published public var size: String?
@Published public var token: TokenTextViewModel?
@Published public var sideText = SideTextViewModel()
@Published public var leverage: String?
@Published public var leverageIcon: LeverageRiskModel?
@Published public var indexPrice: String?
@Published public var entryPrice: String?
@Published public var unrealizedPnl: SignedAmountViewModel?
@Published public var unrealizedPnlPercent: String = ""
@Published public var marginValue: String = "--"
@Published public var marginMode: String = "--"
@Published public var isMarginAdjustable: Bool = false
@Published public var logoUrl: URL?
@Published public var gradientType: GradientType
@Published public var handler: Handler?

public static var previewValue: dydxPortfolioPositionItemViewModel {
let item = dydxPortfolioPositionItemViewModel(
Expand Down

0 comments on commit 6207dc0

Please sign in to comment.