Skip to content

Latest commit

 

History

History
508 lines (340 loc) · 47.9 KB

0042-LIQF-setting_fees_and_rewarding_lps.md

File metadata and controls

508 lines (340 loc) · 47.9 KB

Setting fees and rewarding liquidity providers

Summary

The aim of this specification is to set out how fees on Vega are set based on committed liquidity provider stake and prevailing open interest on the market leading to target stake. Let us recall that liquidity providers can commit and withdraw stake by submitting / amending a special liquidity commitment transaction.

Definitions / Glossary of terms used

  • market.value.windowLength: sets the length of the window over which we estimate the market growth. This is a network parameter.
  • Target stake: as defined in target stake spec. The ideal amount of stake LPs would commit to a market.
  • market.liquidityProvision.minLpStakeQuantumMultiple: There is a network wide parameter specifying the minimum LP stake as the quantum specified per asset, see asset framework spec.

Calculating the Liquidity Fee Factor

There are three methods for setting the liquidity fee factor, with the default method being the 'Marginal Cost method.' The liquidity fee setting mechanism is configured per market as part of the market proposal.

Marginal Cost method

The liquidity fee factor is an input to the total taker fee that a price taker of a trade pays:

total_fee = infrastructure_fee + maker_fee + liquidity_fee

liquidity_fee = fee_factor[liquidity] x trade_value_for_fee_purposes

As part of the commit liquidity network transaction, the liquidity provider submits their desired level for the liquidity fee factor for the market. Here we describe how this fee factor is set from the values submitted by all liquidity providers for a given market. First, we produce a list of pairs which capture committed liquidity of each LP together with their desired liquidity fee factor and arrange this list in an increasing order by fee amount. Thus we have

[LP-1-stake, LP-1-liquidity-fee-factor]
[LP-2-stake, LP-2-liquidity-fee-factor]
...
[LP-N-stake, LP-N-liquidity-fee-factor]

where N is the number of liquidity providers who have committed to supply liquidity to this market. Note that LP-1-liquidity-fee-factor <= LP-2-liquidity-fee-factor <= ... <= LP-N-liquidity-fee-factor because we demand this list of pairs to be sorted in this way.

We now find the smallest integer k such that [target stake] < sum from i=1 to k of [LP-i-stake]. In other words we want in this ordered list to find the liquidity providers that supply the liquidity that's required. If no such k exists we set k=N.

Finally, we set the liquidity-fee-factor for this market to be the fee LP-k-liquidity-fee-factor.

Example for fee setting mechanism using the marginal cost method

In the example below there are 3 liquidity providers all bidding for their chosen fee level. The LP orders they submit are sorted into increasing fee order so that the lowest fee bid is at the top and the highest is at the bottom. The fee level chosen for the market is derived from the liquidity commitment of the market (target stake) and the amount of stake committed from each bidder. Vega processes the LP orders from top to bottom by adding up the commitment stake as it goes until it reaches a level greater than or equal to the target stake. When that point is reached the fee used is the fee of the last liquidity order processed.

[LP 1 stake = 120 ETH, LP 1 liquidity-fee-factor = 0.5%]
[LP 2 stake = 20 ETH, LP 2 liquidity-fee-factor = 0.75%]
[LP 3 stake = 60 ETH, LP 3 liquidity-fee-factor = 3.75%]
  1. If the target stake = 119 then the needed liquidity is given by LP 1, thus k=1 and so the market's liquidity-fee-factor is LP 1 fee = 0.5%.
  2. If the target stake = 123 then the needed liquidity is given by LP 1 and LP 2, thus k=2 and so the market's liquidity-fee-factor is LP 2 fee = 0.75%.
  3. If the target stake = 240 then even putting all the liquidity supplied above does not meet the estimated market liquidity demand and thus we set k=N and so the market's liquidity-fee-factor is LP N fee = LP 3 fee = 3.75%.
  4. Initially (before market opened) the [target stake] is by definition zero (it's not possible to have a position on a market that's not opened yet). Hence by default the market's initial liquidity-fee-factor is the lowest liquidity-fee-factor.

Stake-weighted-average method for setting the liquidity fee factor

The liquidity fee factor is set as the weighted average of the liquidity fee factors, with weights assigned based on the supplied stake from each liquidity provider.

Example for fee setting mechanism using the Stake-weighted-average method

In the example below there are 3 liquidity providers all bidding for their chosen fee level. The overall liquidity fee factor is the weight-average of their nominations:

[LP 1 stake = 120 ETH, LP 1 liquidity-fee-factor = 0.5%]
[LP 2 stake = 20 ETH, LP 2 liquidity-fee-factor = 0.75%]
[LP 3 stake = 60 ETH, LP 3 liquidity-fee-factor = 3.75%]

then

liquidity-fee-factor = ((120 * 0.5%) + (20 * 0.75%) + (60 * 3.75%)) / (120 + 20 + 60) = 1.5%

"Constant Liquidity Fee" Method

The liquidity fee factor is set to a constant directly as part of the market proposal.

Example for fee setting mechanism using the constant method

In the example below there are 3 liquidity providers all bidding for their chosen fee level and the overall liquidity fee factor is:

[LP 1 stake = 120 ETH, LP 1 liquidity-fee-factor = 0.5%]
[LP 2 stake = 20 ETH, LP 2 liquidity-fee-factor = 0.75%]
[LP 3 stake = 60 ETH, LP 3 liquidity-fee-factor = 3.75%]

but the market was proposed with a constant fee of 0.8% so that is what the liquidity-fee-factor will be.

Timing market's liquidity-fee-factor changes

Once the market opens (opening auction starts) a clock starts ticking. We calculate the [target stake] using target stake. The fee is re-evaluated using the mechanism above at the start of each epoch using LPs commitments at start of epoch.

APIs for fee factor calculations - what should core be exposing?

At time of call:

  • The liquidity-fee-factor for the market, and the method used to calculate it.
  • Current liquidity provider commitments and their individually nominated fee factors
  • Target stake

Splitting Fees Between Liquidity Providers

The guiding principle of this section is that by committing stake a liquidity provider gets virtual stake that depends on how trading has grown on the market. The virtual stake then determines equity-like share as will be set out below. Equity-like share is then used to split fee revenue between LPs.

Calculating liquidity provider equity-like share

The parameter which determines the period over which growth is estimated is market.value.windowLength which could be e.g. a week. From the end of the opening auction, which we will refer to as t0 until t0+market.value.windowLength is the 0th or "bootstrap period". Then from t0+market.value.windowLength until t0 + 2 x market.value.windowLength is the 1st period and so on. For each LP we track the stake they have and also their virtual stake. For markets that have no "parent" market, see governance we postulate that before and during the 0th (bootstrap) any stake commitment or removal is mirrored in the virtual stake.

For any period n >= 1 LP can add stake or remove stake but virtual stake is treated differently for markets with "parent market":

If the market has a "parent market" then each LP which commits liquidity (to this market) gets the virtual stake copied from the parent market as the 1st step of the process and the stake they are committing here minus the stake on parent market is treated as the delta here.

Say an LP i wants increases their commitment by delta > market.liquidityProvision.minLpStakeQuantumMultiple x quantum (this could also be the initial commitment). Then we update

LP i virtual stake <- LP i virtual stake + delta.

Say an LP i wants to decrease their commitment by delta < 0. Then we update

LP i virtual stake <- LP i virtual stake x (LP i stake + delta)/(LP i stake).

Independently of the above we also update all virtual stakes at start of each new period. To that end "total value for fee purposes" is cumulated over the period set by market.value.windowLength. For a period n call this T(n). We let the 0th period start the moment the opening auction ends and last for market.value.windowLength. We include the volume of the trades that resolved the opening auction in T(0) for markets with no parent market. For markets with a parent market we take T(0) to be the most recent T_{parent}(latest). From this we calculate the running average trade value for fee purposes:

A(0) <- T(0),
A(n) <- A(n-1) x n/(n+1) + T(n)/(n+1), for `n=1,2,...

For n = 0 set r=0 and for n = 1,2,... the g"r"owth of the market is then

r = 0
if A(n) > 0 and A(n-1) > 0
    r =  (A(n)-A(n-1))/A(n-1),

Thus at the end of period n update

if n = 0 or n = 1 or A(n) = 0 or A(n-1) = 0
    LP i virtual stake <- LP i physical stake
else
    LP i virtual stake <- max(LP i physical stake, (1 + r) x (LP i virtual stake)).

Thus the virtual stake of an LP will always be at least their physical stake. Moreover, in situations when trading volume was zero in the previous period or if it is zero in the current period then we don't define the growth r and so in such extreme situations the virtual stake reverts to the physical stake.

The equity-like share for each LP is then

(LP i equity-like share) = (LP i virtual stake) / (sum over j from 1 to N of (LP j virtual stake)).

Check the sum from over i from 1 to N of LP i equity-like share is equal to 1. Warning the above will be decimal calculations so the above checks will only be true up to a rounding errors.

The average entry valuation (which should be reported by the APIs and could be calculated only by the data node as it doesn't itself impact core state) is defined, at the time of change of an LP commitment as follows:

  1. There already is average entry valuation for the LP in question (and average entry valuation = 0 for a new LP). The LP has existing physical stake S (and S=0 for new LP) and wishes to add / remove stake Delta S. If Delta S < 0 then average entry valuation is unchanged by the transaction. If S + Delta S = 0 then the LP is exiting their LP commitment and we do not calculate the average entry valuation for them in this case. So Delta S > 0 (and so S+Delta S > 0) in what follows.
  2. Calculate the entry valuation at the time stake Delta S is added / removed as
(entry valuation) = sum over j from 1 to N of (LP j virtual stake)

Note, the virtual stake used in the calculation of entry valuation is after the change of the LP commitment is applied. This in particular means that if this is the first LP commitment on the market then the (entry valuation) = Delta S. 3. Update the average entry valuation to

(average entry valuation) <- (average entry valuation) x S / (S + Delta S) + (entry valuation) x (Delta S) / (S + Delta S)

Example 1: Currently the sum of all virtual stakes is 900. A new LP has 0 stake and add stake Delta S = 100. The sum of all virtual stakes is now 1000. The average entry valuation is

(average entry valuation) <- 0 + 1000 x 100 / (0 + 100) = 1000

Example 2: A new LP1 has 0 stake and they wish to add Delta S = 8000 and a new LP2 has 0 stake and they wish to add Delta S = 2000. Currently the sum of all virtual stakes is 10000 after the LP commitments added. The average entry valuations are:

(average entry valuation LP1) <- 0 + 8000 x 8000 / (0 + 8000) = 8000
(average entry valuation LP2) <- 0 + (8000 + 2000) x 2000 / (0 + 2000) = 10000

Example 3: An existing LP has average entry valuation 1000 and S=100. Currently the sum of all virtual stakes is 2000. They wish to add 10 to their stake.

(average entry valuation) <- 1000 x 100 / (100 + 10) + 2000 x 10 / (100 + 10) = 1090.9....

Example 4: An existing LP has average entry valuation 1090.9 and S=110. Currently the sum of all virtual stakes is 3000. They wish to remove 20 from their stake. Their average entry valuation stays the same

(average entry valuation) = 1090.9

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 and then calculating the volume-weighted instantaneous liquidity score.

It can be based either on probability of trading at each price level or an explicit scoring function. 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 and not-yet-triggered stop orders are not included.

Now calculate the total of the instantaneous liquidity scores obtained for each committed LP:

total = the sum of instantaneous liquidity scores for all LPs that have an active liquidity commitment

Now, if the total comes out as 0 then set fractional instantaneous liquidity score to 1.0/n, where n is the number of committed LPs. Otherwise calculate fractional instantaneous liquidity score for each committed LP.

fractional instantaneous liquidity score = instantaneous liquidity score / total

Whenever a new LP fee distribution period starts set a counter n=1. Then on every Vega time change, after fractional instantaneous liquidity score has been obtained for all the committed LPs, update:

liquidity score <- ((n-1)/n) x liquidity score + (1/n) x fractional instantaneous liquidity score

The liquidity score should always be rounded to 10 decimal places to prevent spurious accuracy and overly long string representation of a number.

Distributing fees into LP-per-market fee account

On every trade, liquidity fee should be collected immediately into the market's aggregate LP fee account. The account is under control of the network and funds from this account will be transferred to the owning LP party according to the mechanism below.

A network parameter market.liquidity.providersFeeCalculationTimeStep will control how often fees are distributed from the market's aggregate LP fee account. Starting with the end of the opening auction the clock starts ticking and then rings every time market.liquidity.providersFeeCalculationTimeStep has passed. Every time this happens the balance in this account is transferred to the liquidity provider's general account for the market settlement asset.

The liquidity fees are transferred from the market's aggregate LP fee account into the LP-per-market fee account from two different configurable size buckets, defined by the network parameter market.liquidity.equityLikeShareFeeFraction. The first bucket, a proportion equal to market.liquidity.equityLikeShareFeeFraction of the fee, is divided pro-rata depending on the LP i equity-like share multiplied by LP i liquidity score scaled back to 1 across all LPs at a given time. The other bucket, 1 - market.liquidity.equityLikeShareFeeFraction, is divided purely by each LP's in-epoch liquidity score LP i liquidity score, scaled again across the value of all LPs at that time.

The LP parties don't control the LP-per-market fee account; the fees from there are then transferred to the LPs' general account at the end epoch as described below.

Calculating SLA performance

Measuring time spent meeting their commitment in a single epoch

During the epoch, the amount of time in nanoseconds (of Vega time) that each LP spends meeting the SLA is recorded. This can be done by maintaining a counter s_i as shown below:

  • At the start of a new epoch, s_i = 0

    • If the LP is meeting their commitment, store the Vega time of the start of the epoch as the time the LP began meeting their commitment, otherwise store nothing.
  • At start of block, for LP i, first reset the running minimum valid volume an LP is providing and across the block and then keep updating the minimum volume that the LP is providing that is within the valid range (section "Meeting the committed volume of notional").

  • Note that the volume check must only happen after iceberg orders, that need refreshing as a result of a transaction are refreshed. This means that while an iceberg order has sufficient remaining quantity, it will never be considered to be contributing less than its minimum peak size.

  • At the end of each block:

    • If an LP has started meeting their committed volume of notional based on the minimum volume recorded during the block (section "Calculating liquidity from commitment") after previously not doing so (i.e. nothing is stored as the time the LP began meeting their commitment):

      • Store the current Vega time attached to the block being processed as the time the LP began meeting their commitment.
    • If an LP has stopped meeting their committed volume of notional after previously doing so:

      • Add the difference in nanoseconds between the current Vega time attached to the block being processed and the time the LP began meeting their commitment (stored in the step above) to s_i.
      • Store nothing as the time the LP began meeting their commitment, to signify the LP not meeting their commitment.
  • At the end of the epoch, calculate the actual observed epoch length observed_epoch_length = the difference in nanoseconds between the Vega time at the start of the epoch and the Vega time at the end of the epoch.

Note that because vega time won't be progressing inside a block the above mechanism should ensure that s_i gets incremented only if the LP was meeting their commitment at every point this was checked within the block.

Calculating the SLA performance penalty for a single epoch

Calculate the fraction of the time the LP spent on the book:

fraction_of_time_on_book = s_i / observed_epoch_length

For any LP where fraction_of_time_on_book < market.liquidity.commitmentMinTimeFraction the SLA penalty fraction p_i = 1 (that is, the penalty is 100% of their fees).

For each LP where fraction_of_time_on_book ≥ market.liquidity.commitmentMinTimeFraction, the SLA penalty fraction p_i is calculated as follows:

Let $t$ be fraction_of_time_on_book

Let $s$ be market.liquidity.commitmentMinTimeFraction.

Let $c$ be market.liquidity.slaCompetitionFactor.

$$p_i = \begin{cases} (1 - \frac{t - s}{1 - s}) \cdot c &\text{if } s < 1 \\ 0 &\text{if } s = 1 \end{cases}$$

Calculating the SLA performance penalty for over hysteresis period

Now, for each LP $i$ take the $p_i$ values calculated over the last market.liqudity.performanceHysteresisEpochs - 1, call these $p_i^1, p_i^2, ..., p_i^{n-1}$ (if all the historical ones are not yet available, take as many as there are - i.e. expanding window till you get to the full length).

Now calculate $p_i^n$ to be the arithmetic average of $p_i^k$ for $k = 1,2,...,n-1$. Finally set

$$ p_i^n \leftarrow \max(p_i,p_i^n). $$

i.e. your penalty is the bigger of current epoch and average over the hysteresis period

Applying LP SLA performance penalties to accrued fees

As defined above, for each LP for each epoch you have "penalty fraction" $p_i^n$ which is between [0,1] with 0 indicating LP has met commitment 100% of the time and 1 indicating that LP was below market.liquidity.commitmentMinTimeFraction of the time. All vAMM LPs should also receive a $p_i^n$ value, however this will always be 0, as they are defined as always meeting their commitment.

If for all $i$ (all the LPs) have $p_i^n = 1$ then all the fees go into the market insurance pool and we stop.

Calculate

$$ w_i = \frac{\text{LP-per-market fee account } i}{\sum_k \text{LP-per-market fee account } k}. $$

For each LP transfer $(1-p_i^n) \times \text{ amount in LP-per-market fee account}$ to their general account with a transfer type that marks this as the "LP net liquidity fee distribution".

Transfer the remaining amount from each LP-per-market fee account back into the market's aggregate LP fee account. Record the total inflow as a result of that operation as $B$. Let $b_i := (1-p_i^n) \times w_i$ and renormalise $b_i$s so that they sum up to $1$ i.e.

$$ b_i \leftarrow \frac{b_i}{\sum_k b_k},. $$

Each LP further gets a performance bonus: $b_i \times B$ with a transfer type that marks this as the "LP relative SLA performance bonus distribution".

APIs for fee splits and payments

  • Each liquidity provider's equity-like share
  • Each liquidity provider's average entry valuation

Acceptance Criteria

CALCULATING LIQUIDITY FEE FACTOR TESTS

  • The examples provided result in the given outcomes (0042-LIQF-001)
  • The resulting liquidity-fee-factor is always equal to one of the liquidity provider's individually nominated fee factors (0042-LIQF-002) For product spot: (0042-LIQF-063).
  • The resulting liquidity-fee-factor is never less than zero (0042-LIQF-003)
  • Liquidity fee factors are recalculated every time a liquidity provider nominates a new fee factor (using the commit liquidity network transaction). (0042-LIQF-004)
  • Liquidity fee factors are recalculated every time the liquidity demand estimate changes. (0042-LIQF-005). For product spot: (0042-LIQF-064).
  • If a change in the open interest causes the liquidity demand estimate to change, then fee factor is correctly recalculated. (0042-LIQF-006)
  • If passage of time causes the liquidity demand estimate to change, the fee factor is correctly recalculated. (0042-LIQF-007). For product spot: (0042-LIQF-065).
  • A market can be proposed with a choice of liquidity fee settings. These settings can be updated by a subsequent market update proposal. Moreover, the correct fee value and liquidity fee setting method can be read from the data node APIs. Upon proposal enactment the new liquidity method is applied to recalculate the liquidity fee. The tests should be carried out with the following methods:
  • The above example for the liquidity fee when the method is weighted-average results in a fee-factor of 1.5% (0042-LIQF-057). For product spot: (0042-LIQF-069).
  • The above example for the liquidity fee when the method is constant-fee results in a fee-factor of 0.8% (0042-LIQF-058). For product spot: (0042-LIQF-070).
  • The above example for the liquidity fee when the method is marginal cost results in a fee-factor of 3.75% (0042-LIQF-059). For product spot: (0042-LIQF-071).
  • For the constant-fee method validate that the fee factor can only be between 0 and 1 inclusive (0042-LIQF-060). For product spot: (0042-LIQF-072).

CHANGE OF NETWORK PARAMETERS TESTS

  • Change of network parameter market.liquidityProvision.minLpStakeQuantumMultiple will change the multiplier of the asset quantum that sets the minimum LP commitment amount. If market.liquidityProvision.minLpStakeQuantumMultiple is changed then no LP orders that have already been submitted are affected. However any new submissions or amendments must respect the new amount and those not meeting the new minimum will be rejected. (0042-LIQF-021)
  • Change of network parameter market.value.windowLength will affect equity-like share calculations from the next block. Decreasing it so that the current period is already longer then the new parameter value will end it immediately and the next period will have the length specified by the updated parameter. Increasing it will lengthen the current period up to the the length specified by the updated parameter. (0042-LIQF-022)

SPLITTING FEES BETWEEN liquidity providers

  • The examples provided result in the given outcomes. (0042-LIQF-008)
  • The total amount of liquidity fee distributed is equal to the most recent liquidity-fee-factor x notional-value-of-all-trades (0042-LIQF-011)
  • Liquidity providers with a commitment of 0 will not receive a share of the fees (0042-LIQF-012)
  • When a market settles any fees from any intermediate fee accounts are distributed as if the epoch ended as part of the settlement process, see market lifecycle. Any settled market has zero balances in all the LP fee accounts. (0042-LIQF-014)
  • All liquidity providers with average fraction of liquidity provided by committed LP > 0 in the market receive a greater than zero amount of liquidity fee. The only exception is if a non-zero amount is rounded to zero due to integer representation. (0042-LIQF-015)
  • After fee distribution, if there is a remainder in the liquidity fee account and the market is not being settled, it should be left in the liquidity fee account and carried over to the next distribution window. (0042-LIQF-032)

LP JOINING AND LEAVING MARKETS

  • An LP joining a market that is below the target stake with a higher fee bid than the current fee: their fee is used (0042-LIQF-019)
  • Given the fee setting method is marginal cost. An LP joining a spot market that is below the target stake with a higher fee bid than the current fee: their fee is used when the fee is next recalculated (0042-LIQF-073)
  • An LP joining a market that is below the target stake with a lower fee bid than the current fee: fee doesn't change (0042-LIQF-020)
  • Given the fee setting method is marginal cost. An LP joining a market that is below the target stake with a lower fee bid than the current fee: fee doesn't change (0042-LIQF-074)
  • An LP joining a market that is above the target stake with a sufficiently large commitment to push ALL higher bids above the target stake and a lower fee bid than the current fee: their fee is used (0042-LIQF-029)
  • Given the fee setting method is marginal cost. An LP joining a spot market that is above the target stake with a sufficiently large commitment to push ALL higher bids above the target stake and a lower fee bid than the current fee: their fee is used when the fee is next recalculated (0042-LIQF-075)
  • An LP joining a market that is above the target stake with a commitment not large enough to push any higher bids above the target stake, and a lower fee bid than the current fee: the fee doesn't change (0042-LIQF-030)
  • Given the fee setting method is marginal cost. An LP joining a spot market that is above the target stake with a commitment not large enough to push any higher bids above the target stake, and a lower fee bid than the current fee: the fee doesn't change when the fee is next recalculated (0042-LIQF-076)
  • An LP joining a market that is above the target stake with a commitment large enough to push one of two higher bids above the target stake, and a lower fee bid than the current fee: the fee changes to the other lower bid (0042-LIQF-023)
  • Given the fee setting method is marginal cost. An LP joining a spot market that is above the target stake with a commitment large enough to push one of two higher bids above the target stake, and a lower fee bid than the current fee: the fee changes to the other lower bid when the fee is next recalculated (0042-LIQF-077)
  • An LP joining a market that is above the target stake with a commitment large enough to push one of two higher bids above the target stake, and a higher fee bid than the current fee: the fee doesn't change (0042-LIQF-024)
  • Given the fee setting method is marginal cost. An LP joining a spot market that is above the target stake with a commitment large enough to push one of two higher bids above the target stake, and a higher fee bid than the current fee: the fee doesn't change when the fee is next recalculated (0042-LIQF-078)
  • An LP leaves a market that is above target stake when their fee bid is currently being used: fee changes to fee bid by the LP who takes their place in the bidding order (0042-LIQF-025)
  • Given the fee setting method is marginal cost. An LP leaves a market that is above target stake when their fee bid is currently being used: fee changes to fee bid by the LP who takes their place in the bidding order when the fee is next recalculated (0042-LIQF-079)
  • An LP leaves a market that is above target stake when their fee bid is lower than the one currently being used and their commitment size changes the LP that meets the target stake: fee changes to fee bid by the LP that is now at the place in the bid order to provide the target stake (0042-LIQF-026)
  • Given the fee setting method is marginal cost. An LP leaves a market that is above target stake when their fee bid is lower than the one currently being used and their commitment size changes the LP that meets the target stake: fee changes to fee bid by the LP that is now at the place in the bid order to provide the target stake when the fee is next recalculated (0042-LIQF-080)
  • An LP leaves a market that is above target stake when their fee bid is lower than the one currently being used. The loss of their commitment doesn't change which LP meets the target stake: fee doesn't change (0042-LIQF-027)
  • Given the fee setting method is marginal cost. An LP leaves a spot market that is above target stake when their fee bid is lower than the one currently being used. The loss of their commitment doesn't change which LP meets the target stake: fee doesn't change when the fee is next recalculated (0042-LIQF-081)
  • An LP leaves a market that is above target stake when their fee bid is higher than the one currently being used: fee doesn't change (0042-LIQF-028)
  • Given the fee setting method is marginal cost. An LP leaves a spot market that is above target stake when their fee bid is higher than the one currently being used: fee doesn't change (0042-LIQF-106)

API

  • Equity-like share of each active LP can be obtained via the API (0042-LIQF-016)
  • Liquidity score of each active LP can be obtained via the API (0042-LIQF-017)
  • Through the LiquidityProviders API, liquidity score, average entry valuation and equity-like share of each active LP can be obtained

Successor markets

  • If an LP has virtual stake of 11000 and stake of 10000 on a parent marketID=m1 and a new market is proposed and enacted as m2 with m1 as its parent market and the LP submits a commitment of 10000 to m2 during the "Pending" period, see lifecycle then for the duration of the first market.value.windowLength after the opening auction ends the LP has virtual stake of 11000 and stake of 10000 on m2. (0042-LIQF-031)
  • If an LP has virtual stake of 11000 and stake of 10000 on a parent marketID=m1 and a new market is proposed and enacted as m2 with m1 as its parent market and the LP submits a commitment of 20000 to m2 during the "Pending" period, see lifecycle then for the duration of the first market.value.windowLength after the opening auction ends the LP has virtual stake which must be result of the virtual stake obtained from m1 with the delta=10000 added on, so virtual stake of 21000, assuming all other LPs committed exactly the stake they had on m1. (0042-LIQF-048)
  • If an LP has virtual stake of 11000 and stake of 10000 on a parent marketID=m1 and a new market is proposed and enacted as m2 with m1 as its parent market and the LP submits a commitment of 5000 to m2 during the "Pending" period, see lifecycle then for the duration of the first market.value.windowLength after the opening auction ends the LP has virtual stake obtained from m1 with the delta=-5000 added on (i.e. 5000 removed). (0042-LIQF-033)
  • If market.liquidity.providersFeeCalculationTimeStep > 0 for a given market and an LP submits a new liquidity commitment halfway through the time interval then they receive roughly 1/2 the fee income from that market compared with the next time interval when they maintain their commitment (and the traded value is the same in both time intervals). (0042-LIQF-034)

Calculating SLA Performance

  • If an LP has an active liquidity provision at the start of an epoch, market.liquidity.slaCompetitionFactor = 1, market.liquidity.commitmentMinTimeFraction = 0.5 and throughout the epoch meets their liquidity provision requirements such that the fraction_of_time_on_book = 0.75 then their penalty from that epoch will be 0.5. This will be true whether:

  • If an LP has an active liquidity provision at the start of an epoch, market.liquidity.slaCompetitionFactor = 0, market.liquidity.commitmentMinTimeFraction = 0.5 and throughout the epoch meets their liquidity provision requirements such that the fraction_of_time_on_book = 0.75 then their penalty from that epoch will be 0. (0042-LIQF-041). For spot (0042-LIQF-084)

  • If an LP has an active liquidity provision at the start of an epoch, market.liquidity.slaCompetitionFactor = 0.5, market.liquidity.commitmentMinTimeFraction = 0.5 and throughout the epoch meets their liquidity provision requirements such that the fraction_of_time_on_book = 0.75 then their penalty from that epoch will be 0.25. (0042-LIQF-042). For spot (0042-LIQF-085)

  • When market.liquidity.performanceHysteresisEpochs = 1:

    • If an LP has an active liquidity provision at the start of an epoch and throughout the epoch always meets their liquidity provision requirements then they will have a fraction_of_time_on_book == 1 and no penalty will be applied to their liquidity fee payments at the end of the epoch (0042-LIQF-035). For spot (0042-LIQF-086)
    • If an LP has an active liquidity provision at the start of an epoch and throughout the epoch meets their liquidity provision requirements less than market.liquidity.commitmentMinTimeFraction fraction of the time then they will have a full penalty and will receive 0 liquidity fee payments at the end of the epoch (0042-LIQF-049). For spot (0042-LIQF-087)
    • An LP has an active liquidity provision at the start of an epoch. The penalty rate for said LP over the previous 2 epochs is 0.75. During the epoch market.liquidity.performanceHysteresisEpochs is set to 3. Throughout the current epoch the LP meets their liquidity provision requirements so they will have fraction_of_time_on_book == 1. The penalty applied to fee distribution at epoch end will be 0 and will not consider the previous epochs. (0042-LIQF-053). For spot (0042-LIQF-088)
  • When market.liquidity.performanceHysteresisEpochs > 1:

    • If an LP has an active liquidity provision at the start of an epoch, the average penalty rate over the previous n-1 epochs is 0.75 and throughout the epoch they always meet their liquidity provision requirements then they will have a fraction_of_time_on_book == 1 for the latest epoch a penalty rate of 0.75 will be applied to liquidity fee payments at the end of the epoch (0042-LIQF-047). For spot (0042-LIQF-089)
    • If an LP has an active liquidity provision at the start of an epoch, the average penalty rate over the previous n-1 epochs is 0.5 and throughout the epoch they always meet their liquidity provision requirements then they will have a fraction_of_time_on_book == 1 for the latest epoch a penalty rate of 0.5 will be applied to liquidity fee payments at the end of the epoch (0042-LIQF-039). For spot (0042-LIQF-090)
    • If an LP has an active liquidity provision at the start of an epoch, the average penalty rate over the previous n-1 epochs is 0.5 and throughout the epoch they never meet their liquidity provision requirements then they will have a fraction_of_time_on_book == 0 for the latest epoch a penalty rate of 1 will be applied to liquidity fee payments at the end of the epoch (0042-LIQF-040). For spot (0042-LIQF-091)
    • If an LP has an active liquidity provision at the start of an epoch and no previous performance penalties and throughout the epoch always meets their liquidity provision requirements then they will have a fraction_of_time_on_book == 1 then no penalty will be applied to their liquidity fee payments at the end of the epoch. (0042-LIQF-054). For spot (0042-LIQF-100)

SLA Performance bonus transfers

  • The net inflow and outflow into and out of the market's aggregate LP fee account should be zero as a result of penalty collection and bonus distribution. (0042-LIQF-043). For spot (0042-LIQF-101)
  • With two liquidity providers, one with an effective penalty rate of 0.5 and earned fees of n, and the other with an effective rate of 0.75 and earned fees of m, 50% * n and 25% * m of the second provider's should be transferred back into market's aggregate LP fee account. Then the total provider bonus score should be b = (m / (n + m)) * 0.25 + (n / (n + m)) * 0.5 and provider 1 should receive (0.5 * n + 0.25 * m) * (n / (n + m)) * 0.5 / b and provider 2 should receive (0.5 * n + 0.25 * m) * (m / (n + m)) * 0.25 / b as an additional bonus payment (0042-LIQF-044). For spot (0042-LIQF-102)
  • With two liquidity providers, one with an effective penalty rate of 1 and earned fees of n, and the other with an effective rate of 0 and earned fees of m, the entirety of n should be transferred to the second liquidity provider as a bonus payment (0042-LIQF-045). For spot (0042-LIQF-103)
  • With only one liquidity provider, with an effective penalty rate of 0.5, 50% of their initially earned fees will be taken initially but will be entirely paid back to them as a bonus payment (0042-LIQF-046). For spot (0042-LIQF-104)

Transfers example

Example 1, generated with supplementary worksheet [internal only]. Values should match up to rounding used by core (0042-LIQF-055). For spot (0042-LIQF-105):

LP penalty fraction LP-per-market fee accounts balance 1st transfer amt 2nd (bonus) transfer amt
LP1 0 1000 1000 24673.94095
LP2 0.05 100 95 2344.02439
LP3 0.6 7000 2800 69087.03466
LP4 1 91900 0 0

vAMM behaviour

  • 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)

  • a vAMM which was active on the market throughout the epoch but with an active range which never overlapped with the SLA range is counted with an implied commitment of 0. (0042-LIQF-107)

  • A vAMM which was active on the market with an average of 10000 liquidity units (price * volume) provided across the epoch, and where the market.liquidity.stakeToCcyVolume value is 100, will have an implied commitment of 100. (0042-LIQF-108)

  • A vAMM which was active on the market with an average of 10000 liquidity units (price * volume) provided for half the epoch, and then 0 for the second half of the epoch (as the price was out of the vAMM's configured range), and where the market.liquidity.stakeToCcyVolume value is 100, will have an implied commitment of 50. (0042-LIQF-109)

  • A vAMM which was active on the market with an average of 10000 liquidity units (price * volume) provided for half the epoch, and then is cancelled for the second half of the epoch, and where the market.liquidity.stakeToCcyVolume value is 100, will have an implied commitment of 50. (0042-LIQF-110)

  • A vAMM which was active on the market with an average of 10000 liquidity units (price * volume) provided for half the epoch, and then 5000 for the second half of the epoch (as the price was out of the vAMM's configured range), and where the market.liquidity.stakeToCcyVolume value is 100, will have an implied commitment of 75. (0042-LIQF-111)

  • If a vAMM was active during the market's opening auction if the opening auction ended and if trades were placed before the end of an epoch the vAMM should receive liquidity fee at epoch boundary (just like a normal LP that submitted bond during opening auction and then met the SLA) (0042-LIQF-112)

Explicit instantaneous liquidity scoring function

When market is setup with explicit instantaneous liquidity scoring function 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 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)