code.vegaprotocol.io/vega@v0.79.0/core/execution/stoporders/stop_orders_ext_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 stoporders
    17  
    18  import (
    19  	"code.vegaprotocol.io/vega/core/types"
    20  	"code.vegaprotocol.io/vega/libs/num"
    21  
    22  	"golang.org/x/exp/slices"
    23  )
    24  
    25  func (t *TrailingStopOrders) Len(direction types.StopOrderTriggerDirection) int {
    26  	switch direction {
    27  	case types.StopOrderTriggerDirectionFallsBelow:
    28  		return t.fallsBelow.Len()
    29  	case types.StopOrderTriggerDirectionRisesAbove:
    30  		return t.risesAbove.Len()
    31  	default:
    32  		panic("nope")
    33  	}
    34  }
    35  
    36  func (p *PricedStopOrders) Len(direction types.StopOrderTriggerDirection) int {
    37  	switch direction {
    38  	case types.StopOrderTriggerDirectionFallsBelow:
    39  		return p.fallsBelow.Len()
    40  	case types.StopOrderTriggerDirectionRisesAbove:
    41  		return p.risesAbove.Len()
    42  	default:
    43  		panic("nope")
    44  	}
    45  }
    46  
    47  func (p *PricedStopOrders) Exists(id string) (atPrice *num.Uint, exists bool) {
    48  	findFn := func(item *ordersAtPrice) bool {
    49  		for _, v := range item.orders {
    50  			if v == id {
    51  				atPrice = item.price.Clone()
    52  				exists = true
    53  				return false
    54  			}
    55  		}
    56  
    57  		return true
    58  	}
    59  
    60  	p.fallsBelow.Ascend(findFn)
    61  
    62  	if !exists {
    63  		p.risesAbove.Ascend(findFn)
    64  	}
    65  
    66  	return
    67  }
    68  
    69  func (p *TrailingStopOrders) Exists(id string) (atPrice *num.Uint, offset num.Decimal, exists bool) {
    70  	findFnOrder := func(item *ordersAtOffset) bool {
    71  		for _, v := range item.orders {
    72  			if v == id {
    73  				exists = true
    74  				offset = item.offset
    75  				return false
    76  			}
    77  		}
    78  
    79  		return true
    80  	}
    81  
    82  	findFn := func(item *offsetsAtPrice) bool {
    83  		item.offsets.Ascend(findFnOrder)
    84  		if exists {
    85  			atPrice = item.price.Clone()
    86  			return false
    87  		}
    88  
    89  		return true
    90  	}
    91  
    92  	p.fallsBelow.Ascend(findFn)
    93  
    94  	if !exists {
    95  		p.risesAbove.Ascend(findFn)
    96  	}
    97  
    98  	return
    99  }
   100  
   101  func (p *Pool) Len() int {
   102  	return len(p.orderToParty)
   103  }
   104  
   105  func (p *Pool) Trailing() *TrailingStopOrders {
   106  	return p.trailing
   107  }
   108  
   109  func (p *Pool) Priced() *PricedStopOrders {
   110  	return p.priced
   111  }
   112  
   113  func (p *PricedStopOrders) Equal(p2 *PricedStopOrders) bool {
   114  	fallsbelowOk, risesAboveOk := true, true
   115  
   116  	p.fallsBelow.Ascend(func(item *ordersAtPrice) bool {
   117  		item2, ok := p2.fallsBelow.Get(item)
   118  		if !ok {
   119  			fallsbelowOk = false
   120  			return fallsbelowOk
   121  		}
   122  
   123  		slices.Equal(item.orders, item2.orders)
   124  
   125  		return fallsbelowOk
   126  	})
   127  
   128  	p.risesAbove.Ascend(func(item *ordersAtPrice) bool {
   129  		item2, ok := p2.risesAbove.Get(item)
   130  		if !ok {
   131  			risesAboveOk = false
   132  			return risesAboveOk
   133  		}
   134  		slices.Equal(item.orders, item2.orders)
   135  
   136  		return risesAboveOk
   137  	})
   138  
   139  	return fallsbelowOk && risesAboveOk
   140  }
   141  
   142  func (p *TrailingStopOrders) Equal(p2 *TrailingStopOrders) bool {
   143  	fallsbelowOk, risesAboveOk := true, true
   144  
   145  	p.fallsBelow.Ascend(func(item *offsetsAtPrice) bool {
   146  		item2, ok := p2.fallsBelow.Get(item)
   147  		if !ok {
   148  			fallsbelowOk = false
   149  			return fallsbelowOk
   150  		}
   151  
   152  		item.offsets.Ascend(func(itemInner *ordersAtOffset) bool {
   153  			itemInner2, ok := item2.offsets.Get(itemInner)
   154  			if !ok {
   155  				fallsbelowOk = false
   156  				return fallsbelowOk
   157  			}
   158  			slices.Equal(itemInner.orders, itemInner2.orders)
   159  
   160  			return fallsbelowOk
   161  		})
   162  
   163  		return fallsbelowOk
   164  	})
   165  
   166  	p.risesAbove.Ascend(func(item *offsetsAtPrice) bool {
   167  		item2, ok := p2.risesAbove.Get(item)
   168  		if !ok {
   169  			fallsbelowOk = false
   170  			return fallsbelowOk
   171  		}
   172  
   173  		item.offsets.Ascend(func(itemInner *ordersAtOffset) bool {
   174  			itemInner2, ok := item2.offsets.Get(itemInner)
   175  			if !ok {
   176  				risesAboveOk = false
   177  				return risesAboveOk
   178  			}
   179  			slices.Equal(itemInner.orders, itemInner2.orders)
   180  
   181  			return risesAboveOk
   182  		})
   183  
   184  		return risesAboveOk
   185  	})
   186  
   187  	return fallsbelowOk && risesAboveOk
   188  }
   189  
   190  func (p *Pool) Equal(p2 *Pool) bool {
   191  	if !p.trailing.lastSeenPrice.EQ(p2.trailing.lastSeenPrice) {
   192  		return false
   193  	}
   194  
   195  	for k, v := range p.orderToParty {
   196  		if v2, ok := p2.orderToParty[k]; !ok {
   197  			return false
   198  		} else if v2 != v {
   199  			return false
   200  		}
   201  	}
   202  
   203  	for k, v2 := range p2.orderToParty {
   204  		if v, ok := p.orderToParty[k]; !ok {
   205  			return false
   206  		} else if v2 != v {
   207  			return false
   208  		}
   209  	}
   210  
   211  	for partyId, orders := range p.orders {
   212  		other, ok := p2.orders[partyId]
   213  		if !ok {
   214  			return false
   215  		}
   216  
   217  		for orderId, order := range orders {
   218  			otherOrder, ok := other[orderId]
   219  			if !ok {
   220  				return false
   221  			}
   222  
   223  			if otherOrder.ID != order.ID {
   224  				return false
   225  			}
   226  		}
   227  	}
   228  
   229  	for partyId, orders := range p2.orders {
   230  		other, ok := p.orders[partyId]
   231  		if !ok {
   232  			return false
   233  		}
   234  
   235  		for orderId, order := range orders {
   236  			otherOrder, ok := other[orderId]
   237  			if !ok {
   238  				return false
   239  			}
   240  
   241  			if otherOrder.ID != order.ID {
   242  				return false
   243  			}
   244  		}
   245  	}
   246  
   247  	return p.priced.Equal(p2.priced) && p2.priced.Equal(p.priced) && p.trailing.Equal(p2.trailing) && p2.trailing.Equal(p.trailing)
   248  }