From 65add97beabc7d887ee67587100a5428c004d414 Mon Sep 17 00:00:00 2001 From: Jens von der Heydt Date: Tue, 3 Oct 2017 13:45:42 +0200 Subject: [PATCH] Filter the simulation output from ansi-codes so that the results can be properly interpreted. (#578) The used color.js library does have a "--no-color" switch that should solve the above problem but that library isn't under active development anymore and currently has several bugs regarding the --no-color switch. Since zenbot has a very tight coupling to color.js this is the only way to solve the problem from #578. Solves: #578 --- scripts/auto_backtester/backtester.js | 20 +++++++++++--------- scripts/auto_backtester/package.json | 3 ++- scripts/genetic_backtester/darwin.js | 8 +++++--- scripts/genetic_backtester/package.json | 3 ++- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/scripts/auto_backtester/backtester.js b/scripts/auto_backtester/backtester.js index 2e70b37327..65c21ea4c1 100755 --- a/scripts/auto_backtester/backtester.js +++ b/scripts/auto_backtester/backtester.js @@ -16,6 +16,7 @@ let parallel = require('run-parallel-limit'); let json2csv = require('json2csv'); let roundp = require('round-precision'); let fs = require('fs'); +let StripAnsi = require('strip-ansi'); let VERSION = 'Zenbot 4.04 Backtester v0.2'; @@ -72,7 +73,7 @@ let objectProduct = obj => { let runCommand = (strategy, cb) => { countArr.push(1); let strategyArgs = { - cci_srsi: `--cci_periods=${strategy.rsi_periods} --rsi_periods=${strategy.srsi_periods} --srsi_periods=${strategy.srsi_periods} --srsi_k=${strategy.srsi_k} --srsi_d=${strategy.srsi_d} --oversold_rsi=${strategy.oversold_rsi} --overbought_rsi=${strategy.overbought_rsi} --oversold_cci=${strategy.oversold_cci} --overbought_cci=${strategy.overbought_cci} --constant=${strategy.constant}`, + cci_srsi: `--cci_periods=${strategy.rsi_periods} --rsi_periods=${strategy.srsi_periods} --srsi_periods=${strategy.srsi_periods} --srsi_k=${strategy.srsi_k} --srsi_d=${strategy.srsi_d} --oversold_rsi=${strategy.oversold_rsi} --overbought_rsi=${strategy.overbought_rsi} --oversold_cci=${strategy.oversold_cci} --overbought_cci=${strategy.overbought_cci} --constant=${strategy.constant}`, srsi_macd: `--rsi_periods=${strategy.rsi_periods} --srsi_periods=${strategy.srsi_periods} --srsi_k=${strategy.srsi_k} --srsi_d=${strategy.srsi_d} --oversold_rsi=${strategy.oversold_rsi} --overbought_rsi=${strategy.overbought_rsi} --ema_short_period=${strategy.ema_short_period} --ema_long_period=${strategy.ema_long_period} --signal_period=${strategy.signal_period} --up_trend_threshold=${strategy.up_trend_threshold} --down_trend_threshold=${strategy.down_trend_threshold}`, macd: `--ema_short_period=${strategy.ema_short_period} --ema_long_period=${strategy.ema_long_period} --signal_period=${strategy.signal_period} --up_trend_threshold=${strategy.up_trend_threshold} --down_trend_threshold=${strategy.down_trend_threshold} --overbought_rsi_periods=${strategy.overbought_rsi_periods} --overbought_rsi=${strategy.overbought_rsi}`, rsi: `--rsi_periods=${strategy.rsi_periods} --oversold_rsi=${strategy.oversold_rsi} --overbought_rsi=${strategy.overbought_rsi} --rsi_recover=${strategy.rsi_recover} --rsi_drop=${strategy.rsi_drop} --rsi_divisor=${strategy.rsi_divisor}`, @@ -102,7 +103,8 @@ let processOutput = output => { let wlRegexp = /win\/loss: (\d+)\/(\d+)/g; let errRegexp = /error rate: (.*)%/g; - let output2 = output.substr(output.length - 3000); + let strippedOutput = StripAnsi(output); + let output2 = strippedOutput.substr(strippedOutput.length - 3500); let rawParams = jsonRegexp.exec(output2)[1]; let params = JSON.parse(rawParams); @@ -134,12 +136,12 @@ let processOutput = output => { cciPeriods: params.cci_periods, rsiPeriods: params.rsi_periods, srsiPeriods: params.srsi_periods, - srsiK: params.srsi_k, - srsiD: params.srsi_d, - oversoldRsi: params.oversold_rsi, + srsiK: params.srsi_k, + srsiD: params.srsi_d, + oversoldRsi: params.oversold_rsi, overboughtRsi: params.overbought_rsi, - oversoldCci: params.oversold_cci, - overboughtCci: params.overbought_cci, + oversoldCci: params.oversold_cci, + overboughtCci: params.overbought_cci, constant: params.consant, // srsi_macd @@ -296,7 +298,7 @@ parallel(tasks, PARALLEL_LIMIT, (err, results) => { let filedsGeneral = ['roi', 'vsBuyHold', 'errorRate', 'wlRatio', 'frequency', 'endBalance', 'buyHold', 'wins', 'losses', 'period', 'min_periods', 'days']; let filedNamesGeneral = ['ROI (%)', 'VS Buy Hold (%)', 'Error Rate (%)', 'Win/Loss Ratio', '# Trades/Day', 'Ending Balance ($)', 'Buy Hold ($)', '# Wins', '# Losses', 'Period', 'Min Periods', '# Days']; let fields = { - cci_srsi: filedsGeneral.concat(['cciPeriods', 'rsiPeriods', 'srsiPeriods', 'srsiK', 'srsiD', 'oversoldRsi', 'overboughtRsi', 'oversoldCci', 'overboughtCci', 'Constant', 'params']), + cci_srsi: filedsGeneral.concat(['cciPeriods', 'rsiPeriods', 'srsiPeriods', 'srsiK', 'srsiD', 'oversoldRsi', 'overboughtRsi', 'oversoldCci', 'overboughtCci', 'Constant', 'params']), srsi_macd: filedsGeneral.concat(['rsiPeriods', 'srsiPeriods', 'srsiK', 'srsiD', 'oversoldRsi', 'overboughtRsi', 'emaShortPeriod', 'emaLongPeriod', 'signalPeriod', 'upTrendThreshold', 'downTrendThreshold', 'params']), macd: filedsGeneral.concat([ 'emaShortPeriod', 'emaLongPeriod', 'signalPeriod', 'upTrendThreshold', 'downTrendThreshold', 'overboughtRsiPeriods', 'overboughtRsi', 'params']), rsi: filedsGeneral.concat(['rsiPeriods', 'oversoldRsi', 'overboughtRsi', 'rsiRecover', 'rsiDrop', 'rsiDivsor', 'params']), @@ -305,7 +307,7 @@ parallel(tasks, PARALLEL_LIMIT, (err, results) => { trend_ema: filedsGeneral.concat(['trendEma', 'neutralRate', 'oversoldRsiPeriods', 'oversoldRsi', 'params']) }; let fieldNames = { - cci_srsi: filedNamesGeneral.concat(['CCI Periods', 'RSI Periods', 'SRSI Periods', 'SRSI K', 'SRSI D', 'Oversold RSI', 'Overbought RSI', 'Oversold CCI', 'Overbought CCI', 'Constant', 'Full Parameters']), + cci_srsi: filedNamesGeneral.concat(['CCI Periods', 'RSI Periods', 'SRSI Periods', 'SRSI K', 'SRSI D', 'Oversold RSI', 'Overbought RSI', 'Oversold CCI', 'Overbought CCI', 'Constant', 'Full Parameters']), srsi_macd: filedNamesGeneral.concat(['RSI Periods', 'SRSI Periods', 'SRSI K', 'SRSI D', 'Oversold RSI', 'Overbought RSI', 'EMA Short Period', 'EMA Long Period', 'Signal Period', 'Up Trend Threshold', 'Down Trend Threshold', 'Full Parameters']), macd: filedNamesGeneral.concat(['EMA Short Period', 'EMA Long Period', 'Signal Period', 'Up Trend Threshold', 'Down Trend Threshold', 'Overbought Rsi Periods', 'Overbought Rsi', 'Full Parameters']), rsi: filedNamesGeneral.concat(['RSI Periods', 'Oversold RSI', 'Overbought RSI', 'RSI Recover', 'RSI Drop', 'RSI Divisor', 'Full Parameters']), diff --git a/scripts/auto_backtester/package.json b/scripts/auto_backtester/package.json index 1f2e6ce231..3ef806b0ad 100644 --- a/scripts/auto_backtester/package.json +++ b/scripts/auto_backtester/package.json @@ -6,6 +6,7 @@ "json2csv": "^3.7.3", "round-precision": "^1.0.0", "run-parallel-limit": "^1.0.3", - "shelljs": "^0.7.8" + "shelljs": "^0.7.8", + "strip-ansi": "^4.0.0" } } diff --git a/scripts/genetic_backtester/darwin.js b/scripts/genetic_backtester/darwin.js index de02dbfaf4..b6a0be0a45 100644 --- a/scripts/genetic_backtester/darwin.js +++ b/scripts/genetic_backtester/darwin.js @@ -13,6 +13,7 @@ let json2csv = require('json2csv'); let roundp = require('round-precision'); let fs = require('fs'); let GeneticAlgorithmCtor = require('geneticalgorithm'); +let StripAnsi = require('strip-ansi'); let Phenotypes = require('./phenotype.js'); @@ -98,7 +99,8 @@ let processOutput = output => { let wlRegexp = /win\/loss: (\d+)\/(\d+)/g; let errRegexp = /error rate: (.*)%/g; - let output2 = output.substr(output.length - 3500); + let strippedOutput = StripAnsi(output); + let output2 = strippedOutput.substr(strippedOutput.length - 3500); let rawParams = jsonRegexp.exec(output2)[1]; let params = JSON.parse(rawParams); @@ -427,7 +429,7 @@ let simulateGeneration = () => { console.log(`\n\n=== Simulating generation ${generationCount++} ===\n`); runUpdate(argv.days, argv.selector); - + iterationCount = 1; let tasks = selectedStrategies.map(v => pools[v]['pool'].population().map(phenotype => { return cb => { @@ -442,7 +444,7 @@ let simulateGeneration = () => { }); results.sort((a, b) => (a.fitness < b.fitness) ? 1 : ((b.fitness < a.fitness) ? -1 : 0)); - + let fieldsGeneral = ['fitness', 'vsBuyHold', 'wlRatio', 'frequency', 'strategy', 'order_type', 'endBalance', 'buyHold', 'wins', 'losses', 'period', 'min_periods', 'days', 'params']; let fieldNamesGeneral = ['Fitness', 'VS Buy Hold (%)', 'Win/Loss Ratio', '# Trades/Day', 'Strategy', 'Order Type', 'Ending Balance ($)', 'Buy Hold ($)', '# Wins', '# Losses', 'Period', 'Min Periods', '# Days', 'Full Parameters']; diff --git a/scripts/genetic_backtester/package.json b/scripts/genetic_backtester/package.json index 865329ab7b..dd54301e70 100644 --- a/scripts/genetic_backtester/package.json +++ b/scripts/genetic_backtester/package.json @@ -8,6 +8,7 @@ "round-precision": "^1.0.0", "run-parallel-limit": "^1.0.3", "shelljs": "^0.7.8", - "yargs": "^8.0.2" + "yargs": "^8.0.2", + "strip-ansi": "^4.0.0" } }