diff --git a/protocol/0016-PFUT-product_builtin_future.md b/protocol/0016-PFUT-product_builtin_future.md index 83f49405a..31a418d8a 100644 --- a/protocol/0016-PFUT-product_builtin_future.md +++ b/protocol/0016-PFUT-product_builtin_future.md @@ -116,3 +116,6 @@ Optional parameters: 1. When `max_price` is specified and the market is ran in a [fully-collateralised mode](./0019-MCAL-margin_calculator.md#fully-collateralised) and a party opens a long position at a `max_price`, no closeout happens when mark to market settlement is carried out at a price of `0`. (0016-PFUT-023) 1. When `max_price` is specified and the market is ran in a [fully-collateralised mode](./0019-MCAL-margin_calculator.md#fully-collateralised) and a party opens a short position at a price of `0`, no closeout happens when mark to market settlement is carried out at a `max_price`. (0016-PFUT-024) 1. Futures market can be created without specifying any of the [optional paramters](#1-product-parameters). (0016-PFUT-025) +1. Futures market can be created with a wrapped risk model with [hardcoded risk factors](./0018-RSKM-quant_risk_models.ipynb). (0016-PFUT-026) +1. Updating a risk model on a futures market with regular risk model to a wrapped risk model with [hardcoded risk factors](./0018-RSKM-quant_risk_models.ipynb) results in recalculation of all margin levels in line with hardcoded values and collateral search/release where appropriate. (0016-PFUT-027) +1. Updating a risk model on a futures market with a wrapped risk model with [hardcoded risk factors](./0018-RSKM-quant_risk_models.ipynb) to a regular risk model results in recalculation of all margin levels in line with the specified risk model (hardcoded value are no longer used) and collateral search/release where appropriate. (0016-PFUT-028) diff --git a/protocol/0018-RSKM-quant_risk_models.ipynb b/protocol/0018-RSKM-quant_risk_models.ipynb index 36a6205bf..ae8b7633c 100644 --- a/protocol/0018-RSKM-quant_risk_models.ipynb +++ b/protocol/0018-RSKM-quant_risk_models.ipynb @@ -1,166 +1,170 @@ { - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Quantitative risk models\n", - "\n", - "\n", - "## Summary\n", - "Vega can use different risk models as for different underlying assets and different derivatives one has to choose an appropriate model. Every quantitative risk model used by Vega needs to be able to provide the following.\n", - "\n", - "1. Risk factors, currently for futures but for other products as Vega develops. The risk factor *linearizes* the risk measure used for margin requirements. See `0019-MCAL-margin_calculator.md` for details of how these are used.\n", - "1. Given a probability level $\\alpha \\in (0.9,1)$, time horizon $\\tau > 0$ and current price $S$ return the $\\Delta^-$ and $\\Delta^+$ such that \n", - "$$\n", - "\\mathbb P(S-\\Delta^- \\leq S_\\tau \\leq S+\\Delta^+) \\geq 1-\\alpha\\,.\n", - "$$\n", - "See the price monitoring spec for details of how these are used.\n", - "1. Given current price $S$, time horizon $\\tau > 0$, a list of price levels $S < S_1 < S_2 < \\cdots < S_N^+$ return the probability of trading at each of these price levels defined below. See \"Probability weighted liquidity measure\" spec for how these are used.\n", - "1. Calibration outputs (not required for first release of Mainnet, model parameters result from governance vote per market).\n", - "\n", - "The “quant risk suite” with Vega consists a _quantitative risk model_, _margin calculator_ and _calibrator_.\n", - "\n", - "A market parameter specifies which _quantitative risk model_ is used for a given risk universe (market, see Section 3.5 of the Vega white paper).\n", - "\n", - "\n", - "## Reference-level explanation\n", - "\n", - "### _Quantitative risk model_\n", - "The relevant quantitative risk model for a market is specified on a tradeable instrument. The role of the quantitative risk model is to calculate **risk factors** which are used in the **_margin calculator_** (see below)\n", - "as well as probabilities of various price moves used for price monitoring and measuring liquidity. \n", - "\n", - "To achieve this it utilises the quantitative maths library.\n", - "\n", - "The quantitative risk model may take one or more of the following as inputs:\n", - "* risk parameters (e.g. volatility)\n", - "* product parameters (e.g. minimum contract size)\n", - "* order book data (full current order book with volume aggregated at price levels)\n", - "* position data (for each trader)\n", - "* event data (e.g. passage of time) (Not for Futures / Nicenet )\n", - "\n", - "The quantitative risk model returns two risk factors:\n", - "\n", - "1. Rounded Long position risk factor\n", - "1. Rounded Short position risk factor\n", - "\n", - "The quantitative risk model is able to utilise a relevant method from the quant math library to perform the calculations.\n", - "\n", - "The quant math library calculates:\n", - "1. Long position risk factor\n", - "1. Short position risk factor\n", - "1. Guaranteed accuracy (applicable to both risk factors)\n", - "1. The max move up/down ($\\Delta^-$ and $\\Delta^+$ defined in the [Summary](#Summary)) given current price level and a projection horizon such that the resulting prices are within a specified probability level.\n", - "1. Probability of trading at a given price level (see below).\n", - "\n", - "#### Calculating the probability of trading\n", - "This is well defined only if we have best bid $S_{\\text{best bid}}$ and best ask $S_{\\text{best ask}}$ on the order book. \n", - "The rest of information comes from the quant risk model that has the probability density of price distribution at time horizon $\\tau > 0$ i.e. we have \n", - "$$\n", - "f(x;S) = \\mathbb P(S_\\tau \\in [x, x+dx) | S)\\,, \n", - "$$\n", - "where $S$ is current price level and $S_\\tau$ is a future price, after time $\\tau > 0$.\n", - "\n", - "Given a price level $S$, time horizon $\\tau > 0$, a list of price levels $S < S_1 < S_2 < \\cdots < S_{N^+}$ or a list of price levels $S > S_1 > S_2 > \\cdots > S_{N^-}$ return the probability of trading $p(S_i)$ at each of these as defined below. \n", - "\n", - "1. If $S_i \\in [S_{\\text{best bid}}, S_{\\text{best ask}}]$ for $i=1,\\ldots,N^+$ or $i=1,\\ldots,N^-$ return $p(S_i) = 1$. \n", - "That is, between best bid and best ask the probability of trading is one. \n", - "2. If $S_i > S_{\\text{best ask}}$ for $i=1,\\ldots,N^+$ then return \n", - "$$\n", - "p(S_i) = \\int_{S_i}^{S_{max}} f(x;S_{\\text{best ask}})\\,dx\n", - "$$\n", - "3. If $S_i < S_{\\text{best bid}}$ for $ =1,\\ldots,N^-$ then return\n", - "$$\n", - "p(S_i) = \\int_{S_{min}}^{S_i} f(x;S_{\\text{best bid}})\\,dx\\,.\n", - "$$\n", - "\n", - "#### When to not update risk factors\n", - "\n", - "The call to the quantitative math library should *only* be made if any of the above inputs have changed from last time; if no input has changed then the quantitative risk model doesn't need to update the risk factors. \n", - "\n", - "#### When to update risk factors\n", - "\n", - "Risk factors are an input to the [margin calculation](./0019-MCAL-margin_calculators.md) and are calculated using a quantitative risk model.\n", - "\n", - "Risk factors are updated if \n", - "* An update risk factors call is not already in progress asynchronously; AND\n", - "* Any of the required inputs to risk factors change. Examples 1. when the calibrator has updated any risk parameters. 2. a specified period of time has elapsed (period can = 0 for always recalculate) for re-calculating risk factors. This period of time is defined as a risk parameter (see [market framework](./0001-MKTF-market_framework.md)).\n", - "\n", - "Risk factors are also updated if on creation of a new market that does not yet have risk factors, as any active market needs to have risk factors.\n", - "\n", - "#### Risk factors and consensus\n", - "\n", - "All new risk factors will need to be agreed via consensus when either (or both): \n", - "- asynchronous updates\n", - "- the other cause will be due to floating point non-determinism\n", - "\n", - "The rounding should remove all digits beyond the guaranteed accuracy. \n", - "\n", - "Example: If `Long position risk factor = 1.23456789` and `Guaranteed accuracy = 0.001` then \n", - "`Rounded Long position risk factor = 1.234`. \n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Wrapped risk models\n", - "\n", - "For certain products it might be possible to certain aspects of market's reliance on risk model while keeping other dependencies in places.\n", - "\n", - "### Fully-collateralised\n", - "\n", - "For products with pre-defined finite price range (e.g. [a futures contracts with [`max_price`](./0016-PFUT-product_builtin_future.md#1-product-parameters) parameter specified]) it is possible to make positions fully-collateralised so that for any position a margin can be chosen such that the party stays solvent at any price the market may attain. Using this mode removes the reliance on risk-factors, however the risk model might still be used for other aspects of market's functioning. To signify this and make it transparent to the user a fully-collateralised wrapped risk model is used in those cases." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Acceptance Criteria\n", - "\n", - "1. Different markets can have a different risk model (i.e. a market A can be specified to run with risk model R1 while market B can be specified to run with risk model R2). (0018-RSKM-001)\n", - "1. If any of the input data has changed then an update to risk factors is initiated. (0018-RSKM-003)\n", - "1. Risk factors are agreed upon by consensus. (0018-RSKM-004)\n", - "1. If the risk factor calculation reports \"guaranteed accuracy\" then the risk factors are appropriately rounded. (0018-RSKM-005)\n", - "1. Quant risk suite can compute max move up/down ($\\Delta^-$ and $\\Delta^+$) given current price level and a projection horizon such that the resulting prices are within a specified probability level. (0018-RSKM-007)\n", - "1. Quant risk suite can compute probability of trading at a given level. (0018-RSKM-008)\n", - "1. Lognormal risk model has defined ranges of valid parameters and market proposals and market update proposals are checked against these. The ranges can be found in core (https://github.com/vegaprotocol/vega/blob/develop/commands/proposal_submission.go#L820). (0018-RSKM-009)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.6" - }, - "vscode": { - "interpreter": { - "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" - } - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Quantitative risk models\n", + "\n", + "\n", + "## Summary\n", + "Vega can use different risk models as for different underlying assets and different derivatives one has to choose an appropriate model. Every quantitative risk model used by Vega needs to be able to provide the following.\n", + "\n", + "1. Risk factors, currently for futures but for other products as Vega develops. The risk factor *linearizes* the risk measure used for margin requirements. See `0019-MCAL-margin_calculator.md` for details of how these are used.\n", + "1. Given a probability level $\\alpha \\in (0.9,1)$, time horizon $\\tau > 0$ and current price $S$ return the $\\Delta^-$ and $\\Delta^+$ such that \n", + "$$\n", + "\\mathbb P(S-\\Delta^- \\leq S_\\tau \\leq S+\\Delta^+) \\geq 1-\\alpha\\,.\n", + "$$\n", + "See the price monitoring spec for details of how these are used.\n", + "1. Given current price $S$, time horizon $\\tau > 0$, a list of price levels $S < S_1 < S_2 < \\cdots < S_N^+$ return the probability of trading at each of these price levels defined below. See \"Probability weighted liquidity measure\" spec for how these are used.\n", + "1. Calibration outputs (not required for first release of Mainnet, model parameters result from governance vote per market).\n", + "\n", + "The “quant risk suite” with Vega consists a _quantitative risk model_, _margin calculator_ and _calibrator_.\n", + "\n", + "A market parameter specifies which _quantitative risk model_ is used for a given risk universe (market, see Section 3.5 of the Vega white paper).\n", + "\n", + "\n", + "## Reference-level explanation\n", + "\n", + "### _Quantitative risk model_\n", + "The relevant quantitative risk model for a market is specified on a tradeable instrument. The role of the quantitative risk model is to calculate **risk factors** which are used in the **_margin calculator_** (see below)\n", + "as well as probabilities of various price moves used for price monitoring and measuring liquidity. \n", + "\n", + "To achieve this it utilises the quantitative maths library.\n", + "\n", + "The quantitative risk model may take one or more of the following as inputs:\n", + "* risk parameters (e.g. volatility)\n", + "* product parameters (e.g. minimum contract size)\n", + "* order book data (full current order book with volume aggregated at price levels)\n", + "* position data (for each trader)\n", + "* event data (e.g. passage of time) (Not for Futures / Nicenet )\n", + "\n", + "The quantitative risk model returns two risk factors:\n", + "\n", + "1. Rounded Long position risk factor\n", + "1. Rounded Short position risk factor\n", + "\n", + "The quantitative risk model is able to utilise a relevant method from the quant math library to perform the calculations.\n", + "\n", + "The quant math library calculates:\n", + "1. Long position risk factor\n", + "1. Short position risk factor\n", + "1. Guaranteed accuracy (applicable to both risk factors)\n", + "1. The max move up/down ($\\Delta^-$ and $\\Delta^+$ defined in the [Summary](#Summary)) given current price level and a projection horizon such that the resulting prices are within a specified probability level.\n", + "1. Probability of trading at a given price level (see below).\n", + "\n", + "#### Calculating the probability of trading\n", + "This is well defined only if we have best bid $S_{\\text{best bid}}$ and best ask $S_{\\text{best ask}}$ on the order book. \n", + "The rest of information comes from the quant risk model that has the probability density of price distribution at time horizon $\\tau > 0$ i.e. we have \n", + "$$\n", + "f(x;S) = \\mathbb P(S_\\tau \\in [x, x+dx) | S)\\,, \n", + "$$\n", + "where $S$ is current price level and $S_\\tau$ is a future price, after time $\\tau > 0$.\n", + "\n", + "Given a price level $S$, time horizon $\\tau > 0$, a list of price levels $S < S_1 < S_2 < \\cdots < S_{N^+}$ or a list of price levels $S > S_1 > S_2 > \\cdots > S_{N^-}$ return the probability of trading $p(S_i)$ at each of these as defined below. \n", + "\n", + "1. If $S_i \\in [S_{\\text{best bid}}, S_{\\text{best ask}}]$ for $i=1,\\ldots,N^+$ or $i=1,\\ldots,N^-$ return $p(S_i) = 1$. \n", + "That is, between best bid and best ask the probability of trading is one. \n", + "2. If $S_i > S_{\\text{best ask}}$ for $i=1,\\ldots,N^+$ then return \n", + "$$\n", + "p(S_i) = \\int_{S_i}^{S_{max}} f(x;S_{\\text{best ask}})\\,dx\n", + "$$\n", + "3. If $S_i < S_{\\text{best bid}}$ for $ =1,\\ldots,N^-$ then return\n", + "$$\n", + "p(S_i) = \\int_{S_{min}}^{S_i} f(x;S_{\\text{best bid}})\\,dx\\,.\n", + "$$\n", + "\n", + "#### When to not update risk factors\n", + "\n", + "The call to the quantitative math library should *only* be made if any of the above inputs have changed from last time; if no input has changed then the quantitative risk model doesn't need to update the risk factors. \n", + "\n", + "#### When to update risk factors\n", + "\n", + "Risk factors are an input to the [margin calculation](./0019-MCAL-margin_calculators.md) and are calculated using a quantitative risk model.\n", + "\n", + "Risk factors are updated if \n", + "* An update risk factors call is not already in progress asynchronously; AND\n", + "* Any of the required inputs to risk factors change. Examples 1. when the calibrator has updated any risk parameters. 2. a specified period of time has elapsed (period can = 0 for always recalculate) for re-calculating risk factors. This period of time is defined as a risk parameter (see [market framework](./0001-MKTF-market_framework.md)).\n", + "\n", + "Risk factors are also updated if on creation of a new market that does not yet have risk factors, as any active market needs to have risk factors.\n", + "\n", + "#### Risk factors and consensus\n", + "\n", + "All new risk factors will need to be agreed via consensus when either (or both): \n", + "- asynchronous updates\n", + "- the other cause will be due to floating point non-determinism\n", + "\n", + "The rounding should remove all digits beyond the guaranteed accuracy. \n", + "\n", + "Example: If `Long position risk factor = 1.23456789` and `Guaranteed accuracy = 0.001` then \n", + "`Rounded Long position risk factor = 1.234`. \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Wrapped risk models\n", + "\n", + "For certain products it might be possible to certain aspects of market's reliance on risk model while keeping other dependencies in places.\n", + "\n", + "### Fully-collateralised\n", + "\n", + "For products with pre-defined finite price range (e.g. [a futures contracts with [`max_price`](./0016-PFUT-product_builtin_future.md#1-product-parameters) parameter specified]) it is possible to make positions fully-collateralised so that for any position a margin can be chosen such that the party stays solvent at any price the market may attain. Using this mode removes the reliance on risk-factors, however the risk model might still be used for other aspects of market's functioning. To signify this and make it transparent to the user a fully-collateralised wrapped risk model is used in those cases.\n", + "\n", + "### Hardcoded risk factors\n", + "\n", + "For markets which should ignore model-implied risk factors and use hardcoded values instead a wrapped risk model should be used to signify that. The specified risk factors should be used wherever risk factors are expected and other model-implied outputs should be used for all other calculations based on a risk-model." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Acceptance Criteria\n", + "\n", + "1. Different markets can have a different risk model (i.e. a market A can be specified to run with risk model R1 while market B can be specified to run with risk model R2). (0018-RSKM-001)\n", + "1. If any of the input data has changed then an update to risk factors is initiated. (0018-RSKM-003)\n", + "1. Risk factors are agreed upon by consensus. (0018-RSKM-004)\n", + "1. If the risk factor calculation reports \"guaranteed accuracy\" then the risk factors are appropriately rounded. (0018-RSKM-005)\n", + "1. Quant risk suite can compute max move up/down ($\\Delta^-$ and $\\Delta^+$) given current price level and a projection horizon such that the resulting prices are within a specified probability level. (0018-RSKM-007)\n", + "1. Quant risk suite can compute probability of trading at a given level. (0018-RSKM-008)\n", + "1. Lognormal risk model has defined ranges of valid parameters and market proposals and market update proposals are checked against these. The ranges can be found in core (https://github.com/vegaprotocol/vega/blob/develop/commands/proposal_submission.go#L820). (0018-RSKM-009)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.6" + }, + "vscode": { + "interpreter": { + "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file diff --git a/protocol/0019-MCAL-margin_calculator.md b/protocol/0019-MCAL-margin_calculator.md index e2146aefd..22b575027 100644 --- a/protocol/0019-MCAL-margin_calculator.md +++ b/protocol/0019-MCAL-margin_calculator.md @@ -435,6 +435,10 @@ Assume a [capped future](./0093-CFUT-product_builtin_capped_future.md) market wi - Party B posts an order to buy `30` contracts at a price of `16`, the orders get placed on the book, the maintenance and initial margin levels for party B grow to `1180`, and the margin account balance remains unchanged at `700` and the order margin account balance grows to `480 = max (5 * (100 - 20), 30 * 16)`. The position remains unchanged at `-10`. (0019-MCAL-157) - Party A posts an order to sell `20` contracts at a price of `17`. A trade is generated for `10` contracts at a price of `18` with party B. A sell order for `10` contracts at a price of `17` from party A gets added to the book. The maintenance and initial margin levels for party A is now `10 * (100 - 17) = 830`, the position is `0` and the remaining volume on the book from this party is `10` at a price of `18`. Party A lost `120` on its position, hence `830 - (300 - 120) = 410` additional funds get moved from the general account as part of the transaction which submitted the order to sell `20` at `17`. Party B now has a position of `0` and following orders open on the book: sell `5` at `20` and buy `30` at `16`. The maintenance and initial margin levels are `max(5 * (100 - 20), 30 * 16) = 480`. The margin account momentarily becomes `820` (`700` + `120` of gains from the now closed position of `-10`), order margin account balance is `480`, hence `820` gets released back into the general account and margin account becomes `0`. (0019-MCAL-158) +## Acceptance Criteria (Hardcoded risk factors) + +- When a wrapped model with hardcoded risk factors is used then margin calculations depend entire on the hardcoded values and updating the nested risk model has no effect on margins (0019-MCAL-159) + ## Summary The *margin calculator* returns the set of margin levels for a given *actual position*, along with the amount of additional margin (if any) required to support the party's *potential position* (i.e. active orders including any that are parked/untriggered/undeployed). diff --git a/protocol/0032-PRIM-price_monitoring.md b/protocol/0032-PRIM-price_monitoring.md index 480b05572..5a51f15ba 100644 --- a/protocol/0032-PRIM-price_monitoring.md +++ b/protocol/0032-PRIM-price_monitoring.md @@ -4,8 +4,10 @@ The dynamics of market price movements are such that prices don't always represent the participants' true average view of the price, but are instead artefacts of the market microstructure: sometimes low liquidity and/or a large quantity of order volume can cause the price to diverge from the true market price. It is impossible to tell at any point in time if this has happened or not. -As a result, we assume that relatively small moves are "real" and that larger moves might not be. Price monitoring exists to determine the real price in the latter case. Distinguishing between small and large moves can be highly subjective and market-dependent. We are going to rely on the risk model to formalise this process. Risk model can be used to obtain the probability distribution of prices at a future point in time given the current price. A price monitoring trigger can be constructed using a fixed horizon and probability level. +As a result, we assume that relatively small moves are "real" and that larger moves might not be. Price monitoring exists to determine the real price in the latter case. Distinguishing between small and large moves can be highly subjective and market-dependent. +We are going to rely on the risk model to formalise this process. Risk model can be used to obtain the probability distribution of prices at a future point in time given the current price. A price monitoring trigger can be constructed using a fixed horizon and probability level. To give an example: get the price distribution in an hour as implied by the risk model given the current mid price, if after the hour has passed and the actual mid price is beyond what the model implied (either too low or too high) with some chosen probability level (say 99%), then we'd characterise such market move as large. In general we may want to use a few such triggers per market (i.e. different horizon and probability level pairs). The framework should be able to trigger a price protection auction period with any valid trading mode. +We're also going to allow specifying triggers directly as the maximum valid moves with respect to the reference price. In that case the `maxUpMoveFactor`, `maxDownMoveFactor` can be specified for a given horizon, such that a price is considered valid as long as it's in the range `[reference_price(horizon) * maxDownMoveFactor, [reference)price(horizon) * maxUpMoveFactor]`, where `[reference_price(horizon)` is the reference price corresponding to the specified horizon - obtained in exactly the same way as in the case of a model-based trigger. As mentioned above, price monitoring is meant to stop large market movements that are not "real" from occurring, rather than just detect them after the fact. To that end, it is necessary to pre-process every transaction and check if it triggers the price monitoring action. If pre-processing the transaction doesn't result in the trigger being activated then it should be "committed" by generating the associated events and modifying the order book accordingly (e.g. generate a trade and take the orders that matched off the book). On the other hand if the trigger is activated and the submitted transaction is valid for auction mode, the entire order book **along with that transaction** needs to be processed via price protection auction. If the transaction which activate the trigger is not valid for auction, then it should get rejected and market should continue in the current trading mode. Auction period associated with a given distribution projection horizon and probability level will be specified as part of market setup. Once the auction period finishes the trading should resume in regular fashion (unless other triggers are active, more on that in [reference-level explanation](#reference-level-explanation)). @@ -44,6 +46,8 @@ Likewise, pre-processing transactions will be needed as part of the [fees spec]( #### Market +##### Model-based triggers + - `priceMonitoringParameters` - an array of more price monitoring parameters with the following fields: - `horizon` - price projection horizon expressed as a year fraction over which price is to be projected by the risk model and compared to the actual market moves during that period. Must be positive. - `probability` - probability level used in price monitoring. Must be in the [0.9,1) range. @@ -55,6 +59,13 @@ If any of the above parameters or the risk model gets modified in any way, the p - the auction end time implied by the currently running auction/extension should remain unchanged, - when auction uncrosses price monitoring should get reset using the updated parameters. +##### Model-free triggers + +- `modelFreePriceMonitoringParameters` - an array of more price monitoring parameters with the following fields: + - `horizon` - price projection horizon expressed as a year fraction over which price is to be projected by the risk model and compared to the actual market moves during that period. Must be positive. + - `maxUpMoveFactor` - a factor to be applied to the reference price (for the specified horizon) so that the maximum valid price is `reference_price(horizon) * maxUpMoveFactor`. Must be greater than `1`. + - `maxDownMoveFactor` - a factor to be applied to the reference price (for the specified horizon) so that the minimum valid price is `reference_price(horizon) * maxDownMoveFactor`. Must be less than `1`. + #### Network - `market.monitor.price.defaultParameters`: Specifies default market parameters outlined in the previous paragraph. These will be used if market parameters don't get explicitly specified. @@ -141,3 +152,7 @@ to the risk model and obtains the range of valid up/down price moves per each of - Same as above, but more matching orders get placed during the auction extension. The volume of the trades generated by the later orders is larger than that of the original pair which triggered the auction. Hence the auction concludes generating the trades from the later orders. The overall auction duration is equal to the sum of the extension periods of the two triggers. (0032-PRIM-021). For product spot: (0032-PRIM-038) - For all available mark price calculation methodologies: the price history used by the price monitoring engine is in line with market's mark price history. (0032-PRIM-039) - For all available mark-price calculation methodologies: the mark price update candidate gets rejected if it violates the price monitoring engine bounds. (0032-PRIM-040) +- Model-free triggers can be added to the market at creation time along with regular triggers. (0032-PRIM-041) +- Model-free triggers can be added to the market during market update along with regular triggers. (0032-PRIM-042) +- Adding a model-free trigger with `maxUpMoveFactor = 1.1` and `maxDownMoveFactor = 0.95` results in bonds with max valid price of `110` and min valid price of `95` when a reference price is `100`. When time passes so that the reference price becomes `90` then the resulting max valid price is `99` and min valid price is `85.5`. Violating any of these bounds results in an auction. (0032-PRIM-043 +) diff --git a/protocol/0042-LIQF-setting_fees_and_rewarding_lps.md b/protocol/0042-LIQF-setting_fees_and_rewarding_lps.md index 37af4d9e9..dacab0165 100644 --- a/protocol/0042-LIQF-setting_fees_and_rewarding_lps.md +++ b/protocol/0042-LIQF-setting_fees_and_rewarding_lps.md @@ -216,10 +216,13 @@ An existing LP has `average entry valuation 1090.9` and `S=110`. Currently the s ``` -### Calculating the instantaneous liquidity score +### Calculating the liquidity score At every vega time change calculate the liquidity score for each committed LP. -This is done by taking into account all orders they have deployed within the `[min_lp_price,max_lp_price]` [range](./0044-LIME-lp_mechanics.md) and then calculating the volume-weighted [probability of trading](./0034-PROB-prob_weighted_liquidity_measure.ipynb) at each price level - call it instantaneous liquidity score. +This is done by taking into account all orders they have deployed within the `[min_lp_price,max_lp_price]` [range](./0044-LIME-lp_mechanics.md) and then calculating the volume-weighted instantaneous liquidity score. + +It can be based either on [probability of trading](./0034-PROB-prob_weighted_liquidity_measure.ipynb) at each price level or an [explicit scoring function](./0091-ILSF-instantaneous_liquidity_scoring_funcion.md). The purpose of it is to decide on the relative value of volume placed close to the mid price versus that further away from it. + For orders outside the tightest price monitoring bounds set probability of trading to 0. For orders which have less than 10% [probability of trading], we set the probability to 0 when calculating liquidity score. Note that parked [pegged orders](./0037-OPEG-pegged_orders.md) and not-yet-triggered [stop orders](./0014-ORDT-order_types.md) are not included. @@ -465,3 +468,33 @@ Example 1, generated with [supplementary worksheet](https://docs.google.com/spre - All vAMMs active on a market at the end of an epoch receive SLA bonus rebalancing payments with `0` penalty fraction. (0042-LIQF-092) - A vAMM active on a market during an epoch, which was cancelled prior to the end of an epoch, receives SLA bonus rebalancing payments with `0` penalty fraction. (0042-LIQF-093) - A vAMMs cancelled in a previous epoch does not receive anything and is not considered during SLA rebalancing at the end of an epoch(0042-LIQF-094) + +### Explicit instantaneous liquidity scoring function + +When market is setup with [explicit instantaneous liquidity scoring function](./0091-ILSF-instantaneous_liquidity_scoring_funcion.md) as follows: + +- buy-side: + - reference: BEST_BID + - points: [(0,0.25),(1,0)] + - interpolation strategy: FLAT + +- sell-side: + - reference: BEST_ASK + - points: [(0,0.35),(1,0)] + - interpolation strategy: FLAT + +then all the buy orders deployed at `BEST_BID` get an instantaneous liquidity score of `0.25`, all sell orders deployed at `BEST_ASK` get a score of `0.35` and all other orders get a score of `0`. Updating the risk model has no effect on those scores. (0042-LIQF-095) + +When market is setup with [explicit instantaneous liquidity scoring function](./0091-ILSF-instantaneous_liquidity_scoring_funcion.md) as follows: + +- buy-side: + - reference: MID + - points: [(0,0.4),(200,0.2)] + - interpolation strategy: FLAT + +- sell-side: + - reference: MID + - points: [(0,0.5),(300,0.3)] + - interpolation strategy: FLAT + +the decimal places for the asset are, the decimal places for the market are and tick size is. Then buy orders pegged to MID with an offset of `100` get a score of `0.3`, orders with offset of `200` get a score of `0.2` and orders with and offset of `300` also get a score of `0.2`. Sell orders pegged to MID with an offset of `150` get a score of `0.4`, orders with an offset of `300` get a score of `0.3` and orders with an offset of `400` also get a score of `0.3`. Updating the risk model has no effect on those scores. (0042-LIQF-096) diff --git a/protocol/0053-PERP-product_builtin_perpetual_future.md b/protocol/0053-PERP-product_builtin_perpetual_future.md index 063494a64..8902c9e21 100644 --- a/protocol/0053-PERP-product_builtin_perpetual_future.md +++ b/protocol/0053-PERP-product_builtin_perpetual_future.md @@ -369,3 +369,9 @@ Launch a perpetual futures market which sets `internalCompositePrice` to `Nil` ( Launch a perpetual futures market which sets `internalCompositePrice` to a configuration which uses the impact notional price from the order book. for the "vega side price" for funding calculation. Submit a market update proposal to change this `Nil` (so that mark price gets used for the vega side price). Observe that the new methodology for funding calculations is applied correctly from enactment onwards. (0053-PERP-045). Launch a perpetual futures market which uses the "Last Traded Price" for the "vega side price" for funding calculation. Submit a market update proposal to change this to a composite price with a configuration which uses the impact notional price from the order book. Observe that the new methodology for funding calculations is applied correctly from enactment onwards. (0053-PERP-046). + +Perps market can be created with a wrapped risk model with [hardcoded risk factors](./0018-RSKM-quant_risk_models.ipynb). (0053-PERP-047) + +Updating a risk model on a perps market with regular risk model to a wrapped risk model with [hardcoded risk factors](./0018-RSKM-quant_risk_models.ipynb) results in recalculation of all margin levels in line with hardcoded values and collateral search/release where appropriate. (0053-PERP-048) + +Updating a risk model on a perps market with a wrapped risk model with [hardcoded risk factors](./0018-RSKM-quant_risk_models.ipynb) to a regular risk model results in recalculation of all margin levels in line with the specified risk model (hardcoded value are no longer used) and collateral search/release where appropriate. (0053-PERP-049) diff --git a/protocol/0091-ILSF-instantaneous_liquidity_scoring_funcion.md b/protocol/0091-ILSF-instantaneous_liquidity_scoring_funcion.md new file mode 100644 index 000000000..88d4d1ffe --- /dev/null +++ b/protocol/0091-ILSF-instantaneous_liquidity_scoring_funcion.md @@ -0,0 +1,22 @@ +# Instantaneous liquidity scoring function + +## Summary + +While by default the market uses probability of trading to calculate the [liquidity score](./0042-LIQF-setting_fees_and_rewarding_lps.md#calculating-the-instantaneous-liquidity-score) it should also be possible to explicitly prescribe the instantaneous liquidity scoring function. When such function is specified then it gets used for liquidity score calculation and probability of trading is ignored. + +## Specifying the function + +The function gets specified separately for each side of the book as: + +* `reference`: reference point to which offset from each `point` is to be applied. It can be `MID` or `BEST BID` / `BEST ASK` depending on the side of the book for which the function is specified. +* `points`: collection of `(offset, value)` tuples providing a discrete representation of the function. Tuple `(10,0.4)` means that the value of the instantaneous liquidity function for a price level of reference point with an offset of `10` is `0.4` (specified in the same way as for [pegged orders](./0037-OPEG-pegged_orders.md)). +* `interpolation strategy`: prescribes a way in which price levels not covered by `points` should be calculated. Should be either `FLAT` resulting in a piecewise-constant function (starting from a lowest offset the value specified for it is assumed to prevail until the next offset is reached) or `LINEAR` resulting in a linear interpolation between points. + +Flat extrapolation is always carried out, that is when price level greater than point with a highest offset or smaller than that with a lowest offset needs to be scored we use the nearest values that's been specified. + +Validation: + +* same as pegged orders for `reference` and `offset`, +* at least two `points` must be specified. + +When liquidity scoring function is not specified [probability of trading](./0034-PROB-prob_weighted_liquidity_measure.ipynb) should be used for [liquidity score](./0042-LIQF-setting_fees_and_rewarding_lps.md#calculating-the-instantaneous-liquidity-score) calculation by default. It should also be possible to change it back to a `nil` value later on in market's life to stop using the function prescribed before and return to the default behaviour. diff --git a/protocol/features.json b/protocol/features.json index 7dc4b6958..1700f10c9 100644 --- a/protocol/features.json +++ b/protocol/features.json @@ -701,6 +701,22 @@ "0019-MCAL-158" ] }, + "Model-free alternatives": { + "milestone": "colosseo_II", + "acs": [ + "0016-PFUT-026", + "0016-PFUT-027", + "0016-PFUT-028", + "0053-PERP-047", + "0053-PERP-048", + "0053-PERP-049", + "0032-PRIM-041", + "0032-PRIM-042", + "0032-PRIM-043", + "0042-LIQF-095", + "0042-LIQF-096" + ] + }, "Unknown": { "milestone": "unknown", "acs": [] diff --git a/wordlist.txt b/wordlist.txt index af422bc70..6a5608b5a 100644 --- a/wordlist.txt +++ b/wordlist.txt @@ -220,6 +220,7 @@ permissioned permissionless PERP perps +piecewise PME PnL PoS