code.vegaprotocol.io/vega@v0.79.0/core/liquidity/v2/scores.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 liquidity
    17  
    18  import (
    19  	"code.vegaprotocol.io/vega/core/types"
    20  	"code.vegaprotocol.io/vega/libs/num"
    21  	"code.vegaprotocol.io/vega/protos/vega"
    22  )
    23  
    24  func (e *Engine) GetAverageLiquidityScores() map[string]num.Decimal {
    25  	return e.avgScores
    26  }
    27  
    28  func (e *Engine) UpdateAverageLiquidityScores(bestBid, bestAsk num.Decimal, minLpPrice, maxLpPrice *num.Uint) {
    29  	current, total := e.GetCurrentLiquidityScores(bestBid, bestAsk, minLpPrice, maxLpPrice)
    30  	nLps := len(current)
    31  	if nLps == 0 {
    32  		return
    33  	}
    34  
    35  	// normalise first
    36  	equalFraction := num.DecimalOne().Div(num.DecimalFromInt64(int64(nLps)))
    37  	for k, v := range current {
    38  		if total.IsZero() {
    39  			current[k] = equalFraction
    40  		} else {
    41  			current[k] = v.Div(total)
    42  		}
    43  	}
    44  
    45  	if e.nAvg > 1 {
    46  		n := num.DecimalFromInt64(e.nAvg)
    47  		nMinusOneOverN := n.Sub(num.DecimalOne()).Div(n)
    48  
    49  		for k, vNew := range current {
    50  			// if not found then it defaults to 0
    51  			vOld := e.avgScores[k]
    52  			current[k] = vOld.Mul(nMinusOneOverN).Add(vNew.Div(n))
    53  		}
    54  	}
    55  
    56  	for k := range current {
    57  		current[k] = current[k].Round(10)
    58  	}
    59  
    60  	// always overwrite with latest to automatically remove LPs that are no longer ACTIVE from the list
    61  	e.avgScores = current
    62  	e.nAvg++
    63  }
    64  
    65  // GetCurrentLiquidityScores returns volume-weighted probability of trading per each LP's deployed orders.
    66  func (e *Engine) GetCurrentLiquidityScores(bestBid, bestAsk num.Decimal, minLpPrice, maxLpPrice *num.Uint) (map[string]num.Decimal, num.Decimal) {
    67  	provs := e.provisions.Slice()
    68  	t := num.DecimalZero()
    69  	r := make(map[string]num.Decimal, len(provs))
    70  	for _, p := range provs {
    71  		if p.Status != vega.LiquidityProvision_STATUS_ACTIVE {
    72  			continue
    73  		}
    74  		orders := e.getAllActiveOrders(p.Party)
    75  		l := e.suppliedEngine.CalculateLiquidityScore(orders, bestBid, bestAsk, minLpPrice, maxLpPrice)
    76  		r[p.Party] = l
    77  		t = t.Add(l)
    78  	}
    79  	return r, t
    80  }
    81  
    82  // GetPartyLiquidityScore returns the volume-weighted probability of trading for the orders. Used to get a score for the AMM shape.
    83  func (e *Engine) GetPartyLiquidityScore(orders []*types.Order, bestBid, bestAsk num.Decimal, minP, maxP *num.Uint) num.Decimal {
    84  	return e.suppliedEngine.CalculateLiquidityScore(orders, bestBid, bestAsk, minP, maxP)
    85  }
    86  
    87  func (e *Engine) getAllActiveOrders(party string) []*types.Order {
    88  	partyOrders := e.orderBook.GetOrdersPerParty(party)
    89  	orders := make([]*types.Order, 0, len(partyOrders))
    90  	for _, order := range partyOrders {
    91  		if order.Status == vega.Order_STATUS_ACTIVE {
    92  			orders = append(orders, order)
    93  		}
    94  	}
    95  	return orders
    96  }
    97  
    98  func (e *Engine) ResetAverageLiquidityScores() {
    99  	e.avgScores = make(map[string]num.Decimal, len(e.avgScores))
   100  	e.nAvg = 1
   101  }