VMP-013 Create market - BTCUSDT Perpetual

VMP-013 - Create market - BTCUSDT Perpetual
[Create market [BTCUSDT]

This proposal outlines the introduction of a Bitcoin (BTC) to Tether (USDT) perpetual market on the VEGA Protocol, designed to leverage the full capabilities of the latest update of the protocol’s decentralized derivatives infrastructure.

Market Summary:
name: BTC.PERP
Settlement asset: USDT

Market/Update Details:
BTCUSDT PERP

Risk model:
Log-Normal

Data source definition for the settlement data oracle:
Chainlink Oracle

As part of this proposal for the BTCUSDT perpetual market on the VEGA Protocol, I am actively seeking community feedback on the proposed liquiditySlaParameters . These parameters are designed to encourage strong liquidity provision by establishing clear performance benchmarks for market makers.

EDIT:

After carefully studying the current market state and how the fees and the rewards are accrued I think is beneficial to adjust those SLA parameters. I do believe that with perp thing should work better.

For these reasons I would adjust:

Price range: reduced to 1.5%. This is to promote competitively. The protocol and the users benefit from liquidity. Users want to trade with fair pricing. Moreover, we want to avoid “lazy” market makers who post liquidity at 5% range just to “farm” fees and reward.

CommitmentMinTimeFraction: reduced to 60%. Penalties for not meeting this parameter are really high. It would risk to lose market makers just because they have a technical problem or their setup works differently from the uptime rules (for example quoting only one side when needed). 60% it’s a fair start to attract more player but keeping them at 1.5%. So that more MM can experiment the protocol even though they don’t have the tool to be live 100% of the time. If the protocol loses liquidity, loses users.

PerformanceHysteresisEpochs: reduced to 0. In my opinion, one should be penalised only for the epoch one deserves to be penalised. The risk is the same. Losing good MM because they messed up one day only.

slaCompetitionFactor: reduced to 20%. If you earned fees it means that your liquidity is one of quality. I find unfair to give away more than 20% when penalties apply.

The refined SLA parameters represent a strategic evolution towards fostering a healthier and more competitive market environment, emphasizing incentive-driven competition over punitive measures. By implementing these adjustments, the my aim and hope is to attract and retain market makers through a balanced approach that rewards competitive pricing and acknowledges operational realities, thereby enhancing liquidity and overall market stability. So incentivising better pricing rather than punishing time on the book but having wide prices.

With this settings I seek to

  1. Discourage passive market-making strategies that contribute less value to the ecosystem.
  2. Attract a wider array of market makers, including those who may not have the capabilities to maintain a 100% uptime but are still capable of contributing significantly to the liquidity and robustness of the market.
  3. Create more dynamic environment where market makers are encouraged to improve and optimize their strategies continuously, without the overhang of previous mistakes.
  4. maintain MMs’ motivation to provide quality liquidity, as excessive penalties could otherwise lead to a loss of valuable participants in the market.
"liquiditySlaParameters": {
            "priceRange": "0.015",
            "commitmentMinTimeFraction": "0.60",
            "performanceHysteresisEpochs": "0",
            "slaCompetitionFactor": "0.2"

Full Proposal JSON:

{
    "rationale": {
      "title": "BTCUSDT Perp",
      "description": "## Summary\n\nThis proposal requests to list BTCUSDT Perp as a market with USDT as a settlement asset"
    },
    "terms": {
      "newMarket": {
        "changes": {
          "linearSlippageFactor": "0.001",
          "quadraticSlippageFactor": "0",
          "decimalPlaces": "1",
          "positionDecimalPlaces": "4",
          "instrument": {
            "name": "BTCUSDT Perp",
            "code": "BTCUSDT.PERP",
            "perpetual": {
              "settlementAsset": "bf1e88d19db4b3ca0d1d5bdb73718a01686b18cf731ca26adedf3c8b83802bba",
              "quoteName": "USDT",
              "dataSourceSpecForSettlementData": {
                "external": {
                  "ethOracle": {
                    "address": "0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c",
                    "abi": "[{\"inputs\":[],\"name\":\"latestAnswer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
                    "method": "latestAnswer",
                    "normalisers": [
                      {
                        "name": "btc.price",
                        "expression": "$[0]"
                      }
                    ],
                    "requiredConfirmations": 3,
                    "trigger": {
                      "timeTrigger": {
                        "every": 30
                      }
                    },
                    "filters": [
                      {
                        "key": {
                          "name": "btc.price",
                          "type": "TYPE_INTEGER",
                          "numberDecimalPlaces": "8"
                        },
                        "conditions": [
                          {
                            "operator": "OPERATOR_GREATER_THAN",
                            "value": "0"
                          }
                        ]
                      }
                    ]
                  }
                }
              },
              "settlementScheduleProperty": {
                "internal": {
                  "timeTrigger": {
                    "conditions": [
                      {
                        "operator": "OPERATOR_GREATER_THAN_OR_EQUAL",
                        "value": "0"
                      }
                    ],
                    "triggers": [
                      {
                        "every": 1800
                      }
                    ]
                  }
                }
              },
              "dataSourceSpecBinding": {
                "settlementDataProperty": "btc.price",
                "settlementScheduleProperty": "vegaprotocol.builtin.timetrigger"
              }
            }
          },
          "metadata":[
            "base:BTC",
            "quote:USDT",
            "class:fx/crypto",
            "perpetual",
            "sector:defi",
            "enactment:2023-11-11T08:00:00Z"
          ],
          "priceMonitoringParameters": {
            "triggers": [
              {
                "horizon": "4320",
                "probability": "0.99",
                "auctionExtension": "300"
              },
              {
                "horizon": "1440",
                "probability": "0.99",
                "auctionExtension": "180"
              },
              {
                "horizon": "360",
                "probability": "0.99",
                "auctionExtension": "120"
              }
            ]
          },
          "liquidityMonitoringParameters": {
            "targetStakeParameters": {
              "timeWindow": "3600",
              "scalingFactor": 10
            },
            "triggeringRatio": "0.9",
            "auctionExtension": "1"
          },
          "logNormal": {
            "tau": 0.00000380258,
            "riskAversionParameter": 0.000001,
            "params": {
              "mu": 0,
              "r": 0,
              "sigma": 1.5
            }
          },
          "liquiditySlaParameters": {
            "priceRange": "0.015",
            "commitmentMinTimeFraction": "0.60",
            "performanceHysteresisEpochs": "0",
            "slaCompetitionFactor": "0.2"
          }
        }
      },
      "closingTimestamp": 1699599600,
      "enactmentTimestamp": 1699686000
    }
  }

Hi David,

I think the SLA params you have proposed seem reasonable.

I think anything around 0.75-0.9 for minTimeFraction along with a high competitionFactor will work well initially to encourage LPs to quote consistently while giving them some breathing room so that they can avoid having their bond slashed.

Just wanted to provide some further feedback based on your posts in Discord about the updated SLA params for your proposal. This is pretty much copy pasted from my posts in Discord:

Some initial thoughts:

I don’t think it is necessary to restrict the price range so severely. An LP that places orders farther away than a couple percentage points will already earn significantly less fees. For example; on the current Eth market I have estimated that the probability of trading calculated by core as part of the liquidity score calculation falls off to 0.25 after only a 1.3% increase in price from the best ask. As such, orders placed here will produce only 1/4 of the liquidity score that the same size order would produce at the best ask price, and so I do not think it is necessary to restrict the range so much. I think it is still reasonable for an LP to be able to place orders up to roughly 4%~5% away from the best price on each side of the book considering the fact they will earn a very small amount of fees by placing their orders here.

It is also important to consider that cryptocurrencies are extremely volatile, the price of Eth and Btc can move 2%+ in seconds. I don’t think it is reasonable to force LPs to only quote in such a tight range as 1.5% on leveraged markets such as these.

As for minTimeFraction this is a bit lower than I would like to see but I think a temporary low value such as this could be acceptable initially IF the competition factor is set high eg 70%-100%.

If we take an example using your proposed parameters, if an LP meets their commitment for 60.01% then they will get penalized ~20% of their fee revenue for that epoch, while someone who provided 99% uptime will only get penalised a small amount and they will not get a significant subsidy from the penalties of the LP that only had a 60.01% uptime. As such an LP can take significantly less risk by only quoting 60% of the time and they will still recieve 80% of the liquidity fees allocated to them by the protocol. This disincentivizes LPs from quoting during the riskiest and highest volatility moments in time (Which arguably are the most important times for good liquidity).

I think the main argument for setting a low minTimeFraction would be to provide a “safety net” for MMs while they get used trading on Vega and in the event of outages/datanode issues. However, I think it should be strongly discouraged to do the “bare minimum” by staying just a little bit above this minTimeFraction, and the logical way to discourage that would be to set the competition factor higher to encourage the LPs to maintain their liquidity in the book as much as possible. The competition factor enables this by rewarding those LPs that have consistently high up-time by redirecting fees from poorly performing LPs to the accounts of the consistent LPs as a “performance bonus”, hence driving competition between LPs.

With respect to the hysteresis epochs I think it is fine to set it to 0/1, I also think it is fine to set it higher to encourage consistency and discourage an LP from intentionally staying slightly above the minTimeFraction.

In summary I agree wholeheartedly with your ideology that we need to provide an attractive environment for Market Makers but I do not echo the sentiment that the best way to do this is by setting all the above parameters to very lenient values. I think there needs to be balance, eg; a low minTimeFraction should be matched with a high competitionFactor. Or a high minTimeFraction should be matched with a low bondPenaltyMax or bondPenaltySlope (network level parameters). This helps ensure we are not compromising the liquidity of the market while also not forcing the LPs to take unnecessary risk.

A set of values off the top of my head that I think might be more appropriate would be:

"liquiditySlaParameters": {
            "priceRange": "0.05",
            "commitmentMinTimeFraction": "0.75",
            "performanceHysteresisEpochs": "0",
            "slaCompetitionFactor": "0.8"
}

Interested to hear some thoughts and feedback from other community members and the Vega team on this.

Regards

Ed

There are some values missing under the perpetual part in order for the proposal to be accepted, you can always test on Fairground before mainnet. What you want the values to be I leave up to you but they are required.

"perpetual": {
              "clampLowerBound": "0",
              "clampUpperBound": "0",
              "interestRate": "0",
              "marginFundingFactor": "0.95",

One more small mistake:

That part should be

“dataSourceSpecForSettlementSchedule”: {
“internal”: {

With respect to the interest rate and clamp values that are missing from the initial proposal, as pointed out by Dan, I think we should strongly consider setting these params in a such a way that it creates a positive bias to the funding rate for reasons I described in my comment on the ETH/USD-PERP proposal: VMP-12 - Create Market - ETH/USD(USDT) Perpetual - #27 by Ed-Commodum

Regards

Ed

Bringing this thread back to life as I think we need to get BTC perps created ASAP. We’ve now had ETH perps running for a few days and observed the markets functioning quite well.

There is, however, an issue with the funding calcuations caused by the fact that Chainlink only updates the ETHUSD price once per hour (or if there’s a price move of more than 0.5% since the last update).

Because the ETH perp market on Vega has a very short funding window of only 30 minutes, we are observing very large and volatile funding rates as the mark price on Vega moves with the underlying market, but the Chainlink oracle used for the index price has ~15-30 minutes of latency. Over a large number of funding windows, the average funding rate approximates a value closer to zero, as the funding rate flips from positive and negative between different funding periods. However, in any given funding window the funding rate has been observed as being upwards of 75bps. With funding paid every 30 minutes this creates a rather undesirable experience for traders holding positions. It will also result in a need for market makers to widen their spreads to avoid being exposed to funding rate abritrage.

With this in mind, I suggest we increase the funding period to 8 hours to bring it inline with popular CEXs (e.g. Bybit and Binance). I suggest also applying a 5bps clamp and 10% annual interest rate.

I suggest we leave the ETH perps as they are for now and observe whether the BTC perps have a lower and less volatile funding rate, as well as tighter spreads. If the BTC config is better, we should then change the ETH perps to be consistent with the BTC perps until we’re able to source more frequent index prices via better oracles than Chainlink.

I have prepared a proposal JSON that I think is appropriate:

{
    "rationale": {
      "title": "VMP-13 Create market BTC/USD Perpetual",
      "description": "## Summary\n\nThis proposal requests to list BTC/USD Perpetual as a market with USDT as a settlement asset"
    },
    "terms": {
      "newMarket": {
        "changes": {
          "linearSlippageFactor": "0.001",
          "quadraticSlippageFactor": "0",
          "decimalPlaces": "1",
          "positionDecimalPlaces": "4",
          "instrument": {
            "name": "BTC/USD(USDT)-Perp",
            "code": "BTC/USD-PERP",
            "perpetual": {
              "settlementAsset": "bf1e88d19db4b3ca0d1d5bdb73718a01686b18cf731ca26adedf3c8b83802bba",
              "quoteName": "USDT",
              "marginFundingFactor": "0.9",
              "interestRate": "0.1095",
              "clampLowerBound": "-0.0005",
              "clampUpperBound": "0.0005",
              "dataSourceSpecForSettlementData": {
                "external": {
                  "ethOracle": {
                    "address": "0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c",
                    "abi": "[{\"inputs\":[],\"name\":\"latestAnswer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
                    "method": "latestAnswer",
                    "normalisers": [
                      {
                        "name": "btc.price",
                        "expression": "$[0]"
                      }
                    ],
                    "requiredConfirmations": 3,
                    "trigger": {
                      "timeTrigger": {
                        "initial": "1701453600",
                        "every": "300"
                      }
                    },
                    "filters": [
                      {
                        "key": {
                          "name": "btc.price",
                          "type": "TYPE_INTEGER",
                          "numberDecimalPlaces": "8"
                        },
                        "conditions": [
                          {
                            "operator": "OPERATOR_GREATER_THAN",
                            "value": "0"
                          }
                        ]
                      }
                    ]
                  }
                }
              },
              "dataSourceSpecForSettlementSchedule": {
                "internal": {
                  "timeTrigger": {
                    "conditions": [
                      {
                        "operator": "OPERATOR_GREATER_THAN_OR_EQUAL",
                        "value": "0"
                      }
                    ],
                    "triggers": [
                      {
                        "initial": "1701453600",
                        "every": "28800"
                      }
                    ]
                  }
                }
              },
              "dataSourceSpecBinding": {
                "settlementDataProperty": "btc.price",
                "settlementScheduleProperty": "vegaprotocol.builtin.timetrigger"
              }
            }
          },
          "metadata":[
            "base:BTC",
            "quote:USDT",
            "class:fx/crypto",
            "perpetual",
            "sector:defi",
            "enactment:2023-12-01T18:00:00Z"
          ],
          "priceMonitoringParameters": {
            "triggers": [
              {
                "horizon": "4320",
                "probability": "0.9999999",
                "auctionExtension": "300"
              },
              {
                "horizon": "1440",
                "probability": "0.9999999",
                "auctionExtension": "180"
              },
              {
                "horizon": "360",
                "probability": "0.9999999",
                "auctionExtension": "120"
              }
            ]
          },
          "liquidityMonitoringParameters": {
            "targetStakeParameters": {
              "timeWindow": "3600",
              "scalingFactor": 0.05
            },
            "triggeringRatio": "0.9",
            "auctionExtension": "1"
          },
          "logNormal": {
            "tau": 0.00000380258,
            "riskAversionParameter": 0.000001,
            "params": {
              "mu": 0,
              "r": 0,
              "sigma": 1.5
            }
          },
          "liquiditySlaParameters": {
            "priceRange": "0.03",
            "commitmentMinTimeFraction": "0.85",
            "performanceHysteresisEpochs": "1",
            "slaCompetitionFactor": "0.5"
          }
        }
      },
      "closingTimestamp": 1701453600,
      "enactmentTimestamp": 1701453600
    }
  }

In this proposal the sampling period with which to get spot prices from Ethereum is set to 1800 or every 30 minutes, the settlement schedule trigger has been set to 28800 which is every 8 hours.

The SLA params have been configured to match the existing ETH perp.

The price monitoring triggers have had their "probability" fields increased to match the existing ETH perp.

Additionally, I have added a proposed clamp value that imitates the usual defaults you would find on CEX Perps. An interest rate of 0.1095 (10.95% per year) along with the 8h funding period will result in the funding rate being clamped to 0.01% for every funding period while the price deviation between the mark TWAP and spot TWAP remains within the interval -0.04% to 0.06%.

If there are no objections to this set of parameters and no one can spot any mistakes in the JSON then I will submit the proposal on-chain.

Edit: I have updated the JSON with the 5 min update interval for the spot price sampling from Ethereum as suggested below.

1 Like

The only thing I would change is the interval for getting prices from Ethereum. In case of a large price move, we will be waiting a long time to get an updated price, as the Chainlink oracle updates more frequently if the price move sby more than 50bps.

For that reason, let’s fetch the prices from Ethereum more frequently. I think once every 5 minutes would be better.

Agree that the sampling period should be shorter, i’d say 1 min tbh. 5 min is pretty long during volatile periods

Hi,

I’ve noticed that triggering ratio for the liquidity monitoring is currently set to 0.9, however that’s been changed to 0.1 on ETH/USD market as the current implementation of perps doesn’t handle auctions very well. “quoteName” should probably be “USD” rather than “USDT”. Both of these can be handled with a market update proposal.

Hi Witold, thanks for pointing these out. I will make a market update proposal shortly once the market has enacted.

1 Like

Perfect. Btw. there’s no need to wait, as long as it enacts after the market creation has been enacted it will work fine.