From f64c8cc9ceae9117c18b2c4385eb6beaaac18afc Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Thu, 15 Feb 2018 13:11:17 +0200 Subject: [PATCH 1/4] realistic should be False by default and enabled with a --realistic-simulation flag --- freqtrade/optimize/backtesting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index ce5fc098b..ed8f34851 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -109,7 +109,7 @@ def backtest(args) -> DataFrame: headers = ['date', 'buy', 'open', 'close', 'sell'] processed = args['processed'] max_open_trades = args.get('max_open_trades', 0) - realistic = args.get('realistic', True) + realistic = args.get('realistic', False) record = args.get('record', None) records = [] trades = [] From ec8bf826955c00e061a6b92ce0f433613fda5e4f Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Thu, 15 Feb 2018 15:23:49 +0200 Subject: [PATCH 2/4] combine shared backtest/hyperopt flags --- freqtrade/misc.py | 47 +++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/freqtrade/misc.py b/freqtrade/misc.py index b24f961e0..b5e8ad070 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -207,13 +207,7 @@ def scripts_options(parser: argparse.ArgumentParser) -> None: ) -def backtesting_options(parser: argparse.ArgumentParser) -> None: - parser.add_argument( - '-l', '--live', - action='store_true', - dest='live', - help='using live data', - ) +def optimizer_shared_options(parser: argparse.ArgumentParser) -> None: parser.add_argument( '-i', '--ticker-interval', help='specify ticker interval in minutes (1, 5, 30, 60, 1440)', @@ -227,6 +221,22 @@ def backtesting_options(parser: argparse.ArgumentParser) -> None: action='store_true', dest='realistic_simulation', ) + parser.add_argument( + '--timerange', + help='Specify what timerange of data to use.', + default=None, + type=str, + dest='timerange', + ) + + +def backtesting_options(parser: argparse.ArgumentParser) -> None: + parser.add_argument( + '-l', '--live', + action='store_true', + dest='live', + help='using live data', + ) parser.add_argument( '-r', '--refresh-pairs-cached', help='refresh the pairs files in tests/testdata with the latest data from Bittrex. \ @@ -242,13 +252,6 @@ def backtesting_options(parser: argparse.ArgumentParser) -> None: default=None, dest='export', ) - parser.add_argument( - '--timerange', - help='Specify what timerange of data to use.', - default=None, - type=str, - dest='timerange', - ) def hyperopt_options(parser: argparse.ArgumentParser) -> None: @@ -266,20 +269,6 @@ def hyperopt_options(parser: argparse.ArgumentParser) -> None: dest='mongodb', action='store_true', ) - parser.add_argument( - '-i', '--ticker-interval', - help='specify ticker interval in minutes (1, 5, 30, 60, 1440)', - dest='ticker_interval', - type=int, - metavar='INT', - ) - parser.add_argument( - '--timerange', - help='Specify what timerange of data to use.', - default=None, - type=str, - dest='timerange', - ) parser.add_argument( '-s', '--spaces', help='Specify which parameters to hyperopt. Space separate list. \ @@ -330,11 +319,13 @@ def build_subcommands(parser: argparse.ArgumentParser) -> None: # Add backtesting subcommand backtesting_cmd = subparsers.add_parser('backtesting', help='backtesting module') backtesting_cmd.set_defaults(func=backtesting.start) + optimizer_shared_options(backtesting_cmd) backtesting_options(backtesting_cmd) # Add hyperopt subcommand hyperopt_cmd = subparsers.add_parser('hyperopt', help='hyperopt module') hyperopt_cmd.set_defaults(func=hyperopt.start) + optimizer_shared_options(hyperopt_cmd) hyperopt_options(hyperopt_cmd) From bf72b5bc37c4b3d9be4b86ee8e452226c369cfcd Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Fri, 16 Feb 2018 14:00:12 +0200 Subject: [PATCH 3/4] make args available for optimizer and use them instead of guessing from params --- freqtrade/optimize/hyperopt.py | 83 ++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index f9485c2be..f508440b4 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -403,53 +403,58 @@ def buy_strategy_generator(params: Dict[str, Any]) -> Callable: return populate_buy_trend -def optimizer(params): - global _CURRENT_TRIES +def generate_optimizer(args): + def optimizer(params): + global _CURRENT_TRIES - strategy = Strategy() - if 'roi_t1' in params: - strategy.minimal_roi = generate_roi_table(params) + strategy = Strategy() + if has_space(args.spaces, 'roi'): + strategy.minimal_roi = generate_roi_table(params) - if 'trigger' in params: - backtesting.populate_buy_trend = buy_strategy_generator(params) + if has_space(args.spaces, 'buy'): + backtesting.populate_buy_trend = buy_strategy_generator(params) - if 'stoploss' in params: - stoploss = params['stoploss'] - else: - stoploss = strategy.stoploss + if has_space(args.spaces, 'stoploss'): + stoploss = params['stoploss'] + else: + stoploss = strategy.stoploss - results = backtest({'stake_amount': OPTIMIZE_CONFIG['stake_amount'], - 'processed': PROCESSED, - 'stoploss': stoploss}) - result_explanation = format_results(results) + results = backtest({'stake_amount': OPTIMIZE_CONFIG['stake_amount'], + 'processed': PROCESSED, + 'stoploss': stoploss, + 'realistic': args.realistic_simulation, + }) + result_explanation = format_results(results) - total_profit = results.profit_percent.sum() - trade_count = len(results.index) - trade_duration = results.duration.mean() + total_profit = results.profit_percent.sum() + trade_count = len(results.index) + trade_duration = results.duration.mean() + + if trade_count == 0 or trade_duration > MAX_ACCEPTED_TRADE_DURATION: + print('.', end='') + return { + 'status': STATUS_FAIL, + 'loss': float('inf') + } + + loss = calculate_loss(total_profit, trade_count, trade_duration) + + _CURRENT_TRIES += 1 + + log_results({ + 'loss': loss, + 'current_tries': _CURRENT_TRIES, + 'total_tries': TOTAL_TRIES, + 'result': result_explanation, + }) - if trade_count == 0 or trade_duration > MAX_ACCEPTED_TRADE_DURATION: - print('.', end='') return { - 'status': STATUS_FAIL, - 'loss': float('inf') + 'loss': loss, + 'status': STATUS_OK, + 'result': result_explanation, } - loss = calculate_loss(total_profit, trade_count, trade_duration) - - _CURRENT_TRIES += 1 - - log_results({ - 'loss': loss, - 'current_tries': _CURRENT_TRIES, - 'total_tries': TOTAL_TRIES, - 'result': result_explanation, - }) - - return { - 'loss': loss, - 'status': STATUS_OK, - 'result': result_explanation, - } + return optimizer def format_results(results: DataFrame): @@ -519,7 +524,7 @@ def start(args): try: best_parameters = fmin( - fn=optimizer, + fn=generate_optimizer(args), space=hyperopt_space(args.spaces), algo=tpe.suggest, max_evals=TOTAL_TRIES, From fac122891f91d89ec29565f572abe6241c23ea35 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sat, 17 Feb 2018 11:14:03 +0200 Subject: [PATCH 4/4] remove stoploss parameter from backtest, it is loaded from strategy --- freqtrade/optimize/backtesting.py | 2 -- freqtrade/optimize/hyperopt.py | 5 +---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index ed8f34851..a0dc8a789 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -103,7 +103,6 @@ def backtest(args) -> DataFrame: realistic: do we try to simulate realistic trades? (default: True) sell_profit_only: sell if profit only use_sell_signal: act on sell-signal - stoploss: use stoploss :return: DataFrame """ headers = ['date', 'buy', 'open', 'close', 'sell'] @@ -224,7 +223,6 @@ def start(args): 'realistic': args.realistic_simulation, 'sell_profit_only': sell_profit_only, 'use_sell_signal': use_sell_signal, - 'stoploss': strategy.stoploss, 'record': args.export }) logger.info( diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index f508440b4..72f61e9d3 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -415,13 +415,10 @@ def generate_optimizer(args): backtesting.populate_buy_trend = buy_strategy_generator(params) if has_space(args.spaces, 'stoploss'): - stoploss = params['stoploss'] - else: - stoploss = strategy.stoploss + strategy.stoploss = params['stoploss'] results = backtest({'stake_amount': OPTIMIZE_CONFIG['stake_amount'], 'processed': PROCESSED, - 'stoploss': stoploss, 'realistic': args.realistic_simulation, }) result_explanation = format_results(results)