code.vegaprotocol.io/vega@v0.79.0/core/matching/amends_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 TestOrderBookAmends_simpleAmend(t *testing.T) { 28 market := "market" 29 book := getTestOrderBook(t, market) 30 defer book.Finish() 31 order := types.Order{ 32 MarketID: market, 33 Party: "A", 34 Side: types.SideBuy, 35 Price: num.NewUint(100), 36 OriginalPrice: num.NewUint(100), 37 Size: 2, 38 Remaining: 2, 39 TimeInForce: types.OrderTimeInForceGTC, 40 Type: types.OrderTypeLimit, 41 } 42 confirm, err := book.SubmitOrder(&order) 43 assert.NoError(t, err) 44 assert.Equal(t, 0, len(confirm.Trades)) 45 assert.Equal(t, uint64(2), book.getVolumeAtLevel(100, types.SideBuy)) 46 47 amend := types.Order{ 48 MarketID: market, 49 Party: "A", 50 Side: types.SideBuy, 51 Price: num.NewUint(100), 52 OriginalPrice: num.NewUint(100), 53 Size: 1, 54 Remaining: 1, 55 TimeInForce: types.OrderTimeInForceGTC, 56 Type: types.OrderTypeLimit, 57 } 58 err = book.AmendOrder(&order, &amend) 59 assert.NoError(t, err) 60 assert.Equal(t, 1, int(book.getVolumeAtLevel(100, types.SideBuy))) 61 } 62 63 func TestOrderBookAmends_invalidPartyID(t *testing.T) { 64 market := "market" 65 book := getTestOrderBook(t, market) 66 defer book.Finish() 67 order := types.Order{ 68 MarketID: market, 69 Party: "A", 70 Side: types.SideBuy, 71 Price: num.NewUint(100), 72 OriginalPrice: num.NewUint(100), 73 Size: 2, 74 Remaining: 2, 75 TimeInForce: types.OrderTimeInForceGTC, 76 Type: types.OrderTypeLimit, 77 } 78 confirm, err := book.SubmitOrder(&order) 79 assert.NoError(t, err) 80 assert.Equal(t, 0, len(confirm.Trades)) 81 assert.Equal(t, uint64(2), book.getVolumeAtLevel(100, types.SideBuy)) 82 83 amend := types.Order{ 84 MarketID: market, 85 Party: "B", 86 Side: types.SideBuy, 87 Price: num.NewUint(100), 88 OriginalPrice: num.NewUint(100), 89 Size: 1, 90 Remaining: 1, 91 TimeInForce: types.OrderTimeInForceGTC, 92 Type: types.OrderTypeLimit, 93 } 94 err = book.AmendOrder(&order, &amend) 95 assert.Error(t, types.ErrOrderAmendFailure, err) 96 assert.Equal(t, uint64(2), book.getVolumeAtLevel(100, types.SideBuy)) 97 } 98 99 func TestOrderBookAmends_invalidPriceAmend(t *testing.T) { 100 market := "market" 101 book := getTestOrderBook(t, market) 102 defer book.Finish() 103 order := types.Order{ 104 MarketID: market, 105 Party: "A", 106 Side: types.SideBuy, 107 Price: num.NewUint(100), 108 OriginalPrice: num.NewUint(100), 109 Size: 2, 110 Remaining: 2, 111 TimeInForce: types.OrderTimeInForceGTC, 112 Type: types.OrderTypeLimit, 113 } 114 confirm, err := book.SubmitOrder(&order) 115 assert.NoError(t, err) 116 assert.Equal(t, 0, len(confirm.Trades)) 117 assert.Equal(t, uint64(2), book.getVolumeAtLevel(100, types.SideBuy)) 118 119 amend := types.Order{ 120 MarketID: market, 121 Party: "A", 122 Side: types.SideBuy, 123 Price: num.NewUint(101), 124 OriginalPrice: num.NewUint(101), 125 Size: 1, 126 Remaining: 1, 127 TimeInForce: types.OrderTimeInForceGTC, 128 Type: types.OrderTypeLimit, 129 } 130 err = book.AmendOrder(&order, &amend) 131 assert.Error(t, types.ErrOrderAmendFailure, err) 132 assert.Equal(t, uint64(2), book.getVolumeAtLevel(100, types.SideBuy)) 133 } 134 135 func TestOrderBookAmends_invalidSize(t *testing.T) { 136 market := "market" 137 book := getTestOrderBook(t, market) 138 defer book.Finish() 139 order := types.Order{ 140 MarketID: market, 141 Party: "A", 142 Side: types.SideBuy, 143 Price: num.NewUint(100), 144 OriginalPrice: num.NewUint(100), 145 Size: 2, 146 Remaining: 2, 147 TimeInForce: types.OrderTimeInForceGTC, 148 Type: types.OrderTypeLimit, 149 } 150 confirm, err := book.SubmitOrder(&order) 151 assert.NoError(t, err) 152 assert.Equal(t, 0, len(confirm.Trades)) 153 assert.Equal(t, uint64(2), book.getVolumeAtLevel(100, types.SideBuy)) 154 155 amend := types.Order{ 156 MarketID: market, 157 Party: "A", 158 Side: types.SideBuy, 159 Price: num.NewUint(100), 160 OriginalPrice: num.NewUint(100), 161 Size: 5, 162 Remaining: 5, 163 TimeInForce: types.OrderTimeInForceGTC, 164 Type: types.OrderTypeLimit, 165 } 166 err = book.AmendOrder(&order, &amend) 167 assert.Error(t, types.ErrOrderAmendFailure, err) 168 assert.Equal(t, uint64(2), book.getVolumeAtLevel(100, types.SideBuy)) 169 } 170 171 func TestOrderBookAmends_invalidSize2(t *testing.T) { 172 market := "market" 173 book := getTestOrderBook(t, market) 174 defer book.Finish() 175 order := types.Order{ 176 MarketID: market, 177 Party: "A", 178 Side: types.SideBuy, 179 Price: num.NewUint(100), 180 OriginalPrice: num.NewUint(100), 181 Size: 48, 182 Remaining: 4, 183 TimeInForce: types.OrderTimeInForceGTC, 184 Type: types.OrderTypeLimit, 185 } 186 confirm, err := book.SubmitOrder(&order) 187 assert.NoError(t, err) 188 assert.Equal(t, 0, len(confirm.Trades)) 189 assert.Equal(t, uint64(4), book.getVolumeAtLevel(100, types.SideBuy)) 190 191 amend := types.Order{ 192 MarketID: market, 193 Party: "A", 194 Side: types.SideBuy, 195 Price: num.NewUint(100), 196 OriginalPrice: num.NewUint(100), 197 Size: 45, 198 Remaining: 1, 199 TimeInForce: types.OrderTimeInForceGTC, 200 Type: types.OrderTypeLimit, 201 } 202 203 err = book.AmendOrder(&order, &amend) 204 assert.NoError(t, err) 205 assert.Equal(t, int(1), int(book.getVolumeAtLevel(100, types.SideBuy))) 206 } 207 208 func TestOrderBookAmends_reduceToZero(t *testing.T) { 209 market := "market" 210 book := getTestOrderBook(t, market) 211 defer book.Finish() 212 order := types.Order{ 213 MarketID: market, 214 Party: "A", 215 Side: types.SideBuy, 216 Price: num.NewUint(100), 217 OriginalPrice: num.NewUint(100), 218 Size: 2, 219 Remaining: 2, 220 TimeInForce: types.OrderTimeInForceGTC, 221 Type: types.OrderTypeLimit, 222 } 223 confirm, err := book.SubmitOrder(&order) 224 assert.NoError(t, err) 225 assert.Equal(t, 0, len(confirm.Trades)) 226 assert.Equal(t, uint64(2), book.getVolumeAtLevel(100, types.SideBuy)) 227 228 amend := types.Order{ 229 MarketID: market, 230 Party: "A", 231 Side: types.SideBuy, 232 Price: num.NewUint(100), 233 OriginalPrice: num.NewUint(100), 234 Size: 0, 235 Remaining: 0, 236 TimeInForce: types.OrderTimeInForceGTC, 237 Type: types.OrderTypeLimit, 238 } 239 err = book.AmendOrder(&order, &amend) 240 assert.Error(t, types.ErrOrderAmendFailure, err) 241 assert.Equal(t, uint64(2), book.getVolumeAtLevel(100, types.SideBuy)) 242 } 243 244 func TestOrderBookAmends_invalidSizeDueToPartialFill(t *testing.T) { 245 market := "market" 246 book := getTestOrderBook(t, market) 247 defer book.Finish() 248 order := types.Order{ 249 MarketID: market, 250 Party: "A", 251 Side: types.SideBuy, 252 Price: num.NewUint(100), 253 OriginalPrice: num.NewUint(100), 254 Size: 10, 255 Remaining: 10, 256 TimeInForce: types.OrderTimeInForceGTC, 257 Type: types.OrderTypeLimit, 258 } 259 confirm, err := book.SubmitOrder(&order) 260 assert.NoError(t, err) 261 assert.Equal(t, 0, len(confirm.Trades)) 262 assert.Equal(t, uint64(10), book.getVolumeAtLevel(100, types.SideBuy)) 263 264 order2 := types.Order{ 265 MarketID: market, 266 Party: "B", 267 Side: types.SideSell, 268 Price: num.NewUint(100), 269 OriginalPrice: num.NewUint(100), 270 Size: 5, 271 Remaining: 5, 272 TimeInForce: types.OrderTimeInForceGTC, 273 Type: types.OrderTypeLimit, 274 } 275 confirm, err = book.SubmitOrder(&order2) 276 assert.NoError(t, err) 277 assert.Equal(t, 1, len(confirm.Trades)) 278 assert.Equal(t, uint64(5), book.getVolumeAtLevel(100, types.SideBuy)) 279 280 amend := types.Order{ 281 MarketID: market, 282 Party: "B", 283 Side: types.SideBuy, 284 Price: num.NewUint(100), 285 OriginalPrice: num.NewUint(100), 286 Size: 6, 287 Remaining: 6, 288 TimeInForce: types.OrderTimeInForceGTC, 289 Type: types.OrderTypeLimit, 290 } 291 err = book.AmendOrder(&order, &amend) 292 assert.Error(t, types.ErrOrderAmendFailure, err) 293 assert.Equal(t, uint64(5), book.getVolumeAtLevel(100, types.SideBuy)) 294 } 295 296 func TestOrderBookAmends_validSizeDueToPartialFill(t *testing.T) { 297 market := "market" 298 book := getTestOrderBook(t, market) 299 defer book.Finish() 300 order := types.Order{ 301 MarketID: market, 302 Party: "A", 303 Side: types.SideBuy, 304 Price: num.NewUint(100), 305 OriginalPrice: num.NewUint(100), 306 Size: 10, 307 Remaining: 10, 308 TimeInForce: types.OrderTimeInForceGTC, 309 Type: types.OrderTypeLimit, 310 } 311 confirm, err := book.SubmitOrder(&order) 312 assert.NoError(t, err) 313 assert.Equal(t, 0, len(confirm.Trades)) 314 assert.Equal(t, uint64(10), book.getVolumeAtLevel(100, types.SideBuy)) 315 316 order2 := types.Order{ 317 MarketID: market, 318 Party: "B", 319 Side: types.SideSell, 320 Price: num.NewUint(100), 321 OriginalPrice: num.NewUint(100), 322 Size: 5, 323 Remaining: 5, 324 TimeInForce: types.OrderTimeInForceGTC, 325 Type: types.OrderTypeLimit, 326 } 327 confirm, err = book.SubmitOrder(&order2) 328 assert.NoError(t, err) 329 assert.Equal(t, 1, len(confirm.Trades)) 330 assert.Equal(t, uint64(5), book.getVolumeAtLevel(100, types.SideBuy)) 331 332 amend := types.Order{ 333 MarketID: market, 334 Party: "A", 335 Side: types.SideBuy, 336 Price: num.NewUint(100), 337 OriginalPrice: num.NewUint(100), 338 Size: 3, 339 Remaining: 3, 340 TimeInForce: types.OrderTimeInForceGTC, 341 Type: types.OrderTypeLimit, 342 } 343 err = book.AmendOrder(&order, &amend) 344 assert.Error(t, types.ErrOrderAmendFailure, err) 345 assert.Equal(t, uint64(3), book.getVolumeAtLevel(100, types.SideBuy)) 346 } 347 348 func TestOrderBookAmends_noOrderToAmend(t *testing.T) { 349 market := "market" 350 book := getTestOrderBook(t, market) 351 defer book.Finish() 352 353 amend := types.Order{ 354 MarketID: market, 355 Party: "A", 356 Side: types.SideBuy, 357 Price: num.NewUint(100), 358 OriginalPrice: num.NewUint(100), 359 Size: 1, 360 Remaining: 1, 361 TimeInForce: types.OrderTimeInForceGTC, 362 Type: types.OrderTypeLimit, 363 } 364 assert.Panics(t, func() { 365 book.AmendOrder(nil, &amend) 366 }) 367 }