code.vegaprotocol.io/vega@v0.79.0/core/integration/features/verified/Test-PnL.feature (about) 1 Feature: check if the realised PnL and unreaslied PnL is calculated according to spec in glossaries: https://github.com/vegaprotocol/specs/blob/master/glossaries/trading-and-protocol-glossary.md 2 3 Background: 4 Given the following network parameters are set: 5 | name | value | 6 | network.markPriceUpdateMaximumFrequency | 0s | 7 | limits.markets.maxPeggedOrders | 2 | 8 9 Scenario: 001, check PnL when traders partially close positions, 0007-POSN-011, 0007-POSN-012 10 Given the log normal risk model named "log-normal-risk-model-1": 11 | risk aversion | tau | mu | r | sigma | 12 | 0.000001 | 0.1 | 0 | 0 | 1.0 | 13 #risk factor short: 3.5569036 14 #risk factor long: 0.801225765 15 And the fees configuration named "fees-config-1": 16 | maker fee | infrastructure fee | 17 | 0.004 | 0.001 | 18 And the price monitoring named "price-monitoring-1": 19 | horizon | probability | auction extension | 20 | 1000 | 0.99 | 300 | 21 And the following network parameters are set: 22 | name | value | 23 | market.liquidity.bondPenaltyParameter | 0.2 | 24 Given the liquidity monitoring parameters: 25 | name | triggering ratio | time window | scaling factor | 26 | lqm-params | 0.10 | 24h | 1.0 | 27 And the markets: 28 | id | quote name | asset | liquidity monitoring | risk model | margin calculator | auction duration | fees | price monitoring | data source config | linear slippage factor | quadratic slippage factor | sla params | 29 | ETH/MAR22 | ETH | USD | lqm-params | log-normal-risk-model-1 | default-margin-calculator | 1 | fees-config-1 | price-monitoring-1 | default-eth-for-future | 0.25 | 0 | default-futures | 30 And the parties deposit on asset's general account the following amount: 31 | party | asset | amount | 32 | party0 | USD | 500000000 | 33 | party1 | USD | 100000000 | 34 | party2 | USD | 100000000 | 35 | party3 | USD | 100000000 | 36 37 And the average block duration is "1" 38 39 And the parties submit the following liquidity provision: 40 | id | party | market id | commitment amount | fee | lp type | 41 | lp1 | party0 | ETH/MAR22 | 5000000 | 0.001 | submission | 42 | lp1 | party0 | ETH/MAR22 | 5000000 | 0.001 | amendment | 43 And the parties place the following pegged iceberg orders: 44 | party | market id | peak size | minimum visible size | side | pegged reference | volume | offset | 45 | party0 | ETH/MAR22 | 4855 | 1 | sell | ASK | 6000 | 20 | 46 | party0 | ETH/MAR22 | 5155 | 1 | buy | BID | 6000 | 20 | 47 48 And the parties place the following orders: 49 | party | market id | side | volume | price | resulting trades | type | tif | reference | 50 | party1 | ETH/MAR22 | buy | 1 | 900 | 0 | TYPE_LIMIT | TIF_GTC | buy-ref-1 | 51 | party1 | ETH/MAR22 | buy | 1 | 990 | 0 | TYPE_LIMIT | TIF_GTC | buy-ref-1 | 52 | party1 | ETH/MAR22 | buy | 50 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | buy-ref-2 | 53 | party2 | ETH/MAR22 | sell | 50 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | sell-ref-3 | 54 | party2 | ETH/MAR22 | sell | 1 | 1010 | 0 | TYPE_LIMIT | TIF_GTC | sell-ref-1 | 55 | party2 | ETH/MAR22 | sell | 1 | 1100 | 0 | TYPE_LIMIT | TIF_GTC | sell-ref-2 | 56 57 Then the opening auction period ends for market "ETH/MAR22" 58 Then the auction ends with a traded volume of "50" at a price of "1000" 59 # target_stake = mark_price x max_oi x target_stake_scaling_factor x rf = 1000 x 10 x 1 x 0.1 60 And the insurance pool balance should be "0" for the market "ETH/MAR22" 61 And the market data for the market "ETH/MAR22" should be: 62 | mark price | trading mode | horizon | min bound | max bound | target stake | supplied stake | open interest | 63 | 1000 | TRADING_MODE_CONTINUOUS | 1000 | 986 | 1014 | 177845 | 5000000 | 50 | 64 65 #check the volume on the order book 66 Then the order book should have the following volumes for market "ETH/MAR22": 67 | side | price | volume | 68 | sell | 1100 | 1 | 69 | sell | 1030 | 4855 | 70 | sell | 1010 | 1 | 71 | buy | 990 | 1 | 72 | buy | 970 | 5155 | 73 | buy | 900 | 1 | 74 75 #check position (party0 has no position) 76 Then the parties should have the following profit and loss: 77 | party | volume | unrealised pnl | realised pnl | 78 | party1 | 50 | 0 | 0 | 79 | party2 | -50 | 0 | 0 | 80 81 When the parties place the following orders with ticks: 82 | party | market id | side | volume | price | resulting trades | type | tif | reference | 83 | party1 | ETH/MAR22 | sell | 5 | 1005 | 0 | TYPE_LIMIT | TIF_GTC | buy-p1-2 | 84 | party2 | ETH/MAR22 | buy | 5 | 1005 | 1 | TYPE_LIMIT | TIF_GTC | sell-p2-2 | 85 86 Then the parties should have the following profit and loss: 87 | party | volume | unrealised pnl | realised pnl | 88 | party1 | 45 | 225 | 25 | 89 | party2 | -45 | -225 | -25 | 90 91 When the parties place the following orders with ticks: 92 | party | market id | side | volume | price | resulting trades | type | tif | reference | 93 | party1 | ETH/MAR22 | sell | 5 | 995 | 0 | TYPE_LIMIT | TIF_GTC | buy-p1-3 | 94 | party2 | ETH/MAR22 | buy | 5 | 995 | 1 | TYPE_LIMIT | TIF_GTC | sell-p2-3 | 95 96 Then the parties should have the following profit and loss: 97 | party | volume | unrealised pnl | realised pnl | 98 | party1 | 40 | -200 | 0 | 99 | party2 | -40 | 200 | 0 | 100 101 When the parties place the following orders with ticks: 102 | party | market id | side | volume | price | resulting trades | type | tif | reference | 103 | party1 | ETH/MAR22 | sell | 2 | 1009 | 0 | TYPE_LIMIT | TIF_GTC | buy-p1-4 | 104 | party2 | ETH/MAR22 | buy | 2 | 1009 | 1 | TYPE_LIMIT | TIF_GTC | sell-p2-4 | 105 106 Then the parties should have the following profit and loss: 107 | party | volume | unrealised pnl | realised pnl | 108 | party1 | 38 | 342 | 18 | 109 | party2 | -38 | -342 | -18 | 110 111 Scenario: 002, check PnL at the settlement 112 113 Given time is updated to "2020-11-30T00:00:00Z" 114 115 Given the log normal risk model named "log-normal-risk-model-1": 116 | risk aversion | tau | mu | r | sigma | 117 | 0.000001 | 0.1 | 0 | 0 | 1.0 | 118 And the oracle spec for settlement data filtering data from "0xCAFECAFE1" named "ethDec21Oracle": 119 | property | type | binding | 120 | prices.ETH.value | TYPE_INTEGER | settlement data | 121 And the oracle spec for trading termination filtering data from "0xCAFECAFE1" named "ethDec21Oracle": 122 | property | type | binding | 123 | trading.terminated | TYPE_BOOLEAN | trading termination | 124 125 And the fees configuration named "fees-config-1": 126 | maker fee | infrastructure fee | 127 | 0 | 0 | 128 And the price monitoring named "price-monitoring-1": 129 | horizon | probability | auction extension | 130 | 1000 | 0.99 | 300 | 131 And the following network parameters are set: 132 | name | value | 133 | market.liquidity.bondPenaltyParameter | 0.2 | 134 And the markets: 135 | id | quote name | asset | liquidity monitoring | risk model | margin calculator | auction duration | fees | price monitoring | data source config | linear slippage factor | quadratic slippage factor | sla params | 136 | ETH/MAR22 | ETH | USD | lqm-params | log-normal-risk-model-1 | default-margin-calculator | 1 | fees-config-1 | price-monitoring-1 | ethDec21Oracle | 0.25 | 0 | default-futures | 137 And the parties deposit on asset's general account the following amount: 138 | party | asset | amount | 139 | party0 | USD | 500000000 | 140 | party1 | USD | 100000000 | 141 | party2 | USD | 100000000 | 142 | party3 | USD | 100000000 | 143 144 And the average block duration is "1" 145 146 And the parties submit the following liquidity provision: 147 | id | party | market id | commitment amount | fee | lp type | 148 | lp1 | party0 | ETH/MAR22 | 5000000 | 0 | submission | 149 | lp1 | party0 | ETH/MAR22 | 5000000 | 0 | amendment | 150 And the parties place the following pegged iceberg orders: 151 | party | market id | peak size | minimum visible size | side | pegged reference | volume | offset | 152 | party0 | ETH/MAR22 | 4855 | 1 | sell | ASK | 6000 | 20 | 153 | party0 | ETH/MAR22 | 5155 | 1 | buy | BID | 6000 | 20 | 154 155 And the parties place the following orders: 156 | party | market id | side | volume | price | resulting trades | type | tif | reference | 157 | party1 | ETH/MAR22 | buy | 1 | 900 | 0 | TYPE_LIMIT | TIF_GTC | buy-ref-1 | 158 | party1 | ETH/MAR22 | buy | 1 | 990 | 0 | TYPE_LIMIT | TIF_GTC | buy-ref-1 | 159 | party1 | ETH/MAR22 | buy | 50 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | buy-ref-2 | 160 | party2 | ETH/MAR22 | sell | 50 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | sell-ref-3 | 161 | party2 | ETH/MAR22 | sell | 1 | 1010 | 0 | TYPE_LIMIT | TIF_GTC | sell-ref-1 | 162 | party2 | ETH/MAR22 | sell | 1 | 1100 | 0 | TYPE_LIMIT | TIF_GTC | sell-ref-2 | 163 164 Then the opening auction period ends for market "ETH/MAR22" 165 Then the auction ends with a traded volume of "50" at a price of "1000" 166 # target_stake = mark_price x max_oi x target_stake_scaling_factor x rf = 1000 x 10 x 1 x 0.1 167 And the insurance pool balance should be "0" for the market "ETH/MAR22" 168 And the market data for the market "ETH/MAR22" should be: 169 | mark price | trading mode | horizon | min bound | max bound | target stake | supplied stake | open interest | 170 | 1000 | TRADING_MODE_CONTINUOUS | 1000 | 986 | 1014 | 177845 | 5000000 | 50 | 171 172 #check the volume on the order book 173 Then the order book should have the following volumes for market "ETH/MAR22": 174 | side | price | volume | 175 | sell | 1100 | 1 | 176 | sell | 1030 | 4855 | 177 | sell | 1010 | 1 | 178 | buy | 990 | 1 | 179 | buy | 970 | 5155 | 180 | buy | 900 | 1 | 181 182 #check position (party0 has no position) 183 Then the parties should have the following profit and loss: 184 | party | volume | unrealised pnl | realised pnl | 185 | party1 | 50 | 0 | 0 | 186 | party2 | -50 | 0 | 0 | 187 188 When the parties place the following orders with ticks: 189 | party | market id | side | volume | price | resulting trades | type | tif | reference | 190 | party1 | ETH/MAR22 | sell | 5 | 1005 | 0 | TYPE_LIMIT | TIF_GTC | buy-p1-2 | 191 | party2 | ETH/MAR22 | buy | 5 | 1005 | 1 | TYPE_LIMIT | TIF_GTC | sell-p2-2 | 192 193 Then the parties should have the following profit and loss: 194 | party | volume | unrealised pnl | realised pnl | 195 | party1 | 45 | 225 | 25 | 196 | party2 | -45 | -225 | -25 | 197 198 When the parties place the following orders with ticks: 199 | party | market id | side | volume | price | resulting trades | type | tif | reference | 200 | party1 | ETH/MAR22 | sell | 5 | 995 | 0 | TYPE_LIMIT | TIF_GTC | buy-p1-3 | 201 | party2 | ETH/MAR22 | buy | 5 | 995 | 1 | TYPE_LIMIT | TIF_GTC | sell-p2-3 | 202 203 Then the parties should have the following profit and loss: 204 | party | volume | unrealised pnl | realised pnl | 205 | party1 | 40 | -200 | 0 | 206 | party2 | -40 | 200 | 0 | 207 208 # party1 and party2 close their position 209 When the parties place the following orders with ticks: 210 | party | market id | side | volume | price | resulting trades | type | tif | reference | 211 | party1 | ETH/MAR22 | sell | 40 | 1009 | 0 | TYPE_LIMIT | TIF_GTC | buy-p1-4 | 212 | party2 | ETH/MAR22 | buy | 40 | 1009 | 1 | TYPE_LIMIT | TIF_GTC | sell-p2-4 | 213 214 # there is no closure of positions, so the realised PnL stays the same 215 Then the parties should have the following profit and loss: 216 | party | volume | unrealised pnl | realised pnl | 217 | party1 | 0 | 0 | 360 | 218 | party2 | 0 | 0 | -360 | 219 220 # party1 and party2 open their position 221 When the parties place the following orders with ticks: 222 | party | market id | side | volume | price | resulting trades | type | tif | reference | 223 | party1 | ETH/MAR22 | sell | 5 | 1003 | 0 | TYPE_LIMIT | TIF_GTC | buy-p1-5 | 224 | party2 | ETH/MAR22 | buy | 5 | 1003 | 1 | TYPE_LIMIT | TIF_GTC | sell-p2-5 | 225 226 And the market data for the market "ETH/MAR22" should be: 227 | mark price | trading mode | horizon | min bound | max bound | target stake | supplied stake | open interest | 228 | 1003 | TRADING_MODE_CONTINUOUS | 1000 | 986 | 1014 | 178378 | 5000000 | 5 | 229 230 Then the parties should have the following profit and loss: 231 | party | volume | unrealised pnl | realised pnl | 232 | party1 | -5 | 0 | 360 | 233 | party2 | 5 | 0 | -360 | 234 235 And the parties should have the following account balances: 236 | party | asset | market id | margin | general | 237 | party1 | USD | ETH/MAR22 | 21534 | 99978826 | 238 | party2 | USD | ETH/MAR22 | 6324 | 99993316 | 239 240 #margin+general-initial = 21534+99978826-100000000=360 which is matching with realised pnl for party1 241 #margin+general-initial = 6324+99993316-100000000=-360 which is matching with realised pnl for party2 242 243 When the oracles broadcast data signed with "0xCAFECAFE1": 244 | name | value | 245 | trading.terminated | true | 246 247 And time is updated to "2021-03-01T01:01:01Z" 248 Then the market state should be "STATE_TRADING_TERMINATED" for the market "ETH/MAR22" 249 250 When the oracles broadcast data signed with "0xCAFECAFE1": 251 | name | value | 252 | prices.ETH.value | 800 | 253 254 And then the network moves ahead "10" blocks 255 256 # MTM with the settlement price 800, will add (1003-800)*5=1015 into general account of party1, so new general account will be 99978826+1015=99979841 257 # MTM with the settlement price 800, will reduce (1003-800)*5=1015 from general account of party2, so new general account will be 99994719-1015=99993704 258 259 # Check that party positions and overall account balances are the same as before auction start (accounting for a settlement transfer of 200 from party2 to party1) 260 Then the parties should have the following profit and loss: 261 | party | volume | unrealised pnl | realised pnl | 262 | party1 | -5 | 0 | 1375 | 263 | party2 | 5 | 0 | -1375 | 264 265 # all the asset from margin account should be moved to general account: 266 # party1: 21534+99979841=100001375 267 # party2: 4921+99993704=99998625 268 And the parties should have the following account balances: 269 | party | asset | market id | margin | general | 270 | party1 | USD | ETH/MAR22 | 0 | 100001375 | 271 | party2 | USD | ETH/MAR22 | 0 | 99998625 | 272