diff --git a/core/integration/features/margin/0019-MCAL-208.feature b/core/integration/features/margin/0019-MCAL-208.feature new file mode 100644 index 00000000000..32f622acb56 --- /dev/null +++ b/core/integration/features/margin/0019-MCAL-208.feature @@ -0,0 +1,114 @@ +Feature: test when isolated margin risk factor > 1 + Background: + Given the average block duration is "1" + And the following network parameters are set: + | name | value | + | network.markPriceUpdateMaximumFrequency | 0s | + | limits.markets.maxPeggedOrders | 6 | + | market.auction.minimumDuration | 1 | + And the price monitoring named "my-price-monitoring-1": + | horizon | probability | auction extension | + | 5 | 0.99 | 6 | + + And the liquidity monitoring parameters: + | name | triggering ratio | time window | scaling factor | + | lqm-params | 0.00 | 24h | 1e-9 | + And the simple risk model named "simple-risk-model": + | long | short | max move up | min move down | probability of trading | + | 0.8 | 1 | 100 | -100 | 0.2 | + And the markets: + | id | quote name | asset | liquidity monitoring | risk model | margin calculator | auction duration | fees | price monitoring | data source config | linear slippage factor | quadratic slippage factor | position decimal places | sla params | + | ETH/FEB23 | ETH | USD | lqm-params | simple-risk-model | default-margin-calculator | 1 | default-none | my-price-monitoring-1 | default-eth-for-future | 0.25 | 0 | 2 | default-futures | + + Scenario: 0019-MCAL-208 + Given the parties deposit on asset's general account the following amount: + | party | asset | amount | + | trader1 | USD | 100000000000 | + | trader2 | USD | 100000000000 | + | trader3 | USD | 100000 | + | trader4 | USD | 100000000000 | + | lprov1 | USD | 100000000000 | + + And the parties submit the following liquidity provision: + | id | party | market id | commitment amount | fee | lp type | + | lp1 | lprov1 | ETH/FEB23 | 1000 | 0.1 | submission | + + And the parties place the following orders with ticks: + | party | market id | side | volume | price | resulting trades | type | tif | reference | + | trader1 | ETH/FEB23 | buy | 1000 | 14900 | 0 | TYPE_LIMIT | TIF_GTC | | + | trader1 | ETH/FEB23 | buy | 300 | 15600 | 0 | TYPE_LIMIT | TIF_GTC | | + | lprov1 | ETH/FEB23 | buy | 100 | 15700 | 0 | TYPE_LIMIT | TIF_GTC | lp-buy-1 | + | trader3 | ETH/FEB23 | buy | 300 | 15800 | 0 | TYPE_LIMIT | TIF_GTC | | + | lprov1 | ETH/FEB23 | sell | 300 | 15800 | 0 | TYPE_LIMIT | TIF_GTC | lp-sell-1 | + | trader2 | ETH/FEB23 | sell | 600 | 15820 | 0 | TYPE_LIMIT | TIF_GTC | t2-sell-1 | + | trader2 | ETH/FEB23 | sell | 300 | 200000 | 0 | TYPE_LIMIT | TIF_GTC | | + | trader2 | ETH/FEB23 | sell | 1000 | 200100 | 0 | TYPE_LIMIT | TIF_GTC | | + + When the network moves ahead "2" blocks + Then the market data for the market "ETH/FEB23" should be: + | mark price | trading mode | horizon | min bound | max bound | target stake | supplied stake | open interest | + | 15800 | TRADING_MODE_CONTINUOUS | 5 | 15701 | 15899 | 0 | 1000 | 300 | + + And the parties should have the following account balances: + | party | asset | market id | margin | general | bond | + | trader3 | USD | ETH/FEB23 | 59724 | 40276 | | + + When the parties place the following pegged orders: + | party | market id | side | volume | pegged reference | offset | reference | + | lprov1 | ETH/FEB23 | buy | 100 | BID | 10 | buy_peg_1 | + | lprov1 | ETH/FEB23 | buy | 200 | BID | 20 | buy_peg_2 | + + Then the parties should have the following margin levels: + | party | market id | maintenance | search | initial | release | margin mode | margin factor | order | + | trader3 | ETH/FEB23 | 49770 | 54747 | 59724 | 69678 | cross margin | 0 | 0 | + And the parties should have the following account balances: + | party | asset | market id | margin | general | bond | + | trader3 | USD | ETH/FEB23 | 59724 | 40276 | | + + When the parties place the following orders with ticks: + | party | market id | side | volume | price | resulting trades | type | tif | reference | + | trader3 | ETH/FEB23 | buy | 10 | 15500 | 0 | TYPE_LIMIT | TIF_GTC | t3-buy | + Then the parties should have the following margin levels: + | party | market id | maintenance | search | initial | release | margin mode | margin factor | order | + | trader3 | ETH/FEB23 | 51034 | 56137 | 61240 | 71447 | cross margin | 0 | 0 | + And the parties should have the following account balances: + | party | asset | market id | margin | general | + | trader3 | USD | ETH/FEB23 | 61240 | 38760 | + + When the parties submit update margin mode: + | party | market | margin_mode | margin_factor | error | + | trader3 | ETH/FEB23 | isolated margin | 1.3 | | + Then the parties should have the following margin levels: + | party | market id | maintenance | search | initial | release | margin mode | margin factor | order | + | trader3 | ETH/FEB23 | 49770 | 0 | 59724 | 0 | isolated margin | 1.3 | 2015 | + And the parties should have the following account balances: + | party | asset | market id | margin | general | order margin | + | trader3 | USD | ETH/FEB23 | 61620 | 36365 | 2015 | + + # amend the order to increase the required margin, the order remains on the book without issue + When the parties amend the following orders: + | party | reference | price | size delta | tif | error | + | trader3 | t3-buy | 15500 | 20 | TIF_GTC | | + Then the orders should have the following status: + | party | reference | status | + | trader3 | t3-buy | STATUS_ACTIVE | + And the parties should have the following margin levels: + | party | market id | maintenance | search | initial | release | margin mode | margin factor | order | + | trader3 | ETH/FEB23 | 49770 | 0 | 59724 | 0 | isolated margin | 1.3 | 6045 | + And the parties should have the following account balances: + | party | asset | market id | margin | general | order margin | + | trader3 | USD | ETH/FEB23 | 61620 | 32335 | 6045 | + + When the parties place the following orders with ticks: + | party | market id | side | volume | price | resulting trades | type | tif | reference | + | trader1 | ETH/FEB23 | buy | 10 | 15820 | 1 | TYPE_LIMIT | TIF_GTC | trader2-buy | + + #mark price changed triggers MTM win for trader3: 3*20=60 + And the network moves ahead "1" blocks + Then the parties should have the following margin levels: + | party | market id | maintenance | search | initial | release | margin mode | margin factor | order | + | trader3 | ETH/FEB23 | 49833 | 0 | 59799 | 0 | isolated margin | 1.3 | 6045 | + And the parties should have the following account balances: + | party | asset | market id | margin | general | order margin | + | trader3 | USD | ETH/FEB23 | 61680 | 32335 | 6045 | + diff --git a/core/integration/steps/the_parties_update_margin_mode.go b/core/integration/steps/the_parties_update_margin_mode.go index cc1c5953435..9485f57565d 100644 --- a/core/integration/steps/the_parties_update_margin_mode.go +++ b/core/integration/steps/the_parties_update_margin_mode.go @@ -44,13 +44,16 @@ func ThePartiesUpdateMarginMode( if r.HasColumn("margin_factor") && marginMode == types.MarginModeIsolatedMargin { factor = num.MustDecimalFromString(r.MustStr("margin_factor")) } + expErr := "" + if r.HasColumn("error") && len(r.Str("error")) > 0 { + expErr = r.Str("error") + } err := execution.UpdateMarginMode(context.Background(), party, market, marginMode, factor) - if r.HasColumn("error") && len(r.Str("error")) > 0 && (err == nil || err != nil && r.Str("error") != err.Error()) { - gotError := "" - if err != nil { - gotError = err.Error() - } - return fmt.Errorf("invalid error expected %v got %v", r.Str("error"), gotError) + if err != nil && len(expErr) == 0 { + return fmt.Errorf("unexpected error when updating margin mode: %v", err) + } + if len(expErr) > 0 && (err == nil || err != nil && expErr != err.Error()) { + return fmt.Errorf("invalid error expected %v got %v", expErr, err) } }