Skip to content

Commit 27d96ac

Browse files
authored
Merge pull request #11262 from vegaprotocol/feature-test-0032-PRIM-033
Adding feature test for 0032-PRIM-003 and bug fix
2 parents 33942d5 + 042a132 commit 27d96ac

File tree

9 files changed

+171
-20
lines changed

9 files changed

+171
-20
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
- [11250](https://github.com/vegaprotocol/vega/issues/11250) - Add missing dispatch strategy in transfer proposal.
2727
- [11252](https://github.com/vegaprotocol/vega/issues/11252) - Treat no position as zero position when calculating stop order overrides.
2828
- [11249](https://github.com/vegaprotocol/vega/issues/11249) - Composite mark price oracles are now deactivated when a market is rejected.
29+
- [11262](https://github.com/vegaprotocol/vega/pull/11262) - Fix auction extensions after risk parameter update.
2930

3031

3132
## 0.76.0

core/execution/common/interfaces.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ type PriceMonitor interface {
5959
Changed() bool
6060
IsBoundFactorsInitialised() bool
6161
Initialised() bool
62-
UpdateSettings(risk.Model, *types.PriceMonitoringSettings)
62+
UpdateSettings(risk.Model, *types.PriceMonitoringSettings, price.AuctionState)
6363
}
6464

6565
// TimeService ...

core/execution/future/market.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ func (m *Market) Update(ctx context.Context, config *types.Market, oracleEngine
602602
m.risk.UpdateModel(m.stateVarEngine, m.tradableInstrument.MarginCalculator, m.tradableInstrument.RiskModel, m.mkt.LinearSlippageFactor, m.mkt.QuadraticSlippageFactor)
603603
m.settlement.UpdateProduct(m.tradableInstrument.Instrument.Product)
604604
m.tsCalc.UpdateParameters(*m.mkt.LiquidityMonitoringParameters.TargetStakeParameters)
605-
m.pMonitor.UpdateSettings(m.tradableInstrument.RiskModel, m.mkt.PriceMonitoringSettings)
605+
m.pMonitor.UpdateSettings(m.tradableInstrument.RiskModel, m.mkt.PriceMonitoringSettings, m.as)
606606
m.liquidity.UpdateMarketConfig(m.tradableInstrument.RiskModel, m.pMonitor)
607607
if err := m.markPriceCalculator.UpdateConfig(ctx, oracleEngine, m.mkt.MarkPriceConfiguration); err != nil {
608608
m.markPriceCalculator.SetOraclePriceScalingFunc(m.scaleOracleData)

core/execution/spot/market.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ func (m *Market) Update(ctx context.Context, config *types.Market) error {
292292
if err != nil {
293293
return err
294294
}
295-
m.pMonitor.UpdateSettings(riskModel, m.mkt.PriceMonitoringSettings)
295+
m.pMonitor.UpdateSettings(riskModel, m.mkt.PriceMonitoringSettings, m.as)
296296
m.liquidity.UpdateMarketConfig(riskModel, m.pMonitor)
297297
m.updateLiquidityFee(ctx)
298298

core/integration/features/price_monitoring/end-long-auction-with-trigger-change.feature

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -114,16 +114,16 @@ Feature: Confirm return to continuous trading during significant mark price chan
114114
| ETH/FEB23 | my-price-monitoring-2 | weight | 0,0,1,0 | 0s,0s,0h0m120s,0s |
115115
# first we get bounds based on default factors, once the state variable engine finishes its calculation we get the proper values
116116
Then the market data for the market "ETH/FEB23" should be:
117-
| mark price | trading mode | auction trigger | horizon | ref price | min bound | max bound |
118-
| 1000 | TRADING_MODE_MONITORING_AUCTION | AUCTION_TRIGGER_PRICE | 30 | 1000 | 900 | 1100 |
117+
| mark price | trading mode | auction trigger |
118+
| 1000 | TRADING_MODE_MONITORING_AUCTION | AUCTION_TRIGGER_PRICE |
119119

120120
# the last second of the original extensions
121121
And the network moves ahead "3" blocks
122122
Then the market data for the market "ETH/FEB23" should be:
123-
| mark price | trading mode | auction trigger | horizon | ref price | min bound | max bound |
124-
| 1000 | TRADING_MODE_MONITORING_AUCTION | AUCTION_TRIGGER_PRICE | 30 | 1000 | 997 | 1003 |
123+
| mark price | trading mode | auction trigger |
124+
| 1000 | TRADING_MODE_MONITORING_AUCTION | AUCTION_TRIGGER_PRICE |
125125

126-
# the updated extension triggered, no triggers left
126+
# the updated extension triggered, no triggers left as they've all been switched off since update took place during auction
127127
And the network moves ahead "1" blocks
128128
Then the market data for the market "ETH/FEB23" should be:
129129
| mark price | trading mode | auction trigger |
@@ -174,15 +174,15 @@ Feature: Confirm return to continuous trading during significant mark price chan
174174
# the last second of the original extensions
175175
And the network moves ahead "3" blocks
176176
Then the market data for the market "ETH/FEB23" should be:
177-
| mark price | trading mode | auction trigger | horizon | ref price | min bound | max bound |
178-
| 1000 | TRADING_MODE_MONITORING_AUCTION | AUCTION_TRIGGER_PRICE | 30 | 1000 | 997 | 1003 |
177+
| mark price | trading mode | auction trigger |
178+
| 1000 | TRADING_MODE_MONITORING_AUCTION | AUCTION_TRIGGER_PRICE |
179179

180180
When the parties place the following orders with ticks:
181181
| party | market id | side | volume | price | resulting trades | type | tif |
182182
| party1 | ETH/FEB23 | buy | 1 | 2004 | 0 | TYPE_LIMIT | TIF_GTC |
183183
| party2 | ETH/FEB23 | sell | 1 | 2004 | 0 | TYPE_LIMIT | TIF_GTC |
184184

185-
# the updated extension triggered, no triggers left
185+
# the updated extension triggered, no triggers left as they've all been switched off since update took place during auction
186186
And the network moves ahead "1" blocks
187187
Then the market data for the market "ETH/FEB23" should be:
188188
| mark price | trading mode | auction trigger |
@@ -217,14 +217,14 @@ Feature: Confirm return to continuous trading during significant mark price chan
217217
# the last second of the original extensions
218218
And the network moves ahead "3" blocks
219219
Then the market data for the market "ETH/FEB23" should be:
220-
| mark price | trading mode | auction trigger | horizon | ref price | min bound | max bound |
221-
| 1000 | TRADING_MODE_MONITORING_AUCTION | AUCTION_TRIGGER_PRICE | 30 | 1000 | 997 | 1003 |
220+
| mark price | trading mode | auction trigger |
221+
| 1000 | TRADING_MODE_MONITORING_AUCTION | AUCTION_TRIGGER_PRICE |
222222

223223
When the oracles broadcast data with block time signed with "0xCAFECAFE1":
224224
| name | value | time offset |
225225
| prices.ETH.value | 2000 | -1s |
226226

227-
# the updated extension triggered, no triggers left
227+
# the updated extension triggered, no triggers left as they've all been switched off since update took place during auction
228228
And the network moves ahead "1" blocks
229229
Then the market data for the market "ETH/FEB23" should be:
230230
| mark price | trading mode | auction trigger |
@@ -253,4 +253,26 @@ Feature: Confirm return to continuous trading during significant mark price chan
253253
And the network moves ahead "118" blocks
254254
Then the market data for the market "ETH/FEB23" should be:
255255
| mark price | trading mode | auction trigger | last traded price | horizon | ref price | min bound | max bound |
256-
| 1000 | TRADING_MODE_CONTINUOUS | AUCTION_TRIGGER_UNSPECIFIED | 1003 | 30 | 1003 | 1000 | 1006 |
256+
| 1000 | TRADING_MODE_CONTINUOUS | AUCTION_TRIGGER_UNSPECIFIED | 1003 | 30 | 1003 | 1000 | 1006 |
257+
258+
Scenario: Verify that trigger update in continuous trading works as expected
259+
260+
When the network moves ahead "2" blocks
261+
Then the market data for the market "ETH/FEB23" should be:
262+
| mark price | trading mode | horizon | ref price | min bound | max bound |
263+
| 1000 | TRADING_MODE_CONTINUOUS | 60 | 1000 | 995 | 1005 |
264+
265+
And the price monitoring named "my-price-monitoring-2":
266+
| horizon | probability | auction extension |
267+
| 30 | 0.95 | 1 |
268+
269+
# update trigger here so that there's only one
270+
When the markets are updated:
271+
| id | price monitoring | price type | source weights | source staleness tolerance |
272+
| ETH/FEB23 | my-price-monitoring-2 | weight | 0,0,1,0 | 0s,0s,0h0m120s,0s |
273+
274+
# the last second of the original extensions
275+
And the network moves ahead "3" blocks
276+
Then the market data for the market "ETH/FEB23" should be:
277+
| mark price | trading mode | horizon | ref price | min bound | max bound |
278+
| 1000 | TRADING_MODE_CONTINUOUS | 30 | 1000 | 997 | 1003 |
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
Feature: Spot market
2+
3+
Background:
4+
Given time is updated to "2024-01-01T00:00:00Z"
5+
6+
Given the following network parameters are set:
7+
| name | value |
8+
| network.markPriceUpdateMaximumFrequency | 0s |
9+
| market.value.windowLength | 1h |
10+
11+
Given the following assets are registered:
12+
| id | decimal places |
13+
| ETH | 2 |
14+
| BTC | 2 |
15+
16+
Given the fees configuration named "fees-config-1":
17+
| maker fee | infrastructure fee |
18+
| 0.01 | 0.03 |
19+
Given the log normal risk model named "lognormal-risk-model-1":
20+
| risk aversion | tau | mu | r | sigma |
21+
| 0.001 | 0.01 | 0 | 0.0 | 1.2 |
22+
23+
Given the log normal risk model named "lognormal-risk-model-2":
24+
| risk aversion | tau | mu | r | sigma |
25+
| 0.002 | 0.02 | 0 | 0.1 | 1.3 |
26+
27+
And the price monitoring named "price-monitoring-1":
28+
| horizon | probability | auction extension |
29+
| 30 | 0.999 | 10 |
30+
| 60 | 0.999 | 20 |
31+
| 90 | 0.999 | 40 |
32+
| 120 | 0.999 | 80 |
33+
34+
And the spot markets:
35+
| id | name | base asset | quote asset | risk model | auction duration | fees | price monitoring | decimal places | position decimal places | sla params |
36+
| BTC/ETH | BTC/ETH | BTC | ETH | lognormal-risk-model-1 | 1 | fees-config-1 | price-monitoring-1 | 2 | 2 | default-basic |
37+
38+
# setup accounts
39+
Given the parties deposit on asset's general account the following amount:
40+
| party | asset | amount |
41+
| party1 | ETH | 10000 |
42+
| party1 | BTC | 1000 |
43+
| party2 | ETH | 10000 |
44+
| party4 | BTC | 1000 |
45+
| party5 | BTC | 1000 |
46+
And the average block duration is "1"
47+
48+
# Place some orders to get out of auction
49+
And the parties place the following orders:
50+
| party | market id | side | volume | price | resulting trades | type | tif |
51+
| party1 | BTC/ETH | buy | 1 | 1000 | 0 | TYPE_LIMIT | TIF_GFA |
52+
| party5 | BTC/ETH | sell | 1 | 1000 | 0 | TYPE_LIMIT | TIF_GTC |
53+
54+
And the opening auction period ends for market "BTC/ETH"
55+
When the network moves ahead "1" blocks
56+
Then the trading mode should be "TRADING_MODE_CONTINUOUS" for the market "BTC/ETH"
57+
And the mark price should be "1000" for the market "BTC/ETH"
58+
59+
Scenario: When market is in price monitoring auction, change of a risk model or any of its parameters doesn't affect the previously
60+
calculated auction end time, any remaining price monitoring bounds cannot extend the auction further. Upon uncrossing
61+
price monitoring bounds get reset using the updated parameter values. (0032-PRIM-033)
62+
63+
# Check that the market price bounds are set
64+
And the market data for the market "BTC/ETH" should be:
65+
| mark price | trading mode | horizon | min bound | max bound | target stake | supplied stake | open interest | auction start | auction end |
66+
| 1000 | TRADING_MODE_CONTINUOUS | 30 | 997 | 1003 | 0 | 0 | 0 | 0 | 0 |
67+
| 1000 | TRADING_MODE_CONTINUOUS | 60 | 995 | 1005 | 0 | 0 | 0 | 0 | 0 |
68+
| 1000 | TRADING_MODE_CONTINUOUS | 90 | 994 | 1006 | 0 | 0 | 0 | 0 | 0 |
69+
| 1000 | TRADING_MODE_CONTINUOUS | 120 | 993 | 1007 | 0 | 0 | 0 | 0 | 0 |
70+
71+
# Place 2 persistent orders that are outside all of the price bounds
72+
And the parties place the following orders:
73+
| party | market id | side | volume | price | resulting trades | type | tif | reference |
74+
| party1 | BTC/ETH | buy | 1 | 1008 | 0 | TYPE_LIMIT | TIF_GTC | buy1 |
75+
| party5 | BTC/ETH | sell | 1 | 1008 | 0 | TYPE_LIMIT | TIF_GTC | sell1 |
76+
When the network moves ahead "1" blocks
77+
78+
# Check we have been placed in auction
79+
Then the trading mode should be "TRADING_MODE_MONITORING_AUCTION" for the market "BTC/ETH"
80+
81+
# Check we know the auction time
82+
And the market data for the market "BTC/ETH" should be:
83+
| mark price | trading mode | horizon | min bound | max bound | target stake | supplied stake | open interest | auction start | auction end |
84+
| 1000 | TRADING_MODE_MONITORING_AUCTION | 60 | 995 | 1005 | 0 | 0 | 0 | 1704067203000000000 | 1704067213000000000 |
85+
| 1000 | TRADING_MODE_MONITORING_AUCTION | 90 | 994 | 1006 | 0 | 0 | 0 | 1704067203000000000 | 1704067213000000000 |
86+
| 1000 | TRADING_MODE_MONITORING_AUCTION | 120 | 993 | 1007 | 0 | 0 | 0 | 1704067203000000000 | 1704067213000000000 |
87+
88+
# Now update the risk model to deactivate all pending price bounds
89+
Then the spot markets are updated:
90+
| id | risk model |
91+
| BTC/ETH | lognormal-risk-model-2 |
92+
93+
# If we move ahead 25 blocks we should come out of auction instead of it being extended
94+
When the network moves ahead "25" blocks
95+
96+
And the market data for the market "BTC/ETH" should be:
97+
| mark price | trading mode | horizon | min bound | max bound | target stake | supplied stake | open interest | auction start | auction end |
98+
| 1008 | TRADING_MODE_CONTINUOUS | 30 | 1004 | 1012 | 0 | 0 | 0 | 0 | 0 |
99+
| 1008 | TRADING_MODE_CONTINUOUS | 60 | 1003 | 1013 | 0 | 0 | 0 | 0 | 0 |
100+
| 1008 | TRADING_MODE_CONTINUOUS | 90 | 1001 | 1015 | 0 | 0 | 0 | 0 | 0 |
101+
| 1008 | TRADING_MODE_CONTINUOUS | 120 | 1000 | 1016 | 0 | 0 | 0 | 0 | 0 |
102+
103+
Then the trading mode should be "TRADING_MODE_CONTINUOUS" for the market "BTC/ETH"
104+
105+
# The mark price should show the orders have traded
106+
And the mark price should be "1008" for the market "BTC/ETH"
107+
108+
And the orders should have the following states:
109+
| party | market id | reference | side | volume | remaining | price | status |
110+
| party1 | BTC/ETH | buy1 | buy | 1 | 0 | 1008 | STATUS_FILLED |
111+
| party5 | BTC/ETH | sell1 | sell | 1 | 0 | 1008 | STATUS_FILLED |
112+

core/monitor/price/pricemonitoring.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,9 @@ type Engine struct {
142142
asset string
143143
}
144144

145-
func (e *Engine) UpdateSettings(riskModel risk.Model, settings *types.PriceMonitoringSettings) {
145+
func (e *Engine) UpdateSettings(riskModel risk.Model, settings *types.PriceMonitoringSettings, as AuctionState) {
146146
e.riskModel = riskModel
147-
e.fpHorizons, e.bounds = computeBoundsAndHorizons(settings)
147+
e.fpHorizons, e.bounds = computeBoundsAndHorizons(settings, as)
148148
e.initialised = false
149149
e.boundFactorsInitialised = false
150150
e.priceRangesCache = make(map[int]priceRange, len(e.bounds)) // clear the cache
@@ -169,7 +169,7 @@ func NewMonitor(asset, mktID string, riskModel RangeProvider, auctionState Aucti
169169
}
170170

171171
// Other functions depend on this sorting
172-
horizons, bounds := computeBoundsAndHorizons(settings)
172+
horizons, bounds := computeBoundsAndHorizons(settings, auctionState)
173173

174174
e := &Engine{
175175
riskModel: riskModel,
@@ -525,7 +525,9 @@ func (e *Engine) noHistory() bool {
525525
return len(e.pricesPast) == 0 && len(e.pricesNow) == 0
526526
}
527527

528-
func computeBoundsAndHorizons(settings *types.PriceMonitoringSettings) (map[int64]num.Decimal, []*bound) {
528+
func computeBoundsAndHorizons(settings *types.PriceMonitoringSettings, as AuctionState) (map[int64]num.Decimal, []*bound) {
529+
// set bounds to inactive if we're in price monitoring auction
530+
active := !as.IsPriceAuction()
529531
parameters := make([]*types.PriceMonitoringTrigger, 0, len(settings.Parameters.Triggers))
530532
for _, p := range settings.Parameters.Triggers {
531533
p := *p
@@ -541,7 +543,7 @@ func computeBoundsAndHorizons(settings *types.PriceMonitoringSettings) (map[int6
541543
bounds := make([]*bound, 0, len(parameters))
542544
for _, p := range parameters {
543545
bounds = append(bounds, &bound{
544-
Active: true,
546+
Active: active,
545547
Trigger: p,
546548
})
547549
if _, ok := horizons[p.Horizon]; !ok {

0 commit comments

Comments
 (0)