code.vegaprotocol.io/vega@v0.79.0/core/matching/closeoutprice_test.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package matching
    17  
    18  import (
    19  	"testing"
    20  
    21  	"code.vegaprotocol.io/vega/core/types"
    22  	"code.vegaprotocol.io/vega/libs/num"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  )
    26  
    27  func TestOrderBook_closeOutPriceBuy(t *testing.T) {
    28  	market := "testMarket"
    29  	book := getTestOrderBook(t, market)
    30  	defer book.Finish()
    31  
    32  	tradedOrder1 := types.Order{
    33  		MarketID:      market,
    34  		Party:         "A",
    35  		Side:          types.SideSell,
    36  		Price:         num.NewUint(100),
    37  		OriginalPrice: num.NewUint(100),
    38  		Size:          100,
    39  		Remaining:     100,
    40  		TimeInForce:   types.OrderTimeInForceGTC,
    41  		Type:          types.OrderTypeLimit,
    42  	}
    43  	confirm, err := book.SubmitOrder(&tradedOrder1)
    44  	assert.NoError(t, err)
    45  	assert.Equal(t, 0, len(confirm.Trades))
    46  
    47  	tradedOrder2 := types.Order{
    48  		MarketID:      market,
    49  		Party:         "B",
    50  		Side:          types.SideBuy,
    51  		Price:         num.NewUint(100),
    52  		OriginalPrice: num.NewUint(100),
    53  		Size:          100,
    54  		Remaining:     100,
    55  		TimeInForce:   types.OrderTimeInForceGTC,
    56  		Type:          types.OrderTypeLimit,
    57  	}
    58  	confirm, err = book.SubmitOrder(&tradedOrder2)
    59  	assert.NoError(t, err)
    60  	assert.Equal(t, 1, len(confirm.Trades))
    61  
    62  	order := types.Order{
    63  		MarketID:      market,
    64  		Party:         "A",
    65  		Side:          types.SideBuy,
    66  		Price:         num.NewUint(100),
    67  		OriginalPrice: num.NewUint(100),
    68  		Size:          100,
    69  		Remaining:     100,
    70  		TimeInForce:   types.OrderTimeInForceGTC,
    71  		Type:          types.OrderTypeLimit,
    72  	}
    73  	confirm, err = book.SubmitOrder(&order)
    74  	assert.NoError(t, err)
    75  	assert.Equal(t, 0, len(confirm.Trades))
    76  
    77  	// Normal case
    78  	price, err := book.GetFillPrice(10, types.SideBuy)
    79  	assert.NoError(t, err)
    80  	assert.Equal(t, price.Uint64(), uint64(100))
    81  
    82  	// Incorrect size
    83  	price, err = book.GetFillPrice(0, types.SideBuy)
    84  	assert.Error(t, err, ErrInvalidVolume)
    85  	assert.Equal(t, price.Uint64(), uint64(0))
    86  
    87  	// Not enough on the book
    88  	price, err = book.GetFillPrice(200, types.SideBuy)
    89  	assert.Error(t, err, ErrNotEnoughOrders)
    90  	assert.Equal(t, price.Uint64(), uint64(100))
    91  
    92  	// Wrong side
    93  	price, err = book.GetFillPrice(10, types.SideSell)
    94  	assert.Error(t, err, ErrNotEnoughOrders)
    95  	assert.Equal(t, price.Uint64(), uint64(100))
    96  }
    97  
    98  func TestOrderBook_closeOutPriceSell(t *testing.T) {
    99  	market := "testMarket"
   100  	book := getTestOrderBook(t, market)
   101  	defer book.Finish()
   102  
   103  	tradedOrder1 := types.Order{
   104  		MarketID:      market,
   105  		Party:         "A",
   106  		Side:          types.SideSell,
   107  		Price:         num.NewUint(100),
   108  		OriginalPrice: num.NewUint(100),
   109  		Size:          100,
   110  		Remaining:     100,
   111  		TimeInForce:   types.OrderTimeInForceGTC,
   112  		Type:          types.OrderTypeLimit,
   113  	}
   114  	confirm, err := book.SubmitOrder(&tradedOrder1)
   115  	assert.NoError(t, err)
   116  	assert.Equal(t, 0, len(confirm.Trades))
   117  
   118  	tradedOrder2 := types.Order{
   119  		MarketID:      market,
   120  		Party:         "B",
   121  		Side:          types.SideBuy,
   122  		Price:         num.NewUint(100),
   123  		OriginalPrice: num.NewUint(100),
   124  		Size:          100,
   125  		Remaining:     100,
   126  		TimeInForce:   types.OrderTimeInForceGTC,
   127  		Type:          types.OrderTypeLimit,
   128  	}
   129  	confirm, err = book.SubmitOrder(&tradedOrder2)
   130  	assert.NoError(t, err)
   131  	assert.Equal(t, 1, len(confirm.Trades))
   132  
   133  	untradedOrder := types.Order{
   134  		MarketID:      market,
   135  		Party:         "A",
   136  		Side:          types.SideSell,
   137  		Price:         num.NewUint(100),
   138  		OriginalPrice: num.NewUint(100),
   139  		Size:          100,
   140  		Remaining:     100,
   141  		TimeInForce:   types.OrderTimeInForceGTC,
   142  		Type:          types.OrderTypeLimit,
   143  	}
   144  	confirm, err = book.SubmitOrder(&untradedOrder)
   145  	assert.NoError(t, err)
   146  	assert.Equal(t, 0, len(confirm.Trades))
   147  
   148  	// Normal case
   149  	price, err := book.GetFillPrice(10, types.SideSell)
   150  	assert.NoError(t, err)
   151  	assert.Equal(t, price.Uint64(), uint64(100))
   152  
   153  	// Incorrect size
   154  	price, err = book.GetFillPrice(0, types.SideSell)
   155  	assert.Error(t, err, ErrInvalidVolume)
   156  	assert.Equal(t, price.Uint64(), uint64(0))
   157  
   158  	// Not enough on the book
   159  	price, err = book.GetFillPrice(200, types.SideSell)
   160  	assert.Error(t, err, ErrNotEnoughOrders)
   161  	assert.Equal(t, price.Uint64(), uint64(100))
   162  
   163  	// Wrong side
   164  	price, err = book.GetFillPrice(10, types.SideBuy)
   165  	assert.Error(t, err, ErrNotEnoughOrders)
   166  	assert.Equal(t, price.Uint64(), uint64(100))
   167  }
   168  
   169  func TestOrderBook_closeOutPriceBuy2(t *testing.T) {
   170  	market := "testMarket"
   171  	book := getTestOrderBook(t, market)
   172  	defer book.Finish()
   173  	order := types.Order{
   174  		MarketID:      market,
   175  		Party:         "A",
   176  		Side:          types.SideBuy,
   177  		Price:         num.NewUint(100),
   178  		OriginalPrice: num.NewUint(100),
   179  		Size:          100,
   180  		Remaining:     100,
   181  		TimeInForce:   types.OrderTimeInForceGTC,
   182  		Type:          types.OrderTypeLimit,
   183  	}
   184  	confirm, err := book.SubmitOrder(&order)
   185  	assert.NoError(t, err)
   186  	assert.Equal(t, 0, len(confirm.Trades))
   187  
   188  	order2 := types.Order{
   189  		MarketID:      market,
   190  		Party:         "A",
   191  		Side:          types.SideBuy,
   192  		Price:         num.NewUint(90),
   193  		OriginalPrice: num.NewUint(90),
   194  		Size:          100,
   195  		Remaining:     100,
   196  		TimeInForce:   types.OrderTimeInForceGTC,
   197  		Type:          types.OrderTypeLimit,
   198  	}
   199  	confirm, err = book.SubmitOrder(&order2)
   200  	assert.NoError(t, err)
   201  	assert.Equal(t, 0, len(confirm.Trades))
   202  
   203  	order3 := types.Order{
   204  		MarketID:      market,
   205  		Party:         "A",
   206  		Side:          types.SideBuy,
   207  		Price:         num.NewUint(80),
   208  		OriginalPrice: num.NewUint(80),
   209  		Size:          100,
   210  		Remaining:     100,
   211  		TimeInForce:   types.OrderTimeInForceGTC,
   212  		Type:          types.OrderTypeLimit,
   213  	}
   214  	confirm, err = book.SubmitOrder(&order3)
   215  	assert.NoError(t, err)
   216  	assert.Equal(t, 0, len(confirm.Trades))
   217  
   218  	// Normal case
   219  	price, err := book.GetFillPrice(100, types.SideBuy)
   220  	assert.NoError(t, err)
   221  	assert.Equal(t, price.Uint64(), uint64(100))
   222  
   223  	// Normal case
   224  	price, err = book.GetFillPrice(200, types.SideBuy)
   225  	assert.NoError(t, err)
   226  	assert.Equal(t, price.Uint64(), uint64(95))
   227  
   228  	// Normal case
   229  	price, err = book.GetFillPrice(300, types.SideBuy)
   230  	assert.NoError(t, err)
   231  	assert.Equal(t, price.Uint64(), uint64(90))
   232  }
   233  
   234  func TestOrderBook_closeOutPriceSell2(t *testing.T) {
   235  	market := "testMarket"
   236  	book := getTestOrderBook(t, market)
   237  	defer book.Finish()
   238  	order := types.Order{
   239  		MarketID:      market,
   240  		Party:         "A",
   241  		Side:          types.SideSell,
   242  		Price:         num.NewUint(100),
   243  		OriginalPrice: num.NewUint(100),
   244  		Size:          100,
   245  		Remaining:     100,
   246  		TimeInForce:   types.OrderTimeInForceGTC,
   247  		Type:          types.OrderTypeLimit,
   248  	}
   249  	confirm, err := book.SubmitOrder(&order)
   250  	assert.NoError(t, err)
   251  	assert.Equal(t, 0, len(confirm.Trades))
   252  
   253  	order2 := types.Order{
   254  		MarketID:      market,
   255  		Party:         "A",
   256  		Side:          types.SideSell,
   257  		Price:         num.NewUint(110),
   258  		OriginalPrice: num.NewUint(110),
   259  		Size:          100,
   260  		Remaining:     100,
   261  		TimeInForce:   types.OrderTimeInForceGTC,
   262  		Type:          types.OrderTypeLimit,
   263  	}
   264  	confirm, err = book.SubmitOrder(&order2)
   265  	assert.NoError(t, err)
   266  	assert.Equal(t, 0, len(confirm.Trades))
   267  
   268  	order3 := types.Order{
   269  		MarketID:      market,
   270  		Party:         "A",
   271  		Side:          types.SideSell,
   272  		Price:         num.NewUint(120),
   273  		OriginalPrice: num.NewUint(120),
   274  		Size:          100,
   275  		Remaining:     100,
   276  		TimeInForce:   types.OrderTimeInForceGTC,
   277  		Type:          types.OrderTypeLimit,
   278  	}
   279  	confirm, err = book.SubmitOrder(&order3)
   280  	assert.NoError(t, err)
   281  	assert.Equal(t, 0, len(confirm.Trades))
   282  
   283  	// Normal case
   284  	price, err := book.GetFillPrice(100, types.SideSell)
   285  	assert.NoError(t, err)
   286  	assert.Equal(t, price.Uint64(), uint64(100))
   287  
   288  	// Normal case
   289  	price, err = book.GetFillPrice(200, types.SideSell)
   290  	assert.NoError(t, err)
   291  	assert.Equal(t, price.Uint64(), uint64(105))
   292  
   293  	// Normal case
   294  	price, err = book.GetFillPrice(300, types.SideSell)
   295  	assert.NoError(t, err)
   296  	assert.Equal(t, price.Uint64(), uint64(110))
   297  }