From 712d503e6ca51acde5a676f833f073018d465cab Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 6 Feb 2021 10:30:50 +0100 Subject: [PATCH] Use sell-reason value in backtesting, not the enum object --- freqtrade/optimize/backtesting.py | 9 +++++---- freqtrade/optimize/optimize_reports.py | 2 +- freqtrade/persistence/models.py | 12 ++++++++++-- tests/optimize/test_backtest_detail.py | 2 +- tests/optimize/test_backtesting.py | 2 +- tests/optimize/test_optimize_reports.py | 2 +- 6 files changed, 19 insertions(+), 10 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index b68732d5c..718fd2c42 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -259,11 +259,11 @@ class Backtesting: sell_row[BUY_IDX], sell_row[SELL_IDX], low=sell_row[LOW_IDX], high=sell_row[HIGH_IDX]) if sell.sell_flag: - trade_dur = int((sell_row[DATE_IDX] - trade.open_date).total_seconds() // 60) - closerate = self._get_close_rate(sell_row, trade, sell, trade_dur) trade.close_date = sell_row[DATE_IDX] - trade.sell_reason = sell.sell_type + trade.sell_reason = sell.sell_type.value + trade_dur = int((trade.close_date_utc - trade.open_date_utc).total_seconds() // 60) + closerate = self._get_close_rate(sell_row, trade, sell, trade_dur) trade.close(closerate, show_msg=False) return trade @@ -281,7 +281,7 @@ class Backtesting: sell_row = data[pair][-1] trade.close_date = sell_row[DATE_IDX] - trade.sell_reason = SellType.FORCE_SELL + trade.sell_reason = SellType.FORCE_SELL.value trade.close(sell_row[OPEN_IDX], show_msg=False) # Deepcopy object to have wallets update correctly trade1 = deepcopy(trade) @@ -366,6 +366,7 @@ class Backtesting: fee_open=self.fee, fee_close=self.fee, is_open=True, + exchange='backtesting', ) # TODO: hacky workaround to avoid opening > max_open_trades # This emulates previous behaviour - not sure if this is correct diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index 88b2028ba..6338b1d71 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -132,7 +132,7 @@ def generate_sell_reason_stats(max_open_trades: int, results: DataFrame) -> List tabular_data.append( { - 'sell_reason': reason.value, + 'sell_reason': reason, 'trades': count, 'wins': len(result[result['profit_abs'] > 0]), 'draws': len(result[result['profit_abs'] == 0]), diff --git a/freqtrade/persistence/models.py b/freqtrade/persistence/models.py index dff59819c..a05aa2c96 100644 --- a/freqtrade/persistence/models.py +++ b/freqtrade/persistence/models.py @@ -268,6 +268,14 @@ class Trade(_DECL_BASE): return (f'Trade(id={self.id}, pair={self.pair}, amount={self.amount:.8f}, ' f'open_rate={self.open_rate:.8f}, open_since={open_since})') + @property + def open_date_utc(self): + return self.open_date.replace(tzinfo=timezone.utc) + + @property + def close_date_utc(self): + return self.close_date.replace(tzinfo=timezone.utc) + def to_json(self) -> Dict[str, Any]: return { 'trade_id': self.id, @@ -306,9 +314,9 @@ class Trade(_DECL_BASE): 'close_profit_pct': round(self.close_profit * 100, 2) if self.close_profit else None, 'close_profit_abs': self.close_profit_abs, # Deprecated - 'trade_duration_s': (int((self.close_date - self.open_date).total_seconds()) + 'trade_duration_s': (int((self.close_date_utc - self.open_date_utc).total_seconds()) if self.close_date else None), - 'trade_duration': (int((self.close_date - self.open_date).total_seconds() // 60) + 'trade_duration': (int((self.close_date_utc - self.open_date_utc).total_seconds() // 60) if self.close_date else None), 'profit_ratio': self.close_profit, diff --git a/tests/optimize/test_backtest_detail.py b/tests/optimize/test_backtest_detail.py index daf7c2053..c9499cc42 100644 --- a/tests/optimize/test_backtest_detail.py +++ b/tests/optimize/test_backtest_detail.py @@ -514,6 +514,6 @@ def test_backtest_results(default_conf, fee, mocker, caplog, data) -> None: for c, trade in enumerate(data.trades): res = results.iloc[c] - assert res.sell_reason == trade.sell_reason + assert res.sell_reason == trade.sell_reason.value assert res.open_date == _get_frame_time_from_offset(trade.open_tick) assert res.close_date == _get_frame_time_from_offset(trade.close_tick) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index c8d4338af..db14749c3 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -486,7 +486,7 @@ def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None: 'trade_duration': [235, 40], 'profit_ratio': [0.0, 0.0], 'profit_abs': [0.0, 0.0], - 'sell_reason': [SellType.ROI, SellType.ROI], + 'sell_reason': [SellType.ROI.value, SellType.ROI.value], 'initial_stop_loss_abs': [0.0940005, 0.09272236], 'initial_stop_loss_ratio': [-0.1, -0.1], 'stop_loss_abs': [0.0940005, 0.09272236], diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 51a78c7cc..8b64c2764 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -265,7 +265,7 @@ def test_generate_sell_reason_stats(): 'wins': [2, 0, 0], 'draws': [0, 0, 0], 'losses': [0, 0, 1], - 'sell_reason': [SellType.ROI, SellType.ROI, SellType.STOP_LOSS] + 'sell_reason': [SellType.ROI.value, SellType.ROI.value, SellType.STOP_LOSS.value] } )