history.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. package arbitrage
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/ethereum/go-ethereum/arbitrage/api"
  6. "github.com/ethereum/go-ethereum/internal/ethapi"
  7. "github.com/ethereum/go-ethereum/log"
  8. "github.com/ethereum/go-ethereum/node"
  9. "github.com/shopspring/decimal"
  10. "gopkg.in/urfave/cli.v1"
  11. "os"
  12. "time"
  13. )
  14. type HistoryArbitrage struct {
  15. // 核心变量
  16. stack *node.Node
  17. ctx *cli.Context
  18. wallets []*EasyWallet
  19. // 生命周期控制
  20. quit chan struct{}
  21. running bool
  22. // api
  23. apiBackend ethapi.Backend
  24. blockChainApi *ethapi.PublicBlockChainAPI
  25. ethereumApi *ethapi.PublicEthereumAPI
  26. accountApi *ethapi.PrivateAccountAPI
  27. txApi *ethapi.PublicTransactionPoolAPI
  28. javaApi *api.JavaApi
  29. // 程序逻辑
  30. lpList []api.V2Lp
  31. finalLpList []api.V2Lp
  32. finalLpHashList []string
  33. finalLpBalanceMapping map[string][2]decimal.Decimal
  34. pathList []Path
  35. // 日志体系
  36. logFile *os.File
  37. }
  38. func RegisterHistoryArbitrage(stack *node.Node, ctx *cli.Context, apiBackend ethapi.Backend) {
  39. addrLock := new(ethapi.AddrLocker)
  40. var LogFile, err = os.OpenFile(LogPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
  41. if err != nil {
  42. log.Error(err.Error())
  43. }
  44. h := &HistoryArbitrage{
  45. stack: stack,
  46. ctx: ctx,
  47. wallets: []*EasyWallet{},
  48. running: false,
  49. quit: make(chan struct{}),
  50. apiBackend: apiBackend,
  51. blockChainApi: ethapi.NewPublicBlockChainAPI(apiBackend),
  52. ethereumApi: ethapi.NewPublicEthereumAPI(apiBackend),
  53. accountApi: ethapi.NewPrivateAccountAPI(apiBackend, addrLock),
  54. txApi: ethapi.NewPublicTransactionPoolAPI(apiBackend, addrLock),
  55. javaApi: api.NewJavaApi(),
  56. logFile: LogFile,
  57. }
  58. // 设置日志输出目录
  59. //SetLogFile(LogFile)
  60. SetLogFile(os.Stdout)
  61. h.Register()
  62. }
  63. func (h *HistoryArbitrage) Register() {
  64. // 注册成节点生命周期
  65. h.stack.RegisterLifecycle(h)
  66. }
  67. func (h *HistoryArbitrage) Start() error {
  68. HistoryInfo("Hi, I am history arbitrage bot.")
  69. h.running = true
  70. go h.run()
  71. //addr, err := h.newAccount()
  72. //if err == nil {
  73. // HistoryInfo("Hi, this is new account", "account", addr.String())
  74. //} else {
  75. // HistoryError("New account error", "err", err)
  76. //}
  77. return nil
  78. }
  79. func (h *HistoryArbitrage) setupWallets() {
  80. wallets := h.stack.AccountManager().Wallets()
  81. HistoryInfo("Setup wallets")
  82. for index, wallet := range wallets {
  83. account := wallet.Accounts()[0]
  84. _, err := h.accountApi.UnlockAccount(context.Background(), account.Address, "", nil)
  85. if err != nil {
  86. HistoryError(fmt.Sprintf("Wallet[%02d]", index), "error", err)
  87. continue
  88. }
  89. HistoryInfo(fmt.Sprintf("Wallet[%02d]", index), "addr", account.Address)
  90. h.wallets = append(h.wallets, NewEasyWallet(&wallet, &account))
  91. }
  92. HistoryInfo("Wallets setup done.", "wallet count", len(h.wallets))
  93. }
  94. func (h *HistoryArbitrage) run() {
  95. // 配置钱包
  96. h.setupWallets()
  97. // 初次获取lp
  98. h.lpList = h.GetLpList()
  99. for index, _ := range h.lpList {
  100. h.lpList[index].Fee = 3000
  101. }
  102. HistoryInfo("lp list updated.", "length", len(h.lpList))
  103. // 交易发送测试
  104. //h.sendTransaction(&ArbTx{
  105. // From: h.wallets[0].account.Address,
  106. // To: h.wallets[0].account.Address,
  107. //})
  108. //tempLpList := []string{
  109. // "0x1652db7faeab767a20950b894e72efb9d2438a41",
  110. //}
  111. //
  112. //HistoryInfo(fmt.Sprintf("%+v", h.getPairSBalance(tempLpList)))
  113. running:
  114. for {
  115. select {
  116. case <-h.quit:
  117. HistoryInfo("Bye, see you next.")
  118. break running
  119. default:
  120. h.OnTick()
  121. }
  122. }
  123. }
  124. func (h *HistoryArbitrage) OnTick() {
  125. // 生成临时lp
  126. h.finalLpList = ParseLpToFinalLp(h.lpList)
  127. // 获取纯hash list
  128. h.finalLpHashList = ParseLpListToLpHashList(h.finalLpList)
  129. // 获取余额
  130. h.finalLpBalanceMapping = h.getPairSBalance(h.finalLpHashList)
  131. // 将获取到的余额映射到LP里面
  132. PutR0R1ToLpList(h.finalLpList, h.finalLpBalanceMapping)
  133. // 0值lp过滤
  134. h.finalLpList = FilterLpList(h.finalLpList)
  135. // 生成最终交易路由
  136. h.pathList = ParseLpListToPathList(h.finalLpList, MaxLevel)
  137. // 计算利润
  138. PutSimulationToPathList(h.pathList)
  139. // 排除交易中profit不满足的path
  140. h.pathList = GetFinalPathList(h.pathList)
  141. // 根据利润排序
  142. InsertionSort(h.pathList)
  143. //HistoryInfo(fmt.Sprintf("len=%v", len(h.pathList)))
  144. path := h.pathList[0]
  145. if path.FeeTokenProfit.GreaterThan(MinProfit) {
  146. HistoryInfo(fmt.Sprintf("level=%+v, Sim=%+v, lpList=%+v", path.Level, path.Sim.ToJsonString(), path.LpHashList))
  147. for fmIndex, fm := range path.FmList {
  148. HistoryInfo(fmt.Sprintf("fm%v=%+v", fmIndex, fm))
  149. }
  150. HistoryInfo("")
  151. }
  152. //for _, path := range h.pathList {
  153. // if path.FeeTokenProfit.GreaterThan(MinProfit) {
  154. // //HistoryInfo(fmt.Sprintf("level=%+v, Sim=%+v, lpList=%+v", path.Level, path.Sim.ToJsonString(), path.LpHashList))
  155. // //for fmIndex, fm := range path.FmList {
  156. // // HistoryInfo(fmt.Sprintf("fm%v=%+v", fmIndex, fm))
  157. // //}
  158. // //HistoryInfo("")
  159. // }
  160. //}
  161. // TODO 生成fee
  162. // 智能合约calProfit
  163. // 发交易
  164. // Gas War
  165. time.Sleep(60 * time.Second)
  166. }
  167. func (h *HistoryArbitrage) Stop() error {
  168. h.logFile.Close()
  169. close(h.quit)
  170. return nil
  171. }