code.vegaprotocol.io/vega@v0.79.0/datanode/service/market_depth_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 service_test
    17  
    18  import (
    19  	"context"
    20  	"testing"
    21  	"time"
    22  
    23  	"code.vegaprotocol.io/vega/core/types"
    24  	"code.vegaprotocol.io/vega/datanode/entities"
    25  	"code.vegaprotocol.io/vega/datanode/service"
    26  	"code.vegaprotocol.io/vega/datanode/service/mocks"
    27  	"code.vegaprotocol.io/vega/libs/num"
    28  	"code.vegaprotocol.io/vega/logging"
    29  
    30  	"github.com/golang/mock/gomock"
    31  	"github.com/shopspring/decimal"
    32  	"github.com/stretchr/testify/assert"
    33  	"github.com/stretchr/testify/require"
    34  )
    35  
    36  type MDS struct {
    37  	service    *service.MarketDepth
    38  	ctrl       *gomock.Controller
    39  	pos        *mocks.MockPositionStore
    40  	amm        *mocks.MockAMMStore
    41  	orders     *mocks.MockOrderStore
    42  	marketData *mocks.MockMarketDataStore
    43  	markets    *mocks.MockMarketStore
    44  	assets     *mocks.MockAssetStore
    45  }
    46  
    47  func getTestMDS(t *testing.T) *MDS {
    48  	t.Helper()
    49  	ctrl := gomock.NewController(t)
    50  	pos := mocks.NewMockPositionStore(ctrl)
    51  	orders := mocks.NewMockOrderStore(ctrl)
    52  	marketData := mocks.NewMockMarketDataStore(ctrl)
    53  	amm := mocks.NewMockAMMStore(ctrl)
    54  	markets := mocks.NewMockMarketStore(ctrl)
    55  
    56  	amm.EXPECT().ListActive(gomock.Any()).Return(nil, nil).AnyTimes()
    57  
    58  	return &MDS{
    59  		service:    service.NewMarketDepth(service.NewDefaultConfig().MarketDepth, orders, amm, marketData, pos, nil, markets, logging.NewTestLogger()),
    60  		ctrl:       ctrl,
    61  		pos:        pos,
    62  		amm:        amm,
    63  		orders:     orders,
    64  		marketData: marketData,
    65  		markets:    markets,
    66  	}
    67  }
    68  
    69  func buildOrder(id string, side types.Side, orderType types.OrderType, price uint64, size uint64, remaining uint64) *types.Order {
    70  	order := &types.Order{
    71  		ID:            id,
    72  		Side:          side,
    73  		Type:          orderType,
    74  		Price:         num.NewUint(price),
    75  		OriginalPrice: num.NewUint(price),
    76  		Size:          size,
    77  		Remaining:     remaining,
    78  		TimeInForce:   types.OrderTimeInForceGTC,
    79  		Status:        types.OrderStatusActive,
    80  		MarketID:      "M",
    81  	}
    82  	return order
    83  }
    84  
    85  func TestBuyPriceLevels(t *testing.T) {
    86  	mds := getTestMDS(t)
    87  	vegaTime := time.Now()
    88  
    89  	order1 := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 9, 9)
    90  	mds.service.AddOrder(order1, vegaTime, 1)
    91  
    92  	order2 := buildOrder("Order2", types.SideBuy, types.OrderTypeLimit, 102, 7, 7)
    93  	mds.service.AddOrder(order2, vegaTime, 2)
    94  
    95  	order3 := buildOrder("Order3", types.SideBuy, types.OrderTypeLimit, 101, 8, 8)
    96  	mds.service.AddOrder(order3, vegaTime, 3)
    97  
    98  	order4 := buildOrder("Order4", types.SideBuy, types.OrderTypeLimit, 99, 10, 10)
    99  	mds.service.AddOrder(order4, vegaTime, 4)
   100  
   101  	assert.Equal(t, 4, mds.service.GetBuyPriceLevels("M"))
   102  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   103  	assert.Equal(t, int64(4), mds.service.GetOrderCount("M"))
   104  
   105  	assert.Equal(t, uint64(7), mds.service.GetVolumeAtPrice("M", types.SideBuy, 102))
   106  	assert.Equal(t, uint64(1), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 102))
   107  
   108  	assert.Equal(t, uint64(8), mds.service.GetVolumeAtPrice("M", types.SideBuy, 101))
   109  	assert.Equal(t, uint64(1), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 101))
   110  
   111  	assert.Equal(t, uint64(9), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   112  	assert.Equal(t, uint64(1), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   113  
   114  	assert.Equal(t, uint64(10), mds.service.GetVolumeAtPrice("M", types.SideBuy, 99))
   115  	assert.Equal(t, uint64(1), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 99))
   116  }
   117  
   118  func TestSellPriceLevels(t *testing.T) {
   119  	mds := getTestMDS(t)
   120  	vegaTime := time.Now()
   121  
   122  	order1 := buildOrder("Order1", types.SideSell, types.OrderTypeLimit, 100, 9, 9)
   123  	mds.service.AddOrder(order1, vegaTime, 1)
   124  
   125  	order2 := buildOrder("Order2", types.SideSell, types.OrderTypeLimit, 102, 7, 7)
   126  	mds.service.AddOrder(order2, vegaTime, 2)
   127  
   128  	order3 := buildOrder("Order3", types.SideSell, types.OrderTypeLimit, 101, 8, 8)
   129  	mds.service.AddOrder(order3, vegaTime, 3)
   130  
   131  	order4 := buildOrder("Order4", types.SideSell, types.OrderTypeLimit, 99, 10, 10)
   132  	mds.service.AddOrder(order4, vegaTime, 4)
   133  
   134  	assert.Equal(t, 0, mds.service.GetBuyPriceLevels("M"))
   135  	assert.Equal(t, 4, mds.service.GetSellPriceLevels("M"))
   136  	assert.Equal(t, int64(4), mds.service.GetOrderCount("M"))
   137  
   138  	assert.Equal(t, uint64(7), mds.service.GetVolumeAtPrice("M", types.SideSell, 102))
   139  	assert.Equal(t, uint64(1), mds.service.GetOrderCountAtPrice("M", types.SideSell, 102))
   140  
   141  	assert.Equal(t, uint64(8), mds.service.GetVolumeAtPrice("M", types.SideSell, 101))
   142  	assert.Equal(t, uint64(1), mds.service.GetOrderCountAtPrice("M", types.SideSell, 101))
   143  
   144  	assert.Equal(t, uint64(9), mds.service.GetVolumeAtPrice("M", types.SideSell, 100))
   145  	assert.Equal(t, uint64(1), mds.service.GetOrderCountAtPrice("M", types.SideSell, 100))
   146  
   147  	assert.Equal(t, uint64(10), mds.service.GetVolumeAtPrice("M", types.SideSell, 99))
   148  	assert.Equal(t, uint64(1), mds.service.GetOrderCountAtPrice("M", types.SideSell, 99))
   149  }
   150  
   151  func TestAddOrderToEmptyBook(t *testing.T) {
   152  	mds := getTestMDS(t)
   153  	vegaTime := time.Now()
   154  
   155  	order := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   156  	mds.service.AddOrder(order, vegaTime, 1)
   157  
   158  	assert.Equal(t, 1, mds.service.GetBuyPriceLevels("M"))
   159  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   160  	assert.Equal(t, int64(1), mds.service.GetOrderCount("M"))
   161  
   162  	assert.Equal(t, uint64(10), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   163  	assert.Equal(t, uint64(1), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   164  }
   165  
   166  func TestCancelOrder(t *testing.T) {
   167  	mds := getTestMDS(t)
   168  	vegaTime := time.Now()
   169  
   170  	order := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   171  	mds.service.AddOrder(order, vegaTime, 1)
   172  
   173  	cancelorder := *order
   174  	cancelorder.Status = types.OrderStatusCancelled
   175  	mds.service.AddOrder(&cancelorder, vegaTime, 2)
   176  
   177  	assert.Equal(t, 0, mds.service.GetBuyPriceLevels("M"))
   178  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   179  	assert.Equal(t, int64(0), mds.service.GetOrderCount("M"))
   180  
   181  	assert.Equal(t, uint64(0), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   182  	assert.Equal(t, uint64(0), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   183  }
   184  
   185  func TestStoppedOrder(t *testing.T) {
   186  	mds := getTestMDS(t)
   187  	vegaTime := time.Now()
   188  
   189  	order := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   190  	mds.service.AddOrder(order, vegaTime, 1)
   191  
   192  	cancelorder := *order
   193  	cancelorder.Status = types.OrderStatusStopped
   194  	mds.service.AddOrder(&cancelorder, vegaTime, 2)
   195  
   196  	assert.Equal(t, 0, mds.service.GetBuyPriceLevels("M"))
   197  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   198  	assert.Equal(t, int64(0), mds.service.GetOrderCount("M"))
   199  
   200  	assert.Equal(t, uint64(0), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   201  	assert.Equal(t, uint64(0), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   202  }
   203  
   204  func TestExpiredOrder(t *testing.T) {
   205  	mds := getTestMDS(t)
   206  	vegaTime := time.Now()
   207  
   208  	order := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   209  	mds.service.AddOrder(order, vegaTime, 1)
   210  
   211  	cancelorder := *order
   212  	cancelorder.Status = types.OrderStatusExpired
   213  	mds.service.AddOrder(&cancelorder, vegaTime, 2)
   214  
   215  	assert.Equal(t, 0, mds.service.GetBuyPriceLevels("M"))
   216  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   217  	assert.Equal(t, int64(0), mds.service.GetOrderCount("M"))
   218  
   219  	assert.Equal(t, uint64(0), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   220  	assert.Equal(t, uint64(0), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   221  }
   222  
   223  func TestAmendOrderPrice(t *testing.T) {
   224  	mds := getTestMDS(t)
   225  	vegaTime := time.Now()
   226  
   227  	order := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   228  	order2 := buildOrder("Order2", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   229  
   230  	mds.service.AddOrder(order, vegaTime, 1)
   231  	mds.service.AddOrder(order2, vegaTime, 2)
   232  
   233  	// Amend the price to force a change in price level
   234  	amendorder := *order
   235  	amendorder.Price = num.NewUint(90)
   236  	amendorder.OriginalPrice = num.NewUint(90)
   237  	mds.service.AddOrder(&amendorder, vegaTime, 3)
   238  
   239  	assert.Equal(t, 2, mds.service.GetBuyPriceLevels("M"))
   240  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   241  	assert.Equal(t, int64(2), mds.service.GetOrderCount("M"))
   242  
   243  	assert.Equal(t, uint64(10), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   244  	assert.Equal(t, uint64(10), mds.service.GetVolumeAtPrice("M", types.SideBuy, 90))
   245  	assert.Equal(t, uint64(1), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   246  	assert.Equal(t, uint64(1), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 90))
   247  }
   248  
   249  func TestAmendOrderVolumeUp(t *testing.T) {
   250  	mds := getTestMDS(t)
   251  	vegaTime := time.Now()
   252  
   253  	order := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   254  	mds.service.AddOrder(order, vegaTime, 1)
   255  
   256  	amendorder := *order
   257  	amendorder.Size = 20
   258  	amendorder.Remaining = 20
   259  	mds.service.AddOrder(&amendorder, vegaTime, 2)
   260  
   261  	assert.Equal(t, 1, mds.service.GetBuyPriceLevels("M"))
   262  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   263  	assert.Equal(t, int64(1), mds.service.GetOrderCount("M"))
   264  
   265  	assert.Equal(t, uint64(20), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   266  	assert.Equal(t, uint64(1), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   267  }
   268  
   269  func TestAmendOrderVolumeDown(t *testing.T) {
   270  	mds := getTestMDS(t)
   271  	vegaTime := time.Now()
   272  
   273  	order := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   274  	mds.service.AddOrder(order, vegaTime, 1)
   275  
   276  	amendorder := *order
   277  	amendorder.Size = 5
   278  	amendorder.Remaining = 5
   279  	mds.service.AddOrder(&amendorder, vegaTime, 2)
   280  
   281  	assert.Equal(t, 1, mds.service.GetBuyPriceLevels("M"))
   282  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   283  	assert.Equal(t, int64(1), mds.service.GetOrderCount("M"))
   284  
   285  	assert.Equal(t, uint64(5), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   286  	assert.Equal(t, uint64(1), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   287  }
   288  
   289  func TestAmendOrderVolumeDownToZero(t *testing.T) {
   290  	mds := getTestMDS(t)
   291  	vegaTime := time.Now()
   292  
   293  	order := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   294  	mds.service.AddOrder(order, vegaTime, 1)
   295  
   296  	amendorder := *order
   297  	amendorder.Size = 0
   298  	amendorder.Remaining = 0
   299  	mds.service.AddOrder(&amendorder, vegaTime, 2)
   300  
   301  	assert.Equal(t, 0, mds.service.GetBuyPriceLevels("M"))
   302  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   303  	assert.Equal(t, int64(0), mds.service.GetOrderCount("M"))
   304  
   305  	assert.Equal(t, uint64(0), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   306  	assert.Equal(t, uint64(0), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   307  }
   308  
   309  func TestPartialFill(t *testing.T) {
   310  	mds := getTestMDS(t)
   311  	vegaTime := time.Now()
   312  
   313  	order := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   314  	mds.service.AddOrder(order, vegaTime, 1)
   315  
   316  	pforder := *order
   317  	pforder.Remaining = 5
   318  	mds.service.AddOrder(&pforder, vegaTime, 2)
   319  
   320  	assert.Equal(t, 1, mds.service.GetBuyPriceLevels("M"))
   321  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   322  	assert.Equal(t, int64(1), mds.service.GetOrderCount("M"))
   323  
   324  	assert.Equal(t, uint64(5), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   325  	assert.Equal(t, uint64(1), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   326  }
   327  
   328  func TestIOCPartialFill(t *testing.T) {
   329  	mds := getTestMDS(t)
   330  	vegaTime := time.Now()
   331  
   332  	order := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 5)
   333  	order.Status = types.OrderStatusPartiallyFilled
   334  	order.TimeInForce = types.OrderTimeInForceIOC
   335  	mds.service.AddOrder(order, vegaTime, 1)
   336  
   337  	assert.Equal(t, 0, mds.service.GetBuyPriceLevels("M"))
   338  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   339  	assert.Equal(t, int64(0), mds.service.GetOrderCount("M"))
   340  
   341  	assert.Equal(t, uint64(0), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   342  	assert.Equal(t, uint64(0), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   343  }
   344  
   345  func TestFullyFill(t *testing.T) {
   346  	mds := getTestMDS(t)
   347  	vegaTime := time.Now()
   348  
   349  	order := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   350  	mds.service.AddOrder(order, vegaTime, 1)
   351  
   352  	fforder := *order
   353  	fforder.Remaining = 0
   354  	fforder.Status = types.OrderStatusFilled
   355  	mds.service.AddOrder(&fforder, vegaTime, 2)
   356  
   357  	assert.Equal(t, 0, mds.service.GetBuyPriceLevels("M"))
   358  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   359  	assert.Equal(t, int64(0), mds.service.GetOrderCount("M"))
   360  
   361  	assert.Equal(t, uint64(0), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   362  	assert.Equal(t, uint64(0), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   363  }
   364  
   365  func TestMarketOrder(t *testing.T) {
   366  	mds := getTestMDS(t)
   367  	vegaTime := time.Now()
   368  
   369  	// market orders should not stay on the book
   370  	marketorder := buildOrder("Order1", types.SideBuy, types.OrderTypeMarket, 100, 10, 10)
   371  	mds.service.AddOrder(marketorder, vegaTime, 1)
   372  
   373  	assert.Equal(t, 0, mds.service.GetBuyPriceLevels("M"))
   374  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   375  	assert.Equal(t, int64(0), mds.service.GetOrderCount("M"))
   376  
   377  	assert.Equal(t, uint64(0), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   378  	assert.Equal(t, uint64(0), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   379  }
   380  
   381  func TestFOKOrder(t *testing.T) {
   382  	mds := getTestMDS(t)
   383  	vegaTime := time.Now()
   384  
   385  	// FOK orders do not stay on the book
   386  	fokorder := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   387  	fokorder.TimeInForce = types.OrderTimeInForceFOK
   388  	mds.service.AddOrder(fokorder, vegaTime, 1)
   389  
   390  	assert.Equal(t, 0, mds.service.GetBuyPriceLevels("M"))
   391  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   392  	assert.Equal(t, int64(0), mds.service.GetOrderCount("M"))
   393  
   394  	assert.Equal(t, uint64(0), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   395  	assert.Equal(t, uint64(0), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   396  }
   397  
   398  func TestIOCOrder(t *testing.T) {
   399  	mds := getTestMDS(t)
   400  	vegaTime := time.Now()
   401  
   402  	// IOC orders do not stay on the book
   403  	iocorder := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   404  	iocorder.TimeInForce = types.OrderTimeInForceIOC
   405  	mds.service.AddOrder(iocorder, vegaTime, 1)
   406  
   407  	assert.Equal(t, 0, mds.service.GetBuyPriceLevels("M"))
   408  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   409  	assert.Equal(t, int64(0), mds.service.GetOrderCount("M"))
   410  
   411  	assert.Equal(t, uint64(0), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   412  	assert.Equal(t, uint64(0), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   413  }
   414  
   415  func TestRejectedOrder(t *testing.T) {
   416  	mds := getTestMDS(t)
   417  	vegaTime := time.Now()
   418  
   419  	// Rejected orders should be ignored
   420  	order := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   421  	order.Status = types.OrderStatusRejected
   422  	mds.service.AddOrder(order, vegaTime, 1)
   423  
   424  	assert.Equal(t, 0, mds.service.GetBuyPriceLevels("M"))
   425  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   426  	assert.Equal(t, int64(0), mds.service.GetOrderCount("M"))
   427  
   428  	assert.Equal(t, uint64(0), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   429  	assert.Equal(t, uint64(0), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   430  }
   431  
   432  func TestInvalidOrder(t *testing.T) {
   433  	mds := getTestMDS(t)
   434  	vegaTime := time.Now()
   435  
   436  	// Invalid orders should be ignored
   437  	order := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   438  	order.Status = types.OrderStatusUnspecified
   439  	mds.service.AddOrder(order, vegaTime, 1)
   440  
   441  	assert.Equal(t, 0, mds.service.GetBuyPriceLevels("M"))
   442  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   443  	assert.Equal(t, int64(0), mds.service.GetOrderCount("M"))
   444  
   445  	assert.Equal(t, uint64(0), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   446  	assert.Equal(t, uint64(0), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   447  }
   448  
   449  func TestPartialMatchOrders(t *testing.T) {
   450  	mds := getTestMDS(t)
   451  	vegaTime := time.Now()
   452  
   453  	order1 := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   454  	order2 := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 8)
   455  	order3 := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 5)
   456  	order4 := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 1)
   457  
   458  	mds.service.AddOrder(order1, vegaTime, 1)
   459  	mds.service.AddOrder(order2, vegaTime, 2)
   460  	mds.service.AddOrder(order3, vegaTime, 3)
   461  	mds.service.AddOrder(order4, vegaTime, 4)
   462  
   463  	assert.Equal(t, 1, mds.service.GetBuyPriceLevels("M"))
   464  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   465  	assert.Equal(t, int64(1), mds.service.GetOrderCount("M"))
   466  
   467  	assert.Equal(t, uint64(1), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   468  	assert.Equal(t, uint64(1), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   469  }
   470  
   471  func TestFullyMatchOrders(t *testing.T) {
   472  	mds := getTestMDS(t)
   473  	vegaTime := time.Now()
   474  
   475  	order1 := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   476  	order2 := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 8)
   477  	order3 := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 5)
   478  	order4 := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 100, 10, 0)
   479  	order4.Status = types.OrderStatusFilled
   480  
   481  	mds.service.AddOrder(order1, vegaTime, 1)
   482  	mds.service.AddOrder(order2, vegaTime, 2)
   483  	mds.service.AddOrder(order3, vegaTime, 3)
   484  	mds.service.AddOrder(order4, vegaTime, 4)
   485  
   486  	assert.Equal(t, 0, mds.service.GetBuyPriceLevels("M"))
   487  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   488  	assert.Equal(t, int64(0), mds.service.GetOrderCount("M"))
   489  
   490  	assert.Equal(t, uint64(0), mds.service.GetVolumeAtPrice("M", types.SideBuy, 100))
   491  	assert.Equal(t, uint64(0), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 100))
   492  }
   493  
   494  func TestRemovingPriceLevels(t *testing.T) {
   495  	mds := getTestMDS(t)
   496  	vegaTime := time.Now()
   497  
   498  	order1 := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 101, 10, 10)
   499  	order2 := buildOrder("Order2", types.SideBuy, types.OrderTypeLimit, 100, 10, 10)
   500  	order3 := buildOrder("Order3", types.SideBuy, types.OrderTypeLimit, 102, 10, 10)
   501  	order4 := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 101, 10, 0)
   502  	order4.Status = types.OrderStatusFilled
   503  
   504  	mds.service.AddOrder(order1, vegaTime, 1)
   505  	mds.service.AddOrder(order2, vegaTime, 2)
   506  	mds.service.AddOrder(order3, vegaTime, 3)
   507  	mds.service.AddOrder(order4, vegaTime, 4)
   508  
   509  	assert.Equal(t, 2, mds.service.GetBuyPriceLevels("M"))
   510  	assert.Equal(t, 0, mds.service.GetSellPriceLevels("M"))
   511  	assert.Equal(t, int64(2), mds.service.GetOrderCount("M"))
   512  
   513  	assert.Equal(t, uint64(0), mds.service.GetVolumeAtPrice("M", types.SideBuy, 101))
   514  	assert.Equal(t, uint64(0), mds.service.GetOrderCountAtPrice("M", types.SideBuy, 101))
   515  }
   516  
   517  func TestMarketDepthFields(t *testing.T) {
   518  	mds := getTestMDS(t)
   519  	vegaTime := time.Now()
   520  
   521  	order1 := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 101, 10, 10)
   522  	mds.service.AddOrder(order1, vegaTime, 1)
   523  
   524  	md := mds.service.GetMarketDepth("M", 0)
   525  	assert.NotNil(t, md)
   526  
   527  	assert.Equal(t, "M", md.MarketId)
   528  	assert.Equal(t, 1, len(md.GetBuy()))
   529  
   530  	priceLevels := md.GetBuy()
   531  	pl := priceLevels[0]
   532  	assert.NotNil(t, pl)
   533  	assert.Equal(t, uint64(1), pl.NumberOfOrders)
   534  	assert.Equal(t, "101", pl.Price)
   535  	assert.Equal(t, uint64(10), pl.Volume)
   536  }
   537  
   538  func TestParkingOrder(t *testing.T) {
   539  	mds := getTestMDS(t)
   540  	vegaTime := time.Now()
   541  
   542  	// Create a valid and live pegged order
   543  	order1 := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 101, 10, 10)
   544  	order1.PeggedOrder = &types.PeggedOrder{Reference: types.PeggedReferenceBestBid, Offset: num.NewUint(1)}
   545  	mds.service.AddOrder(order1, vegaTime, 1)
   546  
   547  	// Park it
   548  	order2 := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 0, 10, 10)
   549  	order2.PeggedOrder = &types.PeggedOrder{Reference: types.PeggedReferenceBestBid, Offset: num.NewUint(1)}
   550  	order2.Status = types.OrderStatusParked
   551  	mds.service.AddOrder(order2, vegaTime, 2)
   552  
   553  	md := mds.service.GetMarketDepth("M", 0)
   554  	assert.NotNil(t, md)
   555  
   556  	assert.Equal(t, "M", md.MarketId)
   557  	assert.Equal(t, 0, len(md.GetBuy()))
   558  	assert.Equal(t, 0, len(md.GetSell()))
   559  
   560  	// Unpark it
   561  	order3 := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 101, 10, 10)
   562  	order3.PeggedOrder = &types.PeggedOrder{Reference: types.PeggedReferenceBestBid, Offset: num.NewUint(1)}
   563  	order3.Status = types.OrderStatusActive
   564  	mds.service.AddOrder(order3, vegaTime, 3)
   565  
   566  	md2 := mds.service.GetMarketDepth("M", 0)
   567  	assert.NotNil(t, md2)
   568  
   569  	assert.Equal(t, "M", md2.MarketId)
   570  	assert.Equal(t, 1, len(md2.GetBuy()))
   571  	assert.Equal(t, 0, len(md2.GetSell()))
   572  }
   573  
   574  func TestParkedOrder(t *testing.T) {
   575  	mds := getTestMDS(t)
   576  	vegaTime := time.Now()
   577  
   578  	// Create a parked pegged order which should not go on the depth book
   579  	order1 := buildOrder("Order1", types.SideBuy, types.OrderTypeLimit, 101, 10, 10)
   580  	order1.PeggedOrder = &types.PeggedOrder{Reference: types.PeggedReferenceBestBid, Offset: num.NewUint(1)}
   581  	order1.Status = types.OrderStatusParked
   582  	mds.service.AddOrder(order1, vegaTime, 1)
   583  
   584  	md := mds.service.GetMarketDepth("M", 0)
   585  	assert.NotNil(t, md)
   586  
   587  	assert.Equal(t, "M", md.MarketId)
   588  	assert.Equal(t, 0, len(md.GetBuy()))
   589  	assert.Equal(t, 0, len(md.GetSell()))
   590  }
   591  
   592  func TestParkedOrder2(t *testing.T) {
   593  	mds := getTestMDS(t)
   594  	vegaTime := time.Now()
   595  
   596  	// Create parked pegged order
   597  	order1 := buildOrder("Pegged1", types.SideBuy, types.OrderTypeLimit, 0, 10, 10)
   598  	order1.PeggedOrder = &types.PeggedOrder{Reference: types.PeggedReferenceBestBid, Offset: num.NewUint(1)}
   599  	order1.Status = types.OrderStatusParked
   600  	mds.service.AddOrder(order1, vegaTime, 1)
   601  
   602  	// Create normal order
   603  	order2 := buildOrder("Normal1", types.SideBuy, types.OrderTypeLimit, 100, 1, 1)
   604  	mds.service.AddOrder(order2, vegaTime, 2)
   605  
   606  	// Unpark pegged order
   607  	order3 := buildOrder("Pegged1", types.SideBuy, types.OrderTypeLimit, 99, 10, 10)
   608  	order3.PeggedOrder = &types.PeggedOrder{Reference: types.PeggedReferenceBestBid, Offset: num.NewUint(1)}
   609  	order3.Status = types.OrderStatusActive
   610  	mds.service.AddOrder(order3, vegaTime, 3)
   611  
   612  	// Cancel normal order
   613  	order4 := buildOrder("Normal1", types.SideBuy, types.OrderTypeLimit, 100, 1, 1)
   614  	order4.Status = types.OrderStatusCancelled
   615  	mds.service.AddOrder(order4, vegaTime, 4)
   616  
   617  	// Park pegged order
   618  	order5 := buildOrder("Pegged1", types.SideBuy, types.OrderTypeLimit, 99, 10, 10)
   619  	order5.PeggedOrder = &types.PeggedOrder{Reference: types.PeggedReferenceBestBid, Offset: num.NewUint(1)}
   620  	order5.Status = types.OrderStatusParked
   621  	mds.service.AddOrder(order5, vegaTime, 5)
   622  
   623  	// Create normal order
   624  	order6 := buildOrder("Normal2", types.SideBuy, types.OrderTypeLimit, 100, 1, 1)
   625  	mds.service.AddOrder(order6, vegaTime, 6)
   626  
   627  	// Unpark pegged order
   628  	order7 := buildOrder("Pegged1", types.SideBuy, types.OrderTypeLimit, 99, 10, 10)
   629  	order7.PeggedOrder = &types.PeggedOrder{Reference: types.PeggedReferenceBestBid, Offset: num.NewUint(1)}
   630  	order7.Status = types.OrderStatusActive
   631  	mds.service.AddOrder(order7, vegaTime, 7)
   632  
   633  	// Fill normal order
   634  	order8 := buildOrder("Normal2", types.SideBuy, types.OrderTypeLimit, 100, 1, 0)
   635  	order8.Status = types.OrderStatusFilled
   636  	mds.service.AddOrder(order8, vegaTime, 8)
   637  
   638  	// Create new matching order
   639  	order9 := buildOrder("Normal3", types.SideSell, types.OrderTypeLimit, 100, 1, 0)
   640  	order9.Status = types.OrderStatusFilled
   641  	mds.service.AddOrder(order9, vegaTime, 9)
   642  
   643  	// Park pegged order
   644  	order10 := buildOrder("Pegged1", types.SideBuy, types.OrderTypeLimit, 99, 10, 10)
   645  	order10.PeggedOrder = &types.PeggedOrder{Reference: types.PeggedReferenceBestBid, Offset: num.NewUint(1)}
   646  	order10.Status = types.OrderStatusParked
   647  	mds.service.AddOrder(order10, vegaTime, 10)
   648  
   649  	md := mds.service.GetMarketDepth("M", 0)
   650  	assert.NotNil(t, md)
   651  
   652  	assert.Equal(t, "M", md.MarketId)
   653  	assert.Equal(t, 0, len(md.GetBuy()))
   654  	assert.Equal(t, 0, len(md.GetSell()))
   655  }
   656  
   657  func TestInitFromSqlStore(t *testing.T) {
   658  	ctrl := gomock.NewController(t)
   659  
   660  	ctx := context.Background()
   661  
   662  	t.Run("Init from SQL Store when SQL Store is in use", func(t *testing.T) {
   663  		store := mocks.NewMockOrderStore(ctrl)
   664  		amm := mocks.NewMockAMMStore(ctrl)
   665  		amm.EXPECT().ListActive(gomock.Any()).Return(nil, nil).AnyTimes()
   666  		store.EXPECT().GetLiveOrders(gomock.Any()).Return([]entities.Order{
   667  			{
   668  				ID:              "22EEA97BF1D9067D7533D0E671FC97C22146CE6785B4B142EBDF53FF0ED73E25",
   669  				MarketID:        "2EBD1AF4C84D5E004FD2797FF268258BFA21A37A6D0BCE289FB21151ACEF0F36",
   670  				PartyID:         "FB0C9F50787E5E090591E6600DBBEB5A4771D5A0C9B1AE09BC673AB9F471D210",
   671  				Side:            2,
   672  				Price:           decimal.NewFromInt(1200),
   673  				Size:            5,
   674  				Remaining:       5,
   675  				TimeInForce:     1,
   676  				Type:            1,
   677  				Status:          1,
   678  				Reference:       "",
   679  				Reason:          0,
   680  				Version:         1,
   681  				PeggedOffset:    decimal.NewFromInt(0),
   682  				BatchID:         0,
   683  				PeggedReference: 0,
   684  				LpID:            nil,
   685  				CreatedAt:       time.Time{},
   686  				UpdatedAt:       time.Time{},
   687  				ExpiresAt:       time.Time{},
   688  				VegaTime:        time.Date(2022, 3, 8, 14, 14, 45, 762739000, time.UTC),
   689  				SeqNum:          32,
   690  			},
   691  			{
   692  				ID:              "0E6BFB468B1D57B6463B3A2D133DEA107A56B34CC641235469E834145DE55803",
   693  				MarketID:        "52D3FCF2EFC15518EDFA25154E909348A2D7F45903C72CD88CB32EFD747CA001",
   694  				PartyID:         "29FE22227631DE06D9FBBCF2450DEA492E685E5953AEF60A76A95D0DA156806D",
   695  				Side:            1,
   696  				Price:           decimal.NewFromInt(22),
   697  				Size:            26,
   698  				Remaining:       26,
   699  				TimeInForce:     1,
   700  				Type:            1,
   701  				Status:          1,
   702  				Reference:       "",
   703  				Reason:          0,
   704  				Version:         2,
   705  				PeggedOffset:    decimal.NewFromInt(0),
   706  				BatchID:         1,
   707  				PeggedReference: 0,
   708  				LpID:            nil,
   709  				CreatedAt:       time.Time{},
   710  				UpdatedAt:       time.Time{},
   711  				ExpiresAt:       time.Time{},
   712  				VegaTime:        time.Date(2022, 3, 8, 14, 11, 39, 901022000, time.UTC),
   713  				SeqNum:          32,
   714  			},
   715  			{
   716  				ID:              "D8DA96D3B61F1E745061F85D46CE4440E188F846BBD76F7475C7D8AF0E9AB971",
   717  				MarketID:        "2EBD1AF4C84D5E004FD2797FF268258BFA21A37A6D0BCE289FB21151ACEF0F36",
   718  				PartyID:         "5F9A129B40E17BA0A17272697E3D521356AFC20BB56BF68C9242097AAFF879BF",
   719  				Side:            1,
   720  				Price:           decimal.NewFromInt(900),
   721  				Size:            5,
   722  				Remaining:       5,
   723  				TimeInForce:     1,
   724  				Type:            1,
   725  				Status:          1,
   726  				Reference:       "",
   727  				Reason:          0,
   728  				Version:         1,
   729  				PeggedOffset:    decimal.NewFromInt(0),
   730  				BatchID:         0,
   731  				PeggedReference: 0,
   732  				LpID:            nil,
   733  				CreatedAt:       time.Time{},
   734  				UpdatedAt:       time.Time{},
   735  				ExpiresAt:       time.Time{},
   736  				VegaTime:        time.Date(2022, 3, 8, 14, 14, 45, 762739000, time.UTC),
   737  				SeqNum:          39,
   738  			},
   739  			{
   740  				ID:              "9CABDED74F357688E96AAD50353122F23C441CF6134BA1B31E4B75D5D5EB7B36",
   741  				MarketID:        "2EBD1AF4C84D5E004FD2797FF268258BFA21A37A6D0BCE289FB21151ACEF0F36",
   742  				PartyID:         "5F9A129B40E17BA0A17272697E3D521356AFC20BB56BF68C9242097AAFF879BF",
   743  				Side:            1,
   744  				Price:           decimal.NewFromInt(100),
   745  				Size:            1,
   746  				Remaining:       1,
   747  				TimeInForce:     1,
   748  				Type:            1,
   749  				Status:          1,
   750  				Reference:       "",
   751  				Reason:          0,
   752  				Version:         1,
   753  				PeggedOffset:    decimal.NewFromInt(0),
   754  				BatchID:         0,
   755  				PeggedReference: 0,
   756  				LpID:            nil,
   757  				CreatedAt:       time.Time{},
   758  				UpdatedAt:       time.Time{},
   759  				ExpiresAt:       time.Time{},
   760  				VegaTime:        time.Date(2022, 3, 8, 14, 14, 45, 762739000, time.UTC),
   761  				SeqNum:          43,
   762  			},
   763  			{
   764  				ID:              "4300A037014C7ACFFC1C371697BD7A0ECAE4A54FCC4BFCB8A43E6EF4140A4F64",
   765  				MarketID:        "2EBD1AF4C84D5E004FD2797FF268258BFA21A37A6D0BCE289FB21151ACEF0F36",
   766  				PartyID:         "FB0C9F50787E5E090591E6600DBBEB5A4771D5A0C9B1AE09BC673AB9F471D210",
   767  				Side:            2,
   768  				Price:           decimal.NewFromInt(100000),
   769  				Size:            1,
   770  				Remaining:       1,
   771  				TimeInForce:     1,
   772  				Type:            1,
   773  				Status:          1,
   774  				Reference:       "",
   775  				Reason:          0,
   776  				Version:         2,
   777  				PeggedOffset:    decimal.NewFromInt(0),
   778  				BatchID:         0,
   779  				PeggedReference: 0,
   780  				LpID:            nil,
   781  				CreatedAt:       time.Time{},
   782  				UpdatedAt:       time.Time{},
   783  				ExpiresAt:       time.Time{},
   784  				VegaTime:        time.Date(2022, 3, 8, 14, 14, 45, 762739000, time.UTC),
   785  				SeqNum:          53,
   786  			},
   787  			{
   788  				ID:              "F8062CA2F4EE26C6208881CFC9844F12BEE6AA0A087D155BE695AFF6FF00AB00",
   789  				MarketID:        "2EBD1AF4C84D5E004FD2797FF268258BFA21A37A6D0BCE289FB21151ACEF0F36",
   790  				PartyID:         "076E3373D4F4197731A3161D2F50CE286B93278BF2B650705691514DD49EFDA1",
   791  				Side:            2,
   792  				Price:           decimal.NewFromInt(1201),
   793  				Size:            1301,
   794  				Remaining:       1301,
   795  				TimeInForce:     1,
   796  				Type:            1,
   797  				Status:          1,
   798  				Reference:       "",
   799  				Reason:          0,
   800  				Version:         1,
   801  				PeggedOffset:    decimal.NewFromInt(0),
   802  				BatchID:         1,
   803  				PeggedReference: 0,
   804  				LpID:            nil,
   805  				CreatedAt:       time.Time{},
   806  				UpdatedAt:       time.Time{},
   807  				ExpiresAt:       time.Time{},
   808  				VegaTime:        time.Date(2022, 3, 8, 14, 14, 58, 985875000, time.UTC),
   809  				SeqNum:          61,
   810  			},
   811  			{
   812  				ID:              "15E8D38DD216C5EE969EC7B7A2EB031E56474A9552CC10E00036A7DC1C0546B5",
   813  				MarketID:        "2EBD1AF4C84D5E004FD2797FF268258BFA21A37A6D0BCE289FB21151ACEF0F36",
   814  				PartyID:         "076E3373D4F4197731A3161D2F50CE286B93278BF2B650705691514DD49EFDA1",
   815  				Side:            1,
   816  				Price:           decimal.NewFromInt(899),
   817  				Size:            1738,
   818  				Remaining:       1738,
   819  				TimeInForce:     1,
   820  				Type:            1,
   821  				Status:          1,
   822  				Reference:       "",
   823  				Reason:          0,
   824  				Version:         1,
   825  				PeggedOffset:    decimal.NewFromInt(0),
   826  				BatchID:         1,
   827  				PeggedReference: 0,
   828  				LpID:            nil,
   829  				CreatedAt:       time.Time{},
   830  				UpdatedAt:       time.Time{},
   831  				ExpiresAt:       time.Time{},
   832  				VegaTime:        time.Date(2022, 3, 8, 14, 14, 58, 985875000, time.UTC),
   833  				SeqNum:          66,
   834  			},
   835  		}, nil).Times(1)
   836  		svc := service.NewMarketDepth(service.NewDefaultConfig().MarketDepth, store, amm, nil, nil, nil, nil, logging.NewTestLogger())
   837  		require.NoError(t, svc.Initialise(ctx))
   838  	})
   839  }