Skip to content

Commit

Permalink
feat: rework virtual liquidity calcs and rename margin-ration -> leve…
Browse files Browse the repository at this point in the history
…rage
  • Loading branch information
wwestgarth committed May 3, 2024
1 parent 0e53b5c commit 4c84246
Show file tree
Hide file tree
Showing 44 changed files with 3,053 additions and 2,889 deletions.
20 changes: 10 additions & 10 deletions commands/amend_amm.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,21 +93,21 @@ func checkAmendAMM(cmd *commandspb.AmendAMM) Errors {
}
}

if cmd.ConcentratedLiquidityParameters.MarginRatioAtUpperBound != nil {
if cmd.ConcentratedLiquidityParameters.LeverageAtUpperBound != nil {
hasUpdate = true
if marginRatio, err := num.DecimalFromString(*cmd.ConcentratedLiquidityParameters.MarginRatioAtUpperBound); err != nil {
errs.AddForProperty("amend_amm.concentrated_liquidity_parameters.margin_ratio_at_upper_bound", ErrIsNotValidNumber)
} else if marginRatio.LessThan(num.DecimalZero()) {
errs.AddForProperty("amend_amm.concentrated_liquidity_parameters.margin_ratio_at_upper_bound", ErrMustBePositive)
if leverage, err := num.DecimalFromString(*cmd.ConcentratedLiquidityParameters.LeverageAtUpperBound); err != nil {
errs.AddForProperty("amend_amm.concentrated_liquidity_parameters.leverage_at_upper_bound", ErrIsNotValidNumber)
} else if leverage.LessThan(num.DecimalZero()) {
errs.AddForProperty("amend_amm.concentrated_liquidity_parameters.leverage_at_upper_bound", ErrMustBePositive)
}
}

if cmd.ConcentratedLiquidityParameters.MarginRatioAtLowerBound != nil {
if cmd.ConcentratedLiquidityParameters.LeverageAtLowerBound != nil {
hasUpdate = true
if marginRatio, err := num.DecimalFromString(*cmd.ConcentratedLiquidityParameters.MarginRatioAtLowerBound); err != nil {
errs.AddForProperty("amend_amm.concentrated_liquidity_parameters.margin_ratio_at_lower_bound", ErrIsNotValidNumber)
} else if marginRatio.LessThan(num.DecimalZero()) {
errs.AddForProperty("amend_amm.concentrated_liquidity_parameters.margin_ratio_at_lower_bound", ErrMustBePositive)
if leverage, err := num.DecimalFromString(*cmd.ConcentratedLiquidityParameters.LeverageAtLowerBound); err != nil {
errs.AddForProperty("amend_amm.concentrated_liquidity_parameters.leverage_at_lower_bound", ErrIsNotValidNumber)
} else if leverage.LessThan(num.DecimalZero()) {
errs.AddForProperty("amend_amm.concentrated_liquidity_parameters.leverage_at_lower_bound", ErrMustBePositive)
}
}

Expand Down
24 changes: 12 additions & 12 deletions commands/amend_amm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,50 +218,50 @@ func TestCheckAmendAMM(t *testing.T) {
{
submission: commandspb.AmendAMM{
ConcentratedLiquidityParameters: &commandspb.AmendAMM_ConcentratedLiquidityParameters{
MarginRatioAtUpperBound: ptr.From(""),
LeverageAtUpperBound: ptr.From(""),
},
},
errStr: "amend_amm.concentrated_liquidity_parameters.margin_ratio_at_upper_bound (is not a valid number)",
errStr: "amend_amm.concentrated_liquidity_parameters.leverage_at_upper_bound (is not a valid number)",
},
{
submission: commandspb.AmendAMM{
ConcentratedLiquidityParameters: &commandspb.AmendAMM_ConcentratedLiquidityParameters{
MarginRatioAtUpperBound: ptr.From("abc"),
LeverageAtUpperBound: ptr.From("abc"),
},
},
errStr: "amend_amm.concentrated_liquidity_parameters.margin_ratio_at_upper_bound (is not a valid number)",
errStr: "amend_amm.concentrated_liquidity_parameters.leverage_at_upper_bound (is not a valid number)",
},
{
submission: commandspb.AmendAMM{
ConcentratedLiquidityParameters: &commandspb.AmendAMM_ConcentratedLiquidityParameters{
MarginRatioAtUpperBound: ptr.From("-10"),
LeverageAtUpperBound: ptr.From("-10"),
},
},
errStr: "amend_amm.concentrated_liquidity_parameters.margin_ratio_at_upper_bound (must be positive)",
errStr: "amend_amm.concentrated_liquidity_parameters.leverage_at_upper_bound (must be positive)",
},
{
submission: commandspb.AmendAMM{
ConcentratedLiquidityParameters: &commandspb.AmendAMM_ConcentratedLiquidityParameters{
MarginRatioAtLowerBound: ptr.From(""),
LeverageAtLowerBound: ptr.From(""),
},
},
errStr: "amend_amm.concentrated_liquidity_parameters.margin_ratio_at_lower_bound (is not a valid number)",
errStr: "amend_amm.concentrated_liquidity_parameters.leverage_at_lower_bound (is not a valid number)",
},
{
submission: commandspb.AmendAMM{
ConcentratedLiquidityParameters: &commandspb.AmendAMM_ConcentratedLiquidityParameters{
MarginRatioAtLowerBound: ptr.From("abc"),
LeverageAtLowerBound: ptr.From("abc"),
},
},
errStr: "amend_amm.concentrated_liquidity_parameters.margin_ratio_at_lower_bound (is not a valid number)",
errStr: "amend_amm.concentrated_liquidity_parameters.leverage_at_lower_bound (is not a valid number)",
},
{
submission: commandspb.AmendAMM{
ConcentratedLiquidityParameters: &commandspb.AmendAMM_ConcentratedLiquidityParameters{
MarginRatioAtLowerBound: ptr.From("-10"),
LeverageAtLowerBound: ptr.From("-10"),
},
},
errStr: "amend_amm.concentrated_liquidity_parameters.margin_ratio_at_lower_bound (must be positive)",
errStr: "amend_amm.concentrated_liquidity_parameters.leverage_at_lower_bound (must be positive)",
},
{
submission: commandspb.AmendAMM{
Expand Down
32 changes: 14 additions & 18 deletions commands/submit_amm.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,28 +102,24 @@ func checkSubmitAMM(cmd *commandspb.SubmitAMM) Errors {
errs.AddForProperty("submit_amm.concentrated_liquidity_parameters.lower_bound", errors.New("lower_bound and upper_bound cannot both be empty"))
}

if cmd.ConcentratedLiquidityParameters.MarginRatioAtUpperBound == nil {
if !emptyUpper {
errs.AddForProperty("submit_amm.concentrated_liquidity_parameters.margin_ratio_at_upper_bound", ErrIsRequired)
if cmd.ConcentratedLiquidityParameters.LeverageAtUpperBound != nil {
if len(*cmd.ConcentratedLiquidityParameters.LeverageAtUpperBound) <= 0 {
errs.AddForProperty("submit_amm.concentrated_liquidity_parameters.leverage_at_upper_bound", ErrIsNotValidNumber)
} else if leverage, err := num.DecimalFromString(*cmd.ConcentratedLiquidityParameters.LeverageAtUpperBound); err != nil {
errs.AddForProperty("submit_amm.concentrated_liquidity_parameters.leverage_at_upper_bound", ErrIsNotValidNumber)
} else if leverage.LessThan(num.DecimalZero()) {
errs.AddForProperty("submit_amm.concentrated_liquidity_parameters.leverage_at_upper_bound", ErrMustBePositive)
}
} else if len(*cmd.ConcentratedLiquidityParameters.MarginRatioAtUpperBound) <= 0 {
errs.AddForProperty("submit_amm.concentrated_liquidity_parameters.margin_ratio_at_upper_bound", ErrIsNotValidNumber)
} else if marginRatio, err := num.DecimalFromString(*cmd.ConcentratedLiquidityParameters.MarginRatioAtUpperBound); err != nil {
errs.AddForProperty("submit_amm.concentrated_liquidity_parameters.margin_ratio_at_upper_bound", ErrIsNotValidNumber)
} else if marginRatio.LessThan(num.DecimalZero()) {
errs.AddForProperty("submit_amm.concentrated_liquidity_parameters.margin_ratio_at_upper_bound", ErrMustBePositive)
}

if cmd.ConcentratedLiquidityParameters.MarginRatioAtLowerBound == nil {
if !emptyLower {
errs.AddForProperty("submit_amm.concentrated_liquidity_parameters.margin_ratio_at_lower_bound", ErrIsRequired)
if cmd.ConcentratedLiquidityParameters.LeverageAtLowerBound != nil {
if len(*cmd.ConcentratedLiquidityParameters.LeverageAtLowerBound) <= 0 {
errs.AddForProperty("submit_amm.concentrated_liquidity_parameters.leverage_at_lower_bound", ErrIsNotValidNumber)
} else if leverage, err := num.DecimalFromString(*cmd.ConcentratedLiquidityParameters.LeverageAtLowerBound); err != nil {
errs.AddForProperty("submit_amm.concentrated_liquidity_parameters.leverage_at_lower_bound", ErrIsNotValidNumber)
} else if leverage.LessThan(num.DecimalZero()) {
errs.AddForProperty("submit_amm.concentrated_liquidity_parameters.leverage_at_lower_bound", ErrMustBePositive)
}
} else if len(*cmd.ConcentratedLiquidityParameters.MarginRatioAtLowerBound) <= 0 {
errs.AddForProperty("submit_amm.concentrated_liquidity_parameters.margin_ratio_at_lower_bound", ErrIsNotValidNumber)
} else if marginRatio, err := num.DecimalFromString(*cmd.ConcentratedLiquidityParameters.MarginRatioAtLowerBound); err != nil {
errs.AddForProperty("submit_amm.concentrated_liquidity_parameters.margin_ratio_at_lower_bound", ErrIsNotValidNumber)
} else if marginRatio.LessThan(num.DecimalZero()) {
errs.AddForProperty("submit_amm.concentrated_liquidity_parameters.margin_ratio_at_lower_bound", ErrMustBePositive)
}

if len(cmd.SlippageTolerance) <= 0 {
Expand Down
40 changes: 20 additions & 20 deletions commands/submit_amm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,50 +224,50 @@ func TestCheckSubmitAMM(t *testing.T) {
{
submission: commandspb.SubmitAMM{
ConcentratedLiquidityParameters: &commandspb.SubmitAMM_ConcentratedLiquidityParameters{
MarginRatioAtUpperBound: ptr.From(""),
LeverageAtUpperBound: ptr.From(""),
},
},
errStr: "submit_amm.concentrated_liquidity_parameters.margin_ratio_at_upper_bound (is not a valid number)",
errStr: "submit_amm.concentrated_liquidity_parameters.leverage_at_upper_bound (is not a valid number)",
},
{
submission: commandspb.SubmitAMM{
ConcentratedLiquidityParameters: &commandspb.SubmitAMM_ConcentratedLiquidityParameters{
MarginRatioAtUpperBound: ptr.From("abc"),
LeverageAtUpperBound: ptr.From("abc"),
},
},
errStr: "submit_amm.concentrated_liquidity_parameters.margin_ratio_at_upper_bound (is not a valid number)",
errStr: "submit_amm.concentrated_liquidity_parameters.leverage_at_upper_bound (is not a valid number)",
},
{
submission: commandspb.SubmitAMM{
ConcentratedLiquidityParameters: &commandspb.SubmitAMM_ConcentratedLiquidityParameters{
MarginRatioAtUpperBound: ptr.From("-10"),
LeverageAtUpperBound: ptr.From("-10"),
},
},
errStr: "submit_amm.concentrated_liquidity_parameters.margin_ratio_at_upper_bound (must be positive)",
errStr: "submit_amm.concentrated_liquidity_parameters.leverage_at_upper_bound (must be positive)",
},
{
submission: commandspb.SubmitAMM{
ConcentratedLiquidityParameters: &commandspb.SubmitAMM_ConcentratedLiquidityParameters{
MarginRatioAtLowerBound: ptr.From(""),
LeverageAtLowerBound: ptr.From(""),
},
},
errStr: "submit_amm.concentrated_liquidity_parameters.margin_ratio_at_lower_bound (is not a valid number)",
errStr: "submit_amm.concentrated_liquidity_parameters.leverage_at_lower_bound (is not a valid number)",
},
{
submission: commandspb.SubmitAMM{
ConcentratedLiquidityParameters: &commandspb.SubmitAMM_ConcentratedLiquidityParameters{
MarginRatioAtLowerBound: ptr.From("abc"),
LeverageAtLowerBound: ptr.From("abc"),
},
},
errStr: "submit_amm.concentrated_liquidity_parameters.margin_ratio_at_lower_bound (is not a valid number)",
errStr: "submit_amm.concentrated_liquidity_parameters.leverage_at_lower_bound (is not a valid number)",
},
{
submission: commandspb.SubmitAMM{
ConcentratedLiquidityParameters: &commandspb.SubmitAMM_ConcentratedLiquidityParameters{
MarginRatioAtLowerBound: ptr.From("-10"),
LeverageAtLowerBound: ptr.From("-10"),
},
},
errStr: "submit_amm.concentrated_liquidity_parameters.margin_ratio_at_lower_bound (must be positive)",
errStr: "submit_amm.concentrated_liquidity_parameters.leverage_at_lower_bound (must be positive)",
},
{
submission: commandspb.SubmitAMM{
Expand All @@ -293,9 +293,9 @@ func TestCheckSubmitAMM(t *testing.T) {
SlippageTolerance: "0.09",
CommitmentAmount: "10000",
ConcentratedLiquidityParameters: &commandspb.SubmitAMM_ConcentratedLiquidityParameters{
Base: "20000",
MarginRatioAtUpperBound: ptr.From("0.1"),
MarginRatioAtLowerBound: ptr.From("0.1"),
Base: "20000",
LeverageAtUpperBound: ptr.From("0.1"),
LeverageAtLowerBound: ptr.From("0.1"),
},
},
errStr: "submit_amm.concentrated_liquidity_parameters.lower_bound (lower_bound and upper_bound cannot both be empty)",
Expand All @@ -307,11 +307,11 @@ func TestCheckSubmitAMM(t *testing.T) {
CommitmentAmount: "10000",
ProposedFee: "0.03",
ConcentratedLiquidityParameters: &commandspb.SubmitAMM_ConcentratedLiquidityParameters{
Base: "20000",
UpperBound: ptr.From("30000"),
LowerBound: ptr.From("10000"),
MarginRatioAtUpperBound: ptr.From("0.1"),
MarginRatioAtLowerBound: ptr.From("0.1"),
Base: "20000",
UpperBound: ptr.From("30000"),
LowerBound: ptr.From("10000"),
LeverageAtUpperBound: ptr.From("0.1"),
LeverageAtLowerBound: ptr.From("0.1"),
},
},
},
Expand Down
11 changes: 7 additions & 4 deletions core/execution/amm/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ func NewFromProto(
priceFactor num.Decimal,
positionFactor num.Decimal,
marketActivityTracker *common.MarketActivityTracker,
) *Engine {
) (*Engine, error) {
e := New(log, broker, collateral, market, risk, position, priceFactor, positionFactor, marketActivityTracker)

for _, v := range state.SubAccounts {
Expand All @@ -210,10 +210,14 @@ func NewFromProto(
}

for _, v := range state.Pools {
e.add(NewPoolFromProto(e.rooter.sqrt, e.collateral, e.position, v.Pool, v.Party, priceFactor))
p, err := NewPoolFromProto(e.rooter.sqrt, e.collateral, e.position, v.Pool, v.Party, priceFactor)
if err != nil {
return e, err
}
e.add(p)
}

return e
return e, nil
}

func (e *Engine) IntoProto() *v1.AmmState {
Expand Down Expand Up @@ -435,7 +439,6 @@ func (e *Engine) submit(active []*Pool, agg *types.Order, inner, outer *num.Uint

// calculate the price the pool wil give for the trading volume
price := p.PriceForVolume(volume, agg.Side)

if e.log.GetLevel() == logging.DebugLevel {
e.log.Debug("generated order at price",
logging.String("price", price.String()),
Expand Down
45 changes: 21 additions & 24 deletions core/execution/amm/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,8 @@ func testAmendAMMSparse(t *testing.T) {
// no amend to the commitment amount
amend.CommitmentAmount = nil
// no amend to the margin factors either
amend.Parameters.MarginRatioAtLowerBound = nil
amend.Parameters.MarginRatioAtUpperBound = nil
amend.Parameters.LeverageAtLowerBound = nil
amend.Parameters.LeverageAtUpperBound = nil
// to change something at least, inc the base + bounds by 1
amend.Parameters.Base.AddSum(num.UintOne())
amend.Parameters.UpperBound.AddSum(num.UintOne())
Expand Down Expand Up @@ -284,12 +284,11 @@ func testBasicSubmitOrder(t *testing.T) {
Type: types.OrderTypeLimit,
}

ensureBalances(t, tst.col, 10000000000)
ensurePosition(t, tst.pos, 0, num.NewUint(0))
orders := tst.engine.SubmitOrder(agg, num.NewUint(2000), num.NewUint(2020))
require.Len(t, orders, 1)
assert.Equal(t, "2009", orders[0].Price.String())
assert.Equal(t, uint64(242367), orders[0].Size)
assert.Equal(t, 236855, int(orders[0].Size))

// AMM is now short, but another order comes in that will flip its position to long
agg = &types.Order{
Expand All @@ -299,13 +298,12 @@ func testBasicSubmitOrder(t *testing.T) {
Price: num.NewUint(1900),
}

ensureBalancesN(t, tst.col, 10000000000, 3)
orders = tst.engine.SubmitOrder(agg, num.NewUint(2020), num.NewUint(1990))
require.Len(t, orders, 1)
assert.Equal(t, "2036", orders[0].Price.String())
assert.Equal(t, "2035", orders[0].Price.String())
// note that this volume being bigger than 242367 above means we've moved back to position, then flipped
// sign, and took volume from the other curve.
assert.Equal(t, uint64(371231), orders[0].Size)
assert.Equal(t, 362325, int(orders[0].Size))
}

func testSubmitMarketOrder(t *testing.T) {
Expand All @@ -331,7 +329,7 @@ func testSubmitMarketOrder(t *testing.T) {
orders := tst.engine.SubmitOrder(agg, num.NewUint(1980), num.NewUint(1990))
require.Len(t, orders, 1)
assert.Equal(t, "2005", orders[0].Price.String())
assert.Equal(t, uint64(129839), orders[0].Size)
assert.Equal(t, 126420, int(orders[0].Size))
}

func testSubmitOrderProRata(t *testing.T) {
Expand All @@ -347,7 +345,6 @@ func testSubmitOrderProRata(t *testing.T) {
require.NoError(t, tst.engine.SubmitAMM(ctx, submit, vgcrypto.RandomHash(), nil))
}

ensureBalancesN(t, tst.col, 10000000000, 3)
ensurePositionN(t, tst.pos, 0, num.NewUint(0), 3)

// now submit an order against it
Expand Down Expand Up @@ -408,11 +405,11 @@ func testSubmitOrderAcrossAMMBoundary(t *testing.T) {
assert.Equal(t, "2049", orders[2].Price.String())

// second round, 2 orders moving all pool's to the upper boundary of the second shortest
assert.Equal(t, "2125", orders[3].Price.String())
assert.Equal(t, "2124", orders[4].Price.String())
assert.Equal(t, "2124", orders[3].Price.String())
assert.Equal(t, "2125", orders[4].Price.String())

// third round, 1 orders moving the last pool to its boundary
assert.Equal(t, "2174", orders[5].Price.String())
assert.Equal(t, "2175", orders[5].Price.String())
}

func testSubmitOrderAcrossAMMBoundarySell(t *testing.T) {
Expand Down Expand Up @@ -486,8 +483,8 @@ func testBestPricesAndVolume(t *testing.T) {
bid, bvolume, ask, avolume := tst.engine.BestPricesAndVolumes()
assert.Equal(t, "1999", bid.String())
assert.Equal(t, "2001", ask.String())
assert.Equal(t, uint64(38526), bvolume)
assert.Equal(t, uint64(36615), avolume)
assert.Equal(t, 37512, int(bvolume))
assert.Equal(t, 35781, int(avolume))

// test GetVolumeAtPrice returns the same volume given best bid/ask
tst.pos.EXPECT().GetPositionsByParty(gomock.Any()).Times(6 * 2).Return(
Expand Down Expand Up @@ -748,11 +745,11 @@ func getPoolSubmission(t *testing.T, party, market string) *types.SubmitAMM {
},
CommitmentAmount: num.NewUint(10000000000),
Parameters: &types.ConcentratedLiquidityParameters{
Base: num.NewUint(2000),
LowerBound: num.NewUint(1800),
UpperBound: num.NewUint(2200),
MarginRatioAtLowerBound: ptr.From(num.DecimalOne()),
MarginRatioAtUpperBound: ptr.From(num.DecimalOne()),
Base: num.NewUint(2000),
LowerBound: num.NewUint(1800),
UpperBound: num.NewUint(2200),
LeverageAtLowerBound: ptr.From(num.DecimalOne()),
LeverageAtUpperBound: ptr.From(num.DecimalOne()),
},
}
}
Expand All @@ -767,11 +764,11 @@ func getPoolAmendment(t *testing.T, party, market string) *types.AmendAMM {
},
CommitmentAmount: num.NewUint(10000000000),
Parameters: &types.ConcentratedLiquidityParameters{
Base: num.NewUint(2100),
LowerBound: num.NewUint(1900),
UpperBound: num.NewUint(2300),
MarginRatioAtLowerBound: ptr.From(num.DecimalOne()),
MarginRatioAtUpperBound: ptr.From(num.DecimalOne()),
Base: num.NewUint(2100),
LowerBound: num.NewUint(1900),
UpperBound: num.NewUint(2300),
LeverageAtLowerBound: ptr.From(num.DecimalOne()),
LeverageAtUpperBound: ptr.From(num.DecimalOne()),
},
}
}
Expand Down
Loading

0 comments on commit 4c84246

Please sign in to comment.