| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- const logger = require("./utils/logger");
- const NumKit = require('./utils/num-kit')
- const TimeKit = require('./utils/time-kit')
- const fs = require('fs').promises;
- async function readData() {
- let data = await fs.readFile('./data/k_lines.json', 'utf8')
- return JSON.parse(data)
- }
- let realCountMap = {}
- function getRealDragonMap(kLinesMap, FIRST_FEW_DAYS, BUY_LIMIT_RATE) {
- let realDragonMap = {}
- for (let symbol in kLinesMap) {
- let kLines = kLinesMap[symbol]
- let index = kLines.length - (FIRST_FEW_DAYS + 1)
- let kLine = kLines[index]
- let prevKline = kLines[index - 1]
- // 开盘第一天不计算
- if (!kLine || !prevKline) continue
- let rate = 100 * (kLine.Close - kLine.Open) / kLine.Open
- if (rate > BUY_LIMIT_RATE) {
- kLine.Rate = rate
- kLine.Profit = rate - BUY_LIMIT_RATE
- realDragonMap[symbol] = kLine
- if (!realCountMap[symbol]) {
- realCountMap[symbol] = kLine.Profit
- } else {
- realCountMap[symbol] += kLine.Profit
- }
- realCountMap[symbol] = NumKit.getSubFloat(realCountMap[symbol], 2)
- }
- }
- return realDragonMap
- }
- let fakeCountMap = {}
- function getFakeDragonMap(kLinesMap, FIRST_FEW_DAYS, BUY_LIMIT_RATE) {
- let fakeDragonMap = {}
- for (let symbol in kLinesMap) {
- let kLines = kLinesMap[symbol]
- let index = kLines.length - (FIRST_FEW_DAYS + 1)
- let kLine = kLines[index]
- let prevKline = kLines[index - 1]
- // 开盘第一天不计算
- if (!kLine || (!prevKline)) continue
- let rate = 100 * (kLine.Close - kLine.Open) / kLine.Open
- let maxRate = 100 * (kLine.High - kLine.Open) / kLine.Open
- if (maxRate > BUY_LIMIT_RATE && rate < BUY_LIMIT_RATE) {
- kLine.Rate = rate
- kLine.MaxRate = maxRate
- kLine.Profit = rate > 0 ? rate - BUY_LIMIT_RATE : -BUY_LIMIT_RATE
- fakeDragonMap[symbol] = kLine
- if (!fakeCountMap[symbol]) {
- fakeCountMap[symbol] = kLine.Profit
- } else {
- fakeCountMap[symbol] += kLine.Profit
- }
- fakeCountMap[symbol] = NumKit.getSubFloat(fakeCountMap[symbol], 2)
- }
- }
- return fakeDragonMap
- }
- // 统计单日涨幅大于5%的有多少根k线
- // function statisticA(kLines, start, end) {
- // let count = 0
- //
- // for (let i = start >= 0 ? start : 0; i <= end; i++) {
- // let kLine = kLines[i]
- // let upRate = NumKit.getSubFloat(100 * (kLine.Close - kLine.Open) / kLine.Open, 2)
- //
- // if (upRate > 5) {
- // count += 1
- // }
- // }
- //
- // return count
- // }
- function dragonAnalysis(dragonMap) {
-
- }
- 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 = 1 // 一共回测多少天
- let totalProfit = 0
- for (let i = FIRST_FEW_DAYS; i < FIRST_FEW_DAYS + BAKE_TEST_DAYS; i++) {
- // 赚钱榜
- let realDragonProfit = 0
- let realDragonMap = getRealDragonMap(kLinesMap, i, BUY_LIMIT_RATE)
- for (let symbol in realDragonMap) {
- realDragonProfit += realDragonMap[symbol].Profit
- // logger.info(realDragonMap[symbol].Symbol, realDragonMap[symbol].Profit, realDragonMap[symbol].Rate)
- }
- logger.info("----------------赚钱榜数据分析----------------")
- dragonAnalysis(realDragonMap)
- // 亏钱榜
- let fakeDragonProfit = 0
- let fakeDragonMap = getFakeDragonMap(kLinesMap, i, BUY_LIMIT_RATE)
- for (let symbol in fakeDragonMap) {
- fakeDragonProfit += fakeDragonMap[symbol].Profit
- // logger.info(fakeDragonMap[symbol].Symbol, fakeDragonMap[symbol].Profit, fakeDragonMap[symbol].MaxRate, fakeDragonMap[symbol].Rate)
- }
- logger.info("----------------亏钱榜数据分析----------------")
- dragonAnalysis(fakeDragonMap)
- realDragonProfit = NumKit.getSubFloat(realDragonProfit, 2)
- fakeDragonProfit = NumKit.getSubFloat(fakeDragonProfit, 2)
- let realLength = Object.keys(realDragonMap).length
- let fakeLength = Object.keys(fakeDragonMap).length
- let realRate = NumKit.getSubFloat(realLength / (realLength + fakeLength), 2)
- let fakeRate = NumKit.getSubFloat(1 - realRate, 2)
- let expRealProfit = NumKit.getSubFloat(realRate * realDragonProfit, 2)
- let expFakeProfit = NumKit.getSubFloat(fakeRate * fakeDragonProfit, 2)
- let synProfit = NumKit.getSubFloat(expFakeProfit + expRealProfit, 2)
- let avgProfit = NumKit.getSubFloat(synProfit / (realLength + fakeLength), 2)
- let index = kLinesMap['BTC_USDT'].length - (i + 1)
- let btcK = kLinesMap['BTC_USDT'][index]
- let dateStr = TimeKit.getDateByMillisecond(btcK.Time)
- let btcUpRate = NumKit.getSubFloat(100 * (btcK.Close - btcK.Open) / btcK.Open, 2)
- logger.info(`${i}日(${dateStr}, ${realLength + fakeLength}只),赚钱榜(${realLength}只)利润${realDragonProfit}%`
- + `,亏钱榜(${fakeLength}只)利润${fakeDragonProfit}%`
- + `,真龙期望利润${expRealProfit}%,假龙期望利润${expFakeProfit}%,综合利润${synProfit}%,平均每只利润${avgProfit}%,BTC涨幅${btcUpRate}%`
- )
- totalProfit += avgProfit
- totalProfit = NumKit.getSubFloat(totalProfit, 2)
- }
- // let dayProfit = NumKit.getSubFloat(totalProfit / BAKE_TEST_DAYS, 2)
- // logger.info(`利润期望值总和:${totalProfit}%,平均日化${dayProfit}%。`)
- // for (let symbol in fakeCountMap) {
- // let kLines = kLinesMap[symbol]
- // let startIndex = kLines.length - BAKE_TEST_DAYS
- // let endIndex = kLines.length - 1
- //
- // logger.info(`${symbol} 盈${realCountMap[symbol]},亏${fakeCountMap[symbol]},大于5%涨幅的共有${statisticA(kLines, startIndex, endIndex)}日。`)
- // }
- }
- main().catch((error) => {
- logger.error(error.stack);
- process.exitCode = 1;
- })
|