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  }