-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10148 from vegaprotocol/0053-PERP-027
feat: perps test for ac 0053-PERP-027
- Loading branch information
Showing
3 changed files
with
246 additions
and
0 deletions.
There are no files selected for viewing
143 changes: 143 additions & 0 deletions
143
core/integration/features/settlement/0053-PERP-027-twap-calculation.feature
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
Feature: Test internal and external twap calculation | ||
|
||
Background: | ||
# epoch time is 1602806400 | ||
Given time is updated to "2020-10-16T00:00:00Z" | ||
And the perpetual oracles from "0xCAFECAFE1": | ||
| name | asset | settlement property | settlement type | schedule property | schedule type | margin funding factor | interest rate | clamp lower bound | clamp upper bound | quote name | settlement decimals | | ||
| perp-oracle | USD | perp.ETH.value | TYPE_INTEGER | perp.funding.cue | TYPE_TIMESTAMP | 0.5 | 0.00 | 0.0 | 0.0 | ETH | 1 | | ||
And the liquidity sla params named "SLA": | ||
| price range | commitment min time fraction | performance hysteresis epochs | sla competition factor | | ||
| 1.0 | 0.5 | 1 | 1.0 | | ||
|
||
And the markets: | ||
| id | quote name | asset | risk model | margin calculator | auction duration | fees | price monitoring | data source config | linear slippage factor | quadratic slippage factor | position decimal places | market type | sla params | | ||
| ETH/DEC19 | ETH | USD | default-simple-risk-model-3 | default-margin-calculator | 1 | default-none | default-none | perp-oracle | 1e6 | 1e6 | -3 | perp | default-futures | | ||
|
||
And the following network parameters are set: | ||
| name | value | | ||
| market.auction.minimumDuration | 1 | | ||
| limits.markets.maxPeggedOrders | 2 | | ||
And the following network parameters are set: | ||
| name | value | | ||
| network.markPriceUpdateMaximumFrequency | 0s | | ||
And the average block duration is "1" | ||
|
||
@Perpetual @twap | ||
Scenario: 0053-PERP-027 Internal and External TWAP calculation | ||
Given the following network parameters are set: | ||
| name | value | | ||
| network.markPriceUpdateMaximumFrequency | 120s | | ||
And the parties deposit on asset's general account the following amount: | ||
| party | asset | amount | | ||
| party1 | USD | 10000000 | | ||
| party2 | USD | 10000000 | | ||
| party3 | USD | 10000000 | | ||
| aux | USD | 100000000 | | ||
| aux2 | USD | 100000000 | | ||
| lpprov | USD | 100000000 | | ||
|
||
When the parties submit the following liquidity provision: | ||
| id | party | market id | commitment amount | fee | lp type | | ||
| lp1 | lpprov | ETH/DEC19 | 100000 | 0.001 | submission | | ||
|
||
# move market to continuous | ||
And the parties place the following orders: | ||
| party | market id | side | volume | price | resulting trades | type | tif | | ||
| lpprov | ETH/DEC19 | buy | 1000 | 5 | 0 | TYPE_LIMIT | TIF_GTC | | ||
| aux | ETH/DEC19 | buy | 1 | 5 | 0 | TYPE_LIMIT | TIF_GTC | | ||
| lpprov | ETH/DEC19 | sell | 1000 | 15 | 0 | TYPE_LIMIT | TIF_GTC | | ||
| aux | ETH/DEC19 | sell | 1 | 15 | 0 | TYPE_LIMIT | TIF_GTC | | ||
| aux2 | ETH/DEC19 | buy | 1 | 11 | 0 | TYPE_LIMIT | TIF_GTC | | ||
| aux | ETH/DEC19 | sell | 1 | 11 | 0 | TYPE_LIMIT | TIF_GTC | | ||
|
||
And the market data for the market "ETH/DEC19" should be: | ||
| target stake | supplied stake | | ||
| 12100 | 100000 | | ||
Then the opening auction period ends for market "ETH/DEC19" | ||
|
||
Given the trading mode should be "TRADING_MODE_CONTINUOUS" for the market "ETH/DEC19" | ||
When time is updated to "2020-10-16T00:02:00Z" | ||
# 1602806400 + 120s = 1602806520 | ||
# funding period is ended with perp.funding.cue | ||
Then the oracles broadcast data with block time signed with "0xCAFECAFE1": | ||
| name | value | time offset | | ||
| perp.ETH.value | 110 | -1s | | ||
| perp.funding.cue | 1602806520 | 0s | | ||
|
||
# 1 min in to the next funding period | ||
Given time is updated to "2020-10-16T00:03:00Z" | ||
When the parties place the following orders: | ||
| party | market id | side | volume | price | resulting trades | type | tif | | ||
| party1 | ETH/DEC19 | buy | 1 | 11 | 0 | TYPE_LIMIT | TIF_GTC | | ||
| party2 | ETH/DEC19 | sell | 1 | 11 | 1 | TYPE_LIMIT | TIF_GTC | | ||
|
||
And the oracles broadcast data with block time signed with "0xCAFECAFE1": | ||
| name | value | time offset | | ||
| perp.ETH.value | 90 | -1s | | ||
|
||
# 3 min in to the next funding period | ||
Given time is updated to "2020-10-16T00:05:00Z" | ||
And the mark price should be "11" for the market "ETH/DEC19" | ||
When the parties place the following orders: | ||
| party | market id | side | volume | price | resulting trades | type | tif | | ||
| party1 | ETH/DEC19 | buy | 1 | 10 | 0 | TYPE_LIMIT | TIF_GTC | | ||
| party2 | ETH/DEC19 | sell | 1 | 10 | 1 | TYPE_LIMIT | TIF_GTC | | ||
|
||
Then the oracles broadcast data with block time signed with "0xCAFECAFE1": | ||
| name | value | time offset | | ||
| perp.ETH.value | 100 | -1s | | ||
|
||
|
||
# 5 min in to the next funding period | ||
Given time is updated to "2020-10-16T00:07:00Z" | ||
And the mark price should be "10" for the market "ETH/DEC19" | ||
When the parties place the following orders: | ||
| party | market id | side | volume | price | resulting trades | type | tif | | ||
| party1 | ETH/DEC19 | buy | 1 | 9 | 0 | TYPE_LIMIT | TIF_GTC | | ||
| party2 | ETH/DEC19 | sell | 1 | 9 | 1 | TYPE_LIMIT | TIF_GTC | | ||
|
||
Then the oracles broadcast data with block time signed with "0xCAFECAFE1": | ||
| name | value | time offset | | ||
| perp.ETH.value | 120 | -1s | | ||
|
||
# 6 min in to the funding period emit spot price | ||
Given time is updated to "2020-10-16T00:08:00Z" | ||
And the oracles broadcast data with block time signed with "0xCAFECAFE1": | ||
| name | value | time offset | | ||
| perp.ETH.value | 110 | -1s | | ||
|
||
# 7 mins in to the funding period | ||
When time is updated to "2020-10-16T00:09:00Z" | ||
|
||
And the mark price should be "9" for the market "ETH/DEC19" | ||
|
||
And the parties place the following orders: | ||
| party | market id | side | volume | price | resulting trades | type | tif | | ||
| party1 | ETH/DEC19 | buy | 1 | 8 | 0 | TYPE_LIMIT | TIF_GTC | | ||
| party2 | ETH/DEC19 | sell | 1 | 8 | 1 | TYPE_LIMIT | TIF_GTC | | ||
|
||
Then the oracles broadcast data with block time signed with "0xCAFECAFE1": | ||
| name | value | time offset | | ||
| perp.ETH.value | 80 | -1s | | ||
|
||
# 9 min in to the next funding period | ||
Given time is updated to "2020-10-16T00:11:00Z" | ||
And the mark price should be "8" for the market "ETH/DEC19" | ||
When the parties place the following orders: | ||
| party | market id | side | volume | price | resulting trades | type | tif | | ||
| party1 | ETH/DEC19 | buy | 1 | 7 | 0 | TYPE_LIMIT | TIF_GTC | | ||
| party2 | ETH/DEC19 | sell | 1 | 7 | 1 | TYPE_LIMIT | TIF_GTC | | ||
|
||
Then the oracles broadcast data with block time signed with "0xCAFECAFE1": | ||
| name | value | time offset | | ||
| perp.ETH.value | 140 | -1s | | ||
|
||
# if the funding period ended here, check the twap | ||
Given time is updated to "2020-10-16T00:12:00Z" | ||
|
||
# in theory internal TWAP = 9.3 external TWAP = 10.3 | ||
# but these are type int so the decimal is truncated | ||
Then the product data for the market "ETH/DEC19" should be: | ||
| internal twap | external twap | | ||
| 9 | 10 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// Copyright (C) 2023 Gobalsky Labs Limited | ||
// | ||
// This program is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU Affero General Public License as | ||
// published by the Free Software Foundation, either version 3 of the | ||
// License, or (at your option) any later version. | ||
// | ||
// This program is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU Affero General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU Affero General Public License | ||
// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
package steps | ||
|
||
import ( | ||
"fmt" | ||
|
||
"code.vegaprotocol.io/vega/core/types" | ||
|
||
"github.com/cucumber/godog" | ||
) | ||
|
||
func TheProductDataShouldBe(engine Execution, mID string, data *godog.Table) error { | ||
actual, err := engine.GetMarketData(mID) | ||
if err != nil { | ||
return err | ||
} | ||
for _, row := range parseProductDataTable(data) { | ||
expect := ProductDataWrapper{ | ||
row: row, | ||
} | ||
err := checkProductData(*actual.ProductData, expect) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func checkProductData(pd types.ProductData, row ProductDataWrapper) error { | ||
expectedInternalTwap := row.InternalTWAP() | ||
actualInternalTwap := pd.Data.IntoProto().GetPerpetualData().InternalTwap | ||
|
||
if expectedInternalTwap != actualInternalTwap { | ||
return fmt.Errorf("expected '%s' for InternalTWAP, instead got '%s'", expectedInternalTwap, actualInternalTwap) | ||
} | ||
|
||
expectedExternalTwap := row.ExternalTWAP() | ||
actualExternalTwap := pd.Data.IntoProto().GetPerpetualData().ExternalTwap | ||
if expectedExternalTwap != actualExternalTwap { | ||
return fmt.Errorf("expected '%s' for InternalTWAP, instead got '%s'", expectedExternalTwap, actualExternalTwap) | ||
} | ||
|
||
expectedFundingPayment, b := row.FundingPayment() | ||
actualFundingPayment := pd.Data.IntoProto().GetPerpetualData().FundingPayment | ||
if b && expectedFundingPayment != actualFundingPayment { | ||
return fmt.Errorf("expected '%s' for InternalTWAP, instead got '%s'", expectedFundingPayment, actualFundingPayment) | ||
} | ||
|
||
expectedFundingRate, b := row.FundingRate() | ||
actualFundingRate := pd.Data.IntoProto().GetPerpetualData().FundingRate | ||
if b && expectedFundingRate != actualFundingRate { | ||
return fmt.Errorf("expected '%s' for InternalTWAP, instead got '%s'", expectedFundingRate, actualFundingRate) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func parseProductDataTable(table *godog.Table) []RowWrapper { | ||
return StrictParseTable(table, []string{ | ||
"internal twap", | ||
"external twap", | ||
}, []string{ | ||
"funding payment", | ||
"funding rate", | ||
}) | ||
} | ||
|
||
type ProductDataWrapper struct { | ||
row RowWrapper | ||
} | ||
|
||
func (f ProductDataWrapper) InternalTWAP() string { | ||
return f.row.MustStr("internal twap") | ||
} | ||
|
||
func (f ProductDataWrapper) ExternalTWAP() string { | ||
return f.row.MustStr("external twap") | ||
} | ||
|
||
func (f ProductDataWrapper) FundingPayment() (string, bool) { | ||
return f.row.StrB("funding payment") | ||
} | ||
|
||
func (f ProductDataWrapper) FundingRate() (string, bool) { | ||
return f.row.StrB("funding rate") | ||
} |