code.vegaprotocol.io/vega@v0.79.0/core/execution/future/isolated_margin.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package future
    17  
    18  import (
    19  	"context"
    20  
    21  	"code.vegaprotocol.io/vega/core/events"
    22  	"code.vegaprotocol.io/vega/core/positions"
    23  	"code.vegaprotocol.io/vega/core/types"
    24  	"code.vegaprotocol.io/vega/libs/num"
    25  )
    26  
    27  func (m *Market) updateIsolatedMarginsOnPositionChange(ctx context.Context, mpos *positions.MarketPosition, order *types.Order, trade *types.Trade) error {
    28  	pos, err := m.collateral.GetPartyMargin(mpos, m.settlementAsset, m.GetID())
    29  	if err != nil {
    30  		return err
    31  	}
    32  	price := m.getMarketObservable(order.Price.Clone())
    33  	increment := m.tradableInstrument.Instrument.Product.GetMarginIncrease(m.timeService.GetTimeNow().UnixNano())
    34  	orders := m.matching.GetOrdersPerParty(order.Party)
    35  	marginFactor := m.getMarginFactor(order.Party)
    36  	r, err := m.risk.UpdateIsolatedMarginsOnPositionChange(ctx, pos, price, increment, orders, []*types.Trade{trade}, order.Side, marginFactor)
    37  	if err != nil {
    38  		return err
    39  	}
    40  	for _, rr := range r {
    41  		m.transferMargins(ctx, []events.Risk{rr}, nil)
    42  	}
    43  	pos, err = m.collateral.GetPartyMargin(mpos, m.settlementAsset, m.GetID())
    44  	if err != nil {
    45  		return err
    46  	}
    47  	_, err = m.risk.CheckMarginInvariants(ctx, pos, price, increment, orders, marginFactor)
    48  	return err
    49  }
    50  
    51  func (m *Market) getIsolatedMarginContext(mpos *positions.MarketPosition, order *types.Order) (*num.Uint, events.Margin, num.Decimal, *num.Uint, num.Decimal, []*types.Order, error) {
    52  	var orderPrice *num.Uint
    53  	if order != nil {
    54  		orderPrice = order.Price.Clone()
    55  	} else {
    56  		orderPrice = num.UintZero()
    57  	}
    58  	marketObservable := m.getMarketObservable(orderPrice)
    59  	mID := m.GetID()
    60  	pos, err := m.collateral.GetPartyMargin(mpos, m.settlementAsset, mID)
    61  	if err != nil {
    62  		return nil, nil, num.DecimalZero(), nil, num.DecimalZero(), nil, err
    63  	}
    64  	increment := m.tradableInstrument.Instrument.Product.GetMarginIncrease(m.timeService.GetTimeNow().UnixNano())
    65  	auctionPrice := m.getAuctionPrice()
    66  	marginFactor := m.getMarginFactor(mpos.Party())
    67  	orders := m.matching.GetOrdersPerParty(mpos.Party())
    68  	return marketObservable, pos, increment, auctionPrice, marginFactor, orders, nil
    69  }
    70  
    71  func (m *Market) getAuctionPrice() *num.Uint {
    72  	var auctionPrice *num.Uint
    73  	if m.as.InAuction() {
    74  		if m.capMax != nil && m.fCap.FullyCollateralised {
    75  			// if this is a capped market with max price, this is the price we need to use all the time
    76  			// this function is called to calculate margins, and margin calculations are always going to be based on the max price.
    77  			return m.capMax.Clone()
    78  		}
    79  		auctionPrice = m.matching.GetIndicativePrice()
    80  		if markPrice := m.getCurrentMarkPrice(); markPrice != nil && !markPrice.IsZero() && (markPrice.GT(auctionPrice) || auctionPrice == nil) {
    81  			auctionPrice = markPrice
    82  		}
    83  	}
    84  	return auctionPrice
    85  }