|
|
@@ -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 {
|