vegaprotocol / specs

Specs, designs and requirements 🦔
MIT License
7 stars 2 forks source link

Spec for CLOB shared order margin #2372

Open barnabee opened 3 weeks ago

barnabee commented 3 weeks ago

Overview

Note: this ticket now covers only shared order margin on the CLOB. vAMM shared pools are now covered in a separate ticket as they do not require (and will not use) the new shared order margin account.

See this comment below for a more concrete and simplified MVO design.

This enhancement will relax the capital requirements for posting order volume on the book to allow a large (orders of magnitude) increase in the number of markets that can be effectively quoted with a given amount of capital.

This can be done by taking into account the sequential nature of transaction processing, and the fact that after each transaction we can reduce or cancel posted order volume if the party can no longer meet the margin requirements if it trades.

This is similar conceptually to the existing functionality that cancels orders if the party can't support them due to market market losses on the same key, but where order margin is considered to be at least partially shared between orders on multiple markets.

Position margin remains per-market. This ticket is not about "risk universes" or any form of correlation based per market netting, collateralisation, etc. such as would be required to offset position margin between different markets.

This feature must be designed to be safe. Specifically it must continue to guarantee that:

  1. protocol users cannot open an un[der]funded position; and
  2. protocol users cannot "spoof" the market by posting order volume that is unlikely to be tradable.

Notes:

Please use comments on this issue to discuss the proposed design, with the aim of getting to a point where this is ready to be formalised in a spec PR, where discussion on implementation details can continue.

Proposed theory of operation

The feature would work by allowing sets of limit orders across multiple markets to be backed by the same virtual key / funding pool, rather than having funds reserved per market to cover the worst case orders on that market only. The system would still always cover the worst case position margin increase from any given single transaction on any given market. But, after a trade occurs, it may be necessary to reduce the posted order volume on any number of markets using the same shared order margin account to ensure that whatever may happen in the next transaction can still be covered. In fact, it is already the case that an event in transaction N can cause orders to be cancelled/parked and therefore not be available in transacton N+1, this will simply add another way this can happen.

This works by adding a new "shared order margin account" type, where a shared margin account can be created / enabled by a key for any set of one or more markets (as a simplification, having a single shared order margin account per { public_key, settlement_asset }, would be acceptable (users can use multiple keys if they wish to share only among subsets of marketd). In either case it is likely that any given market should be allowed to appear in at most one shared order margin account per Vega key.

Under this propoal, we would relax the current requirement that a certain amount of capital be moved to a per-market [order] margin account to cover the worst case additional margin liabilities of the orders in a market executing. Instead, the requirement would now be that the combination of the per-market [order] margin balance plus the relevant shared margin account balance must cover these liabilities (in addition to the margin required by the open position, if any).

This new account type would automatically source and release funds from the owning key's general account, to make sure that the margin requirements of each individual market are satisfied by the combination of per-market margin account(s) plus the shared order margin account.

Handling changes to shared margin

Doing the above without adding any additional logic would allow a situation to arise where after an order on market A trades, there would not be enough funds to cover the margin for a previously accepted order on market B, as it may be relying on funds in the shared order margin account that have already been used.

In order to prevent this, open orders on other markets held by the same key and using the same shared order margin account may need to be adjusted after an order trades to fit within the available collateral.

Isolated margin

For isolated margin the shared order margin account plus what's on each market would need to cover all in-scope markets, so the shared order margin account would not necessarily contain the exact amount required for each market (unlike order margin accounts for isolated margin). For some markets it may be over-collateralised, but it can never be allowed to be undercollateralised for the currently configuredmargin ratio.

This should be fine, as long as the correct amounts are transferred if a position is incurred and when maintaining the per-acount order margin.

Ensuring continuity / spoofing protection

In a naïve implementation, if may be possible to spoof a market or create "flaky" liquidity by configuring orders across a large nunber of markets and/or in such a way that a small number of orders (or even a single order) sat at the top of the book on one market would effectively cause all other displayed liquidity to be removed if it trades.

We need to think about how to keep this operating well and prevent the most obviously stupid or nefarious configurations.

The following ideas might be a starting point:

  1. Require some % of the order margin (set by a { market | network } parameter) to be in the per-market [order] margin account. This could be done automatically with the [order] margin account being filled exactly as it is today but with the fractional rather than full required amount being placed in the account. The shared margin account would then need to cover the remainder, with more being added to it if needed, and the order being rejected if there's not enough collateral to do so. The benefit of this is that it puts limits on the total amount of overcommitment of margin.

  2. Set some { market | network } parameter to place an upper limit on the amount of the margin available to a market (shared order margin plus that market's specific order and position accounts) that it can use. This would need to use something like the "margin available to a market" as defined above because:

    • Using the total margin of all types for all markets in the shared set would allow scenarios where a currently small market can take all the available shared margin
    • Using just a maximum percentage of the shared margin rather than all margin available to a market allows margin to "drain" over time from shared order margin into position margin until all margin is locked up in one market's position
    • This would enable the restriction and thus order size on other markets to be updated sanely based on what's really available to them even when one or two markets end up eating a very large share of the margin, perhaps due to MTM losses.

It would be important to allow these to be switched off (parameter = 0/100%/etc.) if so desired.

The effect of these two needs some thought, but they would seemingly allow users to be prevented from supplying liquiidty across a large number of markets in a way that is going to be too exploitable or extremely flaky. It could be argued that 2 might not be needed at a network/market level and should only be an optional tool for LPs to help them maintain continuity of liquidity across a large number of markets. If an LP wanted to provide more liquidity to very specific markets they could separate them into other shared pools together or supply some on another key without shared liquidity at all.

Allowing user control

Users may prefer that one large or heavily traded market be prevented from pushing out all the others. Per-key parameters could be used to set limits on on the amount of orders that can be posted to a market given the total amount of shared margin available and the amount of order and/or position margin currently exclusively allocated to a market. The goal might be to implement a maximum total dominance of any one market or a maximum rate of growth for the amount of the total margin (shared order, order, and position) allocated exclusively to any given market.

One option would be to allow the user to optionally configure a version of option 2 under "Ensuring continuity / spoofing protection" above, with a more restrictive parameter to keep things more distributed. In facf it is possible that this option would be better off as an optional user control rather than market enforced.

It is not clear to me if this is needed, maybe users can manage it themselves. The risk, though, is that the correct sizing is dynamic as available collateral changes and without some kind of bot, users may not get the result they want. This could potentially be complemented well by the position disposal algorithm (https://github.com/vegaprotocol/specs/issues/2368) especially if there is symbiosis between the rate of position accumulation and disposal.

See this comment below for a more concrete and simplified MVO design.

barnabee commented 1 week ago

To summarise how an MVP of this feature might work for CLOB orders:

1. Shared order margin account

Note: this ticket makes an assumption that the required margin for a { key, market} is always comprised of position margin (the margin required for the open position if there were no active orders) and order margin (the difference between the total margin required for the open position plus active orders and the position margin. Currently this is implemented explicitly when in isolated margin mode (where separate margin and order margin accounts are used) but is implicit in cross-margin mode (where the combined total margin is held in the margin account and the order margin account type is not used). The implementation of this feature does not require cross-margin mode be changed to use the order margin account. However, it is important to understand the concepts and definition of position margin and order margin given at the start of this note, and if the order margin account isn't used in cross margin, it will be necessary to track of these amounts in the app state.

2. Quoted volume reduction for CLOB orders

Quoted volume reduction is the process of scaling down the quoted volume on a market to fit within the total funds available for order margin across the per-market order margin account, the shared order margin account, and the general account.

On each affected market, working from highest to loweest exclusive order margin account balance in order, the following process is repeated until all margin requirements, namely the order margin and exclusive order margin requirements are met: