one-pro.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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.nextHandleTime = new Date().getTime() + Config.stopWinHandleSpaceHours * (60 * 60 * 1000)
  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.nextHandleTime = new Date().getTime() + Config.stopLossHandleSpaceHours * (60 * 60 * 1000)
  35. }
  36. }
  37. } else if (token.isLong) {
  38. // TODO 对接买入交易
  39. token.orderBaseAmount = Config.baseTokenAmount
  40. // 1. 获取base资产数量
  41. // 2. 下单获取成交数量以及平均价格
  42. token.orderPrice = token.BinancePrice
  43. token.orderAmount = NumKit.getSubFloat(Config.baseTokenAmount / token.orderPrice, token.exchange.lotSize)
  44. // 3. 下单成功后打印日志
  45. fileLogger.info(`[订单]${pair}, volume: ${Config.baseTokenAmount}, price: ${token.orderPrice}, amount: ${token.orderAmount}.`)
  46. }
  47. })
  48. }
  49. const table = new TableKit(['pair', 'binance', 'order price', 'profit', 'next time'], 20)
  50. const showInfo = function(context, task) {
  51. const logger = task.logger
  52. const tokenMap = context.tokenMap
  53. table.printTitles()
  54. Object.keys(tokenMap).forEach((tokenHash) => {
  55. const token = tokenMap[tokenHash]
  56. const pair = token.exchange.pair
  57. const OneInchPrice = token.OneInchPrice ? token.OneInchPrice : NaN
  58. const BinancePrice = token.BinancePrice ? token.BinancePrice : NaN
  59. const DiffPrice = token.DiffPrice
  60. const percentage = NumKit.getSubFloat((DiffPrice / OneInchPrice) * 100, 2)
  61. const orderPrice = token.orderPrice ? token.orderPrice : NaN
  62. const orderPercentage = NumKit.getSubFloat(((BinancePrice - orderPrice) / orderPrice) * 100, 2)
  63. const nextTimeStr = token.nextHandleTime ? TimeKit.getTimeByMillisecond(token.nextHandleTime) : ''
  64. // 价格非法的就不处理了
  65. // if ((() => {
  66. //
  67. // })()) return
  68. const rows = [pair.toString(), BinancePrice.toString(), orderPrice.toString(), orderPercentage.toString().concat('%'), nextTimeStr]
  69. // 识别到在拉盘
  70. token.isLong = (() => {
  71. const percentageCondition = percentage > Config.percentageLimit
  72. const isNoPrevHandleTime = !token.nextHandleTime
  73. const isTimeCover = new Date().getTime() > token.nextHandleTime
  74. const timeCondition = isNoPrevHandleTime || isTimeCover
  75. return percentageCondition && timeCondition
  76. })()
  77. // 打印表格
  78. table.showLine(rows, undefined)
  79. })
  80. table.printEndLine(logger)
  81. }
  82. const priceHandler = async function(context, task) {
  83. const tokenMap = context.tokenMap
  84. const tokenContractAddressList = Object.keys(tokenMap)
  85. for (const tokenHash of tokenContractAddressList) {
  86. const toToken = tokenMap[tokenHash]
  87. const priceTick = toToken.exchange.priceTick
  88. const fromIerc20Token = Config.baseIerc20Token
  89. const amount = Config.baseTokenAmount
  90. const OneInchPrice = NumKit.getSubFloat(await OneInch.price(fromIerc20Token.contract, tokenHash, amount), priceTick)
  91. const BinancePrice = NumKit.getSubFloat(await BinanceSpot.realPrice(toToken.exchange.pair), priceTick)
  92. toToken.OneInchPrice = OneInchPrice
  93. toToken.BinancePrice = BinancePrice
  94. toToken.DiffPrice = BinancePrice - OneInchPrice
  95. if ((() => {
  96. return Math.abs(toToken.DiffPrice) < Math.pow(10, -priceTick)
  97. })()) {
  98. toToken.DiffPrice = 0
  99. } {
  100. toToken.DiffPrice = NumKit.getSubFloat(toToken.DiffPrice, priceTick)
  101. }
  102. }
  103. }
  104. const onTickFun = async function() {
  105. const task = this
  106. const context = task.context
  107. // 搜集所有价格数据
  108. await priceHandler(context, task)
  109. // 展示关键信息
  110. showInfo(context, task)
  111. // 交易、订单处理
  112. orderHandler(context, task)
  113. }
  114. const onePro = new OneTask('OnePro', Config.delay, OneTask.baseInit, onTickFun)
  115. onePro.Start()