code.vegaprotocol.io/vega@v0.79.0/commands/stop_order_submission_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 commands_test
    17  
    18  import (
    19  	"errors"
    20  	"testing"
    21  
    22  	"code.vegaprotocol.io/vega/commands"
    23  	"code.vegaprotocol.io/vega/libs/ptr"
    24  	"code.vegaprotocol.io/vega/protos/vega"
    25  	commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1"
    26  
    27  	"github.com/stretchr/testify/assert"
    28  )
    29  
    30  func TestCheckStopOrdersStubmission(t *testing.T) {
    31  	cases := []struct {
    32  		submission commandspb.StopOrdersSubmission
    33  		errStr     string
    34  	}{
    35  		{
    36  			submission: commandspb.StopOrdersSubmission{},
    37  			errStr:     "must have at least one of rises above or falls below",
    38  		},
    39  		{
    40  			submission: commandspb.StopOrdersSubmission{
    41  				RisesAbove: &commandspb.StopOrderSetup{},
    42  			},
    43  			errStr: "order_submission (is required), stop_orders_submission.rises_below.trigger (must have a stop order trigger)",
    44  		},
    45  		{
    46  			submission: commandspb.StopOrdersSubmission{
    47  				RisesAbove: &commandspb.StopOrderSetup{
    48  					Trigger: &commandspb.StopOrderSetup_Price{
    49  						Price: "",
    50  					},
    51  				},
    52  			},
    53  			errStr: "order_submission (is required), stop_orders_submission.rises_below.trigger.price (is required)",
    54  		},
    55  		{
    56  			submission: commandspb.StopOrdersSubmission{
    57  				RisesAbove: &commandspb.StopOrderSetup{
    58  					Trigger: &commandspb.StopOrderSetup_Price{
    59  						Price: "-1",
    60  					},
    61  				},
    62  			},
    63  			errStr: "order_submission (is required), stop_orders_submission.rises_below.trigger.price (must be positive)",
    64  		},
    65  		{
    66  			submission: commandspb.StopOrdersSubmission{
    67  				RisesAbove: &commandspb.StopOrderSetup{
    68  					Trigger: &commandspb.StopOrderSetup_Price{
    69  						Price: "asdsad",
    70  					},
    71  				},
    72  			},
    73  			errStr: "order_submission (is required), stop_orders_submission.rises_below.trigger.price (not a valid integer)",
    74  		},
    75  		{
    76  			submission: commandspb.StopOrdersSubmission{
    77  				RisesAbove: &commandspb.StopOrderSetup{
    78  					Trigger: &commandspb.StopOrderSetup_Price{
    79  						Price: "100",
    80  					},
    81  				},
    82  			},
    83  			errStr: "order_submission (is required)",
    84  		},
    85  		{
    86  			submission: commandspb.StopOrdersSubmission{
    87  				RisesAbove: &commandspb.StopOrderSetup{
    88  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
    89  						TrailingPercentOffset: "",
    90  					},
    91  				},
    92  			},
    93  			errStr: "order_submission (is required), stop_orders_submission.rises_below.trigger.trailing_percent_offset (is required)",
    94  		},
    95  		{
    96  			submission: commandspb.StopOrdersSubmission{
    97  				RisesAbove: &commandspb.StopOrderSetup{
    98  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
    99  						TrailingPercentOffset: "0",
   100  					},
   101  				},
   102  			},
   103  			errStr: "order_submission (is required), stop_orders_submission.rises_below.trigger.trailing_percent_offset (must be between 0 and 1)",
   104  		},
   105  		{
   106  			submission: commandspb.StopOrdersSubmission{
   107  				RisesAbove: &commandspb.StopOrderSetup{
   108  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   109  						TrailingPercentOffset: "1",
   110  					},
   111  				},
   112  			},
   113  			errStr: "order_submission (is required), stop_orders_submission.rises_below.trigger.trailing_percent_offset (must be between 0 and 1)",
   114  		},
   115  		{
   116  			submission: commandspb.StopOrdersSubmission{
   117  				RisesAbove: &commandspb.StopOrderSetup{
   118  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   119  						TrailingPercentOffset: "0.89",
   120  					},
   121  				},
   122  			},
   123  			errStr: "order_submission (is required)",
   124  		},
   125  		{
   126  			submission: commandspb.StopOrdersSubmission{
   127  				RisesAbove: &commandspb.StopOrderSetup{
   128  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   129  						TrailingPercentOffset: "132213ds",
   130  					},
   131  				},
   132  			},
   133  			errStr: "order_submission (is required), stop_orders_submission.rises_below.trigger.trailing_percent_offset (not a valid float)",
   134  		},
   135  		{
   136  			submission: commandspb.StopOrdersSubmission{
   137  				RisesAbove: &commandspb.StopOrderSetup{
   138  					ExpiresAt: ptr.From(int64(1000)),
   139  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   140  						TrailingPercentOffset: "0.1",
   141  					},
   142  				},
   143  			},
   144  			errStr: "order_submission (is required), stop_orders_submission.rises_below.expiry_strategy (expiry strategy required when expires_at set)",
   145  		},
   146  		{
   147  			submission: commandspb.StopOrdersSubmission{
   148  				RisesAbove: &commandspb.StopOrderSetup{
   149  					ExpiresAt:      ptr.From(int64(-1000)),
   150  					ExpiryStrategy: ptr.From(vega.StopOrder_EXPIRY_STRATEGY_CANCELS),
   151  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   152  						TrailingPercentOffset: "0.1",
   153  					},
   154  				},
   155  			},
   156  			errStr: "order_submission (is required), stop_orders_submission.rises_below.expires_at (must be positive)",
   157  		},
   158  		{
   159  			submission: commandspb.StopOrdersSubmission{
   160  				RisesAbove: &commandspb.StopOrderSetup{
   161  					ExpiresAt:      ptr.From(int64(1000)),
   162  					ExpiryStrategy: ptr.From(vega.StopOrder_ExpiryStrategy(-1)),
   163  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   164  						TrailingPercentOffset: "0.1",
   165  					},
   166  				},
   167  			},
   168  			errStr: "order_submission (is required), stop_orders_submission.rises_below.expiry_strategy (is not a valid value)",
   169  		},
   170  		{
   171  			submission: commandspb.StopOrdersSubmission{
   172  				RisesAbove: &commandspb.StopOrderSetup{
   173  					ExpiresAt:      ptr.From(int64(1000)),
   174  					ExpiryStrategy: ptr.From(vega.StopOrder_ExpiryStrategy(-1)),
   175  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   176  						TrailingPercentOffset: "0.1",
   177  					},
   178  				},
   179  			},
   180  			errStr: "order_submission (is required), stop_orders_submission.rises_below.expiry_strategy (is not a valid value)",
   181  		},
   182  		{
   183  			submission: commandspb.StopOrdersSubmission{
   184  				RisesAbove: &commandspb.StopOrderSetup{
   185  					ExpiresAt:      ptr.From(int64(1000)),
   186  					ExpiryStrategy: ptr.From(vega.StopOrder_EXPIRY_STRATEGY_UNSPECIFIED),
   187  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   188  						TrailingPercentOffset: "0.1",
   189  					},
   190  				},
   191  			},
   192  			errStr: "order_submission (is required), stop_orders_submission.rises_below.expiry_strategy (is required)",
   193  		},
   194  		{
   195  			submission: commandspb.StopOrdersSubmission{
   196  				RisesAbove: &commandspb.StopOrderSetup{
   197  					ExpiresAt:      ptr.From(int64(1000)),
   198  					ExpiryStrategy: ptr.From(vega.StopOrder_EXPIRY_STRATEGY_CANCELS),
   199  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   200  						TrailingPercentOffset: "0.1",
   201  					},
   202  				},
   203  			},
   204  			errStr: "order_submission (is required)",
   205  		},
   206  		{
   207  			submission: commandspb.StopOrdersSubmission{
   208  				RisesAbove: &commandspb.StopOrderSetup{
   209  					OrderSubmission: &commandspb.OrderSubmission{
   210  						MarketId:    "f9982447fb4128f9968f9981612c5ea85d19b62058ec2636efc812dcbbc745ca",
   211  						Side:        vega.Side_SIDE_BUY,
   212  						Size:        100,
   213  						TimeInForce: vega.Order_TIME_IN_FORCE_IOC,
   214  						Type:        vega.Order_TYPE_MARKET,
   215  						ReduceOnly:  true,
   216  					},
   217  					ExpiresAt:      ptr.From(int64(1000)),
   218  					ExpiryStrategy: ptr.From(vega.StopOrder_EXPIRY_STRATEGY_CANCELS),
   219  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   220  						TrailingPercentOffset: "0.1",
   221  					},
   222  				},
   223  				FallsBelow: &commandspb.StopOrderSetup{
   224  					OrderSubmission: &commandspb.OrderSubmission{
   225  						MarketId:    "e9982447fb4128f9968f9981612c5ea85d19b62058ec2636efc812dcbbc745ca",
   226  						Side:        vega.Side_SIDE_BUY,
   227  						Size:        100,
   228  						TimeInForce: vega.Order_TIME_IN_FORCE_IOC,
   229  						Type:        vega.Order_TYPE_MARKET,
   230  						ReduceOnly:  true,
   231  					},
   232  					ExpiresAt:      ptr.From(int64(1000)),
   233  					ExpiryStrategy: ptr.From(vega.StopOrder_EXPIRY_STRATEGY_CANCELS),
   234  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   235  						TrailingPercentOffset: "0.1",
   236  					},
   237  				},
   238  			},
   239  			errStr: "* (market ID for falls below and rises above must be the same)",
   240  		},
   241  		{
   242  			submission: commandspb.StopOrdersSubmission{
   243  				RisesAbove: &commandspb.StopOrderSetup{
   244  					OrderSubmission: &commandspb.OrderSubmission{
   245  						MarketId:    "f9982447fb4128f9968f9981612c5ea85d19b62058ec2636efc812dcbbc745ca",
   246  						Side:        vega.Side_SIDE_BUY,
   247  						Size:        100,
   248  						TimeInForce: vega.Order_TIME_IN_FORCE_IOC,
   249  						Type:        vega.Order_TYPE_MARKET,
   250  						ReduceOnly:  true,
   251  					},
   252  					ExpiresAt:      ptr.From(int64(1000)),
   253  					ExpiryStrategy: ptr.From(vega.StopOrder_EXPIRY_STRATEGY_CANCELS),
   254  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   255  						TrailingPercentOffset: "0.1",
   256  					},
   257  				},
   258  			},
   259  			errStr: "",
   260  		},
   261  		{
   262  			submission: commandspb.StopOrdersSubmission{
   263  				RisesAbove: &commandspb.StopOrderSetup{
   264  					OrderSubmission: &commandspb.OrderSubmission{
   265  						MarketId:    "f9982447fb4128f9968f9981612c5ea85d19b62058ec2636efc812dcbbc745ca",
   266  						Side:        vega.Side_SIDE_BUY,
   267  						Size:        100,
   268  						TimeInForce: vega.Order_TIME_IN_FORCE_IOC,
   269  						Type:        vega.Order_TYPE_MARKET,
   270  						ReduceOnly:  true,
   271  					},
   272  					ExpiresAt:      ptr.From(int64(1000)),
   273  					ExpiryStrategy: ptr.From(vega.StopOrder_EXPIRY_STRATEGY_CANCELS),
   274  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   275  						TrailingPercentOffset: "0.1",
   276  					},
   277  					SizeOverrideSetting: ptr.From(vega.StopOrder_SIZE_OVERRIDE_SETTING_POSITION),
   278  					SizeOverrideValue:   &vega.StopOrder_SizeOverrideValue{Percentage: "0.5"},
   279  				},
   280  			},
   281  			errStr: "",
   282  		},
   283  		{
   284  			submission: commandspb.StopOrdersSubmission{
   285  				RisesAbove: &commandspb.StopOrderSetup{
   286  					OrderSubmission: &commandspb.OrderSubmission{
   287  						MarketId:    "f9982447fb4128f9968f9981612c5ea85d19b62058ec2636efc812dcbbc745ca",
   288  						Side:        vega.Side_SIDE_BUY,
   289  						Size:        100,
   290  						TimeInForce: vega.Order_TIME_IN_FORCE_IOC,
   291  						Type:        vega.Order_TYPE_MARKET,
   292  						ReduceOnly:  true,
   293  					},
   294  					ExpiresAt:      ptr.From(int64(1000)),
   295  					ExpiryStrategy: ptr.From(vega.StopOrder_EXPIRY_STRATEGY_CANCELS),
   296  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   297  						TrailingPercentOffset: "0.1",
   298  					},
   299  					SizeOverrideSetting: ptr.From(vega.StopOrder_SIZE_OVERRIDE_SETTING_POSITION),
   300  					SizeOverrideValue:   &vega.StopOrder_SizeOverrideValue{Percentage: "BrokenString"},
   301  				},
   302  			},
   303  			errStr: "stop_orders_submission.rises_above.size_override_value (is not a valid number)",
   304  		},
   305  		{
   306  			submission: commandspb.StopOrdersSubmission{
   307  				RisesAbove: &commandspb.StopOrderSetup{
   308  					OrderSubmission: &commandspb.OrderSubmission{
   309  						MarketId:    "f9982447fb4128f9968f9981612c5ea85d19b62058ec2636efc812dcbbc745ca",
   310  						Side:        vega.Side_SIDE_BUY,
   311  						Size:        100,
   312  						TimeInForce: vega.Order_TIME_IN_FORCE_IOC,
   313  						Type:        vega.Order_TYPE_MARKET,
   314  						ReduceOnly:  true,
   315  					},
   316  					ExpiresAt:      ptr.From(int64(1000)),
   317  					ExpiryStrategy: ptr.From(vega.StopOrder_EXPIRY_STRATEGY_CANCELS),
   318  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   319  						TrailingPercentOffset: "0.1",
   320  					},
   321  					SizeOverrideSetting: ptr.From(vega.StopOrder_SIZE_OVERRIDE_SETTING_POSITION),
   322  					SizeOverrideValue:   &vega.StopOrder_SizeOverrideValue{Percentage: "0.0"},
   323  				},
   324  			},
   325  			errStr: "stop_orders_submission.rises_above.size_override_value (must be between 0 (excluded) and 1 (included))",
   326  		},
   327  		{
   328  			submission: commandspb.StopOrdersSubmission{
   329  				RisesAbove: &commandspb.StopOrderSetup{
   330  					OrderSubmission: &commandspb.OrderSubmission{
   331  						MarketId:    "f9982447fb4128f9968f9981612c5ea85d19b62058ec2636efc812dcbbc745ca",
   332  						Side:        vega.Side_SIDE_BUY,
   333  						Size:        100,
   334  						TimeInForce: vega.Order_TIME_IN_FORCE_IOC,
   335  						Type:        vega.Order_TYPE_MARKET,
   336  						ReduceOnly:  true,
   337  					},
   338  					ExpiresAt:      ptr.From(int64(1000)),
   339  					ExpiryStrategy: ptr.From(vega.StopOrder_EXPIRY_STRATEGY_CANCELS),
   340  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   341  						TrailingPercentOffset: "0.1",
   342  					},
   343  					SizeOverrideSetting: ptr.From(vega.StopOrder_SIZE_OVERRIDE_SETTING_POSITION),
   344  					SizeOverrideValue:   &vega.StopOrder_SizeOverrideValue{Percentage: "1.1"},
   345  				},
   346  			},
   347  			errStr: "stop_orders_submission.rises_above.size_override_value (must be between 0 (excluded) and 1 (included))",
   348  		},
   349  		{
   350  			submission: commandspb.StopOrdersSubmission{
   351  				FallsBelow: &commandspb.StopOrderSetup{
   352  					OrderSubmission: &commandspb.OrderSubmission{
   353  						MarketId:    "f9982447fb4128f9968f9981612c5ea85d19b62058ec2636efc812dcbbc745ca",
   354  						Side:        vega.Side_SIDE_BUY,
   355  						Size:        100,
   356  						TimeInForce: vega.Order_TIME_IN_FORCE_IOC,
   357  						Type:        vega.Order_TYPE_MARKET,
   358  						ReduceOnly:  true,
   359  					},
   360  					ExpiresAt:      ptr.From(int64(1000)),
   361  					ExpiryStrategy: ptr.From(vega.StopOrder_EXPIRY_STRATEGY_CANCELS),
   362  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   363  						TrailingPercentOffset: "0.1",
   364  					},
   365  					SizeOverrideSetting: ptr.From(vega.StopOrder_SIZE_OVERRIDE_SETTING_POSITION),
   366  					SizeOverrideValue:   &vega.StopOrder_SizeOverrideValue{Percentage: "0.5"},
   367  				},
   368  			},
   369  			errStr: "",
   370  		},
   371  		{
   372  			submission: commandspb.StopOrdersSubmission{
   373  				FallsBelow: &commandspb.StopOrderSetup{
   374  					OrderSubmission: &commandspb.OrderSubmission{
   375  						MarketId:    "f9982447fb4128f9968f9981612c5ea85d19b62058ec2636efc812dcbbc745ca",
   376  						Side:        vega.Side_SIDE_BUY,
   377  						Size:        100,
   378  						TimeInForce: vega.Order_TIME_IN_FORCE_IOC,
   379  						Type:        vega.Order_TYPE_MARKET,
   380  						ReduceOnly:  true,
   381  					},
   382  					ExpiresAt:      ptr.From(int64(1000)),
   383  					ExpiryStrategy: ptr.From(vega.StopOrder_EXPIRY_STRATEGY_CANCELS),
   384  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   385  						TrailingPercentOffset: "0.1",
   386  					},
   387  					SizeOverrideSetting: ptr.From(vega.StopOrder_SIZE_OVERRIDE_SETTING_POSITION),
   388  					SizeOverrideValue:   &vega.StopOrder_SizeOverrideValue{Percentage: "BrokenString"},
   389  				},
   390  			},
   391  			errStr: "stop_orders_submission.falls_below.size_override_value (is not a valid number)",
   392  		},
   393  		{
   394  			submission: commandspb.StopOrdersSubmission{
   395  				FallsBelow: &commandspb.StopOrderSetup{
   396  					OrderSubmission: &commandspb.OrderSubmission{
   397  						MarketId:    "f9982447fb4128f9968f9981612c5ea85d19b62058ec2636efc812dcbbc745ca",
   398  						Side:        vega.Side_SIDE_BUY,
   399  						Size:        100,
   400  						TimeInForce: vega.Order_TIME_IN_FORCE_IOC,
   401  						Type:        vega.Order_TYPE_MARKET,
   402  						ReduceOnly:  true,
   403  					},
   404  					ExpiresAt:      ptr.From(int64(1000)),
   405  					ExpiryStrategy: ptr.From(vega.StopOrder_EXPIRY_STRATEGY_CANCELS),
   406  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   407  						TrailingPercentOffset: "0.1",
   408  					},
   409  					SizeOverrideSetting: ptr.From(vega.StopOrder_SIZE_OVERRIDE_SETTING_POSITION),
   410  					SizeOverrideValue:   &vega.StopOrder_SizeOverrideValue{Percentage: "0.0"},
   411  				},
   412  			},
   413  			errStr: "stop_orders_submission.falls_below.size_override_value (must be between 0 (excluded) and 1 (included))",
   414  		},
   415  		{
   416  			submission: commandspb.StopOrdersSubmission{
   417  				FallsBelow: &commandspb.StopOrderSetup{
   418  					OrderSubmission: &commandspb.OrderSubmission{
   419  						MarketId:    "f9982447fb4128f9968f9981612c5ea85d19b62058ec2636efc812dcbbc745ca",
   420  						Side:        vega.Side_SIDE_BUY,
   421  						Size:        100,
   422  						TimeInForce: vega.Order_TIME_IN_FORCE_IOC,
   423  						Type:        vega.Order_TYPE_MARKET,
   424  						ReduceOnly:  true,
   425  					},
   426  					ExpiresAt:      ptr.From(int64(1000)),
   427  					ExpiryStrategy: ptr.From(vega.StopOrder_EXPIRY_STRATEGY_CANCELS),
   428  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   429  						TrailingPercentOffset: "0.1",
   430  					},
   431  					SizeOverrideSetting: ptr.From(vega.StopOrder_SIZE_OVERRIDE_SETTING_POSITION),
   432  					SizeOverrideValue:   &vega.StopOrder_SizeOverrideValue{Percentage: "1.1"},
   433  				},
   434  			},
   435  			errStr: "stop_orders_submission.falls_below.size_override_value (must be between 0 (excluded) and 1 (included))",
   436  		},
   437  		{
   438  			submission: commandspb.StopOrdersSubmission{
   439  				RisesAbove: &commandspb.StopOrderSetup{
   440  					OrderSubmission: &commandspb.OrderSubmission{
   441  						MarketId:    "f9982447fb4128f9968f9981612c5ea85d19b62058ec2636efc812dcbbc745ca",
   442  						Side:        vega.Side_SIDE_BUY,
   443  						Size:        100,
   444  						TimeInForce: vega.Order_TIME_IN_FORCE_GFA,
   445  						Type:        vega.Order_TYPE_MARKET,
   446  						ReduceOnly:  true,
   447  					},
   448  					ExpiresAt:      ptr.From(int64(1000)),
   449  					ExpiryStrategy: ptr.From(vega.StopOrder_EXPIRY_STRATEGY_CANCELS),
   450  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   451  						TrailingPercentOffset: "0.1",
   452  					},
   453  				},
   454  			},
   455  			errStr: commands.ErrIsNotValid.Error(),
   456  		},
   457  		{
   458  			submission: commandspb.StopOrdersSubmission{
   459  				FallsBelow: &commandspb.StopOrderSetup{
   460  					OrderSubmission: &commandspb.OrderSubmission{
   461  						MarketId:    "f9982447fb4128f9968f9981612c5ea85d19b62058ec2636efc812dcbbc745ca",
   462  						Side:        vega.Side_SIDE_BUY,
   463  						Size:        100,
   464  						TimeInForce: vega.Order_TIME_IN_FORCE_GFA,
   465  						Type:        vega.Order_TYPE_MARKET,
   466  						ReduceOnly:  true,
   467  					},
   468  					ExpiresAt:      ptr.From(int64(1000)),
   469  					ExpiryStrategy: ptr.From(vega.StopOrder_EXPIRY_STRATEGY_CANCELS),
   470  					Trigger: &commandspb.StopOrderSetup_TrailingPercentOffset{
   471  						TrailingPercentOffset: "0.1",
   472  					},
   473  				},
   474  			},
   475  			errStr: commands.ErrIsNotValid.Error(),
   476  		},
   477  	}
   478  
   479  	for n, c := range cases {
   480  		if len(c.errStr) <= 0 {
   481  			assert.NoError(t, commands.CheckStopOrdersSubmission(&c.submission), n)
   482  			continue
   483  		}
   484  
   485  		assert.Contains(t, checkStopOrdersSubmission(&c.submission).Error(), c.errStr, n)
   486  	}
   487  }
   488  
   489  func checkStopOrdersSubmission(cmd *commandspb.StopOrdersSubmission) commands.Errors {
   490  	err := commands.CheckStopOrdersSubmission(cmd)
   491  
   492  	var e commands.Errors
   493  	if ok := errors.As(err, &e); !ok {
   494  		return commands.NewErrors()
   495  	}
   496  
   497  	return e
   498  }