one-pro.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. const OneTask = require('../libs/one-task')
  2. const OneInch = require('../libs/web3/1inch')
  3. const BinanceSpot = require('../libs/binance/binance-spot')
  4. const Config = require('../config/config')
  5. const NumKit = require('../kit/num-kit')
  6. const TimeKit = require('../kit/time-kit')
  7. const TableKit = require('../kit/table-kit')
  8. const orderHandler = function(context, task) {
  9. const fileLogger = task.fileLogger
  10. const tokenMap = context.tokenMap
  11. // 逐对处理交易信息
  12. Object.keys(tokenMap).forEach((tokenHash) => {
  13. const token = tokenMap[tokenHash]
  14. const pair = token.exchange.pair
  15. // 价格非法判定
  16. if (!token.BinancePrice || !token.OneInchPrice) return
  17. // 卖出逻辑判定
  18. if (token.orderPrice) {
  19. // TODO 对接卖出交易
  20. if (token.BinancePrice > token.orderPrice) {
  21. // 止盈逻辑
  22. const isStopWin = token.BinancePrice > (token.orderPrice * (100 + Config.stopWinPercentage) / 100)
  23. if (isStopWin) {
  24. fileLogger.info(`[止盈]${pair}, price: ${token.orderPrice}->${token.BinancePrice}, amount: ${token.orderAmount}.`)
  25. token.orderPrice = undefined
  26. token.prevHandleTime = new Date().getTime()
  27. }
  28. } else {
  29. // 止损逻辑
  30. const isStopLoss = token.BinancePrice < (token.orderPrice * (100 - Config.stopLossPercentage) / 100)
  31. if (isStopLoss) {
  32. fileLogger.info(`[止损]${pair}, price: ${token.orderPrice}->${token.BinancePrice}, amount: ${token.orderAmount}.`)
  33. token.orderPrice = undefined
  34. token.prevHandleTime = new Date().getTime()
  35. }
  36. }
  37. } else if (token.isLong) {
  38. // TODO 对接买入交易
  39. token.prevHandleTime = new Date().getTime()
  40. token.orderBaseAmount = Config.baseTokenAmount
  41. // 1. 获取base资产数量
  42. // 2. 下单获取成交数量以及平均价格
  43. token.orderPrice = token.BinancePrice
  44. token.orderAmount = NumKit.getSubFloat(Config.baseTokenAmount / token.orderPrice, token.exchange.priceTick)
  45. // 3. 下单成功后打印日志
  46. fileLogger.info(`[订单]${pair}, volume: ${Config.baseTokenAmount}, price: ${token.orderPrice}, amount: ${token.orderAmount}.`)
  47. }
  48. })
  49. }
  50. const table = new TableKit(['pair', 'binance', 'order price', 'profit', 'prev time'], 20)
  51. const showInfo = function(context, task) {
  52. const logger = task.logger
  53. const tokenMap = context.tokenMap
  54. table.printTitles()
  55. Object.keys(tokenMap).forEach((tokenHash) => {
  56. const token = tokenMap[tokenHash]
  57. const pair = token.exchange.pair
  58. const OneInchPrice = token.OneInchPrice ? token.OneInchPrice : NaN
  59. const BinancePrice = token.BinancePrice ? token.BinancePrice : NaN
  60. const DiffPrice = token.DiffPrice
  61. const percentage = NumKit.getSubFloat((DiffPrice / OneInchPrice) * 100, 2)
  62. const orderPrice = token.orderPrice ? token.orderPrice : NaN
  63. const orderPercentage = NumKit.getSubFloat(((BinancePrice - orderPrice) / orderPrice) * 100, 2)
  64. const prevTimeStr = token.prevHandleTime ? TimeKit.getTimeByMillisecond(token.prevHandleTime) : ''
  65. // 价格非法的就不处理了
  66. // if ((() => {
  67. //
  68. // })()) return
  69. const rows = [pair.toString(), BinancePrice.toString(), orderPrice.toString(), orderPercentage.toString().concat('%'), prevTimeStr]
  70. // 识别到在拉盘
  71. token.isLong = (() => {
  72. const percentageCondition = percentage > Config.percentageLimit
  73. const isNoPrevHandleTime = !token.prevHandleTime
  74. const isTimeCover = new Date().getTime() > token.prevHandleTime + Config.handleSpaceHours * (60 * 60 * 1000)
  75. const timeCondition = isNoPrevHandleTime || isTimeCover
  76. return percentageCondition && timeCondition
  77. })()
  78. // 打印表格
  79. table.showLine(rows, undefined)
  80. })
  81. table.printEndLine(logger)
  82. }
  83. const priceHandler = async function(context, task) {
  84. const tokenMap = context.tokenMap
  85. const tokenContractAddressList = Object.keys(tokenMap)
  86. for (const tokenHash of tokenContractAddressList) {
  87. const toToken = tokenMap[tokenHash]
  88. const priceTick = toToken.exchange.priceTick
  89. const fromIerc20Token = Config.baseIerc20Token
  90. const amount = Config.baseTokenAmount
  91. const OneInchPrice = NumKit.getSubFloat(await OneInch.price(fromIerc20Token.contract, tokenHash, amount), priceTick)
  92. const BinancePrice = NumKit.getSubFloat(await BinanceSpot.realPrice(toToken.exchange.pair), priceTick)
  93. toToken.OneInchPrice = OneInchPrice
  94. toToken.BinancePrice = BinancePrice
  95. toToken.DiffPrice = BinancePrice - OneInchPrice
  96. if ((() => {
  97. return Math.abs(toToken.DiffPrice) < Math.pow(10, -priceTick)
  98. })()) {
  99. toToken.DiffPrice = 0
  100. } {
  101. toToken.DiffPrice = NumKit.getSubFloat(toToken.DiffPrice, priceTick)
  102. }
  103. }
  104. }
  105. const onTickFun = async function() {
  106. const task = this
  107. const context = task.context
  108. // 搜集所有价格数据
  109. await priceHandler(context, task)
  110. // 展示关键信息
  111. showInfo(context, task)
  112. // 交易、订单处理
  113. orderHandler(context, task)
  114. }
  115. const onePro = new OneTask('OnePro', Config.delay, OneTask.baseInit, onTickFun)
  116. onePro.Start()