code.vegaprotocol.io/vega@v0.79.0/core/matching/closeoutprice_test.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 matching 17 18 import ( 19 "testing" 20 21 "code.vegaprotocol.io/vega/core/types" 22 "code.vegaprotocol.io/vega/libs/num" 23 24 "github.com/stretchr/testify/assert" 25 ) 26 27 func TestOrderBook_closeOutPriceBuy(t *testing.T) { 28 market := "testMarket" 29 book := getTestOrderBook(t, market) 30 defer book.Finish() 31 32 tradedOrder1 := types.Order{ 33 MarketID: market, 34 Party: "A", 35 Side: types.SideSell, 36 Price: num.NewUint(100), 37 OriginalPrice: num.NewUint(100), 38 Size: 100, 39 Remaining: 100, 40 TimeInForce: types.OrderTimeInForceGTC, 41 Type: types.OrderTypeLimit, 42 } 43 confirm, err := book.SubmitOrder(&tradedOrder1) 44 assert.NoError(t, err) 45 assert.Equal(t, 0, len(confirm.Trades)) 46 47 tradedOrder2 := types.Order{ 48 MarketID: market, 49 Party: "B", 50 Side: types.SideBuy, 51 Price: num.NewUint(100), 52 OriginalPrice: num.NewUint(100), 53 Size: 100, 54 Remaining: 100, 55 TimeInForce: types.OrderTimeInForceGTC, 56 Type: types.OrderTypeLimit, 57 } 58 confirm, err = book.SubmitOrder(&tradedOrder2) 59 assert.NoError(t, err) 60 assert.Equal(t, 1, len(confirm.Trades)) 61 62 order := types.Order{ 63 MarketID: market, 64 Party: "A", 65 Side: types.SideBuy, 66 Price: num.NewUint(100), 67 OriginalPrice: num.NewUint(100), 68 Size: 100, 69 Remaining: 100, 70 TimeInForce: types.OrderTimeInForceGTC, 71 Type: types.OrderTypeLimit, 72 } 73 confirm, err = book.SubmitOrder(&order) 74 assert.NoError(t, err) 75 assert.Equal(t, 0, len(confirm.Trades)) 76 77 // Normal case 78 price, err := book.GetFillPrice(10, types.SideBuy) 79 assert.NoError(t, err) 80 assert.Equal(t, price.Uint64(), uint64(100)) 81 82 // Incorrect size 83 price, err = book.GetFillPrice(0, types.SideBuy) 84 assert.Error(t, err, ErrInvalidVolume) 85 assert.Equal(t, price.Uint64(), uint64(0)) 86 87 // Not enough on the book 88 price, err = book.GetFillPrice(200, types.SideBuy) 89 assert.Error(t, err, ErrNotEnoughOrders) 90 assert.Equal(t, price.Uint64(), uint64(100)) 91 92 // Wrong side 93 price, err = book.GetFillPrice(10, types.SideSell) 94 assert.Error(t, err, ErrNotEnoughOrders) 95 assert.Equal(t, price.Uint64(), uint64(100)) 96 } 97 98 func TestOrderBook_closeOutPriceSell(t *testing.T) { 99 market := "testMarket" 100 book := getTestOrderBook(t, market) 101 defer book.Finish() 102 103 tradedOrder1 := types.Order{ 104 MarketID: market, 105 Party: "A", 106 Side: types.SideSell, 107 Price: num.NewUint(100), 108 OriginalPrice: num.NewUint(100), 109 Size: 100, 110 Remaining: 100, 111 TimeInForce: types.OrderTimeInForceGTC, 112 Type: types.OrderTypeLimit, 113 } 114 confirm, err := book.SubmitOrder(&tradedOrder1) 115 assert.NoError(t, err) 116 assert.Equal(t, 0, len(confirm.Trades)) 117 118 tradedOrder2 := types.Order{ 119 MarketID: market, 120 Party: "B", 121 Side: types.SideBuy, 122 Price: num.NewUint(100), 123 OriginalPrice: num.NewUint(100), 124 Size: 100, 125 Remaining: 100, 126 TimeInForce: types.OrderTimeInForceGTC, 127 Type: types.OrderTypeLimit, 128 } 129 confirm, err = book.SubmitOrder(&tradedOrder2) 130 assert.NoError(t, err) 131 assert.Equal(t, 1, len(confirm.Trades)) 132 133 untradedOrder := types.Order{ 134 MarketID: market, 135 Party: "A", 136 Side: types.SideSell, 137 Price: num.NewUint(100), 138 OriginalPrice: num.NewUint(100), 139 Size: 100, 140 Remaining: 100, 141 TimeInForce: types.OrderTimeInForceGTC, 142 Type: types.OrderTypeLimit, 143 } 144 confirm, err = book.SubmitOrder(&untradedOrder) 145 assert.NoError(t, err) 146 assert.Equal(t, 0, len(confirm.Trades)) 147 148 // Normal case 149 price, err := book.GetFillPrice(10, types.SideSell) 150 assert.NoError(t, err) 151 assert.Equal(t, price.Uint64(), uint64(100)) 152 153 // Incorrect size 154 price, err = book.GetFillPrice(0, types.SideSell) 155 assert.Error(t, err, ErrInvalidVolume) 156 assert.Equal(t, price.Uint64(), uint64(0)) 157 158 // Not enough on the book 159 price, err = book.GetFillPrice(200, types.SideSell) 160 assert.Error(t, err, ErrNotEnoughOrders) 161 assert.Equal(t, price.Uint64(), uint64(100)) 162 163 // Wrong side 164 price, err = book.GetFillPrice(10, types.SideBuy) 165 assert.Error(t, err, ErrNotEnoughOrders) 166 assert.Equal(t, price.Uint64(), uint64(100)) 167 } 168 169 func TestOrderBook_closeOutPriceBuy2(t *testing.T) { 170 market := "testMarket" 171 book := getTestOrderBook(t, market) 172 defer book.Finish() 173 order := types.Order{ 174 MarketID: market, 175 Party: "A", 176 Side: types.SideBuy, 177 Price: num.NewUint(100), 178 OriginalPrice: num.NewUint(100), 179 Size: 100, 180 Remaining: 100, 181 TimeInForce: types.OrderTimeInForceGTC, 182 Type: types.OrderTypeLimit, 183 } 184 confirm, err := book.SubmitOrder(&order) 185 assert.NoError(t, err) 186 assert.Equal(t, 0, len(confirm.Trades)) 187 188 order2 := types.Order{ 189 MarketID: market, 190 Party: "A", 191 Side: types.SideBuy, 192 Price: num.NewUint(90), 193 OriginalPrice: num.NewUint(90), 194 Size: 100, 195 Remaining: 100, 196 TimeInForce: types.OrderTimeInForceGTC, 197 Type: types.OrderTypeLimit, 198 } 199 confirm, err = book.SubmitOrder(&order2) 200 assert.NoError(t, err) 201 assert.Equal(t, 0, len(confirm.Trades)) 202 203 order3 := types.Order{ 204 MarketID: market, 205 Party: "A", 206 Side: types.SideBuy, 207 Price: num.NewUint(80), 208 OriginalPrice: num.NewUint(80), 209 Size: 100, 210 Remaining: 100, 211 TimeInForce: types.OrderTimeInForceGTC, 212 Type: types.OrderTypeLimit, 213 } 214 confirm, err = book.SubmitOrder(&order3) 215 assert.NoError(t, err) 216 assert.Equal(t, 0, len(confirm.Trades)) 217 218 // Normal case 219 price, err := book.GetFillPrice(100, types.SideBuy) 220 assert.NoError(t, err) 221 assert.Equal(t, price.Uint64(), uint64(100)) 222 223 // Normal case 224 price, err = book.GetFillPrice(200, types.SideBuy) 225 assert.NoError(t, err) 226 assert.Equal(t, price.Uint64(), uint64(95)) 227 228 // Normal case 229 price, err = book.GetFillPrice(300, types.SideBuy) 230 assert.NoError(t, err) 231 assert.Equal(t, price.Uint64(), uint64(90)) 232 } 233 234 func TestOrderBook_closeOutPriceSell2(t *testing.T) { 235 market := "testMarket" 236 book := getTestOrderBook(t, market) 237 defer book.Finish() 238 order := types.Order{ 239 MarketID: market, 240 Party: "A", 241 Side: types.SideSell, 242 Price: num.NewUint(100), 243 OriginalPrice: num.NewUint(100), 244 Size: 100, 245 Remaining: 100, 246 TimeInForce: types.OrderTimeInForceGTC, 247 Type: types.OrderTypeLimit, 248 } 249 confirm, err := book.SubmitOrder(&order) 250 assert.NoError(t, err) 251 assert.Equal(t, 0, len(confirm.Trades)) 252 253 order2 := types.Order{ 254 MarketID: market, 255 Party: "A", 256 Side: types.SideSell, 257 Price: num.NewUint(110), 258 OriginalPrice: num.NewUint(110), 259 Size: 100, 260 Remaining: 100, 261 TimeInForce: types.OrderTimeInForceGTC, 262 Type: types.OrderTypeLimit, 263 } 264 confirm, err = book.SubmitOrder(&order2) 265 assert.NoError(t, err) 266 assert.Equal(t, 0, len(confirm.Trades)) 267 268 order3 := types.Order{ 269 MarketID: market, 270 Party: "A", 271 Side: types.SideSell, 272 Price: num.NewUint(120), 273 OriginalPrice: num.NewUint(120), 274 Size: 100, 275 Remaining: 100, 276 TimeInForce: types.OrderTimeInForceGTC, 277 Type: types.OrderTypeLimit, 278 } 279 confirm, err = book.SubmitOrder(&order3) 280 assert.NoError(t, err) 281 assert.Equal(t, 0, len(confirm.Trades)) 282 283 // Normal case 284 price, err := book.GetFillPrice(100, types.SideSell) 285 assert.NoError(t, err) 286 assert.Equal(t, price.Uint64(), uint64(100)) 287 288 // Normal case 289 price, err = book.GetFillPrice(200, types.SideSell) 290 assert.NoError(t, err) 291 assert.Equal(t, price.Uint64(), uint64(105)) 292 293 // Normal case 294 price, err = book.GetFillPrice(300, types.SideSell) 295 assert.NoError(t, err) 296 assert.Equal(t, price.Uint64(), uint64(110)) 297 }