code.vegaprotocol.io/vega@v0.79.0/core/matching/simpleorders_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/events" 22 "code.vegaprotocol.io/vega/core/types" 23 vgcrypto "code.vegaprotocol.io/vega/libs/crypto" 24 "code.vegaprotocol.io/vega/libs/num" 25 26 "github.com/stretchr/testify/assert" 27 "github.com/stretchr/testify/require" 28 ) 29 30 func TestOrderBookSimple_simpleLimitBuy(t *testing.T) { 31 market := "testMarket" 32 book := getTestOrderBook(t, market) 33 defer book.Finish() 34 order := types.Order{ 35 Status: types.OrderStatusActive, 36 MarketID: market, 37 Party: "A", 38 Side: types.SideBuy, 39 Price: num.NewUint(100), 40 OriginalPrice: num.NewUint(100), 41 Size: 1, 42 Remaining: 1, 43 TimeInForce: types.OrderTimeInForceGTC, 44 Type: types.OrderTypeLimit, 45 } 46 confirm, err := book.SubmitOrder(&order) 47 assert.NoError(t, err) 48 assert.Equal(t, 0, len(confirm.Trades)) 49 50 price, volume, err := book.BestBidPriceAndVolume() 51 assert.NoError(t, err) 52 assert.Equal(t, uint64(100), price.Uint64()) 53 assert.Equal(t, uint64(1), volume) 54 assert.Equal(t, book.getNumberOfBuyLevels(), 1) 55 assert.Equal(t, book.getNumberOfSellLevels(), 0) 56 assert.Equal(t, book.getTotalBuyVolume(), uint64(1)) 57 assert.Equal(t, book.getTotalSellVolume(), uint64(0)) 58 assert.Equal(t, len(book.ordersByID), 1) 59 } 60 61 func TestOrderBookSimple_simpleLimitSell(t *testing.T) { 62 market := "testMarket" 63 book := getTestOrderBook(t, market) 64 defer book.Finish() 65 order := types.Order{ 66 Status: types.OrderStatusActive, 67 MarketID: market, 68 Party: "A", 69 Side: types.SideSell, 70 Price: num.NewUint(100), 71 OriginalPrice: num.NewUint(100), 72 Size: 1, 73 Remaining: 1, 74 TimeInForce: types.OrderTimeInForceGTC, 75 Type: types.OrderTypeLimit, 76 } 77 confirm, err := book.SubmitOrder(&order) 78 assert.NoError(t, err) 79 assert.Equal(t, 0, len(confirm.Trades)) 80 81 price, volume, err := book.BestOfferPriceAndVolume() 82 assert.NoError(t, err) 83 assert.Equal(t, uint64(100), price.Uint64()) 84 assert.Equal(t, uint64(1), volume) 85 assert.Equal(t, book.getNumberOfBuyLevels(), 0) 86 assert.Equal(t, book.getNumberOfSellLevels(), 1) 87 assert.Equal(t, book.getTotalBuyVolume(), uint64(0)) 88 assert.Equal(t, book.getTotalSellVolume(), uint64(1)) 89 assert.Equal(t, len(book.ordersByID), 1) 90 } 91 92 func TestOrderBookSimple_simpleMarketBuy(t *testing.T) { 93 market := "testMarket" 94 book := getTestOrderBook(t, market) 95 defer book.Finish() 96 order := types.Order{ 97 Status: types.OrderStatusActive, 98 MarketID: market, 99 Party: "A", 100 Side: types.SideBuy, 101 Price: num.NewUint(100), 102 OriginalPrice: num.NewUint(100), 103 Size: 1, 104 Remaining: 1, 105 TimeInForce: types.OrderTimeInForceIOC, 106 Type: types.OrderTypeMarket, 107 } 108 confirm, err := book.SubmitOrder(&order) 109 assert.NoError(t, err) 110 assert.Equal(t, 0, len(confirm.Trades)) 111 112 price, volume, err := book.BestBidPriceAndVolume() 113 assert.Error(t, err) 114 assert.Equal(t, uint64(0), price.Uint64()) 115 assert.Equal(t, uint64(0), volume) 116 assert.Equal(t, book.getNumberOfBuyLevels(), 0) 117 assert.Equal(t, book.getNumberOfSellLevels(), 0) 118 assert.Equal(t, book.getTotalBuyVolume(), uint64(0)) 119 assert.Equal(t, book.getTotalSellVolume(), uint64(0)) 120 assert.Equal(t, len(book.ordersByID), 0) 121 } 122 123 func TestOrderBookSimple_simpleMarketSell(t *testing.T) { 124 market := "testMarket" 125 book := getTestOrderBook(t, market) 126 defer book.Finish() 127 order := types.Order{ 128 Status: types.OrderStatusActive, 129 MarketID: market, 130 Party: "A", 131 Side: types.SideSell, 132 Price: num.NewUint(100), 133 OriginalPrice: num.NewUint(100), 134 Size: 1, 135 Remaining: 1, 136 TimeInForce: types.OrderTimeInForceIOC, 137 Type: types.OrderTypeMarket, 138 } 139 confirm, err := book.SubmitOrder(&order) 140 assert.NoError(t, err) 141 assert.Equal(t, 0, len(confirm.Trades)) 142 143 price, volume, err := book.BestBidPriceAndVolume() 144 assert.Error(t, err) 145 assert.Equal(t, uint64(0), price.Uint64()) 146 assert.Equal(t, uint64(0), volume) 147 assert.Equal(t, book.getNumberOfBuyLevels(), 0) 148 assert.Equal(t, book.getNumberOfSellLevels(), 0) 149 assert.Equal(t, book.getTotalBuyVolume(), uint64(0)) 150 assert.Equal(t, book.getTotalSellVolume(), uint64(0)) 151 assert.Equal(t, len(book.ordersByID), 0) 152 } 153 154 /* 155 * NETWORK orders are the same as MARKET+FOK order so should not stay on the book 156 * Make sure orders are cancelled and the book is left empty. 157 */ 158 func TestOrderBookSimple_simpleNetworkBuy(t *testing.T) { 159 market := "testMarket" 160 book := getTestOrderBook(t, market) 161 defer book.Finish() 162 order := types.Order{ 163 Status: types.OrderStatusActive, 164 MarketID: market, 165 Party: "A", 166 Side: types.SideBuy, 167 Price: num.NewUint(100), 168 OriginalPrice: num.NewUint(100), 169 Size: 1, 170 Remaining: 1, 171 TimeInForce: types.OrderTimeInForceFOK, 172 Type: types.OrderTypeNetwork, 173 } 174 confirm, err := book.SubmitOrder(&order) 175 assert.NoError(t, err) 176 assert.Equal(t, 0, len(confirm.Trades)) 177 178 price, volume, err := book.BestBidPriceAndVolume() 179 assert.Error(t, err) 180 assert.Equal(t, uint64(0), price.Uint64()) 181 assert.Equal(t, uint64(0), volume) 182 assert.Equal(t, book.getNumberOfBuyLevels(), 0) 183 assert.Equal(t, book.getNumberOfSellLevels(), 0) 184 assert.Equal(t, book.getTotalBuyVolume(), uint64(0)) 185 assert.Equal(t, book.getTotalSellVolume(), uint64(0)) 186 assert.Equal(t, len(book.ordersByID), 0) 187 } 188 189 func TestOrderBookSimple_simpleNetworkSell(t *testing.T) { 190 market := "testMarket" 191 book := getTestOrderBook(t, market) 192 defer book.Finish() 193 order := types.Order{ 194 Status: types.OrderStatusActive, 195 MarketID: market, 196 Party: "A", 197 Side: types.SideSell, 198 Price: num.NewUint(100), 199 OriginalPrice: num.NewUint(100), 200 Size: 1, 201 Remaining: 1, 202 TimeInForce: types.OrderTimeInForceFOK, 203 Type: types.OrderTypeNetwork, 204 } 205 confirm, err := book.SubmitOrder(&order) 206 assert.NoError(t, err) 207 assert.Equal(t, 0, len(confirm.Trades)) 208 209 price, volume, err := book.BestBidPriceAndVolume() 210 assert.Error(t, err) 211 assert.Equal(t, uint64(0), price.Uint64()) 212 assert.Equal(t, uint64(0), volume) 213 assert.Equal(t, book.getNumberOfBuyLevels(), 0) 214 assert.Equal(t, book.getNumberOfSellLevels(), 0) 215 assert.Equal(t, book.getTotalBuyVolume(), uint64(0)) 216 assert.Equal(t, book.getTotalSellVolume(), uint64(0)) 217 assert.Equal(t, len(book.ordersByID), 0) 218 } 219 220 /* 221 * Now we test simple orders against a book with orders in. 222 */ 223 func TestOrderBookSimple_simpleLimitBuyFill(t *testing.T) { 224 market := "testMarket" 225 book := getTestOrderBook(t, market) 226 defer book.Finish() 227 order := types.Order{ 228 ID: "V0000000032-0000000009", 229 Status: types.OrderStatusActive, 230 MarketID: market, 231 Party: "A", 232 Side: types.SideBuy, 233 Price: num.NewUint(100), 234 OriginalPrice: num.NewUint(100), 235 Size: 10, 236 Remaining: 10, 237 TimeInForce: types.OrderTimeInForceGTC, 238 Type: types.OrderTypeLimit, 239 } 240 confirm, err := book.SubmitOrder(&order) 241 assert.NoError(t, err) 242 assert.Equal(t, 0, len(confirm.Trades)) 243 244 order2 := types.Order{ 245 ID: "V0000000032-0000000010", 246 Status: types.OrderStatusActive, 247 MarketID: market, 248 Party: "B", 249 Side: types.SideSell, 250 Price: num.NewUint(100), 251 OriginalPrice: num.NewUint(100), 252 Size: 10, 253 Remaining: 10, 254 TimeInForce: types.OrderTimeInForceGTC, 255 Type: types.OrderTypeLimit, 256 } 257 confirm, err = book.SubmitOrder(&order2) 258 assert.NoError(t, err) 259 assert.Equal(t, 1, len(confirm.Trades)) 260 261 price, volume, err := book.BestBidPriceAndVolume() 262 assert.Error(t, err) 263 assert.Equal(t, uint64(0), price.Uint64()) 264 assert.Equal(t, uint64(0), volume) 265 assert.Equal(t, book.getNumberOfBuyLevels(), 0) 266 assert.Equal(t, book.getNumberOfSellLevels(), 0) 267 assert.Equal(t, book.getTotalBuyVolume(), uint64(0)) 268 assert.Equal(t, book.getTotalSellVolume(), uint64(0)) 269 assert.Equal(t, len(book.ordersByID), 0) 270 } 271 272 func TestOrderBookSimple_simpleLimitSellFill(t *testing.T) { 273 market := "testMarket" 274 book := getTestOrderBook(t, market) 275 defer book.Finish() 276 order := types.Order{ 277 ID: "V0000000032-0000000009", 278 Status: types.OrderStatusActive, 279 MarketID: market, 280 Party: "A", 281 Side: types.SideSell, 282 Price: num.NewUint(100), 283 OriginalPrice: num.NewUint(100), 284 Size: 10, 285 Remaining: 10, 286 TimeInForce: types.OrderTimeInForceGTC, 287 Type: types.OrderTypeLimit, 288 } 289 confirm, err := book.SubmitOrder(&order) 290 assert.NoError(t, err) 291 assert.Equal(t, 0, len(confirm.Trades)) 292 293 order2 := types.Order{ 294 ID: "V0000000032-0000000010", 295 Status: types.OrderStatusActive, 296 MarketID: market, 297 Party: "B", 298 Side: types.SideBuy, 299 Price: num.NewUint(100), 300 OriginalPrice: num.NewUint(100), 301 Size: 10, 302 Remaining: 10, 303 TimeInForce: types.OrderTimeInForceGTC, 304 Type: types.OrderTypeLimit, 305 } 306 confirm, err = book.SubmitOrder(&order2) 307 assert.NoError(t, err) 308 assert.Equal(t, 1, len(confirm.Trades)) 309 310 price, volume, err := book.BestBidPriceAndVolume() 311 assert.Error(t, err) 312 assert.Equal(t, uint64(0), price.Uint64()) 313 assert.Equal(t, uint64(0), volume) 314 assert.Equal(t, book.getNumberOfBuyLevels(), 0) 315 assert.Equal(t, book.getNumberOfSellLevels(), 0) 316 assert.Equal(t, book.getTotalBuyVolume(), uint64(0)) 317 assert.Equal(t, book.getTotalSellVolume(), uint64(0)) 318 assert.Equal(t, len(book.ordersByID), 0) 319 } 320 321 func TestOrderBookSimple_simpleMarketBuyFill(t *testing.T) { 322 market := "testMarket" 323 book := getTestOrderBook(t, market) 324 defer book.Finish() 325 order := types.Order{ 326 ID: "V0000000032-0000000009", 327 Status: types.OrderStatusActive, 328 MarketID: market, 329 Party: "A", 330 Side: types.SideSell, 331 Price: num.NewUint(100), 332 OriginalPrice: num.NewUint(100), 333 Size: 10, 334 Remaining: 10, 335 TimeInForce: types.OrderTimeInForceGTC, 336 Type: types.OrderTypeLimit, 337 } 338 confirm, err := book.SubmitOrder(&order) 339 assert.NoError(t, err) 340 assert.Equal(t, 0, len(confirm.Trades)) 341 342 order2 := types.Order{ 343 ID: "V0000000032-0000000010", 344 Status: types.OrderStatusActive, 345 MarketID: market, 346 Party: "B", 347 Side: types.SideBuy, 348 Price: num.NewUint(100), 349 OriginalPrice: num.NewUint(100), 350 Size: 10, 351 Remaining: 10, 352 TimeInForce: types.OrderTimeInForceIOC, 353 Type: types.OrderTypeMarket, 354 } 355 confirm, err = book.SubmitOrder(&order2) 356 assert.NoError(t, err) 357 assert.Equal(t, 1, len(confirm.Trades)) 358 359 price, volume, err := book.BestBidPriceAndVolume() 360 assert.Error(t, err) 361 assert.Equal(t, uint64(0), price.Uint64()) 362 assert.Equal(t, uint64(0), volume) 363 assert.Equal(t, book.getNumberOfBuyLevels(), 0) 364 assert.Equal(t, book.getNumberOfSellLevels(), 0) 365 assert.Equal(t, book.getTotalBuyVolume(), uint64(0)) 366 assert.Equal(t, book.getTotalSellVolume(), uint64(0)) 367 assert.Equal(t, len(book.ordersByID), 0) 368 } 369 370 func TestOrderBookSimple_simpleMarketSellFill(t *testing.T) { 371 market := "testMarket" 372 book := getTestOrderBook(t, market) 373 defer book.Finish() 374 order := types.Order{ 375 ID: "V0000000032-0000000009", 376 Status: types.OrderStatusActive, 377 MarketID: market, 378 Party: "A", 379 Side: types.SideBuy, 380 Price: num.NewUint(100), 381 OriginalPrice: num.NewUint(100), 382 Size: 10, 383 Remaining: 10, 384 TimeInForce: types.OrderTimeInForceGTC, 385 Type: types.OrderTypeLimit, 386 } 387 confirm, err := book.SubmitOrder(&order) 388 assert.NoError(t, err) 389 assert.Equal(t, 0, len(confirm.Trades)) 390 391 order2 := types.Order{ 392 ID: "V0000000032-0000000010", 393 Status: types.OrderStatusActive, 394 MarketID: market, 395 Party: "B", 396 Side: types.SideSell, 397 Price: num.NewUint(100), 398 OriginalPrice: num.NewUint(100), 399 Size: 10, 400 Remaining: 10, 401 TimeInForce: types.OrderTimeInForceIOC, 402 Type: types.OrderTypeMarket, 403 } 404 confirm, err = book.SubmitOrder(&order2) 405 assert.NoError(t, err) 406 assert.Equal(t, 1, len(confirm.Trades)) 407 408 price, volume, err := book.BestBidPriceAndVolume() 409 assert.Error(t, err) 410 assert.Equal(t, uint64(0), price.Uint64()) 411 assert.Equal(t, uint64(0), volume) 412 assert.Equal(t, book.getNumberOfBuyLevels(), 0) 413 assert.Equal(t, book.getNumberOfSellLevels(), 0) 414 assert.Equal(t, book.getTotalBuyVolume(), uint64(0)) 415 assert.Equal(t, book.getTotalSellVolume(), uint64(0)) 416 assert.Equal(t, len(book.ordersByID), 0) 417 } 418 419 func TestOrderBookSimple_simpleNetworkBuyFill(t *testing.T) { 420 market := "testMarket" 421 book := getTestOrderBook(t, market) 422 defer book.Finish() 423 order := types.Order{ 424 ID: "V0000000032-0000000009", 425 Status: types.OrderStatusActive, 426 MarketID: market, 427 Party: "A", 428 Side: types.SideSell, 429 Price: num.NewUint(100), 430 OriginalPrice: num.NewUint(100), 431 Size: 10, 432 Remaining: 10, 433 TimeInForce: types.OrderTimeInForceGTC, 434 Type: types.OrderTypeLimit, 435 } 436 confirm, err := book.SubmitOrder(&order) 437 assert.NoError(t, err) 438 assert.Equal(t, 0, len(confirm.Trades)) 439 440 order2 := types.Order{ 441 ID: "V0000000032-0000000010", 442 Status: types.OrderStatusActive, 443 MarketID: market, 444 Party: "B", 445 Side: types.SideBuy, 446 Price: num.NewUint(100), 447 OriginalPrice: num.NewUint(100), 448 Size: 10, 449 Remaining: 10, 450 TimeInForce: types.OrderTimeInForceFOK, 451 Type: types.OrderTypeNetwork, 452 } 453 confirm, err = book.SubmitOrder(&order2) 454 assert.NoError(t, err) 455 assert.Equal(t, 1, len(confirm.Trades)) 456 457 price, volume, err := book.BestBidPriceAndVolume() 458 assert.Error(t, err) 459 assert.Equal(t, uint64(0), price.Uint64()) 460 assert.Equal(t, uint64(0), volume) 461 assert.Equal(t, book.getNumberOfBuyLevels(), 0) 462 assert.Equal(t, book.getNumberOfSellLevels(), 0) 463 assert.Equal(t, book.getTotalBuyVolume(), uint64(0)) 464 assert.Equal(t, book.getTotalSellVolume(), uint64(0)) 465 assert.Equal(t, len(book.ordersByID), 0) 466 } 467 468 func TestOrderBookSimple_simpleNetworkSellFill(t *testing.T) { 469 market := "testMarket" 470 book := getTestOrderBook(t, market) 471 defer book.Finish() 472 order := types.Order{ 473 ID: "V0000000032-0000000009", 474 Status: types.OrderStatusActive, 475 MarketID: market, 476 Party: "A", 477 Side: types.SideBuy, 478 Price: num.NewUint(100), 479 OriginalPrice: num.NewUint(100), 480 Size: 10, 481 Remaining: 10, 482 TimeInForce: types.OrderTimeInForceGTC, 483 Type: types.OrderTypeLimit, 484 } 485 confirm, err := book.SubmitOrder(&order) 486 assert.NoError(t, err) 487 assert.Equal(t, 0, len(confirm.Trades)) 488 489 order2 := types.Order{ 490 ID: "V0000000032-0000000010", 491 Status: types.OrderStatusActive, 492 MarketID: market, 493 Party: "B", 494 Side: types.SideSell, 495 Price: num.NewUint(100), 496 OriginalPrice: num.NewUint(100), 497 Size: 10, 498 Remaining: 10, 499 TimeInForce: types.OrderTimeInForceFOK, 500 Type: types.OrderTypeNetwork, 501 } 502 confirm, err = book.SubmitOrder(&order2) 503 assert.NoError(t, err) 504 assert.Equal(t, 1, len(confirm.Trades)) 505 506 price, volume, err := book.BestBidPriceAndVolume() 507 assert.Error(t, err) 508 assert.Equal(t, uint64(0), price.Uint64()) 509 assert.Equal(t, uint64(0), volume) 510 assert.Equal(t, book.getNumberOfBuyLevels(), 0) 511 assert.Equal(t, book.getNumberOfSellLevels(), 0) 512 assert.Equal(t, book.getTotalBuyVolume(), uint64(0)) 513 assert.Equal(t, book.getTotalSellVolume(), uint64(0)) 514 assert.Equal(t, len(book.ordersByID), 0) 515 } 516 517 func TestOrderBookSimple_FillAgainstGTTOrder(t *testing.T) { 518 market := "testMarket" 519 book := getTestOrderBook(t, market) 520 defer book.Finish() 521 order := types.Order{ 522 ID: "V0000000032-0000000009", 523 Status: types.OrderStatusActive, 524 MarketID: market, 525 Party: "A", 526 Side: types.SideBuy, 527 Price: num.NewUint(100), 528 OriginalPrice: num.NewUint(100), 529 Size: 10, 530 Remaining: 10, 531 TimeInForce: types.OrderTimeInForceGTT, 532 Type: types.OrderTypeLimit, 533 ExpiresAt: 10, 534 } 535 confirm, err := book.SubmitOrder(&order) 536 assert.NoError(t, err) 537 assert.Equal(t, 0, len(confirm.Trades)) 538 539 order2 := types.Order{ 540 ID: "V0000000032-0000000010", 541 Status: types.OrderStatusActive, 542 MarketID: market, 543 Party: "B", 544 Side: types.SideSell, 545 Price: num.NewUint(100), 546 OriginalPrice: num.NewUint(100), 547 Size: 10, 548 Remaining: 10, 549 TimeInForce: types.OrderTimeInForceFOK, 550 Type: types.OrderTypeNetwork, 551 } 552 confirm, err = book.SubmitOrder(&order2) 553 assert.NoError(t, err) 554 assert.Equal(t, 1, len(confirm.Trades)) 555 556 price, volume, err := book.BestBidPriceAndVolume() 557 assert.Error(t, err) 558 assert.Equal(t, uint64(0), price.Uint64()) 559 assert.Equal(t, uint64(0), volume) 560 assert.Equal(t, book.getNumberOfBuyLevels(), 0) 561 assert.Equal(t, book.getNumberOfSellLevels(), 0) 562 assert.Equal(t, book.getTotalBuyVolume(), uint64(0)) 563 assert.Equal(t, book.getTotalSellVolume(), uint64(0)) 564 assert.Equal(t, len(book.ordersByID), 0) 565 } 566 567 func TestOrderBookSimple_simpleWashTrade(t *testing.T) { 568 market := "testMarket" 569 book := getTestOrderBook(t, market) 570 defer book.Finish() 571 order := types.Order{ 572 ID: "V0000000032-0000000009", 573 Status: types.OrderStatusActive, 574 MarketID: market, 575 Party: "A", 576 Side: types.SideSell, 577 Price: num.NewUint(100), 578 OriginalPrice: num.NewUint(100), 579 Size: 10, 580 Remaining: 10, 581 TimeInForce: types.OrderTimeInForceGTC, 582 Type: types.OrderTypeLimit, 583 } 584 confirm, err := book.SubmitOrder(&order) 585 assert.NoError(t, err) 586 assert.Equal(t, 0, len(confirm.Trades)) 587 588 order2 := types.Order{ 589 ID: "V0000000032-0000000010", 590 Status: types.OrderStatusActive, 591 MarketID: market, 592 Party: "A", 593 Side: types.SideBuy, 594 Price: num.NewUint(100), 595 OriginalPrice: num.NewUint(100), 596 Size: 10, 597 Remaining: 10, 598 TimeInForce: types.OrderTimeInForceGTC, 599 Type: types.OrderTypeLimit, 600 } 601 confirm, err = book.SubmitOrder(&order2) 602 assert.NoError(t, err) 603 assert.Equal(t, 0, len(confirm.Trades)) 604 assert.Equal(t, order2.Status, types.OrderStatusStopped) 605 } 606 607 func TestOrderBookSimple_simpleWashTradePartiallyFilledThenStopped(t *testing.T) { 608 market := "testMarket" 609 book := getTestOrderBook(t, market) 610 defer book.Finish() 611 order := types.Order{ 612 ID: "V0000000032-0000000009", 613 Status: types.OrderStatusActive, 614 MarketID: market, 615 Party: "B", 616 Side: types.SideSell, 617 Price: num.NewUint(100), 618 OriginalPrice: num.NewUint(100), 619 Size: 1, 620 Remaining: 1, 621 TimeInForce: types.OrderTimeInForceGTC, 622 Type: types.OrderTypeLimit, 623 } 624 confirm, err := book.SubmitOrder(&order) 625 assert.NoError(t, err) 626 assert.Equal(t, 0, len(confirm.Trades)) 627 628 order1 := types.Order{ 629 ID: "V0000000032-0000000010", 630 Status: types.OrderStatusActive, 631 MarketID: market, 632 Party: "A", 633 Side: types.SideSell, 634 Price: num.NewUint(100), 635 OriginalPrice: num.NewUint(100), 636 Size: 1, 637 Remaining: 1, 638 TimeInForce: types.OrderTimeInForceGTC, 639 Type: types.OrderTypeLimit, 640 } 641 confirm, err = book.SubmitOrder(&order1) 642 assert.NoError(t, err) 643 assert.Equal(t, 0, len(confirm.Trades)) 644 645 order2 := types.Order{ 646 ID: "V0000000032-0000000011", 647 Status: types.OrderStatusActive, 648 MarketID: market, 649 Party: "A", 650 Side: types.SideBuy, 651 Price: num.NewUint(100), 652 OriginalPrice: num.NewUint(100), 653 Size: 2, 654 Remaining: 2, 655 TimeInForce: types.OrderTimeInForceGTC, 656 Type: types.OrderTypeLimit, 657 } 658 659 confirm, err = book.SubmitOrder(&order2) 660 assert.NoError(t, err) 661 assert.Equal(t, 1, len(confirm.Trades)) 662 assert.Equal(t, order2.Status, types.OrderStatusPartiallyFilled) 663 assert.Equal(t, int(order2.Remaining), 1) 664 } 665 666 func TestOrderBookSimple_simpleWashTradePartiallyFilledThenStoppedDifferentPrices(t *testing.T) { 667 market := "testMarket" 668 book := getTestOrderBook(t, market) 669 defer book.Finish() 670 order := types.Order{ 671 ID: "V0000000032-0000000009", 672 Status: types.OrderStatusActive, 673 MarketID: market, 674 Party: "B", 675 Side: types.SideSell, 676 Price: num.NewUint(1), 677 OriginalPrice: num.NewUint(1), 678 Size: 1, 679 Remaining: 1, 680 TimeInForce: types.OrderTimeInForceGTC, 681 Type: types.OrderTypeLimit, 682 } 683 confirm, err := book.SubmitOrder(&order) 684 assert.NoError(t, err) 685 assert.Equal(t, 0, len(confirm.Trades)) 686 687 order1 := types.Order{ 688 ID: "V0000000032-0000000010", 689 Status: types.OrderStatusActive, 690 MarketID: market, 691 Party: "A", 692 Side: types.SideSell, 693 Price: num.NewUint(2), 694 OriginalPrice: num.NewUint(2), 695 Size: 1, 696 Remaining: 1, 697 TimeInForce: types.OrderTimeInForceGTC, 698 Type: types.OrderTypeLimit, 699 } 700 confirm, err = book.SubmitOrder(&order1) 701 assert.NoError(t, err) 702 assert.Equal(t, 0, len(confirm.Trades)) 703 704 order2 := types.Order{ 705 ID: "V0000000032-0000000011", 706 Status: types.OrderStatusActive, 707 MarketID: market, 708 Party: "A", 709 Side: types.SideBuy, 710 Price: num.NewUint(100), 711 OriginalPrice: num.NewUint(100), 712 Size: 2, 713 Remaining: 2, 714 TimeInForce: types.OrderTimeInForceGTC, 715 Type: types.OrderTypeLimit, 716 } 717 718 confirm, err = book.SubmitOrder(&order2) 719 assert.NoError(t, err) 720 assert.Equal(t, 1, len(confirm.Trades)) 721 assert.Equal(t, order2.Status, types.OrderStatusPartiallyFilled) 722 assert.Equal(t, int(order2.Remaining), 1) 723 } 724 725 type MarketPos struct { 726 size, buy, sell int64 727 party string 728 price *num.Uint 729 buySumProduct, sellSumProduct *num.Uint 730 } 731 732 func (m MarketPos) AverageEntryPrice() *num.Uint { 733 return num.UintZero() 734 } 735 736 func (m MarketPos) Party() string { 737 return m.party 738 } 739 740 func (m MarketPos) Size() int64 { 741 return m.size 742 } 743 744 func (m MarketPos) Buy() int64 { 745 return m.buy 746 } 747 748 func (m MarketPos) Sell() int64 { 749 return m.sell 750 } 751 752 func (m MarketPos) Price() *num.Uint { 753 if m.price != nil { 754 return m.price 755 } 756 return num.UintZero() 757 } 758 759 func (m MarketPos) BuySumProduct() *num.Uint { 760 if m.buySumProduct != nil { 761 return m.buySumProduct 762 } 763 return num.UintZero() 764 } 765 766 func (m MarketPos) SellSumProduct() *num.Uint { 767 if m.sellSumProduct != nil { 768 return m.sellSumProduct 769 } 770 return num.UintZero() 771 } 772 773 func (m MarketPos) VWBuy() *num.Uint { 774 if m.buySumProduct != nil && m.buy != 0 { 775 return num.UintZero().Div(m.buySumProduct.Clone(), num.NewUint(uint64(m.buy))) 776 } 777 return num.UintZero() 778 } 779 780 func (m MarketPos) VWSell() *num.Uint { 781 if m.sellSumProduct != nil && m.sell != 0 { 782 return num.UintZero().Div(m.sellSumProduct.Clone(), num.NewUint(uint64(m.sell))) 783 } 784 return num.UintZero() 785 } 786 787 func TestOrderBookSimple_CancelDistressedOrders(t *testing.T) { 788 market := "testMarket" 789 book := getTestOrderBook(t, market) 790 defer book.Finish() 791 792 order := types.Order{ 793 Status: types.OrderStatusActive, 794 MarketID: market, 795 Party: "A", 796 Side: types.SideBuy, 797 Price: num.NewUint(100), 798 OriginalPrice: num.NewUint(100), 799 Size: 10, 800 Remaining: 10, 801 TimeInForce: types.OrderTimeInForceGTT, 802 Type: types.OrderTypeLimit, 803 ExpiresAt: 10, 804 ID: vgcrypto.RandomHash(), 805 } 806 confirm, err := book.SubmitOrder(&order) 807 assert.NoError(t, err) 808 assert.Equal(t, 0, len(confirm.Trades)) 809 810 order2 := types.Order{ 811 Status: types.OrderStatusActive, 812 MarketID: market, 813 Party: "A", 814 Side: types.SideSell, 815 Price: num.NewUint(101), 816 OriginalPrice: num.NewUint(101), 817 Size: 10, 818 Remaining: 10, 819 TimeInForce: types.OrderTimeInForceGTC, 820 Type: types.OrderTypeLimit, 821 ID: vgcrypto.RandomHash(), 822 } 823 confirm, err = book.SubmitOrder(&order2) 824 assert.NoError(t, err) 825 assert.Equal(t, 0, len(confirm.Trades)) 826 827 assert.Equal(t, book.getNumberOfBuyLevels(), 1) 828 assert.Equal(t, book.getNumberOfSellLevels(), 1) 829 assert.Equal(t, book.getTotalBuyVolume(), uint64(10)) 830 assert.Equal(t, book.getTotalSellVolume(), uint64(10)) 831 assert.Equal(t, len(book.ordersByID), 2) 832 833 // Now create a structure to contain the details of distressed party "A" and send them to be cancelled. 834 parties := []events.MarketPosition{ 835 MarketPos{ 836 party: "A", 837 }, 838 } 839 orders, err := book.RemoveDistressedOrders(parties) 840 require.NoError(t, err) 841 assert.Equal(t, len(orders), 2) 842 assert.Equal(t, book.getNumberOfBuyLevels(), 0) 843 assert.Equal(t, book.getNumberOfSellLevels(), 0) 844 assert.Equal(t, book.getTotalBuyVolume(), uint64(0)) 845 assert.Equal(t, book.getTotalSellVolume(), uint64(0)) 846 assert.Equal(t, len(book.ordersByID), 0) 847 }