From 871357a2e35f337cafe1492732d16278e818249d Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Fri, 22 Dec 2017 16:53:31 +0200 Subject: [PATCH 1/9] just require positive results --- freqtrade/optimize/hyperopt.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index b3dc3d5e4..218e1a910 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -32,9 +32,9 @@ TARGET_TRADES = 1100 TOTAL_TRIES = None _CURRENT_TRIES = 0 -TOTAL_PROFIT_TO_BEAT = 3 -AVG_PROFIT_TO_BEAT = 0.2 -AVG_DURATION_TO_BEAT = 50 +TOTAL_PROFIT_TO_BEAT = 0 +AVG_PROFIT_TO_BEAT = 0 +AVG_DURATION_TO_BEAT = 100 # Configuration and data used by hyperopt PROCESSED = optimize.preprocess(optimize.load_data()) From 10cf2ce853907c431e0eebc8b827e13b22bebc51 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Fri, 22 Dec 2017 16:54:04 +0200 Subject: [PATCH 2/9] remove unnecessary confusing division --- freqtrade/optimize/hyperopt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 218e1a910..3db11a270 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -101,7 +101,7 @@ def log_results(results): current_try = results['current_tries'] total_tries = results['total_tries'] result = results['result'] - profit = results['total_profit'] / 1000 + profit = results['total_profit'] outcome = '{:5d}/{}: {}'.format(current_try, total_tries, result) From a063680d3204f44e7b597b0553caa08ab2efd84f Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Fri, 22 Dec 2017 16:55:20 +0200 Subject: [PATCH 3/9] calculate log line only if really logging --- freqtrade/optimize/hyperopt.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 3db11a270..85c20fe4b 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -103,10 +103,8 @@ def log_results(results): result = results['result'] profit = results['total_profit'] - outcome = '{:5d}/{}: {}'.format(current_try, total_tries, result) - if profit >= TOTAL_PROFIT_TO_BEAT: - logger.info(outcome) + logger.info('{:5d}/{}: {}'.format(current_try, total_tries, result)) else: print('.', end='') sys.stdout.flush() From 5309ea3820ad4c708229ca76f34240e55d206dc6 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Fri, 22 Dec 2017 16:56:59 +0200 Subject: [PATCH 4/9] use newline for each log result for readability --- freqtrade/optimize/hyperopt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 85c20fe4b..15af8a649 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -104,7 +104,7 @@ def log_results(results): profit = results['total_profit'] if profit >= TOTAL_PROFIT_TO_BEAT: - logger.info('{:5d}/{}: {}'.format(current_try, total_tries, result)) + logger.info('\n{:5d}/{}: {}'.format(current_try, total_tries, result)) else: print('.', end='') sys.stdout.flush() From 24bc3a8390d7a1c611cc9d7a3e3f3e0855d40894 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sat, 23 Dec 2017 15:08:54 +0200 Subject: [PATCH 5/9] show more digits for profits --- freqtrade/optimize/hyperopt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 15af8a649..abf590c4f 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -155,7 +155,7 @@ def optimizer(params): def format_results(results: DataFrame): return ('Made {:6d} buys. Average profit {: 5.2f}%. ' - 'Total profit was {: 7.3f}. Average duration {:5.1f} mins.').format( + 'Total profit was {: 11.8f}. Average duration {:5.1f} mins.').format( len(results.index), results.profit_percent.mean() * 100.0, results.profit_BTC.sum(), From 1058820e1bbc3cfba89712768d6b253429db659e Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sat, 23 Dec 2017 17:26:22 +0200 Subject: [PATCH 6/9] just pass stake_amount instead of the whole config --- freqtrade/optimize/backtesting.py | 8 ++++---- freqtrade/optimize/hyperopt.py | 2 +- freqtrade/tests/test_optimize_backtesting.py | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 5761c9507..5dc1c3a3d 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -64,7 +64,7 @@ def generate_text_table( return tabulate(tabular_data, headers=headers) -def backtest(config: Dict, processed: Dict[str, DataFrame], +def backtest(stake_amount: float, processed: Dict[str, DataFrame], max_open_trades: int = 0, realistic: bool = True) -> DataFrame: """ Implements backtesting functionality @@ -98,8 +98,8 @@ def backtest(config: Dict, processed: Dict[str, DataFrame], trade = Trade( open_rate=row.close, open_date=row.date, - stake_amount=config['stake_amount'], - amount=config['stake_amount'] / row.open, + stake_amount=stake_amount, + amount=stake_amount / row.open, fee=exchange.get_fee() ) @@ -170,7 +170,7 @@ def start(args): # Execute backtest and print results results = backtest( - config, preprocess(data), max_open_trades, args.realistic_simulation + config['stake_amount'], preprocess(data), max_open_trades, args.realistic_simulation ) logger.info( '\n====================== BACKTESTING REPORT ======================================\n%s', diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index abf590c4f..7a3340508 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -116,7 +116,7 @@ def optimizer(params): from freqtrade.optimize import backtesting backtesting.populate_buy_trend = buy_strategy_generator(params) - results = backtest(OPTIMIZE_CONFIG, PROCESSED) + results = backtest(OPTIMIZE_CONFIG['stake_amount'], PROCESSED) result = format_results(results) diff --git a/freqtrade/tests/test_optimize_backtesting.py b/freqtrade/tests/test_optimize_backtesting.py index f35d21648..2863961d3 100644 --- a/freqtrade/tests/test_optimize_backtesting.py +++ b/freqtrade/tests/test_optimize_backtesting.py @@ -12,7 +12,7 @@ def test_backtest(default_conf, mocker): exchange._API = Bittrex({'key': '', 'secret': ''}) data = optimize.load_data(ticker_interval=5, pairs=['BTC_ETH']) - results = backtest(default_conf, optimize.preprocess(data), 10, True) + results = backtest(default_conf['stake_amount'], optimize.preprocess(data), 10, True) num_results = len(results) assert num_results > 0 @@ -23,7 +23,7 @@ def test_1min_ticker_interval(default_conf, mocker): # Run a backtesting for an exiting 5min ticker_interval data = optimize.load_data(ticker_interval=1, pairs=['BTC_UNITEST']) - results = backtest(default_conf, optimize.preprocess(data), 1, True) + results = backtest(default_conf['stake_amount'], optimize.preprocess(data), 1, True) assert len(results) > 0 From 50e7cef5f39fb506d17da4bc0d9a196beeb7bf9f Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sat, 23 Dec 2017 18:01:18 +0200 Subject: [PATCH 7/9] remove commented-out code --- freqtrade/optimize/hyperopt.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 7a3340508..1e37c1e93 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -140,8 +140,6 @@ def optimizer(params): 'result': result, 'results': results } - - # logger.info('{:5d}/{}: {}'.format(_CURRENT_TRIES, TOTAL_TRIES, result)) log_results(result_data) return { From e644d57dbe0a493693865725518dad528b381455 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sat, 23 Dec 2017 18:37:42 +0200 Subject: [PATCH 8/9] log should state profit is in BTC to avoid confusion --- freqtrade/optimize/hyperopt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 1e37c1e93..4eaaf0f9c 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -153,7 +153,7 @@ def optimizer(params): def format_results(results: DataFrame): return ('Made {:6d} buys. Average profit {: 5.2f}%. ' - 'Total profit was {: 11.8f}. Average duration {:5.1f} mins.').format( + 'Total profit was {: 11.8f} BTC. Average duration {:5.1f} mins.').format( len(results.index), results.profit_percent.mean() * 100.0, results.profit_BTC.sum(), From 353b0d2d34f9d80fc6106ea737d9d5e5722c39d7 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sat, 23 Dec 2017 18:38:16 +0200 Subject: [PATCH 9/9] balance hyperopt objective to adjusted profit calculations --- freqtrade/optimize/hyperopt.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 4eaaf0f9c..2a21c2553 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -36,6 +36,10 @@ TOTAL_PROFIT_TO_BEAT = 0 AVG_PROFIT_TO_BEAT = 0 AVG_DURATION_TO_BEAT = 100 +# this is expexted avg profit * expected trade count +# for example 3.5%, 1100 trades, EXPECTED_MAX_PROFIT = 3.85 +EXPECTED_MAX_PROFIT = 3.85 + # Configuration and data used by hyperopt PROCESSED = optimize.preprocess(optimize.load_data()) OPTIMIZE_CONFIG = hyperopt_optimize_conf() @@ -120,11 +124,11 @@ def optimizer(params): result = format_results(results) - total_profit = results.profit_percent.sum() * 1000 + total_profit = results.profit_percent.sum() trade_count = len(results.index) trade_loss = 1 - 0.35 * exp(-(trade_count - TARGET_TRADES) ** 2 / 10 ** 5.2) - profit_loss = max(0, 1 - total_profit / 10000) # max profit 10000 + profit_loss = max(0, 1 - total_profit / EXPECTED_MAX_PROFIT) _CURRENT_TRIES += 1