From 08237abe20f650a093ab10dad983823ed63ef514 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Jul 2018 09:06:12 +0200 Subject: [PATCH 1/5] Fix wrong backtest duration identified in #1038 --- freqtrade/optimize/backtesting.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 05bcdf4b7..1ca2dacec 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -159,7 +159,7 @@ class Backtesting(object): profit_abs=trade.calc_profit(rate=sell_row.open), open_time=buy_row.date, close_time=sell_row.date, - trade_duration=(sell_row.date - buy_row.date).seconds // 60, + trade_duration=(sell_row.date - buy_row.date).total_seconds() // 60, open_index=buy_row.Index, close_index=sell_row.Index, open_at_end=False, @@ -174,7 +174,7 @@ class Backtesting(object): profit_abs=trade.calc_profit(rate=sell_row.open), open_time=buy_row.date, close_time=sell_row.date, - trade_duration=(sell_row.date - buy_row.date).seconds // 60, + trade_duration=(sell_row.date - buy_row.date)..total_seconds() // 60, open_index=buy_row.Index, close_index=sell_row.Index, open_at_end=True, From 8e4d2abd4e4f522bdfa33c35478c9c12d9a56123 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Jul 2018 09:10:17 +0200 Subject: [PATCH 2/5] Fix typo --- 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 1ca2dacec..0605799b1 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -174,7 +174,7 @@ class Backtesting(object): profit_abs=trade.calc_profit(rate=sell_row.open), open_time=buy_row.date, close_time=sell_row.date, - trade_duration=(sell_row.date - buy_row.date)..total_seconds() // 60, + trade_duration=(sell_row.date - buy_row.date).total_seconds() // 60, open_index=buy_row.Index, close_index=sell_row.Index, open_at_end=True, From f9f6a3bd04bc95e7aad3f99db6af805630af86aa Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Jul 2018 09:29:51 +0200 Subject: [PATCH 3/5] cast to int to keep exports constant --- freqtrade/optimize/backtesting.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 0605799b1..d5039fe7d 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -159,7 +159,8 @@ class Backtesting(object): profit_abs=trade.calc_profit(rate=sell_row.open), open_time=buy_row.date, close_time=sell_row.date, - trade_duration=(sell_row.date - buy_row.date).total_seconds() // 60, + trade_duration=int(( + sell_row.date - buy_row.date).total_seconds() // 60), open_index=buy_row.Index, close_index=sell_row.Index, open_at_end=False, @@ -174,7 +175,8 @@ class Backtesting(object): profit_abs=trade.calc_profit(rate=sell_row.open), open_time=buy_row.date, close_time=sell_row.date, - trade_duration=(sell_row.date - buy_row.date).total_seconds() // 60, + trade_duration=int(( + sell_row.date - buy_row.date).total_seconds() // 60), open_index=buy_row.Index, close_index=sell_row.Index, open_at_end=True, From 79b10304359d24dab0eb9382692640072269a573 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Jul 2018 20:08:55 +0200 Subject: [PATCH 4/5] output duration in a more readable way --- freqtrade/optimize/backtesting.py | 10 ++++++---- freqtrade/tests/optimize/test_backtesting.py | 9 ++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index d5039fe7d..d60ce9a54 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -6,7 +6,7 @@ This module contains the backtesting logic import logging import operator from argparse import Namespace -from datetime import datetime +from datetime import datetime, timedelta from typing import Any, Dict, List, NamedTuple, Optional, Tuple import arrow @@ -88,7 +88,7 @@ class Backtesting(object): """ stake_currency = str(self.config.get('stake_currency')) - floatfmt = ('s', 'd', '.2f', '.2f', '.8f', '.1f') + floatfmt = ('s', 'd', '.2f', '.2f', '.8f', '.1f', '.1f', '.1f') tabular_data = [] headers = ['pair', 'buy count', 'avg profit %', 'cum profit %', 'total profit ' + stake_currency, 'avg duration', 'profit', 'loss'] @@ -100,7 +100,8 @@ class Backtesting(object): result.profit_percent.mean() * 100.0, result.profit_percent.sum() * 100.0, result.profit_abs.sum(), - result.trade_duration.mean(), + str(timedelta( + minutes=round(result.trade_duration.mean()))) if len(result) else 'nan', len(result[result.profit_abs > 0]), len(result[result.profit_abs < 0]) ]) @@ -112,7 +113,8 @@ class Backtesting(object): results.profit_percent.mean() * 100.0, results.profit_percent.sum() * 100.0, results.profit_abs.sum(), - results.trade_duration.mean(), + str(timedelta( + minutes=round(results.trade_duration.mean()))) if len(results) else 'nan', len(results[results.profit_abs > 0]), len(results[results.profit_abs < 0]) ]) diff --git a/freqtrade/tests/optimize/test_backtesting.py b/freqtrade/tests/optimize/test_backtesting.py index 6fbf71e40..103137818 100644 --- a/freqtrade/tests/optimize/test_backtesting.py +++ b/freqtrade/tests/optimize/test_backtesting.py @@ -392,15 +392,14 @@ def test_generate_text_table(default_conf, mocker): result_str = ( '| pair | buy count | avg profit % | cum profit % | ' - 'total profit BTC | avg duration | profit | loss |\n' + 'total profit BTC | avg duration | profit | loss |\n' '|:--------|------------:|---------------:|---------------:|' - '-------------------:|---------------:|---------:|-------:|\n' + '-------------------:|:---------------|---------:|-------:|\n' '| ETH/BTC | 2 | 15.00 | 30.00 | ' - '0.60000000 | 20.0 | 2 | 0 |\n' + '0.60000000 | 0:20:00 | 2 | 0 |\n' '| TOTAL | 2 | 15.00 | 30.00 | ' - '0.60000000 | 20.0 | 2 | 0 |' + '0.60000000 | 0:20:00 | 2 | 0 |' ) - print(result_str) assert backtesting._generate_text_table(data={'ETH/BTC': {}}, results=results) == result_str From aa69177436c42b09237a60199116c105931c7454 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 19 Jul 2018 13:14:21 +0200 Subject: [PATCH 5/5] Properly check emptyness and adjust floatfmt --- freqtrade/optimize/backtesting.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index d60ce9a54..83b543136 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -88,7 +88,7 @@ class Backtesting(object): """ stake_currency = str(self.config.get('stake_currency')) - floatfmt = ('s', 'd', '.2f', '.2f', '.8f', '.1f', '.1f', '.1f') + floatfmt = ('s', 'd', '.2f', '.2f', '.8f', 'd', '.1f', '.1f') tabular_data = [] headers = ['pair', 'buy count', 'avg profit %', 'cum profit %', 'total profit ' + stake_currency, 'avg duration', 'profit', 'loss'] @@ -101,7 +101,7 @@ class Backtesting(object): result.profit_percent.sum() * 100.0, result.profit_abs.sum(), str(timedelta( - minutes=round(result.trade_duration.mean()))) if len(result) else 'nan', + minutes=round(result.trade_duration.mean()))) if not result.empty else '0:00', len(result[result.profit_abs > 0]), len(result[result.profit_abs < 0]) ]) @@ -114,7 +114,7 @@ class Backtesting(object): results.profit_percent.sum() * 100.0, results.profit_abs.sum(), str(timedelta( - minutes=round(results.trade_duration.mean()))) if len(results) else 'nan', + minutes=round(results.trade_duration.mean()))) if not results.empty else '0:00', len(results[results.profit_abs > 0]), len(results[results.profit_abs < 0]) ])