skyffire 1 год назад
Родитель
Сommit
4136a3f9d1
3 измененных файлов с 120 добавлено и 16 удалено
  1. BIN
      chart.png
  2. 88 1
      utils/chart-kit.js
  3. 32 15
      十面埋伏分析.js

+ 88 - 1
utils/chart-kit.js

@@ -5,7 +5,92 @@ const { createCanvas } = require('canvas');
 const echarts = require('echarts');
 
 module.exports = class ChartKit {
-  static printChart(dataList) {
+
+  // 例子:https://echarts.apache.org/examples/zh/editor.html?c=bar-negative
+  static printBar(yData, xDataLeft, xDataRight) {
+    // 创建一个 canvas 实例
+    const width = 3840; // 宽度
+    const height = 2160; // 高度
+    const canvas = createCanvas(width, height);
+
+    // 初始化 ECharts 实例
+    const chart = echarts.init(canvas);
+
+    let option = {
+      tooltip: {
+        trigger: 'axis',
+        axisPointer: {
+          type: 'shadow'
+        }
+      },
+      legend: {
+        data: ['Profit', 'Expenses', 'Income']
+      },
+      grid: {
+        left: '3%',
+        right: '4%',
+        bottom: '3%',
+        containLabel: true
+      },
+      xAxis: [
+        {
+          type: 'value'
+        }
+      ],
+      yAxis: [
+        {
+          type: 'category',
+          axisTick: {
+            show: false
+          },
+          data: yData
+        }
+      ],
+      series: [
+        {
+          name: 'Expenses',
+          type: 'bar',
+          stack: 'Total',
+          label: {
+            show: true,
+            position: 'left'
+          },
+          emphasis: {
+            focus: 'series'
+          },
+          data: xDataLeft
+        },
+        {
+          name: 'Income',
+          type: 'bar',
+          stack: 'Total',
+          label: {
+            show: true
+          },
+          emphasis: {
+            focus: 'series'
+          },
+          data: xDataRight
+        }
+      ]
+    };
+
+    // 设置图表的配置项和数据
+    chart.setOption(option);
+
+    // 等待图表渲染完毕
+    setTimeout(() => {
+      const buffer = canvas.toBuffer('image/png');
+      fs.writeFileSync('chart.png', buffer);
+      chart.dispose(); // 释放图表实例,防止内存泄漏
+      console.log('图表已保存为 chart.png');
+    }, 1000); // 设置一个延时以确保图表渲染完成
+
+    return option
+  }
+
+  // dataList : [[x1,y1], [x2,y2], ...]
+  static printPointChart(dataList) {
     // 创建一个 canvas 实例
     const width = 3840; // 宽度
     const height = 2160; // 高度
@@ -40,5 +125,7 @@ module.exports = class ChartKit {
       chart.dispose(); // 释放图表实例,防止内存泄漏
       console.log('图表已保存为 chart.png');
     }, 1000); // 设置一个延时以确保图表渲染完成
+
+    return option
   }
 }

+ 32 - 15
十面埋伏分析.js

@@ -153,11 +153,11 @@ function statisticD(kLines, index) {
   return NumKit.getSubFloat(totalRiseAndFall / kCount, 2)
 }
 
-// 过去30天的上影线幅度大于2.5%,并且收盘是阴线的次数
+// 过去60天的上影线幅度大于2.5%,并且收盘是阴线的次数
 function statisticE(kLines, index) {
   let kCount = 0
   let count = 0
-  for (let i = index - 1; i >= index - 30; i--) {
+  for (let i = index - 1; i >= index - 60; i--) {
     let kLine = kLines[i]
 
     if (!kLines[i - 1]) break
@@ -236,17 +236,23 @@ function statisticH(kLines, index) {
     return 0
   }
 
-  return NumKit.getSubFloat(rst / kCount, 2)
+  return parseInt(NumKit.getSubFloat((rst / kCount - 50) * 10 + 50, 2))
 }
 
+// BTC涨跌幅与当日收益率的关系
+// function statisticI(btcKLines, kLines, index) {
+//
+// }
 
-let dataList = []
-function dragonAnalysis(kLinesMap, dragonMap, dayCount) {
+let dataLeft = []
+let dataRight = []
+let dataY = [...Array(150).keys()]
+function dragonAnalysis(btcKLines, kLinesMap, dragonMap, dayCount) {
   for (let symbol in dragonMap) {
     let kLines = kLinesMap[symbol]
     let index = kLines.length - (dayCount + 1)
 
-    let x = statisticE(kLines, index)
+    let x = statisticH(kLines, index)
     let y = dragonMap[symbol].Profit
 
     // logger.info(
@@ -255,17 +261,23 @@ function dragonAnalysis(kLinesMap, dragonMap, dayCount) {
     //   // + `前30日平均振幅${statisticB(kLines, index)}%。`
     //   + `前30日平均(High - Close)${x}%。`
     // )
-    dataList.push([x, y])
+    if (dataRight[x]) {
+      dataRight[x] += y
+    } else {
+      dataRight[x] = y
+    }
   }
 }
 
 async function main() {
   let kLinesMap = await readData()
 
-  const FIRST_FEW_DAYS = 1            // 第几天的数据,0表示今天,1表示昨天,2表示前天,以此类推
-  const BUY_LIMIT_RATE = 2.5          // 从什么比例入场
-  const BAKE_TEST_DAYS = 10           // 一共回测多少天
+  const FIRST_FEW_DAYS = 1              // 第几天的数据,0表示今天,1表示昨天,2表示前天,以此类推
+  const BUY_LIMIT_RATE = 2.5            // 从什么比例入场
+  const BAKE_TEST_DAYS = 30             // 一共回测多少天
 
+
+  let btcKLines = kLinesMap['BTC_USDT']
   let totalProfit = 0
   for (let day_count = FIRST_FEW_DAYS; day_count < FIRST_FEW_DAYS + BAKE_TEST_DAYS; day_count++) {
     // 赚钱榜
@@ -276,7 +288,7 @@ async function main() {
       // logger.info(realDragonMap[symbol].Symbol, realDragonMap[symbol].Profit, realDragonMap[symbol].Rate)
     }
     logger.info("----------------赚钱榜数据分析----------------")
-    dragonAnalysis(kLinesMap, realDragonMap, day_count)
+    dragonAnalysis(btcKLines, kLinesMap, realDragonMap, day_count)
     // 亏钱榜
     let fakeDragonProfit = 0
     let fakeDragonMap = getFakeDragonMap(kLinesMap, day_count, BUY_LIMIT_RATE)
@@ -285,7 +297,7 @@ async function main() {
       // logger.info(fakeDragonMap[symbol].Symbol, fakeDragonMap[symbol].Profit, fakeDragonMap[symbol].MaxRate, fakeDragonMap[symbol].Rate)
     }
     logger.info("----------------亏钱榜数据分析----------------")
-    dragonAnalysis(kLinesMap, fakeDragonMap, day_count)
+    dragonAnalysis(btcKLines, kLinesMap, fakeDragonMap, day_count)
 
     realDragonProfit = NumKit.getSubFloat(realDragonProfit, 2)
     fakeDragonProfit = NumKit.getSubFloat(fakeDragonProfit, 2)
@@ -312,9 +324,6 @@ async function main() {
     totalProfit = NumKit.getSubFloat(totalProfit, 2)
   }
 
-  logger.info(`${dataList.length}`)
-  ChartKit.printChart(dataList)
-
   // let dayProfit = NumKit.getSubFloat(totalProfit / BAKE_TEST_DAYS, 2)
   // logger.info(`利润期望值总和:${totalProfit}%,平均日化${dayProfit}%。`)
   // for (let symbol in fakeCountMap) {
@@ -324,6 +333,14 @@ async function main() {
   //
   //   logger.info(`${symbol} 盈${realCountMap[symbol]},亏${fakeCountMap[symbol]},大于5%涨幅的共有${statisticA(kLines, startIndex, endIndex)}日。`)
   // }
+  let rst = 'option=' + JSON.stringify(ChartKit.printBar(dataY, dataLeft, dataRight), null, 2)
+  require('fs').writeFile('./data/option.txt', rst, 'utf8', (err) => {
+    if (err) {
+      logger.error('写入文件时发生错误:', err);
+    } else {
+      logger.info('分析结果已写入到 ./data/option.txt');
+    }
+  });
 }
 
 main().catch((error) => {