Use sell-reason value in backtesting, not the enum object

This commit is contained in:
Matthias 2021-02-06 10:30:50 +01:00
parent b5177eadab
commit 712d503e6c
6 changed files with 19 additions and 10 deletions

View File

@ -259,11 +259,11 @@ class Backtesting:
sell_row[BUY_IDX], sell_row[SELL_IDX], sell_row[BUY_IDX], sell_row[SELL_IDX],
low=sell_row[LOW_IDX], high=sell_row[HIGH_IDX]) low=sell_row[LOW_IDX], high=sell_row[HIGH_IDX])
if sell.sell_flag: 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.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) trade.close(closerate, show_msg=False)
return trade return trade
@ -281,7 +281,7 @@ class Backtesting:
sell_row = data[pair][-1] sell_row = data[pair][-1]
trade.close_date = sell_row[DATE_IDX] 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) trade.close(sell_row[OPEN_IDX], show_msg=False)
# Deepcopy object to have wallets update correctly # Deepcopy object to have wallets update correctly
trade1 = deepcopy(trade) trade1 = deepcopy(trade)
@ -366,6 +366,7 @@ class Backtesting:
fee_open=self.fee, fee_open=self.fee,
fee_close=self.fee, fee_close=self.fee,
is_open=True, is_open=True,
exchange='backtesting',
) )
# TODO: hacky workaround to avoid opening > max_open_trades # TODO: hacky workaround to avoid opening > max_open_trades
# This emulates previous behaviour - not sure if this is correct # This emulates previous behaviour - not sure if this is correct

View File

@ -132,7 +132,7 @@ def generate_sell_reason_stats(max_open_trades: int, results: DataFrame) -> List
tabular_data.append( tabular_data.append(
{ {
'sell_reason': reason.value, 'sell_reason': reason,
'trades': count, 'trades': count,
'wins': len(result[result['profit_abs'] > 0]), 'wins': len(result[result['profit_abs'] > 0]),
'draws': len(result[result['profit_abs'] == 0]), 'draws': len(result[result['profit_abs'] == 0]),

View File

@ -268,6 +268,14 @@ class Trade(_DECL_BASE):
return (f'Trade(id={self.id}, pair={self.pair}, amount={self.amount:.8f}, ' return (f'Trade(id={self.id}, pair={self.pair}, amount={self.amount:.8f}, '
f'open_rate={self.open_rate:.8f}, open_since={open_since})') 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]: def to_json(self) -> Dict[str, Any]:
return { return {
'trade_id': self.id, '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_pct': round(self.close_profit * 100, 2) if self.close_profit else None,
'close_profit_abs': self.close_profit_abs, # Deprecated '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), 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), if self.close_date else None),
'profit_ratio': self.close_profit, 'profit_ratio': self.close_profit,

View File

@ -514,6 +514,6 @@ def test_backtest_results(default_conf, fee, mocker, caplog, data) -> None:
for c, trade in enumerate(data.trades): for c, trade in enumerate(data.trades):
res = results.iloc[c] 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.open_date == _get_frame_time_from_offset(trade.open_tick)
assert res.close_date == _get_frame_time_from_offset(trade.close_tick) assert res.close_date == _get_frame_time_from_offset(trade.close_tick)

View File

@ -486,7 +486,7 @@ def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None:
'trade_duration': [235, 40], 'trade_duration': [235, 40],
'profit_ratio': [0.0, 0.0], 'profit_ratio': [0.0, 0.0],
'profit_abs': [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_abs': [0.0940005, 0.09272236],
'initial_stop_loss_ratio': [-0.1, -0.1], 'initial_stop_loss_ratio': [-0.1, -0.1],
'stop_loss_abs': [0.0940005, 0.09272236], 'stop_loss_abs': [0.0940005, 0.09272236],

View File

@ -265,7 +265,7 @@ def test_generate_sell_reason_stats():
'wins': [2, 0, 0], 'wins': [2, 0, 0],
'draws': [0, 0, 0], 'draws': [0, 0, 0],
'losses': [0, 0, 1], '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]
} }
) )