code.vegaprotocol.io/vega@v0.79.0/core/matching/pricelevel_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  	"code.vegaprotocol.io/vega/logging"
    24  
    25  	"github.com/stretchr/testify/assert"
    26  )
    27  
    28  func TestGetPriceLevel(t *testing.T) {
    29  	side := &OrderBookSide{side: types.SideSell}
    30  	assert.Equal(t, 0, len(side.levels))
    31  	side.getPriceLevel(num.NewUint(100))
    32  	assert.Equal(t, 1, len(side.levels))
    33  
    34  	side.getPriceLevel(num.NewUint(110))
    35  	assert.Equal(t, 2, len(side.levels))
    36  
    37  	side.getPriceLevel(num.NewUint(100))
    38  	assert.Equal(t, 2, len(side.levels))
    39  }
    40  
    41  func TestAddAndRemoveOrdersToPriceLevel(t *testing.T) {
    42  	side := &OrderBookSide{side: types.SideSell}
    43  	l := side.getPriceLevel(num.NewUint(100))
    44  	order := &types.Order{
    45  		MarketID:      "testOrderBook",
    46  		Party:         "A",
    47  		Side:          types.SideSell,
    48  		Price:         num.NewUint(101),
    49  		OriginalPrice: num.NewUint(101),
    50  		Size:          100,
    51  		Remaining:     100,
    52  		TimeInForce:   types.OrderTimeInForceGTC,
    53  		CreatedAt:     0,
    54  	}
    55  
    56  	// add orders
    57  	assert.Equal(t, 0, len(l.orders))
    58  	l.addOrder(order)
    59  	assert.Equal(t, 1, len(l.orders))
    60  	l.addOrder(order)
    61  	assert.Equal(t, 2, len(l.orders))
    62  
    63  	// remove orders
    64  	l.removeOrder(1)
    65  	assert.Equal(t, 1, len(l.orders))
    66  	l.removeOrder(0)
    67  	assert.Equal(t, 0, len(l.orders))
    68  }
    69  
    70  func TestUncross(t *testing.T) {
    71  	logger := logging.NewTestLogger()
    72  	defer logger.Sync()
    73  
    74  	side := &OrderBookSide{side: types.SideSell}
    75  	l := side.getPriceLevel(num.NewUint(100))
    76  	passiveOrder := &types.Order{
    77  		MarketID:      "testOrderBook",
    78  		Party:         "A",
    79  		Side:          types.SideSell,
    80  		Price:         num.NewUint(101),
    81  		OriginalPrice: num.NewUint(101),
    82  		Size:          100,
    83  		Remaining:     100,
    84  		TimeInForce:   types.OrderTimeInForceGTC,
    85  		CreatedAt:     0,
    86  	}
    87  	l.addOrder(passiveOrder)
    88  
    89  	aggresiveOrder := &types.Order{
    90  		MarketID:      "testOrderBook",
    91  		Party:         "B",
    92  		Side:          types.SideBuy,
    93  		Price:         num.NewUint(101),
    94  		OriginalPrice: num.NewUint(101),
    95  		Size:          100,
    96  		Remaining:     100,
    97  		TimeInForce:   types.OrderTimeInForceGTC,
    98  		CreatedAt:     0,
    99  	}
   100  
   101  	order, fakeTrades, err := l.fakeUncross(aggresiveOrder, true)
   102  	assert.NoError(t, err)
   103  	assert.Equal(t, uint64(0), order.Remaining)
   104  
   105  	filled, trades, impactedOrders, err := l.uncross(aggresiveOrder, true)
   106  	assert.Equal(t, true, filled)
   107  	assert.Equal(t, 1, len(trades))
   108  	assert.Equal(t, 1, len(impactedOrders))
   109  	assert.NoError(t, err)
   110  
   111  	for i, tr := range trades {
   112  		assert.Equal(t, tr, fakeTrades[i])
   113  	}
   114  }
   115  
   116  func TestUncrossDecimals(t *testing.T) {
   117  	logger := logging.NewTestLogger()
   118  	defer logger.Sync()
   119  
   120  	side := &OrderBookSide{side: types.SideSell}
   121  	l := side.getPriceLevel(num.NewUint(100))
   122  	passiveOrder := &types.Order{
   123  		MarketID:      "testOrderBook",
   124  		Party:         "A",
   125  		Side:          types.SideSell,
   126  		Price:         num.NewUint(101),
   127  		OriginalPrice: num.NewUint(101000),
   128  		Size:          100,
   129  		Remaining:     100,
   130  		TimeInForce:   types.OrderTimeInForceGTC,
   131  		CreatedAt:     0,
   132  	}
   133  	l.addOrder(passiveOrder)
   134  
   135  	aggresiveOrder := &types.Order{
   136  		MarketID:      "testOrderBook",
   137  		Party:         "B",
   138  		Side:          types.SideBuy,
   139  		Price:         num.NewUint(101),
   140  		OriginalPrice: num.NewUint(101000),
   141  		Size:          100,
   142  		Remaining:     100,
   143  		TimeInForce:   types.OrderTimeInForceGTC,
   144  		CreatedAt:     0,
   145  	}
   146  
   147  	order, fakeTrades, err := l.fakeUncross(aggresiveOrder, true)
   148  	assert.NoError(t, err)
   149  	assert.Equal(t, uint64(0), order.Remaining)
   150  
   151  	filled, trades, impactedOrders, err := l.uncross(aggresiveOrder, true)
   152  	assert.Equal(t, true, filled)
   153  	assert.Equal(t, 1, len(trades))
   154  	assert.Equal(t, 1, len(impactedOrders))
   155  	assert.NoError(t, err)
   156  	// ensure the price fields are set correctly
   157  	assert.Equal(t, passiveOrder.OriginalPrice.String(), trades[0].MarketPrice.String())
   158  	assert.Equal(t, passiveOrder.Price.String(), trades[0].Price.String())
   159  
   160  	for i, tr := range trades {
   161  		assert.Equal(t, tr, fakeTrades[i])
   162  	}
   163  }