From 699a77a7514820ca3fd9dc2ca65e433364c02b30 Mon Sep 17 00:00:00 2001 From: Elias Van Ootegem Date: Tue, 27 Aug 2024 09:48:54 +0100 Subject: [PATCH] fix: update position status on trade for parties previously marked as closed out Signed-off-by: Elias Van Ootegem --- CHANGELOG.md | 1 + datanode/entities/position.go | 4 ++++ datanode/entities/position_test.go | 25 ++++++++++++++++++++++++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1af7a5dc2b..e67f55473c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ - [11607](https://github.com/vegaprotocol/vega/issues/11607) - Wire rank lottery distribution to team reward payout. - [959](https://github.com/vegaprotocol/core-test-coverage/issues/959) - Include `ELS` for `AMM` sub keys to the parent key `ELS`. - [11592](https://github.com/vegaprotocol/vega/issues/11592) - Fix the order of calls at end of epoch between rebate engine and market tracker. +- [10907](https://github.com/vegaprotocol/vega/issues/10907) - Fix position API distressed status not getting updated once the party has been closed out. ## 0.77.5 diff --git a/datanode/entities/position.go b/datanode/entities/position.go index 532aa705fa0..265c6bf13cc 100644 --- a/datanode/entities/position.go +++ b/datanode/entities/position.go @@ -144,6 +144,10 @@ func (p *Position) UpdateWithTrade(trade vega.Trade, seller bool, pf num.Decimal p.pendingMTM(assetPrice, pf) if trade.Type == types.TradeTypeNetworkCloseOutBad { p.updateWithBadTrade(trade, seller, pf) + } else if p.DistressedStatus == PositionStatusClosedOut { + // Not a closeout trade, but the position is currently still marked as distressed. + // This indicates the party was closed out previously, but has topped up and opened a new position. + p.DistressedStatus = PositionStatusUnspecified } } diff --git a/datanode/entities/position_test.go b/datanode/entities/position_test.go index ffa65479f2f..07f7a553505 100644 --- a/datanode/entities/position_test.go +++ b/datanode/entities/position_test.go @@ -85,6 +85,7 @@ func TestDistressedPartyUpdate(t *testing.T) { market := "market-id" party := "party1" position := entities.NewEmptyPosition(entities.MarketID(market), entities.PartyID(party)) + pf := num.DecimalFromFloat(1) ps := events.NewSettlePositionEvent(ctx, party, market, num.NewUint(1000), []events.TradeSettlement{ tradeStub{ @@ -95,7 +96,7 @@ func TestDistressedPartyUpdate(t *testing.T) { size: 3, price: num.NewUint(1200), }, - }, 1, num.DecimalFromFloat(1)) + }, 1, pf) position.UpdateWithPositionSettlement(ps) pp := position.ToProto() assert.Equal(t, "0", pp.RealisedPnl) @@ -111,9 +112,31 @@ func TestDistressedPartyUpdate(t *testing.T) { // now assume this party is distressed, and we've taken all their funds sde := events.NewSettleDistressed(ctx, party, market, num.UintZero(), num.NewUint(100), 1) position.UpdateWithSettleDistressed(sde) + // ensure the position is flagged as distressed. + assert.Equal(t, entities.PositionStatusClosedOut, position.DistressedStatus) pp = position.ToProto() assert.Equal(t, "0", pp.UnrealisedPnl) assert.Equal(t, "-1000", pp.RealisedPnl) + + // now submit process a closeout trade event + position.UpdateWithTrade(vega.Trade{ + Size: 5, + Price: "1200", + AssetPrice: "1200", + Type: vega.Trade_TYPE_NETWORK_CLOSE_OUT_BAD, + }, true, pf) + // now ensure the position status still is what we expect it to be + assert.Equal(t, entities.PositionStatusClosedOut, position.DistressedStatus) + + // next, assume the party has topped up, and traded again. + position.UpdateWithTrade(vega.Trade{ + Size: 1, + Price: "1200", + AssetPrice: "1200", + Type: vega.Trade_TYPE_DEFAULT, + }, true, pf) + // now the distressed status ought to be cleared. + assert.Equal(t, entities.PositionStatusUnspecified, position.DistressedStatus) } func TestMultipleTradesAndLossSocializationPartyWithOpenVolume(t *testing.T) {