code.vegaprotocol.io/vega@v0.79.0/core/integration/steps/the_average_fill_price_is.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 steps
    17  
    18  import (
    19  	"fmt"
    20  
    21  	"code.vegaprotocol.io/vega/core/types"
    22  	"code.vegaprotocol.io/vega/libs/num"
    23  
    24  	"github.com/cucumber/godog"
    25  )
    26  
    27  func TheAverageFillPriceIs(exec Execution, table *godog.Table) error {
    28  	rows := parseFillRowTable(table)
    29  	for _, row := range rows {
    30  		fRow := fillRow{row: row}
    31  		market := fRow.market()
    32  		volume := fRow.volume()
    33  		side := fRow.side()
    34  		expectedFillPrice := fRow.fillPrice()
    35  
    36  		actualfillPrice, err := exec.GetFillPriceForMarket(market, volume, side)
    37  		if err != nil {
    38  			return err
    39  		}
    40  
    41  		if expectedFillPrice != nil {
    42  			if actualfillPrice.NEQ(expectedFillPrice) {
    43  				return errWrongFillPrice(market, volume, side, expectedFillPrice, actualfillPrice)
    44  			}
    45  		}
    46  
    47  		expectedMarkPrice := fRow.markPrice()
    48  		if expectedMarkPrice != nil {
    49  			md, err := exec.GetMarketData(market)
    50  			if err != nil {
    51  				return errMarketDataNotFound(market, err)
    52  			}
    53  			if md.MarkPrice.NEQ(expectedMarkPrice) {
    54  				return errWrongMarkPrice(market, expectedMarkPrice, md)
    55  			}
    56  		}
    57  
    58  		expectedFactor, b := fRow.equivalentLinearSlippageFactor()
    59  
    60  		if b {
    61  			refPrice := fRow.refPrice()
    62  			if refPrice == nil {
    63  				return fmt.Errorf("'ref price' must be specified if 'equivalent linear slippage factor' is provided")
    64  			}
    65  			dRefPrice := refPrice.ToDecimal()
    66  			actualFactor := num.MaxD(num.DecimalZero(), actualfillPrice.ToDecimal().Sub(dRefPrice).Div(dRefPrice))
    67  
    68  			if !actualFactor.Equal(expectedFactor) {
    69  				return errWrongFactor(market, volume, side, expectedFactor, actualFactor)
    70  			}
    71  		}
    72  	}
    73  	return nil
    74  }
    75  
    76  func parseFillRowTable(table *godog.Table) []RowWrapper {
    77  	return StrictParseTable(table, []string{
    78  		"market",
    79  		"volume",
    80  		"side",
    81  	}, []string{
    82  		"fill price",
    83  		"ref price",
    84  		"equivalent linear slippage factor",
    85  		"mark price",
    86  	})
    87  }
    88  
    89  type fillRow struct {
    90  	row RowWrapper
    91  }
    92  
    93  func (r fillRow) market() string {
    94  	return r.row.MustStr("market")
    95  }
    96  
    97  func (r fillRow) volume() uint64 {
    98  	return r.row.MustU64("volume")
    99  }
   100  
   101  func (r fillRow) side() types.Side {
   102  	return r.row.MustSide("side")
   103  }
   104  
   105  func (r fillRow) fillPrice() *num.Uint {
   106  	return r.row.MaybeUint("fill price")
   107  }
   108  
   109  func (r fillRow) refPrice() *num.Uint {
   110  	return r.row.MaybeUint("ref price")
   111  }
   112  
   113  func (r fillRow) markPrice() *num.Uint {
   114  	return r.row.MaybeUint("mark price")
   115  }
   116  
   117  func (r fillRow) equivalentLinearSlippageFactor() (num.Decimal, bool) {
   118  	return r.row.DecimalB("equivalent linear slippage factor")
   119  }
   120  
   121  func errWrongFillPrice(market string, volume uint64, side types.Side, expected, actual *num.Uint) error {
   122  	return fmt.Errorf("wrong fill price for market(%v), volume(%v), side(%v): expected(%v) got(%v)",
   123  		market, volume, side, expected, actual,
   124  	)
   125  }
   126  
   127  func errWrongFactor(market string, volume uint64, side types.Side, expected, actual num.Decimal) error {
   128  	return fmt.Errorf("wrong effective linear slippage factor for market(%v), volume(%v), side(%v): expected(%v) got(%v)",
   129  		market, volume, side, expected, actual,
   130  	)
   131  }