|
@@ -1,225 +1,27 @@
|
|
|
-const OneInch = require('../1inch.js')
|
|
|
|
|
-const DoDo = require('../dodo.js')
|
|
|
|
|
|
|
+const OneInch = require('./libs/1inch.js')
|
|
|
|
|
+const DoDo = require('./libs/dodo.js')
|
|
|
|
|
+const EthService = require('./services/eth-service.js')
|
|
|
|
|
+const BaseTokenService = require('./services/base-token-service.js')
|
|
|
|
|
+
|
|
|
const BinanceSpot = require('./libs/binance-spot.js')
|
|
const BinanceSpot = require('./libs/binance-spot.js')
|
|
|
const Config = require('../config/Config.js')
|
|
const Config = require('../config/Config.js')
|
|
|
-const PrivateConfig = require('./PrivateConfig.js')
|
|
|
|
|
const MyKit = require('./kit/MyKit.js')
|
|
const MyKit = require('./kit/MyKit.js')
|
|
|
-const Wallet = require('../wallet.js')
|
|
|
|
|
-const wallet = new Wallet()
|
|
|
|
|
|
|
|
|
|
const bs = new BinanceSpot('-', '-')
|
|
const bs = new BinanceSpot('-', '-')
|
|
|
|
|
|
|
|
-async function onTickDoDo(toToken) {
|
|
|
|
|
- while (true) {
|
|
|
|
|
- // 如果BNB连续变化maxRefreshBNBTimes次,则1INCH或其他交易所可能已经出bug。
|
|
|
|
|
- if (Config.refreshBNBTimes >= Config.maxRefreshBNBTimes) {
|
|
|
|
|
- console.log(`机器人判定交易所可能出了bug,失败次数:${Config.refreshBNBTimes},为保护BNB,已停止交易。`)
|
|
|
|
|
- break
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- try {
|
|
|
|
|
- const tokenSymbol = toToken.symbol
|
|
|
|
|
- const baseToken = Config.baseToken
|
|
|
|
|
- if (!baseToken.balance) {
|
|
|
|
|
- await MyKit.sleep(1000)
|
|
|
|
|
-
|
|
|
|
|
- continue
|
|
|
|
|
- }
|
|
|
|
|
- const binancePairSymbol = tokenSymbol + baseToken.symbol
|
|
|
|
|
- const amount = Config.baseTokenAmount < baseToken.balance ? Config.baseTokenAmount : baseToken.balance
|
|
|
|
|
- const profitLimit = toToken.profitLimit ? toToken.profitLimit : Config.profitLimit
|
|
|
|
|
- const binancePrice = await bs.price(binancePairSymbol)
|
|
|
|
|
-
|
|
|
|
|
- // 一次判断
|
|
|
|
|
- let time = MyKit.getTimeByMillisecond(new Date().getTime())
|
|
|
|
|
-
|
|
|
|
|
- // 直接判断并抢单
|
|
|
|
|
- const DoDoSwapRst = await DoDo.swap(baseToken.contract, baseToken.decimals, toToken.contract, toToken.decimals, amount)
|
|
|
|
|
- // 对询价结果容错
|
|
|
|
|
- if (!DoDoSwapRst || !DoDoSwapRst.data) {
|
|
|
|
|
- continue
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 构建交易包
|
|
|
|
|
- const swapRST = DoDoSwapRst.data
|
|
|
|
|
- swapRST.price = MyKit._N(swapRST.resPricePerToToken, 6)
|
|
|
|
|
- swapRST.tx = {
|
|
|
|
|
- gasPrice: 7 * (10 ** 9),
|
|
|
|
|
- gas: '500000',
|
|
|
|
|
- from: PrivateConfig.address,
|
|
|
|
|
- to: swapRST.to,
|
|
|
|
|
- data: swapRST.data
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 间距百分比与预估利润
|
|
|
|
|
- distance = MyKit._N(100 * ((binancePrice / swapRST.price - 1.001)), 4)
|
|
|
|
|
- profit = MyKit._N(amount * distance / 100 - Config.charge, 4)
|
|
|
|
|
-
|
|
|
|
|
- // debug
|
|
|
|
|
- if (Config.debug) {
|
|
|
|
|
- console.log(`[${time}, ${binancePairSymbol}] D价格: ${swapRST.price},C价格: ${binancePrice},利润:${profit},源:${swapRST.useSource}。`)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 屏蔽询价源
|
|
|
|
|
- if (Config.limitSources.indexOf(swapRST.useSource) !== -1 || !swapRST.useSource) {
|
|
|
|
|
- continue
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (swapRST.price && !baseToken.isSwap && profit > Config.profitLimit) {
|
|
|
|
|
- if (distance > 20) {
|
|
|
|
|
- console.log('[利润大于20%]手续费*1.5执行抢单逻辑.')
|
|
|
|
|
- swapRST.tx.gasPrice = parseInt((parseInt(swapRST.tx.gasPrice) * 1.5)) + ''
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- console.log(`[${time}, ${tokenSymbol}]判定通过, 利润率:${distance}%, 预估利润:${profit}${baseToken.symbol}, 目标利润:${Config.profitLimit}${baseToken.symbol}.\n`)
|
|
|
|
|
- console.log(`DEFI价格: ${swapRST.price}, CEFI价格: ${binancePrice}, 报价源: ${swapRST.useSource}\n\n`)
|
|
|
|
|
- await wallet.transferByTXDoDo(swapRST.tx)
|
|
|
|
|
- }
|
|
|
|
|
- // else if (profit > 0) {
|
|
|
|
|
- // console.log(`[${time}, ${tokenSymbol}]二次判定不通过, 利润率:${distance}%, 预估利润:${profit}${baseToken.symbol}, 目标利润:${profitLimit}${baseToken.symbol}.\n`)
|
|
|
|
|
- // console.log(`DEFI价格: ${swapRST.price}, CEFI价格: ${binancePrice}, 报价源: ${swapRST.useSource}\n\n`)
|
|
|
|
|
- // }
|
|
|
|
|
- } catch (e) {
|
|
|
|
|
- console.log(e)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- await MyKit.sleep(Config.delay)
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-async function onTick1Inch(toToken) {
|
|
|
|
|
- while (true) {
|
|
|
|
|
- toToken.alive = true
|
|
|
|
|
-
|
|
|
|
|
- // 如果BNB连续变化maxRefreshBNBTimes次,则1INCH或其他交易所可能已经出bug。
|
|
|
|
|
- if (Config.refreshBNBTimes >= Config.maxRefreshBNBTimes) {
|
|
|
|
|
- console.log(`机器人判定交易所可能出了bug,失败次数:${Config.refreshBNBTimes},为保护BNB,已停止交易。`)
|
|
|
|
|
- break
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- try {
|
|
|
|
|
- const tokenSymbol = toToken.symbol
|
|
|
|
|
- const baseToken = Config.baseToken
|
|
|
|
|
- if (!baseToken.balance) {
|
|
|
|
|
- await MyKit.sleep(1000)
|
|
|
|
|
-
|
|
|
|
|
- continue
|
|
|
|
|
- }
|
|
|
|
|
- const binancePairSymbol = tokenSymbol + baseToken.symbol
|
|
|
|
|
- const amount = Config.baseTokenAmount < baseToken.balance ? Config.baseTokenAmount : baseToken.balance
|
|
|
|
|
- const OneInchPrice = await OneInch.price(baseToken.contract, baseToken.decimals, amount, toToken.contract)
|
|
|
|
|
- const binancePrice = await bs.price(binancePairSymbol)
|
|
|
|
|
- let distance = MyKit._N(100 * ((binancePrice / OneInchPrice) - 1.001), 4)
|
|
|
|
|
- let profit = MyKit._N(amount * distance / 100 - Config.charge, 4)
|
|
|
|
|
- let time = MyKit.getTimeByMillisecond(new Date().getTime())
|
|
|
|
|
-
|
|
|
|
|
- // debug
|
|
|
|
|
- if (Config.debug && profit > 0) {
|
|
|
|
|
- console.log(`[${time}, ${binancePairSymbol}] D价格: ${OneInchPrice},C价格: ${binancePrice},利润:${profit}。`)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 一次判断
|
|
|
|
|
- if (profit > Config.profitLimit) {
|
|
|
|
|
- // 二次判断,并获取交易tx
|
|
|
|
|
- const swapRST = await OneInch.swap(baseToken.contract, toToken.contract, baseToken.decimals, amount)
|
|
|
|
|
- if (!swapRST) {
|
|
|
|
|
- continue
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- distance = MyKit._N(100 * ((binancePrice / swapRST.price) - 1.001), 4)
|
|
|
|
|
- profit = MyKit._N(amount * distance / 100 - Config.charge, 4)
|
|
|
|
|
- if (!baseToken.isSwap && profit > Config.profitLimit) {
|
|
|
|
|
- time = MyKit.getTimeByMillisecond(new Date().getTime())
|
|
|
|
|
-
|
|
|
|
|
- // gas容错
|
|
|
|
|
- swapRST.tx.gas = parseInt((parseInt(swapRST.tx.gas) * 1.5)) + ''
|
|
|
|
|
-
|
|
|
|
|
- // 如果利润大于5%,手续费*2抢单
|
|
|
|
|
- if (distance > 20) {
|
|
|
|
|
- console.log('[利润大于20%]手续费*1.5执行抢单逻辑.')
|
|
|
|
|
- swapRST.tx.gasPrice = parseInt((parseInt(swapRST.tx.gasPrice) * 1.5)) + ''
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- console.log(`[${time}, ${tokenSymbol}]判定通过, 利润率:${distance}%, 预估利润:${profit}${baseToken.symbol}, 目标利润:${Config.profitLimit}${baseToken.symbol}.\n`)
|
|
|
|
|
- console.log(`DEFI价格: ${swapRST.price}, CEFI价格: ${binancePrice}\n\n`)
|
|
|
|
|
- await wallet.transferByTX1Inch(swapRST.tx)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- await MyKit.sleep(5000)
|
|
|
|
|
- } catch (e) {
|
|
|
|
|
- console.log(e)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-async function flushBalance () {
|
|
|
|
|
- while (true) {
|
|
|
|
|
- try {
|
|
|
|
|
- Config.baseToken.contractModel.methods.balanceOf(PrivateConfig.address).call((err, result) => {
|
|
|
|
|
- if (result) {
|
|
|
|
|
- let balance = MyKit._N(parseFloat(result) / (10 ** Config.baseToken.decimals), 4)
|
|
|
|
|
- const prevBalance = Config.baseToken.balance
|
|
|
|
|
- Config.baseToken.balance = balance
|
|
|
|
|
-
|
|
|
|
|
- if ((prevBalance || prevBalance === 0) && balance !== prevBalance) {
|
|
|
|
|
- console.log(`[${Config.baseToken.symbol}余额变更]${prevBalance}->${balance}, 交易失败(BNB连续减少但BUSD不变化)次数: 0.\n`)
|
|
|
|
|
- Config.refreshBNBTimes = 0
|
|
|
|
|
- } else if (!prevBalance && prevBalance !== 0) {
|
|
|
|
|
- console.log(`[${Config.baseToken.symbol}余额初始化]${balance}.`)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- } catch (e) {
|
|
|
|
|
- console.log(e)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- await MyKit.sleep(1000)
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-async function flushBNB() {
|
|
|
|
|
- while (true) {
|
|
|
|
|
- try {
|
|
|
|
|
- let balance = await wallet.getBalance()
|
|
|
|
|
-
|
|
|
|
|
- if (balance) {
|
|
|
|
|
- balance = MyKit._N(parseFloat(balance), 4)
|
|
|
|
|
- const prevBalance = Config.bnbBalance
|
|
|
|
|
-
|
|
|
|
|
- if ((prevBalance || prevBalance === 0) && balance !== prevBalance) {
|
|
|
|
|
- console.log(`[BNB余额变更]${prevBalance}->${balance}.`)
|
|
|
|
|
- // 发送过交易的情况下才判定为因交易减少BNB
|
|
|
|
|
- if (balance < prevBalance) {
|
|
|
|
|
- console.log(`\t当前交易失败(BNB连续减少但BUSD不变化)次数:${++Config.refreshBNBTimes}.`)
|
|
|
|
|
- }
|
|
|
|
|
- } else if (!prevBalance && prevBalance !== 0) {
|
|
|
|
|
- console.log(`[BNB余额初始化]${balance}.`)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- Config.bnbBalance = balance
|
|
|
|
|
- }
|
|
|
|
|
- } catch (e) {
|
|
|
|
|
- console.log(e)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- await MyKit.sleep(1000)
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
async function main () {
|
|
async function main () {
|
|
|
console.log('初始化中...')
|
|
console.log('初始化中...')
|
|
|
console.log(`交易所:${Config.exchange}。`)
|
|
console.log(`交易所:${Config.exchange}。`)
|
|
|
await MyKit.sleep(1000)
|
|
await MyKit.sleep(1000)
|
|
|
|
|
|
|
|
- flushBalance()
|
|
|
|
|
- flushBNB()
|
|
|
|
|
|
|
+ EthService.Start()
|
|
|
|
|
+ BaseTokenService.Start()
|
|
|
|
|
|
|
|
for (const token of Config.tokenList) {
|
|
for (const token of Config.tokenList) {
|
|
|
if (Config.exchange === '1inch') {
|
|
if (Config.exchange === '1inch') {
|
|
|
- onTick1Inch(token)
|
|
|
|
|
|
|
+ OneInch.Start(token)
|
|
|
} else if (Config.exchange === 'dodo') {
|
|
} else if (Config.exchange === 'dodo') {
|
|
|
- onTickDoDo(token)
|
|
|
|
|
|
|
+ DoDo.Start(token)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|