|
|
@@ -0,0 +1,64 @@
|
|
|
+package arbitrage
|
|
|
+
|
|
|
+import (
|
|
|
+ "fmt"
|
|
|
+ "github.com/shopspring/decimal"
|
|
|
+)
|
|
|
+
|
|
|
+func SimulationLevel2Path(path Path) {
|
|
|
+ if path.Level != 2 {
|
|
|
+ HistoryError(fmt.Sprintf("Level error. Need %v, but got %v.", 2, path.Level))
|
|
|
+
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ fm0 := path.FmList[0]
|
|
|
+ fm1 := path.FmList[1]
|
|
|
+
|
|
|
+ // fee0, fee1
|
|
|
+ fee0 := decimal.NewFromInt(fm0.Fee)
|
|
|
+ fee1 := decimal.NewFromInt(fm1.Fee)
|
|
|
+
|
|
|
+ decimalNumber1 := decimal.NewFromInt(1)
|
|
|
+ decimalNumber1e6 := decimal.NewFromInt(1).Pow(decimal.NewFromInt(6))
|
|
|
+
|
|
|
+ // F0 = 1 - fee0/1e6
|
|
|
+ F0 := decimalNumber1.Sub(fee0.Div(decimalNumber1e6))
|
|
|
+ // F1 = 1 - fee1/1e6
|
|
|
+ F1 := decimalNumber1.Sub(fee1.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())
|
|
|
+
|
|
|
+ // F0 * F1 * S0
|
|
|
+ part00 := F0.Mul(F1.Mul(S0))
|
|
|
+ // B1 * F0
|
|
|
+ part01 := B1.Mul(F0)
|
|
|
+ // F0 * F1 * S0 + B1 * F0
|
|
|
+ part0 := part00.Add(part01)
|
|
|
+
|
|
|
+ // if F0*F1*S0 + B1*F0 == 0
|
|
|
+ if part0.IntPart() == 0 {
|
|
|
+ HistoryError(fmt.Sprintf("Is error part0. F0=%v, F1=%v, S0=%v, B1=%v, F0=%v.", F0, F1, S0, B1, F0))
|
|
|
+
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // B0 * B1
|
|
|
+ part10 := B0.Mul(B1)
|
|
|
+ // F0 * F1
|
|
|
+ part11 := F0.Mul(F1)
|
|
|
+ // S0 * S1
|
|
|
+ part12 := S0.Mul(S1)
|
|
|
+ // B0 * B1 * F0 * F1 * S0 * S1 ** 0.5
|
|
|
+ part1 := part10.Mul(part11.Mul(part12)).Pow(decimal.NewFromFloat(0.5)).Sub(part10)
|
|
|
+
|
|
|
+ // best input number
|
|
|
+ I := part1.Div(part0)
|
|
|
+
|
|
|
+ HistoryInfo(fmt.Sprintf("part0=%v, part1=%v, I=%v.", part0, part1, I))
|
|
|
+}
|