Jelajahi Sumber

两个先进因子已加入。

skyffire 1 tahun lalu
induk
melakukan
7e29520efd
3 mengubah file dengan 35 tambahan dan 220 penghapusan
  1. TEMPAT SAMPAH
      chart.png
  2. 13 13
      utils/chart-kit.js
  3. 22 207
      十面埋伏分析.js

TEMPAT SAMPAH
chart.png


+ 13 - 13
utils/chart-kit.js

@@ -1,6 +1,6 @@
 // npm install echarts canvas
 
-const fs = require('fs');
+// const fs = require('fs');
 const { createCanvas } = require('canvas');
 const echarts = require('echarts');
 
@@ -79,12 +79,12 @@ module.exports = class ChartKit {
     chart.setOption(option);
 
     // 等待图表渲染完毕
-    setTimeout(() => {
-      const buffer = canvas.toBuffer('image/png');
-      fs.writeFileSync('chart.png', buffer);
-      chart.dispose(); // 释放图表实例,防止内存泄漏
-      console.log('图表已保存为 chart.png');
-    }, 1000); // 设置一个延时以确保图表渲染完成
+    // setTimeout(() => {
+    //   const buffer = canvas.toBuffer('image/png');
+    //   fs.writeFileSync('chart.png', buffer);
+    //   chart.dispose(); // 释放图表实例,防止内存泄漏
+    //   console.log('图表已保存为 chart.png');
+    // }, 1000); // 设置一个延时以确保图表渲染完成
 
     return option
   }
@@ -119,12 +119,12 @@ module.exports = class ChartKit {
     chart.setOption(option);
 
     // 等待图表渲染完毕
-    setTimeout(() => {
-      const buffer = canvas.toBuffer('image/png');
-      fs.writeFileSync('chart.png', buffer);
-      chart.dispose(); // 释放图表实例,防止内存泄漏
-      console.log('图表已保存为 chart.png');
-    }, 1000); // 设置一个延时以确保图表渲染完成
+    // setTimeout(() => {
+    //   const buffer = canvas.toBuffer('image/png');
+    //   fs.writeFileSync('chart.png', buffer);
+    //   chart.dispose(); // 释放图表实例,防止内存泄漏
+    //   console.log('图表已保存为 chart.png');
+    // }, 1000); // 设置一个延时以确保图表渲染完成
 
     return option
   }

+ 22 - 207
十面埋伏分析.js

@@ -10,208 +10,27 @@ async function readData() {
   return JSON.parse(data)
 }
 
-// 统计过去N日累计涨幅,跟这个无关
+// 统计过去N日累计涨幅,【在-1%~-20%容易有亏损,有一定关系】
 function statisticA(kLines, index) {
-  let startK = kLines[index - 2]
+  let startK = kLines[index - 10]
   let endK = kLines[index - 1]
 
   if (!startK || !endK) {
     return 0
   }
 
-  let rst = NumKit.getSubFloat(100 * (endK.Close - startK.Open) / startK.Open, 2)
-
-  if (rst > 30 || rst < -30) {
-    return 0
-  }
-
-  return rst
+  return parseInt(100 * (endK.Close - startK.Open) / startK.Open) + 100
 }
 
-// 过去30天的平均振幅,跟这个无关
+// 返回过去一共N天涨幅超过M%【这个有关的】
 function statisticB(kLines, index) {
-  let kCount = 0
-  let totalRiseAndFall = 0
-  for (let i = index - 1; i >= index - 30; i--) {
-    let kLine = kLines[i]
-
-    if (!kLines[i - 1]) break
-
-    kCount += 1
-    totalRiseAndFall += (100 * (kLine.High - kLine.Low) / kLine.Low)
-  }
-
-  if (kCount === 0) {
-    return 0
-  }
-
-  return NumKit.getSubFloat(totalRiseAndFall / kCount, 2)
-}
-
-// 过去150天的平均(High - Close),跟这个无关
-function statisticC(kLines, index) {
-  let kCount = 0
-  let totalRiseAndFall = 0
-  for (let i = index - 1; i >= index - 150; i--) {
-    let kLine = kLines[i]
-
-    if (!kLines[i - 1]) break
-
-    kCount += 1
-    totalRiseAndFall += (100 * (kLine.High - kLine.Close) / kLine.Close)
-  }
-
-  if (kCount === 0) {
-    return 0
-  }
-
-  return NumKit.getSubFloat(totalRiseAndFall / kCount, 2)
-}
-
-// 过去30天的平均上影线,跟这个无关
-function statisticD(kLines, index) {
-  let kCount = 0
-  let totalRiseAndFall = 0
-  for (let i = index - 1; i >= index - 30; i--) {
-    let kLine = kLines[i]
-
-    if (!kLines[i - 1]) break
-
-    kCount += 1
-    let target = kLine.Close > kLine.Open ? kLine.Close : kLine.Open
-    totalRiseAndFall += (100 * (kLine.High - target) / target)
-  }
-
-  if (kCount === 0) {
-    return 0
-  }
-
-  return NumKit.getSubFloat(totalRiseAndFall / kCount, 2)
-}
-
-// 过去N天的上影线幅度大于2.5%,并且收盘是阴线的次数
-function statisticE(kLines, index) {
-  let kCount = 0
-  let count = 0
-  for (let i = index - 1; i >= index - 30; i--) {
-    let kLine = kLines[i]
-
-    if (!kLines[i - 1]) break
-
-    kCount += 1
-    let target = kLine.Close > kLine.Open ? kLine.Close : kLine.Open
-    let rise = (100 * (kLine.High - target) / target)
-    count += (rise > 2.5 && kLine.Close < kLine.Open ? 1 : 0)
-  }
-
-  if (kCount === 0) {
-    return 0
-  }
-
-  return count
-}
-
-// 过去30天的平均交易额(百万),跟这个无关
-function statisticF(kLines, index) {
-  let kCount = 0
-  let rst = 0
-  for (let i = index - 1; i >= index - 30; i--) {
-    let kLine = kLines[i]
-
-    if (!kLines[i - 1]) break
-
-    kCount += 1
-    rst += (kLine.Turnover / 1e6)
-  }
-
-  if (kCount === 0) {
-    return 0
-  }
-
-  return NumKit.getSubFloat(rst / kCount, 2)
-}
-
-// 过去30天的平均买入交易额(百万)
-function statisticG(kLines, index) {
-  let kCount = 0
-  let rst = 0
-  for (let i = index - 1; i >= index - 30; i--) {
-    let kLine = kLines[i]
-
-    if (!kLines[i - 1]) break
-
-    let rise = (kLine.BuyTurnover / 1e6)
-    if (rise > 100) continue
-    kCount += 1
-    rst += rise
-  }
-
-  if (kCount === 0) {
-    return 0
-  }
-
-  return NumKit.getSubFloat(rst / kCount, 2)
-}
-
-// 过去N天的平均买入交易额的比例
-function statisticH(kLines, index) {
-  let kCount = 0
-  let rst = 0
-  for (let i = index - 1; i >= index - 2; i--) {
-    let kLine = kLines[i]
-
-    if (!kLines[i - 1]) break
-
-    let rise = 100 * (kLine.BuyTurnover / kLine.Turnover)
-
-    kCount += 1
-    rst += rise
-  }
-
-  if (kCount === 0) {
-    return 0
-  }
-
-  return parseInt(NumKit.getSubFloat((rst / kCount - 50) * 10 + 100, 2))
-}
-
-// 过去N天阴线数量
-function statisticI(kLines, index) {
-  let count = 0
-  for (let i = index - 1; i >= index - 10; i--) {
-    let kLine = kLines[i]
-
-    if (!kLines[i - 1]) break
-
-    count += kLine.Close < kLine.Open ? 1 : 0
-  }
-
-  return count
-}
-
-// 返回过去一共连续N天阴线
-function statisticJ(kLines, index) {
   let count = 0
-  for (let i = index - 1; i >= 0; i--) {
+  for (let i = index - 1; i >= index - 3; i--) {
     let kLine = kLines[i]
 
     if (!kLines[i - 1]) break
-    if (kLine.Close > kLine.Open) break
 
-    count += 1
-  }
-
-  return count
-}
-
-// 返回过去一共连续N天阳线
-function statisticK(kLines, index) {
-  let count = 0
-  for (let i = index - 1; i >= 0; i--) {
-    let kLine = kLines[i]
-
-    if (!kLines[i - 1]) break
-    if (kLine.Close < kLine.Open) break
+    if (100 * (kLine.Close - kLine.Open) / kLine.Open < 3) continue
 
     count += 1
   }
@@ -219,20 +38,16 @@ function statisticK(kLines, index) {
   return count
 }
 
-// 返回过去一共N天涨幅超过M%,这个有关的
-function statisticL(kLines, index) {
-  let count = 0
-  for (let i = index - 1; i >= index - 3; i--) {
-    let kLine = kLines[i]
-
-    if (!kLines[i - 1]) break
+// 指标过滤
+function filter(kLines, index) {
+  // 一共N天涨幅超过M%
+  if (statisticB(kLines, index) !== 0) return false
 
-    if (100 * (kLine.Close - kLine.Open) / kLine.Open < 3) continue
+  // 过去N日累计涨幅,85表示亏15%,115表示赚15%,100是分界线
+  let upRateN = statisticA(kLines, index)
+  if (upRateN >= 85 && upRateN <= 100) return false
 
-    count += 1
-  }
-
-  return count
+  return true
 }
 
 let realCountMap = {}
@@ -249,7 +64,7 @@ function getRealDragonMap(kLinesMap, dayCount, BUY_LIMIT_RATE) {
     if (!kLine || !prevKline) continue
 
     // 指标过滤
-    // if (statisticL(kLines, index) !== 0) continue
+    if (!filter(kLines, index)) continue
 
     let rate = 100 * (kLine.Close - kLine.Open) / kLine.Open
     if (rate > BUY_LIMIT_RATE) {
@@ -282,7 +97,7 @@ function getFakeDragonMap(kLinesMap, dayCount, BUY_LIMIT_RATE) {
     if (!kLine || (!prevKline)) continue
 
     // 指标过滤
-    // if (statisticL(kLines, index) !== 0) continue
+    if (!filter(kLines, index)) continue
 
     let rate = 100 * (kLine.Close - kLine.Open) / kLine.Open
     if (rate < BUY_LIMIT_RATE) {
@@ -307,13 +122,13 @@ let dataLeft = []
 let dataRight = []
 let tempLeft = []
 let tempRight = []
-let dataY = [...Array(30).keys()]
+let dataY = [...Array(100).keys()]
 function dragonAnalysis(btcKLines, kLinesMap, dragonMap, dayCount) {
   for (let symbol in dragonMap) {
     let kLines = kLinesMap[symbol]
     let index = kLines.length - (dayCount + 1)
 
-    let x = statisticL(kLines, index)
+    let x = statisticA(kLines, index)
     let y = dragonMap[symbol].Profit
 
     // logger.info(
@@ -353,17 +168,17 @@ function dragonAnalysis(btcKLines, kLinesMap, dragonMap, dayCount) {
       }
     }
     dataRight[x] = (tempLeft[x]?tempRight[x]/Math.abs(tempLeft[x]):0)
-    if (dataRight[x] > 5) dataRight[x] = 5
-    if (dataRight[x] < 0.8) dataRight[x] = 0.8
+    if (dataRight[x] > 10) dataRight[x] = 10
+    if (dataRight[x] < 0.5) dataRight[x] = 0.5
   }
 }
 
 async function main() {
   let kLinesMap = await readData()
 
-  const FIRST_FEW_DAYS = 1               // 第几天的数据,0表示今天,1表示昨天,2表示前天,以此类推
+  const FIRST_FEW_DAYS = 180               // 第几天的数据,0表示今天,1表示昨天,2表示前天,以此类推
   const BUY_LIMIT_RATE = 0               // 从什么比例入场
-  const BAKE_TEST_DAYS = 60              // 一共回测多少天, 150天是熊市最没有交易量的时候
+  const BAKE_TEST_DAYS = 30              // 一共回测多少天, 150天是熊市最没有交易量的时候
 
 
   let btcKLines = kLinesMap['BTC_USDT']