delphi.market/src/market.go
2023-09-09 22:52:50 +02:00

33 lines
1.1 KiB
Go

package main
import (
"errors"
"math"
)
// logarithmic market scoring rule (LMSR) market maker from Robin Hanson:
// https://mason.gmu.edu/~rhanson/mktscore.pdf
func BinaryLMSRBuy(invariant int, funding int, tokensAQ float64, tokensBQ float64, sats int) (float64, error) {
k := float64(invariant)
f := float64(funding)
numOutcomes := 2.0
expA := -tokensAQ / f
expB := -tokensBQ / f
if k != math.Pow(numOutcomes, expA)+math.Pow(numOutcomes, expB) {
// invariant should not already be broken
return -1, errors.New("invariant already broken")
}
// AMM converts order into equal amount of tokens per outcome and then solves equation to fix invariant
// see https://docs.gnosis.io/conditionaltokens/docs/introduction3/#an-example-with-lmsr
newTokensA := tokensAQ + float64(sats)
newTokensB := tokensBQ + float64(sats)
expB = -newTokensB / f
x := newTokensA + f*math.Log(k-math.Pow(numOutcomes, expB))/math.Log(numOutcomes)
expA = -(newTokensA - x) / f
if k != math.Pow(numOutcomes, expA)+math.Pow(numOutcomes, expB) {
// invariant should not be broken
return -1, errors.New("invariant broken")
}
return x, nil
}