龚成明 před 2 roky
rodič
revize
3dc3ff3435
4 změnil soubory, kde provedl 27 přidání a 9 odebrání
  1. 4 2
      PrivateConfig.js.sample
  2. 2 0
      kit/time-kit.js
  3. 2 0
      libs/token.js
  4. 19 7
      scripts/one-pro.js

+ 4 - 2
PrivateConfig.js.sample

@@ -7,8 +7,10 @@ PrivateConfig.binanceSecretKey = ''
 PrivateConfig.percentageLimit = 0.37           // 两交易所的差价百分比
 PrivateConfig.stopWinHandleSpaceHours = 1      // 止盈后几个小时才能交易
 PrivateConfig.stopLossHandleSpaceHours = 4     // 止损后几个小时才能交易
-PrivateConfig.stopWinPercentage = 2            // 止盈百分比
-PrivateConfig.stopLossPercentage = 2           // 止损百分比
+PrivateConfig.stopWinTimeOverHours = 12        // 盈利时持仓时间
+PrivateConfig.stopLossTimeOverHours = 2        // 亏损时持仓时间
+PrivateConfig.hardStopWinPercentage = 100      // 强制止盈百分比
+PrivateConfig.hardStopLossPercentage = 10      // 强制止损百分比
 PrivateConfig.baseTokenAmount = 68             // 交易额
 PrivateConfig.delay = 5000                     // 轮询时间
 

+ 2 - 0
kit/time-kit.js

@@ -1,4 +1,6 @@
 module.exports = class TimeKit {
+  static ONE_HOUR = (60 * 60 * 1000)
+
   static dateToTimestamp (str) {
     let [a, b] = str.split(' ')
     let [year, month, day] = a.split('/')

+ 2 - 0
libs/token.js

@@ -23,6 +23,7 @@ module.exports = class Token {
     const localData = {
       orderPrice: this.orderPrice,
       orderAmount: this.orderAmount,
+      orderTime: this.orderTime,
       nextHandleTime: this.nextHandleTime
     }
 
@@ -36,6 +37,7 @@ module.exports = class Token {
 
       this.orderAmount = localData.orderAmount
       this.orderPrice = localData.orderPrice
+      this.orderTime = localData.orderTime
       this.nextHandleTime = localData.nextHandleTime
     } catch (e) {}
   }

+ 19 - 7
scripts/one-pro.js

@@ -14,9 +14,18 @@ const holdingHandler = async function(context, task, token, pair) {
   const binanceSpot = context.binanceSpot
   const accountAssetMap = context.accountAssetMap
 
+  const nowTimestamp = new Date().getTime()
   // 这两个逻辑只有可能满足一个
-  let isStopWin = token.BinancePrice > (token.orderPrice * (100 + config.stopWinPercentage) / 100)
-  let isStopLoss = token.BinancePrice < (token.orderPrice * (100 - config.stopLossPercentage) / 100)
+  const isHardStopWin = token.BinancePrice > (token.orderPrice * (100 + config.hardStopWinPercentage) / 100)
+  const isTimeOverStopWin = token.BinancePrice > token.orderPrice && nowTimestamp > token.orderTime + config.stopWinTimeOverHours * TimeKit.ONE_HOUR
+
+  const isHardStopLoss = token.BinancePrice < (token.orderPrice * (100 - config.hardStopLossPercentage) / 100)
+  const isTimeOverStopLoss = token.BinancePrice < token.orderPrice && nowTimestamp < token.orderTime + config.stopLossTimeOverHours * TimeKit.ONE_HOUR
+
+  const isStopWin = isHardStopWin || isTimeOverStopWin
+  const isStopLoss = isHardStopLoss || isTimeOverStopLoss
+
+  const isTimeOverStop = isTimeOverStopWin || isTimeOverStopLoss
 
   assert.notEqual(isStopWin && isStopLoss, true, '止盈止损逻辑错误,请认真检查。')
 
@@ -26,7 +35,7 @@ const holdingHandler = async function(context, task, token, pair) {
 
     token.orderPrice = undefined
     token.orderAmount = undefined
-    token.nextHandleTime = new Date().getTime() + config.stopLossHandleSpaceHours * (60 * 60 * 1000)
+    token.nextHandleTime = nowTimestamp + config.stopLossHandleSpaceHours * TimeKit.ONE_HOUR
 
     try {
       const sellMarketRst = await binanceSpot.sellMarket(pair, orderAmount)
@@ -37,11 +46,11 @@ const holdingHandler = async function(context, task, token, pair) {
       // 交易数据持久化
       await token.save()
 
-      fileLogger.info(`[${isStopWin ? '盈+' : '损-'}]${pair}, `
+      fileLogger.info(`[${isTimeOverStop ? '时' : '强'}${isStopWin ? '盈+' : '损-'}]${pair}, `
         .concat(`成交额${cummulativeQuoteQty}, 均价${orderPrice}->${price}, 卖出${orderAmount}个.`)
       )
     } catch (e) {
-      fileLogger.error(`[止${isStopWin ? '盈' : '损'}失败]${pair}, ${e}`)
+      fileLogger.error(`[${isTimeOverStop ? '时' : '强'}止${isStopWin ? '盈' : '损'}失败]${pair}, ${e}`)
     }
   }
 }
@@ -52,13 +61,15 @@ const noHoldingHandler = async function(context, task, token, pair) {
   const binanceSpot = context.binanceSpot
   const accountAssetMap = context.accountAssetMap
 
+  const nowTimestamp = new Date().getTime()
+
   // 1. 获取base资产数量
   const baseAssetAmount = accountAssetMap[config.baseIerc20Token.symbol]
 
   // 2. 判断余额是否够下单
   if (config.baseTokenAmount > baseAssetAmount) {
     fileLogger.info(`[余额不足]${pair}, 需要: ${config.baseTokenAmount}, 剩余: ${baseAssetAmount}.`)
-    token.nextHandleTime = new Date().getTime() + config.stopLossHandleSpaceHours * (60 * 60 * 1000)
+    token.nextHandleTime = nowTimestamp + config.stopLossHandleSpaceHours * TimeKit.ONE_HOUR
 
     return
   }
@@ -70,6 +81,7 @@ const noHoldingHandler = async function(context, task, token, pair) {
     token.cummulativeQuoteQty = NumKit.getSubFloat(buyMarketRst.cummulativeQuoteQty, 6)
     token.orderAmount = NumKit.getSubFloat(buyMarketRst.executedQty, token.exchange.lotSize)
     token.orderPrice = NumKit.getSubFloat(buyMarketRst.avgPrice, token.exchange.priceTick)
+    token.orderTime = nowTimestamp
 
     // 关键数据持久化
     await token.save()
@@ -133,7 +145,7 @@ const showInfo = function(context, task) {
     const rows = [pair.toString(), OneInchPrice.toString(), BinancePrice.toString(),
       orderPrice.toString(), orderPercentage.toString(), nextTimeStr]
 
-    // 识别到在拉盘
+    // 入场信号
     token.isLong = (() => {
       const percentageCondition = percentage > config.percentageLimit