|
|
@@ -10,12 +10,12 @@ async function readData() {
|
|
|
}
|
|
|
|
|
|
let realCountMap = {}
|
|
|
-function getRealDragonMap(kLinesMap, FIRST_FEW_DAYS, BUY_LIMIT_RATE) {
|
|
|
+function getRealDragonMap(kLinesMap, dayCount, BUY_LIMIT_RATE) {
|
|
|
let realDragonMap = {}
|
|
|
for (let symbol in kLinesMap) {
|
|
|
let kLines = kLinesMap[symbol]
|
|
|
|
|
|
- let index = kLines.length - (FIRST_FEW_DAYS + 1)
|
|
|
+ let index = kLines.length - (dayCount + 1)
|
|
|
let kLine = kLines[index]
|
|
|
let prevKline = kLines[index - 1]
|
|
|
|
|
|
@@ -25,7 +25,7 @@ function getRealDragonMap(kLinesMap, FIRST_FEW_DAYS, BUY_LIMIT_RATE) {
|
|
|
let rate = 100 * (kLine.Close - kLine.Open) / kLine.Open
|
|
|
if (rate > BUY_LIMIT_RATE) {
|
|
|
kLine.Rate = rate
|
|
|
- kLine.Profit = rate - BUY_LIMIT_RATE
|
|
|
+ kLine.Profit = NumKit.getSubFloat(rate - BUY_LIMIT_RATE, 2)
|
|
|
realDragonMap[symbol] = kLine
|
|
|
|
|
|
if (!realCountMap[symbol]) {
|
|
|
@@ -41,11 +41,11 @@ function getRealDragonMap(kLinesMap, FIRST_FEW_DAYS, BUY_LIMIT_RATE) {
|
|
|
}
|
|
|
|
|
|
let fakeCountMap = {}
|
|
|
-function getFakeDragonMap(kLinesMap, FIRST_FEW_DAYS, BUY_LIMIT_RATE) {
|
|
|
+function getFakeDragonMap(kLinesMap, dayCount, BUY_LIMIT_RATE) {
|
|
|
let fakeDragonMap = {}
|
|
|
for (let symbol in kLinesMap) {
|
|
|
let kLines = kLinesMap[symbol]
|
|
|
- let index = kLines.length - (FIRST_FEW_DAYS + 1)
|
|
|
+ let index = kLines.length - (dayCount + 1)
|
|
|
let kLine = kLines[index]
|
|
|
let prevKline = kLines[index - 1]
|
|
|
|
|
|
@@ -57,7 +57,8 @@ function getFakeDragonMap(kLinesMap, FIRST_FEW_DAYS, BUY_LIMIT_RATE) {
|
|
|
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
|
|
|
+ // kLine.Profit = NumKit.getSubFloat(rate > 0 ? rate - BUY_LIMIT_RATE : -BUY_LIMIT_RATE, 2)
|
|
|
+ kLine.Profit = NumKit.getSubFloat(rate - BUY_LIMIT_RATE, 2)
|
|
|
fakeDragonMap[symbol] = kLine
|
|
|
|
|
|
if (!fakeCountMap[symbol]) {
|
|
|
@@ -72,24 +73,71 @@ function getFakeDragonMap(kLinesMap, FIRST_FEW_DAYS, BUY_LIMIT_RATE) {
|
|
|
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) {
|
|
|
-
|
|
|
+// 统计过去7日累计涨幅,跟这个无关
|
|
|
+function statisticA(kLines, index) {
|
|
|
+ let startK = kLines[index - 7]
|
|
|
+ let endK = kLines[index - 1]
|
|
|
+
|
|
|
+ if (!startK || !endK) {
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+
|
|
|
+ return NumKit.getSubFloat(100 * (endK.Close - startK.Open) / startK.Open, 2)
|
|
|
+}
|
|
|
+
|
|
|
+// 过去30天的平均振幅,跟这个无关
|
|
|
+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)
|
|
|
+}
|
|
|
+
|
|
|
+// 过去30天的平均(High - Close),跟这个可能有关系
|
|
|
+// TODO 将最近一个月的所有二维数据(y为盈利,x为平均(High - Close),进行二维化展开分析)
|
|
|
+function statisticC(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.Close) / kLine.Close)
|
|
|
+ }
|
|
|
+
|
|
|
+ if (kCount === 0) {
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+
|
|
|
+ return NumKit.getSubFloat(totalRiseAndFall / kCount, 2)
|
|
|
+}
|
|
|
+
|
|
|
+function dragonAnalysis(kLinesMap, dragonMap, dayCount) {
|
|
|
+ for (let symbol in dragonMap) {
|
|
|
+ let kLines = kLinesMap[symbol]
|
|
|
+ let index = kLines.length - (dayCount + 1)
|
|
|
+
|
|
|
+ logger.info(
|
|
|
+ `${symbol}的分析(${dragonMap[symbol].Profit}%)`
|
|
|
+ // + `前7日累计涨幅${statisticA(kLines, index)}%。`
|
|
|
+ // + `前30日平均振幅${statisticB(kLines, index)}%。`
|
|
|
+ + `前30日平均(High - Close)${statisticC(kLines, index)}%。`
|
|
|
+ )
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
async function main() {
|
|
|
@@ -100,25 +148,25 @@ async function main() {
|
|
|
const BAKE_TEST_DAYS = 1 // 一共回测多少天
|
|
|
|
|
|
let totalProfit = 0
|
|
|
- for (let i = FIRST_FEW_DAYS; i < FIRST_FEW_DAYS + BAKE_TEST_DAYS; i++) {
|
|
|
+ for (let day_count = FIRST_FEW_DAYS; day_count < FIRST_FEW_DAYS + BAKE_TEST_DAYS; day_count++) {
|
|
|
// 赚钱榜
|
|
|
let realDragonProfit = 0
|
|
|
- let realDragonMap = getRealDragonMap(kLinesMap, i, BUY_LIMIT_RATE)
|
|
|
+ let realDragonMap = getRealDragonMap(kLinesMap, day_count, 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)
|
|
|
+ dragonAnalysis(kLinesMap, realDragonMap, day_count)
|
|
|
// 亏钱榜
|
|
|
let fakeDragonProfit = 0
|
|
|
- let fakeDragonMap = getFakeDragonMap(kLinesMap, i, BUY_LIMIT_RATE)
|
|
|
+ let fakeDragonMap = getFakeDragonMap(kLinesMap, day_count, 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)
|
|
|
+ dragonAnalysis(kLinesMap, fakeDragonMap, day_count)
|
|
|
|
|
|
realDragonProfit = NumKit.getSubFloat(realDragonProfit, 2)
|
|
|
fakeDragonProfit = NumKit.getSubFloat(fakeDragonProfit, 2)
|
|
|
@@ -131,14 +179,14 @@ async function main() {
|
|
|
let synProfit = NumKit.getSubFloat(expFakeProfit + expRealProfit, 2)
|
|
|
let avgProfit = NumKit.getSubFloat(synProfit / (realLength + fakeLength), 2)
|
|
|
|
|
|
- let index = kLinesMap['BTC_USDT'].length - (i + 1)
|
|
|
+ let index = kLinesMap['BTC_USDT'].length - (day_count + 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}%`
|
|
|
+ logger.info(`${day_count}日(${dateStr}, ${realLength + fakeLength}只),赚钱榜(${realLength}只)利润${realDragonProfit}%`
|
|
|
+ `,亏钱榜(${fakeLength}只)利润${fakeDragonProfit}%`
|
|
|
- + `,真龙期望利润${expRealProfit}%,假龙期望利润${expFakeProfit}%,综合利润${synProfit}%,平均每只利润${avgProfit}%,BTC涨幅${btcUpRate}%`
|
|
|
+ + `,赚钱榜期望利润${expRealProfit}%,亏钱榜期望利润${expFakeProfit}%,综合利润${synProfit}%,平均每只利润${avgProfit}%,BTC涨幅${btcUpRate}%`
|
|
|
)
|
|
|
|
|
|
totalProfit += avgProfit
|