| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- package arbitrage
- import (
- "context"
- "fmt"
- "github.com/ethereum/go-ethereum/arbitrage/api"
- "github.com/ethereum/go-ethereum/internal/ethapi"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/node"
- "github.com/shopspring/decimal"
- "gopkg.in/urfave/cli.v1"
- "os"
- "time"
- )
- type HistoryArbitrage struct {
- // 核心变量
- stack *node.Node
- ctx *cli.Context
- wallets []*EasyWallet
- // 生命周期控制
- quit chan struct{}
- running bool
- // api
- apiBackend ethapi.Backend
- blockChainApi *ethapi.PublicBlockChainAPI
- ethereumApi *ethapi.PublicEthereumAPI
- accountApi *ethapi.PrivateAccountAPI
- txApi *ethapi.PublicTransactionPoolAPI
- javaApi *api.JavaApi
- // 程序逻辑
- lpList []api.V2Lp
- finalLpList []api.V2Lp
- finalLpHashList []string
- finalLpBalanceMapping map[string][2]decimal.Decimal
- pathList []Path
- // 日志体系
- logFile *os.File
- }
- func RegisterHistoryArbitrage(stack *node.Node, ctx *cli.Context, apiBackend ethapi.Backend) {
- addrLock := new(ethapi.AddrLocker)
- var LogFile, err = os.OpenFile(LogPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
- if err != nil {
- log.Error(err.Error())
- }
- h := &HistoryArbitrage{
- stack: stack,
- ctx: ctx,
- wallets: []*EasyWallet{},
- running: false,
- quit: make(chan struct{}),
- apiBackend: apiBackend,
- blockChainApi: ethapi.NewPublicBlockChainAPI(apiBackend),
- ethereumApi: ethapi.NewPublicEthereumAPI(apiBackend),
- accountApi: ethapi.NewPrivateAccountAPI(apiBackend, addrLock),
- txApi: ethapi.NewPublicTransactionPoolAPI(apiBackend, addrLock),
- javaApi: api.NewJavaApi(),
- logFile: LogFile,
- }
- // 设置日志输出目录
- //SetLogFile(LogFile)
- SetLogFile(os.Stdout)
- h.Register()
- }
- func (h *HistoryArbitrage) Register() {
- // 注册成节点生命周期
- h.stack.RegisterLifecycle(h)
- }
- func (h *HistoryArbitrage) Start() error {
- HistoryInfo("Hi, I am history arbitrage bot.")
- h.running = true
- go h.run()
- //addr, err := h.newAccount()
- //if err == nil {
- // HistoryInfo("Hi, this is new account", "account", addr.String())
- //} else {
- // HistoryError("New account error", "err", err)
- //}
- return nil
- }
- func (h *HistoryArbitrage) setupWallets() {
- wallets := h.stack.AccountManager().Wallets()
- HistoryInfo("Setup wallets")
- for index, wallet := range wallets {
- account := wallet.Accounts()[0]
- _, err := h.accountApi.UnlockAccount(context.Background(), account.Address, "", nil)
- if err != nil {
- HistoryError(fmt.Sprintf("Wallet[%02d]", index), "error", err)
- continue
- }
- HistoryInfo(fmt.Sprintf("Wallet[%02d]", index), "addr", account.Address)
- h.wallets = append(h.wallets, NewEasyWallet(&wallet, &account))
- }
- HistoryInfo("Wallets setup done.", "wallet count", len(h.wallets))
- }
- func (h *HistoryArbitrage) run() {
- // 配置钱包
- h.setupWallets()
- // 初次获取lp
- h.lpList = h.GetLpList()
- for index, _ := range h.lpList {
- h.lpList[index].Fee = 3000
- }
- HistoryInfo("lp list updated.", "length", len(h.lpList))
- // 交易发送测试
- //h.sendTransaction(&ArbTx{
- // From: h.wallets[0].account.Address,
- // To: h.wallets[0].account.Address,
- //})
- //tempLpList := []string{
- // "0x1652db7faeab767a20950b894e72efb9d2438a41",
- //}
- //
- //HistoryInfo(fmt.Sprintf("%+v", h.getPairSBalance(tempLpList)))
- running:
- for {
- select {
- case <-h.quit:
- HistoryInfo("Bye, see you next.")
- break running
- default:
- h.OnTick()
- }
- }
- }
- func (h *HistoryArbitrage) OnTick() {
- // 生成临时lp
- tempLpList := ParseLpToFinalLp(h.lpList)
- // 获取纯hash list
- h.finalLpHashList = ParseLpListToLpHashList(tempLpList)
- // 获取余额
- h.finalLpBalanceMapping = h.getPairSBalance(h.finalLpHashList)
- // 将获取到的余额映射到LP里面
- PutR0R1ToLpList(tempLpList, h.finalLpBalanceMapping)
- // 0值lp过滤
- h.finalLpList = FilterLpList(tempLpList)
- // 生成最终交易路由
- h.pathList = ParseLpListToPathList(h.finalLpList, MaxLevel)
- // 计算利润
- PutSimulationToPathList(h.pathList)
- // 排除交易中profit不满足的path
- h.pathList = GetFinalPathList(h.pathList)
- // 根据利润排序
- InsertionSort(h.pathList)
- //HistoryInfo(fmt.Sprintf("len=%v", len(h.pathList)))
- path := h.pathList[0]
- if path.FeeTokenProfit.GreaterThan(MinProfit) {
- HistoryInfo(fmt.Sprintf("level=%+v, Sim=%+v, lpList=%+v", path.Level, path.Sim.ToJsonString(), path.LpHashList))
- for fmIndex, fm := range path.FmList {
- HistoryInfo(fmt.Sprintf("fm%v=%+v", fmIndex, fm))
- }
- HistoryInfo("")
- }
- //for _, path := range h.pathList {
- // if path.FeeTokenProfit.GreaterThan(MinProfit) {
- // //HistoryInfo(fmt.Sprintf("level=%+v, Sim=%+v, lpList=%+v", path.Level, path.Sim.ToJsonString(), path.LpHashList))
- // //for fmIndex, fm := range path.FmList {
- // // HistoryInfo(fmt.Sprintf("fm%v=%+v", fmIndex, fm))
- // //}
- // //HistoryInfo("")
- // }
- //}
- // 发交易
- // Gas War
- // TODO 获取fee
- time.Sleep(60 * time.Second)
- }
- func (h *HistoryArbitrage) Stop() error {
- h.logFile.Close()
- close(h.quit)
- return nil
- }
|