浏览代码

level3的利润计算也没有问题了,可以进行下一步:利润排序

skyfffire 2 年之前
父节点
当前提交
b9f044ec68
共有 3 个文件被更改,包括 136 次插入58 次删除
  1. 84 18
      arbitrage/calc_utils.go
  2. 50 39
      arbitrage/calc_utils_test.go
  3. 2 1
      arbitrage/lp_utils.go

+ 84 - 18
arbitrage/calc_utils.go

@@ -42,9 +42,9 @@ func SimulationLevel2Path(path *Path) {
 	decimalNumber1 := decimal.NewFromInt(1)
 	decimalNumber1e6 := decimal.NewFromInt(1e6)
 
-	//F0 = 1 - fee0/1e6
+	// F0 = 1 - fee0/1e6
 	F0 := decimalNumber1.Sub(fee0.Div(decimalNumber1e6))
-	//F1 = 1 - fee1/1e6
+	// F1 = 1 - fee1/1e6
 	F1 := decimalNumber1.Sub(fee1.Div(decimalNumber1e6))
 
 	// B0, S0
@@ -54,34 +54,29 @@ func SimulationLevel2Path(path *Path) {
 	B1, _ := decimal.NewFromString(fm1.InReserve.String())
 	S1, _ := decimal.NewFromString(fm1.OutReserve.String())
 
-	// F0 * F1 * S0
-	partA0 := F0.Mul(F1.Mul(S0))
-	// B1 * F0
-	partA1 := B1.Mul(F0)
-	// F0 * F1 * S0 + B1 * F0
-	partA := partA0.Add(partA1)
-
 	// if F0*F1*S0 + B1*F0 == 0
-	if partA.IntPart() == 0 {
-		HistoryError(fmt.Sprintf("Is error part0. F0=%v, F1=%v, S0=%v, B1=%v, F0=%v", F0, F1, S0, B1, F0))
+	partX := F0.Mul(F1).Mul(S0).Add(B1.Mul(F0))
+	if partX.Equals(decimal.NewFromInt(0)) {
+		HistoryError(fmt.Sprintf("Is error partX. F0=%v, F1=%v, S0=%v, B1=%v", F0, F1, S0, B1))
 
 		return
 	}
 
-	// B0 * B1 * F0 * F1 * S0 * S1
-	partB := B0.Mul(B1).Mul(F0).Mul(F1).Mul(S0).Mul(S1)
-	// B0 * B1 * F0 * F1 * S0 * S1 ** 0.5 - B0 * B1
-	partC := Sqrt(partB, 0).Sub(B0.Mul(B1))
+	// (B0 * B1 * F0 * F1 * S0 * S1) ** 0.5
+	partB0 := Sqrt(B0.Mul(B1).Mul(F0).Mul(F1).Mul(S0).Mul(S1), 0)
+	// B0 * B1 * F0 * F1 * S0 * S1 - B0 * B1
+	partB := partB0.Sub(B0.Mul(B1))
 
 	// best input number
-	I := partC.Div(partA).Truncate(0)
+	I := partB.Div(partX).Truncate(0)
 
 	amountIn := I
 	amountOut0 := CalcOutByIn(amountIn, B0, S0, fee0)
 	amountOut1 := CalcOutByIn(amountOut0, B1, S1, fee1)
 	profit := amountOut1.Sub(amountIn)
 
-	sim := Simulation{
+	path.Profit = profit
+	path.Sim = Simulation{
 		AmountIn:      amountIn,
 		AmountInStr:   amountIn.String(),
 		AmountOut0:    amountOut0,
@@ -91,8 +86,79 @@ func SimulationLevel2Path(path *Path) {
 		Profit:        profit,
 		ProfitStr:     profit.String(),
 	}
+}
+
+func SimulationLevel3Path(path *Path) {
+	if path.Level != 3 {
+		HistoryError(fmt.Sprintf("Level error. Need %v, but got %v", 3, path.Level))
+
+		return
+	}
+
+	fm0 := path.FmList[0]
+	fm1 := path.FmList[1]
+	fm2 := path.FmList[2]
+
+	// fee0, fee1
+	fee0 := decimal.NewFromInt(fm0.Fee)
+	fee1 := decimal.NewFromInt(fm1.Fee)
+	fee2 := decimal.NewFromInt(fm2.Fee)
+
+	decimalNumber1 := decimal.NewFromInt(1)
+	decimalNumber1e6 := decimal.NewFromInt(1e6)
 
-	path.Sim = sim
+	// F0 = 1 - fee0/1e6
+	F0 := decimalNumber1.Sub(fee0.Div(decimalNumber1e6))
+	// F1 = 1 - fee1/1e6
+	F1 := decimalNumber1.Sub(fee1.Div(decimalNumber1e6))
+	// F2 = 1 - fee2 / 1e6
+	F2 := decimalNumber1.Sub(fee2.Div(decimalNumber1e6))
+
+	// B0, S0
+	B0, _ := decimal.NewFromString(fm0.InReserve.String())
+	S0, _ := decimal.NewFromString(fm0.OutReserve.String())
+	// B1, S1
+	B1, _ := decimal.NewFromString(fm1.InReserve.String())
+	S1, _ := decimal.NewFromString(fm1.OutReserve.String())
+	// B2, S2
+	B2, _ := decimal.NewFromString(fm2.InReserve.String())
+	S2, _ := decimal.NewFromString(fm2.OutReserve.String())
+
+	// if (F0 * F1 * F2 * S0 * S1 + B2 * F0 * F1 * S0 + B1 * B2 * F0) == 0
+	partX := F0.Mul(F1).Mul(F2).Mul(S0).Mul(S1).Add(B2.Mul(F0).Mul(F1).Mul(S0).Add(B1.Mul(B2).Mul(F0)))
+	if partX.Equals(decimal.NewFromInt(0)) {
+		HistoryError(fmt.Sprintf("Is error partX. F0=%v, F1=%v, F2=%v, S0=%v, S1=%v, B1=%v, B2=%v", F0, F1, F2, S0, S1, B1, B2))
+
+		return
+	}
+
+	// (B0 * B1 * B2 * F0 * F1 * F2 * S0 * S1 * S2) ** 0.5
+	partA0 := Sqrt(B0.Mul(B1).Mul(B2).Mul(S0).Mul(S1).Mul(S2).Mul(F0).Mul(F1).Mul(F2), 0)
+	// B0 * B1 * B2
+	partA1 := B0.Mul(B1).Mul(B2)
+	// ((B0 * B1 * B2 * F0 * F1 * F2 * S0 * S1 * S2) ** 0.5 - B0 * B1 * B2) / F0 * F1 * F2 * S0 * S1 + B2 * F0 * F1 * S0 + B1 * B2 * F0
+	amountIn := partA0.Sub(partA1).Div(partX).Truncate(0)
+	//HistoryInfo(fmt.Sprintf("amountIn=%v", amountIn))
+
+	decimalNumber2 := decimal.NewFromInt(2)
+	amountOut0 := CalcOutByIn(amountIn, B0, S0, fee0).Sub(decimalNumber2)
+	amountOut1 := CalcOutByIn(amountOut0, B1, S1, fee1).Sub(decimalNumber2)
+	amountOut2 := CalcOutByIn(amountOut1, B2, S2, fee2).Sub(decimalNumber2)
+	profit := amountOut2.Sub(amountIn)
+
+	path.Profit = profit
+	path.Sim = Simulation{
+		AmountIn:      amountIn,
+		AmountInStr:   amountIn.String(),
+		AmountOut0:    amountOut0,
+		AmountOut0Str: amountOut0.String(),
+		AmountOut1:    amountOut1,
+		AmountOut1Str: amountOut1.String(),
+		AmountOut2:    amountOut2,
+		AmountOut2Str: amountOut2.String(),
+		Profit:        profit,
+		ProfitStr:     profit.String(),
+	}
 }
 
 func CalcOutByIn(amountIn decimal.Decimal, reserveIn decimal.Decimal, reserveOut decimal.Decimal, fee decimal.Decimal) decimal.Decimal {

+ 50 - 39
arbitrage/calc_utils_test.go

@@ -6,44 +6,6 @@ import (
 	"testing"
 )
 
-//path3 := Path{
-//LoanTokenHash: "0xea76a1f367f907822425794f9b7af2babcdd5c2b",
-//Level:         3,
-//Profit:        0,
-//FmList: []FundMovements{
-//{
-//LpHash:     "0x0db5e03036a65de4591a1e1d880d6b08dc719ea4",
-//Fee:        0,
-//InIndex:    0,
-//InToken:    "0x0769298444cf2bd861df2ac9a61db971b77f8abb",
-//InReserve:  big.NewInt(218981463359557),
-//OutIndex:   1,
-//OutToken:   "0xea76a1f367f907822425794f9b7af2babcdd5c2b",
-//OutReserve: big.NewInt(1100114988303332),
-//},
-//{
-//LpHash:     "0x05c35f1e08ebd74abebc4c80ad78d9be8ef40b7f",
-//Fee:        0,
-//InIndex:    1,
-//InToken:    "0xea76a1f367f907822425794f9b7af2babcdd5c2b",
-//InReserve:  big.NewInt(37975597815966),
-//OutIndex:   0,
-//OutToken:   "0xe446a35fd3d65bb8ee65cc3dd084b34b5ea80041",
-//OutReserve: big.NewInt(14947615986622),
-//},
-//{
-//LpHash:     "0x03c6c469118985ee938d387e8d720239154eb87a",
-//Fee:        0,
-//InIndex:    1,
-//InToken:    "0xe446a35fd3d65bb8ee65cc3dd084b34b5ea80041",
-//InReserve:  big.NewInt(112222625564643),
-//OutIndex:   0,
-//OutToken:   "0x0769298444cf2bd861df2ac9a61db971b77f8abb",
-//OutReserve: big.NewInt(176020331889305),
-//},
-//},
-//}
-
 func TestSimulationLevel2Path(t *testing.T) {
 	B0, _ := new(big.Int).SetString("5322f45fa85", 16)
 	S0, _ := new(big.Int).SetString("5dd5e65767ffbc64221", 16)
@@ -53,7 +15,6 @@ func TestSimulationLevel2Path(t *testing.T) {
 	path2 := Path{
 		LoanTokenHash: "0xea76a1f367f907822425794f9b7af2babcdd5c2b",
 		Level:         2,
-		Profit:        0,
 		FmList: []FundMovements{
 			{
 				LpHash:     "0x0db5e03036a65de4591a1e1d880d6b08dc719ea4",
@@ -82,3 +43,53 @@ func TestSimulationLevel2Path(t *testing.T) {
 
 	HistoryInfo(fmt.Sprintf("%+v", path2.Sim.ToJsonString()))
 }
+
+func TestSimulationLevel3Path(t *testing.T) {
+	B0, _ := new(big.Int).SetString("5322f45fa85", 16)
+	S0, _ := new(big.Int).SetString("5dd5e65767ffbc64221", 16)
+	B1, _ := new(big.Int).SetString("6c6293541464922a3e", 16)
+	S1, _ := new(big.Int).SetString("511896afa2", 16)
+	B2, _ := new(big.Int).SetString("511496afa2", 16)
+	S2, _ := new(big.Int).SetString("611896afa2", 16)
+
+	path3 := Path{
+		LoanTokenHash: "0xea76a1f367f907822425794f9b7af2babcdd5c2b",
+		Level:         3,
+		FmList: []FundMovements{
+			{
+				LpHash:     "0x0db5e03036a65de4591a1e1d880d6b08dc719ea4",
+				Fee:        20,
+				InIndex:    0,
+				InToken:    "0x0769298444cf2bd861df2ac9a61db971b77f8abb",
+				InReserve:  B0,
+				OutIndex:   1,
+				OutToken:   "0xea76a1f367f907822425794f9b7af2babcdd5c2b",
+				OutReserve: S0,
+			},
+			{
+				LpHash:     "0x03c6c469118985ee938d387e8d720239154eb87a",
+				Fee:        30,
+				InIndex:    1,
+				InToken:    "0xea76a1f367f907822425794f9b7af2babcdd5c2b",
+				InReserve:  B1,
+				OutIndex:   0,
+				OutToken:   "0xe446a35fd3d65bb8ee65cc3dd084b34b5ea80041",
+				OutReserve: S1,
+			},
+			{
+				LpHash:     "0x03c6c469118985ee938d387e8d720239154eb87a",
+				Fee:        15,
+				InIndex:    1,
+				InToken:    "0xe446a35fd3d65bb8ee65cc3dd084b34b5ea80041",
+				InReserve:  B2,
+				OutIndex:   0,
+				OutToken:   "0x0769298444cf2bd861df2ac9a61db971b77f8abb",
+				OutReserve: S2,
+			},
+		},
+	}
+
+	SimulationLevel3Path(&path3)
+
+	HistoryInfo(fmt.Sprintf("%+v", path3.Sim.ToJsonString()))
+}

+ 2 - 1
arbitrage/lp_utils.go

@@ -4,6 +4,7 @@ import (
 	"github.com/ethereum/go-ethereum/arbitrage/api"
 	"github.com/ethereum/go-ethereum/log"
 	"github.com/ethereum/go-ethereum/params"
+	"github.com/shopspring/decimal"
 	"math/big"
 )
 
@@ -29,7 +30,7 @@ type Path struct {
 	LoanIndex     int64
 	LoanTokenHash string
 	Level         int64
-	Profit        int64
+	Profit        decimal.Decimal
 	Sim           Simulation
 	FmList        []FundMovements
 }