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 }