From 08ca7a8166337879b668bc7601e6cd04c36f683d Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Thu, 26 Oct 2017 17:24:28 +0300 Subject: [PATCH 1/3] change print to format so result can be used in hyperopt Trials --- freqtrade/tests/test_backtesting.py | 10 +++++----- freqtrade/tests/test_hyperopt.py | 9 +++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/freqtrade/tests/test_backtesting.py b/freqtrade/tests/test_backtesting.py index 3af459ee4..fa2af3511 100644 --- a/freqtrade/tests/test_backtesting.py +++ b/freqtrade/tests/test_backtesting.py @@ -13,17 +13,17 @@ from freqtrade.persistence import Trade logging.disable(logging.DEBUG) # disable debug logs that slow backtesting a lot -def print_results(results): - print('Made {} buys. Average profit {:.2f}%. Total profit was {:.3f}. Average duration {:.1f} mins.'.format( +def format_results(results): + return 'Made {} buys. Average profit {:.2f}%. Total profit was {:.3f}. Average duration {:.1f} mins.'.format( len(results.index), results.profit.mean() * 100.0, results.profit.sum(), results.duration.mean() * 5 - )) + ) def print_pair_results(pair, results): print('For currency {}:'.format(pair)) - print_results(results[results.currency == pair]) + print(format_results(results[results.currency == pair])) @pytest.fixture def pairs(): @@ -77,4 +77,4 @@ def test_backtest(conf, pairs, mocker, report=True): print('====================== BACKTESTING REPORT ================================') [print_pair_results(pair, results) for pair in pairs] print('TOTAL OVER ALL TRADES:') - print_results(results) + print(format_results(results)) diff --git a/freqtrade/tests/test_hyperopt.py b/freqtrade/tests/test_hyperopt.py index ceefb06ac..ca952003d 100644 --- a/freqtrade/tests/test_hyperopt.py +++ b/freqtrade/tests/test_hyperopt.py @@ -15,7 +15,7 @@ from freqtrade.analyze import analyze_ticker from freqtrade.main import should_sell from freqtrade.persistence import Trade -from freqtrade.tests.test_backtesting import backtest, print_results +from freqtrade.tests.test_backtesting import backtest, format_results logging.disable(logging.DEBUG) # disable debug logs that slow backtesting a lot @@ -83,9 +83,10 @@ def test_hyperopt(conf, pairs, mocker): mocker.patch('freqtrade.analyze.populate_buy_trend', side_effect=buy_strategy) results = backtest(conf, pairs, mocker) - print_results(results) - - # set the value below to suit your number concurrent trades so its realistic to 20days of data + result = format_results(results) + print(result) + + # set TARGET_TRADES to suit your number concurrent trades so its realistic to 20days of data TARGET_TRADES = 1200 if results.profit.sum() == 0 or results.profit.mean() == 0: return 49999999999 # avoid division by zero, return huge value to discard result From 649781d823b95b157cc1604ebc049278df28d782 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sat, 28 Oct 2017 15:22:15 +0300 Subject: [PATCH 2/3] store result strings, display best result in summary. switch to a lot better objective algo --- freqtrade/tests/test_hyperopt.py | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/freqtrade/tests/test_hyperopt.py b/freqtrade/tests/test_hyperopt.py index ca952003d..f6c47a866 100644 --- a/freqtrade/tests/test_hyperopt.py +++ b/freqtrade/tests/test_hyperopt.py @@ -1,15 +1,17 @@ # pragma pylint: disable=missing-docstring +from operator import itemgetter import json import logging import os from functools import reduce +from math import exp import pytest import arrow from pandas import DataFrame from qtpylib.indicators import crossed_above -from hyperopt import fmin, tpe, hp +from hyperopt import fmin, tpe, hp, Trials, STATUS_OK from freqtrade.analyze import analyze_ticker from freqtrade.main import should_sell @@ -19,6 +21,10 @@ from freqtrade.tests.test_backtesting import backtest, format_results logging.disable(logging.DEBUG) # disable debug logs that slow backtesting a lot +# set TARGET_TRADES to suit your number concurrent trades so its realistic to 20days of data +TARGET_TRADES = 1200 + + @pytest.fixture def pairs(): return ['btc-neo', 'btc-eth', 'btc-omg', 'btc-edg', 'btc-pay', @@ -85,12 +91,18 @@ def test_hyperopt(conf, pairs, mocker): result = format_results(results) print(result) + + total_profit = results.profit.sum() * 1000 + trade_count = len(results.index) - # set TARGET_TRADES to suit your number concurrent trades so its realistic to 20days of data - TARGET_TRADES = 1200 - if results.profit.sum() == 0 or results.profit.mean() == 0: - return 49999999999 # avoid division by zero, return huge value to discard result - return abs(len(results.index) - 1200.1) / (results.profit.sum() ** 2) * results.duration.mean() # the smaller the better + trade_loss = 1 - 0.8 * exp(-(trade_count - TARGET_TRADES) ** 2 / 10 ** 5) + profit_loss = exp(-total_profit**3 / 10**11) + + return { + 'loss': trade_loss + profit_loss, + 'status': STATUS_OK, + 'result': result + } space = { 'mfi': hp.choice('mfi', [ @@ -131,4 +143,9 @@ def test_hyperopt(conf, pairs, mocker): {'type': 'ao_cross_zero'} ]), } - print('Best parameters {}'.format(fmin(fn=optimizer, space=space, algo=tpe.suggest, max_evals=40))) + trials = Trials() + best = fmin(fn=optimizer, space=space, algo=tpe.suggest, max_evals=40, trials=trials) + print('\n\n\n\n====================== HYPEROPT BACKTESTING REPORT ================================') + print('Best parameters {}'.format(best)) + newlist = sorted(trials.results, key=itemgetter('loss')) + print('Result: {}'.format(newlist[0]['result'])) From 25d6d6bbe509aedf87c2cb02e929a63c3509cb3b Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sat, 28 Oct 2017 15:24:05 +0300 Subject: [PATCH 3/3] remove unused imports from test_hyperopt --- freqtrade/tests/test_hyperopt.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/freqtrade/tests/test_hyperopt.py b/freqtrade/tests/test_hyperopt.py index f6c47a866..fa1c0fab1 100644 --- a/freqtrade/tests/test_hyperopt.py +++ b/freqtrade/tests/test_hyperopt.py @@ -1,22 +1,15 @@ # pragma pylint: disable=missing-docstring from operator import itemgetter -import json import logging import os from functools import reduce from math import exp - import pytest -import arrow from pandas import DataFrame from qtpylib.indicators import crossed_above from hyperopt import fmin, tpe, hp, Trials, STATUS_OK -from freqtrade.analyze import analyze_ticker -from freqtrade.main import should_sell -from freqtrade.persistence import Trade - from freqtrade.tests.test_backtesting import backtest, format_results logging.disable(logging.DEBUG) # disable debug logs that slow backtesting a lot @@ -94,7 +87,7 @@ def test_hyperopt(conf, pairs, mocker): total_profit = results.profit.sum() * 1000 trade_count = len(results.index) - + trade_loss = 1 - 0.8 * exp(-(trade_count - TARGET_TRADES) ** 2 / 10 ** 5) profit_loss = exp(-total_profit**3 / 10**11)